fix open traces in slice and resulting empty top slices. do not offset open polys in expand()

This commit is contained in:
Stewart Allen 2020-11-17 00:45:34 -05:00
commit 8ac7d3b89a
8 changed files with 49 additions and 9 deletions

View file

@ -1,6 +1,7 @@
# Kiri:Moto todo # Kiri:Moto todo
## 2.3 remaining ## 2.3 remaining
* cnc path routing collisions with two or more parts
* cap path ends * cap path ends
* onshape mouse mapping option * onshape mouse mapping option
@ -11,6 +12,7 @@
* cnc: step down should interpolate top/bottom again * cnc: step down should interpolate top/bottom again
* cnc: adaptive shadow-line generation for small parts collision detection * cnc: adaptive shadow-line generation for small parts collision detection
* fdm: manual supports, continuous printing * fdm: manual supports, continuous printing
* onshape: session token timeout bug
* all: 2d image to 3d part * all: 2d image to 3d part
## `C` cosmetic, `F` functional, `P` performance, `B` bug fix ## `C` cosmetic, `F` functional, `P` performance, `B` bug fix

View file

@ -1,6 +1,6 @@
{ {
"name": "grid-apps", "name": "grid-apps",
"version": "2.3.11.D", "version": "2.3.12.D",
"description": "grid.space 3d slice & modeling tools", "description": "grid.space 3d slice & modeling tools",
"author": "Stewart Allen <sa@grid.space>", "author": "Stewart Allen <sa@grid.space>",
"license": "MIT", "license": "MIT",

View file

@ -1192,6 +1192,7 @@
} }
poly.parent = parent || this.parent; poly.parent = parent || this.parent;
poly.area2 = this.area2; poly.area2 = this.area2;
poly.open = this.open;
return poly; return poly;
}; };

View file

@ -466,6 +466,9 @@
* in FDM mode and uncleared areas in CAM mode. * in FDM mode and uncleared areas in CAM mode.
*/ */
function offset(polys, dist, options) { 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 // cause inner / outer polys to be reversed from each other
alignWindings(polys); alignWindings(polys);
polys.forEach(function(poly) { polys.forEach(function(poly) {

View file

@ -186,6 +186,16 @@
return min; 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) { function newTop(poly) {
return new Top(poly); return new Top(poly);
} }

View file

@ -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) { setOptions(options) {
Object.assign(this.options, options || {}); Object.assign(this.options, options || {});
return this.options; return this.options;
@ -243,7 +254,7 @@
if (lines.length) { if (lines.length) {
retn.lines = removeDuplicateLines(lines); retn.lines = removeDuplicateLines(lines);
retn.tops = POLY.nest(connectLines(retn.lines)); retn.tops = POLY.nest(connectLines(retn.lines, opt));
if (opt.swapX || opt.swapY) { if (opt.swapX || opt.swapY) {
this.unswap(opt.swapX, opt.swapY, retn.lines, retn.tops); 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); opt.each(retn, index, total, UTIL.time() - mark);
} }
return retn; return haslines && hastops ? retn : null;
} }
swap(points, options) { swap(points, options) {
@ -466,7 +480,7 @@
* @param {number} [index] * @param {number} [index]
* @returns {Array} * @returns {Array}
*/ */
function connectLines(input) { function connectLines(input, opt = {}) {
// map points to all other points they're connected to // map points to all other points they're connected to
let DBUG = BASE.debug, let DBUG = BASE.debug,
CONF = BASE.config, CONF = BASE.config,
@ -662,7 +676,9 @@
tmp, dist, j; tmp, dist, j;
if (!bridge) { if (!bridge) {
emit(BASE.newPolygon().addPoints(array).setOpen()); if (opt.openok) {
emit(BASE.newPolygon().addPoints(array).setOpen());
}
continue; continue;
} }

View file

@ -3,7 +3,7 @@
let terms = { let terms = {
COPYRIGHT: "Copyright (C) Stewart Allen <sa@grid.space> - All Rights Reserved", COPYRIGHT: "Copyright (C) Stewart Allen <sa@grid.space> - All Rights Reserved",
LICENSE: "See the license.md file included with the source distribution", LICENSE: "See the license.md file included with the source distribution",
VERSION: "2.3.D11" VERSION: "2.3.D12"
}; };
if (typeof(module) === 'object') { if (typeof(module) === 'object') {

View file

@ -125,8 +125,9 @@
tshadow = POLY.union(tshadow.appendAll(data.tops), 0.01, true); tshadow = POLY.union(tshadow.appendAll(data.tops), 0.01, true);
tslices.push(data.slice); tslices.push(data.slice);
if (false) { if (false) {
sliceAll.push(data.slice); const slice = data.slice;
data.slice.output() sliceAll.push(slice);
slice.output()
.setLayer("debug", {line: 0x888800, thin: true }) .setLayer("debug", {line: 0x888800, thin: true })
.addPolys(POLY.setZ(tshadow.clone(true), data.z), { thin: true }); .addPolys(POLY.setZ(tshadow.clone(true), data.z), { thin: true });
} }
@ -295,6 +296,7 @@
let shadow = []; let shadow = [];
let slices = []; let slices = [];
const indices = slicer.interval(outlineDown, { down: true, min: zBottom, fit: true }); const indices = slicer.interval(outlineDown, { down: true, min: zBottom, fit: true });
// console.log('indices', ...indices, {zBottom, slicer});
slicer.slice(indices, { each: (data, index, total) => { slicer.slice(indices, { each: (data, index, total) => {
shadow = POLY.union(shadow.appendAll(data.tops), 0.01, true); shadow = POLY.union(shadow.appendAll(data.tops), 0.01, true);
data.shadow = shadow.clone(true); data.shadow = shadow.clone(true);
@ -303,6 +305,7 @@
// data.slice.tops[0].inner = data.shadow; // data.slice.tops[0].inner = data.shadow;
// data.slice.tops[0].inner = POLY.setZ(tshadow.clone(true), data.z); // data.slice.tops[0].inner = POLY.setZ(tshadow.clone(true), data.z);
slices.push(data.slice); slices.push(data.slice);
// data.slice.xray();
// onupdate(0.2 + (index/total) * 0.1, "outlines"); // onupdate(0.2 + (index/total) * 0.1, "outlines");
updateOp(index, total); updateOp(index, total);
}, genso: true }); }, genso: true });
@ -324,6 +327,10 @@
slices.forEach(slice => { slices.forEach(slice => {
let tops = slice.shadow;//.clone(true); let tops = slice.shadow;//.clone(true);
let offset = POLY.expand(tops, outlineToolDiam / 2, slice.z); let offset = POLY.expand(tops, outlineToolDiam / 2, slice.z);
if (!(offset && offset.length)) {
return;
}
// when pocket only, drop first outer poly // when pocket only, drop first outer poly
// if it matches the shell and promote inner polys // if it matches the shell and promote inner polys
if (procOutlineIn) { if (procOutlineIn) {
@ -354,6 +361,7 @@
if (addTabsOutline && slice.z <= zMin + tabHeight) { if (addTabsOutline && slice.z <= zMin + tabHeight) {
offset = addCutoutTabs(offset, slice.z, outlineToolDiam, tabWidth, proc.camTabsCount, proc.camTabsAngle); offset = addCutoutTabs(offset, slice.z, outlineToolDiam, tabWidth, proc.camTabsCount, proc.camTabsAngle);
} }
// offset.xout(`slice ${slice.z}`); // offset.xout(`slice ${slice.z}`);
slice.camLines = offset; slice.camLines = offset;
if (true) slice.output() if (true) slice.output()