add concurrent fill
This commit is contained in:
parent
a8973dbef8
commit
cb15501a23
4 changed files with 95 additions and 42 deletions
|
|
@ -15,7 +15,9 @@
|
||||||
encode: encode,
|
encode: encode,
|
||||||
decode: decode,
|
decode: decode,
|
||||||
registerDecoder: registerDecoder,
|
registerDecoder: registerDecoder,
|
||||||
allocFloat32Array: allocFloat32Array
|
allocFloat32Array: allocFloat32Array,
|
||||||
|
encodePointArray,
|
||||||
|
decodePointArray
|
||||||
};
|
};
|
||||||
|
|
||||||
function allocFloat32Array(arg) {
|
function allocFloat32Array(arg) {
|
||||||
|
|
|
||||||
|
|
@ -13,32 +13,50 @@ self.alert = function(o) {
|
||||||
console.log(o);
|
console.log(o);
|
||||||
};
|
};
|
||||||
|
|
||||||
function reply(msg) {
|
|
||||||
self.postMessage(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
self.onmessage = function(msg) {
|
self.onmessage = function(msg) {
|
||||||
let data = msg.data;
|
let data = msg.data;
|
||||||
switch (data.cmd) {
|
let cmd = data.cmd;
|
||||||
case "union":
|
(funcs[cmd] || funcs.bad)(data);
|
||||||
if (!(data.polys && data.polys.length)) {
|
|
||||||
reply({union: CODEC.encode([])});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let polys = CODEC.decode(data.polys);
|
|
||||||
let union = POLY.union(polys, data.minarea || 0, true);
|
|
||||||
reply({union: CODEC.encode(union)});
|
|
||||||
break;
|
|
||||||
case "top.shells":
|
|
||||||
let top = CODEC.decode(data.top, {full: true});
|
|
||||||
let {z, count, offset1, offsetN, fillOffset, opt} = data;
|
|
||||||
KIRI.driver.FDM.share.doTopShells(z, top, count, offset1, offsetN, fillOffset, opt);
|
|
||||||
reply({top: CODEC.encode(top, {full: true})});
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
reply({error: "invalid command"});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// console.log(`kiri | init mini | ${KIRI.version || "rogue"}`);
|
function reply(msg, direct) {
|
||||||
|
self.postMessage(msg, direct);
|
||||||
|
}
|
||||||
|
|
||||||
|
const funcs = {
|
||||||
|
union: data => {
|
||||||
|
if (!(data.polys && data.polys.length)) {
|
||||||
|
reply({union: CODEC.encode([])});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let polys = CODEC.decode(data.polys);
|
||||||
|
let union = POLY.union(polys, data.minarea || 0, true);
|
||||||
|
reply({union: CODEC.encode(union)});
|
||||||
|
},
|
||||||
|
|
||||||
|
topShells: data => {
|
||||||
|
let top = CODEC.decode(data.top, {full: true});
|
||||||
|
let {z, count, offset1, offsetN, fillOffset, opt} = data;
|
||||||
|
KIRI.driver.FDM.share.doTopShells(z, top, count, offset1, offsetN, fillOffset, opt);
|
||||||
|
reply({top: CODEC.encode(top, {full: true})});
|
||||||
|
},
|
||||||
|
|
||||||
|
fill: data => {
|
||||||
|
let polys = CODEC.decode(data.polys);
|
||||||
|
let { angle, spacing, minLen, maxLen } = data;
|
||||||
|
let fill = POLY.fillArea(polys, angle, spacing, [], minLen, maxLen);
|
||||||
|
let arr = new Float32Array(fill.length * 4);
|
||||||
|
for (let i=0, p=0; p<fill.length; ) {
|
||||||
|
let pt = fill[p++];
|
||||||
|
arr[i++] = pt.x;
|
||||||
|
arr[i++] = pt.y;
|
||||||
|
arr[i++] = pt.z;
|
||||||
|
arr[i++] = pt.index;
|
||||||
|
}
|
||||||
|
reply({ fill: arr }, [ arr.buffer ]);
|
||||||
|
},
|
||||||
|
|
||||||
|
bad: data => {
|
||||||
|
reply({error: "invalid command"});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,29 @@ KIRI.minions = {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
fill: function(polys, angle, spacing, output, minLen, maxLen) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
if (concurrent === 0) {
|
||||||
|
resolve(POLY.fillArea(polys, angle, spacing, [], minLen, maxLen));
|
||||||
|
}
|
||||||
|
minwork.queue({
|
||||||
|
cmd: "fill",
|
||||||
|
polys: KIRI.codec.encode(polys),
|
||||||
|
angle, spacing, minLen, maxLen
|
||||||
|
}, data => {
|
||||||
|
let arr = data.fill;
|
||||||
|
let fill = [];
|
||||||
|
for (let i=0; i<arr.length; ) {
|
||||||
|
let pt = BASE.newPoint(arr[i++], arr[i++], arr[i++]);
|
||||||
|
pt.index = arr[i++];
|
||||||
|
fill.push(pt);
|
||||||
|
}
|
||||||
|
output.appendAll(fill);
|
||||||
|
resolve(fill);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
queue: function(work, ondone) {
|
queue: function(work, ondone) {
|
||||||
minionq.push({work, ondone});
|
minionq.push({work, ondone});
|
||||||
minwork.kick();
|
minwork.kick();
|
||||||
|
|
|
||||||
|
|
@ -295,7 +295,6 @@
|
||||||
doShells(slice, count, offset, fillOff, {
|
doShells(slice, count, offset, fillOff, {
|
||||||
vase: vaseMode,
|
vase: vaseMode,
|
||||||
thin: spro.detectThinWalls && !isSynth,
|
thin: spro.detectThinWalls && !isSynth,
|
||||||
// widget: widget,
|
|
||||||
danger: ctrl.danger
|
danger: ctrl.danger
|
||||||
}, promises);
|
}, promises);
|
||||||
}, "shells");
|
}, "shells");
|
||||||
|
|
@ -425,27 +424,28 @@
|
||||||
if (doSolidLayers) {
|
if (doSolidLayers) {
|
||||||
forSlices(0.2, 0.34, slice => {
|
forSlices(0.2, 0.34, slice => {
|
||||||
if (slice.index > 0) doDiff(slice, minSolid);
|
if (slice.index > 0) doDiff(slice, minSolid);
|
||||||
}, "diff");
|
}, "layer deltas");
|
||||||
forSlices(0.34, 0.35, slice => {
|
forSlices(0.34, 0.35, slice => {
|
||||||
projectFlats(slice, solidLayers);
|
projectFlats(slice, solidLayers);
|
||||||
projectBridges(slice, solidLayers);
|
projectBridges(slice, solidLayers);
|
||||||
}, "solids");
|
}, "project solids");
|
||||||
forSlices(0.35, 0.5, slice => {
|
forSlices(0.35, 0.5, slice => {
|
||||||
let params = getRangeParameters(settings, slice.index);
|
let params = slice.params;// getRangeParameters(settings, slice.index);
|
||||||
let first = slice.index === 0;
|
let first = slice.index === 0;
|
||||||
let solidWidth = params.sliceFillWidth || 1;
|
let solidWidth = params.sliceFillWidth || 1;
|
||||||
let spaceMult = first ? params.firstLayerLineMult || 1 : 1;
|
let spaceMult = first ? params.firstLayerLineMult || 1 : 1;
|
||||||
let fillSpace = fillSpacing * spaceMult * solidWidth;
|
let fillSpace = fillSpacing * spaceMult * solidWidth;
|
||||||
doSolidsFill(slice, fillSpace, sliceFillAngle, minSolid);
|
doSolidsFill(slice, fillSpace, sliceFillAngle, minSolid);
|
||||||
sliceFillAngle += 90.0;
|
sliceFillAngle += 90.0;
|
||||||
}, "solids");
|
}, "fill solids");
|
||||||
|
await fillResolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
// sparse layers only present when non-vase mose and sparse % > 0
|
// sparse layers only present when non-vase mose and sparse % > 0
|
||||||
if (!isSynth) {
|
if (!isSynth) {
|
||||||
let lastType;
|
let lastType;
|
||||||
forSlices(0.5, 0.7, slice => {
|
forSlices(0.5, 0.7, slice => {
|
||||||
let params = getRangeParameters(settings, slice.index);
|
let params = slice.params;// getRangeParameters(settings, slice.index);
|
||||||
if (vaseMode || !params.sliceFillSparse) {
|
if (vaseMode || !params.sliceFillSparse) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -466,7 +466,7 @@
|
||||||
}, "infill");
|
}, "infill");
|
||||||
} else if (isSynth) {
|
} else if (isSynth) {
|
||||||
forSlices(0.5, 0.7, slice => {
|
forSlices(0.5, 0.7, slice => {
|
||||||
let params = getRangeParameters(settings, slice.index);
|
let params = slice.params;// getRangeParameters(settings, slice.index);
|
||||||
let density = params.sliceSupportDensity;
|
let density = params.sliceSupportDensity;
|
||||||
if (density)
|
if (density)
|
||||||
for (let top of slice.tops) {
|
for (let top of slice.tops) {
|
||||||
|
|
@ -492,7 +492,7 @@
|
||||||
let mark = Date.now();
|
let mark = Date.now();
|
||||||
// shadow = POLY.union(alltops, 0.1, true);
|
// shadow = POLY.union(alltops, 0.1, true);
|
||||||
shadow = await KIRI.minions.union(alltops, 0.1);
|
shadow = await KIRI.minions.union(alltops, 0.1);
|
||||||
console.log({unioned_in: Date.now() - mark});
|
// console.log({unioned_in: Date.now() - mark});
|
||||||
if (spro.sliceSupportExtra) {
|
if (spro.sliceSupportExtra) {
|
||||||
shadow = POLY.offset(shadow, spro.sliceSupportExtra);
|
shadow = POLY.offset(shadow, spro.sliceSupportExtra);
|
||||||
}
|
}
|
||||||
|
|
@ -511,7 +511,7 @@
|
||||||
// render if not explicitly disabled
|
// render if not explicitly disabled
|
||||||
if (render) {
|
if (render) {
|
||||||
forSlices(0.9, 1.0, slice => {
|
forSlices(0.9, 1.0, slice => {
|
||||||
let params = getRangeParameters(settings, slice.index);
|
let params = slice.params;// getRangeParameters(settings, slice.index);
|
||||||
doRender(slice, isSynth, params, ctrl.devel);
|
doRender(slice, isSynth, params, ctrl.devel);
|
||||||
}, "render");
|
}, "render");
|
||||||
}
|
}
|
||||||
|
|
@ -636,7 +636,7 @@
|
||||||
promises.push(
|
promises.push(
|
||||||
new Promise((resolve, reject) => {
|
new Promise((resolve, reject) => {
|
||||||
KIRI.minions.queue({
|
KIRI.minions.queue({
|
||||||
cmd: "top.shells",
|
cmd: "topShells",
|
||||||
z: slice.z, count, offset1, offsetN, fillOffset, opt,
|
z: slice.z, count, offset1, offsetN, fillOffset, opt,
|
||||||
top: KIRI.codec.encode(top, {full: true})
|
top: KIRI.codec.encode(top, {full: true})
|
||||||
}, data => {
|
}, data => {
|
||||||
|
|
@ -1028,8 +1028,6 @@
|
||||||
*/
|
*/
|
||||||
function doSolidsFill(slice, spacing, angle, minArea) {
|
function doSolidsFill(slice, spacing, angle, minArea) {
|
||||||
|
|
||||||
const render = slice.output();
|
|
||||||
|
|
||||||
let minarea = minArea || 1,
|
let minarea = minArea || 1,
|
||||||
tops = slice.tops,
|
tops = slice.tops,
|
||||||
solids = slice.solids;
|
solids = slice.solids;
|
||||||
|
|
@ -1093,7 +1091,7 @@
|
||||||
}
|
}
|
||||||
const tofill = [];
|
const tofill = [];
|
||||||
const angfill = [];
|
const angfill = [];
|
||||||
const newfill = [];
|
const newfill = top.fill_lines = [];
|
||||||
// determine fill orientation from top
|
// determine fill orientation from top
|
||||||
solids.forEach(function(solid) {
|
solids.forEach(function(solid) {
|
||||||
if (solid.parent === top.poly) {
|
if (solid.parent === top.poly) {
|
||||||
|
|
@ -1105,23 +1103,35 @@
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (tofill.length > 0) {
|
if (tofill.length > 0) {
|
||||||
fillArea(tofill, angle, spacing, newfill);
|
fillAsync(tofill, angle, spacing, newfill);
|
||||||
top.fill_lines_norm = {angle:angle,spacing:spacing};
|
top.fill_lines_norm = {angle:angle,spacing:spacing};
|
||||||
}
|
}
|
||||||
if (angfill.length > 0) {
|
if (angfill.length > 0) {
|
||||||
top.fill_lines_ang = {spacing:spacing,list:[],poly:[]};
|
top.fill_lines_ang = {spacing:spacing,list:[],poly:[]};
|
||||||
angfill.forEach(function(af) {
|
angfill.forEach(function(af) {
|
||||||
fillArea([af], af.fillang.angle + 45, spacing, newfill);
|
fillAsync([af], af.fillang.angle + 45, spacing, newfill);
|
||||||
top.fill_lines_ang.list.push(af.fillang.angle + 45);
|
top.fill_lines_ang.list.push(af.fillang.angle + 45);
|
||||||
top.fill_lines_ang.poly.push(af.clone());
|
top.fill_lines_ang.poly.push(af.clone());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
top.fill_lines.appendAll(newfill);
|
// top.fill_lines.appendAll(newfill);
|
||||||
});
|
});
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let fillQ = [];
|
||||||
|
|
||||||
|
function fillAsync(polys, angle, spacing, output, minLen, maxLen) {
|
||||||
|
fillQ.push(KIRI.minions.fill(polys, angle, spacing, output, minLen, maxLen));
|
||||||
|
}
|
||||||
|
|
||||||
|
async function fillResolve() {
|
||||||
|
// console.log({resolving: fillQ.length});
|
||||||
|
await Promise.all(fillQ);
|
||||||
|
fillQ.length = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* calculate external overhangs requiring support
|
* calculate external overhangs requiring support
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue