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