add polygon.simplify(), xray for sla
This commit is contained in:
parent
6608d9d3d2
commit
9085b88380
6 changed files with 84 additions and 60 deletions
4
notes.md
4
notes.md
|
|
@ -108,3 +108,7 @@
|
|||
# Laser
|
||||
|
||||
* `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
|
||||
|
|
|
|||
|
|
@ -1411,18 +1411,6 @@
|
|||
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
|
||||
* non-nested polygons. used primarily in slicer/connectLines.
|
||||
|
|
@ -1748,14 +1736,40 @@
|
|||
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) {
|
||||
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) {
|
||||
if (!this.overlaps(poly)) return null;
|
||||
|
||||
let fillang = this.fillang && this.area() > poly.area() ? this.fillang : poly.fillang,
|
||||
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;
|
||||
PRO.union = function(poly, min, all) {
|
||||
if (!this.overlaps(poly)) return null;
|
||||
|
||||
clip.AddPaths(sp1, ptyp.ptSubject, true);
|
||||
clip.AddPaths(sp2, ptyp.ptClip, true);
|
||||
let fillang = this.fillang && this.area() > poly.area() ? this.fillang : poly.fillang,
|
||||
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)) {
|
||||
let union = POLY().fromClipperTreeUnion(ctre, poly.getZ(), minarea);
|
||||
if (all) {
|
||||
if (union.length === 2) {
|
||||
return null;
|
||||
// if (this.unionMatch(union) || poly.unionMatch(union)) {
|
||||
// return null;
|
||||
// }
|
||||
clip.AddPaths(sp1, ptyp.ptSubject, true);
|
||||
clip.AddPaths(sp2, ptyp.ptClip, true);
|
||||
|
||||
if (clip.Execute(ctyp.ctUnion, ctre, cfil.pftEvenOdd, cfil.pftEvenOdd)) {
|
||||
let union = POLY().fromClipperTreeUnion(ctre, poly.getZ(), minarea);
|
||||
if (all) {
|
||||
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;
|
||||
};
|
||||
};
|
||||
|
||||
/** ******************************************************************
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@
|
|||
let last = slices[slices.length-1];
|
||||
// remove empty slices
|
||||
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
|
||||
slices.push(last);
|
||||
}
|
||||
|
|
@ -212,7 +212,11 @@
|
|||
SLICER.sliceWidget(widget, {
|
||||
height: height,
|
||||
add: !process.slaOpenTop,
|
||||
concurrent: isConcurrent
|
||||
union: controller.healMesh,
|
||||
concurrent: isConcurrent,
|
||||
indices: process.indices || process.xray,
|
||||
debug: process.xray,
|
||||
xray: process.xray
|
||||
}, function(slices) {
|
||||
onSliceDone(slices).then(ondone);
|
||||
}, function(update) {
|
||||
|
|
@ -225,7 +229,6 @@
|
|||
const render = slice.output();
|
||||
|
||||
if (slice.unioned) {
|
||||
// console.log('solid', slice.index)
|
||||
slice.unioned.forEach(poly => {
|
||||
poly = poly.clone(true);//.move(widget.track.pos);
|
||||
render
|
||||
|
|
@ -233,7 +236,6 @@
|
|||
.addAreas([poly], { outline: true });
|
||||
});
|
||||
} else if (slice.tops) {
|
||||
// console.log('top', slice.index)
|
||||
slice.tops.forEach(top => {
|
||||
let poly = top.poly;//.clone(true).move(widget.track.pos);
|
||||
render
|
||||
|
|
@ -243,7 +245,6 @@
|
|||
}
|
||||
|
||||
if (slice.supports) {
|
||||
// console.log('support', slice.index)
|
||||
slice.supports.forEach(poly => {
|
||||
render
|
||||
.setLayer("support", { line: 0x010101, face: 0xfcba03, opacity: 0.2 })
|
||||
|
|
|
|||
|
|
@ -2641,7 +2641,7 @@
|
|||
$('rot_z_gt').onclick = () => { API.selection.rotate(0,0,-d) };
|
||||
// rendering options
|
||||
$('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-solid').onclick = () => { API.view.wireframe(false, 0, 1); };
|
||||
// mesh buttons
|
||||
|
|
|
|||
|
|
@ -250,7 +250,7 @@
|
|||
const devel = {
|
||||
xray: (layers) => {
|
||||
let proc = API.conf.get().process;
|
||||
let size = proc.sliceHeight || 1;
|
||||
let size = proc.sliceHeight || proc.slaSlice || 1;
|
||||
layers = Array.isArray(layers) ? layers : [ layers ];
|
||||
proc.xray = layers.map(l => l * size + size / 2);
|
||||
API.function.slice();
|
||||
|
|
@ -1269,7 +1269,7 @@
|
|||
if (scale === 1) {
|
||||
updateStackLabelState();
|
||||
}
|
||||
if (control.lineType === 'line') {
|
||||
if (!isBelt && control.lineType === 'line' && !process.xray) {
|
||||
$('render-ghost').onclick();
|
||||
}
|
||||
});
|
||||
|
|
@ -1404,7 +1404,8 @@
|
|||
}
|
||||
updateStackLabelState();
|
||||
|
||||
if (settings.controller.lineType === 'line') {
|
||||
let { controller, process } = settings;
|
||||
if (!isBelt && controller.lineType === 'line' && !process.xray) {
|
||||
$('render-ghost').onclick();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -675,7 +675,7 @@
|
|||
let closed = path[0].group.indexOf(path.peek()) >= 0;
|
||||
if (closed && path.length > 2) {
|
||||
if (debug) console.log({ closed: path.length, path });
|
||||
emit(BASE.newPolygon().addPoints(path), debug);
|
||||
emit(BASE.newPolygon().addPoints(path));
|
||||
} else if (path.length > 1) {
|
||||
let gap = path[0].distTo2D(path.peek()).round(4);
|
||||
if (debug) console.log({ open: path.length, gap, path });
|
||||
|
|
|
|||
Loading…
Reference in a new issue