From f271fa0fc843fe6c0ba7cd15be1621584194efc1 Mon Sep 17 00:00:00 2001 From: Stewart Allen Date: Fri, 31 Oct 2025 22:53:37 -0400 Subject: [PATCH] add gpu accelerated contouring --- src/kiri/mode/cam/op-contour.js | 2 +- src/kiri/mode/cam/prepare.js | 2 +- src/kiri/mode/cam/topo3.js | 124 +++++++++++++++++++++++++++++++- src/kiri/mode/cam/topo4.js | 2 +- src/kiri/run/worker.js | 3 + 5 files changed, 129 insertions(+), 4 deletions(-) diff --git a/src/kiri/mode/cam/op-contour.js b/src/kiri/mode/cam/op-contour.js index 1d14b313..ebeae04d 100644 --- a/src/kiri/mode/cam/op-contour.js +++ b/src/kiri/mode/cam/op-contour.js @@ -8,7 +8,7 @@ import { newPolygon } from '../../../geo/polygon.js'; import { tip2tipEmit } from '../../../geo/paths.js'; function createFilter(op, origin, axis) { - console.log({ origin, axis }); + // console.log({ origin, axis }); let ok = () => true; let filter = slices => slices; let filterString = op.filter?.map(l => l.trim()).join('\n'); diff --git a/src/kiri/mode/cam/prepare.js b/src/kiri/mode/cam/prepare.js index fafe22c6..516a5a09 100644 --- a/src/kiri/mode/cam/prepare.js +++ b/src/kiri/mode/cam/prepare.js @@ -429,7 +429,7 @@ export function prepEach(widget, settings, print, firstPoint, update) { emit = 1; isMove = false; } else if (deltaZ <= -tolerance) { - console.log({ deltaZ, tolerance }); + console.log({ deltaZ, tolerance, iscontour }); // move over before descending layerPush(point.clone().setZ(lastPoint.z), 0, 0, tool); // new pos for plunge calc diff --git a/src/kiri/mode/cam/topo3.js b/src/kiri/mode/cam/topo3.js index 678cf831..abe4984e 100644 --- a/src/kiri/mode/cam/topo3.js +++ b/src/kiri/mode/cam/topo3.js @@ -19,6 +19,7 @@ export class Topo { let { widget, settings, tshadow, tabs } = opt.state; let { controller, process } = settings, + { webGPU } = controller, animesh = parseInt(controller.animesh || 100) * 2500, axis = contour.axis.toLowerCase(), contourX = axis === "x", @@ -46,7 +47,6 @@ export class Topo { maxangle = contour.angle, curvesOnly = contour.curves, bridge = contour.bridging || 0, - // R2A = 180 / Math.PI, stepsX = Math.ceil(boundsX / resolution), stepsY = Math.ceil(boundsY / resolution), widtopo = widget.topo, @@ -107,6 +107,128 @@ export class Topo { newslices.push(debug); } + if (webGPU) { + // invert tool Z offset for gpu code + let gputool = toolOffset.slice(); + for (let i=0; i calcPoint(i * ymult + yoff, j * xmult + xoff, v, i * xStep, j * yStep)) + : Array.from(lineData).map((v,j) => calcPoint(j * xmult + xoff, i * ymult + yoff, v, j * xStep, i * yStep)) + ; + let slice = newSlice(i); + let poly = newPolygon().setOpen(); + let lines = slice.camLines = [ ]; + let skip = 0; + let lp; + for (let p of points) { + if (inside && positions[p.ty * terrain.gridWidth + p.tx] < zBottom - epsilon) { + if (poly.length > 1) { + lines.push(poly); + poly = newPolygon().setOpen(); + } else if (poly.length === 1) { + poly = newPolygon().setOpen(); + } + lp = undefined; + skip = 0; + continue; + } + if (p.z < zBottom - epsilon) { + lp = p; + if (poly.length === 0) { + skip++; + continue; + } + if (poly.length > 1) { + skip = 0; + p.z = zBottom; + poly.push(p); + lines.push(poly); + poly = newPolygon().setOpen(); + continue; + } + } else if (lp && skip && poly.length === 0) { + lp.z = zBottom; + poly.push(lp); + } + poly.push(lp = p); + skip = 0; + } + if (poly.length > 1) { + lines.push(poly); + } + if (!inside && clipTab.length) + for (let poly of lines) { + for (let p of poly.points) { + for (let clip of clipTab) { + if (p.z < clip.z && p.isInPolygon(clip)) { + p.z = clip.z; + break; + } + } + } + } + slices.push(slice); + if (inside) { + onupdate(i, numScanlines); + } + } + ondone(slices); + return this; + } + const probe = this.probe = new Probe({ profile: toolOffset, data, diff --git a/src/kiri/mode/cam/topo4.js b/src/kiri/mode/cam/topo4.js index c29be373..af58f74e 100644 --- a/src/kiri/mode/cam/topo4.js +++ b/src/kiri/mode/cam/topo4.js @@ -190,7 +190,7 @@ export class Topo { zBottom, resolution, bounds, - { onProgress(pct, msg) { onupdate(pct/100) } } + { onProgress(pct) { onupdate(pct/100) } } ); let { numRotations, pointsPerLine, pathData } = output; diff --git a/src/kiri/run/worker.js b/src/kiri/run/worker.js index 9059a3c7..e55ad8aa 100644 --- a/src/kiri/run/worker.js +++ b/src/kiri/run/worker.js @@ -65,6 +65,9 @@ self.alert = function(o) { self.uuid = ((Math.random() * Date.now()) | 0).toString(36); +/** + * @returns {RasterPath} + */ self.get_raster_gpu = async function() { let gpu = self.raster_gpu; if (!gpu) {