add array grouping and walk order. add new thin fill output method
This commit is contained in:
parent
1108940a54
commit
5e6c4b91aa
4 changed files with 81 additions and 2 deletions
|
|
@ -180,6 +180,20 @@
|
|||
return this.filter(v => isNaN(v)).length > 0;
|
||||
};
|
||||
|
||||
// turn array into arrays of specified size
|
||||
AP.group = function(size) {
|
||||
let na = new Array(Math.ceil(this.length / size));
|
||||
let nai = 0;
|
||||
for (let i=0; i<this.length; i += size) {
|
||||
let grp = new Array(size);
|
||||
for (let j=0; j<size; j++) {
|
||||
grp[j] = this[i+j];
|
||||
}
|
||||
na[nai++] = grp;
|
||||
}
|
||||
return na;
|
||||
};
|
||||
|
||||
// wrap a function and unroll the first parameter into
|
||||
// successive function calls if it is an array
|
||||
Array.handle = function(fn) {
|
||||
|
|
|
|||
|
|
@ -428,6 +428,39 @@
|
|||
return diff;
|
||||
}
|
||||
|
||||
// order array of elements using next closest element comparator
|
||||
// used for things like next-closest point walks (fdm thin fill)
|
||||
// in future, replace poly2poly and similar with this
|
||||
function orderClosest(array, fn, from) {
|
||||
if (!array.length) {
|
||||
return array;
|
||||
}
|
||||
let out = new Array(array.length);
|
||||
let outi = 0;
|
||||
let root = 0;
|
||||
if (!from) {
|
||||
from = array[root++];
|
||||
out[outi++] = from;
|
||||
}
|
||||
for (;;) {
|
||||
let best, best_i, best_dist = Infinity;
|
||||
for (let i=root; i<array.length; i++) {
|
||||
let el = array[i];
|
||||
if (!el) continue;
|
||||
let dist = fn(from, el);
|
||||
if (dist < best_dist) {
|
||||
best_dist = dist;
|
||||
best_i = i;
|
||||
best = el;
|
||||
}
|
||||
}
|
||||
if (!best) break;
|
||||
array[best_i] = undefined;
|
||||
from = out[outi++] = best;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/** ******************************************************************
|
||||
* Connect to base
|
||||
******************************************************************* */
|
||||
|
|
@ -530,6 +563,7 @@
|
|||
intersect,
|
||||
determinant,
|
||||
numOrDefault,
|
||||
orderClosest,
|
||||
zInPlane,
|
||||
comma: (v) => {
|
||||
if (!v) return v;
|
||||
|
|
|
|||
|
|
@ -834,6 +834,37 @@
|
|||
});
|
||||
}
|
||||
|
||||
function outputThin(lines) {
|
||||
let points = lines.group(2).map(grp => {
|
||||
let [ p1, p2 ] = grp;
|
||||
return newPoint(
|
||||
(p1.x + p2.x) / 2,
|
||||
(p1.y + p2.y) / 2,
|
||||
(p1.z + p2.z) / 2
|
||||
)
|
||||
});
|
||||
let order = UTIL.orderClosest(points, (p1, p2) => p1.distTo2D(p2));
|
||||
if (order.length === 0) {
|
||||
return;
|
||||
}
|
||||
let first = points[0];
|
||||
let last = first;
|
||||
addOutput(preout, first, 0, moveSpeed, extruder);
|
||||
for (let p of order) {
|
||||
let dist = last ? last.distTo2D(p) : 0;
|
||||
if (dist > thinWall) {
|
||||
retract();
|
||||
addOutput(preout, p, 0, moveSpeed, extruder);
|
||||
}
|
||||
addOutput(preout, p, 1, fillSpeed, extruder);
|
||||
last = p;
|
||||
}
|
||||
// close a circle
|
||||
if (last && last.distTo2D(first) <= thinWall) {
|
||||
addOutput(preout, first, 1, fillSpeed, extruder);
|
||||
}
|
||||
}
|
||||
|
||||
function outputFills(lines, opt = {}) {
|
||||
if (!lines || lines.length === 0) {
|
||||
return;
|
||||
|
|
@ -1078,7 +1109,7 @@
|
|||
setType('int');
|
||||
|
||||
// output thin fill
|
||||
outputFills(next.thin_fill, {near: true});
|
||||
outputThin(next.thin_fill);
|
||||
|
||||
// then output solid and sparse fill
|
||||
outputFills(next.fill_lines, {flow: solidWidth});
|
||||
|
|
|
|||
|
|
@ -189,7 +189,7 @@
|
|||
} else {
|
||||
// frop top object passed back by slicePost()
|
||||
let top = new Top(poly.poly);
|
||||
top.thin_fill = poly.thin_fill.map(p => BASE.newPoint(p.x,p.y,p.z));
|
||||
top.thin_fill = poly.thin_fill ? poly.thin_fill.map(p => BASE.newPoint(p.x,p.y,p.z)) : undefined;
|
||||
top.fill_lines = poly.fill_lines;
|
||||
top.fill_off = poly.fill_off;
|
||||
top.last = poly.last;
|
||||
|
|
|
|||
Loading…
Reference in a new issue