diff --git a/notes.md b/notes.md index 1030a5c4..ed7f8ee9 100644 --- a/notes.md +++ b/notes.md @@ -1,6 +1,7 @@ # Kiri:Moto todo ## 2.3 remaining +* cnc path routing collisions with two or more parts * cap path ends * onshape mouse mapping option @@ -11,6 +12,7 @@ * cnc: step down should interpolate top/bottom again * cnc: adaptive shadow-line generation for small parts collision detection * fdm: manual supports, continuous printing +* onshape: session token timeout bug * all: 2d image to 3d part ## `C` cosmetic, `F` functional, `P` performance, `B` bug fix diff --git a/package.json b/package.json index f1264aa1..355e87a5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "grid-apps", - "version": "2.3.11.D", + "version": "2.3.12.D", "description": "grid.space 3d slice & modeling tools", "author": "Stewart Allen ", "license": "MIT", diff --git a/src/geo/polygon.js b/src/geo/polygon.js index 436d900d..533d8463 100644 --- a/src/geo/polygon.js +++ b/src/geo/polygon.js @@ -1192,6 +1192,7 @@ } poly.parent = parent || this.parent; poly.area2 = this.area2; + poly.open = this.open; return poly; }; diff --git a/src/geo/polygons.js b/src/geo/polygons.js index 7c88bfd4..b6d534d3 100644 --- a/src/geo/polygons.js +++ b/src/geo/polygons.js @@ -466,6 +466,9 @@ * in FDM mode and uncleared areas in CAM mode. */ function offset(polys, dist, options) { + // do not offset open lines + polys = polys.filter(p => !p.open); + // cause inner / outer polys to be reversed from each other alignWindings(polys); polys.forEach(function(poly) { diff --git a/src/kiri/slice.js b/src/kiri/slice.js index 2f89d8f8..ef4f0d69 100644 --- a/src/kiri/slice.js +++ b/src/kiri/slice.js @@ -186,6 +186,16 @@ return min; }; + PRO.xray = function(dash = 3) { + console.log('xray', this); + this.output().setLayer(`xp`, 0x888800).addPolys(this.topPolys()); + this.lines.forEach((line, i) => { + const group = i % dash; + const color = [ 0xff0000, 0x00ff00, 0x0000ff, 0xffff00, 0xff00ff ][group]; + this.output().setLayer(`xl-${group}`, color).addLine(line.p1, line.p2); + }); + }; + function newTop(poly) { return new Top(poly); } diff --git a/src/kiri/slicer2.js b/src/kiri/slicer2.js index 273cc9be..7e00c746 100644 --- a/src/kiri/slicer2.js +++ b/src/kiri/slicer2.js @@ -20,6 +20,17 @@ } } + // notopok = when genso set, allow empty top array + // emptyok = allow empty slices + // openok = allow open tops + // swapX = swap X/Z + // swapY = sawp Y/Z + // zList = generate list of z vertices + // zline = generate list of z vertices with coplanar lines + // trace = find z coplanar trace lines + // flatoff = amount to offset z when slicing on detected flats + // genso = generate a slice object with tops + // each = call for each slice generated from an interval setOptions(options) { Object.assign(this.options, options || {}); return this.options; @@ -243,7 +254,7 @@ if (lines.length) { retn.lines = removeDuplicateLines(lines); - retn.tops = POLY.nest(connectLines(retn.lines)); + retn.tops = POLY.nest(connectLines(retn.lines, opt)); if (opt.swapX || opt.swapY) { this.unswap(opt.swapX, opt.swapY, retn.lines, retn.tops); @@ -256,11 +267,14 @@ } } - if (opt.each && (lines.length || opt.emptyok)) { + const haslines = lines.length || opt.emptyok; + const hastops = !opt.genso || retn.tops.length || opt.notopok; + + if (opt.each && haslines && hastops) { opt.each(retn, index, total, UTIL.time() - mark); } - return retn; + return haslines && hastops ? retn : null; } swap(points, options) { @@ -466,7 +480,7 @@ * @param {number} [index] * @returns {Array} */ - function connectLines(input) { + function connectLines(input, opt = {}) { // map points to all other points they're connected to let DBUG = BASE.debug, CONF = BASE.config, @@ -662,7 +676,9 @@ tmp, dist, j; if (!bridge) { - emit(BASE.newPolygon().addPoints(array).setOpen()); + if (opt.openok) { + emit(BASE.newPolygon().addPoints(array).setOpen()); + } continue; } diff --git a/src/license.js b/src/license.js index 374c51f8..6853d043 100644 --- a/src/license.js +++ b/src/license.js @@ -3,7 +3,7 @@ let terms = { COPYRIGHT: "Copyright (C) Stewart Allen - All Rights Reserved", LICENSE: "See the license.md file included with the source distribution", - VERSION: "2.3.D11" + VERSION: "2.3.D12" }; if (typeof(module) === 'object') { diff --git a/src/mode/cam/slice.js b/src/mode/cam/slice.js index 1ed44638..08cc2f1d 100644 --- a/src/mode/cam/slice.js +++ b/src/mode/cam/slice.js @@ -125,8 +125,9 @@ tshadow = POLY.union(tshadow.appendAll(data.tops), 0.01, true); tslices.push(data.slice); if (false) { - sliceAll.push(data.slice); - data.slice.output() + const slice = data.slice; + sliceAll.push(slice); + slice.output() .setLayer("debug", {line: 0x888800, thin: true }) .addPolys(POLY.setZ(tshadow.clone(true), data.z), { thin: true }); } @@ -295,6 +296,7 @@ let shadow = []; let slices = []; const indices = slicer.interval(outlineDown, { down: true, min: zBottom, fit: true }); + // console.log('indices', ...indices, {zBottom, slicer}); slicer.slice(indices, { each: (data, index, total) => { shadow = POLY.union(shadow.appendAll(data.tops), 0.01, true); data.shadow = shadow.clone(true); @@ -303,6 +305,7 @@ // data.slice.tops[0].inner = data.shadow; // data.slice.tops[0].inner = POLY.setZ(tshadow.clone(true), data.z); slices.push(data.slice); + // data.slice.xray(); // onupdate(0.2 + (index/total) * 0.1, "outlines"); updateOp(index, total); }, genso: true }); @@ -324,6 +327,10 @@ slices.forEach(slice => { let tops = slice.shadow;//.clone(true); let offset = POLY.expand(tops, outlineToolDiam / 2, slice.z); + if (!(offset && offset.length)) { + return; + } + // when pocket only, drop first outer poly // if it matches the shell and promote inner polys if (procOutlineIn) { @@ -354,6 +361,7 @@ if (addTabsOutline && slice.z <= zMin + tabHeight) { offset = addCutoutTabs(offset, slice.z, outlineToolDiam, tabWidth, proc.camTabsCount, proc.camTabsAngle); } + // offset.xout(`slice ${slice.z}`); slice.camLines = offset; if (true) slice.output()