From 3a41b73c755159ace2f221e0f7d16710ebef1191 Mon Sep 17 00:00:00 2001 From: casperlamboo Date: Wed, 13 May 2015 12:12:15 +0200 Subject: [PATCH 1/3] Implemented new layer part structure --- gulpfile.js | 1 + library/clipper.js | 8 +-- models/cube.stl | Bin 0 -> 684 bytes slice_test.html | 16 ++++- src/path.js | 99 +++++++++++++---------------- src/paths.js | 151 +++++++++++++++++++++++++++++++++++++++++++++ src/slicer.js | 113 +++++++++++++++++---------------- 7 files changed, 273 insertions(+), 115 deletions(-) create mode 100644 models/cube.stl create mode 100644 src/paths.js diff --git a/gulpfile.js b/gulpfile.js index e9b67c5..84e4a3f 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -10,6 +10,7 @@ var files = [ "src/utils.js", "src/box.js", "src/printer.js", + "src/paths.js", "src/path.js", "src/slicer.js" ]; diff --git a/library/clipper.js b/library/clipper.js index 5fb0652..7bc31a1 100755 --- a/library/clipper.js +++ b/library/clipper.js @@ -3100,7 +3100,7 @@ if (this.m_ExecuteLocked) return false; if (this.m_HasOpenPaths) - //ClipperLib.Error("Error: PolyTree struct is need for open path clipping."); + ClipperLib.Error("Error: PolyTree struct is need for open path clipping."); this.m_ExecuteLocked = true; ClipperLib.Clear(solution); this.m_SubjFillType = subjFillType; @@ -4884,8 +4884,8 @@ else ClipperLib.Clipper.Round = R2; // eg. browser.chrome || browser.firefox || browser.opera ClipperLib.Clipper.TopX = function (edge, currentY) { - //if (edge.Bot == edge.Curr) alert ("edge.Bot = edge.Curr"); - //if (edge.Bot == edge.Top) alert ("edge.Bot = edge.Top"); + //if (edge.Bot == edge.Curr) console.log ("edge.Bot = edge.Curr"); + //if (edge.Bot == edge.Top) console.log ("edge.Bot = edge.Top"); if (currentY == edge.Top.Y) return edge.Top.X; return edge.Bot.X + ClipperLib.Clipper.Round(edge.Dx * (currentY - edge.Bot.Y)); @@ -6596,7 +6596,7 @@ } catch (err) { - alert(err.message); + console.log(err.message); } }; // --------------------------------- diff --git a/models/cube.stl b/models/cube.stl new file mode 100644 index 0000000000000000000000000000000000000000..660d4cd345a26dfcafbb09c453b684018683f266 GIT binary patch literal 684 zcmb7>I}XAy5JcV4a0r)BfDl5Wj6vceC_xlJq5x9LoPe6sfT`&@11F%yV|!#Lq+uJ6 zHv9H7Sye?|p0ZSK%6u=EyX=r=cqW`D&^)`!s`wq`a+r;Vq3qJ?~f_k6YPsztZ|dMqeUQRuT_x? zUb`8n;PnlEOcjDObO)i34_>vk+e(ODu}z+r*Dd&N`|97V=v73hW))_TrpD_64!|n} V{h_0DI^2OOOX%pY8I2%K{RNV?g8%>k literal 0 HcmV?d00001 diff --git a/slice_test.html b/slice_test.html index 3b09b8f..8a58699 100644 --- a/slice_test.html +++ b/slice_test.html @@ -11,6 +11,7 @@ + @@ -69,7 +70,7 @@ var printerConfig = { var printer = new D3D.Printer(printerConfig); var localIp = location.hash.substring(1); -var doodleBox = new D3D.Box(localIp); +//var doodleBox = new D3D.Box(localIp); //var printer = doodleBox.printer; var scene = new THREE.Scene(); @@ -115,20 +116,29 @@ mesh.position.z = 100; //scene.add(mesh); var loader = new THREE.STLLoader(); -loader.load("models/cubes.stl", function (geometry) { +loader.load("models/cube.stl", function (geometry) { + var geometry = new THREE.BoxGeometry(10, 10, 10, 1, 1, 1); + 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 slicer = new D3D.Slicer().setMesh(mesh); + var canvas = document.getElementById("canvas"); + var context = canvas.getContext("2d"); + + var img = slicer.drawPaths(printer, 0, 1); + context.drawImage(img, 0, 0); + gcode = slicer.getGcode(printer); }); diff --git a/src/path.js b/src/path.js index f0fbb59..9781526 100644 --- a/src/path.js +++ b/src/path.js @@ -9,98 +9,93 @@ D3D.Path = function (path, closed) { "use strict"; - this.path = path || []; + Array.call(this); + + this.setPath(path || []); + this.closed = (closed !== undefined) ? closed : true; }; +D3D.Path.prototype = Object.create(Array.prototype); D3D.Path.prototype.setPath = function (path) { "use strict"; - this.path = path; + for (var i = 0; i < path.length; i ++) { + this.push(path[i]); + } return this; }; +D3D.Path.prototype.clip = function (path, type) { + "use strict"; + + var solution = new ClipperLib.Paths(); + + var clipper = new ClipperLib.Clipper(); + clipper.AddPath(this, ClipperLib.PolyType.ptSubject, true); + if (path instanceof D3D.Path) { + clipper.AddPath(path, ClipperLib.PolyType.ptClip, true); + } + else if (path instanceof D3D.Paths) { + clipper.AddPaths(path, ClipperLib.PolyType.ptClip, true); + } + clipper.Execute(type, solution); + + return new D3D.Paths(solution, this.closed); +}; 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); + return this.clip(path, ClipperLib.ClipType.ctUnion); }; 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); + return this.clip(path, ClipperLib.ClipType.ctDifference); }; 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); + return this.clip(path, ClipperLib.ClipType.ctIntersection); }; 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); + return this.clip(path, ClipperLib.ClipType.ctXor); }; 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); + var solution = new ClipperLib.Path(); + var co = new ClipperLib.ClipperOffset(2, 0.25); + co.AddPath(this, ClipperLib.JoinType.jtRound, ClipperLib.EndType.etClosedPolygon); co.Execute(solution, offset); - return new D3D.Path(solution, this.closed); + return new D3D.Path(solution[0], this.closed); }; D3D.Path.prototype.scaleUp = function (factor) { "use strict"; - var path = ClipperLib.JS.ScaleUpPaths(this.path, factor); + ClipperLib.JS.ScaleUpPath(this, factor); return this; }; D3D.Path.prototype.scaleDown = function (factor) { "use strict"; - var path = ClipperLib.JS.ScaleDownPaths(this.path, factor); + var path = ClipperLib.JS.ScaleDownPath(this, 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]; + for (var i = 0; i < this.length; i ++) { + var shape = this[i]; var area = ClipperLib.Clipper.Area(shape); if (area < minArea) { - this.path.splice(i, 1); + this.splice(i, 1); i --; } } @@ -110,27 +105,19 @@ D3D.Path.prototype.tresholdArea = function (minArea) { 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; + return ClipperLib.Clipper.Area(this); }; D3D.Path.prototype.join = function (path) { "use strict"; - this.path = this.path.concat(path.path); + this.setPath(this.concat(path)); return this; } D3D.Path.prototype.clone = function () { "use strict"; - var path = ClipperLib.JS.Clone(this.path); + var path = ClipperLib.JS.Clone(this); return new D3D.Path(path, this.closed); } @@ -138,8 +125,8 @@ 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]; + for (var i = 0; i < this.length; i ++) { + var shape = this[i]; context.beginPath(); var length = this.closed ? (shape.length + 1) : shape.length; diff --git a/src/paths.js b/src/paths.js new file mode 100644 index 0000000..9736c05 --- /dev/null +++ b/src/paths.js @@ -0,0 +1,151 @@ +/****************************************************** +* +* Path +* +* Abstraction layer for annoying clipper js +* +******************************************************/ + +D3D.Paths = function (paths) { + "use strict"; + + Array.call(this); + + this.setPaths(paths || []); + + this.closed = (this[0] !== undefined) ? this[0].closed : true; +}; +D3D.Paths.prototype = Object.create(Array.prototype); +D3D.Paths.prototype.setPaths = function (paths) { + "use strict"; + + for (var i = 0; i < paths.length; i ++) { + var path = paths[i]; + if (!(path instanceof D3D.Path)) { + //console.log("Path not instance of D3D.Path, converting path to D3D.Path"); + path = new D3D.Path(path, true); + } + this.push(path); + } + + return this; +}; +D3D.Paths.prototype.clip = function (path, type) { + "use strict"; + + var solution = new ClipperLib.Paths(); + + var clipper = new ClipperLib.Clipper(); + clipper.AddPaths(this, ClipperLib.PolyType.ptSubject, this.closed); + if (path instanceof D3D.Paths) { + clipper.AddPaths(path, ClipperLib.PolyType.ptClip, path.closed); + } + else if (path instanceof D3D.Path) { + clipper.AddPath(path, ClipperLib.PolyType.ptClip, path.closed); + } + clipper.Execute(type, solution); + + return new D3D.Paths(solution); +}; +D3D.Paths.prototype.union = function (path) { + "use strict"; + + return this.clip(path, ClipperLib.ClipType.ctUnion); +}; +D3D.Paths.prototype.difference = function (path) { + "use strict"; + + return this.clip(path, ClipperLib.ClipType.ctDifference); +}; +D3D.Paths.prototype.intersect = function (path) { + "use strict"; + + return this.clip(path, ClipperLib.ClipType.ctIntersection); +}; +D3D.Paths.prototype.xor = function () { + "use strict"; + + return this.clip(path, ClipperLib.ClipType.ctXor); +}; +D3D.Paths.prototype.offset = function (offset) { + "use strict"; + + var solution = new ClipperLib.Paths(); + var co = new ClipperLib.ClipperOffset(1, 1); + co.AddPaths(this, ClipperLib.JoinType.jtRound, ClipperLib.EndType.etClosedPolygon); + co.Execute(solution, offset); + + return new D3D.Paths(solution); +}; +D3D.Paths.prototype.scaleUp = function (factor) { + "use strict"; + + var path = ClipperLib.JS.ScaleUpPaths(this, factor); + + return this; +}; +D3D.Paths.prototype.scaleDown = function (factor) { + "use strict"; + + var path = ClipperLib.JS.ScaleDownPaths(this, factor); + + return this; +}; +D3D.Paths.prototype.tresholdArea = function (minArea) { + "use strict"; + + for (var i = 0; i < this.length; i ++) { + var shape = this[i]; + + var area = ClipperLib.Clipper.Area(shape); + + if (area < minArea) { + this.splice(i, 1); + i --; + } + } + + return areas; +}; +D3D.Paths.prototype.area = function () { + "use strict"; + + return ClipperLib.Clipper.Area(this); +}; +D3D.Paths.prototype.join = function (path) { + "use strict"; + + for (var i = 0; i < path.length; i ++) { + this.push(path[i]); + } + + return this; +}; +D3D.Paths.prototype.clone = function () { + "use strict"; + + var paths = []; + + for (var i = 0; i < this.length; i ++) { + paths.push(this[i].clone()); + } + + return new D3D.Paths(paths); +}; +D3D.Paths.prototype.draw = function (context, color) { + "use strict"; + + context.strokeStyle = color; + for (var i = 0; i < this.length; i ++) { + var shape = this[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(); + } +}; \ No newline at end of file diff --git a/src/slicer.js b/src/slicer.js index fe8ccc9..bc91f4b 100644 --- a/src/slicer.js +++ b/src/slicer.js @@ -64,27 +64,24 @@ D3D.Slicer.prototype.createLines = function () { for (var i = 0; i < this.geometry.faces.length; i ++) { var face = this.geometry.faces[i]; - var normal = new THREE.Vector2().set(face.normal.x, face.normal.z).normalize(); - //check for only adding unique lines - //returns index of said line - var a = addLine(face.a, face.b); - var b = addLine(face.b, face.c); - var c = addLine(face.c, face.a); + if (!(face.normal.y === 1 || face.normal.y === -1)) { + var normal = new THREE.Vector2().set(face.normal.x, face.normal.z).normalize(); - //set connecting lines (based on face) - this.lines[a].connects.push(b, c); - this.lines[b].connects.push(c, a); - this.lines[c].connects.push(a, b); + //check for only adding unique lines + //returns index of said line + var a = addLine(face.a, face.b); + var b = addLine(face.b, face.c); + var c = addLine(face.c, face.a); - this.lines[a].normals.push(normal); - this.lines[b].normals.push(normal); - this.lines[c].normals.push(normal); + //set connecting lines (based on face) + this.lines[a].connects.push(b, c); + this.lines[b].connects.push(c, a); + this.lines[c].connects.push(a, b); - if (face.normal.y === 1 || face.normal.y === -1) { - this.lines[a].ignore ++; - this.lines[b].ignore ++; - this.lines[c].ignore ++; + this.lines[a].normals.push(normal); + this.lines[b].normals.push(normal); + this.lines[c].normals.push(normal); } } }; @@ -99,14 +96,12 @@ 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); - if (line.ignore < 2) { - for (var layerIndex = min; layerIndex <= max; layerIndex ++) { - if (layerIndex >= 0) { - if (layersIntersections[layerIndex] === undefined) { - layersIntersections[layerIndex] = []; - } - layersIntersections[layerIndex].push(i); + for (var layerIndex = min; layerIndex <= max; layerIndex ++) { + if (layerIndex >= 0) { + if (layersIntersections[layerIndex] === undefined) { + layersIntersections[layerIndex] = []; } + layersIntersections[layerIndex].push(i); } } } @@ -130,12 +125,12 @@ D3D.Slicer.prototype.slice = function (height, step) { } var done = []; - var slice = []; + var slice = new D3D.Paths([], true); for (var i = 0; i < layerIntersections.length; i ++) { var index = layerIntersections[i]; if (done.indexOf(index) === -1) { - var shape = []; + var shape = new D3D.Path([], true); while (index !== -1) { var intersection = intersections[index]; @@ -198,8 +193,7 @@ D3D.Slicer.prototype.slice = function (height, step) { //stop when ther are no intersects if (slice.length > 0) { - slices.push(new D3D.Path(slice, true)); - //slices.push(slice); + slices.push(slice); } else { break; @@ -228,36 +222,50 @@ D3D.Slicer.prototype.slicesToData = function (slices, printer) { for (var layer = 0; layer < slices.length; layer ++) { var slice = slices[layer]; - var outerLayer = slice.clone(); - outerLayer.scaleUp(scale); + var insets = new D3D.Paths(); + var fills = new D3D.Paths(); + var outerLayers = new D3D.Paths(); - var insets = new D3D.Path(); - for (var offset = wallThickness; offset <= shellThickness; offset += wallThickness) { - var inset = outerLayer.offset(-offset); + var downFill = (layer - skinCount >= 0) ? slices[layer - skinCount] : new D3D.Paths(); + var upFill = (layer + skinCount < slices.length) ? slices[layer + skinCount] : new D3D.Paths(); + //var surroundingLayer = downFill.intersect(upFill); + var surroundingLayer = upFill.clone().scaleUp(scale); + //D3D.Paths surroundingLayer - insets.join(inset); - } + for (var i = 0; i < slice.length; i ++) { + var part = slice[i]; - var fillArea = (inset || outerLayer).offset(-wallThickness/2); + var outerLayer = part.clone(); + outerLayer.scaleUp(scale); - 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)); + for (var offset = wallThickness; offset <= shellThickness; offset += wallThickness) { + var inset = outerLayer.offset(-offset); - var lowFillArea = fillArea.difference(highFillArea); + insets.push(inset); + } + + var fillArea = (inset || outerLayer).offset(-wallThickness/2); + + var highFillArea = fillArea.difference(surroundingLayer); + + var lowFillArea = fillArea.difference(highFillArea); + + var fill = new D3D.Paths([]); + + fills.join(lowFillTemplate.intersect(lowFillArea)); - 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)); + fills.join(highFillTemplate.intersect(highFillArea)); + + console.log(highFillTemplate.intersect(highFillArea)); + + outerLayers.push(outerLayer); } data.push({ - outerLayer: outerLayer.scaleDown(scale), + outerLayer: outerLayers.scaleDown(scale), insets: insets.scaleDown(scale), - fill: fill.scaleDown(scale) + fill: fills.scaleDown(scale) }); } @@ -270,17 +278,17 @@ D3D.Slicer.prototype.getFillTemplate = function (dimension, size, even, uneven) if (even) { for (var length = 0; length <= dimension; length += size) { - paths.push([{X: length, Y: 0}, {X: length, Y: dimension}]); + paths.push(new D3D.Path([{X: length, Y: 0}, {X: length, Y: dimension}], false)); } } if (uneven) { for (var length = 0; length <= dimension; length += size) { - paths.push([{X: 0, Y: length}, {X: dimension, Y: length}]); + paths.push(new D3D.Path([{X: 0, Y: length}, {X: dimension, Y: length}], false)); } } //return paths; - return new D3D.Path(paths, false); + return new D3D.Paths(paths); }; D3D.Slicer.prototype.dataToGcode = function (data, printer) { "use strict"; @@ -302,8 +310,8 @@ D3D.Slicer.prototype.dataToGcode = function (data, printer) { function sliceToGcode (slice) { var gcode = []; - for (var i = 0; i < slice.path.length; i ++) { - var shape = slice.path[i]; + for (var i = 0; i < slice.length; i ++) { + var shape = slice[i]; var previousPoint; @@ -429,6 +437,7 @@ D3D.Slicer.prototype.getGcode = function (printer) { var data = this.slicesToData(slices, printer); var end = new Date().getTime(); + console.log(data); console.log("Data: " + (end - start) + "ms"); //return data; From 5ac9364cc3d7033e5cba18241a629d4499f3b8c4 Mon Sep 17 00:00:00 2001 From: casperlamboo Date: Wed, 13 May 2015 13:18:37 +0200 Subject: [PATCH 2/3] step before layer part integration --- library/clipper.js | 24 +-- models/diamond.stl | 506 +++++++++++++++++++++++++++++++++++++++++++++ slice_test.html | 9 +- src/slicer.js | 6 +- 4 files changed, 526 insertions(+), 19 deletions(-) create mode 100755 models/diamond.stl diff --git a/library/clipper.js b/library/clipper.js index 7bc31a1..eb844d7 100755 --- a/library/clipper.js +++ b/library/clipper.js @@ -2876,8 +2876,8 @@ }; ClipperLib.ClipperBase.prototype.AddPaths = function (ppg, polyType, closed) { - // console.log("-------------------------------------------"); - // console.log(JSON.stringify(ppg)); + // console.warn("-------------------------------------------"); + // console.warn(JSON.stringify(ppg)); var result = false; for (var i = 0, ilen = ppg.length; i < ilen; ++i) if (this.AddPath(ppg[i], polyType, closed)) @@ -3100,7 +3100,7 @@ if (this.m_ExecuteLocked) return false; if (this.m_HasOpenPaths) - ClipperLib.Error("Error: PolyTree struct is need for open path clipping."); + //ClipperLib.Error("Error: PolyTree struct is need for open path clipping."); this.m_ExecuteLocked = true; ClipperLib.Clear(solution); this.m_SubjFillType = subjFillType; @@ -3185,7 +3185,7 @@ if (this.m_Scanbeam === null) break; var topY = this.PopScanbeam(); - //console.log("botY:" + botY + ", topY:" + topY); + //console.warn("botY:" + botY + ", topY:" + topY); if (!this.ProcessIntersections(botY, topY)) return false; this.ProcessEdgesAtTopOfScanbeam(topY); @@ -4747,7 +4747,7 @@ return; //prepare for sorting ... var e = this.m_ActiveEdges; - //console.log(JSON.stringify(JSON.decycle( e ))); + //console.warn(JSON.stringify(JSON.decycle( e ))); this.m_SortedEdges = e; while (e !== null) { @@ -4766,13 +4766,13 @@ { var eNext = e.NextInSEL; var pt = new ClipperLib.IntPoint(); - //console.log("e.Curr.X: " + e.Curr.X + " eNext.Curr.X" + eNext.Curr.X); + //console.warn("e.Curr.X: " + e.Curr.X + " eNext.Curr.X" + eNext.Curr.X); if (e.Curr.X > eNext.Curr.X) { if (!this.IntersectPoint(e, eNext, pt) && e.Curr.X > eNext.Curr.X + 1) { - //console.log("e.Curr.X: "+JSON.stringify(JSON.decycle( e.Curr.X ))); - //console.log("eNext.Curr.X+1: "+JSON.stringify(JSON.decycle( eNext.Curr.X+1))); + //console.warn("e.Curr.X: "+JSON.stringify(JSON.decycle( e.Curr.X ))); + //console.warn("eNext.Curr.X+1: "+JSON.stringify(JSON.decycle( eNext.Curr.X+1))); ClipperLib.Error("Intersection error"); } if (pt.Y > botY) @@ -4884,8 +4884,8 @@ else ClipperLib.Clipper.Round = R2; // eg. browser.chrome || browser.firefox || browser.opera ClipperLib.Clipper.TopX = function (edge, currentY) { - //if (edge.Bot == edge.Curr) console.log ("edge.Bot = edge.Curr"); - //if (edge.Bot == edge.Top) console.log ("edge.Bot = edge.Top"); + //if (edge.Bot == edge.Curr) console.warn ("edge.Bot = edge.Curr"); + //if (edge.Bot == edge.Top) console.warn ("edge.Bot = edge.Top"); if (currentY == edge.Top.Y) return edge.Top.X; return edge.Bot.X + ClipperLib.Clipper.Round(edge.Dx * (currentY - edge.Bot.Y)); @@ -6469,7 +6469,7 @@ if (solution.length > 0) solution.splice(0, 1); } - //console.log(JSON.stringify(solution)); + //console.warn(JSON.stringify(solution)); } else // function (polytree, delta) { @@ -6596,7 +6596,7 @@ } catch (err) { - console.log(err.message); + console.warn(err.message); } }; // --------------------------------- diff --git a/models/diamond.stl b/models/diamond.stl new file mode 100755 index 0000000..c46c44c --- /dev/null +++ b/models/diamond.stl @@ -0,0 +1,506 @@ +solid OpenSCAD_Model + facet normal 0 0 0 + outer loop + vertex 24 0 45.03 + vertex 12 0 54.03 + vertex 20.7846 -12 45.03 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex 8.48528 8.48528 54.03 + vertex 12 0 54.03 + vertex 20.7846 12 45.03 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex -12 -20.7846 45.03 + vertex -20.7846 -12 45 + vertex -12 -20.7846 45 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex -12 1.46953e-015 54.03 + vertex 8.48528 8.48528 54.03 + vertex 7.34764e-016 12 54.03 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex 12 0 54.03 + vertex -8.48528 -8.48528 54.03 + vertex 8.48528 -8.48528 54.03 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex 12 0 54.03 + vertex 8.48528 -8.48528 54.03 + vertex 20.7846 -12 45.03 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex 12 0 54.03 + vertex 8.48528 8.48528 54.03 + vertex -8.48528 -8.48528 54.03 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex 7.34764e-016 12 54.03 + vertex 1.46953e-015 24 45.03 + vertex -12 20.7846 45.03 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex 12 20.7846 45.03 + vertex 20.7846 12 45 + vertex 12 20.7846 45 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex 7.34764e-016 12 54.03 + vertex 8.48528 8.48528 54.03 + vertex 12 20.7846 45.03 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex -0.15 -0.259808 15 + vertex 0.15 0.259808 15 + vertex 0.15 -0.259808 15 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex 20.7846 -12 45.03 + vertex 12 -20.7846 45 + vertex 20.7846 -12 45 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex -12 1.46953e-015 54.03 + vertex -20.7846 12 45.03 + vertex -24 2.93906e-015 45.03 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex -24 2.93906e-015 45.03 + vertex -20.7846 -12 45 + vertex -20.7846 -12 45.03 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex 8.48528 8.48528 54.03 + vertex 20.7846 12 45.03 + vertex 12 20.7846 45.03 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex -20.7846 -12 45 + vertex -12 -20.7846 45.03 + vertex -20.7846 -12 45.03 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex -0.15 0.259808 15 + vertex -12 20.7846 45 + vertex 1.46953e-015 24 45 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex 0.15 0.259808 15 + vertex 20.7846 12 45 + vertex 0.3 0 15 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex -2.20429e-015 -12 54.03 + vertex -4.40858e-015 -24 45.03 + vertex 12 -20.7846 45.03 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex -2.20429e-015 -12 54.03 + vertex -8.48528 -8.48528 54.03 + vertex -12 -20.7846 45.03 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex -24 2.93906e-015 45 + vertex -20.7846 12 45.03 + vertex -20.7846 12 45 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex -0.15 0.259808 15 + vertex -0.15 -0.259808 15 + vertex -0.3 3.67382e-017 15 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex 20.7846 12 45 + vertex 20.7846 12 45.03 + vertex 24 0 45.03 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex 20.7846 12 45.03 + vertex 12 0 54.03 + vertex 24 0 45.03 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex -8.48528 -8.48528 54.03 + vertex 8.48528 8.48528 54.03 + vertex -12 1.46953e-015 54.03 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex 20.7846 12 45.03 + vertex 20.7846 12 45 + vertex 12 20.7846 45.03 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex 1.46953e-015 24 45.03 + vertex -12 20.7846 45 + vertex -12 20.7846 45.03 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex 7.34764e-016 12 54.03 + vertex -12 20.7846 45.03 + vertex -8.48528 8.48528 54.03 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex 20.7846 12 45 + vertex 0.15 0.259808 15 + vertex 12 20.7846 45 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex 1.46953e-015 24 45.03 + vertex 7.34764e-016 12 54.03 + vertex 12 20.7846 45.03 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex -4.40858e-015 -24 45.03 + vertex 12 -20.7846 45 + vertex 12 -20.7846 45.03 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex 8.48528 -8.48528 54.03 + vertex -8.48528 -8.48528 54.03 + vertex -2.20429e-015 -12 54.03 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex -12 20.7846 45 + vertex 1.46953e-015 24 45.03 + vertex 1.46953e-015 24 45 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex -4.40858e-015 -24 45.03 + vertex -2.20429e-015 -12 54.03 + vertex -12 -20.7846 45.03 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex -0.15 -0.259808 15 + vertex -20.7846 -12 45 + vertex -0.3 3.67382e-017 15 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex -0.15 0.259808 15 + vertex 0.15 0.259808 15 + vertex -0.15 -0.259808 15 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex 0.15 -0.259808 15 + vertex 0.3 0 15 + vertex 20.7846 -12 45 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex -20.7846 -12 45 + vertex -0.15 -0.259808 15 + vertex -12 -20.7846 45 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex 12 -20.7846 45 + vertex 20.7846 -12 45.03 + vertex 12 -20.7846 45.03 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex 0.15 -0.259808 15 + vertex 0.15 0.259808 15 + vertex 0.3 0 15 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex -24 2.93906e-015 45.03 + vertex -20.7846 12 45.03 + vertex -24 2.93906e-015 45 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex -12 1.46953e-015 54.03 + vertex -24 2.93906e-015 45.03 + vertex -20.7846 -12 45.03 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex -12 20.7846 45 + vertex -20.7846 12 45.03 + vertex -12 20.7846 45.03 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex -12 1.46953e-015 54.03 + vertex 7.34764e-016 12 54.03 + vertex -8.48528 8.48528 54.03 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex 1.46953e-015 24 45.03 + vertex 12 20.7846 45 + vertex 1.46953e-015 24 45 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex 1.46953e-015 24 45.03 + vertex 12 20.7846 45.03 + vertex 12 20.7846 45 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex 20.7846 -12 45.03 + vertex 8.48528 -8.48528 54.03 + vertex 12 -20.7846 45.03 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex 8.48528 -8.48528 54.03 + vertex -2.20429e-015 -12 54.03 + vertex 12 -20.7846 45.03 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex 12 20.7846 45 + vertex 0.15 0.259808 15 + vertex 1.46953e-015 24 45 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex 0.15 0.259808 15 + vertex -0.15 0.259808 15 + vertex 1.46953e-015 24 45 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex 12 -20.7846 45 + vertex -4.40858e-015 -24 45.03 + vertex -4.40858e-015 -24 45 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex -4.40858e-015 -24 45.03 + vertex -12 -20.7846 45.03 + vertex -12 -20.7846 45 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex -4.40858e-015 -24 45.03 + vertex -12 -20.7846 45 + vertex -4.40858e-015 -24 45 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex -12 -20.7846 45 + vertex -0.15 -0.259808 15 + vertex -4.40858e-015 -24 45 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex 12 -20.7846 45 + vertex -4.40858e-015 -24 45 + vertex 0.15 -0.259808 15 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex -4.40858e-015 -24 45 + vertex -0.15 -0.259808 15 + vertex 0.15 -0.259808 15 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex -0.15 0.259808 15 + vertex -0.3 3.67382e-017 15 + vertex -20.7846 12 45 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex -0.3 3.67382e-017 15 + vertex -24 2.93906e-015 45 + vertex -20.7846 12 45 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex -12 -20.7846 45.03 + vertex -8.48528 -8.48528 54.03 + vertex -20.7846 -12 45.03 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex -8.48528 -8.48528 54.03 + vertex -12 1.46953e-015 54.03 + vertex -20.7846 -12 45.03 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex -12 20.7846 45.03 + vertex -20.7846 12 45.03 + vertex -8.48528 8.48528 54.03 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex -20.7846 12 45.03 + vertex -12 1.46953e-015 54.03 + vertex -8.48528 8.48528 54.03 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex 0.3 0 15 + vertex 20.7846 12 45 + vertex 24 0 45 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex 12 -20.7846 45 + vertex 0.15 -0.259808 15 + vertex 20.7846 -12 45 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex -0.3 3.67382e-017 15 + vertex -20.7846 -12 45 + vertex -24 2.93906e-015 45 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex -20.7846 -12 45 + vertex -24 2.93906e-015 45.03 + vertex -24 2.93906e-015 45 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex 20.7846 12 45 + vertex 24 0 45.03 + vertex 24 0 45 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex 24 0 45.03 + vertex 20.7846 -12 45.03 + vertex 20.7846 -12 45 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex 24 0 45.03 + vertex 20.7846 -12 45 + vertex 24 0 45 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex 20.7846 -12 45 + vertex 0.3 0 15 + vertex 24 0 45 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex -20.7846 12 45.03 + vertex -12 20.7846 45 + vertex -20.7846 12 45 + endloop + endfacet + facet normal 0 0 0 + outer loop + vertex -12 20.7846 45 + vertex -0.15 0.259808 15 + vertex -20.7846 12 45 + endloop + endfacet +endsolid OpenSCAD_Model diff --git a/slice_test.html b/slice_test.html index 8a58699..8fb18e0 100644 --- a/slice_test.html +++ b/slice_test.html @@ -70,7 +70,7 @@ var printerConfig = { var printer = new D3D.Printer(printerConfig); var localIp = location.hash.substring(1); -//var doodleBox = new D3D.Box(localIp); +var doodleBox = new D3D.Box(localIp); //var printer = doodleBox.printer; var scene = new THREE.Scene(); @@ -116,13 +116,14 @@ mesh.position.z = 100; //scene.add(mesh); var loader = new THREE.STLLoader(); -loader.load("models/cube.stl", function (geometry) { +loader.load("models/diamond.stl", function (geometry) { var geometry = new THREE.BoxGeometry(10, 10, 10, 1, 1, 1); - + //var geometry = new THREE.TorusGeometry(20, 10, 30, 30); 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; @@ -136,7 +137,7 @@ loader.load("models/cube.stl", function (geometry) { var canvas = document.getElementById("canvas"); var context = canvas.getContext("2d"); - var img = slicer.drawPaths(printer, 0, 1); + var img = slicer.drawPaths(printer, 0, 10); context.drawImage(img, 0, 0); gcode = slicer.getGcode(printer); diff --git a/src/slicer.js b/src/slicer.js index bc91f4b..47cde27 100644 --- a/src/slicer.js +++ b/src/slicer.js @@ -193,6 +193,8 @@ D3D.Slicer.prototype.slice = function (height, step) { //stop when ther are no intersects if (slice.length > 0) { + var layerParts = []; + slices.push(slice); } else { @@ -257,8 +259,6 @@ D3D.Slicer.prototype.slicesToData = function (slices, printer) { var highFillTemplate = this.getFillTemplate(dimensionsZ, wallThickness, (layer % 2 === 0), (layer % 2 === 1)); fills.join(highFillTemplate.intersect(highFillArea)); - console.log(highFillTemplate.intersect(highFillArea)); - outerLayers.push(outerLayer); } @@ -411,7 +411,7 @@ D3D.Slicer.prototype.drawPaths = function (printer, min, max) { for (var layer = min; layer < max; layer ++) { var slice = data[layer % data.length]; - slice.insets.draw(context, "blue"); + //slice.insets.draw(context, "blue"); slice.outerLayer.draw(context, "green"); slice.fill.draw(context, "red"); } From 81ff68d1f6aa90182e36e15b432f5336c4ad71c1 Mon Sep 17 00:00:00 2001 From: casperlamboo Date: Wed, 13 May 2015 17:37:52 +0200 Subject: [PATCH 3/3] implimentent layer parts --- build/d3d.js | 300 +++++++++++++++++++++++++++-------------------- build/d3d.min.js | 2 +- gulpfile.js | 1 - slice_test.html | 30 ++++- src/path.js | 140 ---------------------- src/paths.js | 31 +++-- src/slicer.js | 120 ++++++++++++------- 7 files changed, 294 insertions(+), 330 deletions(-) delete mode 100644 src/path.js diff --git a/build/d3d.js b/build/d3d.js index f42af8b..98775db 100644 --- a/build/d3d.js +++ b/build/d3d.js @@ -568,140 +568,135 @@ D3D.Printer.prototype.subsituteVariables = function (gcode) { * ******************************************************/ -D3D.Path = function (path, closed) { +D3D.Paths = function (paths, closed) { "use strict"; - this.path = path || []; + Array.call(this); + + this.setPaths(paths || []); + this.closed = (closed !== undefined) ? closed : true; }; -D3D.Path.prototype.setPath = function (path) { +D3D.Paths.prototype = Object.create(Array.prototype); +D3D.Paths.prototype.setPaths = function (paths) { "use strict"; - this.path = path; + for (var i = 0; i < paths.length; i ++) { + var path = paths[i]; + this.push(path); + } return this; }; -D3D.Path.prototype.union = function (path) { +D3D.Paths.prototype.clip = function (path, type) { "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); + clipper.AddPaths(this, ClipperLib.PolyType.ptSubject, this.closed); + clipper.AddPaths(path, ClipperLib.PolyType.ptClip, path.closed); + clipper.Execute(type, solution); - return new D3D.Path(solution, this.closed); + return new D3D.Paths(solution); }; -D3D.Path.prototype.difference = function (path) { +D3D.Paths.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.ctDifference, solution); - - return new D3D.Path(solution, this.closed); + return this.clip(path, ClipperLib.ClipType.ctUnion); }; -D3D.Path.prototype.intersect = function (path) { +D3D.Paths.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.ctIntersection, solution); - - return new D3D.Path(solution, this.closed); + return this.clip(path, ClipperLib.ClipType.ctDifference); }; -D3D.Path.prototype.xor = function () { +D3D.Paths.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.ctXor, solution); - - return new D3D.Path(solution, this.closed); + return this.clip(path, ClipperLib.ClipType.ctIntersection); }; -D3D.Path.prototype.offset = function (offset) { +D3D.Paths.prototype.xor = function () { + "use strict"; + + return this.clip(path, ClipperLib.ClipType.ctXor); +}; +D3D.Paths.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.AddPaths(this, ClipperLib.JoinType.jtRound, ClipperLib.EndType.etClosedPolygon); co.Execute(solution, offset); - return new D3D.Path(solution, this.closed); + return new D3D.Paths(solution); }; -D3D.Path.prototype.scaleUp = function (factor) { +D3D.Paths.prototype.scaleUp = function (factor) { "use strict"; - var path = ClipperLib.JS.ScaleUpPaths(this.path, factor); + var path = ClipperLib.JS.ScaleUpPaths(this, factor); return this; }; -D3D.Path.prototype.scaleDown = function (factor) { +D3D.Paths.prototype.scaleDown = function (factor) { "use strict"; - var path = ClipperLib.JS.ScaleDownPaths(this.path, factor); + var path = ClipperLib.JS.ScaleDownPaths(this, factor); return this; }; -D3D.Path.prototype.tresholdArea = function (minArea) { +D3D.Paths.prototype.tresholdArea = function (minArea) { "use strict"; - for (var i = 0; i < this.path.length; i ++) { - var shape = this.path[i]; + for (var i = 0; i < this.length; i ++) { + var shape = this[i]; var area = ClipperLib.Clipper.Area(shape); if (area < minArea) { - this.path.splice(i, 1); + this.splice(i, 1); i --; } } return areas; }; -D3D.Path.prototype.area = function () { +D3D.Paths.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; + return ClipperLib.Clipper.Area(this); }; -D3D.Path.prototype.join = function (path) { +D3D.Paths.prototype.join = function (path) { "use strict"; - this.path = this.path.concat(path.path); + for (var i = 0; i < path.length; i ++) { + this.push(path[i]); + } return this; -} -D3D.Path.prototype.clone = function () { +}; +D3D.Paths.prototype.clone = function () { "use strict"; - var path = ClipperLib.JS.Clone(this.path); + return new D3D.Paths(ClipperLib.JS.Clone(this), this.closed); +}; +D3D.Paths.prototype.bounds = function () { + "use strict"; - return new D3D.Path(path, this.closed); -} -D3D.Path.prototype.draw = function (context, color) { + return ClipperLib.Clipper.GetBounds(this); +}; +D3D.Paths.prototype.reverse = function () { + "use strict"; + + ClipperLib.Clipper.ReversePaths(this); + + return this; +}; +D3D.Paths.prototype.draw = function (context, color) { "use strict"; context.strokeStyle = color; - for (var i = 0; i < this.path.length; i ++) { - var shape = this.path[i]; + for (var i = 0; i < this.length; i ++) { + var shape = this[i]; context.beginPath(); var length = this.closed ? (shape.length + 1) : shape.length; @@ -738,12 +733,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; @@ -770,7 +764,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 }); } @@ -779,22 +774,25 @@ D3D.Slicer.prototype.createLines = function () { for (var i = 0; i < this.geometry.faces.length; i ++) { var face = this.geometry.faces[i]; - var normal = new THREE.Vector2().set(face.normal.x, face.normal.z).normalize(); - //check for only adding unique lines - //returns index of said line - var a = addLine(face.a, face.b); - var b = addLine(face.b, face.c); - var c = addLine(face.c, face.a); + //if (face.normal.y !== 1 && face.normal.y !== -1) { + var normal = new THREE.Vector2().set(face.normal.x, face.normal.z).normalize(); - //set connecting lines (based on face) - this.lines[a].connects.push(b, c); - this.lines[b].connects.push(c, a); - this.lines[c].connects.push(a, b); + //check for only adding unique lines + //returns index of said line + var a = addLine(face.a, face.b); + var b = addLine(face.b, face.c); + var c = addLine(face.c, face.a); - this.lines[a].normals.push(normal); - this.lines[b].normals.push(normal); - this.lines[c].normals.push(normal); + //set connecting lines (based on face) + this.lines[a].connects.push(b, c); + this.lines[b].connects.push(c, a); + this.lines[c].connects.push(a, b); + + this.lines[a].normals.push(normal); + this.lines[b].normals.push(normal); + this.lines[c].normals.push(normal); + //} } }; D3D.Slicer.prototype.slice = function (height, step) { @@ -820,7 +818,7 @@ D3D.Slicer.prototype.slice = function (height, step) { var slices = []; - for (var layer = 1; layer < layersIntersections.length; layer ++) { + for (var layer = 1; layer < layersIntersections.length-1; layer ++) { var layerIntersections = layersIntersections[layer]; var y = layer*step; @@ -837,7 +835,7 @@ D3D.Slicer.prototype.slice = function (height, step) { } var done = []; - var slice = []; + var slice = new D3D.Paths([], true); for (var i = 0; i < layerIntersections.length; i ++) { var index = layerIntersections[i]; @@ -898,15 +896,34 @@ D3D.Slicer.prototype.slice = function (height, step) { //think this check is not nescesary, always higher as 0 if (shape.length > 0) { - slice.push(shape); + slice.push(new D3D.Paths([shape])); } } } + var layerParts = []; + + for (var i = 0; i < slice.length; i ++) { + var layerPart1 = slice[i]; + var merge = false; + + for (var j = 0; j < layerParts.length; j ++) { + var layerPart2 = layerParts[j]; + + if (layerPart2.intersect(layerPart1).length > 0) { + layerPart2.join(layerPart1); + merge = true; + break; + } + } + if (!merge) { + layerParts.push(layerPart1); + } + } + //stop when ther are no intersects - if (slice.length > 0) { - slices.push(new D3D.Path(slice, true)); - //slices.push(slice); + if (layerParts.length > 0) { + slices.push(layerParts); } else { break; @@ -934,37 +951,59 @@ D3D.Slicer.prototype.slicesToData = function (slices, printer) { 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 layerData = []; + data.push(layerData); + + var downSkin = new D3D.Paths(); + if (layer - skinCount >= 0) { + var downLayer = slices[layer - skinCount]; + for (var i = 0; i < downLayer.length; i ++) { + downSkin.join(downLayer[i]); + } } + var upSkin = new D3D.Paths(); + if (layer + skinCount < slices.length) { + var downLayer = slices[layer + skinCount]; + for (var i = 0; i < downLayer.length; i ++) { + upSkin.join(downLayer[i]); + } + } + var surroundingLayer = upSkin.intersect(downSkin).clone().scaleUp(scale); + var sliceData = []; - var fillArea = (inset || outerLayer).offset(-wallThickness/2); + for (var i = 0; i < slice.length; i ++) { + var part = slice[i]; - 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 outerLayer = part.clone(); + outerLayer.scaleUp(scale); - var lowFillArea = fillArea.difference(highFillArea); + var insets = new D3D.Paths(); + for (var offset = wallThickness; offset <= shellThickness; offset += wallThickness) { + var inset = outerLayer.offset(-offset); + + insets.join(inset); + } + + var fillArea = (inset || outerLayer).offset(-wallThickness/2); + + var highFillArea = fillArea.difference(surroundingLayer); + + var lowFillArea = fillArea.difference(highFillArea); + + var fill = new D3D.Paths([]); + + fill.join(lowFillTemplate.intersect(lowFillArea)); - 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) - }); + layerData.push({ + outerLayer: outerLayer.scaleDown(scale), + fill: fill.scaleDown(scale), + insets: insets.scaleDown(scale) + }); + } } return data; @@ -972,7 +1011,7 @@ D3D.Slicer.prototype.slicesToData = function (slices, printer) { D3D.Slicer.prototype.getFillTemplate = function (dimension, size, even, uneven) { "use strict"; - var paths = []; + var paths = new D3D.Paths([], false); if (even) { for (var length = 0; length <= dimension; length += size) { @@ -986,7 +1025,7 @@ D3D.Slicer.prototype.getFillTemplate = function (dimension, size, even, uneven) } //return paths; - return new D3D.Path(paths, false); + return paths; }; D3D.Slicer.prototype.dataToGcode = function (data, printer) { "use strict"; @@ -1008,13 +1047,15 @@ D3D.Slicer.prototype.dataToGcode = function (data, printer) { function sliceToGcode (slice) { var gcode = []; - for (var i = 0; i < slice.path.length; i ++) { - var shape = slice.path[i]; + for (var i = 0; i < slice.length; i ++) { + var shape = slice[i]; var previousPoint; - for (var j = 0; j < shape.length; j ++) { - var point = shape[j]; + var length = slice.closed ? (shape.length + 1) : shape.length; + + for (var j = 0; j < length; j ++) { + var point = shape[j % shape.length]; if (j === 0) { //TODO @@ -1082,9 +1123,13 @@ 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.insets)); - gcode = gcode.concat(sliceToGcode(slice.fill)); + for (var i = 0; i < slice.length; i ++) { + var layerPart = slice[i]; + + gcode = gcode.concat(sliceToGcode(layerPart.outerLayer)); + gcode = gcode.concat(sliceToGcode(layerPart.insets)); + gcode = gcode.concat(sliceToGcode(layerPart.fill)); + } } gcode = gcode.concat(printer.getEndCode()); @@ -1106,13 +1151,16 @@ 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]; - slice.insets.draw(context, "blue"); - slice.outerLayer.draw(context, "green"); - slice.fill.draw(context, "red"); + for (var i = 0; i < slice.length; i ++) { + var layerPart = slice[i]; + + layerPart.insets.draw(context, "blue"); + layerPart.outerLayer.draw(context, "green"); + layerPart.fill.draw(context, "red"); + } } return canvas; diff --git a/build/d3d.min.js b/build/d3d.min.js index 6a49e7a..aad9a10 100644 --- a/build/d3d.min.js +++ b/build/d3d.min.js @@ -1 +1 @@ -function sendAPI(t,e,i){"use strict";$.ajax({url:t,type:"POST",data:e,dataType:"json",timeout:1e4,success:function(t){"success"===t.status?void 0!==i&&i(t.data):console.warn(t.msg)}}).fail(function(){console.warn("Failed connecting to "+t),sendAPI(t,e,i)})}function getAPI(t,e){"use strict";$.ajax({url:t,dataType:"json",timeout:5e3,success:function(t){"success"===t.status?void 0!==e&&e(t.data):console.warn(t.msg)}}).fail(function(){console.warn("Failed connecting to "+t),getAPI(t,e)})}function downloadFile(t,e){"use strict";$(document.createElement("a")).attr({download:t,href:"data:text/plain,"+e})[0].click()}var D3D={version:"0.1",website:"http://www.doodle3d.com/",contact:"develop@doodle3d.com"};THREE.Vector2.prototype.normal=function(){"use strict";var t=this.y,e=-this.x;return this.set(t,e)},Array.prototype.clone=function(){"use strict";for(var t=[],e=0;e0&&this.printer.status.buffered_lines+this.batchSize<=this.maxBufferedLines?this.printBatch():this.updateState()},D3D.Box.prototype.updateState=function(){"use strict";var t=this;this.getInfoStatus(function(e){t.printer.status=e,void 0!==t.onupdate&&t.onupdate(e),t.update()})},D3D.Box.prototype.print=function(t){"use strict";for(this.currentBatch=0,t=t.clone();t.length>0;){var e=t.splice(0,Math.min(this.batchSize,t.length));this.printBatches.push(e)}return this},D3D.Box.prototype.printBatch=function(){"use strict";var t=this,e=this.printBatches.shift();this.setPrinterPrint({start:0===this.currentBatch?!0:!1,first:0===this.currentBatch?!0:!1,gcode:e.join("\n")},function(e){console.log("batch sent: "+t.currentBatch,e),t.printBatches.length>0&&t.currentBatch++,t.updateState()})},D3D.Box.prototype.stopPrint=function(){"use strict";this.printBatches=[],this.currentBatch=0;var t=["M107 ;fan off","G91 ;relative positioning","G1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure","G1 Z+0.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more","G28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way","M84 ;disable axes / steppers","G90 ;absolute positioning","M104 S180",";M140 S70","M117 Done ;display message (20 characters to clear whole screen)"];return this.setPrinterStop({gcode:t.join("\n")},function(t){console.log("Printer stop command sent")}),this},D3D.Box.prototype.getConfig=function(t,e){"use strict";return getAPI(this.api+"config/?"+t.join("=&")+"=",e),this},D3D.Box.prototype.getConfigAll=function(t){"use strict";return getAPI(this.api+"config/all",t),this},D3D.Box.prototype.setConfig=function(t,e){"use strict";var i=this;return sendAPI(this.api+"config",t,function(r){for(var n in r.validation)"ok"!==r.validation[n]&&delete t[n];i.updateConfig(t),i.printer.updateConfig(t),void 0!==e&&e(r)}),this},D3D.Box.prototype.getInfo=function(t){"use strict";return getAPI(this.api+"info",t),this},D3D.Box.prototype.getInfoStatus=function(t){"use strict";return getAPI(this.api+"info/status",t),this},D3D.Box.prototype.downloadInfoLogFiles=function(){"use strict";window.location=this.api+"info/logfiles"},D3D.Box.prototype.getInfoAcces=function(t){"use strict";return getAPI(this.api+"info/access",t),this},D3D.Box.prototype.getNetworkScan=function(t){"use strict";return getAPI(this.api+"network/scan",t),this},D3D.Box.prototype.getNetworkKnown=function(t){"use strict";return getAPI(this.api+"network/known",t),this},D3D.Box.prototype.getNetworkStatus=function(t){"use strict";return getAPI(this.api+"network/status",t),this},D3D.Box.prototype.setNetworkAssosiate=function(t,e){"use strict";return sendAPI(this.api+"network/associate",t,e),this},D3D.Box.prototype.setNetworkDisassosiate=function(t){"use strict";return sendAPI(this.api+"network/disassociate",{},t),this},D3D.Box.prototype.setNetworkOpenAP=function(t){"use strict";return sendAPI(this.api+"network/openap",{},t),this},D3D.Box.prototype.setNetworkRemove=function(t,e){"use strict";return sendAPI(this.api+"network/remove",{ssid:t},e),this},D3D.Box.prototype.getNetworkSignin=function(t){"use strict";return getAPI(this.api+"network/signin",t),this},D3D.Box.prototype.getNetworkAlive=function(t){"use strict";return getAPI(this.api+"network/alive",t),this},D3D.Box.prototype.getPrinterTemperature=function(t){"use strict";return getAPI(this.api+"printer/temperature",t),this},D3D.Box.prototype.getPrinterProgress=function(t){"use strict";return getAPI(this.api+"printer/progress",t),this},D3D.Box.prototype.getPrinterState=function(t){"use strict";return getAPI(this.api+"printer/state",t),this},D3D.Box.prototype.getPrinterListAll=function(t){"use strict";return getAPI(this.api+"printer/listall",t),this},D3D.Box.prototype.setPrinterHeatup=function(t){"use strict";return sendAPI(this.api+"printer/heatup",{},t),this},D3D.Box.prototype.setPrinterPrint=function(t,e){"use strict";return sendAPI(this.api+"printer/print",t,e),this},D3D.Box.prototype.setPrinterStop=function(t,e){"use strict";return sendAPI(this.api+"printer/stop",t,e),this},D3D.Box.prototype.getSketch=function(t,e){"use strict";return getAPI(this.api+"sketch/?id="+t,e),this},D3D.Box.prototype.setSketch=function(t,e){"use strict";return sendAPI(this.api+"sketch",{data:t},e),this},D3D.Box.prototype.getSketchStatus=function(t){"use strict";return getAPI(this.api+"sketch/status",t),this},D3D.Box.prototype.setSketchClear=function(t){"use strict";return sendAPI(this.api+"sketch/clear",t),this},D3D.Box.prototype.getSystemVersions=function(t){"use strict";return getAPI(this.api+"system/fwversions",t),this},D3D.Box.prototype.getUpdateStatus=function(t){"use strict";return getAPI(this.api+"update/status",t),this},D3D.Box.prototype.setUpdateDownload=function(t){"use strict";return sendAPI(this.api+"update/download",{},t),this},D3D.Box.prototype.setUpdateInstall=function(t){"use strict";return sendAPI(this.api+"update/install",{},t),this},D3D.Box.prototype.setUpdateClear=function(t){"use strict";return sendAPI(this.api+"update/clear",{},t),this},D3D.Printer=function(t){"use strict";this.status={},this.config={},this.updateConfig(t)},D3D.Printer.prototype.updateConfig=function(t){"use strict";for(var e in t)0===e.indexOf("printer")&&(this.config[e]=t[e]);return this},D3D.Printer.prototype.getStartCode=function(){"use strict";var t=this.config["printer.startcode"];return t=this.subsituteVariables(t),t.split("\n")},D3D.Printer.prototype.getEndCode=function(){"use strict";var t=this.config["printer.endcode"];return t=this.subsituteVariables(t),t.split("\n")},D3D.Printer.prototype.subsituteVariables=function(t){"use strict";var e=this.config["printer.temperature"],i=this.config["printer.bed.temperature"],r=this.config["printer.heatup.temperature"],n=this.config["printer.heatup.bed.temperature"],s=this.config["printer.type"],o=this.config["printer.heatedbed"];switch(s){case"makerbot_replicator2":s="r2";break;case"makerbot_replicator2x":s="r2x";break;case"makerbot_thingomatic":s="t6";break;case"makerbot_generic":s="r2";break;case"_3Dison_plus":s="r2"}var a=o?"":";";return t=t.replace(/{printingTemp}/gi,e),t=t.replace(/{printingBedTemp}/gi,i),t=t.replace(/{preheatTemp}/gi,r),t=t.replace(/{preheatBedTemp}/gi,n),t=t.replace(/{printerType}/gi,s),t=t.replace(/{if heatedBed}/gi,a)},D3D.Path=function(t,e){"use strict";this.path=t||[],this.closed=void 0!==e?e:!0},D3D.Path.prototype.setPath=function(t){"use strict";return this.path=t,this},D3D.Path.prototype.union=function(t){"use strict";var e=new ClipperLib.Paths,i=new ClipperLib.Clipper;return i.AddPaths(this.path,ClipperLib.PolyType.ptSubject,this.closed),i.AddPaths(t.path,ClipperLib.PolyType.ptClip,t.closed),i.Execute(ClipperLib.ClipType.ctUnion,e),new D3D.Path(e,this.closed)},D3D.Path.prototype.difference=function(t){"use strict";var e=new ClipperLib.Paths,i=new ClipperLib.Clipper;return i.AddPaths(this.path,ClipperLib.PolyType.ptSubject,this.closed),i.AddPaths(t.path,ClipperLib.PolyType.ptClip,t.closed),i.Execute(ClipperLib.ClipType.ctDifference,e),new D3D.Path(e,this.closed)},D3D.Path.prototype.intersect=function(t){"use strict";var e=new ClipperLib.Paths,i=new ClipperLib.Clipper;return i.AddPaths(this.path,ClipperLib.PolyType.ptSubject,this.closed),i.AddPaths(t.path,ClipperLib.PolyType.ptClip,t.closed),i.Execute(ClipperLib.ClipType.ctIntersection,e),new D3D.Path(e,this.closed)},D3D.Path.prototype.xor=function(){"use strict";var t=new ClipperLib.Paths,e=new ClipperLib.Clipper;return e.AddPaths(this.path,ClipperLib.PolyType.ptSubject,this.closed),e.AddPaths(path.path,ClipperLib.PolyType.ptClip,path.closed),e.Execute(ClipperLib.ClipType.ctXor,t),new D3D.Path(t,this.closed)},D3D.Path.prototype.offset=function(t){"use strict";var e=new ClipperLib.Paths,i=new ClipperLib.ClipperOffset(1,1);return i.AddPaths(this.path,ClipperLib.JoinType.jtRound,ClipperLib.EndType.etClosedPolygon),i.Execute(e,t),new D3D.Path(e,this.closed)},D3D.Path.prototype.scaleUp=function(t){"use strict";ClipperLib.JS.ScaleUpPaths(this.path,t);return this},D3D.Path.prototype.scaleDown=function(t){"use strict";ClipperLib.JS.ScaleDownPaths(this.path,t);return this},D3D.Path.prototype.tresholdArea=function(t){"use strict";for(var e=0;er&&(this.path.splice(e,1),e--)}return areas},D3D.Path.prototype.area=function(){"use strict";for(var t=[],e=0;es;s++){var o=r[s%r.length];t.lineTo(2*o.X,2*o.Y)}t.stroke()}},D3D.Slicer=function(){"use strict";this.lines=[]},D3D.Slicer.prototype.setMesh=function(t){"use strict";t.updateMatrix();var e=t.geometry.clone();return e.mergeVertices(),e.applyMatrix(t.matrix),e instanceof THREE.BufferGeometry&&(e=(new THREE.Geometry).fromBufferGeometry(e)),this.geometry=e,this.createLines(),this},D3D.Slicer.prototype.createLines=function(){"use strict";function t(t,r){var n=e[t+"_"+r]||e[r+"_"+t];return void 0===n&&(n=i.lines.length,e[t+"_"+r]=n,i.lines.push({line:new THREE.Line3(i.geometry.vertices[t],i.geometry.vertices[r]),connects:[],normals:[]})),n}this.lines=[];for(var e={},i=this,r=0;r=a;a++)a>=0&&(void 0===i[a]&&(i[a]=[]),i[a].push(r));for(var p=[],c=1;c0)break;f=-1}else f=-1}v.length>0&&P.push(v)}}if(!(P.length>0))break;p.push(new D3D.Path(P,!0))}return p},D3D.Slicer.prototype.slicesToData=function(t,e){"use strict";for(var i=100,r=e.config["printer.layerHeight"]*i,n=e.config["printer.dimensions.z"]*i,s=e.config["printer.wallThickness"]*i,o=e.config["printer.shellThickness"]*i,a=e.config["printer.fillSize"]*i,p=(e.config["printer.brimOffset"]*i,Math.ceil(o/r)),c=[],h=this.getFillTemplate(n,a,!0,!0),u=0;u=D;D+=s){var g=f.offset(-D);d.join(g)}var y=(g||f).offset(-s/2),P=u-p>=0?t[u-p]:new D3D.Path,v=u+p0){var b=this.getFillTemplate(n,s,u%2===0,u%2===1);x.join(b.intersect(w))}c.push({outerLayer:f.scaleDown(i),insets:d.scaleDown(i),fill:x.scaleDown(i)})}return c},D3D.Slicer.prototype.getFillTemplate=function(t,e,i,r){"use strict";var n=[];if(i)for(var s=0;t>=s;s+=e)n.push([{X:s,Y:0},{X:s,Y:t}]);if(r)for(var s=0;t>=s;s+=e)n.push([{X:0,Y:s},{X:t,Y:s}]);return new D3D.Path(n,!1)},D3D.Slicer.prototype.dataToGcode=function(t,e){"use strict";function i(t){for(var e=[],i=0;if&&u&&e.push(["G0","E"+(g-d).toFixed(3),"F"+(60*l).toFixed(3)].join(" ")),e.push(["G0","X"+a.X.toFixed(3)+" Y"+a.Y.toFixed(3)+" Z"+x,"F"+60*p].join(" ")),g>f&&u&&e.push(["G0","E"+g.toFixed(3),"F"+(60*l).toFixed(3)].join(" "));else{var c=(new THREE.Vector2).set(a.X,a.Y),D=(new THREE.Vector2).set(n.X,n.Y),w=c.distanceTo(D);g+=w*h*r/P*v,e.push(["G1","X"+a.X.toFixed(3)+" Y"+a.Y.toFixed(3)+" Z"+x,"F"+y,"E"+g.toFixed(3)].join(" "))}n=a}return e}for(var r=e.config["printer.layerHeight"],n=e.config["printer.speed"],s=e.config["printer.bottomLayerSpeed"],o=e.config["printer.firstLayerSlow"],a=e.config["printer.bottomFlowRate"],p=e.config["printer.travelSpeed"],c=e.config["printer.filamentThickness"],h=e.config["printer.wallThickness"],u=(e.config["printer.enableTraveling"],e.config["printer.retraction.enabled"]),l=e.config["printer.retraction.speed"],f=e.config["printer.retraction.minDistance"],d=e.config["printer.retraction.amount"],D=e.getStartCode(),g=0,y=o?(60*s).toFixed(3):(60*n).toFixed(3),P=Math.pow(c/2,2)*Math.PI,v=a,w=0;wc;c++){var h=o[c%o.length];h.insets.draw(p,"blue"),h.outerLayer.draw(p,"green"),h.fill.draw(p,"red")}return a},D3D.Slicer.prototype.getGcode=function(t){"use strict";var e=t.config["printer.layerHeight"],i=t.config["printer.dimensions.z"],r=(new Date).getTime(),n=this.slice(i,e),s=(new Date).getTime();console.log("Slicing: "+(s-r)+"ms");var r=(new Date).getTime(),o=this.slicesToData(n,t),s=(new Date).getTime();console.log("Data: "+(s-r)+"ms");var r=(new Date).getTime(),a=this.dataToGcode(o,t),s=(new Date).getTime();return console.log("Gcode: "+(s-r)+"ms"),a}; \ No newline at end of file +function sendAPI(t,e,i){"use strict";$.ajax({url:t,type:"POST",data:e,dataType:"json",timeout:1e4,success:function(t){"success"===t.status?void 0!==i&&i(t.data):console.warn(t.msg)}}).fail(function(){console.warn("Failed connecting to "+t),sendAPI(t,e,i)})}function getAPI(t,e){"use strict";$.ajax({url:t,dataType:"json",timeout:5e3,success:function(t){"success"===t.status?void 0!==e&&e(t.data):console.warn(t.msg)}}).fail(function(){console.warn("Failed connecting to "+t),getAPI(t,e)})}function downloadFile(t,e){"use strict";$(document.createElement("a")).attr({download:t,href:"data:text/plain,"+e})[0].click()}var D3D={version:"0.1",website:"http://www.doodle3d.com/",contact:"develop@doodle3d.com"};THREE.Vector2.prototype.normal=function(){"use strict";var t=this.y,e=-this.x;return this.set(t,e)},Array.prototype.clone=function(){"use strict";for(var t=[],e=0;e0&&this.printer.status.buffered_lines+this.batchSize<=this.maxBufferedLines?this.printBatch():this.updateState()},D3D.Box.prototype.updateState=function(){"use strict";var t=this;this.getInfoStatus(function(e){t.printer.status=e,void 0!==t.onupdate&&t.onupdate(e),t.update()})},D3D.Box.prototype.print=function(t){"use strict";for(this.currentBatch=0,t=t.clone();t.length>0;){var e=t.splice(0,Math.min(this.batchSize,t.length));this.printBatches.push(e)}return this},D3D.Box.prototype.printBatch=function(){"use strict";var t=this,e=this.printBatches.shift();this.setPrinterPrint({start:0===this.currentBatch?!0:!1,first:0===this.currentBatch?!0:!1,gcode:e.join("\n")},function(e){console.log("batch sent: "+t.currentBatch,e),t.printBatches.length>0&&t.currentBatch++,t.updateState()})},D3D.Box.prototype.stopPrint=function(){"use strict";this.printBatches=[],this.currentBatch=0;var t=["M107 ;fan off","G91 ;relative positioning","G1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure","G1 Z+0.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more","G28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way","M84 ;disable axes / steppers","G90 ;absolute positioning","M104 S180",";M140 S70","M117 Done ;display message (20 characters to clear whole screen)"];return this.setPrinterStop({gcode:t.join("\n")},function(t){console.log("Printer stop command sent")}),this},D3D.Box.prototype.getConfig=function(t,e){"use strict";return getAPI(this.api+"config/?"+t.join("=&")+"=",e),this},D3D.Box.prototype.getConfigAll=function(t){"use strict";return getAPI(this.api+"config/all",t),this},D3D.Box.prototype.setConfig=function(t,e){"use strict";var i=this;return sendAPI(this.api+"config",t,function(r){for(var n in r.validation)"ok"!==r.validation[n]&&delete t[n];i.updateConfig(t),i.printer.updateConfig(t),void 0!==e&&e(r)}),this},D3D.Box.prototype.getInfo=function(t){"use strict";return getAPI(this.api+"info",t),this},D3D.Box.prototype.getInfoStatus=function(t){"use strict";return getAPI(this.api+"info/status",t),this},D3D.Box.prototype.downloadInfoLogFiles=function(){"use strict";window.location=this.api+"info/logfiles"},D3D.Box.prototype.getInfoAcces=function(t){"use strict";return getAPI(this.api+"info/access",t),this},D3D.Box.prototype.getNetworkScan=function(t){"use strict";return getAPI(this.api+"network/scan",t),this},D3D.Box.prototype.getNetworkKnown=function(t){"use strict";return getAPI(this.api+"network/known",t),this},D3D.Box.prototype.getNetworkStatus=function(t){"use strict";return getAPI(this.api+"network/status",t),this},D3D.Box.prototype.setNetworkAssosiate=function(t,e){"use strict";return sendAPI(this.api+"network/associate",t,e),this},D3D.Box.prototype.setNetworkDisassosiate=function(t){"use strict";return sendAPI(this.api+"network/disassociate",{},t),this},D3D.Box.prototype.setNetworkOpenAP=function(t){"use strict";return sendAPI(this.api+"network/openap",{},t),this},D3D.Box.prototype.setNetworkRemove=function(t,e){"use strict";return sendAPI(this.api+"network/remove",{ssid:t},e),this},D3D.Box.prototype.getNetworkSignin=function(t){"use strict";return getAPI(this.api+"network/signin",t),this},D3D.Box.prototype.getNetworkAlive=function(t){"use strict";return getAPI(this.api+"network/alive",t),this},D3D.Box.prototype.getPrinterTemperature=function(t){"use strict";return getAPI(this.api+"printer/temperature",t),this},D3D.Box.prototype.getPrinterProgress=function(t){"use strict";return getAPI(this.api+"printer/progress",t),this},D3D.Box.prototype.getPrinterState=function(t){"use strict";return getAPI(this.api+"printer/state",t),this},D3D.Box.prototype.getPrinterListAll=function(t){"use strict";return getAPI(this.api+"printer/listall",t),this},D3D.Box.prototype.setPrinterHeatup=function(t){"use strict";return sendAPI(this.api+"printer/heatup",{},t),this},D3D.Box.prototype.setPrinterPrint=function(t,e){"use strict";return sendAPI(this.api+"printer/print",t,e),this},D3D.Box.prototype.setPrinterStop=function(t,e){"use strict";return sendAPI(this.api+"printer/stop",t,e),this},D3D.Box.prototype.getSketch=function(t,e){"use strict";return getAPI(this.api+"sketch/?id="+t,e),this},D3D.Box.prototype.setSketch=function(t,e){"use strict";return sendAPI(this.api+"sketch",{data:t},e),this},D3D.Box.prototype.getSketchStatus=function(t){"use strict";return getAPI(this.api+"sketch/status",t),this},D3D.Box.prototype.setSketchClear=function(t){"use strict";return sendAPI(this.api+"sketch/clear",t),this},D3D.Box.prototype.getSystemVersions=function(t){"use strict";return getAPI(this.api+"system/fwversions",t),this},D3D.Box.prototype.getUpdateStatus=function(t){"use strict";return getAPI(this.api+"update/status",t),this},D3D.Box.prototype.setUpdateDownload=function(t){"use strict";return sendAPI(this.api+"update/download",{},t),this},D3D.Box.prototype.setUpdateInstall=function(t){"use strict";return sendAPI(this.api+"update/install",{},t),this},D3D.Box.prototype.setUpdateClear=function(t){"use strict";return sendAPI(this.api+"update/clear",{},t),this},D3D.Printer=function(t){"use strict";this.status={},this.config={},this.updateConfig(t)},D3D.Printer.prototype.updateConfig=function(t){"use strict";for(var e in t)0===e.indexOf("printer")&&(this.config[e]=t[e]);return this},D3D.Printer.prototype.getStartCode=function(){"use strict";var t=this.config["printer.startcode"];return t=this.subsituteVariables(t),t.split("\n")},D3D.Printer.prototype.getEndCode=function(){"use strict";var t=this.config["printer.endcode"];return t=this.subsituteVariables(t),t.split("\n")},D3D.Printer.prototype.subsituteVariables=function(t){"use strict";var e=this.config["printer.temperature"],i=this.config["printer.bed.temperature"],r=this.config["printer.heatup.temperature"],n=this.config["printer.heatup.bed.temperature"],s=this.config["printer.type"],o=this.config["printer.heatedbed"];switch(s){case"makerbot_replicator2":s="r2";break;case"makerbot_replicator2x":s="r2x";break;case"makerbot_thingomatic":s="t6";break;case"makerbot_generic":s="r2";break;case"_3Dison_plus":s="r2"}var a=o?"":";";return t=t.replace(/{printingTemp}/gi,e),t=t.replace(/{printingBedTemp}/gi,i),t=t.replace(/{preheatTemp}/gi,r),t=t.replace(/{preheatBedTemp}/gi,n),t=t.replace(/{printerType}/gi,s),t=t.replace(/{if heatedBed}/gi,a)},D3D.Paths=function(t,e){"use strict";Array.call(this),this.setPaths(t||[]),this.closed=void 0!==e?e:!0},D3D.Paths.prototype=Object.create(Array.prototype),D3D.Paths.prototype.setPaths=function(t){"use strict";for(var e=0;er&&(this.splice(e,1),e--)}return areas},D3D.Paths.prototype.area=function(){"use strict";return ClipperLib.Clipper.Area(this)},D3D.Paths.prototype.join=function(t){"use strict";for(var e=0;es;s++){var o=r[s%r.length];t.lineTo(2*o.X,2*o.Y)}t.stroke()}},D3D.Slicer=function(){"use strict";this.lines=[]},D3D.Slicer.prototype.setMesh=function(t){"use strict";t.updateMatrix();var e=t.geometry.clone();return e instanceof THREE.BufferGeometry&&(e=(new THREE.Geometry).fromBufferGeometry(e)),e.mergeVertices(),e.applyMatrix(t.matrix),this.geometry=e,this.createLines(),this},D3D.Slicer.prototype.createLines=function(){"use strict";function t(t,r){var n=e[t+"_"+r]||e[r+"_"+t];return void 0===n&&(n=i.lines.length,e[t+"_"+r]=n,i.lines.push({line:new THREE.Line3(i.geometry.vertices[t],i.geometry.vertices[r]),connects:[],normals:[],ignore:0})),n}this.lines=[];for(var e={},i=this,r=0;r=a;a++)a>=0&&(void 0===i[a]&&(i[a]=[]),i[a].push(r));for(var p=[],c=1;c0)break;f=-1}else f=-1}P.length>0&&v.push(new D3D.Paths([P]))}}for(var T=[],r=0;r0){L.join(k),I=!0;break}}I||T.push(k)}if(!(T.length>0))break;p.push(T)}return p},D3D.Slicer.prototype.slicesToData=function(t,e){"use strict";for(var i=100,r=e.config["printer.layerHeight"]*i,n=e.config["printer.dimensions.z"]*i,s=e.config["printer.wallThickness"]*i,o=e.config["printer.shellThickness"]*i,a=e.config["printer.fillSize"]*i,p=(e.config["printer.brimOffset"]*i,Math.ceil(o/r)),c=[],h=this.getFillTemplate(n,a,!0,!0),u=0;u=0)for(var D=t[u-p],d=0;d=x;x+=s){var b=m.offset(-x);w.join(b)}var B=(b||m).offset(-s/2),A=B.difference(v),C=B.difference(A),S=new D3D.Paths([]);S.join(h.intersect(C));var T=this.getFillTemplate(n,s,u%2===0,u%2===1);S.join(T.intersect(A)),f.push({outerLayer:m.scaleDown(i),fill:S.scaleDown(i),insets:w.scaleDown(i)})}}return c},D3D.Slicer.prototype.getFillTemplate=function(t,e,i,r){"use strict";var n=new D3D.Paths([],!1);if(i)for(var s=0;t>=s;s+=e)n.push([{X:s,Y:0},{X:s,Y:t}]);if(r)for(var s=0;t>=s;s+=e)n.push([{X:0,Y:s},{X:t,Y:s}]);return n},D3D.Slicer.prototype.dataToGcode=function(t,e){"use strict";function i(t){for(var e=[],i=0;ia;a++){var c=s[a%s.length];if(0===a)d>f&&u&&e.push(["G0","E"+(d-g).toFixed(3),"F"+(60*l).toFixed(3)].join(" ")),e.push(["G0","X"+c.X.toFixed(3)+" Y"+c.Y.toFixed(3)+" Z"+x,"F"+60*p].join(" ")),d>f&&u&&e.push(["G0","E"+d.toFixed(3),"F"+(60*l).toFixed(3)].join(" "));else{var D=(new THREE.Vector2).set(c.X,c.Y),m=(new THREE.Vector2).set(n.X,n.Y),w=D.distanceTo(m);d+=w*h*r/v*P,e.push(["G1","X"+c.X.toFixed(3)+" Y"+c.Y.toFixed(3)+" Z"+x,"F"+y,"E"+d.toFixed(3)].join(" "))}n=c}return e}for(var r=e.config["printer.layerHeight"],n=e.config["printer.speed"],s=e.config["printer.bottomLayerSpeed"],o=e.config["printer.firstLayerSlow"],a=e.config["printer.bottomFlowRate"],p=e.config["printer.travelSpeed"],c=e.config["printer.filamentThickness"],h=e.config["printer.wallThickness"],u=(e.config["printer.enableTraveling"],e.config["printer.retraction.enabled"]),l=e.config["printer.retraction.speed"],f=e.config["printer.retraction.minDistance"],g=e.config["printer.retraction.amount"],D=e.getStartCode(),d=0,y=o?(60*s).toFixed(3):(60*n).toFixed(3),v=Math.pow(c/2,2)*Math.PI,P=a,m=0;mc;c++)for(var h=o[c%o.length],u=0;u - @@ -119,6 +118,31 @@ var loader = new THREE.STLLoader(); loader.load("models/diamond.stl", function (geometry) { var geometry = new THREE.BoxGeometry(10, 10, 10, 1, 1, 1); //var geometry = new THREE.TorusGeometry(20, 10, 30, 30); + + var geometry = (function () { + "use strict"; + + var circle = new THREE.Shape(); + circle.absarc(0, 0, 10, 0, Math.PI*2, false); + + var hole = new THREE.Path(); + hole.absarc(0, 0, 5, 0, Math.PI*2, true ); + + circle.holes.push(hole); + + var matrix = new THREE.Matrix4(); + matrix.makeRotationX(Math.PI*1.5); + + var geometry = new THREE.ExtrudeGeometry(circle, { + amount: 3, + bevelEnabled: false, + steps: 1 + }); + geometry.applyMatrix(matrix); + + return geometry; + })(); + var mesh = new THREE.Mesh(geometry, material); mesh.position.x = 100; @@ -137,8 +161,8 @@ loader.load("models/diamond.stl", function (geometry) { var canvas = document.getElementById("canvas"); var context = canvas.getContext("2d"); - var img = slicer.drawPaths(printer, 0, 10); - context.drawImage(img, 0, 0); + //var img = slicer.drawPaths(printer, 7, 8); + //context.drawImage(img, 0, 0); gcode = slicer.getGcode(printer); }); diff --git a/src/path.js b/src/path.js deleted file mode 100644 index 9781526..0000000 --- a/src/path.js +++ /dev/null @@ -1,140 +0,0 @@ -/****************************************************** -* -* Path -* -* Abstraction layer for annoying clipper js -* -******************************************************/ - -D3D.Path = function (path, closed) { - "use strict"; - - Array.call(this); - - this.setPath(path || []); - - this.closed = (closed !== undefined) ? closed : true; -}; -D3D.Path.prototype = Object.create(Array.prototype); -D3D.Path.prototype.setPath = function (path) { - "use strict"; - - for (var i = 0; i < path.length; i ++) { - this.push(path[i]); - } - - return this; -}; -D3D.Path.prototype.clip = function (path, type) { - "use strict"; - - var solution = new ClipperLib.Paths(); - - var clipper = new ClipperLib.Clipper(); - clipper.AddPath(this, ClipperLib.PolyType.ptSubject, true); - if (path instanceof D3D.Path) { - clipper.AddPath(path, ClipperLib.PolyType.ptClip, true); - } - else if (path instanceof D3D.Paths) { - clipper.AddPaths(path, ClipperLib.PolyType.ptClip, true); - } - clipper.Execute(type, solution); - - return new D3D.Paths(solution, this.closed); -}; -D3D.Path.prototype.union = function (path) { - "use strict"; - - return this.clip(path, ClipperLib.ClipType.ctUnion); -}; -D3D.Path.prototype.difference = function (path) { - "use strict"; - - return this.clip(path, ClipperLib.ClipType.ctDifference); -}; -D3D.Path.prototype.intersect = function (path) { - "use strict"; - - return this.clip(path, ClipperLib.ClipType.ctIntersection); -}; -D3D.Path.prototype.xor = function () { - "use strict"; - - return this.clip(path, ClipperLib.ClipType.ctXor); -}; -D3D.Path.prototype.offset = function (offset) { - "use strict"; - - var solution = new ClipperLib.Path(); - var co = new ClipperLib.ClipperOffset(2, 0.25); - co.AddPath(this, ClipperLib.JoinType.jtRound, ClipperLib.EndType.etClosedPolygon); - co.Execute(solution, offset); - - return new D3D.Path(solution[0], this.closed); -}; -D3D.Path.prototype.scaleUp = function (factor) { - "use strict"; - - ClipperLib.JS.ScaleUpPath(this, factor); - - return this; -}; -D3D.Path.prototype.scaleDown = function (factor) { - "use strict"; - - var path = ClipperLib.JS.ScaleDownPath(this, factor); - - return this; -}; -D3D.Path.prototype.tresholdArea = function (minArea) { - "use strict"; - - for (var i = 0; i < this.length; i ++) { - var shape = this[i]; - - var area = ClipperLib.Clipper.Area(shape); - - if (area < minArea) { - this.splice(i, 1); - i --; - } - } - - return areas; -}; -D3D.Path.prototype.area = function () { - "use strict"; - - return ClipperLib.Clipper.Area(this); -}; -D3D.Path.prototype.join = function (path) { - "use strict"; - - this.setPath(this.concat(path)); - - return this; -} -D3D.Path.prototype.clone = function () { - "use strict"; - - var path = ClipperLib.JS.Clone(this); - - 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.length; i ++) { - var shape = this[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(); - } -}; \ No newline at end of file diff --git a/src/paths.js b/src/paths.js index 9736c05..ba7ac12 100644 --- a/src/paths.js +++ b/src/paths.js @@ -6,14 +6,14 @@ * ******************************************************/ -D3D.Paths = function (paths) { +D3D.Paths = function (paths, closed) { "use strict"; Array.call(this); this.setPaths(paths || []); - this.closed = (this[0] !== undefined) ? this[0].closed : true; + this.closed = (closed !== undefined) ? closed : true; }; D3D.Paths.prototype = Object.create(Array.prototype); D3D.Paths.prototype.setPaths = function (paths) { @@ -21,10 +21,6 @@ D3D.Paths.prototype.setPaths = function (paths) { for (var i = 0; i < paths.length; i ++) { var path = paths[i]; - if (!(path instanceof D3D.Path)) { - //console.log("Path not instance of D3D.Path, converting path to D3D.Path"); - path = new D3D.Path(path, true); - } this.push(path); } @@ -37,12 +33,7 @@ D3D.Paths.prototype.clip = function (path, type) { var clipper = new ClipperLib.Clipper(); clipper.AddPaths(this, ClipperLib.PolyType.ptSubject, this.closed); - if (path instanceof D3D.Paths) { - clipper.AddPaths(path, ClipperLib.PolyType.ptClip, path.closed); - } - else if (path instanceof D3D.Path) { - clipper.AddPath(path, ClipperLib.PolyType.ptClip, path.closed); - } + clipper.AddPaths(path, ClipperLib.PolyType.ptClip, path.closed); clipper.Execute(type, solution); return new D3D.Paths(solution); @@ -124,13 +115,19 @@ D3D.Paths.prototype.join = function (path) { D3D.Paths.prototype.clone = function () { "use strict"; - var paths = []; + return new D3D.Paths(ClipperLib.JS.Clone(this), this.closed); +}; +D3D.Paths.prototype.bounds = function () { + "use strict"; - for (var i = 0; i < this.length; i ++) { - paths.push(this[i].clone()); - } + return ClipperLib.Clipper.GetBounds(this); +}; +D3D.Paths.prototype.reverse = function () { + "use strict"; - return new D3D.Paths(paths); + ClipperLib.Clipper.ReversePaths(this); + + return this; }; D3D.Paths.prototype.draw = function (context, color) { "use strict"; diff --git a/src/slicer.js b/src/slicer.js index 47cde27..b3ce248 100644 --- a/src/slicer.js +++ b/src/slicer.js @@ -65,7 +65,7 @@ D3D.Slicer.prototype.createLines = function () { for (var i = 0; i < this.geometry.faces.length; i ++) { var face = this.geometry.faces[i]; - if (!(face.normal.y === 1 || face.normal.y === -1)) { + //if (face.normal.y !== 1 && face.normal.y !== -1) { var normal = new THREE.Vector2().set(face.normal.x, face.normal.z).normalize(); //check for only adding unique lines @@ -82,7 +82,7 @@ D3D.Slicer.prototype.createLines = function () { this.lines[a].normals.push(normal); this.lines[b].normals.push(normal); this.lines[c].normals.push(normal); - } + //} } }; D3D.Slicer.prototype.slice = function (height, step) { @@ -108,7 +108,7 @@ D3D.Slicer.prototype.slice = function (height, step) { var slices = []; - for (var layer = 1; layer < layersIntersections.length; layer ++) { + for (var layer = 1; layer < layersIntersections.length-1; layer ++) { var layerIntersections = layersIntersections[layer]; var y = layer*step; @@ -130,7 +130,7 @@ D3D.Slicer.prototype.slice = function (height, step) { var index = layerIntersections[i]; if (done.indexOf(index) === -1) { - var shape = new D3D.Path([], true); + var shape = []; while (index !== -1) { var intersection = intersections[index]; @@ -186,16 +186,34 @@ D3D.Slicer.prototype.slice = function (height, step) { //think this check is not nescesary, always higher as 0 if (shape.length > 0) { - slice.push(shape); + slice.push(new D3D.Paths([shape])); } } } - //stop when ther are no intersects - if (slice.length > 0) { - var layerParts = []; + var layerParts = []; - slices.push(slice); + for (var i = 0; i < slice.length; i ++) { + var layerPart1 = slice[i]; + var merge = false; + + for (var j = 0; j < layerParts.length; j ++) { + var layerPart2 = layerParts[j]; + + if (layerPart2.intersect(layerPart1).length > 0) { + layerPart2.join(layerPart1); + merge = true; + break; + } + } + if (!merge) { + layerParts.push(layerPart1); + } + } + + //stop when ther are no intersects + if (layerParts.length > 0) { + slices.push(layerParts); } else { break; @@ -223,16 +241,26 @@ D3D.Slicer.prototype.slicesToData = function (slices, printer) { for (var layer = 0; layer < slices.length; layer ++) { var slice = slices[layer]; - - var insets = new D3D.Paths(); - var fills = new D3D.Paths(); - var outerLayers = new D3D.Paths(); - - var downFill = (layer - skinCount >= 0) ? slices[layer - skinCount] : new D3D.Paths(); - var upFill = (layer + skinCount < slices.length) ? slices[layer + skinCount] : new D3D.Paths(); - //var surroundingLayer = downFill.intersect(upFill); - var surroundingLayer = upFill.clone().scaleUp(scale); - //D3D.Paths surroundingLayer + + var layerData = []; + data.push(layerData); + + var downSkin = new D3D.Paths(); + if (layer - skinCount >= 0) { + var downLayer = slices[layer - skinCount]; + for (var i = 0; i < downLayer.length; i ++) { + downSkin.join(downLayer[i]); + } + } + var upSkin = new D3D.Paths(); + if (layer + skinCount < slices.length) { + var downLayer = slices[layer + skinCount]; + for (var i = 0; i < downLayer.length; i ++) { + upSkin.join(downLayer[i]); + } + } + var surroundingLayer = upSkin.intersect(downSkin).clone().scaleUp(scale); + var sliceData = []; for (var i = 0; i < slice.length; i ++) { var part = slice[i]; @@ -240,10 +268,11 @@ D3D.Slicer.prototype.slicesToData = function (slices, printer) { var outerLayer = part.clone(); outerLayer.scaleUp(scale); + var insets = new D3D.Paths(); for (var offset = wallThickness; offset <= shellThickness; offset += wallThickness) { var inset = outerLayer.offset(-offset); - insets.push(inset); + insets.join(inset); } var fillArea = (inset || outerLayer).offset(-wallThickness/2); @@ -254,19 +283,17 @@ D3D.Slicer.prototype.slicesToData = function (slices, printer) { var fill = new D3D.Paths([]); - fills.join(lowFillTemplate.intersect(lowFillArea)); + fill.join(lowFillTemplate.intersect(lowFillArea)); var highFillTemplate = this.getFillTemplate(dimensionsZ, wallThickness, (layer % 2 === 0), (layer % 2 === 1)); - fills.join(highFillTemplate.intersect(highFillArea)); + fill.join(highFillTemplate.intersect(highFillArea)); - outerLayers.push(outerLayer); + layerData.push({ + outerLayer: outerLayer.scaleDown(scale), + fill: fill.scaleDown(scale), + insets: insets.scaleDown(scale) + }); } - - data.push({ - outerLayer: outerLayers.scaleDown(scale), - insets: insets.scaleDown(scale), - fill: fills.scaleDown(scale) - }); } return data; @@ -274,21 +301,21 @@ D3D.Slicer.prototype.slicesToData = function (slices, printer) { D3D.Slicer.prototype.getFillTemplate = function (dimension, size, even, uneven) { "use strict"; - var paths = []; + var paths = new D3D.Paths([], false); if (even) { for (var length = 0; length <= dimension; length += size) { - paths.push(new D3D.Path([{X: length, Y: 0}, {X: length, Y: dimension}], false)); + paths.push([{X: length, Y: 0}, {X: length, Y: dimension}]); } } if (uneven) { for (var length = 0; length <= dimension; length += size) { - paths.push(new D3D.Path([{X: 0, Y: length}, {X: dimension, Y: length}], false)); + paths.push([{X: 0, Y: length}, {X: dimension, Y: length}]); } } //return paths; - return new D3D.Paths(paths); + return paths; }; D3D.Slicer.prototype.dataToGcode = function (data, printer) { "use strict"; @@ -315,8 +342,10 @@ D3D.Slicer.prototype.dataToGcode = function (data, printer) { var previousPoint; - for (var j = 0; j < shape.length; j ++) { - var point = shape[j]; + var length = slice.closed ? (shape.length + 1) : shape.length; + + for (var j = 0; j < length; j ++) { + var point = shape[j % shape.length]; if (j === 0) { //TODO @@ -384,9 +413,13 @@ 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.insets)); - gcode = gcode.concat(sliceToGcode(slice.fill)); + for (var i = 0; i < slice.length; i ++) { + var layerPart = slice[i]; + + gcode = gcode.concat(sliceToGcode(layerPart.outerLayer)); + gcode = gcode.concat(sliceToGcode(layerPart.insets)); + gcode = gcode.concat(sliceToGcode(layerPart.fill)); + } } gcode = gcode.concat(printer.getEndCode()); @@ -411,9 +444,13 @@ D3D.Slicer.prototype.drawPaths = function (printer, min, max) { for (var layer = min; layer < max; layer ++) { var slice = data[layer % data.length]; - //slice.insets.draw(context, "blue"); - slice.outerLayer.draw(context, "green"); - slice.fill.draw(context, "red"); + for (var i = 0; i < slice.length; i ++) { + var layerPart = slice[i]; + + layerPart.insets.draw(context, "blue"); + layerPart.outerLayer.draw(context, "green"); + layerPart.fill.draw(context, "red"); + } } return canvas; @@ -437,7 +474,6 @@ D3D.Slicer.prototype.getGcode = function (printer) { var data = this.slicesToData(slices, printer); var end = new Date().getTime(); - console.log(data); console.log("Data: " + (end - start) + "ms"); //return data;