add experimental promises + concurrent shell offsetting
This commit is contained in:
parent
0af6eb6c61
commit
a8973dbef8
7 changed files with 97 additions and 35 deletions
2
app.js
2
app.js
|
|
@ -342,6 +342,8 @@ const script = {
|
|||
"geo/polygon",
|
||||
"geo/polygons",
|
||||
"geo/gyroid",
|
||||
"mode/fdm/driver",
|
||||
"mode/fdm/slice",
|
||||
"kiri/slice",
|
||||
"kiri/layers",
|
||||
"kiri/widget",
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
newPoint = BASE.newPoint,
|
||||
Bounds = BASE.Bounds;
|
||||
|
||||
let seqid = 1;
|
||||
let seqid = Math.round(Math.random() * 0xffffffff);
|
||||
|
||||
/** ******************************************************************
|
||||
* Constructors
|
||||
|
|
|
|||
|
|
@ -231,14 +231,27 @@
|
|||
});
|
||||
|
||||
KIRI.Top.prototype.encode = function(state) {
|
||||
return {
|
||||
let obj = {
|
||||
type: 'top',
|
||||
poly: encode(this.poly, state),
|
||||
poly: encode(this.poly, state)
|
||||
};
|
||||
if (state.full) {
|
||||
obj.last = encode(this.last, state);
|
||||
obj.shells = encode(this.shells, state);
|
||||
obj.fill_off = encode(this.fill_off, state);
|
||||
obj.fill_lines = encode(this.fill_lines, state);
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
|
||||
registerDecoder('top', function(v, state) {
|
||||
let top = KIRI.newTop(decode(v.poly, state));
|
||||
if (state.full) {
|
||||
top.last = decode(v.last, state);
|
||||
top.shells = decode(v.shells, state);
|
||||
top.fill_off = decode(v.fill_off, state);
|
||||
top.fill_lines = decode(v.fill_lines, state);
|
||||
}
|
||||
return top;
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -13,20 +13,30 @@ self.alert = function(o) {
|
|||
console.log(o);
|
||||
};
|
||||
|
||||
function reply(msg) {
|
||||
self.postMessage(msg);
|
||||
}
|
||||
|
||||
self.onmessage = function(msg) {
|
||||
let data = msg.data;
|
||||
switch (data.cmd) {
|
||||
case "union":
|
||||
if (!(data.polys && data.polys.length)) {
|
||||
self.postMessage({union: CODEC.encode([])});
|
||||
reply({union: CODEC.encode([])});
|
||||
return;
|
||||
}
|
||||
let polys = CODEC.decode(data.polys);
|
||||
let union = POLY.union(polys, data.minarea || 0, true);
|
||||
self.postMessage({union: CODEC.encode(union)});
|
||||
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:
|
||||
self.postMessage({error: "invalid command"});
|
||||
reply({error: "invalid command"});
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ if (concurrent) {
|
|||
}
|
||||
|
||||
// for concurrent operations
|
||||
const minwork =
|
||||
KIRI.minions = {
|
||||
union: function(polys, minarea) {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
|
@ -41,30 +42,27 @@ KIRI.minions = {
|
|||
let polyper = Math.ceil(polys.length / concurrent);
|
||||
let running = 0;
|
||||
let union = [];
|
||||
let receiver = function(msg) {
|
||||
let polys = KIRI.codec.decode(msg.data.union);
|
||||
let receiver = function(data) {
|
||||
let polys = KIRI.codec.decode(data.union);
|
||||
union.appendAll(polys);
|
||||
if (--running === 0) {
|
||||
resolve(POLY.union(union, 0, true));
|
||||
}
|
||||
};
|
||||
for (let i=0; i<polys.length; i += polyper) {
|
||||
minions[running].onmessage = receiver;
|
||||
minions[running].postMessage({
|
||||
running++;
|
||||
minwork.queue({
|
||||
cmd: "union",
|
||||
minarea,
|
||||
polys: KIRI.codec.encode(polys.slice(i, i + polyper))
|
||||
});
|
||||
running++;
|
||||
}, receiver);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
queue: function(work) {
|
||||
return new Promise((resolve, reject) => {
|
||||
minionq.push({work, resolve, reject});
|
||||
kick();
|
||||
});
|
||||
queue: function(work, ondone) {
|
||||
minionq.push({work, ondone});
|
||||
minwork.kick();
|
||||
},
|
||||
|
||||
kick: function() {
|
||||
|
|
@ -72,10 +70,11 @@ KIRI.minions = {
|
|||
let qrec = minionq.shift();
|
||||
let minion = minions.shift();
|
||||
minion.onmessage = (msg) => {
|
||||
qrec.resolve(msg.data);
|
||||
minions.push(minion);
|
||||
qrec.ondone(msg.data);
|
||||
minwork.kick();
|
||||
};
|
||||
minion.postMessage(work);
|
||||
minion.postMessage(qrec.work);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -680,8 +680,8 @@
|
|||
|
||||
if (Math.abs(angle) <= 3 * Math.PI / 4) {
|
||||
cc = BASE.util.center2pr(from, to, arcQ.rSum / cl, gc === "G3");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!cc) {
|
||||
cc = {x:arcQ.xSum/cl, y:arcQ.ySum/cl, z:arcQ[0].z, r:arcQ.rSum/cl};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -263,9 +263,10 @@
|
|||
slice.solids = [];
|
||||
});
|
||||
|
||||
let promises = ctrl.danger ? [] : undefined;
|
||||
// create shells and diff inner fillable areas
|
||||
forSlices(0.0, 0.2, slice => {
|
||||
let params = getRangeParameters(settings, slice.index);
|
||||
forSlices(0.0, 0.15, slice => {
|
||||
let params = slice.params = getRangeParameters(settings, slice.index);
|
||||
let shellFrac = (params.sliceShells - (params.sliceShells | 0));
|
||||
let sliceShells = params.sliceShells | 0;
|
||||
if (ctrl.danger && shellFrac) {
|
||||
|
|
@ -280,24 +281,38 @@
|
|||
let isBottom = slice.index < spro.sliceBottomLayers;
|
||||
let isTop = slice.index > slices.length - spro.sliceTopLayers-1;
|
||||
let isDense = params.sliceFillSparse > 0.98;
|
||||
let solid = (isBottom || ((isTop || isDense) && !vaseMode)) && !isSynth;
|
||||
let solidWidth = params.sliceFillWidth || 1;
|
||||
let spaceMult = first ? spro.firstLayerLineMult || 1 : 1;
|
||||
if ((isBottom || ((isTop || isDense) && !vaseMode)) && !isSynth) {
|
||||
slice.solid = {
|
||||
solidWidth,
|
||||
spaceMult
|
||||
};
|
||||
}
|
||||
let offset = shellOffset * spaceMult;
|
||||
let fillOff = fillOffset * spaceMult;
|
||||
let count = isSynth ? 1 : sliceShells;
|
||||
doShells(slice, count, offset, fillOff, {
|
||||
vase: vaseMode,
|
||||
thin: spro.detectThinWalls && !isSynth,
|
||||
widget: widget,
|
||||
// widget: widget,
|
||||
danger: ctrl.danger
|
||||
});
|
||||
if (solid) {
|
||||
let fillSpace = fillSpacing * spaceMult * solidWidth;
|
||||
}, promises);
|
||||
}, "shells");
|
||||
|
||||
if (promises) {
|
||||
await Promise.all(promises);
|
||||
// console.log('resolved', promises.length);
|
||||
}
|
||||
|
||||
// just the top/bottom special solid layers
|
||||
forSlices(0.15, 0.2, slice => {
|
||||
if (slice.solid) {
|
||||
let fillSpace = fillSpacing * slice.solid.spaceMult * slice.solid.solidWidth;
|
||||
doSolidLayerFill(slice, fillSpace, sliceFillAngle);
|
||||
}
|
||||
sliceFillAngle += 90.0;
|
||||
}, "offsets");
|
||||
}, "shells");
|
||||
|
||||
// add lead in when specified in belt mode
|
||||
if (!isSynth && isBelt) {
|
||||
|
|
@ -474,10 +489,10 @@
|
|||
alltops = alltops.map(p => p.clean(true, undefined, 5000));
|
||||
// console.log({reduced: alltops.map(p => p.deepLength).reduce((a,v)=>a+v)});
|
||||
}
|
||||
// let mark = Date.now();
|
||||
let mark = Date.now();
|
||||
// shadow = POLY.union(alltops, 0.1, true);
|
||||
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) {
|
||||
shadow = POLY.offset(shadow, spro.sliceSupportExtra);
|
||||
}
|
||||
|
|
@ -586,6 +601,7 @@
|
|||
// shared with SLA driver
|
||||
FDM.share = {
|
||||
doShells,
|
||||
doTopShells,
|
||||
doDiff,
|
||||
projectFlats,
|
||||
projectBridges,
|
||||
|
|
@ -604,7 +620,7 @@
|
|||
* @param {number} fillOffset
|
||||
* @param {Obejct} options
|
||||
*/
|
||||
function doShells(slice, count, offsetN, fillOffset, opt = {}) {
|
||||
function doShells(slice, count, offsetN, fillOffset, opt = {}, promises) {
|
||||
let offset1 = offsetN / 2;
|
||||
|
||||
if (slice.index === 0) {
|
||||
|
|
@ -612,12 +628,34 @@
|
|||
// segment polygon
|
||||
}
|
||||
|
||||
for (let top of slice.tops) {
|
||||
doTopShells(slice.z, top, count, offset1, offsetN, fillOffset, opt);
|
||||
if (promises) {
|
||||
let oldtops = slice.tops;
|
||||
let newtops = slice.tops = [];
|
||||
oldtops.old = true;
|
||||
for (let top of oldtops) {
|
||||
promises.push(
|
||||
new Promise((resolve, reject) => {
|
||||
KIRI.minions.queue({
|
||||
cmd: "top.shells",
|
||||
z: slice.z, count, offset1, offsetN, fillOffset, opt,
|
||||
top: KIRI.codec.encode(top, {full: true})
|
||||
}, data => {
|
||||
let top = KIRI.codec.decode(data.top, {full: true});
|
||||
newtops.push(top);
|
||||
resolve();
|
||||
});
|
||||
})
|
||||
);
|
||||
}
|
||||
newtops.new = true;
|
||||
} else {
|
||||
for (let top of slice.tops) {
|
||||
doTopShells(slice.z, top, count, offset1, offsetN, fillOffset, opt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function doTopShells(z, top, count, offset1, offsetN, fillOffset, opt) {
|
||||
function doTopShells(z, top, count, offset1, offsetN, fillOffset, opt = {}) {
|
||||
let top_poly = [ top.poly ];
|
||||
|
||||
if (opt.vase) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue