first crude / inaccurate lathe path

This commit is contained in:
Stewart Allen 2023-01-16 23:33:24 -05:00
commit 0ff63dae50
3 changed files with 112 additions and 65 deletions

View file

@ -132,11 +132,11 @@ class Tool {
profile.set(toolOffset); profile.set(toolOffset);
this.profile = profile; this.profile = profile;
this.profileDim = { this.profileDim = {
size: shaft_diameter, size: shaft_diameter,
pix: profile_pix_iter + 2 pix: profile_pix_iter + 2
}; };
return this; return this;
} }
} }

View file

@ -43,28 +43,26 @@ class Topo4 {
x: axis === "x", x: axis === "x",
y: axis === "y" y: axis === "y"
}, },
tolerance = op.tolerance,
zMin = min.z + 0.0001, zMin = min.z + 0.0001,
tolerance = op.tolerance,
resolution = tolerance ? tolerance : 1 / Math.sqrt(density / (span.x * span.y)), resolution = tolerance ? tolerance : 1 / Math.sqrt(density / (span.x * span.y)),
toolOffset = tool.generateProfile(resolution).profile, step = this.step = tool.fluteDiameter() * op.step;
toolDiameter = tool.fluteDiameter(),
toolStep = toolDiameter * op.step,
steps = {
x: Math.ceil(span.x / resolution),
y: Math.ceil(span.y / resolution)
};
if (tolerance === 0) { if (tolerance === 0) {
console.log(widget.id, 'topo4 auto tolerance', resolution.round(4)); console.log(widget.id, 'topo4 auto tolerance', resolution.round(4));
} }
this.widget = widget;
this.resolution = resolution; this.resolution = resolution;
this.vertices = widget.getGeoVertices().toShared();
this.tool = tool.generateProfile(resolution).profile;
onupdate(0, "lathe"); onupdate(0, "lathe");
const slices = await this.slice(onupdate); const range = this.range = { min: Infinity, max: -Infinity };
const slices = this.sliced = await this.slice(onupdate);
for (let slice of slices) { for (let slice of slices) {
range.min = Math.min(range.min, slice.z);
range.max = Math.max(range.max, slice.z);
slice.output() slice.output()
.setLayer("lathe", { line: 0x888888 }) .setLayer("lathe", { line: 0x888888 })
.addPolys(slice.topPolys()); .addPolys(slice.topPolys());
@ -77,9 +75,8 @@ class Topo4 {
} }
async slice(onupdate) { async slice(onupdate) {
const { widget, resolution } = this; const { vertices, resolution } = this;
const vertices = this.vertices = widget.getGeoVertices().toShared();
const range = this.range = { min: Infinity, max: -Infinity }; const range = this.range = { min: Infinity, max: -Infinity };
const box = this.box = new THREE.Box2(); const box = this.box = new THREE.Box2();
@ -108,7 +105,7 @@ class Topo4 {
index++; index++;
} }
slices.push(slice); slices.push(slice);
// console.log({ shards, range, step, slices }); console.log({ shards, range, step, slices });
if (kiri.minions.running > 1) { if (kiri.minions.running > 1) {
return await this.sliceMinions(onupdate); return await this.sliceMinions(onupdate);
@ -152,25 +149,19 @@ class Topo4 {
} }
async sliceMinions(onupdate) { async sliceMinions(onupdate) {
const { worker, minions, codec } = kiri; const { codec } = kiri;
const { widget, vertices, slices, resolution } = this; const { queue, putCache, clearCache } = this;
const { vertices, slices, resolution } = this;
worker.putCache({ key: widget.id, data: vertices }, { done: data => { putCache("vertices", vertices);
// console.log({ put_cache_done: data });
}});
let complete = 0; let complete = 0;
let promises = slices.map(slice => { let promises = slices.map(slice => {
return new Promise(resolve => { return queue("topo4_slice", {
minions.queue({ resolution,
cmd: "topo4_slice", slice
id: widget.id, }).then(data => {
resolution, onupdate(++complete / slices.length);
slice return data;
}, data => {
resolve(data);
onupdate(++complete / slices.length);
});
}); });
}); });
@ -183,13 +174,12 @@ class Topo4 {
.setFields({ shared: rec.shared })) .setFields({ shared: rec.shared }))
.sort((a,b) => a.z - b.z); .sort((a,b) => a.z - b.z);
worker.clearCache({}, { done: data => { }}); clearCache();
return output; return output;
} }
async lathe(onupdate) { async lathe(onupdate) {
if (kiri.minions.running > 1) { if (false && kiri.minions.running > 1) {
return await this.latheMinions(onupdate); return await this.latheMinions(onupdate);
} else { } else {
return await this.latheWorker(onupdate); return await this.latheWorker(onupdate);
@ -197,43 +187,95 @@ class Topo4 {
} }
async latheWorker(onupdate) { async latheWorker(onupdate) {
const { range, resolution, sliced, tool } = this;
const slices = sliced.map(s => { return { z: s.z, lines: s.shared } });
const heights = [];
const tlen = tool.length;
const slen = slices.length;
// iterate over all slices (real x = z)
// find max real z using z ray intersect from tool point to slice lines + offset
for (let si = 0; si < slen; si++) {
const rx = slices[si].z;
let mz = 0;
// iterate over tool offsets
for (let ti = 0; ti < tlen; ) {
// tool offset in grid units from present x (si)
const xo = tool[ti++]; // x grid offset (slice)
const yo = tool[ti++]; // y grid offset (mult rez to get real y)
const zo = tool[ti++]; // real z delta offset
// get slice index corresponding with offset
const ts = si + xo;
// outside of slice array, skip
if (ts < 0 || ts >= slen) continue;
const slice = slices[ts];
const lines = slice.lines;
const plen = lines.length;
for (let i = 0; i < plen; ) {
++i; // skip x which should match slice.z
const py0 = lines[i++];
const pz0 = lines[i++];
++i; // skip x which should match slice.z
const py1 = lines[i++];
const pz1 = lines[i++];
if (py0 <= yo && py1 >= yo) {
// check z height
mz = Math.max(mz, pz0, pz1);
}
}
}
heights.push(mz);
}
console.log({ tool, range, resolution, slices, heights });
return []; return [];
} }
async latheMinions(onupdate) { async latheMinions(onupdate) {
const { worker, minions, codec } = kiri; const { codec } = kiri;
const { slices, resolution } = this; const { sliced, range, resolution, tool } = this;
const { putCache, clearCache, queue } = this;
worker.putCache({ console.log({ sliced });
key: "lathe", putCache("lathe", {
data: slices.map(s => { tool,
return { z: s.z, lines: s.shared } range,
}) resolution,
}, { done: data => { slices: sliced.map(s => { return { z: s.z, lines: s.shared } })
// console.log({ put_cache_done: data }); });
}});
let complete = 0; let complete = 0;
let promises = slices.map(slice => { let promises = sliced.map(slice => {
return new Promise(resolve => { return queue("topo4_lathe", {
minions.queue({ // resolution
cmd: "topo4_lathe", }).then(data => {
resolution onupdate(++complete / sliced.length);
}, data => { return data;
resolve(data);
onupdate(++complete / slices.length);
}); });
});
}); });
// merge boxes for all rasters for contouring clipping // merge boxes for all rasters for contouring clipping
const output = await Promise.all(promises); const output = await Promise.all(promises);
console.log({ output });
worker.clearCache({}, { done: data => { }}); clearCache();
return []; return [];
} }
putCache(key, data) {
kiri.worker.putCache({ key, data }, { done: data => { } });
}
clearCache() {
kiri.worker.clearCache({}, { done: data => { } });
}
queue(cmd, params) {
return new Promise(resolve => {
kiri.minions.queue({ cmd, ...params }, resolve);
});
}
} }
CAM.Topo4 = async function(opt) { CAM.Topo4 = async function(opt) {
@ -245,8 +287,8 @@ moto.broker.subscribe("minion.started", msg => {
const { codec } = kiri; const { codec } = kiri;
funcs.topo4_slice = (data, seq) => { funcs.topo4_slice = (data, seq) => {
const { id, slice, resolution } = data; const { slice, resolution } = data;
const vertices = cache[id]; const vertices = cache.vertices;
const recs = new kiri.topo_slicer(slice.index) const recs = new kiri.topo_slicer(slice.index)
.setFromArray(vertices, slice) .setFromArray(vertices, slice)
.slice(resolution) .slice(resolution)
@ -273,12 +315,10 @@ moto.broker.subscribe("minion.started", msg => {
}; };
funcs.topo4_lathe = (data, seq) => { funcs.topo4_lathe = (data, seq) => {
console.log({ topo4_lathe: cache }); // console.log({ topo4_lathe: data });
const { resolution } = data; // const { resolution } = data;
const slices = cache.lathe; const { resolution, sliced, tool } = cache.lathe;
log({ slices, resolution });
reply({ seq, abc: 123 }); reply({ seq, abc: 123 });
} }

View file

@ -45,9 +45,16 @@ function parse(text) {
case 'f': case 'f':
let tok = toks.map(f => parseInt(f.split('/')[0])); let tok = toks.map(f => parseInt(f.split('/')[0]));
// add support for negative indices (offset from last vertex array point) // add support for negative indices (offset from last vertex array point)
faces.appendAll(verts[tok[0]-1]); if (toks.length > 3) {
faces.appendAll(verts[tok[1]-1]); // earcut faces > 3 vertices
faces.appendAll(verts[tok[2]-1]); // faces.appendAll(verts[tok[1]-1]);
// faces.appendAll(verts[tok[2]-1]);
// faces.appendAll(verts[tok[3]-1]);
} else {
faces.appendAll(verts[tok[0]-1]);
faces.appendAll(verts[tok[1]-1]);
faces.appendAll(verts[tok[2]-1]);
}
break; break;
case 'g': case 'g':
if (faces.length) { if (faces.length) {