complete fully threaded contouring, restore progress bar

This commit is contained in:
Stewart Allen 2023-01-14 16:53:17 -05:00
commit 755f38fb39

View file

@ -150,7 +150,9 @@ class Topo {
}; };
onupdate(0, 1, "raster"); onupdate(0, 1, "raster");
await this.raster(widget, params); await this.raster(widget, params, (i, l, p) => {
onupdate(i / 2, l, p);
});
topo.raster = false; topo.raster = false;
} }
@ -173,9 +175,10 @@ class Topo {
clipTo, clipTo,
clipTab, clipTab,
tabHeight, tabHeight,
onupdate,
newslices, newslices,
color color
}, (i, l, p) => {
onupdate(l / 2 + i / 2, l, p);
}); });
ondone(newslices); ondone(newslices);
@ -183,13 +186,11 @@ class Topo {
return this; return this;
} }
async raster(widget, params) { async raster(widget, params, onupdate) {
const { resolution } = params; const { resolution } = params;
const { box } = params; const { box } = params;
console.log({ topo_raster: widget, resolution });
const { worker, minions } = kiri; const { worker, minions } = kiri;
const vertices = widget.getGeoVertices().toShared(); const vertices = widget.getGeoVertices().toShared();
const range = { min: Infinity, max: -Infinity }; const range = { min: Infinity, max: -Infinity };
@ -219,15 +220,15 @@ class Topo {
slices.push(slice); slices.push(slice);
console.log({ shards, range, step, slices }); console.log({ shards, range, step, slices });
let complete = 0;
// define sharded ranges // define sharded ranges
if (minions.running > 1) { if (minions.running > 1) {
console.time('topo raster minion');
worker.putCache({ key: widget.id, data: vertices }, { done: data => { worker.putCache({ key: widget.id, data: vertices }, { done: data => {
// console.log({ put_cache_done: data }); // console.log({ put_cache_done: data });
}}); }});
let promises = slices.map((slice, index) => { let promises = slices.map(slice => {
return new Promise(resolve => { return new Promise(resolve => {
minions.queue({ minions.queue({
cmd: "topo_raster", cmd: "topo_raster",
@ -236,6 +237,7 @@ class Topo {
slice slice
}, data => { }, data => {
resolve(data); resolve(data);
onupdate(++complete, slices.length, "raster");
}); });
}); });
}); });
@ -255,11 +257,9 @@ class Topo {
worker.clearCache({}, { done: data => { worker.clearCache({}, { done: data => {
// console.log({ clear_cache_done: data }); // console.log({ clear_cache_done: data });
}}); }});
console.timeEnd('topo raster minion');
} else { } else {
console.time('topo raster');
// iterate over shards, merge output // iterate over shards, merge output
// const output = []; // const output = [];
for (let slice of slices) { for (let slice of slices) {
@ -286,34 +286,29 @@ class Topo {
return slice; return slice;
}); });
onupdate(++complete, slices.length, "raster");
} }
console.timeEnd('topo raster');
} }
} }
async contour(params) { async contour(params, onupdate) {
const trace = this.trace; const trace = this.trace;
const concurrent = kiri.minions.running; const concurrent = kiri.minions.running;
const { minX, maxX, minY, maxY, boundsX, boundsY, stepsX, stepsY } = params; const { minX, maxX, minY, maxY, boundsX, boundsY, stepsX, stepsY } = params;
const { gridDelta, resolution, partOff, toolStep, contourX, contourY } = params; const { gridDelta, resolution, partOff, toolStep, contourX, contourY } = params;
const { clipTo, clipTab, tabHeight, onupdate, newslices, color } = params; const { clipTo, clipTab, tabHeight, newslices, color } = params;
let gridx = 0, let stepsTaken = 0,
gridy,
gridi, // index
gridv, // value
i, il, j, x, y, tv,
stepsTaken = 0,
stepsTotal = 0; stepsTotal = 0;
if (contourX) { if (contourX) {
stepsTotal += ((maxX - minX + partOff * 2) / toolStep) | 0; stepsTotal += ((maxY - minY + partOff * 2) / toolStep) | 0;
} }
if (contourY) { if (contourY) {
stepsTotal += ((maxY - minY + partOff * 2) / toolStep) | 0; stepsTotal += ((maxX - minX + partOff * 2) / toolStep) | 0;
} }
const box = params.box.clone().expandByVector(new THREE.Vector3( const box = params.box.clone().expandByVector(new THREE.Vector3(
@ -329,13 +324,31 @@ class Topo {
concurrent concurrent
}); });
if (contourY) { let resolver;
// emit slice per X let pcount = 0;
for (x = minX - partOff; x <= maxX + partOff; x += toolStep) { let slicesY = [];
if (x < box.min.x || x > box.max.x) continue; let slicesX = [];
gridx = Math.round(((x - minX) / boundsX) * stepsX); let promise = new Promise(resolve => {
gridy = -gridDelta; resolver = () => {
// sort output slices (required for async)
slicesY.sort((a,b) => a.z - b.z);
slicesX.sort((a,b) => a.z - b.z);
newslices.appendAll(slicesY);
newslices.appendAll(slicesX);
resolve();
}
});
let inc = () => { pcount++ };
let dec = () => { if (--pcount === 0) resolver() };
if (contourY) {
onupdate(0, stepsTotal, "contour y");
// emit slice per X
for (let x = minX - partOff; x <= maxX + partOff; x += toolStep) {
if (x < box.min.x || x > box.max.x) continue;
const gridx = Math.round(((x - minX) / boundsX) * stepsX);
const gridy = -gridDelta;
inc();
trace.crossY({ trace.crossY({
from: minY - partOff, from: minY - partOff,
to: maxY + partOff, to: maxY + partOff,
@ -349,40 +362,45 @@ class Topo {
slice.output() slice.output()
.setLayer("contour y", {face: color, line: color}) .setLayer("contour y", {face: color, line: color})
.addPolys(segments); .addPolys(segments);
newslices.push(slice); slicesY.push(slice);
} }
onupdate(++stepsTaken, stepsTotal, "contour y"); onupdate(++stepsTaken, stepsTotal, "contour y");
dec();
}); });
} }
} }
if (contourX) { if (contourX) {
// emit slice per Y // emit slice per Y
for (y = minY - partOff; y <= maxY + partOff; y += toolStep) { onupdate(0, stepsTotal, "contour x");
for (let y = minY - partOff; y <= maxY + partOff; y += toolStep) {
if (y < box.min.y || y > box.max.y) continue; if (y < box.min.y || y > box.max.y) continue;
gridy = Math.round(((y - minY) / boundsY) * stepsY); const gridy = Math.round(((y - minY) / boundsY) * stepsY);
gridx = -gridDelta; const gridx = -gridDelta;
inc();
const segments = trace.crossX({ trace.crossX({
from: minX - partOff, from: minX - partOff,
to: maxX + partOff, to: maxX + partOff,
y, y,
gridx, gridx,
gridy gridy
}); }, segments => {
if (segments.length > 0) { if (segments.length > 0) {
let slice = newSlice(gridy); let slice = newSlice(gridy);
slice.camLines = segments; slice.camLines = segments;
slice.output() slice.output()
.setLayer("contour x", {face: color, line: color}) .setLayer("contour x", {face: color, line: color})
.addPolys(segments); .addPolys(segments);
newslices.push(slice); slicesX.push(slice);
} }
onupdate(++stepsTaken, stepsTotal, "contour x"); onupdate(++stepsTaken, stepsTotal, "contour x");
dec();
});
} }
} }
await promise;
trace.cleanup(); trace.cleanup();
} }
@ -531,8 +549,9 @@ class Trace {
init(params) { init(params) {
this.cross = params; this.cross = params;
if (this.cross.concurrent) { const { minions } = kiri;
const { worker, minions } = kiri;
if (minions && this.cross.concurrent) {
const { codec } = kiri; const { codec } = kiri;
minions.broadcast("trace_init", codec.encode({ minions.broadcast("trace_init", codec.encode({
@ -545,16 +564,47 @@ class Trace {
} }
cleanup() { cleanup() {
if (this.cross.concurrent) { const { minions } = kiri;
const { worker, minions } = kiri;
if (minions && this.cross.concurrent) {
minions.broadcast("trace_cleanup"); minions.broadcast("trace_cleanup");
} }
} }
crossY(params, then) { crossY(params, then) {
const { minions } = kiri;
if (minions && this.cross.concurrent) {
minions.queue({
cmd: "trace_y",
params
}, data => {
then(kiri.codec.decode(data.slice));
});
} else {
this.crossY_sync(params, then);
}
}
crossX(params, then) {
const { minions } = kiri;
if (minions && this.cross.concurrent) {
minions.queue({
cmd: "trace_x",
params
}, data => {
then(kiri.codec.decode(data.slice));
});
} else {
this.crossX_sync(params, then);
}
}
crossY_sync(params, then) {
const { push_point, end_poly, newtrace, newslice, inClip } = this.object; const { push_point, end_poly, newtrace, newslice, inClip } = this.object;
const { clipTab, tabHeight, clipTo, box, resolution } = this.cross; const { clipTab, tabHeight, clipTo, box, resolution } = this.cross;
const { toolAtZ, toolAtXY, zAtXY } = this.probe; const { toolAtZ } = this.probe;
let { from, to, x, gridx, gridy } = params; let { from, to, x, gridx, gridy } = params;
const checkr = newPoint(0,0); const checkr = newPoint(0,0);
newslice(); newslice();
@ -587,16 +637,16 @@ class Trace {
then(this.slice); then(this.slice);
} }
crossX(params) { crossX_sync(params, then) {
const { push_point, end_poly, newtrace, newslice, inClip } = this.object; const { push_point, end_poly, newtrace, newslice, inClip } = this.object;
const { clipTab, tabHeight, clipTo, box, resolution } = this.cross; const { clipTab, tabHeight, clipTo, box, resolution } = this.cross;
const { toolAtZ, toolAtXY, zAtXY } = this.probe; const { toolAtZ } = this.probe;
let { from, to, y, gridx, gridy } = params; let { from, to, y, gridx, gridy } = params;
const checkr = newPoint(0,0); const checkr = newPoint(0,0);
newslice(); newslice();
newtrace(); newtrace();
for (let x = from; x < to; x += resolution) { for (let x = from; x < to; x += resolution) {
if (x < box.min.x || y > box.max.x) { if (x < box.min.x || x > box.max.x) {
gridx++; gridx++;
continue; continue;
} }
@ -620,7 +670,7 @@ class Trace {
gridx++; gridx++;
} }
end_poly(); end_poly();
return this.slice; then(this.slice);
} }
} }
@ -720,7 +770,6 @@ CAM.Topo = async function(opt) {
}; };
moto.broker.subscribe("minion.started", msg => { moto.broker.subscribe("minion.started", msg => {
// console.log({ cam_slicer2_minion: msg });
const { funcs, cache, reply, log } = msg; const { funcs, cache, reply, log } = msg;
funcs.topo_raster = (data, seq) => { funcs.topo_raster = (data, seq) => {
@ -763,11 +812,28 @@ moto.broker.subscribe("minion.started", msg => {
trace, trace,
cross: data.cross cross: data.cross
}; };
log('trace_init', { data, trace: cache.trace }); trace.init(data.cross);
}; };
funcs.trace_y = (data, seq) => {
const { cache } = self;
const { trace } = cache.trace;
trace.crossY_sync(data.params, slice => {
slice = kiri.codec.encode(slice);
reply({ seq, slice });
});
},
funcs.trace_x = (data, seq) => {
const { cache } = self;
const { trace } = cache.trace;
trace.crossX_sync(data.params, slice => {
slice = kiri.codec.encode(slice);
reply({ seq, slice });
});
},
funcs.trace_cleanup = () => { funcs.trace_cleanup = () => {
// log('trace_cleanup');
delete cache.trace; delete cache.trace;
}; };
}); });