fixes #12. add start of thin wall detection

This commit is contained in:
Stewart Allen 2017-12-31 11:27:21 -05:00
commit 9fff3c50b5
6 changed files with 116 additions and 18 deletions

View file

@ -28,6 +28,7 @@ var gs_base_polygons = exports;
subtract : subtract,
flatten : flatten,
trimTo : trimTo,
expand2 : expand2,
expand : expand,
union : union,
nest : nest,
@ -429,6 +430,67 @@ var gs_base_polygons = exports;
return polys;
}
/**
* by "over" expanding then contracting, this causes shells that are too
* close together to merge and cancel out. it's a more expensive operation
* but prevents shells that are too close together to extrude properly.
*
* @param {Polygon[]} polys
* @param {number} dist1 first offset distance
* @param {number} dist2 2nd thru last offset distance
* @param {number} over additional offset over then under
* @param {Polygon[]} [out] optional collector
* @param {number} [count] offset passes (0 == until no space left)
* @param {Function} [collector] receives output of each pass
* @param {number} [z] defaults to 0
* @returns {Polygon[]} last offset
*/
function expand2(polys, dist1, dist2, over, out, count, collector, z) {
// prepare alignments for clipper lib
alignWindings(polys);
polys.forEach(function(poly) {
if (poly.inner) setWinding(poly.inner, !poly.isClockwise());
});
var fact = CONF.clipper,
clib = self.ClipperLib,
clip = clib.Clipper,
cpft = clib.PolyFillType,
cjnt = clib.JoinType,
cety = clib.EndType,
coff = new clib.ClipperOffset(),
ctre = new clib.PolyTree();
// inset
polys.forEach(function(poly) {
var clean = clip.CleanPolygons(poly.toClipper(), CONF.clipperClean);
var simple = clip.SimplifyPolygons(clean, cpft.pftNonZero);
coff.AddPaths(simple, cjnt.jtMiter, cety.etClosedPolygon);
});
coff.Execute(ctre, (dist1 + over) * fact);
polys = fromClipperTree(ctre, z);
// outset
coff = new clib.ClipperOffset();
ctre = new clib.PolyTree();
polys.forEach(function(poly) {
var clean = clip.CleanPolygons(poly.toClipper(), CONF.clipperClean);
var simple = clip.SimplifyPolygons(clean, cpft.pftNonZero);
coff.AddPaths(simple, cjnt.jtMiter, cety.etClosedPolygon);
});
coff.Execute(ctre, (-over) * fact);
polys = fromClipperTree(ctre, z);
// process
if (out) out.appendAll(polys);
if (collector) collector(polys, count);
if ((count === 0 || count > 1) && polys.length > 0) {
expand2(polys, dist2 || dist1, dist2, over, out, count > 0 ? count-1 : 0, collector, z);
}
return polys;
}
/**
* @param {Polygon} poly input
* @param {Polygon[]} traces output