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;
|
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
|
// wrap a function and unroll the first parameter into
|
||||||
// successive function calls if it is an array
|
// successive function calls if it is an array
|
||||||
Array.handle = function(fn) {
|
Array.handle = function(fn) {
|
||||||
|
|
|
||||||
|
|
@ -428,6 +428,39 @@
|
||||||
return diff;
|
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
|
* Connect to base
|
||||||
******************************************************************* */
|
******************************************************************* */
|
||||||
|
|
@ -530,6 +563,7 @@
|
||||||
intersect,
|
intersect,
|
||||||
determinant,
|
determinant,
|
||||||
numOrDefault,
|
numOrDefault,
|
||||||
|
orderClosest,
|
||||||
zInPlane,
|
zInPlane,
|
||||||
comma: (v) => {
|
comma: (v) => {
|
||||||
if (!v) return 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 = {}) {
|
function outputFills(lines, opt = {}) {
|
||||||
if (!lines || lines.length === 0) {
|
if (!lines || lines.length === 0) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -1078,7 +1109,7 @@
|
||||||
setType('int');
|
setType('int');
|
||||||
|
|
||||||
// output thin fill
|
// output thin fill
|
||||||
outputFills(next.thin_fill, {near: true});
|
outputThin(next.thin_fill);
|
||||||
|
|
||||||
// then output solid and sparse fill
|
// then output solid and sparse fill
|
||||||
outputFills(next.fill_lines, {flow: solidWidth});
|
outputFills(next.fill_lines, {flow: solidWidth});
|
||||||
|
|
|
||||||
|
|
@ -189,7 +189,7 @@
|
||||||
} else {
|
} else {
|
||||||
// frop top object passed back by slicePost()
|
// frop top object passed back by slicePost()
|
||||||
let top = new Top(poly.poly);
|
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_lines = poly.fill_lines;
|
||||||
top.fill_off = poly.fill_off;
|
top.fill_off = poly.fill_off;
|
||||||
top.last = poly.last;
|
top.last = poly.last;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue