From 9afba1b5677324320677ba6aeeffe0e066075e73 Mon Sep 17 00:00:00 2001 From: Stewart Allen Date: Thu, 12 Jan 2023 22:30:10 -0500 Subject: [PATCH] clean up raster code. tee up contour tracing in minions --- src/kiri-mode/cam/client.js | 2 +- src/kiri-mode/cam/topo.js | 243 ++++++++++++++++++++++-------------- 2 files changed, 147 insertions(+), 98 deletions(-) diff --git a/src/kiri-mode/cam/client.js b/src/kiri-mode/cam/client.js index 2778394e..3540fed4 100644 --- a/src/kiri-mode/cam/client.js +++ b/src/kiri-mode/cam/client.js @@ -1281,7 +1281,7 @@ CAM.init = function(kiri, api) { axis: UC.newSelect(LANG.cd_axis, {}, "regaxis"), sep: UC.newBlank({class:"pop-sep"}), spindle: UC.newInput(LANG.cc_spnd_s, {title:LANG.cc_spnd_l, convert:UC.toInt, show:hasSpindle}), - step: UC.newInput(LANG.cc_sovr_s, {title:LANG.cc_sovr_l, convert:UC.toFloat, bound:UC.bound(0.01,1.0)}), + step: UC.newInput(LANG.cc_sovr_s, {title:LANG.cc_sovr_l, convert:UC.toFloat, bound:UC.bound(0.01,2.0)}), rate: UC.newInput(LANG.cc_feed_s, {title:LANG.cc_feed_l, convert:UC.toInt, units:true}), angle: UC.newInput(LANG.cf_angl_s, {title:LANG.cf_angl_l, convert:UC.toFloat, bound:UC.bound(45,90)}), sep: UC.newBlank({class:"pop-sep"}), diff --git a/src/kiri-mode/cam/topo.js b/src/kiri-mode/cam/topo.js index 96a4479b..d26da6ae 100644 --- a/src/kiri-mode/cam/topo.js +++ b/src/kiri-mode/cam/topo.js @@ -56,7 +56,7 @@ class Topo { maxangle = contour.angle, curvesOnly = contour.curves, bridge = contour.bridging || 0, - R2A = 180 / Math.PI, + // R2A = 180 / Math.PI, stepsX = Math.ceil(boundsX / resolution), stepsY = Math.ceil(boundsY / resolution), widtopo = widget.topo, @@ -116,10 +116,7 @@ class Topo { sliceout, latent, lastP, - slice, lx, ly, - startTime = time(), - stepsTaken = 0, - stepsTotal = 0; + slice; // return the touching z given topo x,y and a tool profile function toolAtZ(x,y) { @@ -165,8 +162,8 @@ class Topo { return topo.data[ix * stepsY + iy] || zMin; }; - function push_point(x,y,z) { - const newP = newPoint(x,y,z); + function push_point(x, y, z) { + const newP = newPoint(x, y, z); // todo: merge co-linear, not just co-planar if (lastP && Math.abs(lastP.z - z) < flatness) { if (curvesOnly) { @@ -217,21 +214,28 @@ class Topo { gridy, gridi, // index gridv, // value - i, il, j, jl, x, y, tv, ltv; + i, il, j, x, y, tv, + stepsTaken = 0, + stepsTotal = 0; - const box = topo.box.expandByVector(new THREE.Vector3( + if (contourX) { + stepsTotal += ((maxX - minX + partOff * 2) / toolStep) | 0; + } + + if (contourY) { + stepsTotal += ((maxY - minY + partOff * 2) / toolStep) | 0; + } + + const box = topo.box.clone().expandByVector(new THREE.Vector3( partOff, partOff, 0 )); - const checkr = newPoint(0,0); - const inClip = function(polys, checkZ) { - checkr.x = x; - checkr.y = y; - for (let i=0; i box.max.y) { + gridy++; + continue; + } + // find tool z at grid point + let tv = toolAtZ(gridx, gridy); + checkr.x = x; + checkr.y = y; + // when tabs are on and this point is inside the + // tab polygon, ensure z is at least tabHeight + if (clipTab && tv < tabHeight && inClip(clipTab, tv, checkr)) { + tv = tabZ; + } + // if the value is on the floor and inside the clip + // poly (usually shadow), end the segment + if (clipTo && !inClip(clipTo, undefined, checkr)) { + end_poly(); + gridy++; + continue; + } + push_point(x, y, tv); + gridy++; + } + end_poly(); + } + + function traceX(params) { + let { from, to, step, box, y, gridx, gridy } = params; + let { clipTab, tabHeight, clipTo } = params; + const checkr = newPoint(0,0); + newtrace = newPolygon().setOpen(); + sliceout = []; + for (let x = from; x < to; x += step) { + if (x < box.min.x || y > box.max.x) { + gridx++; + continue; + } + // find tool z at grid point + let tv = toolAtZ(gridx, gridy); + checkr.x = x; + checkr.y = y; + // when tabs are on and this point is inside the + // tab polygon, ensure z is at least tabHeight + if (clipTab && tv < tabHeight && inClip(clipTab, tv, checkr)) { + tv = tabZ; + } + // if the value is on the floor and inside the clip + // poly (usually shadow), end the segment + if (clipTo && !inClip(clipTo, undefined, checkr)) { + end_poly(); + gridx++; + continue; + } + push_point(x, y, tv); + gridx++; + } + end_poly(); + } + if (contourY) { - startTime = time(); // emit slice per X for (x = minX - partOff; x <= maxX + partOff; x += toolStep) { if (x < box.min.x || x > box.max.x) continue; gridx = Math.round(((x - minX) / boundsX) * stepsX); - ly = gridy = -gridDelta; - slice = newSlice(gridx); - newtrace = newPolygon().setOpen(); - sliceout = []; - for (y = minY - partOff; y < maxY + partOff; y += resolution) { - if (y < box.min.y || y > box.max.y) { - gridy++; - continue; - } - // find tool z at grid point - tv = toolAtZ(gridx, gridy); - // when tabs are on and this point is inside the - // tab polygon, ensure z is at least tabHeight - if (tabsOn && tv < tabHeight && inClip(clipTab, tv)) { - tv = tabZ;//tabHeight; - } - // if the value is on the floor and inside the clip - // poly (usually shadow), end the segment - if (clipTo && !inClip(clipTo)) { - end_poly(); - gridy++; - ly = -gridDelta; - continue; - } - push_point(x,y,tv); - ly = y; - ltv = tv; - gridy++; - } - end_poly(); + gridy = -gridDelta; + + traceY({ + from: minY - partOff, + to: maxY + partOff, + step: resolution, + box, + x, + gridx, + gridy, + clipTo, + clipTab, + tabHeight + }); + if (sliceout.length > 0) { - newslices.push(slice); + slice = newSlice(gridx); slice.camLines = sliceout; slice.output() .setLayer("contour y", {face: color, line: color}) .addPolys(sliceout); + newslices.push(slice); } onupdate(++stepsTaken, stepsTotal, "contour y"); } } if (contourX) { - startTime = time(); // emit slice per Y for (y = minY - partOff; y <= maxY + partOff; y += toolStep) { if (y < box.min.y || y > box.max.y) continue; gridy = Math.round(((y - minY) / boundsY) * stepsY); - lx = gridx = -gridDelta; - slice = newSlice(gridy); - newtrace = newPolygon().setOpen(); - sliceout = []; - for (x = minX - partOff; x <= maxX + partOff; x += resolution) { - if (x < box.min.x || x > box.max.x) { - gridx++; - continue; - } - tv = toolAtZ(gridx, gridy); - if (tabsOn && tv < tabHeight && inClip(clipTab, tv)) { - tv = tabZ; - } - if (clipTo && !inClip(clipTo)) { - end_poly(); - gridx++; - lx = -gridDelta; - continue; - } - push_point(x,y,tv); - lx = x; - ltv = tv; - gridx++; - } - end_poly(); + gridx = -gridDelta; + + traceX({ + from: minX - partOff, + to: maxX + partOff, + step: resolution, + box, + y, + gridx, + gridy, + clipTo, + clipTab, + tabHeight + }); + if (sliceout.length > 0) { - newslices.push(slice); + slice = newSlice(gridy); slice.camLines = sliceout; slice.output() .setLayer("contour x", {face: color, line: color}) .addPolys(sliceout); + newslices.push(slice); } onupdate(++stepsTaken, stepsTotal, "contour x"); } } } - const box = topo.box = new THREE.Box2(); + if (topo.raster) { + const box = topo.box = new THREE.Box2(); - const params = { - resolution, - curvesOnly, - flatness, - stepsY, - minY, - maxY, - zMin, - data, - box - }; + const params = { + resolution, + curvesOnly, + flatness, + stepsY, + minY, + maxY, + zMin, + data, + box + }; - await this.topo_slice(widget, params); + onupdate(0, 1, "raster"); + await this.topo_raster(widget, params); + topo.raster = false; + } contouring(); ondone(newslices); @@ -351,10 +400,10 @@ class Topo { return this; } - async topo_slice(widget, params) { + async topo_raster(widget, params) { const { resolution } = params; - console.log({ topo_slice: widget, resolution }); + console.log({ topo_raster: widget, resolution }); const dispatch = kiri.worker; const minions = kiri.minions; @@ -391,7 +440,7 @@ class Topo { // define sharded ranges if (minions.running > 1) { - console.time('new topo slice minion'); + console.time('topo raster minion'); dispatch.putCache({ key: widget.id, data: vertices }, { done: data => { // console.log({ put_cache_done: data }); }}); @@ -399,7 +448,7 @@ class Topo { let promises = slices.map((slice, index) => { return new Promise(resolve => { minions.queue({ - cmd: "topo_slice", + cmd: "topo_raster", id: widget.id, params, slice @@ -424,11 +473,11 @@ class Topo { dispatch.clearCache({}, { done: data => { // console.log({ clear_cache_done: data }); }}); - console.timeEnd('new topo slice minion'); + console.timeEnd('topo raster minion'); } else { - console.time('new topo slice'); + console.time('topo raster'); // iterate over shards, merge output // const output = []; for (let slice of slices) { @@ -456,7 +505,7 @@ class Topo { return slice; }); } - console.timeEnd('new topo slice'); + console.timeEnd('topo raster'); } } @@ -470,7 +519,7 @@ function raster_slice(inputs) { let gridy, gridi, // index gridv, // value - i, il, j, jl, x, y, tv, ltv; + i, il, j, x, y, tv; // filter lines pairs to only surface "up-facing", "uncovered" lines let points = []; @@ -561,7 +610,7 @@ moto.broker.subscribe("minion.started", msg => { // console.log({ cam_slicer2_minion: msg }); const { funcs, cache, reply, log } = msg; - funcs.topo_slice = (data, seq) => { + funcs.topo_raster = (data, seq) => { const { id, slice, params } = data; const { resolution } = params; const vertices = cache[id];