diff --git a/src/geo/polygon.js b/src/geo/polygon.js index fd476a96..95a9d5c9 100644 --- a/src/geo/polygon.js +++ b/src/geo/polygon.js @@ -704,6 +704,10 @@ return !this.open; }; + PRO.appearsClosed = function() { + return this.first().isEqual(this.last()); + }; + PRO.setClockwise = function() { if (!this.isClockwise()) this.reverse(); return this; diff --git a/src/mode/cam/topo.js b/src/mode/cam/topo.js index 63bb8c40..2528e458 100644 --- a/src/mode/cam/topo.js +++ b/src/mode/cam/topo.js @@ -73,7 +73,7 @@ // return the touching z given topo x,y and a tool profile function toolTipZ(x,y) { - let profile = toolOffset, + const profile = toolOffset, sx = stepsx, sy = stepsy, xl = sx - 1, @@ -101,7 +101,7 @@ } function push_point(x,y,z) { - let newP = newPoint(x,y,z); + const newP = newPoint(x,y,z); if (lastP && lastP.z === z) { if (curvesOnly) { end_poly(); @@ -138,27 +138,27 @@ gridy, gridi, // index gridv, // value - x, y, tv, ltv; + i, il, j, jl, x, y, tv, ltv; // for each Y slice, find z grid value (x/z swapped) - for (let j=0, jl=slices.length; j zMin || p2.z > zMin) && // one endpoint above 0 (p1.z > gridv || p2.z > gridv) && // one endpoint above gridv ((p1.y <= y && p2.y >= y) || // one endpoint left (p2.y <= y && p1.y >= y)) // one endpoint right ) { - let dy = p1.y - p2.y, + const dy = p1.y - p2.y, dz = p1.z - p2.z, pct = (p1.y - y) / dy, nz = p1.z - (dz * pct); diff --git a/src/mode/fdm/prepare.js b/src/mode/fdm/prepare.js index 899e9222..59b30b0e 100644 --- a/src/mode/fdm/prepare.js +++ b/src/mode/fdm/prepare.js @@ -409,12 +409,24 @@ const opts = options || {}; const tools = opts.tools || {}; - const thin = opts.thin || false; + const flat = opts.flat; + const thin = opts.thin && !flat; const ckspeed = opts.speed !== false; const moveColor = opts.move >= 0 ? opts.move : 0xaaaaaa; const printColor = opts.print >= 0 ? opts.print : 0x777700; const layers = []; + const moveOpt = { + face: moveColor, + line: flat ? 1 : moveColor, + opacity: flat ? 0.5 : 1 + }; + const printOpt = { + face: printColor, + line: flat ? 1 : printColor, + opacity: flat ? 0.5 : 1 + }; + const maxspd = levels.map(level => { return level.map(o => o.speed || 0).reduce((a, v) => Math.max(a,v)); }).reduce((a, v) => Math.max(a, v)) + 1; @@ -422,6 +434,7 @@ // for reporting self.worker.print.maxSpeed = maxspd - 1; self.worker.print.thinColor = thin; + self.worker.print.flatColor = flat; let lastOut = null; let current = null; @@ -490,15 +503,26 @@ pushPrint(lastOut.tool, current) } output - .setLayer(opts.other || 'move', moveColor, opts.moves !== true) + .setLayer(opts.other || 'move', moveOpt, opts.moves !== true) .addPolys(moves, { thin: true, z: opts.z }); Object.values(prints).forEach(array => { - array.forEach(poly => { if (poly.length > 1) output - .setLayer(opts.action || 'print', printColor) - .addPolys([ poly ], thin ? { thin, z: opts.z, color: poly.color } : { - offset: array.width, height, z: opts.z, - color: { face: poly.color, line: poly.color } - }) + array.forEach(poly => { + if (poly.appearsClosed()) { + poly.setClosed(); + poly.points.pop(); + poly.length--; + } + output + .setLayer(opts.action || 'print', printOpt) + .addPolys([ poly ], + thin ? { thin, z: opts.z, color: poly.color } : + flat ? { + flat, z: opts.z, color: poly.color, + outline: true, offset: array.width, open: poly.open } : + { + offset: array.width, height, z: opts.z, + color: { face: poly.color, line: poly.color } + }) }); }); diff --git a/src/mode/fdm/slice.js b/src/mode/fdm/slice.js index 76643e51..c15ae15f 100644 --- a/src/mode/fdm/slice.js +++ b/src/mode/fdm/slice.js @@ -30,7 +30,11 @@ function vopt(opt) { if (opt) { - if (isFlat) { opt.flat = true; return opt } + if (isFlat) { + opt.flat = true; + opt.outline = true; + return opt + } if (isThin) return null; } return opt; @@ -71,9 +75,17 @@ view = widget.mesh && widget.mesh.newGroup ? widget.mesh.newGroup() : null; isFlat = false; - isThin = settings.controller.thinRender; + isThin = !isFlat && settings.controller.thinRender; offset = nozzleSize / 2; + if (isFlat) { + Object.values(COLOR).forEach(color => { + color.flat = true; + color.line = 1 + color.opacity = 0.5; + }); + }; + if (!(sliceHeight > 0 && sliceHeight < 100)) { return ondone("invalid slice height"); }