fix poly union bug

This commit is contained in:
Stewart Allen 2020-04-26 20:19:02 -04:00
commit 5e49c3191a
3 changed files with 33 additions and 16 deletions

View file

@ -1224,7 +1224,7 @@ var gs_base_polygon = exports;
* @param {Polygon} poly * @param {Polygon} poly
* @returns {?Polygon} intersected polygon or null if no intersection * @returns {?Polygon} intersected polygon or null if no intersection
*/ */
PRO.union = function(poly) { PRO.union = function(poly, min) {
if (!this.overlaps(poly)) return null; if (!this.overlaps(poly)) return null;
var fillang = this.fillang && this.area() > poly.area() ? this.fillang : poly.fillang, var fillang = this.fillang && this.area() > poly.area() ? this.fillang : poly.fillang,
@ -1235,17 +1235,18 @@ var gs_base_polygon = exports;
clip = new clib.Clipper(), clip = new clib.Clipper(),
ctre = new clib.PolyTree(), ctre = new clib.PolyTree(),
sp1 = this.toClipper(), sp1 = this.toClipper(),
sp2 = poly.toClipper(); sp2 = poly.toClipper(),
minarea = min >= 0 ? min : 0.1;
clip.AddPaths(sp1, ptyp.ptSubject, true); clip.AddPaths(sp1, ptyp.ptSubject, true);
clip.AddPaths(sp2, ptyp.ptClip, true); clip.AddPaths(sp2, ptyp.ptClip, true);
if (clip.Execute(ctyp.ctUnion, ctre, cfil.pftEvenOdd, cfil.pftEvenOdd)) { if (clip.Execute(ctyp.ctUnion, ctre, cfil.pftEvenOdd, cfil.pftEvenOdd)) {
poly = POLY().fromClipperTree(ctre, poly.getZ()); let union = POLY().fromClipperTreeUnion(ctre, poly.getZ(), minarea);
if (poly.length === 1) { if (union.length === 1) {
poly = poly[0]; union = union[0];
poly.fillang = fillang; union.fillang = fillang;
return poly; return union;
} }
} }

View file

@ -37,6 +37,7 @@ var gs_base_polygons = exports;
toClipper : toClipper, toClipper : toClipper,
fromClipperNode : fromClipperNode, fromClipperNode : fromClipperNode,
fromClipperTree : fromClipperTree, fromClipperTree : fromClipperTree,
fromClipperTreeUnion: fromClipperTreeUnion,
cleanClipperTree : cleanClipperTree, cleanClipperTree : cleanClipperTree,
fingerprintCompare: fingerprintCompare, fingerprintCompare: fingerprintCompare,
fingerprint: fingerprint fingerprint: fingerprint
@ -82,6 +83,23 @@ var gs_base_polygons = exports;
return polys; return polys;
}; };
function fromClipperTreeUnion(tnode, z, minarea) {
let polys = [], poly;
tnode.m_Childs.forEach(function(child) {
poly = fromClipperNode(child, z);
if (minarea && poly.area() < minarea) {
return;
}
polys.push(poly);
if (child.m_Childs) {
fromClipperTreeUnion(child, z, minarea);
}
});
return polys;
};
function cleanClipperTree(tree) { function cleanClipperTree(tree) {
var clib = self.ClipperLib, var clib = self.ClipperLib,
clip = clib.Clipper; clip = clib.Clipper;
@ -303,10 +321,9 @@ var gs_base_polygons = exports;
* Print.init w/ brims * Print.init w/ brims
* *
* @param {Polygon[]} polys * @param {Polygon[]} polys
* @param {number} [z]
* @returns {Polygon[]} * @returns {Polygon[]}
*/ */
function union(polys) { function union(polys, minarea) {
if (polys.length < 2) return polys; if (polys.length < 2) return polys;
var out = polys.slice(), i, j, union, uset = []; var out = polys.slice(), i, j, union, uset = [];
@ -315,7 +332,7 @@ var gs_base_polygons = exports;
if (!out[i]) continue; if (!out[i]) continue;
for (j=i+1; j<out.length; j++) { for (j=i+1; j<out.length; j++) {
if (!out[j]) continue; if (!out[j]) continue;
union = out[i].union(out[j]); union = out[i].union(out[j], minarea);
if (union) { if (union) {
out[i] = null; out[i] = null;
out[j] = null; out[j] = null;

View file

@ -98,7 +98,7 @@ let gs_kiri_sla = exports;
polys.appendAll(slice.tops.map(t => t.poly.clone())); polys.appendAll(slice.tops.map(t => t.poly.clone()));
}); });
// p.clone prevents inner voids from forming // p.clone prevents inner voids from forming
let union = POLY.union(polys).map(p => p.clone()); let union = POLY.union(polys,0).map(p => p.clone());
let expand = POLY.expand(union, off, zoff, [], 1); let expand = POLY.expand(union, off, zoff, [], 1);
let lastraft; let lastraft;
for (let s=0; s<layers + gap; s++) { for (let s=0; s<layers + gap; s++) {
@ -165,7 +165,7 @@ let gs_kiri_sla = exports;
let traces = POLY.nest(POLY.flatten(slice.gatherTraces([]))); let traces = POLY.nest(POLY.flatten(slice.gatherTraces([])));
let trims = slice.solids.trimmed || []; let trims = slice.solids.trimmed || [];
traces.appendAll(trims); traces.appendAll(trims);
let union = POLY.union(traces); let union = POLY.union(traces,0);
slice.solids.unioned = union; slice.solids.unioned = union;
}, "solid"); }, "solid");
} else { } else {
@ -301,8 +301,7 @@ let gs_kiri_sla = exports;
// union support pillars // union support pillars
slices.forEach(slice => { slices.forEach(slice => {
if (slice.supports) { if (slice.supports) {
// todo unioning seems to be failing slice.supports = POLY.union(slice.supports,0);
// slice.supports = POLY.union(slice.supports);
} }
}); });
} }
@ -548,14 +547,14 @@ let gs_kiri_sla = exports;
} }
if (!cached) { if (!cached) {
fill = POLY.union(fill); fill = POLY.union(fill,0);
fill_cache[seq_c] = fill; fill_cache[seq_c] = fill;
} else { } else {
fill = cached.slice().map(p => p.clone(true).setZ(slice.z)); fill = cached.slice().map(p => p.clone(true).setZ(slice.z));
} }
fill = POLY.trimTo(fill, slice.tops.map(t => t.poly)); fill = POLY.trimTo(fill, slice.tops.map(t => t.poly));
fill = POLY.union(slice.solids.unioned.appendAll(fill)); fill = POLY.union(slice.solids.unioned.appendAll(fill),0);
slice.solids.unioned = fill; slice.solids.unioned = fill;
} }