checkpoint prototype
This commit is contained in:
parent
2f755459ff
commit
849a55439b
12 changed files with 169 additions and 50 deletions
|
|
@ -227,6 +227,12 @@ for (let i in AP) {
|
|||
});
|
||||
}
|
||||
|
||||
Float32Array.prototype.toShared = function() {
|
||||
const newvert = new Float32Array(new SharedArrayBuffer(this.buffer.byteLength));
|
||||
newvert.set(this);
|
||||
return newvert;
|
||||
};
|
||||
|
||||
String.prototype.reverse = function() {
|
||||
return this.split('').reverse().join('');
|
||||
};
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ kiri.load(api => {
|
|||
if (!widget.tool) {
|
||||
let tool = widget.tool = new mesh.tool();
|
||||
let translate = index ? true : false;
|
||||
tool.index(widget.getGeoVertices(true, translate));
|
||||
tool.index(widget.getGeoVertices({ unroll: true, translate }));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1136,7 +1136,7 @@ class OpPocket extends CamOp {
|
|||
}
|
||||
}
|
||||
let surfaces = op.surfaces[widget.id] || [];
|
||||
let vert = widget.getGeoVertices(true,true).map(v => v.round(4));
|
||||
let vert = widget.getGeoVertices({ unroll: true, translate: true }).map(v => v.round(4));
|
||||
// let vert = widget.getVertices().array.map(v => v.round(4));
|
||||
let outline = [];
|
||||
let faces = CAM.surface_find(widget, surfaces);
|
||||
|
|
|
|||
|
|
@ -245,7 +245,7 @@ CAM.slice = async function(settings, widget, onupdate, ondone) {
|
|||
tracker.rotation = isIndexed ? axisRotation : 0;
|
||||
// setup new state when indexing the workspace
|
||||
if (true && op.op.type === "index") {
|
||||
let points = base.verticesToPoints(widget.getGeoVertices(true, true));
|
||||
let points = base.verticesToPoints(widget.getGeoVertices({ unroll: true, translate: true }));
|
||||
state.slicer = new kiri.cam_slicer(points, {
|
||||
zlist: true,
|
||||
zline: true
|
||||
|
|
|
|||
|
|
@ -3,8 +3,10 @@
|
|||
"use strict";
|
||||
|
||||
/**
|
||||
* Slicing engine used by CAM
|
||||
* Slicing engine used by CAM Topo
|
||||
*/
|
||||
|
||||
// dep: moto.broker
|
||||
// dep: kiri.slice
|
||||
gapp.register("kiri-mode.cam.slicer2", [], (root, exports) => {
|
||||
|
||||
|
|
@ -13,6 +15,10 @@ const { config, newOrderedLine, newPoint } = base;
|
|||
|
||||
class Slicer {
|
||||
|
||||
static intersectPoints = intersectPoints;
|
||||
static checkOverUnderOn = checkOverUnderOn;
|
||||
static removeDuplicateLines = removeDuplicateLines;
|
||||
|
||||
constructor() {
|
||||
this.min = Infinity;
|
||||
this.max = -Infinity;
|
||||
|
|
@ -80,13 +86,13 @@ class Slicer {
|
|||
const zMax = this.max;
|
||||
const phash = {};
|
||||
const lines = [];
|
||||
|
||||
|
||||
let { under, over, both } = options;
|
||||
let p1, p2, p3;
|
||||
|
||||
|
||||
// default to 'over' selection with 2 points on a line
|
||||
if (!under && !both) over = true;
|
||||
|
||||
|
||||
// iterate over matching buckets for this z offset
|
||||
for (let i = 0; i < points.length; ) {
|
||||
p1 = points[i++];
|
||||
|
|
@ -127,11 +133,11 @@ class Slicer {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (lines.length == 0 && options.noEmpty) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
return removeDuplicateLines(lines);
|
||||
}
|
||||
|
||||
|
|
@ -311,9 +317,56 @@ function removeDuplicateLines(lines, debug) {
|
|||
return output;
|
||||
}
|
||||
|
||||
Slicer.checkOverUnderOn = checkOverUnderOn;
|
||||
Slicer.intersectPoints = intersectPoints;
|
||||
moto.broker.subscribe("worker.started", msg => {
|
||||
const { dispatch, minions } = msg;
|
||||
// console.log({ cam_slicer2_worker: dispatch });
|
||||
kiri.topo_slice = async (widget, resolution) => {
|
||||
console.log({ topo_slice: widget, resolution });
|
||||
const vertices = widget.getGeoVertices().toShared();
|
||||
const range = { min: Infinity, max: -Infinity };
|
||||
for (let i=0,l=vertices.length; i<l; i += 3) {
|
||||
const x = vertices[i];
|
||||
const z = vertices[i + 2];
|
||||
vertices[i] = z;
|
||||
vertices[i + 2] = x;
|
||||
range.min = Math.min(range.min, x);
|
||||
range.max = Math.max(range.max, x);
|
||||
}
|
||||
// define sharded ranges
|
||||
if (false && minions.concurrent) {
|
||||
dispatch.putCache({ key: widget.id, data: vertices }, { done: data => {
|
||||
console.log({ put_cache_done: data });
|
||||
}});
|
||||
|
||||
kiri.cam_slicer2 = Slicer;
|
||||
dispatch.clearCache({}, { done: data => {
|
||||
console.log({ clear_cache_done: data });
|
||||
}});
|
||||
return [];
|
||||
} else {
|
||||
console.time('nuslice');
|
||||
// iterate over shards, merge output
|
||||
const output = new Slicer()
|
||||
.setFromArray(vertices)
|
||||
.slice(resolution)
|
||||
.map(rec => {
|
||||
const slice = kiri.newSlice(rec.z);
|
||||
slice.lines = rec.lines;
|
||||
for (let line of rec.lines) {
|
||||
const { p1, p2 } = line;
|
||||
if (!p1.swapped) { p1.swapXZ(); p1.swapped = true }
|
||||
if (!p2.swapped) { p2.swapXZ(); p2.swapped = true }
|
||||
}
|
||||
return slice;
|
||||
});
|
||||
console.log({ output });
|
||||
console.timeEnd('nuslice');
|
||||
return output;
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
moto.broker.subscribe("minion.started", funcs => {
|
||||
// console.log({ cam_slicer2_minion: funcs });
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
|||
|
|
@ -439,7 +439,16 @@ class Topo {
|
|||
ondone(newslices);
|
||||
}
|
||||
|
||||
let points = base.verticesToPoints(widget.getGeoVertices(true, true));
|
||||
console.log('get vertices and points');
|
||||
let points = base.verticesToPoints(widget.getGeoVertices({ unroll: true, translate: true }));
|
||||
|
||||
console.log('topo slice 2');
|
||||
const slices2 = await kiri.topo_slice(widget, resolution);
|
||||
console.log({ topo_slice_done: slices2 });
|
||||
processSlices(slices2);
|
||||
return this;
|
||||
|
||||
console.log('old slice setup')
|
||||
let slicer = new kiri.cam_slicer(points, {
|
||||
swapX: true, emptyok: true, notopok: true
|
||||
});
|
||||
|
|
@ -448,12 +457,15 @@ class Topo {
|
|||
if (contourX) stepsTotal += Math.round((maxY-minY) / toolStep);
|
||||
if (contourY) stepsTotal += Math.round((maxX-minX) / toolStep);
|
||||
|
||||
console.log('old slice run', stepsTotal)
|
||||
let slices = topo.slices = topo.slices || slicer.slice(sindex, { each: (data, index, total) => {
|
||||
onupdate(++stepsTaken, stepsTotal, "topo slice");
|
||||
}, genso: true });
|
||||
|
||||
console.log('process slices', stepsTaken)
|
||||
processSlices(slices.filter(s => s.lines).map(data => data.slice));
|
||||
|
||||
console.log('process done', stepsTaken)
|
||||
// const t0 = Date.now();
|
||||
// for (let point of points) point.swapXZ();
|
||||
// let lines = new kiri.cam_slicer2().setFromPoints(points).slice(resolution);
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
"use strict";
|
||||
|
||||
// dep: moto.license
|
||||
// dep: moto.broker
|
||||
// dep: geo.base
|
||||
// dep: geo.polygons
|
||||
// dep: geo.slicer
|
||||
|
|
@ -10,6 +11,7 @@
|
|||
// dep: kiri.codec
|
||||
// dep: kiri-mode.fdm.post
|
||||
// use: kiri-mode.cam.slicer
|
||||
// dep: kiri-mode.cam.slicer2
|
||||
// dep: ext.clip2
|
||||
gapp.register("kiri-run.minion", [], (root, exports) => {
|
||||
|
||||
|
|
@ -22,8 +24,8 @@ const clib = self.ClipperLib;
|
|||
const ctyp = clib.ClipType;
|
||||
const ptyp = clib.PolyType;
|
||||
const cfil = clib.PolyFillType;
|
||||
const cache = self.cache = {};
|
||||
|
||||
let cache = self.cache = {};
|
||||
let name = "unknown";
|
||||
|
||||
// catch clipper alerts and convert to console messages
|
||||
|
|
@ -45,7 +47,7 @@ function log() {
|
|||
console.log(`[${name}]`, ...arguments);
|
||||
}
|
||||
|
||||
const funcs = {
|
||||
const funcs = self.minion = {
|
||||
label(data, seq) {
|
||||
name = data.name;
|
||||
},
|
||||
|
|
@ -138,19 +140,20 @@ const funcs = {
|
|||
});
|
||||
},
|
||||
|
||||
camSetPoints: data => {
|
||||
const points = new Float32Array(data.data);
|
||||
let i = 0, p = 0, realp = new Array(points.length / 3);
|
||||
while (i < points.length) {
|
||||
realp[p++] = base.newPoint(points[i++], points[i++], points[i++]).round(3);
|
||||
putCache: msg => {
|
||||
const { key, data } = msg;
|
||||
log({ minion_putCache: key, data });
|
||||
if (data) {
|
||||
console.log({ minion_put_cache: key, data });
|
||||
cache[key] = data;
|
||||
} else {
|
||||
console.log({ minion_del_cache: key });
|
||||
delete cache[key];
|
||||
}
|
||||
// log({ camSetPoints: points, realp });
|
||||
cache.camPoints = realp;
|
||||
},
|
||||
|
||||
camClearPoints: data => {
|
||||
// log({ camClearPoints: data });
|
||||
delete cache.camPoints;
|
||||
clearCache: msg => {
|
||||
cache = self.cache = [];
|
||||
},
|
||||
|
||||
wasm: data => {
|
||||
|
|
@ -166,4 +169,6 @@ const funcs = {
|
|||
}
|
||||
};
|
||||
|
||||
moto.broker.publish("minion.started", funcs);
|
||||
|
||||
});
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
// dep: kiri.codec
|
||||
// dep: kiri.slice
|
||||
// dep: moto.license
|
||||
// dep: moto.broker
|
||||
// use: load.png
|
||||
// use: ext.jszip
|
||||
// use: kiri.render
|
||||
|
|
@ -230,19 +231,10 @@ kiri.minions = {
|
|||
}
|
||||
},
|
||||
|
||||
wasm(enable) {
|
||||
for (let minion of minions) {
|
||||
minion.postMessage({
|
||||
cmd: "wasm",
|
||||
enable
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
broadcast(cmd, data, direct) {
|
||||
for (let minion of minions) {
|
||||
minion.postMessage({
|
||||
cmd, data
|
||||
cmd, ...data
|
||||
}, direct);
|
||||
}
|
||||
}
|
||||
|
|
@ -252,6 +244,7 @@ console.log(`kiri | init work | ${gapp.version || "rogue"}`);
|
|||
|
||||
// code is running in the worker / server context
|
||||
const dispatch =
|
||||
self.worker =
|
||||
kiri.server =
|
||||
kiri.worker = {
|
||||
pool_start(data, send) {
|
||||
|
|
@ -326,8 +319,11 @@ kiri.worker = {
|
|||
group.id = data.group;
|
||||
wgroup[data.group] = group;
|
||||
}
|
||||
let vertices = new Float32Array(data.vertices),
|
||||
widget = kiri.newWidget(data.id, group).loadVertices(vertices).setInWorker();
|
||||
|
||||
let vertices = data.vertices,
|
||||
widget = kiri.newWidget(data.id, group)
|
||||
.setInWorker()
|
||||
.loadVertices(vertices);
|
||||
|
||||
// do it here so cancel can work
|
||||
wcache[data.id] = widget;
|
||||
|
|
@ -623,8 +619,26 @@ kiri.worker = {
|
|||
} else {
|
||||
wasm_ctrl.disable();
|
||||
}
|
||||
minwork.wasm(data.enable);
|
||||
minwork.broadcast("wasm", { enable: data.enable ? true : false });
|
||||
send.done({ wasm: data });
|
||||
},
|
||||
|
||||
putCache(msg, send) {
|
||||
const { key, data } = msg;
|
||||
console.log({ worker_putCache: key, data });
|
||||
if (data) {
|
||||
pcache[key] = data;
|
||||
} else {
|
||||
delete pcache[key];
|
||||
}
|
||||
minwork.broadcast("putCache", msg);
|
||||
send.done({ ok: true });
|
||||
},
|
||||
|
||||
clearCache(msg, send) {
|
||||
pcache = {};
|
||||
minwork.broadcast("clearCache", msg);
|
||||
send.done({ ok: true });
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -686,6 +700,8 @@ dispatch.onmessage = self.onmessage = function(e) {
|
|||
}
|
||||
};
|
||||
|
||||
moto.broker.publish("worker.started", { dispatch, minions: minwork });
|
||||
|
||||
});
|
||||
|
||||
// load kiri modules
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ let loc = self.location,
|
|||
syncd = {},
|
||||
running = {},
|
||||
worker = null,
|
||||
minions = false,
|
||||
restarting = false
|
||||
// occ = new Worker("/kiri/ext/occ-worker.js", {type:"module"}),
|
||||
;
|
||||
|
|
@ -56,10 +57,12 @@ const client = exports({
|
|||
|
||||
pool: {
|
||||
start() {
|
||||
minions = true;
|
||||
send("pool_start", {}, noop);
|
||||
},
|
||||
|
||||
stop() {
|
||||
minions = false;
|
||||
send("pool_stop", {}, noop);
|
||||
}
|
||||
},
|
||||
|
|
@ -126,6 +129,11 @@ const client = exports({
|
|||
}
|
||||
};
|
||||
|
||||
// restart minions if they were running
|
||||
if (minions) {
|
||||
client.pool.start();
|
||||
}
|
||||
|
||||
restarting = false;
|
||||
},
|
||||
|
||||
|
|
@ -166,7 +174,7 @@ const client = exports({
|
|||
widgets.forEach(widget => {
|
||||
if (widget.modified || !syncd[widget.id]) {
|
||||
syncd[widget.id] = true;
|
||||
let vertices = widget.getGeoVertices().buffer.slice(0);
|
||||
let vertices = widget.getGeoVertices();
|
||||
send("sync", {
|
||||
id: widget.id,
|
||||
meta: widget.meta,
|
||||
|
|
@ -176,7 +184,7 @@ const client = exports({
|
|||
position: widget.mesh.position,
|
||||
}, done => {
|
||||
widget.modified = false;
|
||||
}, [vertices]);
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
|
@ -303,6 +311,19 @@ const client = exports({
|
|||
send("wasm", {enable}, reply => {
|
||||
// console.log({wasm_worker_said: reply});
|
||||
});
|
||||
},
|
||||
|
||||
putCache(key, data) {
|
||||
console.log({ putCache: key, data });
|
||||
send("putCache", {key, data}, reply => {
|
||||
// console.log({ putCache_reply: reply });
|
||||
});
|
||||
},
|
||||
|
||||
clearCache() {
|
||||
send("clearCache", {}, reply => {
|
||||
// console.log({ clearCache_reply: reply });
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -73,6 +73,8 @@ class Files {
|
|||
* @param {Function} [callback]
|
||||
*/
|
||||
putFile(name, vertices, callback) {
|
||||
console.log({ putFile: name, vertices });
|
||||
|
||||
let mark = Date.now();
|
||||
let store = this;
|
||||
let pdb = store.db.promise();
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ class Widget {
|
|||
}
|
||||
const widget = this;
|
||||
const mark = time();
|
||||
const vertices = this.getGeoVertices(true);
|
||||
const vertices = widget.getGeoVertices({ unroll: true }).slice();
|
||||
widget.meta.file = filename;
|
||||
widget.meta.save = mark;
|
||||
catalog().putFile(filename, vertices, () => {
|
||||
|
|
@ -123,8 +123,9 @@ class Widget {
|
|||
return;
|
||||
}
|
||||
const widget = this;
|
||||
console.log({ saveState: widget.id });
|
||||
index().put('ws-save-'+this.id, {
|
||||
geo: widget.getGeoVertices(false),
|
||||
geo: widget.getGeoVertices({ unroll: false }).slice(),
|
||||
track: widget.track,
|
||||
group: this.group.id,
|
||||
meta: this.meta,
|
||||
|
|
@ -152,6 +153,7 @@ class Widget {
|
|||
* @returns {Widget}
|
||||
*/
|
||||
loadVertices(data, options = { index: false }) {
|
||||
// console.log({ loadVertices: this.id, worker: this.inWorker, data });
|
||||
let vertices,
|
||||
autoscale = false;
|
||||
if (ArrayBuffer.isView(data) || typeof(data) != 'object') {
|
||||
|
|
@ -160,12 +162,12 @@ class Widget {
|
|||
vertices = data.vertices;
|
||||
throw "deprecated vertex data format";
|
||||
}
|
||||
// will not serialize into indexeddb -- need a performance sensitive workaround
|
||||
// if (window.SharedArrayBuffer) {
|
||||
// let newvert = new Float32Array(new SharedArrayBuffer(vertices.buffer.byteLength));
|
||||
// newvert.set(vertices);
|
||||
// vertices = newvert;
|
||||
// }
|
||||
if (!(vertices.buffer && vertices.buffer instanceof SharedArrayBuffer)) {
|
||||
// console.log('converting to shared vertices');
|
||||
let newvert = new Float32Array(new SharedArrayBuffer(vertices.buffer.byteLength));
|
||||
newvert.set(vertices);
|
||||
vertices = newvert;
|
||||
}
|
||||
switch (typeof(autoscale)) {
|
||||
case 'boolean':
|
||||
autoscale = options;
|
||||
|
|
@ -610,7 +612,8 @@ class Widget {
|
|||
this.points = null;
|
||||
}
|
||||
|
||||
getGeoVertices(unroll, translate) {
|
||||
getGeoVertices(opt = {}) {
|
||||
const { unroll, translate } = opt;
|
||||
let geo = this.mesh.geometry;
|
||||
let pos = geo.getAttribute('position');
|
||||
// if indexed, return points rotated about X and then offset
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ class Broker {
|
|||
for (let t of topic) {
|
||||
this.subscribe(t, listener);
|
||||
}
|
||||
return;
|
||||
return this;
|
||||
}
|
||||
if (typeof topic !== 'string') {
|
||||
console.trace({invalid_topic: topic});
|
||||
|
|
@ -57,6 +57,7 @@ class Broker {
|
|||
channel.push(listener);
|
||||
this.publish(".topic.add", topic);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
unsubscribe(topic, listener) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue