add option to emit sparse fills as polygons to trace and fill

This commit is contained in:
Stewart Allen 2020-04-28 09:51:25 -04:00
commit 6f9ea355dd
3 changed files with 75 additions and 6 deletions

View file

@ -268,6 +268,20 @@ var gs_base_polygon = exports;
return this;
}
// return average of all point positions
PRO.average = function() {
let ap = newPoint(0,0,0,null);
this.points.forEach(p => {
ap.x += p.x;
ap.y += p.y;
ap.z += p.z;
});
ap.x /= this.points.length;
ap.y /= this.points.length;
ap.z /= this.points.length;
return ap;
};
/**
* @param {boolean} [point] return just the center point
* @returns {Polygon|Point} a new polygon centered on x=0, y=0, z=0

View file

@ -669,14 +669,17 @@ let gs_kiri_slice = exports;
* the bounds of the top polygons and their inner solid areas.
*/
PRO.doSparseLayerFill = function(options) {
let spacing = options.spacing, // spacing space between fill lines
let process = options.process,
spacing = options.spacing, // spacing space between fill lines
density = options.density, // density of infill 0.0 - 1.0
bounds = options.bounds, // bounding box of widget
height = options.height, // z layer height
type = options.type || 'hex';
this.isSparseFill = false;
if (this.tops.length === 0 || density === 0.0 || this.isSolidFill) return;
if (this.tops.length === 0 || density === 0.0 || this.isSolidFill) {
return;
}
let scope = this,
tops = scope.tops,
@ -691,6 +694,7 @@ let gs_kiri_slice = exports;
polys = [],
lines = [],
line = [],
solids = [],
// callback passed to pluggable infill algorithm
target = {
slice: function() { return scope },
@ -702,7 +706,14 @@ let gs_kiri_slice = exports;
zHeight: function() { return height },
offset: function() { return spacing },
density: function() { return density },
emit: function(x,y) { line.push(newPoint(x,y,scope.z)) },
emit: function(x,y) {
if (isNaN(x)) {
solids.push(x);
} else {
line.push(newPoint(x,y,scope.z));
scope.isSparseFill = true;
}
},
newline: function() {
if (line.length > 0) {
lines.push(line);
@ -711,8 +722,6 @@ let gs_kiri_slice = exports;
}
};
scope.isSparseFill = true;
// use specified fill type
if (type && FILL[type]) {
FILL[type](target);
@ -752,6 +761,51 @@ let gs_kiri_slice = exports;
}
}
let sparse_clip = scope.isSparseFill;
// solid fill areas
if (solids.length) {
tops.forEach(top => {
if (!top.inner) return;
let masks = top.inner.slice();
if (top.solids) {
masks = POLY.subtract(masks, top.solids, [], null, scope.z);
}
let angl = process.sliceFillAngle * ((scope.index % 2) + 1);
solids.forEach(solid => {
let inter = [],
fillable = [];
masks.forEach(mask => {
let p = solid.mask(mask);
if (p && p.length) inter.appendAll(p);
});
// offset fill area to accommodate trace
if (inter.length) {
POLY.expand(inter, -options.lineWidth/2, scope.z, fillable);
}
// fill intersected areas
if (inter.length) {
scope.isSparseFill = true;
if (!top.fill_lines) top.fill_lines = [];
inter.forEach(p => {
p.forEachSegment((p1, p2) => {
top.fill_lines.push(p1, p2);
});
});
}
if (fillable.length) {
let lines = POLY.fillArea(fillable, angl, options.lineWidth);
top.fill_lines.appendAll(lines);
}
});
});
}
// if only solids were added and no lines to clip
if (!sparse_clip) {
return;
}
clip.AddPaths(lines, ptyp.ptSubject, false);
clip.AddPaths(POLY.toClipper(polys), ptyp.ptClip, true);
@ -759,7 +813,7 @@ let gs_kiri_slice = exports;
ctre.m_AllPolys.forEach(function(node) {
poly = POLY.fromClipperNode(node, scope.z);
tops.forEach(function(top) {
// use only polygons inside the top
// use only polygons inside this top
if (poly.isInside(top.poly)) {
top.fill_sparse.push(poly);
}

View file

@ -33,6 +33,7 @@
# SLA
* `P` prioritize supports by length of unsupported span. mandatory when circularity > X
* or % area of inner to outer poly is high (making it a thin shell)
# CAM