add precursor thin wall detection

This commit is contained in:
Stewart Allen 2018-01-09 19:07:37 -05:00
commit 28097e84f1
2 changed files with 55 additions and 14 deletions

View file

@ -386,6 +386,14 @@ var gs_base_polygons = exports;
return out; return out;
} }
function sumCirc(polys) {
var sum = 0.0;
polys.forEach(function(poly) {
sum += poly.circularityDeep();
});
return sum;
}
/** /**
* @param {Polygon[]} polys * @param {Polygon[]} polys
* @param {number} distance offset * @param {number} distance offset
@ -410,7 +418,8 @@ var gs_base_polygons = exports;
cjnt = clib.JoinType, cjnt = clib.JoinType,
cety = clib.EndType, cety = clib.EndType,
coff = new clib.ClipperOffset(), coff = new clib.ClipperOffset(),
ctre = new clib.PolyTree(); ctre = new clib.PolyTree(),
circ = sumCirc(polys);
polys.forEach(function(poly) { polys.forEach(function(poly) {
var clean = clip.CleanPolygons(poly.toClipper(), CONF.clipperClean); var clean = clip.CleanPolygons(poly.toClipper(), CONF.clipperClean);
@ -439,13 +448,14 @@ var gs_base_polygons = exports;
* @param {number} dist1 first offset distance * @param {number} dist1 first offset distance
* @param {number} dist2 2nd thru last offset distance * @param {number} dist2 2nd thru last offset distance
* @param {number} over additional offset over then under * @param {number} over additional offset over then under
* @param {Polygon[]} [out] optional collector * @param {Polygon[]} out optional collector
* @param {number} [count] offset passes (0 == until no space left) * @param {number} count offset passes (0 == until no space left)
* @param {Function} [collector] receives output of each pass * @param {Function} collector receives output of each pass
* @param {Function} thins receives output of each pass
* @param {number} [z] defaults to 0 * @param {number} [z] defaults to 0
* @returns {Polygon[]} last offset * @returns {Polygon[]} last offset
*/ */
function expand2(polys, dist1, dist2, over, out, count, collector, z) { function expand2(polys, dist1, dist2, over, out, count, collector, thins, z) {
// prepare alignments for clipper lib // prepare alignments for clipper lib
alignWindings(polys); alignWindings(polys);
polys.forEach(function(poly) { polys.forEach(function(poly) {
@ -459,7 +469,8 @@ var gs_base_polygons = exports;
cjnt = clib.JoinType, cjnt = clib.JoinType,
cety = clib.EndType, cety = clib.EndType,
coff = new clib.ClipperOffset(), coff = new clib.ClipperOffset(),
ctre = new clib.PolyTree(); ctre = new clib.PolyTree(),
orig = polys;
// inset // inset
polys.forEach(function(poly) { polys.forEach(function(poly) {
@ -481,11 +492,22 @@ var gs_base_polygons = exports;
coff.Execute(ctre, (-over) * fact); coff.Execute(ctre, (-over) * fact);
polys = fromClipperTree(ctre, z); polys = fromClipperTree(ctre, z);
// detect possible thin walls
if (polys.length && thins) {
var circ1 = sumCirc(orig),
circ2 = sumCirc(polys),
diff = Math.abs(1 - (circ1 / circ2));
if (diff > 0.2) {
thins(orig, polys, diff);
}
}
// process // process
if (out) out.appendAll(polys); if (out) out.appendAll(polys);
if (collector) collector(polys, count); if (collector) collector(polys, count);
if ((count === 0 || count > 1) && polys.length > 0) { if ((count === 0 || count > 1) && polys.length > 0) {
expand2(polys, dist2 || dist1, dist2, over, out, count > 0 ? count-1 : 0, collector, z); expand2(polys, dist2 || dist1, dist2, over, out, count > 0 ? count-1 : 0, collector, thins, z);
} }
return polys; return polys;
@ -551,10 +573,11 @@ var gs_base_polygons = exports;
* @param {number} angle (-90 to 90) * @param {number} angle (-90 to 90)
* @param {number} spacing * @param {number} spacing
* @param {Polygon[]} [output] * @param {Polygon[]} [output]
* @param {numer} minLen * @param {number} [minLen]
* @param {number} [maxLen]
* @returns {Point[]} supplied output or new array * @returns {Point[]} supplied output or new array
*/ */
function fillArea(polys, angle, spacing, output, minLen) { function fillArea(polys, angle, spacing, output, minLen, maxLen) {
var i = 1, var i = 1,
p0 = polys[0], p0 = polys[0],
zpos = p0.getZ(), zpos = p0.getZ(),
@ -590,7 +613,8 @@ var gs_base_polygons = exports;
cfil = clib.PolyFillType, cfil = clib.PolyFillType,
clip = new clib.Clipper(), clip = new clib.Clipper(),
ctre = new clib.PolyTree(), ctre = new clib.PolyTree(),
minlen = BASE.config.clipper * (minLen || 0.25), minlen = BASE.config.clipper * (minLen || 0),
maxlen = BASE.config.clipper * (maxLen || 0),
lines = []; lines = [];
for (i = 0; i < steps; i++) { for (i = 0; i < steps; i++) {
@ -608,8 +632,11 @@ var gs_base_polygons = exports;
if (clip.Execute(ctyp.ctIntersection, ctre, cfil.pftNonZero, cfil.pftEvenOdd)) { if (clip.Execute(ctyp.ctIntersection, ctre, cfil.pftNonZero, cfil.pftEvenOdd)) {
ctre.m_AllPolys.forEach(function(poly) { ctre.m_AllPolys.forEach(function(poly) {
// filter out polygons under min length (0.5mm) if (minlen || maxlen) {
// if (clib.JS.PerimeterOfPath(poly.m_polygon, false, 1) < minlen) return; var plen = clib.JS.PerimeterOfPath(poly.m_polygon, false, 1);
if (minlen && plen < minlen) return;
if (maxlen && plen > maxlen) return;
}
poly.m_polygon.forEach(function(point) { poly.m_polygon.forEach(function(point) {
rayint.push(newPoint(null,null,zpos,null,point)); rayint.push(newPoint(null,null,zpos,null,point));
}); });

View file

@ -370,6 +370,10 @@ var gs_kiri_slice = exports;
top.inner = []; top.inner = [];
var last = []; var last = [];
if (opt.thin) {
top.thin_fill = [];
}
if (count) { if (count) {
// permit offset of 0 for laser // permit offset of 0 for laser
if (offset1 === 0) { if (offset1 === 0) {
@ -384,6 +388,7 @@ var gs_kiri_slice = exports;
-offset1, -offset1,
top.traces, top.traces,
count, count,
// on each new offset trace ...
function(polys, countNow) { function(polys, countNow) {
last = polys; last = polys;
// mark each poly with depth (offset #) starting at 0 // mark each poly with depth (offset #) starting at 0
@ -395,6 +400,14 @@ var gs_kiri_slice = exports;
}); });
}); });
}, },
// thin wall probe
function(p1, p2) {
// var pall = [].appendAll(p1).appendAll(p2),
// r1 = fillArea(pall, 45, offsetN, [], offsetN, offsetN * 2),
// r2 = fillArea(pall, 135, offsetN, [], offsetN, offsetN * 2),
// rall = top.thin_fill.appendAll(r1).appendAll(r2);
// console.log([slice.index, p1, p2, r1, r2]);
},
top.poly.getZ()); top.poly.getZ());
} else { } else {
POLY.expand( POLY.expand(
@ -404,6 +417,7 @@ var gs_kiri_slice = exports;
top.traces, top.traces,
count, count,
-offsetN, -offsetN,
// on each new offset trace ...
function(polys, countNow) { function(polys, countNow) {
last = polys; last = polys;
// mark each poly with depth (offset #) starting at 0 // mark each poly with depth (offset #) starting at 0
@ -511,7 +525,7 @@ var gs_kiri_slice = exports;
this.tops.forEach(function(top) { this.tops.forEach(function(top) {
if (top.inner && top.inner.length > 0) { if (top.inner && top.inner.length > 0) {
top.fill_lines = fillArea(top.inner, angle, spacing, null, 0.00001); top.fill_lines = fillArea(top.inner, angle, spacing, null);
} else { } else {
top.fill_lines = null; top.fill_lines = null;
} }
@ -759,7 +773,7 @@ var gs_kiri_slice = exports;
// create empty filled line array for each top // create empty filled line array for each top
tops.forEach(function(top) { tops.forEach(function(top) {
top.fill_lines = []; top.fill_lines = top.thin_fill || [];
var tofill = [], var tofill = [],
angfill = []; angfill = [];
trims.forEach(function(solid) { trims.forEach(function(solid) {