From 70c00e1babd3bc58de192d077b0b6ba83cce77e4 Mon Sep 17 00:00:00 2001 From: Stewart Allen Date: Sun, 15 Jan 2023 15:06:29 -0500 Subject: [PATCH] cam fix slice z output order, restore progress bar accuracy --- src/kiri-mode/cam/ops.js | 35 ++++++++++----- src/kiri-mode/cam/slice.js | 2 +- src/kiri-mode/cam/slicer.js | 88 +++++++++++++++++++------------------ 3 files changed, 71 insertions(+), 54 deletions(-) diff --git a/src/kiri-mode/cam/ops.js b/src/kiri-mode/cam/ops.js index 4177f10e..503c9077 100644 --- a/src/kiri-mode/cam/ops.js +++ b/src/kiri-mode/cam/ops.js @@ -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`; diff --git a/src/kiri-mode/cam/slice.js b/src/kiri-mode/cam/slice.js index eb95a2c9..8fddcc70 100644 --- a/src/kiri-mode/cam/slice.js +++ b/src/kiri-mode/cam/slice.js @@ -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) { diff --git a/src/kiri-mode/cam/slicer.js b/src/kiri-mode/cam/slicer.js index 2b3a6a62..7e5dbd43 100644 --- a/src/kiri-mode/cam/slicer.js +++ b/src/kiri-mode/cam/slicer.js @@ -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) }); + }); }; });