async-ify fdm slicing layer diffs for ~3x speedup
This commit is contained in:
parent
672b3d1077
commit
bdf3de7b04
3 changed files with 106 additions and 38 deletions
|
|
@ -672,14 +672,22 @@ export function sliceOne(settings, widget, onupdate, ondone) {
|
||||||
async function processLayerDiffs(plo, phi) {
|
async function processLayerDiffs(plo, phi) {
|
||||||
let div = divide(plo, phi, [ 0.9, 0.05, 0.05 ]);
|
let div = divide(plo, phi, [ 0.9, 0.05, 0.05 ]);
|
||||||
// boolean diff layers to detect bridges and flats
|
// boolean diff layers to detect bridges and flats
|
||||||
|
let promises = [];
|
||||||
profileStart("delta");
|
profileStart("delta");
|
||||||
forSlices(div[0].lo, div[1].hi, slice => {
|
forSlices(div[0].lo, div[1].hi, slice => {
|
||||||
let params = slice.params || process;
|
let params = slice.params || process;
|
||||||
let solidMinArea = params.sliceSolidMinArea;
|
let solidMinArea = params.sliceSolidMinArea;
|
||||||
let sliceMinThick = params.sliceSolidMinThick;
|
let sliceMinThick = params.sliceSolidMinThick;
|
||||||
let sliceFillGrow = params.sliceFillGrow;
|
let sliceFillGrow = params.sliceFillGrow;
|
||||||
layerDiff(slice, { area: solidMinArea, grow: sliceFillGrow, thick: sliceMinThick });
|
let p = layerDiff(slice, {
|
||||||
|
area: solidMinArea,
|
||||||
|
grow: sliceFillGrow,
|
||||||
|
thick: sliceMinThick,
|
||||||
|
async: true
|
||||||
|
});
|
||||||
|
promises.push(p);
|
||||||
}, "layer deltas");
|
}, "layer deltas");
|
||||||
|
await Promise.all(promises);
|
||||||
profileEnd();
|
profileEnd();
|
||||||
// project bridges and flats up and down into part
|
// project bridges and flats up and down into part
|
||||||
profileStart("delta-project");
|
profileStart("delta-project");
|
||||||
|
|
@ -1443,9 +1451,26 @@ export function layerDiff(slice, options = {}) {
|
||||||
let newBridges = [];
|
let newBridges = [];
|
||||||
let newFlats = [];
|
let newFlats = [];
|
||||||
|
|
||||||
POLY.subtract(topInner, downInner, newBridges, newFlats, slice.z, area, {
|
if (options.async) {
|
||||||
wasm: true
|
return self.kiri_worker.minions
|
||||||
});
|
.subtract({
|
||||||
|
a: topInner, b: downInner,
|
||||||
|
outA: newBridges, outB: newFlats,
|
||||||
|
area, wasm: true, z: slice.z,
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
layerDiffDone({ slice, bridges, flats, newBridges, newFlats, options });
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
POLY.subtract(topInner, downInner, newBridges, newFlats, slice.z, area, {
|
||||||
|
wasm: true
|
||||||
|
});
|
||||||
|
layerDiffDone({ slice, bridges, flats, newBridges, newFlats, options });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function layerDiffDone({ slice, bridges, flats, newBridges, newFlats, options }) {
|
||||||
|
const { sla, grow, area, thick } = options;
|
||||||
|
|
||||||
// console.log(slice.z, { newBridges, newFlats });
|
// console.log(slice.z, { newBridges, newFlats });
|
||||||
newBridges = newBridges.filter(p => p.areaDeep() >= area && p.thickness(true) >= thick);
|
newBridges = newBridges.filter(p => p.areaDeep() >= area && p.thickness(true) >= thick);
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,20 @@ const funcs = self.minion = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
subtract(data, seq) {
|
||||||
|
let { arg, opt } = data;
|
||||||
|
let { area, wasm, z } = opt;
|
||||||
|
let a = codec.decode(arg.a);
|
||||||
|
let b = codec.decode(arg.b);
|
||||||
|
let outA = [], outB = [];
|
||||||
|
POLY.subtract(a, b, outA, outB, z, area, { wasm });
|
||||||
|
reply({
|
||||||
|
seq,
|
||||||
|
outA: codec.encode(outA),
|
||||||
|
outB: codec.encode(outB)
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
union(data, seq) {
|
union(data, seq) {
|
||||||
if (!(data.polys && data.polys.length)) {
|
if (!(data.polys && data.polys.length)) {
|
||||||
reply({ seq, union: codec.encode([]) });
|
reply({ seq, union: codec.encode([]) });
|
||||||
|
|
|
||||||
|
|
@ -101,6 +101,9 @@ function minhandler(msg) {
|
||||||
|
|
||||||
// for concurrent operations
|
// for concurrent operations
|
||||||
const minwork = {
|
const minwork = {
|
||||||
|
|
||||||
|
// core functions
|
||||||
|
|
||||||
get concurrent() {
|
get concurrent() {
|
||||||
return concurrent
|
return concurrent
|
||||||
},
|
},
|
||||||
|
|
@ -137,6 +140,66 @@ const minwork = {
|
||||||
minions.length = 0;
|
minions.length = 0;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
queue(work, ondone, direct) {
|
||||||
|
minionq.push({work, ondone, direct});
|
||||||
|
minwork.kick();
|
||||||
|
},
|
||||||
|
|
||||||
|
queueAsync(work, direct) {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
minwork.queue(work, resolve, direct);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
kick() {
|
||||||
|
if (minions.length && minionq.length) {
|
||||||
|
let qrec = minionq.shift();
|
||||||
|
let minion = minions.shift();
|
||||||
|
let seq = miniseq++;
|
||||||
|
qrec.work.seq = seq;
|
||||||
|
minifns[seq] = (data) => {
|
||||||
|
qrec.ondone(data);
|
||||||
|
minions.push(minion);
|
||||||
|
minwork.kick();
|
||||||
|
};
|
||||||
|
minion.postMessage(qrec.work, qrec.direct);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
broadcast(cmd, data, direct) {
|
||||||
|
for (let minion of minions) {
|
||||||
|
minion.postMessage({
|
||||||
|
cmd, ...data
|
||||||
|
}, direct);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// added functions (should be namespaced)
|
||||||
|
|
||||||
|
subtract({ a, b, outA, outB, z, area, wasm }) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
if (concurrent < 2 || a.length + b.length < concurrent * 2 || POLY.points([...a,...b]) < concurrent * 50) {
|
||||||
|
POLY.subtract(a, b, outA, outB, z, area, { wasm });
|
||||||
|
resolve();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
minwork.queue({
|
||||||
|
cmd: "subtract",
|
||||||
|
opt: { area, wasm, z },
|
||||||
|
arg: {
|
||||||
|
a: codec.encode(a),
|
||||||
|
b: codec.encode(b),
|
||||||
|
outA: outA ? 1 : 0,
|
||||||
|
outB: outB ? 1 : 0,
|
||||||
|
}
|
||||||
|
}, result => {
|
||||||
|
if (outA) outA.push(...codec.decode(result.outA));
|
||||||
|
if (outB) outB.push(...codec.decode(result.outB));
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
union(polys, minarea) {
|
union(polys, minarea) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (concurrent < 2 || polys.length < concurrent * 2 || POLY.points(polys) < concurrent * 50) {
|
if (concurrent < 2 || polys.length < concurrent * 2 || POLY.points(polys) < concurrent * 50) {
|
||||||
|
|
@ -245,40 +308,6 @@ const minwork = {
|
||||||
}, [ floatP.buffer ]);
|
}, [ floatP.buffer ]);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
queue(work, ondone, direct) {
|
|
||||||
minionq.push({work, ondone, direct});
|
|
||||||
minwork.kick();
|
|
||||||
},
|
|
||||||
|
|
||||||
queueAsync(work, direct) {
|
|
||||||
return new Promise(resolve => {
|
|
||||||
minwork.queue(work, resolve, direct);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
kick() {
|
|
||||||
if (minions.length && minionq.length) {
|
|
||||||
let qrec = minionq.shift();
|
|
||||||
let minion = minions.shift();
|
|
||||||
let seq = miniseq++;
|
|
||||||
qrec.work.seq = seq;
|
|
||||||
minifns[seq] = (data) => {
|
|
||||||
qrec.ondone(data);
|
|
||||||
minions.push(minion);
|
|
||||||
minwork.kick();
|
|
||||||
};
|
|
||||||
minion.postMessage(qrec.work, qrec.direct);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
broadcast(cmd, data, direct) {
|
|
||||||
for (let minion of minions) {
|
|
||||||
minion.postMessage({
|
|
||||||
cmd, ...data
|
|
||||||
}, direct);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log(`kiri | init work | ${version || "rogue"}`);
|
console.log(`kiri | init work | ${version || "rogue"}`);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue