fixup cam minion slicing, api settings cross compatibility
This commit is contained in:
parent
1c2aebbb4c
commit
e10450a5ea
5 changed files with 100 additions and 97 deletions
|
|
@ -1,8 +1,7 @@
|
|||
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||
|
||||
import { base, util } from '../../geo/base.js';
|
||||
import { broker } from '../../moto/broker.js';
|
||||
import { decode, decodePointArray, encode, encodePointArray } from '../../kiri/codec.js';
|
||||
import { decode, decodePointArray } from '../../kiri/codec.js';
|
||||
import { newLine, newOrderedLine } from '../../geo/line.js';
|
||||
import { newPoint } from '../../geo/point.js';
|
||||
import { newSlice } from '../../kiri/slice.js';
|
||||
|
|
@ -23,20 +22,17 @@ const end = function () {
|
|||
|
||||
export class Slicer {
|
||||
constructor(widget, options = { zlist: true, zline: true, lines: false }) {
|
||||
this.minions = self.kiri_worker.minions;
|
||||
this.minions = self.kiri_worker?.minions;
|
||||
this.options = {};
|
||||
this.setOptions(options);
|
||||
|
||||
if (widget) {
|
||||
this.threaded = widget.settings.controller.threaded;
|
||||
this.setPoints(widget.getGeoVertices({ unroll: true, translate: true }));
|
||||
this.computeFeatures();
|
||||
}
|
||||
}
|
||||
|
||||
get threaded() {
|
||||
return this.options.threaded;
|
||||
}
|
||||
|
||||
// zList = generate list of z vertices
|
||||
// zline = generate list of z vertices with coplanar lines
|
||||
// trace = find z coplanar trace lines
|
||||
|
|
@ -480,32 +476,3 @@ function makeZLine(phash, p1, p2, coplanar, edge) {
|
|||
|
||||
Slicer.checkOverUnderOn = checkOverUnderOn;
|
||||
Slicer.intersectPoints = intersectPoints;
|
||||
|
||||
broker.subscribe("minion.started", msg => {
|
||||
const { funcs, cache, reply, log } = msg;
|
||||
|
||||
funcs.cam_slice_init = () => {
|
||||
cache.slicer = new Slicer();
|
||||
};
|
||||
|
||||
funcs.cam_slice_cleanup = () => {
|
||||
delete cache.slicer;
|
||||
};
|
||||
|
||||
funcs.cam_slice = (data, seq) => {
|
||||
const { bucket, opt } = data;
|
||||
// log({ slice: bucket, opt });
|
||||
cache.slicer.sliceBucket(bucket, opt, slice => {
|
||||
// console.log({ slice });
|
||||
}).then(data => {
|
||||
data.forEach(rec => {
|
||||
rec.polys = encode(rec.polys);
|
||||
if (rec.lines) {
|
||||
const points = rec.lines.map(l => [l.p1, l.p2]).flat();
|
||||
rec.lines = encodePointArray(points);
|
||||
}
|
||||
});
|
||||
reply({ seq, slices: data });
|
||||
});
|
||||
};
|
||||
});
|
||||
|
|
|
|||
|
|
@ -7,12 +7,12 @@ import '../add/class.js';
|
|||
import '../add/three.js';
|
||||
|
||||
import { base } from '../geo/base.js';
|
||||
import { codec, encode } from '../kiri/codec.js';
|
||||
import { doTopShells } from '../kiri-mode/fdm/post.js';
|
||||
import { newPoint } from '../geo/point.js';
|
||||
import { polygons as POLY } from '../geo/polygons.js';
|
||||
import { sliceZ } from '../geo/slicer.js';
|
||||
import { codec } from '../kiri/codec.js';
|
||||
import { broker } from '../moto/broker.js';
|
||||
import { doTopShells } from '../kiri-mode/fdm/post.js';
|
||||
import { Slicer as cam_slicer } from '../kiri-mode/cam/slicer.js';
|
||||
import { wasm_ctrl } from '../geo/wasm.js';
|
||||
|
||||
const clib = self.ClipperLib;
|
||||
|
|
@ -29,9 +29,14 @@ self.alert = function(o) {
|
|||
};
|
||||
|
||||
self.onmessage = function(msg) {
|
||||
let data = msg.data;
|
||||
let cmd = data.cmd;
|
||||
(funcs[cmd] || funcs.bad)(data, data.seq, cmd);
|
||||
let { data } = msg;
|
||||
let { cmd } = data;
|
||||
debug('MINION.onmessage', { cmd, data });
|
||||
try {
|
||||
(funcs[cmd] || funcs.invalid)(data, data.seq, cmd);
|
||||
} catch (error) {
|
||||
log('MINION.dispatch.error', error);
|
||||
}
|
||||
};
|
||||
|
||||
function reply(msg, direct) {
|
||||
|
|
@ -42,12 +47,22 @@ function log() {
|
|||
console.log(`[${name}]`, ...arguments);
|
||||
}
|
||||
|
||||
function debug() {
|
||||
// console.log(`[${name}]`, ...arguments);
|
||||
}
|
||||
|
||||
const funcs = self.minion = {
|
||||
label(data, seq) {
|
||||
name = data.name;
|
||||
invalid(data, seq, cmd) {
|
||||
console.error({ invalid_minion_command: cmd, data });
|
||||
reply({ seq, error: `invalid command (${cmd})` });
|
||||
},
|
||||
|
||||
config: data => {
|
||||
label(data, seq) {
|
||||
name = data.name;
|
||||
self.kiri_minion = { name, cache, log };
|
||||
},
|
||||
|
||||
config(data) {
|
||||
if (data.base) {
|
||||
Object.assign(base.config, data.base);
|
||||
} else {
|
||||
|
|
@ -55,7 +70,7 @@ const funcs = self.minion = {
|
|||
}
|
||||
},
|
||||
|
||||
union: (data, seq) => {
|
||||
union(data, seq) {
|
||||
if (!(data.polys && data.polys.length)) {
|
||||
reply({ seq, union: codec.encode([]) });
|
||||
return;
|
||||
|
|
@ -66,7 +81,7 @@ const funcs = self.minion = {
|
|||
reply({ seq, union: codec.encode(union) }, state.zeros);
|
||||
},
|
||||
|
||||
topShells: (data, seq) => {
|
||||
topShells(data, seq) {
|
||||
let top = codec.decode(data.top, {full: true});
|
||||
let {z, count, offset1, offsetN, fillOffset, opt} = data;
|
||||
doTopShells(z, top, count, offset1, offsetN, fillOffset, opt);
|
||||
|
|
@ -74,7 +89,7 @@ const funcs = self.minion = {
|
|||
reply({ seq, top: codec.encode(top, {full: true}) }, state.zeros);
|
||||
},
|
||||
|
||||
fill: (data, seq) => {
|
||||
fill(data, seq) {
|
||||
let polys = codec.decode(data.polys);
|
||||
let { angle, spacing, minLen, maxLen } = data;
|
||||
let fill = POLY.fillArea(polys, angle, spacing, [], minLen, maxLen);
|
||||
|
|
@ -89,7 +104,7 @@ const funcs = self.minion = {
|
|||
reply({ seq, fill: arr }, [ arr.buffer ]);
|
||||
},
|
||||
|
||||
clip: (data, seq) => {
|
||||
clip(data, seq) {
|
||||
const clip = new clib.Clipper();
|
||||
const ctre = new clib.PolyTree();
|
||||
const clips = [];
|
||||
|
|
@ -115,8 +130,8 @@ const funcs = self.minion = {
|
|||
reply({ seq, clips }, state.zeros);
|
||||
},
|
||||
|
||||
sliceZ: (data, seq) => {
|
||||
console.log('minion.sliceZ', { data, seq });
|
||||
sliceZ(data, seq) {
|
||||
log('minion.sliceZ', { data, seq });
|
||||
let { z, points, options } = data;
|
||||
let i = 0, p = 0, realp = new Array(points.length / 3);
|
||||
while (i < points.length) {
|
||||
|
|
@ -136,7 +151,7 @@ const funcs = self.minion = {
|
|||
});
|
||||
},
|
||||
|
||||
putCache: msg => {
|
||||
putCache(msg) {
|
||||
const { key, data } = msg;
|
||||
// log({ minion_putCache: key, data });
|
||||
if (data) {
|
||||
|
|
@ -146,13 +161,13 @@ const funcs = self.minion = {
|
|||
}
|
||||
},
|
||||
|
||||
clearCache: msg => {
|
||||
clearCache(msg) {
|
||||
for (let key in cache) {
|
||||
delete cache[key];
|
||||
}
|
||||
},
|
||||
|
||||
wasm: data => {
|
||||
wasm(data) {
|
||||
if (data.enable) {
|
||||
wasm_ctrl.enable();
|
||||
} else {
|
||||
|
|
@ -160,9 +175,27 @@ const funcs = self.minion = {
|
|||
}
|
||||
},
|
||||
|
||||
bad: (data, seq, cmd) => {
|
||||
reply({ seq, error: `invalid command (${cmd})` });
|
||||
}
|
||||
};
|
||||
cam_slice_init() {
|
||||
cache.slicer = new cam_slicer();
|
||||
},
|
||||
|
||||
broker.publish("minion.started", { funcs, cache, reply, log });
|
||||
cam_slice_cleanup() {
|
||||
delete cache.slicer;
|
||||
},
|
||||
|
||||
cam_slice(data, seq) {
|
||||
const { bucket, opt } = data;
|
||||
cache.slicer.sliceBucket(bucket, opt, slice => {
|
||||
// log({ slice });
|
||||
}).then(data => {
|
||||
data.forEach(rec => {
|
||||
rec.polys = encode(rec.polys);
|
||||
if (rec.lines) {
|
||||
const points = rec.lines.map(l => [l.p1, l.p2]).flat();
|
||||
rec.lines = encodePointArray(points);
|
||||
}
|
||||
});
|
||||
reply({ seq, slices: data });
|
||||
});
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import '../add/three.js';
|
|||
import '../ext/jszip.js';
|
||||
|
||||
import { base } from '../geo/base.js';
|
||||
import { broker } from '../moto/broker.js';
|
||||
import { codec } from '../kiri/codec.js';
|
||||
import { util } from '../geo/base.js';
|
||||
import { newPoint } from '../geo/point.js';
|
||||
|
|
@ -28,8 +27,7 @@ import { WJET } from '../kiri-mode/wjet/driver.js';
|
|||
|
||||
const { time } = util;
|
||||
|
||||
let debug = (self.debug === true),
|
||||
drivers = {
|
||||
let drivers = {
|
||||
DRAG,
|
||||
CAM,
|
||||
FDM,
|
||||
|
|
@ -39,7 +37,7 @@ let debug = (self.debug === true),
|
|||
WJET
|
||||
},
|
||||
ccvalue = self.navigator ? self.navigator.hardwareConcurrency || 0 : 0,
|
||||
concurrent = Math.min(4, self.Worker && ccvalue > 3 ? ccvalue - 1 : 0),
|
||||
concurrent = 1,//Math.min(4, self.Worker && ccvalue > 3 ? ccvalue - 1 : 0),
|
||||
current = {
|
||||
print: null,
|
||||
snap: null,
|
||||
|
|
@ -53,6 +51,11 @@ let debug = (self.debug === true),
|
|||
minifns = {},
|
||||
miniseq = 0;
|
||||
|
||||
function debug() {
|
||||
if (self.debug === true)
|
||||
console.log(...arguments);
|
||||
}
|
||||
|
||||
// catch clipper alerts and convert to console messages
|
||||
self.alert = function(o) {
|
||||
console.log(o);
|
||||
|
|
@ -88,11 +91,11 @@ const minwork = {
|
|||
for (let i=0; i < concurrent; i++) {
|
||||
let minion = new Worker(`/lib/kiri-run/minion.js`, { type: 'module' });
|
||||
minion.onerror = (error) => {
|
||||
console.log({ MINION_ERROR: error });
|
||||
debug({ MINION_ERROR: error });
|
||||
error.preventDefault();
|
||||
};
|
||||
minion.onmessageerror = (error) => {
|
||||
console.log({ MINION_MESSAGE_ERROR: error });
|
||||
debug({ MINION_MESSAGE_ERROR: error });
|
||||
error.preventDefault();
|
||||
};
|
||||
minion.onmessage = minhandler;
|
||||
|
|
@ -189,11 +192,11 @@ const minwork = {
|
|||
},
|
||||
|
||||
sliceZ(z, points, options) {
|
||||
console.log('minwork.sliceZ', { z, points, options });
|
||||
debug('minwork.sliceZ', { z, points, options });
|
||||
return new Promise((resolve, reject) => {
|
||||
if (concurrent < 2) {
|
||||
reject("concurrent slice unavaiable");
|
||||
}
|
||||
// if (concurrent < 2) {
|
||||
// reject("concurrent slice unavaiable");
|
||||
// }
|
||||
let { each } = options;
|
||||
// todo use shared array buffer?
|
||||
let i = 0, floatP = new Float32Array(points.length * 3);
|
||||
|
|
@ -202,7 +205,7 @@ const minwork = {
|
|||
floatP[i++] = p.y;
|
||||
floatP[i++] = p.z;
|
||||
}
|
||||
const state = { zeros: [] };
|
||||
const state = { zeros: [ floatP.buffer ] };
|
||||
minwork.queue({
|
||||
cmd: "sliceZ",
|
||||
z,
|
||||
|
|
@ -219,12 +222,13 @@ const minwork = {
|
|||
},
|
||||
|
||||
queue(work, ondone, direct) {
|
||||
if (direct) {
|
||||
return ondone(work);
|
||||
}
|
||||
debug('WORKER.queue', { work, direct });
|
||||
// if (direct) {
|
||||
// return ondone(work);
|
||||
// }
|
||||
let seq = ++miniseq;
|
||||
minifns[seq] = ondone;
|
||||
minionq.push({ seq, work });
|
||||
minionq.push({ seq, work, direct });
|
||||
minwork.kick();
|
||||
},
|
||||
|
||||
|
|
@ -239,9 +243,10 @@ const minwork = {
|
|||
return;
|
||||
}
|
||||
let minion = minions.shift();
|
||||
let { seq, work } = minionq.shift();
|
||||
let { seq, work, direct } = minionq.shift();
|
||||
work.seq = seq;
|
||||
minion.postMessage(work);
|
||||
debug('WORKER.send', { work, direct });
|
||||
minion.postMessage(work, direct);
|
||||
minions.push(minion);
|
||||
},
|
||||
|
||||
|
|
@ -768,5 +773,3 @@ CAM.init(worker);
|
|||
FDM.init(worker);
|
||||
LASER.init(worker);
|
||||
SLA.init(worker);
|
||||
|
||||
broker.publish("worker.started", { dispatch, minions: minwork });
|
||||
|
|
|
|||
|
|
@ -756,9 +756,14 @@ function setEnableWASM(bool) {
|
|||
api.event.emit("set.assembly", bool);
|
||||
}
|
||||
|
||||
// extend API (api.conf)
|
||||
const apiConf = {
|
||||
dbo: () => { return ls2o('ws-settings') },
|
||||
// merged api for backward compatibility
|
||||
const apiSet = {
|
||||
dbo() { return ls2o('ws-settings') },
|
||||
dev() { return settings.device },
|
||||
proc() { return settings.process },
|
||||
ctrl() { return settings.controller },
|
||||
mode() { return settings.mode },
|
||||
prof() { return settings.sproc[settings.mode] },
|
||||
get: getSettings,
|
||||
put: putSettings,
|
||||
load: loadSettings,
|
||||
|
|
@ -773,20 +778,9 @@ const apiConf = {
|
|||
restore: restoreSettings,
|
||||
export: settingsExport,
|
||||
import: settingsImport,
|
||||
};
|
||||
|
||||
// extend API (api.settings)
|
||||
const apiSet = {
|
||||
get: getSettings,
|
||||
import: settingsImport,
|
||||
import_zip: settingsImportZip,
|
||||
import_url: settingsImportUrl,
|
||||
import_prusa: settingsPrusaConvert,
|
||||
dev() { return settings.device },
|
||||
proc() { return settings.process },
|
||||
ctrl() { return settings.controller },
|
||||
mode() { return settings.mode },
|
||||
prof() { return settings.sproc[settings.mode] },
|
||||
sync: {
|
||||
async get() {},
|
||||
async put() {},
|
||||
|
|
@ -794,14 +788,16 @@ const apiSet = {
|
|||
}
|
||||
};
|
||||
|
||||
export default {
|
||||
conf: apiConf,
|
||||
set: apiSet,
|
||||
settings: apiSet
|
||||
};
|
||||
// for backward compatibility
|
||||
apiSet.conf = apiSet;
|
||||
apiSet.set = apiSet;
|
||||
apiSet.settings = apiSet;
|
||||
|
||||
export default apiSet;
|
||||
|
||||
// for backward compatibility
|
||||
export {
|
||||
apiConf as conf,
|
||||
apiSet as conf,
|
||||
apiSet as set,
|
||||
apiSet as settings
|
||||
};
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ class Broker {
|
|||
#topics = {};
|
||||
#used = {};
|
||||
#send = {};
|
||||
#uuid = ((Math.random() * 0xffffffff) | 0).toString(36);
|
||||
|
||||
constructor() {
|
||||
// using the pattern "broker.send(msg)" induces runtime errors
|
||||
|
|
@ -36,6 +37,9 @@ class Broker {
|
|||
// creates topic if new topic
|
||||
// creates a send function if new topic
|
||||
subscribe(topic, listener) {
|
||||
if (this.#debug) {
|
||||
console.log({ subscribe: topic, listener });
|
||||
}
|
||||
if (Array.isArray(topic)) {
|
||||
for (let t of topic) {
|
||||
this.subscribe(t, listener);
|
||||
|
|
@ -91,7 +95,7 @@ class Broker {
|
|||
this.publish(".topic.publish", {topic, message, options});
|
||||
}
|
||||
if (this.#debug && !topic.startsWith(".")) {
|
||||
console.log({ topic, message });
|
||||
console.log({ publish: topic, message });
|
||||
}
|
||||
// store last seen message on a topic
|
||||
// acts as a tracker for all used topics
|
||||
|
|
|
|||
Loading…
Reference in a new issue