add polygon.simplify(), xray for sla

This commit is contained in:
Stewart Allen 2022-01-26 17:28:23 -05:00
commit 9085b88380
6 changed files with 84 additions and 60 deletions

View file

@ -108,3 +108,7 @@
# Laser # Laser
* `F` add PLT / HP-GL output format (https://en.wikipedia.org/wiki/HP-GL) * `F` add PLT / HP-GL output format (https://en.wikipedia.org/wiki/HP-GL)
# Other
* investigate libtess https://www.npmjs.com/package/libtess b/c earcut sometimes broken

View file

@ -1411,18 +1411,6 @@
return this.clean(true, undefined, Math.min(CONF.clipper / 10, CONF.clipperClean * 5)); return this.clean(true, undefined, Math.min(CONF.clipper / 10, CONF.clipperClean * 5));
}; };
// does not work with nested polys
PRO.simplify = function(parent) {
if (this.length === 0 || this.open) return [ this ];
let clib = self.ClipperLib,
clip = clib.Clipper,
ctyp = clib.ClipType,
p2cl = this.toClipper(),
clean = clip.SimplifyPolygon(p2cl[0], ctyp.pftPositive),
z = this.getZ();
return clean.map(array => fromClipperPath(array, z));
};
/** /**
* simplify and merge collinear. only works for single * simplify and merge collinear. only works for single
* non-nested polygons. used primarily in slicer/connectLines. * non-nested polygons. used primarily in slicer/connectLines.
@ -1748,14 +1736,40 @@
return (a1 > a2) ? a2 / a1 : a1 / a2; return (a1 > a2) ? a2 / a1 : a1 / a2;
}; };
// does not work with nested polys
PRO.simplify = function(opt = {}) {
let z = this.getZ();
// use expand / deflate technique instead
if (opt.pump) {
let p2 = POLY().offset([ this ], opt.pump, { z });
if (p2) {
p2 = POLY().offset(p2, -opt.pump, { z });
return p2;
}
return null;
}
let clib = self.ClipperLib,
cfil = clib.PolyFillType,
clip = this.toClipper(),
res = clib.Clipper.SimplifyPolygons(clip, cfil.pftNonZero);
if (!(res && res.length)) {
return null;
}
return res.map(array => {
let poly = newPolygon();
for (let pt of array) {
poly.push(BASE.pointFromClipper(pt, z));
}
return poly;
});
};
PRO.unionMatch = function(polys) { PRO.unionMatch = function(polys) {
return polys.filter(poly => poly.isEquivalent(this)).length; return polys.filter(poly => poly.isEquivalent(this)).length;
// for (let poly of polys) {
// if (this.isEquivalent(poly)) {
// return true;
// }
// }
// return false;
}; };
/** /**
@ -1767,41 +1781,45 @@
PRO.union = function(poly, min, all) { PRO.union = function(poly, min, all) {
if (!this.overlaps(poly)) return null; if (!this.overlaps(poly)) return null;
let fillang = this.fillang && this.area() > poly.area() ? this.fillang : poly.fillang, PRO.union = function(poly, min, all) {
clib = self.ClipperLib, if (!this.overlaps(poly)) return null;
ctyp = clib.ClipType,
ptyp = clib.PolyType,
cfil = clib.PolyFillType,
clip = new clib.Clipper(),
ctre = new clib.PolyTree(),
sp1 = this.toClipper(),
sp2 = poly.toClipper(),
minarea = min >= 0 ? min : 0.1;
clip.AddPaths(sp1, ptyp.ptSubject, true); let fillang = this.fillang && this.area() > poly.area() ? this.fillang : poly.fillang,
clip.AddPaths(sp2, ptyp.ptClip, true); clib = self.ClipperLib,
ctyp = clib.ClipType,
ptyp = clib.PolyType,
cfil = clib.PolyFillType,
clip = new clib.Clipper(),
ctre = new clib.PolyTree(),
sp1 = this.toClipper(),
sp2 = poly.toClipper(),
minarea = min >= 0 ? min : 0.1;
if (clip.Execute(ctyp.ctUnion, ctre, cfil.pftEvenOdd, cfil.pftEvenOdd)) { clip.AddPaths(sp1, ptyp.ptSubject, true);
let union = POLY().fromClipperTreeUnion(ctre, poly.getZ(), minarea); clip.AddPaths(sp2, ptyp.ptClip, true);
if (all) {
if (union.length === 2) { if (clip.Execute(ctyp.ctUnion, ctre, cfil.pftEvenOdd, cfil.pftEvenOdd)) {
return null; let union = POLY().fromClipperTreeUnion(ctre, poly.getZ(), minarea);
// if (this.unionMatch(union) || poly.unionMatch(union)) { if (all) {
// return null; if (union.length === 2) {
// } return null;
// if (this.unionMatch(union) || poly.unionMatch(union)) {
// return null;
// }
}
return union;
}
if (union.length === 1) {
union = union[0];
union.fillang = fillang;
return union;
} else {
console.trace({check_union_call_path: union, this: this, poly});
} }
return union;
} }
if (union.length === 1) {
union = union[0];
union.fillang = fillang;
return union;
} else {
console.trace({check_union_call_path: union, this: this, poly});
}
}
return null; return null;
};
}; };
/** ****************************************************************** /** ******************************************************************

View file

@ -82,7 +82,7 @@
let last = slices[slices.length-1]; let last = slices[slices.length-1];
// remove empty slices // remove empty slices
slices = widget.slices = slices.filter(slice => slice.tops.length); slices = widget.slices = slices.filter(slice => slice.tops.length);
if (!process.slaOpenTop) { if (!process.slaOpenTop && !process.xray) {
// re-add last empty slice for open top // re-add last empty slice for open top
slices.push(last); slices.push(last);
} }
@ -212,7 +212,11 @@
SLICER.sliceWidget(widget, { SLICER.sliceWidget(widget, {
height: height, height: height,
add: !process.slaOpenTop, add: !process.slaOpenTop,
concurrent: isConcurrent union: controller.healMesh,
concurrent: isConcurrent,
indices: process.indices || process.xray,
debug: process.xray,
xray: process.xray
}, function(slices) { }, function(slices) {
onSliceDone(slices).then(ondone); onSliceDone(slices).then(ondone);
}, function(update) { }, function(update) {
@ -225,7 +229,6 @@
const render = slice.output(); const render = slice.output();
if (slice.unioned) { if (slice.unioned) {
// console.log('solid', slice.index)
slice.unioned.forEach(poly => { slice.unioned.forEach(poly => {
poly = poly.clone(true);//.move(widget.track.pos); poly = poly.clone(true);//.move(widget.track.pos);
render render
@ -233,7 +236,6 @@
.addAreas([poly], { outline: true }); .addAreas([poly], { outline: true });
}); });
} else if (slice.tops) { } else if (slice.tops) {
// console.log('top', slice.index)
slice.tops.forEach(top => { slice.tops.forEach(top => {
let poly = top.poly;//.clone(true).move(widget.track.pos); let poly = top.poly;//.clone(true).move(widget.track.pos);
render render
@ -243,7 +245,6 @@
} }
if (slice.supports) { if (slice.supports) {
// console.log('support', slice.index)
slice.supports.forEach(poly => { slice.supports.forEach(poly => {
render render
.setLayer("support", { line: 0x010101, face: 0xfcba03, opacity: 0.2 }) .setLayer("support", { line: 0x010101, face: 0xfcba03, opacity: 0.2 })

View file

@ -2641,7 +2641,7 @@
$('rot_z_gt').onclick = () => { API.selection.rotate(0,0,-d) }; $('rot_z_gt').onclick = () => { API.selection.rotate(0,0,-d) };
// rendering options // rendering options
$('render-hide').onclick = () => { API.view.wireframe(false, 0, 0); }; $('render-hide').onclick = () => { API.view.wireframe(false, 0, 0); };
$('render-ghost').onclick = () => { API.view.wireframe(false, 0, API.view.isArrange() ? 0.5 : 0.25); }; $('render-ghost').onclick = () => { API.view.wireframe(false, 0, API.view.isArrange() ? 0.4 : 0.25); };
$('render-wire').onclick = () => { API.view.wireframe(true, 0, API.space.isDark() ? 0.25 : 0.5); }; $('render-wire').onclick = () => { API.view.wireframe(true, 0, API.space.isDark() ? 0.25 : 0.5); };
$('render-solid').onclick = () => { API.view.wireframe(false, 0, 1); }; $('render-solid').onclick = () => { API.view.wireframe(false, 0, 1); };
// mesh buttons // mesh buttons

View file

@ -250,7 +250,7 @@
const devel = { const devel = {
xray: (layers) => { xray: (layers) => {
let proc = API.conf.get().process; let proc = API.conf.get().process;
let size = proc.sliceHeight || 1; let size = proc.sliceHeight || proc.slaSlice || 1;
layers = Array.isArray(layers) ? layers : [ layers ]; layers = Array.isArray(layers) ? layers : [ layers ];
proc.xray = layers.map(l => l * size + size / 2); proc.xray = layers.map(l => l * size + size / 2);
API.function.slice(); API.function.slice();
@ -1269,7 +1269,7 @@
if (scale === 1) { if (scale === 1) {
updateStackLabelState(); updateStackLabelState();
} }
if (control.lineType === 'line') { if (!isBelt && control.lineType === 'line' && !process.xray) {
$('render-ghost').onclick(); $('render-ghost').onclick();
} }
}); });
@ -1404,7 +1404,8 @@
} }
updateStackLabelState(); updateStackLabelState();
if (settings.controller.lineType === 'line') { let { controller, process } = settings;
if (!isBelt && controller.lineType === 'line' && !process.xray) {
$('render-ghost').onclick(); $('render-ghost').onclick();
} }

View file

@ -675,7 +675,7 @@
let closed = path[0].group.indexOf(path.peek()) >= 0; let closed = path[0].group.indexOf(path.peek()) >= 0;
if (closed && path.length > 2) { if (closed && path.length > 2) {
if (debug) console.log({ closed: path.length, path }); if (debug) console.log({ closed: path.length, path });
emit(BASE.newPolygon().addPoints(path), debug); emit(BASE.newPolygon().addPoints(path));
} else if (path.length > 1) { } else if (path.length > 1) {
let gap = path[0].distTo2D(path.peek()).round(4); let gap = path[0].distTo2D(path.peek()).round(4);
if (debug) console.log({ open: path.length, gap, path }); if (debug) console.log({ open: path.length, gap, path });