cam fix slice z output order, restore progress bar accuracy
This commit is contained in:
parent
d60d1e14d9
commit
70c00e1bab
3 changed files with 71 additions and 54 deletions
|
|
@ -256,7 +256,9 @@ class OpRough extends CamOp {
|
|||
}
|
||||
|
||||
// console.log('indices', ...indices, {zBottom});
|
||||
await slicer.slice(indices, { each: (data, index, total) => {
|
||||
let cnt = 0;
|
||||
let tot = 0;
|
||||
await slicer.slice(indices, { each: data => {
|
||||
shadow = unsafe ? data.tops : POLY.union(shadow.slice().appendAll(data.tops), 0.01, true);
|
||||
if (flats.indexOf(data.z) >= 0) {
|
||||
// exclude flats injected to complete shadow
|
||||
|
|
@ -268,8 +270,11 @@ class OpRough extends CamOp {
|
|||
// data.slice.tops[0].inner = data.shadow;
|
||||
// data.slice.tops[0].inner = POLY.setZ(tshadow.clone(true), data.z);
|
||||
slices.push(data.slice);
|
||||
progress((index / total) * 0.5);
|
||||
}, genso: true });
|
||||
progress(0.25 + 0.25 * (++cnt / tot));
|
||||
}, progress: (index, total) => {
|
||||
tot = total;
|
||||
progress((index / total) * 0.25);
|
||||
} });
|
||||
|
||||
if (trueShadow) {
|
||||
shadow = tshadow.clone(true);
|
||||
|
|
@ -376,7 +381,7 @@ class OpRough extends CamOp {
|
|||
slice.output()
|
||||
.setLayer("roughing", {face: color, line: color})
|
||||
.addPolys(offset);
|
||||
progress(0.5 + (index / slices.length) * 0.5);
|
||||
progress(0.5 + 0.5 * (index / slices.length));
|
||||
});
|
||||
|
||||
this.sliceOut = slices.filter(slice => slice.camLines);
|
||||
|
|
@ -505,6 +510,8 @@ class OpOutline extends CamOp {
|
|||
.filter(v => v > 0 && indices.indexOf(v) < 0);
|
||||
indices = indices.appendAll(flats).sort((a,b) => b-a);
|
||||
// console.log('indices', ...indices, {zBottom, slicer});
|
||||
let cnt = 0;
|
||||
let tot = 0;
|
||||
if (op.outside && !op.inside) {
|
||||
// console.log({outline_bypass: indices, down: op.down});
|
||||
indices.forEach((ind,i) => {
|
||||
|
|
@ -517,7 +524,7 @@ class OpOutline extends CamOp {
|
|||
slices.push(slice);
|
||||
});
|
||||
} else
|
||||
await slicer.slice(indices, { each: (data, index, total) => {
|
||||
await slicer.slice(indices, { each: data => {
|
||||
shadow = unsafe ? data.tops : POLY.union(shadow.slice().appendAll(data.tops), 0.01, true);
|
||||
if (flats.indexOf(data.z) >= 0) {
|
||||
// exclude flats injected to complete shadow
|
||||
|
|
@ -530,8 +537,11 @@ class OpOutline extends CamOp {
|
|||
slices.push(data.slice);
|
||||
// data.slice.xray();
|
||||
// onupdate(0.2 + (index/total) * 0.1, "outlines");
|
||||
progress(0.5 + 0.5 * (++cnt / tot));
|
||||
}, progress: (index, total) => {
|
||||
tot = total;
|
||||
progress((index / total) * 0.5);
|
||||
}, genso: true });
|
||||
} });
|
||||
shadow = POLY.union(shadow.appendAll(shadowTop.tops), 0.01, true);
|
||||
|
||||
// start slices at top of stock when `clear top` enabled
|
||||
|
|
@ -1493,7 +1503,7 @@ class OpXRay extends CamOp {
|
|||
let xrayind = Object.keys(slicer.zLine)
|
||||
.map(v => parseFloat(v).round(5))
|
||||
.sort((a,b) => a-b);
|
||||
let xrayopt = { each: (data, index, total) => {
|
||||
let xrayopt = { each: data => {
|
||||
let slice = newSlice(data.z);
|
||||
slice.addTops(data.tops);
|
||||
// data.tops.forEach(top => slice.addTop(top));
|
||||
|
|
@ -1534,7 +1544,9 @@ class OpShadow extends CamOp {
|
|||
}
|
||||
|
||||
let lsz; // only shadow up to bottom of last shadow for progressive union
|
||||
let terrain = await slicer.slice(tzindex, { each: (data, index, total) => {
|
||||
let cnt = 0;
|
||||
let tot = 0;
|
||||
let terrain = await slicer.slice(tzindex, { each: data => {
|
||||
let shadow = trueShadow ? shadowAt(data.z, lsz) : [];
|
||||
tshadow = POLY.union(tshadow.slice().appendAll(data.tops).appendAll(shadow), 0.01, true);
|
||||
tslices.push(data.slice);
|
||||
|
|
@ -1562,8 +1574,11 @@ class OpShadow extends CamOp {
|
|||
// .addLines(p2, { thin: true });
|
||||
}
|
||||
lsz = data.z;
|
||||
progress(index / total);
|
||||
}, genso: true });
|
||||
progress(0.5 + 0.5 * (++cnt / tot));
|
||||
}, progress: (index, total) => {
|
||||
tot = total;
|
||||
progress((index / total) * 0.5);
|
||||
} });
|
||||
|
||||
if (terrain.length === 0) {
|
||||
throw `invalid widget shadow`;
|
||||
|
|
|
|||
|
|
@ -342,7 +342,7 @@ CAM.traces = async function(settings, widget, single) {
|
|||
|
||||
let traces = [];
|
||||
// find and trim polys (including open) to shadow
|
||||
let oneach = (data, index, total) => {
|
||||
let oneach = data => {
|
||||
if (single) {
|
||||
for (let line of data.lines) {
|
||||
if (line.p1.distTo2D(line.p2) > 1) {
|
||||
|
|
|
|||
|
|
@ -15,6 +15,15 @@ const { sliceConnect, sliceDedup } = base;
|
|||
const { newSlice } = kiri;
|
||||
|
||||
const POLY = polygons;
|
||||
const timing = false;
|
||||
|
||||
const begin = function() {
|
||||
if (timing) console.time(...arguments);
|
||||
};
|
||||
|
||||
const end = function() {
|
||||
if (timing) console.timeEnd(...arguments);
|
||||
};
|
||||
|
||||
class Slicer {
|
||||
constructor(widget, options = { zlist: true, zline: true, lines: false }) {
|
||||
|
|
@ -30,14 +39,10 @@ class Slicer {
|
|||
return this.options.threaded;
|
||||
}
|
||||
|
||||
// notopok = when genso set, allow empty top array
|
||||
// emptyok = allow empty slices
|
||||
// openok = allow open tops
|
||||
// zList = generate list of z vertices
|
||||
// zline = generate list of z vertices with coplanar lines
|
||||
// trace = find z coplanar trace lines
|
||||
// flatoff = amount to offset z when slicing on detected flats
|
||||
// genso = generate a slice object with tops
|
||||
// each = call for each slice generated from an interval
|
||||
setOptions(options) {
|
||||
Object.assign(this.options, options || {});
|
||||
|
|
@ -57,7 +62,7 @@ class Slicer {
|
|||
// these are used for auto-slicing in laser
|
||||
// and to flats detection in CAM mode
|
||||
computeFeatures(options) {
|
||||
console.time('computeFeatures');
|
||||
begin('compute features');
|
||||
|
||||
const opt = this.setOptions(options);
|
||||
const bounds = this.bounds = new THREE.Box3();
|
||||
|
|
@ -120,10 +125,9 @@ class Slicer {
|
|||
}
|
||||
}
|
||||
|
||||
end('compute features');
|
||||
// console.log({ bounds, zFlat, zLine, zList });
|
||||
|
||||
console.timeEnd('computeFeatures');
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
@ -151,11 +155,11 @@ class Slicer {
|
|||
const plen = points.length;
|
||||
const zlen = zs.length;
|
||||
const ppz = plen / zlen;
|
||||
const count = 100;//Math.ceil(ppz / 10000);
|
||||
const count = 25;//Math.ceil(ppz / 10000);
|
||||
const step = Math.ceil(zlen / count);
|
||||
const buckets = [];
|
||||
|
||||
console.log({ plen, zlen, ppz, count, step });
|
||||
// console.log({ plen, zlen, ppz, count, step });
|
||||
|
||||
if (count === 1) {
|
||||
buckets.push({ zs });
|
||||
|
|
@ -173,7 +177,7 @@ class Slicer {
|
|||
p2 = newPoint(0,0,0),
|
||||
p3 = newPoint(0,0,0);
|
||||
|
||||
console.time("create buckets");
|
||||
begin("create buckets");
|
||||
for (let i = 0, il = points.length; i < il; ) {
|
||||
p1.set(points[i++], points[i++], points[i++]);
|
||||
p2.set(points[i++], points[i++], points[i++]);
|
||||
|
|
@ -190,30 +194,35 @@ class Slicer {
|
|||
if (zmin > max && zmax > max) {
|
||||
continue;
|
||||
}
|
||||
index.push(i);
|
||||
index.push(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z, p3.x, p3.y, p3.z);
|
||||
}
|
||||
}
|
||||
console.timeEnd("create buckets");
|
||||
end("create buckets");
|
||||
}
|
||||
|
||||
// console.log({ zs, zlen, count, step, buckets });
|
||||
|
||||
console.time("slicing");
|
||||
begin("slicing");
|
||||
const { minions } = kiri;
|
||||
const threaded = minions && minions.running;
|
||||
const sliceFn = (threaded ? this.sliceBucketMinion : this.sliceBucket).bind(this);
|
||||
const track = { count: 0, total: zs.length };
|
||||
|
||||
if (threaded) minions.broadcast("cam_slice_init", { points: this.points });
|
||||
console.log({ buckets });
|
||||
if (threaded) minions.broadcast("cam_slice_init", {});
|
||||
|
||||
const promises = []
|
||||
for (let bucket of buckets) {
|
||||
promises.push(sliceFn(bucket, opt));
|
||||
promises.push(sliceFn(bucket, opt, slice => {
|
||||
track.count++;
|
||||
if (opt.progress) {
|
||||
opt.progress(track.count, track.total);
|
||||
}
|
||||
// console.log({ oneach: slice, ...track });
|
||||
}));
|
||||
}
|
||||
const data = (await Promise.all(promises)).flat();
|
||||
|
||||
data.sort((a,b) => a.z - b.z).forEach((rec, i) => {
|
||||
data.sort((a,b) => b.z - a.z).forEach((rec, i) => {
|
||||
rec.tops = rec.polys;
|
||||
rec.slice = newSlice(rec.z).addTops(rec.tops);
|
||||
if (opt.each) {
|
||||
|
|
@ -222,13 +231,12 @@ class Slicer {
|
|||
});
|
||||
|
||||
if (threaded) minions.broadcast("cam_slice_cleanup");
|
||||
|
||||
console.timeEnd("slicing");
|
||||
end("slicing");
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
async sliceBucketMinion(bucket, opt) {
|
||||
async sliceBucketMinion(bucket, opt, oneach) {
|
||||
const slices = (await new Promise(resolve => {
|
||||
kiri.minions.queue({
|
||||
cmd: "cam_slice",
|
||||
|
|
@ -236,11 +244,14 @@ class Slicer {
|
|||
bucket,
|
||||
}, resolve);
|
||||
})).slices;
|
||||
console.log(bucket, slices);
|
||||
for (let slice of slices) {
|
||||
oneach(slice);
|
||||
}
|
||||
// console.log(bucket, slices);
|
||||
return kiri.codec.decode(slices);
|
||||
}
|
||||
|
||||
async sliceBucket(bucket, opt) {
|
||||
async sliceBucket(bucket, opt, oneach) {
|
||||
const { zs, index } = bucket;
|
||||
const slices = [];
|
||||
for (let z of zs) {
|
||||
|
|
@ -248,6 +259,7 @@ class Slicer {
|
|||
if (slice) {
|
||||
slices.push(slice);
|
||||
}
|
||||
oneach(slice);
|
||||
}
|
||||
return slices;
|
||||
}
|
||||
|
|
@ -259,19 +271,15 @@ class Slicer {
|
|||
over = opt.over || false,
|
||||
debug = opt.debug,
|
||||
phash = {},
|
||||
lines = [],
|
||||
index = 0,
|
||||
next = 0;
|
||||
lines = [];
|
||||
|
||||
const { points } = this,
|
||||
// const { points } = this,
|
||||
const points = indices,
|
||||
p1 = newPoint(0,0,0),
|
||||
p2 = newPoint(0,0,0),
|
||||
p3 = newPoint(0,0,0);
|
||||
|
||||
while (true) {
|
||||
if (indices) {
|
||||
index = indices[next++];
|
||||
}
|
||||
for (let index = 0; index < points.length; ) {
|
||||
p1.set(points[index++], points[index++], points[index++]);
|
||||
p2.set(points[index++], points[index++], points[index++]);
|
||||
p3.set(points[index++], points[index++], points[index++]);
|
||||
|
|
@ -307,13 +315,6 @@ class Slicer {
|
|||
console.log({msg: "invalid ips", line: line, where: where});
|
||||
}
|
||||
}
|
||||
|
||||
if (index >= points.length) {
|
||||
break;
|
||||
}
|
||||
if (indices && next >= indices.length) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (dedup) {
|
||||
|
|
@ -461,8 +462,8 @@ kiri.cam_slicer = Slicer;
|
|||
moto.broker.subscribe("minion.started", msg => {
|
||||
const { funcs, cache, reply, log } = msg;
|
||||
|
||||
funcs.cam_slice_init = data => {
|
||||
cache.slicer = new Slicer().setPoints(data.points);
|
||||
funcs.cam_slice_init = () => {
|
||||
cache.slicer = new Slicer();
|
||||
};
|
||||
|
||||
funcs.cam_slice_cleanup = () => {
|
||||
|
|
@ -471,10 +472,11 @@ moto.broker.subscribe("minion.started", msg => {
|
|||
|
||||
funcs.cam_slice = (data, seq) => {
|
||||
const { bucket, opt } = data;
|
||||
cache.slicer.sliceBucket(bucket, opt)
|
||||
.then(data => {
|
||||
reply({ seq, slices: kiri.codec.encode(data) });
|
||||
});
|
||||
cache.slicer.sliceBucket(bucket, opt, slice => {
|
||||
// console.log({ slice });
|
||||
}).then(data => {
|
||||
reply({ seq, slices: kiri.codec.encode(data) });
|
||||
});
|
||||
};
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue