try using xor to heal non-manifold / overlapping sliced polys. aka deathstar fix
This commit is contained in:
parent
cfa9eacbb2
commit
d7d136ad8c
5 changed files with 54 additions and 7 deletions
|
|
@ -30,6 +30,7 @@ const POLY = polygons,
|
|||
EndType = ClipperLib.EndType,
|
||||
JoinType = ClipperLib.JoinType,
|
||||
PolyTree = ClipperLib.PolyTree,
|
||||
ClipXOR = ClipType.ctXor,
|
||||
ClipDiff = ClipType.ctDifference,
|
||||
ClipUnion = ClipType.ctUnion,
|
||||
ClipIntersect = ClipType.ctIntersection,
|
||||
|
|
@ -1769,9 +1770,30 @@ class Polygon {
|
|||
|
||||
if (clip.Execute(ClipDiff, tree, FillEvenOdd, FillEvenOdd)) {
|
||||
poly = POLY.fromClipperTree(tree, poly.getZ());
|
||||
poly.forEach(p => {
|
||||
p.fillang = fillang;
|
||||
})
|
||||
poly.forEach(p => p.fillang = fillang);
|
||||
return poly;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Polygon} poly poly to xor against this one
|
||||
* @returns {?Polygon[]}
|
||||
*/
|
||||
xor(poly) {
|
||||
let fillang = this.fillang && this.area() > poly.area() ? this.fillang : poly.fillang,
|
||||
clip = new Clipper(),
|
||||
tree = new PolyTree(),
|
||||
sp1 = this.toClipper(),
|
||||
sp2 = poly.toClipper();
|
||||
|
||||
clip.AddPaths(sp1, PathSubject, true);
|
||||
clip.AddPaths(sp2, PathClip, true);
|
||||
|
||||
if (clip.Execute(ClipXOR, tree, FillNonZero, FillNonZero)) {
|
||||
poly = POLY.fromClipperTree(tree, poly.getZ());
|
||||
poly.forEach(p => p.fillang = fillang);
|
||||
return poly;
|
||||
} else {
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -388,9 +388,21 @@ async function sliceZ(z, points, options = {}) {
|
|||
if (groupFn) {
|
||||
let groups = groupFn(lines, z, options);
|
||||
if (options.union) {
|
||||
let points = groups.map(p => p.length).reduce((a,b) => a + b);
|
||||
// simplistic healing of non-manifold meshes
|
||||
let opt = { x: 1 };
|
||||
let union = POLY.union(POLY.nest(groups), 0.1, true, opt);
|
||||
// fall back to xor'ing polygons that might overlap
|
||||
// when one does not cleanly contain the other and we lose lots of points
|
||||
// trigger when 2 polygons and we lose > 40% of points in the union
|
||||
let delta = opt.changes < 0 ? Math.abs(opt.changes / points) : 0;
|
||||
if (groups.length === 2 && delta >= 0.4) {
|
||||
let xor = groups[0].xor(groups[1]);
|
||||
console.log({ points, pct: (opt.changes / points).round(3), xor: xor.length });
|
||||
if (xor.length) {
|
||||
union = xor;
|
||||
}
|
||||
}
|
||||
// track total poly length changes to determine if healed
|
||||
rval.changes = opt.changes;
|
||||
groups = POLY.flatten(union, null, true);
|
||||
|
|
@ -749,7 +761,7 @@ function sliceConnect(input, z, opt = {}) {
|
|||
emit(newPolygon().addPoints(array));
|
||||
}
|
||||
|
||||
if (debug) console.log({ emitted });
|
||||
if (debug) console.log({ emitted, output });
|
||||
if (debug && emitted < points.length) console.log({ leftovers:points.length - emitted });
|
||||
|
||||
return output;
|
||||
|
|
|
|||
|
|
@ -828,7 +828,13 @@ FDM.export = function(print, online, ondone, ondebug) {
|
|||
}
|
||||
|
||||
// update time and distance (should calc in moveTo() instead)
|
||||
time += (dist / speedMMM) * 60 * timeFactor;
|
||||
if (dist && speedMMM) {
|
||||
time += (dist / speedMMM) * 60 * timeFactor;
|
||||
}
|
||||
// if (isNaN(time)) {
|
||||
// console.log({ layer, path, dist, speedMMM, timeFactor });
|
||||
// throw "NaN";
|
||||
// }
|
||||
distance += dist;
|
||||
subst.progress = progress = Math.round((distance / totaldistance) * 100);
|
||||
|
||||
|
|
|
|||
|
|
@ -323,7 +323,7 @@ FDM.slice = function(settings, widget, onupdate, ondone) {
|
|||
healed = true;
|
||||
slice.changes = changes;
|
||||
if (self.debug) {
|
||||
console.log('slice healed', slice.index, slice.z);
|
||||
console.log('slice healed', slice.index, slice.z, changes);
|
||||
}
|
||||
}
|
||||
if (process.xray) {
|
||||
|
|
|
|||
|
|
@ -264,6 +264,7 @@ class Print {
|
|||
height = 0,
|
||||
factor = 1,
|
||||
tool = 0,
|
||||
time = 0,
|
||||
minf = Infinity,
|
||||
maxf = 0,
|
||||
seq = [],
|
||||
|
|
@ -458,11 +459,13 @@ class Print {
|
|||
(Math.pow(pos.X - lastPos.X, 2)) +
|
||||
(Math.pow(pos.Y - lastPos.Y, 2))
|
||||
);
|
||||
// debug print time
|
||||
time += (dV * pos.F) / 1000;
|
||||
// filament per mm
|
||||
let dR = (dE / dV);
|
||||
if (dV > 2 && dE > 0.001) {
|
||||
let lab = (absE ? 'aA' : 'rR')[scope.debugE++ % 2];
|
||||
// console.log(lab, height.toFixed(2), dV.toFixed(2), dE.toFixed(3), dR.toFixed(4), pos.F.toFixed(0));
|
||||
console.log(lab, height.toFixed(2), dV.toFixed(2), dE.toFixed(3), dR.toFixed(4), pos.F.toFixed(0));
|
||||
}
|
||||
}
|
||||
// add point to current sequence
|
||||
|
|
@ -578,6 +581,10 @@ class Print {
|
|||
scope.maxSpeed = Math.floor(maxf / 60);
|
||||
scope.belt = belt;
|
||||
|
||||
if (scope.debugE) {
|
||||
console.log({ print_time: time.round(2) });
|
||||
}
|
||||
|
||||
done({ output: scope.output });
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue