mirror of
https://github.com/Doodle3D/Doodle3D-Slicer.git
synced 2024-11-19 04:27:55 +01:00
created abstraction for clipper js
This commit is contained in:
parent
c63f50075f
commit
9740c254c2
5
.gitignore
vendored
5
.gitignore
vendored
@ -15,4 +15,7 @@ src/script/.DS_Store
|
||||
|
||||
src/.DS_Store
|
||||
|
||||
bower_components/
|
||||
bower_components/
|
||||
src/oldcode.js
|
||||
|
||||
test.html
|
||||
|
445
build/d3d.js
vendored
445
build/d3d.js
vendored
@ -89,61 +89,6 @@ Array.prototype.clone = function () {
|
||||
|
||||
return array;
|
||||
};
|
||||
|
||||
function applyMouseControls (renderer, camera, center, maxDistance) {
|
||||
"use strict";
|
||||
//TODO
|
||||
//impliment touch controls
|
||||
//windows mouse wheel fix
|
||||
|
||||
var distance = 20;
|
||||
var rotX = 0;
|
||||
var rotY = 0;
|
||||
var moveCamera = false;
|
||||
|
||||
function updateCamera () {
|
||||
camera.position.set(
|
||||
Math.cos(rotY)*Math.sin(rotX)*distance,
|
||||
Math.sin(rotY)*distance,
|
||||
Math.cos(rotY)*Math.cos(rotX)*distance
|
||||
).add(center);
|
||||
camera.lookAt(center);
|
||||
}
|
||||
|
||||
$(renderer.domElement).on("mousedown", function (e) {
|
||||
moveCamera = true;
|
||||
}).on("wheel", function (e) {
|
||||
var event = e.originalEvent;
|
||||
|
||||
event.preventDefault();
|
||||
distance = THREE.Math.clamp(distance - event.wheelDelta, 1, maxDistance);
|
||||
|
||||
updateCamera();
|
||||
});
|
||||
|
||||
$(window).on("mouseup", function (e) {
|
||||
moveCamera = false;
|
||||
}).on("mousemove", function (e) {
|
||||
var event = e.originalEvent;
|
||||
|
||||
if (moveCamera === true) {
|
||||
rotX = (rotX - event.webkitMovementX/100) % (2*Math.PI);
|
||||
rotY = THREE.Math.clamp(rotY + event.webkitMovementY/100, -Math.PI/2, Math.PI/2);
|
||||
|
||||
updateCamera();
|
||||
}
|
||||
});
|
||||
|
||||
updateCamera();
|
||||
}
|
||||
|
||||
var requestAnimFrame = (function () {
|
||||
"use strict";
|
||||
|
||||
return requestAnimationFrame || webkitRequestAnimationFrame || mozRequestAnimationFrame || function (callback) {
|
||||
setTimeout(callback, 1000/60);
|
||||
};
|
||||
})();
|
||||
/******************************************************
|
||||
*
|
||||
* Box
|
||||
@ -617,6 +562,159 @@ D3D.Printer.prototype.subsituteVariables = function (gcode) {
|
||||
};
|
||||
/******************************************************
|
||||
*
|
||||
* Path
|
||||
*
|
||||
* Abstraction layer for annoying clipper js
|
||||
*
|
||||
******************************************************/
|
||||
|
||||
D3D.Path = function (path, closed) {
|
||||
"use strict";
|
||||
|
||||
this.path = path || [];
|
||||
this.closed = (closed !== undefined) ? closed : true;
|
||||
};
|
||||
D3D.Path.prototype.setPath = function (path) {
|
||||
"use strict";
|
||||
|
||||
this.path = path;
|
||||
|
||||
return this;
|
||||
};
|
||||
D3D.Path.prototype.union = function (path) {
|
||||
"use strict";
|
||||
|
||||
var solution = new ClipperLib.Paths();
|
||||
|
||||
var clipper = new ClipperLib.Clipper();
|
||||
clipper.AddPaths(this.path, ClipperLib.PolyType.ptSubject, this.closed);
|
||||
clipper.AddPaths(path.path, ClipperLib.PolyType.ptClip, path.closed);
|
||||
clipper.Execute(ClipperLib.ClipType.ctUnion, solution);
|
||||
|
||||
return new D3D.Path(solution, this.closed);
|
||||
};
|
||||
D3D.Path.prototype.difference = function (path) {
|
||||
"use strict";
|
||||
|
||||
var solution = new ClipperLib.Paths();
|
||||
|
||||
var clipper = new ClipperLib.Clipper();
|
||||
clipper.AddPaths(this.path, ClipperLib.PolyType.ptSubject, this.closed);
|
||||
clipper.AddPaths(path.path, ClipperLib.PolyType.ptClip, path.closed);
|
||||
clipper.Execute(ClipperLib.ClipType.ctDifference, solution);
|
||||
|
||||
return new D3D.Path(solution, this.closed);
|
||||
};
|
||||
D3D.Path.prototype.intersect = function (path) {
|
||||
"use strict";
|
||||
|
||||
var solution = new ClipperLib.Paths();
|
||||
|
||||
var clipper = new ClipperLib.Clipper();
|
||||
clipper.AddPaths(this.path, ClipperLib.PolyType.ptSubject, this.closed);
|
||||
clipper.AddPaths(path.path, ClipperLib.PolyType.ptClip, path.closed);
|
||||
clipper.Execute(ClipperLib.ClipType.ctIntersection, solution);
|
||||
|
||||
return new D3D.Path(solution, this.closed);
|
||||
};
|
||||
D3D.Path.prototype.xor = function () {
|
||||
"use strict";
|
||||
|
||||
var solution = new ClipperLib.Paths();
|
||||
|
||||
var clipper = new ClipperLib.Clipper();
|
||||
clipper.AddPaths(this.path, ClipperLib.PolyType.ptSubject, this.closed);
|
||||
clipper.AddPaths(path.path, ClipperLib.PolyType.ptClip, path.closed);
|
||||
clipper.Execute(ClipperLib.ClipType.ctXor, solution);
|
||||
|
||||
return new D3D.Path(solution, this.closed);
|
||||
};
|
||||
D3D.Path.prototype.offset = function (offset) {
|
||||
"use strict";
|
||||
|
||||
var solution = new ClipperLib.Paths();
|
||||
var co = new ClipperLib.ClipperOffset(1, 1);
|
||||
co.AddPaths(this.path, ClipperLib.JoinType.jtRound, ClipperLib.EndType.etClosedPolygon);
|
||||
co.Execute(solution, offset);
|
||||
|
||||
return new D3D.Path(solution, this.closed);
|
||||
};
|
||||
D3D.Path.prototype.scaleUp = function (factor) {
|
||||
"use strict";
|
||||
|
||||
var path = ClipperLib.JS.ScaleUpPaths(this.path, factor);
|
||||
|
||||
return this;
|
||||
};
|
||||
D3D.Path.prototype.scaleDown = function (factor) {
|
||||
"use strict";
|
||||
|
||||
var path = ClipperLib.JS.ScaleDownPaths(this.path, factor);
|
||||
|
||||
return this;
|
||||
};
|
||||
D3D.Path.prototype.tresholdArea = function (minArea) {
|
||||
"use strict";
|
||||
|
||||
for (var i = 0; i < this.path.length; i ++) {
|
||||
var shape = this.path[i];
|
||||
|
||||
var area = ClipperLib.Clipper.Area(shape);
|
||||
|
||||
if (area < minArea) {
|
||||
this.path.splice(i, 1);
|
||||
i --;
|
||||
}
|
||||
}
|
||||
|
||||
return areas;
|
||||
};
|
||||
D3D.Path.prototype.area = function () {
|
||||
"use strict";
|
||||
|
||||
var areas = [];
|
||||
|
||||
for (var i = 0; i < this.path.length; i ++) {
|
||||
var shape = this.path[i];
|
||||
|
||||
areas.push(ClipperLib.Clipper.Area(shape))
|
||||
}
|
||||
|
||||
return areas;
|
||||
};
|
||||
D3D.Path.prototype.join = function (path) {
|
||||
"use strict";
|
||||
|
||||
this.path = this.path.concat(path.path);
|
||||
|
||||
return this;
|
||||
}
|
||||
D3D.Path.prototype.clone = function () {
|
||||
"use strict";
|
||||
|
||||
var path = ClipperLib.JS.Clone(this.path);
|
||||
|
||||
return new D3D.Path(path, this.closed);
|
||||
}
|
||||
D3D.Path.prototype.draw = function (context, color) {
|
||||
"use strict";
|
||||
|
||||
context.strokeStyle = color;
|
||||
for (var i = 0; i < this.path.length; i ++) {
|
||||
var shape = this.path[i];
|
||||
|
||||
context.beginPath();
|
||||
var length = this.closed ? (shape.length + 1) : shape.length;
|
||||
for (var j = 0; j < length; j ++) {
|
||||
var point = shape[j % shape.length];
|
||||
|
||||
context.lineTo(point.X*2, point.Y*2);
|
||||
}
|
||||
context.stroke();
|
||||
}
|
||||
};
|
||||
/******************************************************
|
||||
*
|
||||
* Slicer
|
||||
*
|
||||
* TODO (optimalisatie)
|
||||
@ -732,8 +830,8 @@ D3D.Slicer.prototype.slice = function (height, step) {
|
||||
var line = this.lines[index].line;
|
||||
|
||||
var alpha = (y - line.start.y) / (line.end.y - line.start.y);
|
||||
var x = line.start.x * alpha + line.end.x * (1 - alpha);
|
||||
var z = line.start.z * alpha + line.end.z * (1 - alpha);
|
||||
var x = line.end.x * alpha + line.start.x * (1 - alpha);
|
||||
var z = line.end.z * alpha + line.start.z * (1 - alpha);
|
||||
|
||||
intersections[index] = new THREE.Vector2(x, z);
|
||||
}
|
||||
@ -807,7 +905,8 @@ D3D.Slicer.prototype.slice = function (height, step) {
|
||||
|
||||
//stop when ther are no intersects
|
||||
if (slice.length > 0) {
|
||||
slices.push(slice);
|
||||
slices.push(new D3D.Path(slice, true));
|
||||
//slices.push(slice);
|
||||
}
|
||||
else {
|
||||
break;
|
||||
@ -816,20 +915,64 @@ D3D.Slicer.prototype.slice = function (height, step) {
|
||||
|
||||
return slices;
|
||||
};
|
||||
D3D.Slicer.prototype.getInset = function (slice, offset) {
|
||||
D3D.Slicer.prototype.slicesToData = function (slices, printer) {
|
||||
"use strict";
|
||||
|
||||
var solution = new ClipperLib.Paths();
|
||||
var co = new ClipperLib.ClipperOffset(1, 1);
|
||||
co.AddPaths(slice, ClipperLib.JoinType.jtRound, ClipperLib.EndType.etClosedPolygon);
|
||||
co.Execute(solution, -offset);
|
||||
var scale = 100;
|
||||
|
||||
return solution;
|
||||
var layerHeight = printer.config["printer.layerHeight"] * scale;
|
||||
var dimensionsZ = printer.config["printer.dimensions.z"] * scale;
|
||||
var wallThickness = printer.config["printer.wallThickness"] * scale;
|
||||
var shellThickness = printer.config["printer.shellThickness"] * scale;
|
||||
var fillSize = printer.config["printer.fillSize"] * scale;
|
||||
var brimOffset = printer.config["printer.brimOffset"] * scale;
|
||||
var skinCount = Math.ceil(shellThickness/layerHeight);
|
||||
|
||||
var data = [];
|
||||
|
||||
var lowFillTemplate = this.getFillTemplate(dimensionsZ, fillSize, true, true);
|
||||
|
||||
for (var layer = 0; layer < slices.length; layer ++) {
|
||||
var slice = slices[layer];
|
||||
|
||||
var outerLayer = slice.clone();
|
||||
outerLayer.scaleUp(scale);
|
||||
|
||||
var insets = new D3D.Path();
|
||||
for (var offset = wallThickness; offset <= shellThickness; offset += wallThickness) {
|
||||
var inset = outerLayer.offset(-offset);
|
||||
|
||||
insets.join(inset);
|
||||
}
|
||||
|
||||
var fillArea = (inset || outerLayer).offset(-wallThickness/2);
|
||||
|
||||
var downFill = (layer - skinCount >= 0) ? slices[layer - skinCount] : new D3D.Path();
|
||||
var upFill = (layer + skinCount < slices.length) ? slices[layer + skinCount] : new D3D.Path();
|
||||
var highFillArea = fillArea.difference(downFill.intersect(upFill).scaleUp(scale));
|
||||
|
||||
var lowFillArea = fillArea.difference(highFillArea);
|
||||
|
||||
var fill = new D3D.Path([], false);
|
||||
fill.join(lowFillTemplate.intersect(lowFillArea));
|
||||
if (highFillArea.path.length > 0) {
|
||||
var highFillTemplate = this.getFillTemplate(dimensionsZ, wallThickness, (layer % 2 === 0), (layer % 2 === 1));
|
||||
fill.join(highFillTemplate.intersect(highFillArea));
|
||||
}
|
||||
|
||||
data.push({
|
||||
outerLayer: outerLayer.scaleDown(scale),
|
||||
insets: insets.scaleDown(scale),
|
||||
fill: fill.scaleDown(scale)
|
||||
});
|
||||
}
|
||||
|
||||
return data;
|
||||
};
|
||||
D3D.Slicer.prototype.getFillTemplate = function (dimension, size, even, uneven) {
|
||||
"use strict";
|
||||
|
||||
var paths = new ClipperLib.Paths();
|
||||
var paths = [];
|
||||
|
||||
if (even) {
|
||||
for (var length = 0; length <= dimension; length += size) {
|
||||
@ -842,125 +985,8 @@ D3D.Slicer.prototype.getFillTemplate = function (dimension, size, even, uneven)
|
||||
}
|
||||
}
|
||||
|
||||
return paths;
|
||||
};
|
||||
D3D.Slicer.prototype.slicesToData = function (slices, printer) {
|
||||
"use strict";
|
||||
|
||||
//scale because of clipper crap
|
||||
var scale = 100;
|
||||
|
||||
var layerHeight = printer.config["printer.layerHeight"] * scale;
|
||||
var dimensionsZ = printer.config["printer.dimensions.z"] * scale;
|
||||
var wallThickness = printer.config["printer.wallThickness"] * scale;
|
||||
var shellThickness = printer.config["printer.shellThickness"] * scale;
|
||||
var fillSize = printer.config["printer.fillSize"] * scale;
|
||||
var brimOffset = printer.config["printer.brimOffset"] * scale;
|
||||
|
||||
var data = [];
|
||||
|
||||
var lowFillTemplate = this.getFillTemplate(dimensionsZ, fillSize, true, true);
|
||||
|
||||
for (var layer = 0; layer < slices.length; layer ++) {
|
||||
var slice = slices[layer];
|
||||
|
||||
//var outerLayer = ClipperLib.JS.Clean(slice, 1.0);
|
||||
var outerLayer = slice.clone();
|
||||
ClipperLib.JS.ScaleUpPaths(outerLayer, scale);
|
||||
|
||||
var innerLayer = [];
|
||||
|
||||
for (var i = wallThickness; i < shellThickness; i += wallThickness) {
|
||||
var inset = this.getInset(outerLayer, i);
|
||||
|
||||
innerLayer = innerLayer.concat(inset);
|
||||
}
|
||||
|
||||
//moet fillArea wel kleiner?
|
||||
//var fillArea = this.getInset((inset || outerLayer), wallThickness);
|
||||
var fillArea = (inset || outerLayer);
|
||||
|
||||
var fillAbove = false;
|
||||
//for (var i = 1; i < shellThickness/layerHeight; i ++) {
|
||||
for (var i = 1; i < shellThickness/layerHeight; i ++) {
|
||||
var newLayer = ClipperLib.JS.Clone(slices[layer + i]);
|
||||
ClipperLib.JS.ScaleUpPaths(newLayer, scale);
|
||||
|
||||
if (newLayer.length === 0 || (fillAbove && fillAbove.length === 0)) {
|
||||
fillAbove = [];
|
||||
|
||||
break;
|
||||
}
|
||||
else if (fillAbove === false) {
|
||||
fillAbove = newLayer;
|
||||
}
|
||||
else {
|
||||
var c = new ClipperLib.Clipper();
|
||||
var solution = new ClipperLib.Paths();
|
||||
c.AddPaths(newLayer, ClipperLib.PolyType.ptSubject, true);
|
||||
c.AddPaths(fillAbove, ClipperLib.PolyType.ptClip, true);
|
||||
c.Execute(ClipperLib.ClipType.ctIntersection, solution);
|
||||
|
||||
fillAbove = solution;
|
||||
}
|
||||
}
|
||||
//kijkt alleen nog naar boven
|
||||
//omliggende lagen hebben inhoud van lowFill;
|
||||
//inset moet opgevult worden;
|
||||
//verschill tussen lowFill en inset moet vol, rest is raster
|
||||
|
||||
var clipper = new ClipperLib.Clipper();
|
||||
var highFillArea = new ClipperLib.Paths();
|
||||
clipper.AddPaths(fillArea, ClipperLib.PolyType.ptSubject, true);
|
||||
clipper.AddPaths(fillAbove, ClipperLib.PolyType.ptClip, true);
|
||||
clipper.Execute(ClipperLib.ClipType.ctDifference, highFillArea);
|
||||
|
||||
var clipper = new ClipperLib.Clipper();
|
||||
var lowFillArea = new ClipperLib.Paths();
|
||||
clipper.AddPaths(fillArea, ClipperLib.PolyType.ptSubject, true);
|
||||
clipper.AddPaths(highFillArea, ClipperLib.PolyType.ptClip, true);
|
||||
clipper.Execute(ClipperLib.ClipType.ctDifference, lowFillArea);
|
||||
|
||||
var fill = [];
|
||||
|
||||
var clipper = new ClipperLib.Clipper();
|
||||
var lowFillStrokes = new ClipperLib.Paths();
|
||||
clipper.AddPaths(lowFillTemplate, ClipperLib.PolyType.ptSubject, false);
|
||||
clipper.AddPaths(lowFillArea, ClipperLib.PolyType.ptClip, true);
|
||||
clipper.Execute(ClipperLib.ClipType.ctIntersection, lowFillStrokes);
|
||||
|
||||
fill = fill.concat(lowFillStrokes);
|
||||
|
||||
//optimize
|
||||
//make as big as bounding box of highFillArea
|
||||
var highFillTemplate = this.getFillTemplate(dimensionsZ, wallThickness, (layer % 2 === 0), (layer % 2 === 1));
|
||||
|
||||
var clipper = new ClipperLib.Clipper();
|
||||
var highFillStrokes = new ClipperLib.Paths();
|
||||
clipper.AddPaths(highFillTemplate, ClipperLib.PolyType.ptSubject, false);
|
||||
clipper.AddPaths(highFillArea, ClipperLib.PolyType.ptClip, true);
|
||||
clipper.Execute(ClipperLib.ClipType.ctIntersection, highFillStrokes);
|
||||
|
||||
fill = fill.concat(highFillStrokes);
|
||||
|
||||
//create brim
|
||||
/*if (layer === 0) {
|
||||
var brim = this.getInset(outerLayer, -brimOffset);
|
||||
outerLayer = brim.concat(outerLayer);
|
||||
}*/
|
||||
|
||||
ClipperLib.JS.ScaleDownPaths(outerLayer, scale);
|
||||
ClipperLib.JS.ScaleDownPaths(innerLayer, scale);
|
||||
ClipperLib.JS.ScaleDownPaths(fill, scale);
|
||||
|
||||
data.push({
|
||||
outerLayer: outerLayer,
|
||||
innerLayer: innerLayer,
|
||||
fill: fill
|
||||
});
|
||||
}
|
||||
|
||||
return data;
|
||||
//return paths;
|
||||
return new D3D.Path(paths, false);
|
||||
};
|
||||
D3D.Slicer.prototype.dataToGcode = function (data, printer) {
|
||||
"use strict";
|
||||
@ -982,8 +1008,8 @@ D3D.Slicer.prototype.dataToGcode = function (data, printer) {
|
||||
function sliceToGcode (slice) {
|
||||
var gcode = [];
|
||||
|
||||
for (var i = 0; i < slice.length; i ++) {
|
||||
var shape = slice[i];
|
||||
for (var i = 0; i < slice.path.length; i ++) {
|
||||
var shape = slice.path[i];
|
||||
|
||||
var previousPoint;
|
||||
|
||||
@ -1057,54 +1083,20 @@ D3D.Slicer.prototype.dataToGcode = function (data, printer) {
|
||||
var z = ((layer + 1) * layerHeight).toFixed(3);
|
||||
|
||||
gcode = gcode.concat(sliceToGcode(slice.outerLayer));
|
||||
gcode = gcode.concat(sliceToGcode(slice.innerLayer));
|
||||
gcode = gcode.concat(sliceToGcode(slice.insets));
|
||||
gcode = gcode.concat(sliceToGcode(slice.fill));
|
||||
}
|
||||
|
||||
gcode = gcode.concat(printer.getEndCode());
|
||||
return gcode;
|
||||
};
|
||||
//only for debug purposes
|
||||
D3D.Slicer.prototype.drawPaths = function (printer, min, max) {
|
||||
"use strict";
|
||||
|
||||
var layerHeight = printer.config["printer.layerHeight"];
|
||||
var dimensionsZ = printer.config["printer.dimensions.z"];
|
||||
|
||||
function drawLines (paths, color) {
|
||||
context.fillStyle = color;
|
||||
context.strokeStyle = color;
|
||||
context.beginPath();
|
||||
|
||||
for (var i = 0; i < paths.length; i ++) {
|
||||
var path = paths[i];
|
||||
|
||||
context.moveTo((path[0].X * 2), (path[0].Y * 2));
|
||||
|
||||
for (var j = 0; j < path.length; j ++) {
|
||||
var point = path[j];
|
||||
context.lineTo((point.X * 2), (point.Y * 2));
|
||||
}
|
||||
//context.closePath();
|
||||
}
|
||||
context.stroke();
|
||||
}
|
||||
|
||||
function drawVertexes (paths, color) {
|
||||
context.fillStyle = color;
|
||||
context.strokeStyle = color;
|
||||
|
||||
for (var i = 0; i < paths.length; i ++) {
|
||||
var path = paths[i];
|
||||
|
||||
for (var j = 0; j < path.length; j ++) {
|
||||
var point = path[j];
|
||||
context.beginPath();
|
||||
context.arc(point.X * 2, point.Y * 2, 1, 0, Math.PI*2, false);
|
||||
context.stroke();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var slices = this.slice(dimensionsZ, layerHeight);
|
||||
|
||||
var data = this.slicesToData(slices, printer);
|
||||
@ -1114,14 +1106,13 @@ D3D.Slicer.prototype.drawPaths = function (printer, min, max) {
|
||||
canvas.height = 400;
|
||||
var context = canvas.getContext("2d");
|
||||
|
||||
|
||||
for (var layer = min; layer < max; layer ++) {
|
||||
var slice = data[layer % data.length];
|
||||
|
||||
drawLines(slice.outerLayer, "red");
|
||||
drawLines(slice.innerLayer, "green");
|
||||
drawLines(slice.fill, "blue");
|
||||
|
||||
drawVertexes(slice.outerLayer, "green");
|
||||
slice.insets.draw(context, "blue");
|
||||
slice.outerLayer.draw(context, "green");
|
||||
slice.fill.draw(context, "red");
|
||||
}
|
||||
|
||||
return canvas;
|
||||
|
2
build/d3d.min.js
vendored
2
build/d3d.min.js
vendored
File diff suppressed because one or more lines are too long
@ -10,6 +10,7 @@ var files = [
|
||||
"src/utils.js",
|
||||
"src/box.js",
|
||||
"src/printer.js",
|
||||
"src/path.js",
|
||||
"src/slicer.js"
|
||||
];
|
||||
|
||||
|
BIN
models/cubes.stl
Normal file
BIN
models/cubes.stl
Normal file
Binary file not shown.
BIN
models/overhang_test.stl
Normal file
BIN
models/overhang_test.stl
Normal file
Binary file not shown.
109
slice_test.html
109
slice_test.html
@ -11,6 +11,7 @@
|
||||
<script src="src/utils.js"></script>
|
||||
<script src="src/box.js"></script>
|
||||
<script src="src/printer.js"></script>
|
||||
<script src="src/path.js"></script>
|
||||
<script src="src/slicer.js"></script>
|
||||
|
||||
<script src="gcode/testgcode.js"></script>
|
||||
@ -43,9 +44,8 @@ var printerConfig = {
|
||||
"printer.heatup.bed.temperature": 70,
|
||||
"printer.heatup.enabled": true,
|
||||
"printer.heatup.temperature": 180,
|
||||
"printer.layerHeight": 0.3,
|
||||
"printer.retraction.amount": 3,
|
||||
"printer.retraction.enabled": true,
|
||||
"printer.retraction.enabled": false,
|
||||
"printer.retraction.minDistance": 5,
|
||||
"printer.retraction.speed": 50,
|
||||
"printer.screenToMillimeterScale": 0.3, //????
|
||||
@ -55,13 +55,16 @@ var printerConfig = {
|
||||
"printer.travelSpeed": 200,
|
||||
"printer.type": "ultimaker",
|
||||
"printer.useSubLayers": true, //wat is dit?
|
||||
"printer.wallThickness": 0.4,
|
||||
|
||||
"printer.wallThickness": 0.4, //nozzle
|
||||
"printer.layerHeight": 0.3,
|
||||
|
||||
//variabele toevoegen;
|
||||
//-snelheid, retraction etc voor verschillende types (outerlayer, innerlayer, fill)
|
||||
"printer.shellThickness": 0.8,
|
||||
"printer.shellThickness": 0.4,
|
||||
"printer.fillSize": 5, //dit is het raster aan de binnen kant van de geometry
|
||||
"printer.brimOffset": 5
|
||||
"printer.brimOffset": 5,
|
||||
"printer.bottomTopThickness": 0.8
|
||||
};
|
||||
var printer = new D3D.Printer(printerConfig);
|
||||
|
||||
@ -104,53 +107,30 @@ var geometry = (function () {
|
||||
|
||||
var material = new THREE.MeshBasicMaterial({color: 0x000000, wireframe: true});
|
||||
//var geometry = new THREE.TorusGeometry(20, 10, 30, 30);
|
||||
var geometry = new THREE.BoxGeometry(20, 20, 20, 1, 1, 1);
|
||||
var geometry = new THREE.BoxGeometry(10, 10, 10, 1, 1, 1);
|
||||
//var geometry = new THREE.SphereGeometry(10, 10, 10);
|
||||
var mesh = new THREE.Mesh(geometry, material);
|
||||
mesh.position.x = 100;
|
||||
mesh.position.z = 100;
|
||||
scene.add(mesh);
|
||||
//scene.add(mesh);
|
||||
|
||||
var canvas = document.getElementById("canvas");
|
||||
var context = canvas.getContext("2d");
|
||||
|
||||
var slicer = new D3D.Slicer().setMesh(mesh);
|
||||
|
||||
gcode = slicer.getGcode(printer);
|
||||
|
||||
var canvas = document.getElementById("canvas");
|
||||
var context = canvas.getContext("2d");
|
||||
|
||||
var layer = 0;
|
||||
var img = slicer.drawPaths(printer, layer, layer + 1);
|
||||
context.drawImage(img, 0, 0);
|
||||
|
||||
/*
|
||||
var loader = new THREE.STLLoader();
|
||||
loader.load('stl/overhang_test.stl', function (geometry) {
|
||||
|
||||
var matrix = new THREE.Matrix4();
|
||||
matrix.makeRotationX(Math.PI*1.5);
|
||||
|
||||
geometry.applyMatrix(matrix);
|
||||
|
||||
var material = new THREE.MeshLambertMaterial({color: 0x000000, wireframe: true});
|
||||
loader.load("models/cubes.stl", function (geometry) {
|
||||
var mesh = new THREE.Mesh(geometry, material);
|
||||
|
||||
mesh.position.x = 100;
|
||||
mesh.position.z = 100;
|
||||
mesh.rotation.x = -Math.PI/2;
|
||||
mesh.scale.x = mesh.scale.y = mesh.scale.z = 3;
|
||||
//mesh is lifted a little bit...
|
||||
mesh.position.y = -0.6552429199218741;
|
||||
|
||||
scene.add(mesh);
|
||||
|
||||
var canvas = document.getElementById("canvas");
|
||||
var context = canvas.getContext("2d");
|
||||
var slicer = new D3D.Slicer().setMesh(mesh);
|
||||
|
||||
var slicer = new D3D.Slicer().setMesh(geometry);
|
||||
|
||||
var layer = 149;
|
||||
var img = slicer.drawPaths(printer, layer, layer + 1);
|
||||
context.drawImage(img, 0, 0);
|
||||
|
||||
var gcode = slicer.getGcode(printer);
|
||||
console.log(gcode);
|
||||
gcode = slicer.getGcode(printer);
|
||||
});
|
||||
*/
|
||||
|
||||
(function animate () {
|
||||
"use strict";
|
||||
@ -158,6 +138,53 @@ loader.load('stl/overhang_test.stl', function (geometry) {
|
||||
requestAnimationFrame(animate);
|
||||
renderer.render(scene, camera);
|
||||
})();
|
||||
|
||||
function applyMouseControls (renderer, camera, center, maxDistance) {
|
||||
"use strict";
|
||||
//TODO
|
||||
//impliment touch controls
|
||||
//windows mouse wheel fix
|
||||
|
||||
var distance = 20;
|
||||
var rotX = 0;
|
||||
var rotY = 0;
|
||||
var moveCamera = false;
|
||||
|
||||
function updateCamera () {
|
||||
camera.position.set(
|
||||
Math.cos(rotY)*Math.sin(rotX)*distance,
|
||||
Math.sin(rotY)*distance,
|
||||
Math.cos(rotY)*Math.cos(rotX)*distance
|
||||
).add(center);
|
||||
camera.lookAt(center);
|
||||
}
|
||||
|
||||
$(renderer.domElement).on("mousedown", function (e) {
|
||||
moveCamera = true;
|
||||
}).on("wheel", function (e) {
|
||||
var event = e.originalEvent;
|
||||
|
||||
event.preventDefault();
|
||||
distance = THREE.Math.clamp(distance - event.wheelDelta, 1, maxDistance);
|
||||
|
||||
updateCamera();
|
||||
});
|
||||
|
||||
$(window).on("mouseup", function (e) {
|
||||
moveCamera = false;
|
||||
}).on("mousemove", function (e) {
|
||||
var event = e.originalEvent;
|
||||
|
||||
if (moveCamera === true) {
|
||||
rotX = (rotX - event.webkitMovementX/100) % (2*Math.PI);
|
||||
rotY = THREE.Math.clamp(rotY + event.webkitMovementY/100, -Math.PI/2, Math.PI/2);
|
||||
|
||||
updateCamera();
|
||||
}
|
||||
});
|
||||
|
||||
updateCamera();
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
153
src/path.js
Normal file
153
src/path.js
Normal file
@ -0,0 +1,153 @@
|
||||
/******************************************************
|
||||
*
|
||||
* Path
|
||||
*
|
||||
* Abstraction layer for annoying clipper js
|
||||
*
|
||||
******************************************************/
|
||||
|
||||
D3D.Path = function (path, closed) {
|
||||
"use strict";
|
||||
|
||||
this.path = path || [];
|
||||
this.closed = (closed !== undefined) ? closed : true;
|
||||
};
|
||||
D3D.Path.prototype.setPath = function (path) {
|
||||
"use strict";
|
||||
|
||||
this.path = path;
|
||||
|
||||
return this;
|
||||
};
|
||||
D3D.Path.prototype.union = function (path) {
|
||||
"use strict";
|
||||
|
||||
var solution = new ClipperLib.Paths();
|
||||
|
||||
var clipper = new ClipperLib.Clipper();
|
||||
clipper.AddPaths(this.path, ClipperLib.PolyType.ptSubject, this.closed);
|
||||
clipper.AddPaths(path.path, ClipperLib.PolyType.ptClip, path.closed);
|
||||
clipper.Execute(ClipperLib.ClipType.ctUnion, solution);
|
||||
|
||||
return new D3D.Path(solution, this.closed);
|
||||
};
|
||||
D3D.Path.prototype.difference = function (path) {
|
||||
"use strict";
|
||||
|
||||
var solution = new ClipperLib.Paths();
|
||||
|
||||
var clipper = new ClipperLib.Clipper();
|
||||
clipper.AddPaths(this.path, ClipperLib.PolyType.ptSubject, this.closed);
|
||||
clipper.AddPaths(path.path, ClipperLib.PolyType.ptClip, path.closed);
|
||||
clipper.Execute(ClipperLib.ClipType.ctDifference, solution);
|
||||
|
||||
return new D3D.Path(solution, this.closed);
|
||||
};
|
||||
D3D.Path.prototype.intersect = function (path) {
|
||||
"use strict";
|
||||
|
||||
var solution = new ClipperLib.Paths();
|
||||
|
||||
var clipper = new ClipperLib.Clipper();
|
||||
clipper.AddPaths(this.path, ClipperLib.PolyType.ptSubject, this.closed);
|
||||
clipper.AddPaths(path.path, ClipperLib.PolyType.ptClip, path.closed);
|
||||
clipper.Execute(ClipperLib.ClipType.ctIntersection, solution);
|
||||
|
||||
return new D3D.Path(solution, this.closed);
|
||||
};
|
||||
D3D.Path.prototype.xor = function () {
|
||||
"use strict";
|
||||
|
||||
var solution = new ClipperLib.Paths();
|
||||
|
||||
var clipper = new ClipperLib.Clipper();
|
||||
clipper.AddPaths(this.path, ClipperLib.PolyType.ptSubject, this.closed);
|
||||
clipper.AddPaths(path.path, ClipperLib.PolyType.ptClip, path.closed);
|
||||
clipper.Execute(ClipperLib.ClipType.ctXor, solution);
|
||||
|
||||
return new D3D.Path(solution, this.closed);
|
||||
};
|
||||
D3D.Path.prototype.offset = function (offset) {
|
||||
"use strict";
|
||||
|
||||
var solution = new ClipperLib.Paths();
|
||||
var co = new ClipperLib.ClipperOffset(1, 1);
|
||||
co.AddPaths(this.path, ClipperLib.JoinType.jtRound, ClipperLib.EndType.etClosedPolygon);
|
||||
co.Execute(solution, offset);
|
||||
|
||||
return new D3D.Path(solution, this.closed);
|
||||
};
|
||||
D3D.Path.prototype.scaleUp = function (factor) {
|
||||
"use strict";
|
||||
|
||||
var path = ClipperLib.JS.ScaleUpPaths(this.path, factor);
|
||||
|
||||
return this;
|
||||
};
|
||||
D3D.Path.prototype.scaleDown = function (factor) {
|
||||
"use strict";
|
||||
|
||||
var path = ClipperLib.JS.ScaleDownPaths(this.path, factor);
|
||||
|
||||
return this;
|
||||
};
|
||||
D3D.Path.prototype.tresholdArea = function (minArea) {
|
||||
"use strict";
|
||||
|
||||
for (var i = 0; i < this.path.length; i ++) {
|
||||
var shape = this.path[i];
|
||||
|
||||
var area = ClipperLib.Clipper.Area(shape);
|
||||
|
||||
if (area < minArea) {
|
||||
this.path.splice(i, 1);
|
||||
i --;
|
||||
}
|
||||
}
|
||||
|
||||
return areas;
|
||||
};
|
||||
D3D.Path.prototype.area = function () {
|
||||
"use strict";
|
||||
|
||||
var areas = [];
|
||||
|
||||
for (var i = 0; i < this.path.length; i ++) {
|
||||
var shape = this.path[i];
|
||||
|
||||
areas.push(ClipperLib.Clipper.Area(shape))
|
||||
}
|
||||
|
||||
return areas;
|
||||
};
|
||||
D3D.Path.prototype.join = function (path) {
|
||||
"use strict";
|
||||
|
||||
this.path = this.path.concat(path.path);
|
||||
|
||||
return this;
|
||||
}
|
||||
D3D.Path.prototype.clone = function () {
|
||||
"use strict";
|
||||
|
||||
var path = ClipperLib.JS.Clone(this.path);
|
||||
|
||||
return new D3D.Path(path, this.closed);
|
||||
}
|
||||
D3D.Path.prototype.draw = function (context, color) {
|
||||
"use strict";
|
||||
|
||||
context.strokeStyle = color;
|
||||
for (var i = 0; i < this.path.length; i ++) {
|
||||
var shape = this.path[i];
|
||||
|
||||
context.beginPath();
|
||||
var length = this.closed ? (shape.length + 1) : shape.length;
|
||||
for (var j = 0; j < length; j ++) {
|
||||
var point = shape[j % shape.length];
|
||||
|
||||
context.lineTo(point.X*2, point.Y*2);
|
||||
}
|
||||
context.stroke();
|
||||
}
|
||||
};
|
263
src/slicer.js
263
src/slicer.js
@ -23,12 +23,11 @@ D3D.Slicer.prototype.setMesh = function (mesh) {
|
||||
mesh.updateMatrix();
|
||||
|
||||
var geometry = mesh.geometry.clone();
|
||||
geometry.mergeVertices();
|
||||
geometry.applyMatrix(mesh.matrix);
|
||||
|
||||
if (geometry instanceof THREE.BufferGeometry) {
|
||||
geometry = new THREE.Geometry().fromBufferGeometry(geometry);
|
||||
}
|
||||
geometry.mergeVertices();
|
||||
geometry.applyMatrix(mesh.matrix);
|
||||
|
||||
this.geometry = geometry;
|
||||
|
||||
@ -55,7 +54,8 @@ D3D.Slicer.prototype.createLines = function () {
|
||||
self.lines.push({
|
||||
line: new THREE.Line3(self.geometry.vertices[a], self.geometry.vertices[b]),
|
||||
connects: [],
|
||||
normals: []
|
||||
normals: [],
|
||||
ignore: 0
|
||||
});
|
||||
}
|
||||
|
||||
@ -80,6 +80,12 @@ D3D.Slicer.prototype.createLines = function () {
|
||||
this.lines[a].normals.push(normal);
|
||||
this.lines[b].normals.push(normal);
|
||||
this.lines[c].normals.push(normal);
|
||||
|
||||
if (face.normal.y === 1 || face.normal.y === -1) {
|
||||
this.lines[a].ignore ++;
|
||||
this.lines[b].ignore ++;
|
||||
this.lines[c].ignore ++;
|
||||
}
|
||||
}
|
||||
};
|
||||
D3D.Slicer.prototype.slice = function (height, step) {
|
||||
@ -93,12 +99,14 @@ D3D.Slicer.prototype.slice = function (height, step) {
|
||||
var min = Math.ceil(Math.min(line.line.start.y, line.line.end.y) / step);
|
||||
var max = Math.floor(Math.max(line.line.start.y, line.line.end.y) / step);
|
||||
|
||||
for (var layerIndex = min; layerIndex <= max; layerIndex ++) {
|
||||
if (layerIndex >= 0) {
|
||||
if (layersIntersections[layerIndex] === undefined) {
|
||||
layersIntersections[layerIndex] = [];
|
||||
if (line.ignore < 2) {
|
||||
for (var layerIndex = min; layerIndex <= max; layerIndex ++) {
|
||||
if (layerIndex >= 0) {
|
||||
if (layersIntersections[layerIndex] === undefined) {
|
||||
layersIntersections[layerIndex] = [];
|
||||
}
|
||||
layersIntersections[layerIndex].push(i);
|
||||
}
|
||||
layersIntersections[layerIndex].push(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -115,8 +123,8 @@ D3D.Slicer.prototype.slice = function (height, step) {
|
||||
var line = this.lines[index].line;
|
||||
|
||||
var alpha = (y - line.start.y) / (line.end.y - line.start.y);
|
||||
var x = line.start.x * alpha + line.end.x * (1 - alpha);
|
||||
var z = line.start.z * alpha + line.end.z * (1 - alpha);
|
||||
var x = line.end.x * alpha + line.start.x * (1 - alpha);
|
||||
var z = line.end.z * alpha + line.start.z * (1 - alpha);
|
||||
|
||||
intersections[index] = new THREE.Vector2(x, z);
|
||||
}
|
||||
@ -190,7 +198,8 @@ D3D.Slicer.prototype.slice = function (height, step) {
|
||||
|
||||
//stop when ther are no intersects
|
||||
if (slice.length > 0) {
|
||||
slices.push(slice);
|
||||
slices.push(new D3D.Path(slice, true));
|
||||
//slices.push(slice);
|
||||
}
|
||||
else {
|
||||
break;
|
||||
@ -199,20 +208,65 @@ D3D.Slicer.prototype.slice = function (height, step) {
|
||||
|
||||
return slices;
|
||||
};
|
||||
D3D.Slicer.prototype.getInset = function (slice, offset) {
|
||||
D3D.Slicer.prototype.slicesToData = function (slices, printer) {
|
||||
"use strict";
|
||||
|
||||
var solution = new ClipperLib.Paths();
|
||||
var co = new ClipperLib.ClipperOffset(1, 1);
|
||||
co.AddPaths(slice, ClipperLib.JoinType.jtRound, ClipperLib.EndType.etClosedPolygon);
|
||||
co.Execute(solution, -offset);
|
||||
var scale = 100;
|
||||
|
||||
return solution;
|
||||
var layerHeight = printer.config["printer.layerHeight"] * scale;
|
||||
var dimensionsZ = printer.config["printer.dimensions.z"] * scale;
|
||||
var wallThickness = printer.config["printer.wallThickness"] * scale;
|
||||
var shellThickness = printer.config["printer.shellThickness"] * scale;
|
||||
var fillSize = printer.config["printer.fillSize"] * scale;
|
||||
var brimOffset = printer.config["printer.brimOffset"] * scale;
|
||||
var skinCount = Math.ceil(shellThickness/layerHeight);
|
||||
|
||||
var data = [];
|
||||
|
||||
var lowFillTemplate = this.getFillTemplate(dimensionsZ, fillSize, true, true);
|
||||
|
||||
for (var layer = 0; layer < slices.length; layer ++) {
|
||||
var slice = slices[layer];
|
||||
|
||||
var outerLayer = slice.clone();
|
||||
outerLayer.scaleUp(scale);
|
||||
|
||||
var insets = new D3D.Path();
|
||||
for (var offset = wallThickness; offset <= shellThickness; offset += wallThickness) {
|
||||
var inset = outerLayer.offset(-offset);
|
||||
|
||||
insets.join(inset);
|
||||
}
|
||||
|
||||
var fillArea = (inset || outerLayer).offset(-wallThickness/2);
|
||||
|
||||
var downFill = (layer - skinCount >= 0) ? slices[layer - skinCount] : new D3D.Path();
|
||||
var upFill = (layer + skinCount < slices.length) ? slices[layer + skinCount] : new D3D.Path();
|
||||
var highFillArea = fillArea.difference(downFill.intersect(upFill).scaleUp(scale));
|
||||
|
||||
var lowFillArea = fillArea.difference(highFillArea);
|
||||
|
||||
var fill = new D3D.Path([], false);
|
||||
fill.join(lowFillTemplate.intersect(lowFillArea));
|
||||
if (highFillArea.path.length > 0) {
|
||||
var highFillTemplate = this.getFillTemplate(dimensionsZ, wallThickness, (layer % 2 === 0), (layer % 2 === 1));
|
||||
var highFillStrokes = highFillArea;
|
||||
fill.join(highFillTemplate.intersect(highFillStrokes));
|
||||
}
|
||||
|
||||
data.push({
|
||||
outerLayer: outerLayer.scaleDown(scale),
|
||||
insets: insets.scaleDown(scale),
|
||||
fill: fill.scaleDown(scale)
|
||||
});
|
||||
}
|
||||
|
||||
return data;
|
||||
};
|
||||
D3D.Slicer.prototype.getFillTemplate = function (dimension, size, even, uneven) {
|
||||
"use strict";
|
||||
|
||||
var paths = new ClipperLib.Paths();
|
||||
var paths = [];
|
||||
|
||||
if (even) {
|
||||
for (var length = 0; length <= dimension; length += size) {
|
||||
@ -225,125 +279,8 @@ D3D.Slicer.prototype.getFillTemplate = function (dimension, size, even, uneven)
|
||||
}
|
||||
}
|
||||
|
||||
return paths;
|
||||
};
|
||||
D3D.Slicer.prototype.slicesToData = function (slices, printer) {
|
||||
"use strict";
|
||||
|
||||
//scale because of clipper crap
|
||||
var scale = 100;
|
||||
|
||||
var layerHeight = printer.config["printer.layerHeight"] * scale;
|
||||
var dimensionsZ = printer.config["printer.dimensions.z"] * scale;
|
||||
var wallThickness = printer.config["printer.wallThickness"] * scale;
|
||||
var shellThickness = printer.config["printer.shellThickness"] * scale;
|
||||
var fillSize = printer.config["printer.fillSize"] * scale;
|
||||
var brimOffset = printer.config["printer.brimOffset"] * scale;
|
||||
|
||||
var data = [];
|
||||
|
||||
var lowFillTemplate = this.getFillTemplate(dimensionsZ, fillSize, true, true);
|
||||
|
||||
for (var layer = 0; layer < slices.length; layer ++) {
|
||||
var slice = slices[layer];
|
||||
|
||||
//var outerLayer = ClipperLib.JS.Clean(slice, 1.0);
|
||||
var outerLayer = slice.clone();
|
||||
ClipperLib.JS.ScaleUpPaths(outerLayer, scale);
|
||||
|
||||
var innerLayer = [];
|
||||
|
||||
for (var i = wallThickness; i < shellThickness; i += wallThickness) {
|
||||
var inset = this.getInset(outerLayer, i);
|
||||
|
||||
innerLayer = innerLayer.concat(inset);
|
||||
}
|
||||
|
||||
//moet fillArea wel kleiner?
|
||||
//var fillArea = this.getInset((inset || outerLayer), wallThickness);
|
||||
var fillArea = (inset || outerLayer);
|
||||
|
||||
var fillAbove = false;
|
||||
//for (var i = 1; i < shellThickness/layerHeight; i ++) {
|
||||
for (var i = 1; i < shellThickness/layerHeight; i ++) {
|
||||
var newLayer = ClipperLib.JS.Clone(slices[layer + i]);
|
||||
ClipperLib.JS.ScaleUpPaths(newLayer, scale);
|
||||
|
||||
if (newLayer.length === 0 || (fillAbove && fillAbove.length === 0)) {
|
||||
fillAbove = [];
|
||||
|
||||
break;
|
||||
}
|
||||
else if (fillAbove === false) {
|
||||
fillAbove = newLayer;
|
||||
}
|
||||
else {
|
||||
var c = new ClipperLib.Clipper();
|
||||
var solution = new ClipperLib.Paths();
|
||||
c.AddPaths(newLayer, ClipperLib.PolyType.ptSubject, true);
|
||||
c.AddPaths(fillAbove, ClipperLib.PolyType.ptClip, true);
|
||||
c.Execute(ClipperLib.ClipType.ctIntersection, solution);
|
||||
|
||||
fillAbove = solution;
|
||||
}
|
||||
}
|
||||
//kijkt alleen nog naar boven
|
||||
//omliggende lagen hebben inhoud van lowFill;
|
||||
//inset moet opgevult worden;
|
||||
//verschill tussen lowFill en inset moet vol, rest is raster
|
||||
|
||||
var clipper = new ClipperLib.Clipper();
|
||||
var highFillArea = new ClipperLib.Paths();
|
||||
clipper.AddPaths(fillArea, ClipperLib.PolyType.ptSubject, true);
|
||||
clipper.AddPaths(fillAbove, ClipperLib.PolyType.ptClip, true);
|
||||
clipper.Execute(ClipperLib.ClipType.ctDifference, highFillArea);
|
||||
|
||||
var clipper = new ClipperLib.Clipper();
|
||||
var lowFillArea = new ClipperLib.Paths();
|
||||
clipper.AddPaths(fillArea, ClipperLib.PolyType.ptSubject, true);
|
||||
clipper.AddPaths(highFillArea, ClipperLib.PolyType.ptClip, true);
|
||||
clipper.Execute(ClipperLib.ClipType.ctDifference, lowFillArea);
|
||||
|
||||
var fill = [];
|
||||
|
||||
var clipper = new ClipperLib.Clipper();
|
||||
var lowFillStrokes = new ClipperLib.Paths();
|
||||
clipper.AddPaths(lowFillTemplate, ClipperLib.PolyType.ptSubject, false);
|
||||
clipper.AddPaths(lowFillArea, ClipperLib.PolyType.ptClip, true);
|
||||
clipper.Execute(ClipperLib.ClipType.ctIntersection, lowFillStrokes);
|
||||
|
||||
fill = fill.concat(lowFillStrokes);
|
||||
|
||||
//optimize
|
||||
//make as big as bounding box of highFillArea
|
||||
var highFillTemplate = this.getFillTemplate(dimensionsZ, wallThickness, (layer % 2 === 0), (layer % 2 === 1));
|
||||
|
||||
var clipper = new ClipperLib.Clipper();
|
||||
var highFillStrokes = new ClipperLib.Paths();
|
||||
clipper.AddPaths(highFillTemplate, ClipperLib.PolyType.ptSubject, false);
|
||||
clipper.AddPaths(highFillArea, ClipperLib.PolyType.ptClip, true);
|
||||
clipper.Execute(ClipperLib.ClipType.ctIntersection, highFillStrokes);
|
||||
|
||||
fill = fill.concat(highFillStrokes);
|
||||
|
||||
//create brim
|
||||
/*if (layer === 0) {
|
||||
var brim = this.getInset(outerLayer, -brimOffset);
|
||||
outerLayer = brim.concat(outerLayer);
|
||||
}*/
|
||||
|
||||
ClipperLib.JS.ScaleDownPaths(outerLayer, scale);
|
||||
ClipperLib.JS.ScaleDownPaths(innerLayer, scale);
|
||||
ClipperLib.JS.ScaleDownPaths(fill, scale);
|
||||
|
||||
data.push({
|
||||
outerLayer: outerLayer,
|
||||
innerLayer: innerLayer,
|
||||
fill: fill
|
||||
});
|
||||
}
|
||||
|
||||
return data;
|
||||
//return paths;
|
||||
return new D3D.Path(paths, false);
|
||||
};
|
||||
D3D.Slicer.prototype.dataToGcode = function (data, printer) {
|
||||
"use strict";
|
||||
@ -365,8 +302,8 @@ D3D.Slicer.prototype.dataToGcode = function (data, printer) {
|
||||
function sliceToGcode (slice) {
|
||||
var gcode = [];
|
||||
|
||||
for (var i = 0; i < slice.length; i ++) {
|
||||
var shape = slice[i];
|
||||
for (var i = 0; i < slice.path.length; i ++) {
|
||||
var shape = slice.path[i];
|
||||
|
||||
var previousPoint;
|
||||
|
||||
@ -440,54 +377,20 @@ D3D.Slicer.prototype.dataToGcode = function (data, printer) {
|
||||
var z = ((layer + 1) * layerHeight).toFixed(3);
|
||||
|
||||
gcode = gcode.concat(sliceToGcode(slice.outerLayer));
|
||||
gcode = gcode.concat(sliceToGcode(slice.innerLayer));
|
||||
gcode = gcode.concat(sliceToGcode(slice.insets));
|
||||
gcode = gcode.concat(sliceToGcode(slice.fill));
|
||||
}
|
||||
|
||||
gcode = gcode.concat(printer.getEndCode());
|
||||
return gcode;
|
||||
};
|
||||
//only for debug purposes
|
||||
D3D.Slicer.prototype.drawPaths = function (printer, min, max) {
|
||||
"use strict";
|
||||
|
||||
var layerHeight = printer.config["printer.layerHeight"];
|
||||
var dimensionsZ = printer.config["printer.dimensions.z"];
|
||||
|
||||
function drawLines (paths, color) {
|
||||
context.fillStyle = color;
|
||||
context.strokeStyle = color;
|
||||
context.beginPath();
|
||||
|
||||
for (var i = 0; i < paths.length; i ++) {
|
||||
var path = paths[i];
|
||||
|
||||
context.moveTo((path[0].X * 2), (path[0].Y * 2));
|
||||
|
||||
for (var j = 0; j < path.length; j ++) {
|
||||
var point = path[j];
|
||||
context.lineTo((point.X * 2), (point.Y * 2));
|
||||
}
|
||||
//context.closePath();
|
||||
}
|
||||
context.stroke();
|
||||
}
|
||||
|
||||
function drawVertexes (paths, color) {
|
||||
context.fillStyle = color;
|
||||
context.strokeStyle = color;
|
||||
|
||||
for (var i = 0; i < paths.length; i ++) {
|
||||
var path = paths[i];
|
||||
|
||||
for (var j = 0; j < path.length; j ++) {
|
||||
var point = path[j];
|
||||
context.beginPath();
|
||||
context.arc(point.X * 2, point.Y * 2, 1, 0, Math.PI*2, false);
|
||||
context.stroke();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var slices = this.slice(dimensionsZ, layerHeight);
|
||||
|
||||
var data = this.slicesToData(slices, printer);
|
||||
@ -500,11 +403,9 @@ D3D.Slicer.prototype.drawPaths = function (printer, min, max) {
|
||||
for (var layer = min; layer < max; layer ++) {
|
||||
var slice = data[layer % data.length];
|
||||
|
||||
drawLines(slice.outerLayer, "red");
|
||||
drawLines(slice.innerLayer, "green");
|
||||
drawLines(slice.fill, "blue");
|
||||
|
||||
drawVertexes(slice.outerLayer, "green");
|
||||
slice.insets.draw(context, "blue");
|
||||
slice.outerLayer.draw(context, "green");
|
||||
slice.fill.draw(context, "red");
|
||||
}
|
||||
|
||||
return canvas;
|
||||
|
57
src/utils.js
57
src/utils.js
@ -88,59 +88,4 @@ Array.prototype.clone = function () {
|
||||
}
|
||||
|
||||
return array;
|
||||
};
|
||||
|
||||
function applyMouseControls (renderer, camera, center, maxDistance) {
|
||||
"use strict";
|
||||
//TODO
|
||||
//impliment touch controls
|
||||
//windows mouse wheel fix
|
||||
|
||||
var distance = 20;
|
||||
var rotX = 0;
|
||||
var rotY = 0;
|
||||
var moveCamera = false;
|
||||
|
||||
function updateCamera () {
|
||||
camera.position.set(
|
||||
Math.cos(rotY)*Math.sin(rotX)*distance,
|
||||
Math.sin(rotY)*distance,
|
||||
Math.cos(rotY)*Math.cos(rotX)*distance
|
||||
).add(center);
|
||||
camera.lookAt(center);
|
||||
}
|
||||
|
||||
$(renderer.domElement).on("mousedown", function (e) {
|
||||
moveCamera = true;
|
||||
}).on("wheel", function (e) {
|
||||
var event = e.originalEvent;
|
||||
|
||||
event.preventDefault();
|
||||
distance = THREE.Math.clamp(distance - event.wheelDelta, 1, maxDistance);
|
||||
|
||||
updateCamera();
|
||||
});
|
||||
|
||||
$(window).on("mouseup", function (e) {
|
||||
moveCamera = false;
|
||||
}).on("mousemove", function (e) {
|
||||
var event = e.originalEvent;
|
||||
|
||||
if (moveCamera === true) {
|
||||
rotX = (rotX - event.webkitMovementX/100) % (2*Math.PI);
|
||||
rotY = THREE.Math.clamp(rotY + event.webkitMovementY/100, -Math.PI/2, Math.PI/2);
|
||||
|
||||
updateCamera();
|
||||
}
|
||||
});
|
||||
|
||||
updateCamera();
|
||||
}
|
||||
|
||||
var requestAnimFrame = (function () {
|
||||
"use strict";
|
||||
|
||||
return requestAnimationFrame || webkitRequestAnimationFrame || mozRequestAnimationFrame || function (callback) {
|
||||
setTimeout(callback, 1000/60);
|
||||
};
|
||||
})();
|
||||
};
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user