diff --git a/src/add/array.js b/src/add/array.js index cd4d6c42..7c6324cf 100644 --- a/src/add/array.js +++ b/src/add/array.js @@ -8,7 +8,7 @@ if (!AP.flat) { try { return [].concat.apply([], this); } catch (e) { - // console.log({flat_error: e}); + // console.log({ flat_error: e, array: this }); let out = []; for (let e of this.slice()) { out.push(...e); diff --git a/src/kiri-mode/cam/anim-2d-be.js b/src/kiri-mode/cam/anim-2d-be.js index f63baaf2..720c74b0 100644 --- a/src/kiri-mode/cam/anim-2d-be.js +++ b/src/kiri-mode/cam/anim-2d-be.js @@ -27,7 +27,7 @@ export function init(worker) { // destructure arcs into path points 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(); const step = rez; diff --git a/src/kiri-mode/cam/anim-3d-be.js b/src/kiri-mode/cam/anim-3d-be.js index 92ad730c..c9e83282 100644 --- a/src/kiri-mode/cam/anim-3d-be.js +++ b/src/kiri-mode/cam/anim-3d-be.js @@ -3,6 +3,7 @@ // WORKER BACK END ANIMATION CODE for 3D (indexed) import { CSG } from '../../geo/csg.js'; +import { Tool } from './tool.js'; let nextMeshID = 1; let stock, center, rez; @@ -269,7 +270,7 @@ function toolUpdate(toolid, send) { if (tool) { send.data({ mesh_del: toolID }); } - tool = new CAM.Tool({ tools }, toolid); + tool = new Tool({ tools }, toolid); const Instance = CSG.Instance(); const slen = tool.shaftLength() || 15; const srad = tool.shaftDiameter() / 2; diff --git a/src/kiri-mode/cam/client.js b/src/kiri-mode/cam/client.js index e1e4c6b7..9b08a288 100644 --- a/src/kiri-mode/cam/client.js +++ b/src/kiri-mode/cam/client.js @@ -246,7 +246,7 @@ const opDel = (rec) => { }; export function opRender() { - let oplist = env.current.process.ops; + let oplist = env.current?.process?.ops; if (!(env.isCamMode && oplist)) { return; } diff --git a/src/kiri-mode/cam/topo3.js b/src/kiri-mode/cam/topo3.js index 49b46a9d..0db88414 100644 --- a/src/kiri-mode/cam/topo3.js +++ b/src/kiri-mode/cam/topo3.js @@ -1,6 +1,5 @@ /** Copyright Stewart Allen -- All Rights Reserved */ -import { broker } from '../../moto/broker.js'; import { codec } from '../../kiri/codec.js'; import { newPoint } from '../../geo/point.js'; import { newPolygon } from '../../geo/polygon.js'; @@ -422,7 +421,7 @@ class Topo { } -class Probe { +export class Probe { constructor(params) { @@ -478,7 +477,7 @@ class Probe { } -class Trace { +export class Trace { constructor(probe, params) { @@ -584,7 +583,7 @@ class Trace { init(params) { this.cross = params; - const { minions } = self.kiri_worker; + const { minions } = self.kiri_worker ?? {}; const { clipTab, clipTabZ } = params; // 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 { flatness, zMin, minY, maxY, stepsY, gridx } = inputs; const { slice } = inputs; @@ -811,74 +810,6 @@ function raster_slice(inputs) { 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) { return new Topo().generate(opt); } diff --git a/src/kiri-mode/cam/topo4.js b/src/kiri-mode/cam/topo4.js index fc4807b0..8a345afe 100644 --- a/src/kiri-mode/cam/topo4.js +++ b/src/kiri-mode/cam/topo4.js @@ -1,22 +1,12 @@ /** Copyright Stewart Allen -- All Rights Reserved */ -import { base } from '../geo/base.js'; -import { line } from '../geo/line.js'; -import { point } from '../geo/point.js'; -import { polygon } from '../geo/polygon.js'; -import { polygons } from '../geo/polygons.js'; -import { broker } from '../moto/broker.js'; -import { slice } from '../kiri/slice.js'; -import { driver } from '../kiri-mode/cam/driver.js'; -import { slicer2 } from '../kiri-mode/cam/slicer2.js'; +import { codec } from '../../kiri/codec.js'; +import { newPoint } from '../../geo/point.js'; +import { newPolygon } from '../../geo/polygon.js'; +import { sliceConnect } from '../../geo/slicer.js'; +import { Tool } from './tool.js'; +import { Slicer as topo_slicer } from './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 DEG2RAD = Math.PI / 180; @@ -35,7 +25,7 @@ class Topo4 { let { controller, process } = settings; let axis = op.axis.toLowerCase(), - tool = new CAM.Tool(settings, op.tool), + tool = new Tool(settings, op.tool), bounds = widget.getBoundingBox().clone(), density = parseInt(controller.animesh || 100) * 2500, { min, max } = bounds, @@ -151,16 +141,15 @@ class Topo4 { async sliceWorker(onupdate) { const { vertices, slices, resolution } = this; - const { codec } = kiri; let output = []; let complete = 0; for (let slice of slices) { - const recs = new kiri.topo_slicer(slice.index) + const recs = new topo_slicer(slice.index) .setFromArray(vertices, slice) .slice(resolution) .map(rec => { - const slice = kiri.newSlice(rec.z); + const slice = newSlice(rec.z); for (let line of rec.lines) { const { p1, p2 } = line; if (!p1.swapped) { p1.swapXZ(); p1.swapped = true } @@ -184,7 +173,6 @@ class Topo4 { } async sliceMinions(onupdate) { - const { codec } = kiri; const { queue, putCache, clearCache } = this; const { vertices, slices, resolution } = this; putCache("vertices", vertices); @@ -474,61 +462,6 @@ function rotatePoints(lines, rot) { new THREE.BufferAttribute(lines, 3).applyMatrix4(rot); } -CAM.Topo4 = function(opt) { +export function Topo4(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 }; diff --git a/src/kiri-run/minion.js b/src/kiri-run/minion.js index fb183798..e6ac8ade 100644 --- a/src/kiri-run/minion.js +++ b/src/kiri-run/minion.js @@ -13,6 +13,8 @@ import { newPoint } from '../geo/point.js'; import { polygons as POLY } from '../geo/polygons.js'; import { sliceZ } from '../geo/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'; const clib = self.ClipperLib; @@ -175,6 +177,8 @@ const funcs = self.minion = { } }, + // CAM slice support + cam_slice_init() { cache.slicer = new cam_slicer(); }, @@ -198,4 +202,115 @@ const funcs = self.minion = { 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 }); + } };