track slice index to assist sharded raster

This commit is contained in:
Stewart Allen 2023-01-11 19:23:46 -05:00
commit 3fb23a818b
2 changed files with 45 additions and 27 deletions

View file

@ -16,9 +16,10 @@ class Slicer {
static checkOverUnderOn = checkOverUnderOn; static checkOverUnderOn = checkOverUnderOn;
static removeDuplicateLines = removeDuplicateLines; static removeDuplicateLines = removeDuplicateLines;
constructor() { constructor(index = 0) {
this.min = Infinity; this.min = Infinity;
this.max = -Infinity; this.max = -Infinity;
this.index = index;
} }
// position is a non-indexed 3js geometry position attribute array // position is a non-indexed 3js geometry position attribute array
@ -78,7 +79,7 @@ class Slicer {
slice(interval = 1) { slice(interval = 1) {
const ret = []; const ret = [];
for (let z = this.min; z < this.max; z += interval) { for (let z = this.min; z < this.max; z += interval) {
ret.push({ z, lines: this.sliceZ(z) }); ret.push({ z, index: this.index++, lines: this.sliceZ(z) });
} }
return ret; return ret;
} }

View file

@ -57,14 +57,14 @@ class Topo {
curvesOnly = contour.curves, curvesOnly = contour.curves,
bridge = contour.bridging || 0, bridge = contour.bridging || 0,
R2A = 180 / Math.PI, 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,
topoCache = widtopo && widtopo.resolution === resolution ? widtopo : undefined, topoCache = widtopo && widtopo.resolution === resolution ? widtopo : undefined,
topo = widget.topo = topoCache || { topo = widget.topo = topoCache || {
data: new Float32Array(new SharedArrayBuffer(stepsx * stepsy * 4)), data: new Float32Array(new SharedArrayBuffer(stepsX * stepsY * 4)),
stepsx: stepsx, stepsX: stepsX,
stepsy: stepsy, stepsY: stepsY,
bounds: bounds, bounds: bounds,
diameter: toolDiameter, diameter: toolDiameter,
resolution: resolution, resolution: resolution,
@ -124,8 +124,8 @@ class Topo {
// return the touching z given topo x,y and a tool profile // return the touching z given topo x,y and a tool profile
function toolAtZ(x,y) { function toolAtZ(x,y) {
const profile = toolOffset, const profile = toolOffset,
sx = stepsx, sx = stepsX,
sy = stepsy, sy = stepsY,
xl = sx - 1, xl = sx - 1,
yl = sy - 1; yl = sy - 1;
@ -151,8 +151,8 @@ class Topo {
} }
// export z probe function // export z probe function
const rx = stepsx / boundsX; const rx = stepsX / boundsX;
const ry = stepsx / boundsX; const ry = stepsX / boundsX;
this.toolAtXY = function(px, py) { this.toolAtXY = function(px, py) {
px = Math.round(rx * (px - minX)); px = Math.round(rx * (px - minX));
py = Math.round(ry * (py - minY)); py = Math.round(ry * (py - minY));
@ -162,7 +162,7 @@ class Topo {
const zAtXY = this.zAtXY = function(px, py) { const zAtXY = this.zAtXY = function(px, py) {
let ix = Math.round(rx * (px - minX)); let ix = Math.round(rx * (px - minX));
let iy = Math.round(ry * (py - minY)); let iy = Math.round(ry * (py - minY));
return topo.data[ix * stepsy + iy] || zMin; return topo.data[ix * stepsY + iy] || zMin;
}; };
function push_point(x,y,z) { function push_point(x,y,z) {
@ -234,7 +234,7 @@ class Topo {
zMin, zMin,
minY, minY,
maxY, maxY,
stepsy, stepsY,
slice, slice,
gridx: gridx++ gridx: gridx++
}); });
@ -275,7 +275,7 @@ class Topo {
// emit slice per X // emit slice per X
for (x = minX - partOff; x <= maxX + partOff; x += toolStep) { for (x = minX - partOff; x <= maxX + partOff; x += toolStep) {
if (x < box.min.x || x > box.max.x) continue; if (x < box.min.x || x > box.max.x) continue;
gridx = Math.round(((x - minX) / boundsX) * stepsx); gridx = Math.round(((x - minX) / boundsX) * stepsX);
ly = gridy = -gridDelta; ly = gridy = -gridDelta;
slice = newSlice(gridx); slice = newSlice(gridx);
newtrace = newPolygon().setOpen(); newtrace = newPolygon().setOpen();
@ -322,7 +322,7 @@ class Topo {
// emit slice per Y // emit slice per Y
for (y = minY - partOff; y <= maxY + partOff; y += toolStep) { for (y = minY - partOff; y <= maxY + partOff; y += toolStep) {
if (y < box.min.y || y > box.max.y) continue; if (y < box.min.y || y > box.max.y) continue;
gridy = Math.round(((y - minY) / boundsY) * stepsy); gridy = Math.round(((y - minY) / boundsY) * stepsY);
lx = gridx = -gridDelta; lx = gridx = -gridDelta;
slice = newSlice(gridy); slice = newSlice(gridy);
newtrace = newPolygon().setOpen(); newtrace = newPolygon().setOpen();
@ -360,7 +360,18 @@ class Topo {
} }
} }
const slices2 = await this.topo_slice(widget, resolution); const params = {
resolution,
curvesOnly,
flatness,
stepsY,
minY,
maxY,
zMin,
data
};
const slices2 = await this.topo_slice(widget, params);
rastering(slices2); rastering(slices2);
contouring(slices2); contouring(slices2);
@ -369,7 +380,9 @@ class Topo {
return this; return this;
} }
async topo_slice(widget, resolution) { async topo_slice(widget, params) {
const { resolution } = params;
console.log({ topo_slice: widget, resolution }); console.log({ topo_slice: widget, resolution });
const dispatch = kiri.worker; const dispatch = kiri.worker;
@ -391,12 +404,14 @@ class Topo {
const step = (range.max - range.min) / shards; const step = (range.max - range.min) / shards;
let slices = []; let slices = [];
let slice = { min: range.min, max: range.min + step }; let index = 0;
let slice = { min: range.min, max: range.min + step, index };
for (let z = range.min; z < range.max; z += resolution) { for (let z = range.min; z < range.max; z += resolution) {
if (z > slice.max) { if (z > slice.max) {
slices.push(slice); slices.push(slice);
slice = { min: z, max: z + step }; slice = { min: z, max: z + step, index };
} }
index++;
} }
slices.push(slice); slices.push(slice);
console.log({ shards, range, step, slices }); console.log({ shards, range, step, slices });
@ -409,7 +424,7 @@ class Topo {
// console.log({ put_cache_done: data }); // console.log({ put_cache_done: data });
}}); }});
let ps = slices.map(slice => { let ps = slices.map((slice, index) => {
return new Promise(resolve => { return new Promise(resolve => {
minions.queue({ minions.queue({
cmd: "topo_slice", cmd: "topo_slice",
@ -428,8 +443,9 @@ class Topo {
.sort((a,b) => a[0] - b[0]) .sort((a,b) => a[0] - b[0])
.map(rec => { .map(rec => {
let slice = kiri.newSlice(rec[0]); let slice = kiri.newSlice(rec[0]);
slice.index = rec[1];
let lines = slice.lines = []; let lines = slice.lines = [];
for (let i=1, l=rec.length; i<l; ) { for (let i=2, l=rec.length; i<l; ) {
lines.push( lines.push(
base.newLine( base.newLine(
base.newPoint(rec[i++], rec[i++], rec[i++]), base.newPoint(rec[i++], rec[i++], rec[i++]),
@ -452,11 +468,12 @@ class Topo {
// iterate over shards, merge output // iterate over shards, merge output
const output = []; const output = [];
for (let slice of slices) { for (let slice of slices) {
const res = new kiri.topo_slicer() const res = new kiri.topo_slicer(slice.index)
.setFromArray(vertices, slice) .setFromArray(vertices, slice)
.slice(resolution) .slice(resolution)
.map(rec => { .map(rec => {
const slice = kiri.newSlice(rec.z); const slice = kiri.newSlice(rec.z);
slice.index = rec.index;
slice.lines = rec.lines; slice.lines = rec.lines;
for (let line of rec.lines) { for (let line of rec.lines) {
const { p1, p2 } = line; const { p1, p2 } = line;
@ -477,7 +494,7 @@ class Topo {
function raster_slice(inputs) { function raster_slice(inputs) {
const { lines, data, box, resolution, curvesOnly } = inputs; const { lines, data, box, resolution, curvesOnly } = inputs;
const { flatness, zMin, minY, maxY, stepsy, gridx } = inputs; const { flatness, zMin, minY, maxY, stepsY, gridx } = inputs;
const { slice } = inputs; const { slice } = inputs;
let gridy, let gridy,
@ -518,8 +535,8 @@ function raster_slice(inputs) {
gridy = 0; gridy = 0;
// rasterize one x slice // rasterize one x slice
for (y = minY; y < maxY && gridy < stepsy; y += resolution) { for (y = minY; y < maxY && gridy < stepsY; y += resolution) {
gridi = gridx * stepsy + gridy; gridi = gridx * stepsY + gridy;
gridv = data[gridi] || 0; gridv = data[gridi] || 0;
// strategy using raw lines (faster slice, but more lines) // strategy using raw lines (faster slice, but more lines)
for (i=0, il=points.length; i<il; i += 2) { for (i=0, il=points.length; i<il; i += 2) {
@ -576,11 +593,11 @@ moto.broker.subscribe("minion.started", msg => {
funcs.topo_slice = (data, seq) => { funcs.topo_slice = (data, seq) => {
const vertices = cache[data.id]; const vertices = cache[data.id];
const res = new kiri.topo_slicer() const res = new kiri.topo_slicer(data.slice.index)
.setFromArray(vertices, data.slice) .setFromArray(vertices, data.slice)
.slice(data.resolution) .slice(data.resolution)
.map(rec => { .map(rec => {
const ret = [ rec.z ]; const ret = [ rec.z, rec.index ];
for (let line of rec.lines) { for (let line of rec.lines) {
const { p1, p2 } = line; const { p1, p2 } = line;
if (!p1.swapped) { p1.swapXZ(); p1.swapped = true } if (!p1.swapped) { p1.swapXZ(); p1.swapped = true }