fix arc.flat() bug, migrate 3d/4d topo for minions
This commit is contained in:
parent
bf3a6b1f1b
commit
3a71c93752
7 changed files with 135 additions and 155 deletions
|
|
@ -8,7 +8,7 @@ if (!AP.flat) {
|
||||||
try {
|
try {
|
||||||
return [].concat.apply([], this);
|
return [].concat.apply([], this);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// console.log({flat_error: e});
|
// console.log({ flat_error: e, array: this });
|
||||||
let out = [];
|
let out = [];
|
||||||
for (let e of this.slice()) {
|
for (let e of this.slice()) {
|
||||||
out.push(...e);
|
out.push(...e);
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ export function init(worker) {
|
||||||
|
|
||||||
// destructure arcs into path points
|
// destructure arcs into path points
|
||||||
path = path.map(o =>
|
path = path.map(o =>
|
||||||
o.arcPoints ? [ ...o.arcPoints.map(point => ({ ...o, point })), o ] : o
|
o.arcPoints ? [ ...o.arcPoints.map(point => ({ ...o, point })), o ] : [ o ]
|
||||||
).flat();
|
).flat();
|
||||||
|
|
||||||
const step = rez;
|
const step = rez;
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
// WORKER BACK END ANIMATION CODE for 3D (indexed)
|
// WORKER BACK END ANIMATION CODE for 3D (indexed)
|
||||||
|
|
||||||
import { CSG } from '../../geo/csg.js';
|
import { CSG } from '../../geo/csg.js';
|
||||||
|
import { Tool } from './tool.js';
|
||||||
|
|
||||||
let nextMeshID = 1;
|
let nextMeshID = 1;
|
||||||
let stock, center, rez;
|
let stock, center, rez;
|
||||||
|
|
@ -269,7 +270,7 @@ function toolUpdate(toolid, send) {
|
||||||
if (tool) {
|
if (tool) {
|
||||||
send.data({ mesh_del: toolID });
|
send.data({ mesh_del: toolID });
|
||||||
}
|
}
|
||||||
tool = new CAM.Tool({ tools }, toolid);
|
tool = new Tool({ tools }, toolid);
|
||||||
const Instance = CSG.Instance();
|
const Instance = CSG.Instance();
|
||||||
const slen = tool.shaftLength() || 15;
|
const slen = tool.shaftLength() || 15;
|
||||||
const srad = tool.shaftDiameter() / 2;
|
const srad = tool.shaftDiameter() / 2;
|
||||||
|
|
|
||||||
|
|
@ -246,7 +246,7 @@ const opDel = (rec) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
export function opRender() {
|
export function opRender() {
|
||||||
let oplist = env.current.process.ops;
|
let oplist = env.current?.process?.ops;
|
||||||
if (!(env.isCamMode && oplist)) {
|
if (!(env.isCamMode && oplist)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||||
|
|
||||||
import { broker } from '../../moto/broker.js';
|
|
||||||
import { codec } from '../../kiri/codec.js';
|
import { codec } from '../../kiri/codec.js';
|
||||||
import { newPoint } from '../../geo/point.js';
|
import { newPoint } from '../../geo/point.js';
|
||||||
import { newPolygon } from '../../geo/polygon.js';
|
import { newPolygon } from '../../geo/polygon.js';
|
||||||
|
|
@ -422,7 +421,7 @@ class Topo {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class Probe {
|
export class Probe {
|
||||||
|
|
||||||
constructor(params) {
|
constructor(params) {
|
||||||
|
|
||||||
|
|
@ -478,7 +477,7 @@ class Probe {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class Trace {
|
export class Trace {
|
||||||
|
|
||||||
constructor(probe, params) {
|
constructor(probe, params) {
|
||||||
|
|
||||||
|
|
@ -584,7 +583,7 @@ class Trace {
|
||||||
|
|
||||||
init(params) {
|
init(params) {
|
||||||
this.cross = params;
|
this.cross = params;
|
||||||
const { minions } = self.kiri_worker;
|
const { minions } = self.kiri_worker ?? {};
|
||||||
const { clipTab, clipTabZ } = params;
|
const { clipTab, clipTabZ } = params;
|
||||||
|
|
||||||
// because codec does not encode arbitrary fields
|
// because codec does not encode arbitrary fields
|
||||||
|
|
@ -720,7 +719,7 @@ class Trace {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function raster_slice(inputs) {
|
export 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;
|
||||||
|
|
@ -811,74 +810,6 @@ function raster_slice(inputs) {
|
||||||
return points;
|
return points;
|
||||||
};
|
};
|
||||||
|
|
||||||
broker.subscribe("minion.started", msg => {
|
|
||||||
const { funcs, cache, reply, log } = msg;
|
|
||||||
|
|
||||||
funcs.topo_raster = (data, seq) => {
|
|
||||||
const { id, slice, params } = data;
|
|
||||||
const { resolution } = params;
|
|
||||||
const vertices = cache[id];
|
|
||||||
const box = new THREE.Box2();
|
|
||||||
new topo_slicer(slice.index)
|
|
||||||
.setFromArray(vertices, slice)
|
|
||||||
.slice(resolution)
|
|
||||||
.forEach(rec => {
|
|
||||||
const { z, index, lines } = rec;
|
|
||||||
|
|
||||||
for (let line of lines) {
|
|
||||||
const { p1, p2 } = line;
|
|
||||||
if (!p1.swapped) { p1.swapXZ(); p1.swapped = true }
|
|
||||||
if (!p2.swapped) { p2.swapXZ(); p2.swapped = true }
|
|
||||||
}
|
|
||||||
|
|
||||||
raster_slice({
|
|
||||||
...params,
|
|
||||||
box,
|
|
||||||
lines,
|
|
||||||
gridx: index
|
|
||||||
});
|
|
||||||
});
|
|
||||||
// only pass back bounds of rasters to be merged
|
|
||||||
reply({ seq, box });
|
|
||||||
};
|
|
||||||
|
|
||||||
funcs.trace_init = data => {
|
|
||||||
const { cache } = self;
|
|
||||||
data.cross.clipTo = codec.decode(data.cross.clipTo);
|
|
||||||
data.cross.clipTab = codec.decode(data.cross.clipTab);
|
|
||||||
const probe = new Probe(data.probe);
|
|
||||||
const trace = new Trace(probe, data.trace);
|
|
||||||
cache.trace = {
|
|
||||||
probe,
|
|
||||||
trace,
|
|
||||||
cross: data.cross
|
|
||||||
};
|
|
||||||
trace.init(data.cross);
|
|
||||||
};
|
|
||||||
|
|
||||||
funcs.trace_y = (data, seq) => {
|
|
||||||
const { cache } = self;
|
|
||||||
const { trace } = cache.trace;
|
|
||||||
trace.crossY_sync(data.params, slice => {
|
|
||||||
slice = codec.encode(slice);
|
|
||||||
reply({ seq, slice });
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
funcs.trace_x = (data, seq) => {
|
|
||||||
const { cache } = self;
|
|
||||||
const { trace } = cache.trace;
|
|
||||||
trace.crossX_sync(data.params, slice => {
|
|
||||||
slice = codec.encode(slice);
|
|
||||||
reply({ seq, slice });
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
funcs.trace_cleanup = () => {
|
|
||||||
delete cache.trace;
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
export async function generate(opt) {
|
export async function generate(opt) {
|
||||||
return new Topo().generate(opt);
|
return new Topo().generate(opt);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,12 @@
|
||||||
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||||
|
|
||||||
import { base } from '../geo/base.js';
|
import { codec } from '../../kiri/codec.js';
|
||||||
import { line } from '../geo/line.js';
|
import { newPoint } from '../../geo/point.js';
|
||||||
import { point } from '../geo/point.js';
|
import { newPolygon } from '../../geo/polygon.js';
|
||||||
import { polygon } from '../geo/polygon.js';
|
import { sliceConnect } from '../../geo/slicer.js';
|
||||||
import { polygons } from '../geo/polygons.js';
|
import { Tool } from './tool.js';
|
||||||
import { broker } from '../moto/broker.js';
|
import { Slicer as topo_slicer } from './slicer2.js';
|
||||||
import { slice } from '../kiri/slice.js';
|
|
||||||
import { driver } from '../kiri-mode/cam/driver.js';
|
|
||||||
import { slicer2 } from '../kiri-mode/cam/slicer2.js';
|
|
||||||
|
|
||||||
const { base, kiri, moto } = root;
|
|
||||||
const { driver, newSlice } = kiri;
|
|
||||||
const { CAM } = driver;
|
|
||||||
const { polygons, newPoint, newPolygon, sliceConnect } = base;
|
|
||||||
|
|
||||||
const PRO = CAM.process;
|
|
||||||
const POLY = polygons;
|
|
||||||
const RAD2DEG = 180 / Math.PI;
|
const RAD2DEG = 180 / Math.PI;
|
||||||
const DEG2RAD = Math.PI / 180;
|
const DEG2RAD = Math.PI / 180;
|
||||||
|
|
||||||
|
|
@ -35,7 +25,7 @@ class Topo4 {
|
||||||
let { controller, process } = settings;
|
let { controller, process } = settings;
|
||||||
|
|
||||||
let axis = op.axis.toLowerCase(),
|
let axis = op.axis.toLowerCase(),
|
||||||
tool = new CAM.Tool(settings, op.tool),
|
tool = new Tool(settings, op.tool),
|
||||||
bounds = widget.getBoundingBox().clone(),
|
bounds = widget.getBoundingBox().clone(),
|
||||||
density = parseInt(controller.animesh || 100) * 2500,
|
density = parseInt(controller.animesh || 100) * 2500,
|
||||||
{ min, max } = bounds,
|
{ min, max } = bounds,
|
||||||
|
|
@ -151,16 +141,15 @@ class Topo4 {
|
||||||
|
|
||||||
async sliceWorker(onupdate) {
|
async sliceWorker(onupdate) {
|
||||||
const { vertices, slices, resolution } = this;
|
const { vertices, slices, resolution } = this;
|
||||||
const { codec } = kiri;
|
|
||||||
|
|
||||||
let output = [];
|
let output = [];
|
||||||
let complete = 0;
|
let complete = 0;
|
||||||
for (let slice of slices) {
|
for (let slice of slices) {
|
||||||
const recs = new kiri.topo_slicer(slice.index)
|
const recs = new 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 = newSlice(rec.z);
|
||||||
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 }
|
||||||
|
|
@ -184,7 +173,6 @@ class Topo4 {
|
||||||
}
|
}
|
||||||
|
|
||||||
async sliceMinions(onupdate) {
|
async sliceMinions(onupdate) {
|
||||||
const { codec } = kiri;
|
|
||||||
const { queue, putCache, clearCache } = this;
|
const { queue, putCache, clearCache } = this;
|
||||||
const { vertices, slices, resolution } = this;
|
const { vertices, slices, resolution } = this;
|
||||||
putCache("vertices", vertices);
|
putCache("vertices", vertices);
|
||||||
|
|
@ -474,61 +462,6 @@ function rotatePoints(lines, rot) {
|
||||||
new THREE.BufferAttribute(lines, 3).applyMatrix4(rot);
|
new THREE.BufferAttribute(lines, 3).applyMatrix4(rot);
|
||||||
}
|
}
|
||||||
|
|
||||||
CAM.Topo4 = function(opt) {
|
export function Topo4(opt) {
|
||||||
return new Topo4().generate(opt);
|
return new Topo4().generate(opt);
|
||||||
};
|
};
|
||||||
|
|
||||||
moto.broker.subscribe("minion.started", msg => {
|
|
||||||
const { funcs, cache, reply, log } = msg;
|
|
||||||
const { codec } = kiri;
|
|
||||||
|
|
||||||
funcs.topo4_slice = (data, seq) => {
|
|
||||||
const { slice, resolution } = data;
|
|
||||||
const vertices = cache.vertices;
|
|
||||||
const recs = new kiri.topo_slicer(slice.index)
|
|
||||||
.setFromArray(vertices, slice)
|
|
||||||
.slice(resolution)
|
|
||||||
.map(rec => {
|
|
||||||
const { z, index, lines } = rec;
|
|
||||||
|
|
||||||
for (let line of lines) {
|
|
||||||
const { p1, p2 } = line;
|
|
||||||
if (!p1.swapped) { p1.swapXZ(); p1.swapped = true }
|
|
||||||
if (!p2.swapped) { p2.swapXZ(); p2.swapped = true }
|
|
||||||
}
|
|
||||||
|
|
||||||
const points = codec.encodePointArray(lines.map(l => [ l.p1, l.p2 ]).flat());
|
|
||||||
const shared = new Float32Array(new SharedArrayBuffer(points.length * 4));
|
|
||||||
shared.set(points);
|
|
||||||
|
|
||||||
return {
|
|
||||||
z, index, shared,
|
|
||||||
polys: codec.encode(sliceConnect(lines)),
|
|
||||||
};
|
|
||||||
});
|
|
||||||
// only pass back bounds of rasters to be merged
|
|
||||||
reply({ seq, recs });
|
|
||||||
};
|
|
||||||
|
|
||||||
funcs.topo4_lathe = (data, seq) => {
|
|
||||||
const { angle } = data;
|
|
||||||
const { slices, tool } = cache.lathe;
|
|
||||||
|
|
||||||
const axis = new THREE.Vector3(1, 0, 0);
|
|
||||||
const mrot = new THREE.Matrix4().makeRotationAxis(axis, -angle);
|
|
||||||
const stmp = slices.map(s => {
|
|
||||||
const lines = s.lines.slice();
|
|
||||||
rotatePoints(lines, mrot);
|
|
||||||
return { z: s.z, lines }
|
|
||||||
});
|
|
||||||
|
|
||||||
const topo4 = Object.assign(new Topo4(), cache.lathe);
|
|
||||||
const heights = topo4.lathePath(stmp, tool);
|
|
||||||
|
|
||||||
reply({ seq, heights });
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
export { scale, rotatePoints, PRO, POLY, RAD2DEG, DEG2RAD, axis, range, slices, lathe, box, i, x, z, shards, step, index, slice, output, complete, recs, points, shared, promises, tlen, slen, sinc, heights, oslices, lines, plen, rec, py0, pz0, py1, pz1, lz, si, rx, mz, ti, xo, yo, zo, ts, dz, dy, fr, rota, steps, mrot, paths, angle, count, poly, repeat, done, tangle, p, linear, vertices, stmp, topo4, Topo4 };
|
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,8 @@ import { newPoint } from '../geo/point.js';
|
||||||
import { polygons as POLY } from '../geo/polygons.js';
|
import { polygons as POLY } from '../geo/polygons.js';
|
||||||
import { sliceZ } from '../geo/slicer.js';
|
import { sliceZ } from '../geo/slicer.js';
|
||||||
import { Slicer as cam_slicer } from '../kiri-mode/cam/slicer.js';
|
import { Slicer as cam_slicer } from '../kiri-mode/cam/slicer.js';
|
||||||
|
import { Slicer as topo_slicer } from '../kiri-mode/cam/slicer2.js';
|
||||||
|
import { Probe, Trace, raster_slice } from '../kiri-mode/cam/topo3.js';
|
||||||
import { wasm_ctrl } from '../geo/wasm.js';
|
import { wasm_ctrl } from '../geo/wasm.js';
|
||||||
|
|
||||||
const clib = self.ClipperLib;
|
const clib = self.ClipperLib;
|
||||||
|
|
@ -175,6 +177,8 @@ const funcs = self.minion = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// CAM slice support
|
||||||
|
|
||||||
cam_slice_init() {
|
cam_slice_init() {
|
||||||
cache.slicer = new cam_slicer();
|
cache.slicer = new cam_slicer();
|
||||||
},
|
},
|
||||||
|
|
@ -198,4 +202,115 @@ const funcs = self.minion = {
|
||||||
reply({ seq, slices: data });
|
reply({ seq, slices: data });
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// CAM Topo3 support
|
||||||
|
|
||||||
|
topo_raster(data, seq) {
|
||||||
|
const { id, slice, params } = data;
|
||||||
|
const { resolution } = params;
|
||||||
|
const vertices = cache[id];
|
||||||
|
const box = new THREE.Box2();
|
||||||
|
new topo_slicer(slice.index)
|
||||||
|
.setFromArray(vertices, slice)
|
||||||
|
.slice(resolution)
|
||||||
|
.forEach(rec => {
|
||||||
|
const { z, index, lines } = rec;
|
||||||
|
|
||||||
|
for (let line of lines) {
|
||||||
|
const { p1, p2 } = line;
|
||||||
|
if (!p1.swapped) { p1.swapXZ(); p1.swapped = true }
|
||||||
|
if (!p2.swapped) { p2.swapXZ(); p2.swapped = true }
|
||||||
|
}
|
||||||
|
|
||||||
|
raster_slice({
|
||||||
|
...params,
|
||||||
|
box,
|
||||||
|
lines,
|
||||||
|
gridx: index
|
||||||
|
});
|
||||||
|
});
|
||||||
|
// only pass back bounds of rasters to be merged
|
||||||
|
reply({ seq, box });
|
||||||
|
},
|
||||||
|
|
||||||
|
trace_init(data) {
|
||||||
|
data.cross.clipTo = codec.decode(data.cross.clipTo);
|
||||||
|
data.cross.clipTab = codec.decode(data.cross.clipTab);
|
||||||
|
const probe = new Probe(data.probe);
|
||||||
|
const trace = new Trace(probe, data.trace);
|
||||||
|
cache.trace = {
|
||||||
|
probe,
|
||||||
|
trace,
|
||||||
|
cross: data.cross
|
||||||
|
};
|
||||||
|
trace.init(data.cross);
|
||||||
|
},
|
||||||
|
|
||||||
|
trace_y(data, seq) {
|
||||||
|
const { trace } = cache.trace;
|
||||||
|
trace.crossY_sync(data.params, slice => {
|
||||||
|
slice = codec.encode(slice);
|
||||||
|
reply({ seq, slice });
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
trace_x(data, seq) {
|
||||||
|
const { trace } = cache.trace;
|
||||||
|
trace.crossX_sync(data.params, slice => {
|
||||||
|
slice = codec.encode(slice);
|
||||||
|
reply({ seq, slice });
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
trace_cleanup() {
|
||||||
|
delete cache.trace;
|
||||||
|
},
|
||||||
|
|
||||||
|
// CAM Topo4 support
|
||||||
|
|
||||||
|
topo4_slice(data, seq) {
|
||||||
|
const { slice, resolution } = data;
|
||||||
|
const vertices = cache.vertices;
|
||||||
|
const recs = new kiri.topo_slicer(slice.index)
|
||||||
|
.setFromArray(vertices, slice)
|
||||||
|
.slice(resolution)
|
||||||
|
.map(rec => {
|
||||||
|
const { z, index, lines } = rec;
|
||||||
|
|
||||||
|
for (let line of lines) {
|
||||||
|
const { p1, p2 } = line;
|
||||||
|
if (!p1.swapped) { p1.swapXZ(); p1.swapped = true }
|
||||||
|
if (!p2.swapped) { p2.swapXZ(); p2.swapped = true }
|
||||||
|
}
|
||||||
|
|
||||||
|
const points = codec.encodePointArray(lines.map(l => [ l.p1, l.p2 ]).flat());
|
||||||
|
const shared = new Float32Array(new SharedArrayBuffer(points.length * 4));
|
||||||
|
shared.set(points);
|
||||||
|
|
||||||
|
return {
|
||||||
|
z, index, shared,
|
||||||
|
polys: codec.encode(sliceConnect(lines)),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
// only pass back bounds of rasters to be merged
|
||||||
|
reply({ seq, recs });
|
||||||
|
},
|
||||||
|
|
||||||
|
topo4_lathe(data, seq) {
|
||||||
|
const { angle } = data;
|
||||||
|
const { slices, tool } = cache.lathe;
|
||||||
|
|
||||||
|
const axis = new THREE.Vector3(1, 0, 0);
|
||||||
|
const mrot = new THREE.Matrix4().makeRotationAxis(axis, -angle);
|
||||||
|
const stmp = slices.map(s => {
|
||||||
|
const lines = s.lines.slice();
|
||||||
|
rotatePoints(lines, mrot);
|
||||||
|
return { z: s.z, lines }
|
||||||
|
});
|
||||||
|
|
||||||
|
const topo4 = Object.assign(new Topo4(), cache.lathe);
|
||||||
|
const heights = topo4.lathePath(stmp, tool);
|
||||||
|
|
||||||
|
reply({ seq, heights });
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue