2020-06-03 22:39:30 -04:00
|
|
|
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
|
|
|
|
|
2020-02-29 20:13:49 -05:00
|
|
|
"use strict";
|
|
|
|
|
|
2022-02-22 11:32:35 -05:00
|
|
|
// dep: geo.base
|
|
|
|
|
// dep: geo.polygons
|
|
|
|
|
// dep: geo.wasm
|
|
|
|
|
// dep: kiri.codec
|
2022-02-22 22:00:50 -05:00
|
|
|
// dep: kiri.slice
|
2022-02-22 11:47:59 -05:00
|
|
|
// dep: moto.license
|
2022-02-25 23:49:51 -05:00
|
|
|
// use: load.png
|
2022-02-23 12:05:34 -05:00
|
|
|
// use: kiri.render
|
2022-02-22 11:32:35 -05:00
|
|
|
// use: kiri-mode.cam.animate
|
|
|
|
|
// use: kiri-mode.cam.slice
|
|
|
|
|
// use: kiri-mode.cam.prepare
|
|
|
|
|
// use: kiri-mode.cam.export
|
|
|
|
|
// use: kiri-mode.cam.tool
|
|
|
|
|
// use: kiri-mode.fdm.slice
|
|
|
|
|
// use: kiri-mode.fdm.prepare
|
|
|
|
|
// use: kiri-mode.fdm.export
|
|
|
|
|
// use: kiri-mode.sla.slice
|
|
|
|
|
// use: kiri-mode.sla.export
|
|
|
|
|
// use: kiri-mode.fdm.slice
|
|
|
|
|
// use: kiri-mode.fdm.prepare
|
|
|
|
|
// use: kiri-mode.fdm.export
|
|
|
|
|
// use: kiri-mode.laser.driver
|
2022-02-22 11:36:04 -05:00
|
|
|
gapp.register("kiri-run.worker", [], (root, exports) => {
|
2022-02-22 00:05:29 -05:00
|
|
|
|
|
|
|
|
const { base, kiri } = root;
|
2022-02-20 14:31:27 -05:00
|
|
|
const { util, polygons, wasm_ctrl } = base;
|
2022-02-19 16:32:43 -05:00
|
|
|
const { codec } = kiri;
|
|
|
|
|
const { time } = util;
|
|
|
|
|
const POLY = polygons;
|
|
|
|
|
|
2022-02-24 13:47:26 -05:00
|
|
|
let debug = self.debug === true,
|
2021-08-01 12:23:35 -04:00
|
|
|
ccvalue = this.navigator ? navigator.hardwareConcurrency || 0 : 0,
|
2021-06-21 12:54:41 -04:00
|
|
|
concurrent = self.Worker && ccvalue > 3 ? ccvalue - 1 : 0,
|
2020-06-16 11:08:50 -04:00
|
|
|
current = self.worker = {
|
|
|
|
|
print: null,
|
|
|
|
|
snap: null
|
2020-11-03 11:19:13 -05:00
|
|
|
},
|
2021-01-24 00:13:09 -05:00
|
|
|
wgroup = {},
|
2021-06-19 22:44:08 -04:00
|
|
|
wcache = {},
|
|
|
|
|
minions = [],
|
2021-06-20 23:38:19 -04:00
|
|
|
minionq = [],
|
|
|
|
|
minifns = {},
|
|
|
|
|
miniseq = 0;
|
2020-03-18 18:22:57 -04:00
|
|
|
|
2022-02-19 16:32:43 -05:00
|
|
|
kiri.version = gapp.version;
|
2022-01-04 08:15:26 -05:00
|
|
|
|
2020-03-18 18:22:57 -04:00
|
|
|
// catch clipper alerts and convert to console messages
|
|
|
|
|
self.alert = function(o) {
|
|
|
|
|
console.log(o);
|
|
|
|
|
};
|
2020-02-29 20:13:49 -05:00
|
|
|
|
2022-02-24 13:47:26 -05:00
|
|
|
function minhandler(msg) {
|
|
|
|
|
let data = msg.data;
|
|
|
|
|
let seq = data.seq;
|
|
|
|
|
let fn = minifns[seq];
|
|
|
|
|
if (!fn) {
|
|
|
|
|
throw `missing dispatch ${seq}`;
|
2021-06-20 23:38:19 -04:00
|
|
|
}
|
2022-02-24 13:47:26 -05:00
|
|
|
delete minifns[seq];
|
|
|
|
|
fn(data);
|
2021-06-19 22:44:08 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// for concurrent operations
|
2021-06-20 00:25:35 -04:00
|
|
|
const minwork =
|
2022-02-19 16:32:43 -05:00
|
|
|
kiri.minions = {
|
2021-06-20 18:10:19 -04:00
|
|
|
concurrent,
|
|
|
|
|
|
2022-02-24 13:47:26 -05:00
|
|
|
start() {
|
|
|
|
|
if (minions.length || !concurrent) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
for (let i=0; i < concurrent; i++) {
|
|
|
|
|
let _ = debug ? '_' : '';
|
|
|
|
|
let minion = new Worker(`/code/kiri_pool.js?${_}${self.kiri.version}`);
|
|
|
|
|
minion.onmessage = minhandler;
|
|
|
|
|
minion.postMessage({ cmd: "label", name: `#${i}` });
|
|
|
|
|
minions.push(minion);
|
|
|
|
|
}
|
|
|
|
|
console.log(`kiri | init pool | ${gapp.version || "rogue"} | ${concurrent + 1}`);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
stop() {
|
|
|
|
|
for (let minion of minions) {
|
|
|
|
|
minion.terminate();
|
|
|
|
|
}
|
|
|
|
|
minions.length = 0;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
union(polys, minarea) {
|
2021-06-19 22:44:08 -04:00
|
|
|
return new Promise((resolve, reject) => {
|
2021-06-24 18:15:51 -04:00
|
|
|
if (concurrent < 2 || polys.length < concurrent * 2 || POLY.points(polys) < concurrent * 50) {
|
|
|
|
|
resolve(POLY.union(polys, minarea, true));
|
2021-06-20 18:10:19 -04:00
|
|
|
return;
|
2021-06-19 22:44:08 -04:00
|
|
|
}
|
|
|
|
|
let polyper = Math.ceil(polys.length / concurrent);
|
|
|
|
|
let running = 0;
|
|
|
|
|
let union = [];
|
2021-06-20 00:25:35 -04:00
|
|
|
let receiver = function(data) {
|
2022-02-19 16:32:43 -05:00
|
|
|
let polys = codec.decode(data.union);
|
2021-06-19 22:44:08 -04:00
|
|
|
union.appendAll(polys);
|
|
|
|
|
if (--running === 0) {
|
2021-06-24 18:15:51 -04:00
|
|
|
resolve(POLY.union(union, minarea, true));
|
2021-06-19 22:44:08 -04:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
for (let i=0; i<polys.length; i += polyper) {
|
2021-06-20 00:25:35 -04:00
|
|
|
running++;
|
|
|
|
|
minwork.queue({
|
2021-06-19 22:44:08 -04:00
|
|
|
cmd: "union",
|
|
|
|
|
minarea,
|
2022-02-19 16:32:43 -05:00
|
|
|
polys: codec.encode(polys.slice(i, i + polyper))
|
2021-06-20 00:25:35 -04:00
|
|
|
}, receiver);
|
2021-06-19 22:44:08 -04:00
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
|
2022-02-24 13:47:26 -05:00
|
|
|
fill(polys, angle, spacing, output, minLen, maxLen) {
|
2021-06-20 13:03:30 -04:00
|
|
|
return new Promise((resolve, reject) => {
|
2021-06-20 22:15:46 -04:00
|
|
|
if (concurrent < 2) {
|
2021-06-20 13:03:30 -04:00
|
|
|
resolve(POLY.fillArea(polys, angle, spacing, [], minLen, maxLen));
|
2021-06-20 18:10:19 -04:00
|
|
|
return;
|
2021-06-20 13:03:30 -04:00
|
|
|
}
|
|
|
|
|
minwork.queue({
|
|
|
|
|
cmd: "fill",
|
2022-02-19 16:32:43 -05:00
|
|
|
polys: codec.encode(polys),
|
2021-06-20 13:03:30 -04:00
|
|
|
angle, spacing, minLen, maxLen
|
|
|
|
|
}, data => {
|
|
|
|
|
let arr = data.fill;
|
|
|
|
|
let fill = [];
|
|
|
|
|
for (let i=0; i<arr.length; ) {
|
2022-02-19 16:32:43 -05:00
|
|
|
let pt = base.newPoint(arr[i++], arr[i++], arr[i++]);
|
2021-06-20 13:03:30 -04:00
|
|
|
pt.index = arr[i++];
|
|
|
|
|
fill.push(pt);
|
|
|
|
|
}
|
|
|
|
|
output.appendAll(fill);
|
|
|
|
|
resolve(fill);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
|
2022-02-24 13:47:26 -05:00
|
|
|
clip(slice, polys, lines) {
|
2021-06-20 18:10:19 -04:00
|
|
|
return new Promise((resolve, reject) => {
|
2021-06-20 22:15:46 -04:00
|
|
|
if (concurrent < 2) {
|
2021-06-20 18:10:19 -04:00
|
|
|
reject("concurrent clip unavaiable");
|
|
|
|
|
}
|
|
|
|
|
minwork.queue({
|
|
|
|
|
cmd: "clip",
|
|
|
|
|
polys: POLY.toClipper(polys),
|
|
|
|
|
lines: lines.map(a => a.map(p => p.toClipper())),
|
|
|
|
|
z: slice.z
|
|
|
|
|
}, data => {
|
2022-02-19 16:32:43 -05:00
|
|
|
let polys = codec.decode(data.clips);
|
2021-06-20 18:10:19 -04:00
|
|
|
for (let top of slice.tops) {
|
|
|
|
|
for (let poly of polys) {
|
|
|
|
|
if (poly.isInside(top.poly)) {
|
|
|
|
|
top.fill_sparse.push(poly);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
resolve(polys);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
|
2022-02-24 13:47:26 -05:00
|
|
|
sliceZ(z, points, options) {
|
2021-06-20 22:15:46 -04:00
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
|
if (concurrent < 2) {
|
|
|
|
|
reject("concurrent slice unavaiable");
|
|
|
|
|
}
|
2022-02-16 22:57:12 -05:00
|
|
|
let { each } = options;
|
2021-06-20 22:15:46 -04:00
|
|
|
let i = 0, floatP = new Float32Array(points.length * 3);
|
|
|
|
|
for (let p of points) {
|
|
|
|
|
floatP[i++] = p.x;
|
|
|
|
|
floatP[i++] = p.y;
|
|
|
|
|
floatP[i++] = p.z;
|
|
|
|
|
}
|
|
|
|
|
minwork.queue({
|
2022-02-16 22:57:12 -05:00
|
|
|
cmd: "sliceZ",
|
|
|
|
|
z,
|
2021-06-20 22:15:46 -04:00
|
|
|
points: floatP,
|
2022-02-19 16:32:43 -05:00
|
|
|
options: codec.toCodable(options)
|
2021-06-20 22:15:46 -04:00
|
|
|
}, data => {
|
2022-02-19 16:32:43 -05:00
|
|
|
let recs = codec.decode(data.output);
|
2022-02-16 22:57:12 -05:00
|
|
|
if (each) {
|
|
|
|
|
for (let rec of recs) {
|
|
|
|
|
each(rec);
|
|
|
|
|
}
|
2021-06-20 22:15:46 -04:00
|
|
|
}
|
2021-06-23 22:31:27 -04:00
|
|
|
resolve(recs);
|
2021-06-20 22:15:46 -04:00
|
|
|
}, [ floatP.buffer ]);
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
|
2022-02-24 13:47:26 -05:00
|
|
|
queue(work, ondone, direct) {
|
2021-06-20 22:15:46 -04:00
|
|
|
minionq.push({work, ondone, direct});
|
2021-06-20 00:25:35 -04:00
|
|
|
minwork.kick();
|
2021-06-19 22:44:08 -04:00
|
|
|
},
|
|
|
|
|
|
2022-02-24 13:47:26 -05:00
|
|
|
kick() {
|
2021-06-19 22:44:08 -04:00
|
|
|
if (minions.length && minionq.length) {
|
|
|
|
|
let qrec = minionq.shift();
|
|
|
|
|
let minion = minions.shift();
|
2021-06-20 23:38:19 -04:00
|
|
|
let seq = miniseq++;
|
|
|
|
|
qrec.work.seq = seq;
|
|
|
|
|
minifns[seq] = (data) => {
|
|
|
|
|
qrec.ondone(data);
|
2021-06-19 22:44:08 -04:00
|
|
|
minions.push(minion);
|
2021-06-20 00:25:35 -04:00
|
|
|
minwork.kick();
|
2021-06-19 22:44:08 -04:00
|
|
|
};
|
2021-06-20 22:15:46 -04:00
|
|
|
minion.postMessage(qrec.work, qrec.direct);
|
2021-06-19 22:44:08 -04:00
|
|
|
}
|
2021-07-07 21:09:34 -04:00
|
|
|
},
|
|
|
|
|
|
2022-02-24 13:47:26 -05:00
|
|
|
wasm(enable) {
|
2021-07-07 21:09:34 -04:00
|
|
|
for (let minion of minions) {
|
|
|
|
|
minion.postMessage({
|
|
|
|
|
cmd: "wasm",
|
|
|
|
|
enable
|
|
|
|
|
});
|
|
|
|
|
}
|
2021-06-19 22:44:08 -04:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2021-12-29 00:19:22 -05:00
|
|
|
console.log(`kiri | init work | ${gapp.version || "rogue"}`);
|
2020-11-03 11:19:13 -05:00
|
|
|
|
|
|
|
|
// code is running in the worker / server context
|
|
|
|
|
const dispatch =
|
2022-02-19 16:32:43 -05:00
|
|
|
kiri.server =
|
|
|
|
|
kiri.worker = {
|
2022-02-24 13:47:26 -05:00
|
|
|
pool_start(data, send) {
|
|
|
|
|
minwork.start();
|
|
|
|
|
send.done({});
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
pool_stop(data, send) {
|
|
|
|
|
minwork.stop();
|
|
|
|
|
send.done({});
|
|
|
|
|
},
|
|
|
|
|
|
2021-01-24 00:13:09 -05:00
|
|
|
group: wgroup,
|
|
|
|
|
|
|
|
|
|
cache: wcache,
|
2020-11-03 11:19:13 -05:00
|
|
|
|
2022-02-24 13:47:26 -05:00
|
|
|
decimate(data, send) {
|
2020-11-06 10:47:49 -05:00
|
|
|
let { vertices, options } = data;
|
2020-02-29 20:13:49 -05:00
|
|
|
vertices = new Float32Array(vertices),
|
2022-02-19 16:32:43 -05:00
|
|
|
vertices = base.pointsToVertices(base.verticesToPoints(vertices, options));
|
2020-02-29 20:13:49 -05:00
|
|
|
send.done(vertices);
|
|
|
|
|
},
|
|
|
|
|
|
2022-02-24 13:47:26 -05:00
|
|
|
heal(data, send) {
|
2021-12-09 21:33:05 -05:00
|
|
|
let { vertices, refresh } = data;
|
2021-09-08 11:04:57 -04:00
|
|
|
let mesh = new base.Mesh({vertices}).heal();
|
2021-12-09 21:33:05 -05:00
|
|
|
if (mesh.newFaces || refresh) {
|
2021-09-08 11:04:57 -04:00
|
|
|
vertices = mesh.unrolled().toFloat32();
|
|
|
|
|
send.done({vertices}, [vertices]);
|
|
|
|
|
} else {
|
|
|
|
|
send.done({});
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
2022-02-24 13:47:26 -05:00
|
|
|
snap(data, send) {
|
2020-06-16 11:08:50 -04:00
|
|
|
current.snap = data;
|
2020-04-15 21:44:37 -04:00
|
|
|
send.done();
|
|
|
|
|
},
|
|
|
|
|
|
2022-02-24 13:47:26 -05:00
|
|
|
png(data, send) {
|
2021-11-12 23:21:11 -05:00
|
|
|
if (current.snap) {
|
|
|
|
|
let sws = current.snap.url;
|
|
|
|
|
let b64 = atob(sws.substring(sws.indexOf(',') + 1));
|
|
|
|
|
let bin = Uint8Array.from(b64, c => c.charCodeAt(0));
|
|
|
|
|
let img = new png.PNG();
|
|
|
|
|
img.parse(bin, (err, data) => {
|
|
|
|
|
send.done({png: bin}, [ bin ]);
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
send.done({error: "missing snapshot"});
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
2022-02-24 13:47:26 -05:00
|
|
|
clear(data, send) {
|
2021-11-17 15:03:28 -05:00
|
|
|
// current.snap = null;
|
2021-01-24 00:13:09 -05:00
|
|
|
current.print = null;
|
2021-02-08 10:10:31 -05:00
|
|
|
dispatch.group = wgroup = {};
|
|
|
|
|
dispatch.cache = wcache = {};
|
2022-02-19 16:32:43 -05:00
|
|
|
kiri.Widget.Groups.clear();
|
2021-02-08 10:10:31 -05:00
|
|
|
send.done({ clear: true });
|
2021-01-24 00:13:09 -05:00
|
|
|
},
|
|
|
|
|
|
2020-11-30 18:01:32 -05:00
|
|
|
// widget sync
|
2022-02-24 13:47:26 -05:00
|
|
|
sync(data, send) {
|
2021-02-08 10:55:36 -05:00
|
|
|
if (data.valid) {
|
|
|
|
|
// remove widgets not present in valid list
|
|
|
|
|
for (let key in wcache) {
|
|
|
|
|
if (data.valid.indexOf(key) < 0) {
|
|
|
|
|
delete wcache[key];
|
|
|
|
|
for (let [id,group] of Object.entries(wgroup)) {
|
|
|
|
|
wgroup[id] = group = group.filter(v => v.id !== key);
|
|
|
|
|
group.id = id;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-03-15 15:20:50 -04:00
|
|
|
send.done(data.id);
|
2021-02-08 10:55:36 -05:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2021-01-24 00:13:09 -05:00
|
|
|
let group = wgroup[data.group];
|
|
|
|
|
if (!group) {
|
|
|
|
|
group = [];
|
|
|
|
|
group.id = data.group;
|
|
|
|
|
wgroup[data.group] = group;
|
|
|
|
|
}
|
2020-11-30 18:01:32 -05:00
|
|
|
let vertices = new Float32Array(data.vertices),
|
2022-02-19 16:32:43 -05:00
|
|
|
widget = kiri.newWidget(data.id, group).loadVertices(vertices).setInWorker();
|
2020-02-29 20:13:49 -05:00
|
|
|
|
|
|
|
|
// do it here so cancel can work
|
2021-01-24 00:13:09 -05:00
|
|
|
wcache[data.id] = widget;
|
2020-12-04 19:44:31 -05:00
|
|
|
// stored for possible future rotations
|
|
|
|
|
widget.vertices = vertices;
|
2022-01-24 21:54:50 -05:00
|
|
|
// restore meta
|
|
|
|
|
widget.meta = data.meta;
|
2021-01-24 00:13:09 -05:00
|
|
|
// restore tracking object
|
|
|
|
|
widget.track = data.track;
|
2020-11-30 18:01:32 -05:00
|
|
|
send.done(data.id);
|
|
|
|
|
},
|
|
|
|
|
|
2022-02-24 13:47:26 -05:00
|
|
|
rotate(data, send) {
|
2021-01-24 00:13:09 -05:00
|
|
|
let { settings } = data;
|
|
|
|
|
if (!settings.device.bedBelt) {
|
|
|
|
|
return send.done({});
|
|
|
|
|
}
|
2020-04-01 09:04:10 -04:00
|
|
|
|
2021-01-24 20:38:45 -05:00
|
|
|
function mins(vert, last = {}) {
|
|
|
|
|
let miny = last.miny || Infinity,
|
|
|
|
|
maxy = last.maxy || -Infinity;
|
2021-01-10 22:22:36 -05:00
|
|
|
for (let i=0, l=vert.length; i<l; ) {
|
|
|
|
|
let x = vert[i++];
|
|
|
|
|
let y = vert[i++];
|
|
|
|
|
let z = vert[i++];
|
2021-04-27 21:53:21 -04:00
|
|
|
// if (z < 0.01) {
|
2021-01-24 20:38:45 -05:00
|
|
|
miny = Math.min(miny, y);
|
|
|
|
|
maxy = Math.max(maxy, y);
|
2021-04-27 21:53:21 -04:00
|
|
|
// }
|
2021-01-10 22:22:36 -05:00
|
|
|
}
|
2021-01-24 20:38:45 -05:00
|
|
|
return { miny, maxy };
|
2021-01-24 00:13:09 -05:00
|
|
|
}
|
2021-01-10 22:22:36 -05:00
|
|
|
|
2021-01-25 00:48:19 -05:00
|
|
|
function gmin(group) {
|
2021-01-24 20:38:45 -05:00
|
|
|
let minv = {};
|
|
|
|
|
for (let w of group) {
|
|
|
|
|
minv = mins(w.vertices, minv);
|
|
|
|
|
}
|
2021-01-25 00:48:19 -05:00
|
|
|
return minv;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (let group of Object.values(wgroup)) {
|
|
|
|
|
let { miny, maxy } = gmin(group);
|
2021-01-24 20:38:45 -05:00
|
|
|
let widget = group[0];
|
2021-01-08 23:44:26 -05:00
|
|
|
let track = widget.track;
|
2021-01-24 00:13:09 -05:00
|
|
|
let xpos = track.pos.x;
|
|
|
|
|
let ypos = settings.device.bedDepth / 2 + track.pos.y + miny;
|
2021-01-24 20:38:45 -05:00
|
|
|
let rotation = (Math.PI / 180) * 45;
|
2022-02-12 10:44:50 -05:00
|
|
|
let proc = settings.process;
|
2021-04-13 09:57:56 -04:00
|
|
|
// move to accomodate anchor
|
2022-02-12 10:44:50 -05:00
|
|
|
ypos += (proc.beltAnchor || proc.firstLayerBeltLead || 0);
|
2021-04-27 21:53:21 -04:00
|
|
|
for (let w of group) {
|
|
|
|
|
w.moveMesh(0, miny, 0);
|
|
|
|
|
}
|
|
|
|
|
widget.rotateRaw(rotation,0,0,true);
|
2021-01-25 00:48:19 -05:00
|
|
|
let minr = gmin(group);
|
2021-04-27 21:53:21 -04:00
|
|
|
widget.belt = { xpos, ypos, yadd: minr.maxy - minr.miny, dy: -miny, dz: 0 };
|
2021-01-24 00:13:09 -05:00
|
|
|
for (let others of group.slice(1)) {
|
|
|
|
|
others.belt = widget.belt;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
send.data({group: group.id, belt: widget.belt});
|
2020-12-04 19:44:31 -05:00
|
|
|
}
|
2021-01-24 00:13:09 -05:00
|
|
|
send.done({});
|
|
|
|
|
},
|
2020-12-04 19:44:31 -05:00
|
|
|
|
2022-02-24 13:47:26 -05:00
|
|
|
unrotate(data, send) {
|
2021-01-24 00:13:09 -05:00
|
|
|
let { settings } = data;
|
|
|
|
|
if (!settings.device.bedBelt) {
|
|
|
|
|
return send.done({});
|
|
|
|
|
}
|
|
|
|
|
let rotation = (Math.PI / 180) * 45;
|
|
|
|
|
for (let group of Object.values(wgroup)) {
|
|
|
|
|
let widget = group[0];
|
|
|
|
|
let { xpos, ypos } = widget.belt;
|
2021-04-27 21:53:21 -04:00
|
|
|
let { dy, dz } = widget.belt;
|
2022-02-12 10:44:50 -05:00
|
|
|
let proc = settings.process;
|
2021-04-13 09:57:56 -04:00
|
|
|
// move to accomodate anchor
|
2022-02-12 10:44:50 -05:00
|
|
|
dy -= (proc.beltAnchor || proc.firstLayerBeltLead || 0) ;
|
2021-01-24 00:13:09 -05:00
|
|
|
widget.rotinfo = { angle: 45, dy, dz, xpos, ypos };
|
|
|
|
|
for (let others of group.slice(1)) {
|
|
|
|
|
others.rotinfo = widget.rotinfo;
|
2020-02-29 20:13:49 -05:00
|
|
|
}
|
2021-01-24 00:13:09 -05:00
|
|
|
send.data({group: group.id, rotinfo: widget.rotinfo});
|
|
|
|
|
}
|
|
|
|
|
send.done({});
|
|
|
|
|
},
|
2020-12-07 23:31:07 -05:00
|
|
|
|
2022-02-24 13:47:26 -05:00
|
|
|
slice(data, send) {
|
2021-01-24 00:13:09 -05:00
|
|
|
send.data({update:0.001, updateStatus:"slicing"});
|
2020-04-01 09:04:10 -04:00
|
|
|
|
2021-06-18 22:57:30 -04:00
|
|
|
current.print = null;
|
|
|
|
|
|
2021-01-24 00:13:09 -05:00
|
|
|
let settings = data.settings,
|
|
|
|
|
widget = wcache[data.id],
|
|
|
|
|
last = time(),
|
|
|
|
|
now;
|
|
|
|
|
|
2021-10-18 23:36:19 -04:00
|
|
|
widget.anno = data.anno || widget.anno;
|
|
|
|
|
|
2021-02-03 20:52:25 -05:00
|
|
|
widget.slice(settings, function(error) {
|
|
|
|
|
if (error) {
|
|
|
|
|
send.data({error: error});
|
|
|
|
|
} else {
|
|
|
|
|
const slices = widget.slices || [];
|
|
|
|
|
send.data({send_start: time()});
|
|
|
|
|
send.data({
|
|
|
|
|
stats: widget.stats,
|
|
|
|
|
slices: slices.length,
|
|
|
|
|
});
|
2022-02-19 16:32:43 -05:00
|
|
|
slices.forEach((slice,index) => {
|
2021-02-03 20:52:25 -05:00
|
|
|
const state = { zeros: [] };
|
|
|
|
|
send.data({index: index, slice: slice.encode(state)}, state.zeros);
|
|
|
|
|
})
|
|
|
|
|
send.data({send_end: time()});
|
|
|
|
|
}
|
|
|
|
|
send.done({done: true});
|
|
|
|
|
}, function(update, msg) {
|
|
|
|
|
now = time();
|
|
|
|
|
if (now - last < 10 && update < 0.99) return;
|
|
|
|
|
// on update
|
|
|
|
|
send.data({update: (0.05 + update * 0.95), updateStatus: msg});
|
|
|
|
|
last = now;
|
|
|
|
|
});
|
2020-02-29 20:13:49 -05:00
|
|
|
},
|
|
|
|
|
|
2022-02-24 13:47:26 -05:00
|
|
|
sliceAll(data, send) {
|
2022-02-19 16:32:43 -05:00
|
|
|
const { settings } = data;
|
|
|
|
|
const { mode } = settings;
|
|
|
|
|
const driver = kiri.driver[mode];
|
2021-07-13 22:41:22 -04:00
|
|
|
|
|
|
|
|
if (driver.sliceAll) {
|
|
|
|
|
driver.sliceAll(settings, send.data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
send.done({done: true});
|
|
|
|
|
},
|
|
|
|
|
|
2022-02-24 13:47:26 -05:00
|
|
|
prepare(data, send) {
|
2020-11-08 10:55:36 -05:00
|
|
|
// create widget array from id:widget cache
|
2021-01-24 00:13:09 -05:00
|
|
|
const widgets = Object.values(wcache);
|
2020-02-29 20:13:49 -05:00
|
|
|
|
2020-11-08 10:55:36 -05:00
|
|
|
// let client know we've started
|
2020-02-29 20:13:49 -05:00
|
|
|
send.data({update:0.05, updateStatus:"preview"});
|
|
|
|
|
|
2022-02-19 16:32:43 -05:00
|
|
|
const { settings } = data;
|
|
|
|
|
const { mode } = settings;
|
|
|
|
|
const driver = kiri.driver[mode];
|
2020-11-08 13:04:54 -05:00
|
|
|
|
|
|
|
|
if (!(driver && driver.prepare)) {
|
|
|
|
|
return console.log({invalid_print_driver: mode, driver});
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-26 09:10:20 -05:00
|
|
|
const layers = driver.prepare(widgets, settings, (progress, message, layer) => {
|
|
|
|
|
const state = { zeros: [] };
|
|
|
|
|
const emit = { progress, message };
|
|
|
|
|
if (layer) {
|
2022-02-19 16:32:43 -05:00
|
|
|
emit.layer = codec.encode(layer, state)
|
2020-11-26 09:10:20 -05:00
|
|
|
}
|
|
|
|
|
send.data(emit);
|
2020-02-29 20:13:49 -05:00
|
|
|
});
|
2020-11-08 13:04:54 -05:00
|
|
|
|
2020-12-05 10:04:00 -05:00
|
|
|
const unitScale = settings.controller.units === 'in' ? (1 / 25.4) : 1;
|
2020-11-10 23:22:58 -05:00
|
|
|
const print = current.print || {};
|
2021-05-20 09:40:15 -04:00
|
|
|
const minSpeed = (print.minSpeed || 0) * unitScale;
|
2020-12-05 10:04:00 -05:00
|
|
|
const maxSpeed = (print.maxSpeed || 0) * unitScale;
|
2020-11-26 08:48:19 -05:00
|
|
|
const state = { zeros: [] };
|
|
|
|
|
|
|
|
|
|
send.data({ progress: 1, message: "transfer" });
|
2020-11-10 21:48:04 -05:00
|
|
|
|
|
|
|
|
send.done({
|
|
|
|
|
done: true,
|
2022-02-19 16:32:43 -05:00
|
|
|
// output: codec.encode(layers, state),
|
2021-05-20 09:40:15 -04:00
|
|
|
minSpeed,
|
2020-11-11 08:07:02 -05:00
|
|
|
maxSpeed
|
2020-11-26 08:48:19 -05:00
|
|
|
}, state.zeros);
|
2020-02-29 20:13:49 -05:00
|
|
|
},
|
2020-04-14 09:26:59 -04:00
|
|
|
|
2022-02-24 13:47:26 -05:00
|
|
|
export(data, send) {
|
2020-11-08 17:35:40 -05:00
|
|
|
const mode = data.settings.mode;
|
2022-02-19 16:32:43 -05:00
|
|
|
const driver = kiri.driver[mode];
|
2020-11-08 17:35:40 -05:00
|
|
|
|
|
|
|
|
if (!(driver && driver.export)) {
|
|
|
|
|
console.log({missing_export_driver: mode});
|
|
|
|
|
return send.done()
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-08 19:38:02 -05:00
|
|
|
let output;
|
|
|
|
|
driver.export(current.print, function(line, direct) {
|
|
|
|
|
send.data({line}, direct);
|
|
|
|
|
}, function(done) {
|
|
|
|
|
// SLA workaround
|
|
|
|
|
output = done;
|
2021-06-18 15:03:00 -04:00
|
|
|
}, function(debug) {
|
|
|
|
|
send.data({debug});
|
2020-11-08 17:35:40 -05:00
|
|
|
});
|
2021-11-15 14:10:15 -05:00
|
|
|
const {
|
|
|
|
|
bounds, time, lines, bytes, distance,
|
|
|
|
|
settings, segments, purges
|
|
|
|
|
} = current.print;
|
2020-11-08 17:35:40 -05:00
|
|
|
|
|
|
|
|
send.done({
|
|
|
|
|
done: true,
|
2021-11-15 14:10:15 -05:00
|
|
|
output: output ? output : {
|
|
|
|
|
bounds, time, lines, bytes, distance,
|
|
|
|
|
settings, segments, purges
|
|
|
|
|
}
|
2020-04-14 09:26:59 -04:00
|
|
|
});
|
|
|
|
|
},
|
2020-02-29 20:13:49 -05:00
|
|
|
|
2022-02-24 13:47:26 -05:00
|
|
|
colors(data, send) {
|
2020-11-11 08:07:02 -05:00
|
|
|
const { colors, max } = data;
|
|
|
|
|
const colorMap = {};
|
|
|
|
|
colors.forEach(color => {
|
2022-02-23 12:05:34 -05:00
|
|
|
colorMap[color] = kiri.render.rate_to_color(color, max);
|
2020-11-11 08:07:02 -05:00
|
|
|
});
|
|
|
|
|
send.done(colorMap);
|
|
|
|
|
},
|
|
|
|
|
|
2022-02-24 13:47:26 -05:00
|
|
|
parse(args, send) {
|
2020-11-09 13:57:18 -05:00
|
|
|
const { settings, code, type } = args;
|
|
|
|
|
const origin = settings.origin;
|
|
|
|
|
const offset = {
|
|
|
|
|
x: origin.x,
|
|
|
|
|
y: -origin.y,
|
|
|
|
|
z: origin.z
|
|
|
|
|
};
|
2021-01-09 21:08:24 -05:00
|
|
|
const device = settings.device;
|
2022-02-19 16:32:43 -05:00
|
|
|
const print = current.print = kiri.newPrint(settings, Object.values(wcache));
|
2021-01-09 21:08:24 -05:00
|
|
|
const tools = device.extruders;
|
2020-11-09 18:21:59 -05:00
|
|
|
const mode = settings.mode;
|
2020-11-12 12:15:39 -05:00
|
|
|
const thin = settings.controller.lineType === 'line' || mode !== 'FDM';
|
|
|
|
|
const flat = settings.controller.lineType === 'flat' && mode === 'FDM';
|
2020-11-09 13:57:18 -05:00
|
|
|
const parsed = print.parseGCode(code, offset, progress => {
|
2020-11-18 13:17:05 -05:00
|
|
|
send.data({ progress: progress * 0.25 });
|
2020-11-09 13:57:18 -05:00
|
|
|
}, done => {
|
2021-05-20 09:40:15 -04:00
|
|
|
const minSpeed = print.minSpeed;
|
2020-11-13 09:27:42 -05:00
|
|
|
const maxSpeed = print.maxSpeed;
|
2022-02-23 12:05:34 -05:00
|
|
|
const layers = kiri.render.path(done.output, progress => {
|
2020-11-18 13:17:05 -05:00
|
|
|
send.data({ progress: 0.25 + progress * 0.75 });
|
2021-01-08 10:55:40 -05:00
|
|
|
}, { thin: thin || print.belt, flat, tools });
|
2022-02-19 16:32:43 -05:00
|
|
|
send.done({parsed: codec.encode(layers), maxSpeed, minSpeed});
|
2021-01-09 21:08:24 -05:00
|
|
|
}, {
|
|
|
|
|
fdm: mode === 'FDM',
|
|
|
|
|
belt: device.bedBelt
|
|
|
|
|
});
|
2020-02-29 20:13:49 -05:00
|
|
|
},
|
|
|
|
|
|
2022-02-24 13:47:26 -05:00
|
|
|
parse_svg(parsed, send) {
|
2020-11-09 23:01:41 -05:00
|
|
|
parsed.forEach(layer => {
|
|
|
|
|
layer.forEach(out => {
|
|
|
|
|
const { x, y, z } = out.point;
|
2022-02-19 16:32:43 -05:00
|
|
|
out.point = base.newPoint(x,y,z || 0);
|
2020-11-09 23:01:41 -05:00
|
|
|
});
|
|
|
|
|
});
|
2022-02-19 16:32:43 -05:00
|
|
|
const print = current.print = kiri.newPrint(null, Object.values(wcache));
|
2022-02-23 12:05:34 -05:00
|
|
|
const layers = kiri.render.path(parsed, progress => {
|
2020-11-09 23:01:41 -05:00
|
|
|
send.data({ progress });
|
|
|
|
|
}, { thin: true });
|
2022-02-19 16:32:43 -05:00
|
|
|
send.done({parsed: codec.encode(layers)});
|
2020-11-09 23:01:41 -05:00
|
|
|
},
|
|
|
|
|
|
2022-02-24 13:47:26 -05:00
|
|
|
config(data, send) {
|
2020-09-14 09:43:34 -04:00
|
|
|
const update = {};
|
|
|
|
|
if (data.base) {
|
|
|
|
|
update.base = data.base;
|
2022-02-19 16:32:43 -05:00
|
|
|
Object.assign(base.config, data.base);
|
2020-09-14 09:43:34 -04:00
|
|
|
} else {
|
|
|
|
|
console.log({invalid:data});
|
|
|
|
|
}
|
2021-06-21 02:12:25 -04:00
|
|
|
for (let minion of minions) {
|
|
|
|
|
minion.postMessage({
|
|
|
|
|
cmd: "config",
|
|
|
|
|
base: data.base
|
|
|
|
|
});
|
|
|
|
|
}
|
2020-09-14 09:43:34 -04:00
|
|
|
send.done({config: update});
|
2020-11-26 23:18:28 -05:00
|
|
|
},
|
|
|
|
|
|
2022-02-24 13:47:26 -05:00
|
|
|
image2mesh(info, send) {
|
2022-02-25 23:49:51 -05:00
|
|
|
let { device } = info.settings;
|
|
|
|
|
load.PNG.parse(info.png, {
|
|
|
|
|
outWidth: device.bedDepth,
|
|
|
|
|
outHeight: device.bedWidth,
|
|
|
|
|
inv_image: info.inv_image,
|
|
|
|
|
inv_alpha: info.inv_alpha,
|
|
|
|
|
border: info.border,
|
|
|
|
|
blur: info.blur,
|
|
|
|
|
base: info.base,
|
|
|
|
|
progress(progress) { send.data({ progress }) },
|
|
|
|
|
done(vertices) { send.done({ vertices }, [ vertices.buffer ])}
|
2020-11-26 23:18:28 -05:00
|
|
|
});
|
2021-02-01 16:39:22 -05:00
|
|
|
},
|
|
|
|
|
|
2022-02-24 13:47:26 -05:00
|
|
|
zip(data, send) {
|
2021-02-01 16:39:22 -05:00
|
|
|
let { files } = data;
|
|
|
|
|
let zip = new JSZip();
|
|
|
|
|
for (let file of files) {
|
|
|
|
|
zip.file(file.name, file.data);
|
|
|
|
|
}
|
|
|
|
|
zip.generateAsync({
|
|
|
|
|
type: "uint8array",
|
|
|
|
|
compression: "DEFLATE",
|
2021-08-29 20:48:01 -04:00
|
|
|
compressionOptions: { level: 6 },
|
2021-02-01 16:39:22 -05:00
|
|
|
streamFiles: true
|
|
|
|
|
}, progress => {
|
|
|
|
|
send.data(progress);
|
|
|
|
|
}).then(output => {
|
|
|
|
|
send.done(output);
|
|
|
|
|
});
|
2021-07-07 21:09:34 -04:00
|
|
|
},
|
|
|
|
|
|
2022-02-24 13:47:26 -05:00
|
|
|
wasm(data, send) {
|
2021-07-07 21:09:34 -04:00
|
|
|
if (data.enable) {
|
2022-02-20 14:31:27 -05:00
|
|
|
wasm_ctrl.enable();
|
2021-07-07 21:09:34 -04:00
|
|
|
} else {
|
2022-02-20 14:31:27 -05:00
|
|
|
wasm_ctrl.disable();
|
2021-07-07 21:09:34 -04:00
|
|
|
}
|
|
|
|
|
minwork.wasm(data.enable);
|
|
|
|
|
send.done({ wasm: data });
|
2020-09-14 09:43:34 -04:00
|
|
|
}
|
2020-02-29 20:13:49 -05:00
|
|
|
};
|
|
|
|
|
|
2021-05-05 19:11:05 -04:00
|
|
|
dispatch.send = (msg) => {
|
|
|
|
|
// console.log('worker send', msg);
|
|
|
|
|
self.postMessage(msg);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
dispatch.onmessage = self.onmessage = function(e) {
|
|
|
|
|
// console.log('worker recv', e);
|
2020-11-03 11:19:13 -05:00
|
|
|
let time_recv = time(),
|
2021-05-05 19:11:05 -04:00
|
|
|
msg = e.data || {},
|
2020-02-29 20:13:49 -05:00
|
|
|
run = dispatch[msg.task],
|
|
|
|
|
send = {
|
|
|
|
|
data : function(data,direct) {
|
2020-11-26 08:48:19 -05:00
|
|
|
// if (direct && direct.length) {
|
|
|
|
|
// console.log({
|
|
|
|
|
// zeros: direct.length,
|
|
|
|
|
// sz:direct.map(z => z.byteLength).reduce((a,v) => a+v)
|
|
|
|
|
// });
|
|
|
|
|
// }
|
2021-05-05 19:11:05 -04:00
|
|
|
dispatch.send({
|
2020-02-29 20:13:49 -05:00
|
|
|
seq: msg.seq,
|
|
|
|
|
task: msg.task,
|
|
|
|
|
done: false,
|
|
|
|
|
data: data
|
2020-11-26 08:48:19 -05:00
|
|
|
}, direct);
|
2020-02-29 20:13:49 -05:00
|
|
|
},
|
|
|
|
|
done : function(data,direct) {
|
2020-11-26 08:48:19 -05:00
|
|
|
// if (direct && direct.length) {
|
|
|
|
|
// console.log({
|
|
|
|
|
// zeros: direct.length,
|
|
|
|
|
// sz:direct.map(z => z.byteLength).reduce((a,v) => a+v)
|
|
|
|
|
// });
|
|
|
|
|
// }
|
2021-05-05 19:11:05 -04:00
|
|
|
dispatch.send({
|
2020-02-29 20:13:49 -05:00
|
|
|
seq: msg.seq,
|
|
|
|
|
task: msg.task,
|
|
|
|
|
done: true,
|
|
|
|
|
data: data
|
2020-11-26 08:48:19 -05:00
|
|
|
}, direct);
|
2020-02-29 20:13:49 -05:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (run) {
|
2021-02-03 20:52:25 -05:00
|
|
|
try {
|
|
|
|
|
let time_xfer = (time_recv - msg.time),
|
|
|
|
|
output = run(msg.data, send),
|
|
|
|
|
time_send = time(),
|
|
|
|
|
time_proc = time_send - time_recv;
|
|
|
|
|
|
2021-05-05 19:11:05 -04:00
|
|
|
if (output) dispatch.send({
|
2021-02-03 20:52:25 -05:00
|
|
|
seq: msg.seq,
|
|
|
|
|
task: msg.task,
|
|
|
|
|
time_send: time_xfer,
|
|
|
|
|
time_proc: time_proc,
|
|
|
|
|
// replaced on reply side
|
|
|
|
|
time_recv: time(),
|
|
|
|
|
data: output
|
|
|
|
|
});
|
|
|
|
|
} catch (wrkerr) {
|
2021-02-09 19:08:28 -05:00
|
|
|
// console.log(wrkerr);
|
|
|
|
|
console.trace(wrkerr.stack);
|
2021-02-03 20:52:25 -05:00
|
|
|
send.done({error: wrkerr.toString()});
|
|
|
|
|
}
|
2020-02-29 20:13:49 -05:00
|
|
|
} else {
|
2021-05-05 19:11:05 -04:00
|
|
|
console.log({worker_unhandled: e, msg, fn: dispatch[msg.task]});
|
2020-02-29 20:13:49 -05:00
|
|
|
}
|
|
|
|
|
};
|
2020-06-16 11:08:50 -04:00
|
|
|
|
2022-02-22 00:05:29 -05:00
|
|
|
});
|
|
|
|
|
|
2020-11-03 11:19:13 -05:00
|
|
|
// load kiri modules
|
2022-02-22 00:05:29 -05:00
|
|
|
// kiri.load_exec(dispatch);
|