add gpu accelerated contouring
This commit is contained in:
parent
007d03b629
commit
f271fa0fc8
5 changed files with 129 additions and 4 deletions
|
|
@ -8,7 +8,7 @@ import { newPolygon } from '../../../geo/polygon.js';
|
||||||
import { tip2tipEmit } from '../../../geo/paths.js';
|
import { tip2tipEmit } from '../../../geo/paths.js';
|
||||||
|
|
||||||
function createFilter(op, origin, axis) {
|
function createFilter(op, origin, axis) {
|
||||||
console.log({ origin, axis });
|
// console.log({ origin, axis });
|
||||||
let ok = () => true;
|
let ok = () => true;
|
||||||
let filter = slices => slices;
|
let filter = slices => slices;
|
||||||
let filterString = op.filter?.map(l => l.trim()).join('\n');
|
let filterString = op.filter?.map(l => l.trim()).join('\n');
|
||||||
|
|
|
||||||
|
|
@ -429,7 +429,7 @@ export function prepEach(widget, settings, print, firstPoint, update) {
|
||||||
emit = 1;
|
emit = 1;
|
||||||
isMove = false;
|
isMove = false;
|
||||||
} else if (deltaZ <= -tolerance) {
|
} else if (deltaZ <= -tolerance) {
|
||||||
console.log({ deltaZ, tolerance });
|
console.log({ deltaZ, tolerance, iscontour });
|
||||||
// move over before descending
|
// move over before descending
|
||||||
layerPush(point.clone().setZ(lastPoint.z), 0, 0, tool);
|
layerPush(point.clone().setZ(lastPoint.z), 0, 0, tool);
|
||||||
// new pos for plunge calc
|
// new pos for plunge calc
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ export class Topo {
|
||||||
let { widget, settings, tshadow, tabs } = opt.state;
|
let { widget, settings, tshadow, tabs } = opt.state;
|
||||||
|
|
||||||
let { controller, process } = settings,
|
let { controller, process } = settings,
|
||||||
|
{ webGPU } = controller,
|
||||||
animesh = parseInt(controller.animesh || 100) * 2500,
|
animesh = parseInt(controller.animesh || 100) * 2500,
|
||||||
axis = contour.axis.toLowerCase(),
|
axis = contour.axis.toLowerCase(),
|
||||||
contourX = axis === "x",
|
contourX = axis === "x",
|
||||||
|
|
@ -46,7 +47,6 @@ export class Topo {
|
||||||
maxangle = contour.angle,
|
maxangle = contour.angle,
|
||||||
curvesOnly = contour.curves,
|
curvesOnly = contour.curves,
|
||||||
bridge = contour.bridging || 0,
|
bridge = contour.bridging || 0,
|
||||||
// R2A = 180 / Math.PI,
|
|
||||||
stepsX = Math.ceil(boundsX / resolution),
|
stepsX = Math.ceil(boundsX / resolution),
|
||||||
stepsY = Math.ceil(boundsY / resolution),
|
stepsY = Math.ceil(boundsY / resolution),
|
||||||
widtopo = widget.topo,
|
widtopo = widget.topo,
|
||||||
|
|
@ -107,6 +107,128 @@ export class Topo {
|
||||||
newslices.push(debug);
|
newslices.push(debug);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (webGPU) {
|
||||||
|
// invert tool Z offset for gpu code
|
||||||
|
let gputool = toolOffset.slice();
|
||||||
|
for (let i=0; i<gputool.length; i+= 3) {
|
||||||
|
gputool[i+2] *= -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const vertices = widget.getGeoVertices({ unroll: true, translate: true });
|
||||||
|
const wbounds = widget.getBoundingBox();
|
||||||
|
if (!inside) {
|
||||||
|
wbounds.expandByVector({ x: toolDiameter/2, y: toolDiameter/2, z: 0 });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (contourY) {
|
||||||
|
console.time('swap XY vertices');
|
||||||
|
// swap XY vertices
|
||||||
|
for (let i=0; i<vertices.length; i+= 3) {
|
||||||
|
let tmp = vertices[i+1];
|
||||||
|
vertices[i+1] = vertices[i+0];
|
||||||
|
vertices[i+0] = tmp;
|
||||||
|
}
|
||||||
|
console.timeEnd('swap XY vertices');
|
||||||
|
}
|
||||||
|
|
||||||
|
let gpu = await self.get_raster_gpu();
|
||||||
|
let xStep = density;
|
||||||
|
let yStep = Math.round(toolStep / resolution);
|
||||||
|
let epsilon = 10e-5;
|
||||||
|
let terrain = await gpu.rasterizeMesh(vertices, tolerance, 0, wbounds);
|
||||||
|
let { positions } = terrain;
|
||||||
|
let output = await gpu.generatePlanarToolpath(
|
||||||
|
positions,
|
||||||
|
gputool,
|
||||||
|
xStep,
|
||||||
|
yStep,
|
||||||
|
zBottom - 1,
|
||||||
|
resolution,
|
||||||
|
{
|
||||||
|
terrainBounds: wbounds,
|
||||||
|
onProgress(pct) { console.log({ pct }); onupdate(pct/100, 100) }
|
||||||
|
}
|
||||||
|
);
|
||||||
|
let { numScanlines, pointsPerLine, pathData } = output;
|
||||||
|
let xmult = xStep * resolution;
|
||||||
|
let ymult = yStep * resolution;
|
||||||
|
let xoff = wbounds.min.x;
|
||||||
|
let yoff = wbounds.min.y;
|
||||||
|
let slices = [];
|
||||||
|
function calcPoint(x, y, z, tx, ty) {
|
||||||
|
let p = newPoint(x, y, z);
|
||||||
|
p.tx = tx;
|
||||||
|
p.ty = ty;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
for (let i=0; i<numScanlines; i++) {
|
||||||
|
let lineStart = i * pointsPerLine;
|
||||||
|
let lineData = pathData.slice(lineStart, lineStart + pointsPerLine);
|
||||||
|
let points = contourY
|
||||||
|
? Array.from(lineData).map((v,j) => 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({
|
const probe = this.probe = new Probe({
|
||||||
profile: toolOffset,
|
profile: toolOffset,
|
||||||
data,
|
data,
|
||||||
|
|
|
||||||
|
|
@ -190,7 +190,7 @@ export class Topo {
|
||||||
zBottom,
|
zBottom,
|
||||||
resolution,
|
resolution,
|
||||||
bounds,
|
bounds,
|
||||||
{ onProgress(pct, msg) { onupdate(pct/100) } }
|
{ onProgress(pct) { onupdate(pct/100) } }
|
||||||
);
|
);
|
||||||
|
|
||||||
let { numRotations, pointsPerLine, pathData } = output;
|
let { numRotations, pointsPerLine, pathData } = output;
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,9 @@ self.alert = function(o) {
|
||||||
|
|
||||||
self.uuid = ((Math.random() * Date.now()) | 0).toString(36);
|
self.uuid = ((Math.random() * Date.now()) | 0).toString(36);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {RasterPath}
|
||||||
|
*/
|
||||||
self.get_raster_gpu = async function() {
|
self.get_raster_gpu = async function() {
|
||||||
let gpu = self.raster_gpu;
|
let gpu = self.raster_gpu;
|
||||||
if (!gpu) {
|
if (!gpu) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue