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";
|
|
|
|
|
|
2020-11-03 11:19:13 -05:00
|
|
|
let BASE = self.base,
|
|
|
|
|
KIRI = self.kiri,
|
|
|
|
|
UTIL = BASE.util,
|
|
|
|
|
time = UTIL.time,
|
2021-04-13 09:57:56 -04:00
|
|
|
qtpi = Math.cos(Math.PI/4),
|
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 = {},
|
|
|
|
|
wcache = {};
|
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
|
|
|
|
2020-11-24 00:37:44 -05:00
|
|
|
console.log(`kiri | init work | ${KIRI.version || "rogue"}`);
|
2020-11-03 11:19:13 -05:00
|
|
|
BASE.debug.disable();
|
|
|
|
|
|
|
|
|
|
// code is running in the worker / server context
|
|
|
|
|
const dispatch =
|
|
|
|
|
KIRI.server =
|
|
|
|
|
KIRI.worker = {
|
2021-01-24 00:13:09 -05:00
|
|
|
group: wgroup,
|
|
|
|
|
|
|
|
|
|
cache: wcache,
|
2020-11-03 11:19:13 -05:00
|
|
|
|
2020-11-06 10:47:49 -05:00
|
|
|
decimate: function(data, send) {
|
|
|
|
|
let { vertices, options } = data;
|
2020-02-29 20:13:49 -05:00
|
|
|
vertices = new Float32Array(vertices),
|
2020-11-06 10:47:49 -05:00
|
|
|
vertices = BASE.pointsToVertices(BASE.verticesToPoints(vertices, options));
|
2020-02-29 20:13:49 -05:00
|
|
|
send.done(vertices);
|
|
|
|
|
},
|
|
|
|
|
|
2020-04-15 21:44:37 -04:00
|
|
|
snap: function(data, send) {
|
2020-06-16 11:08:50 -04:00
|
|
|
current.snap = data;
|
2020-04-15 21:44:37 -04:00
|
|
|
send.done();
|
|
|
|
|
},
|
|
|
|
|
|
2021-01-24 00:13:09 -05:00
|
|
|
clear: function(data, send) {
|
|
|
|
|
current.snap = null;
|
|
|
|
|
current.print = null;
|
2021-02-08 10:10:31 -05:00
|
|
|
dispatch.group = wgroup = {};
|
|
|
|
|
dispatch.cache = wcache = {};
|
|
|
|
|
send.done({ clear: true });
|
2021-01-24 00:13:09 -05:00
|
|
|
},
|
|
|
|
|
|
2020-11-30 18:01:32 -05:00
|
|
|
// widget sync
|
|
|
|
|
sync: function(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),
|
2021-01-24 00:13:09 -05:00
|
|
|
widget = KIRI.newWidget(data.id, group).loadVertices(vertices);
|
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;
|
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);
|
|
|
|
|
},
|
|
|
|
|
|
2021-01-24 00:13:09 -05:00
|
|
|
rotate: function(data, send) {
|
|
|
|
|
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-01-24 20:38:45 -05:00
|
|
|
if (z < 0.01) {
|
|
|
|
|
miny = Math.min(miny, y);
|
|
|
|
|
maxy = Math.max(maxy, y);
|
|
|
|
|
}
|
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 00:13:09 -05:00
|
|
|
|
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;
|
2021-01-21 23:45:03 -05:00
|
|
|
|
2021-04-13 09:57:56 -04:00
|
|
|
// move to accomodate anchor
|
2021-04-13 10:01:45 -04:00
|
|
|
ypos += (settings.process.firstLayerBeltLead || 0);
|
2021-04-13 09:57:56 -04:00
|
|
|
|
2021-01-24 20:38:45 -05:00
|
|
|
widget.rotate(rotation,0,0,true);
|
2021-01-25 00:48:19 -05:00
|
|
|
let minr = gmin(group);
|
|
|
|
|
widget.belt = { xpos, ypos, yadd: minr.maxy - minr.miny };
|
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
|
|
|
|
2021-01-24 00:13:09 -05:00
|
|
|
unrotate: function(data, send) {
|
|
|
|
|
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];
|
|
|
|
|
widget.groupBounds();
|
|
|
|
|
widget.rotate(-rotation,0,0,true);
|
|
|
|
|
let { dy, dz } = widget.track.center;
|
|
|
|
|
widget.groupBounds();
|
|
|
|
|
let { xpos, ypos } = widget.belt;
|
2021-04-13 09:57:56 -04:00
|
|
|
// move to accomodate anchor
|
2021-04-13 10:01:45 -04:00
|
|
|
dy -= (settings.process.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
|
|
|
|
2021-01-24 00:13:09 -05:00
|
|
|
slice: function(data, send) {
|
|
|
|
|
send.data({update:0.001, updateStatus:"slicing"});
|
2020-04-01 09:04:10 -04:00
|
|
|
|
2021-01-24 00:13:09 -05:00
|
|
|
let settings = data.settings,
|
|
|
|
|
widget = wcache[data.id],
|
|
|
|
|
last = time(),
|
|
|
|
|
now;
|
|
|
|
|
|
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,
|
|
|
|
|
});
|
|
|
|
|
slices.forEach(function(slice,index) {
|
|
|
|
|
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
|
|
|
},
|
|
|
|
|
|
2020-11-08 13:04:54 -05:00
|
|
|
prepare: function(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"});
|
|
|
|
|
|
2020-11-08 13:04:54 -05:00
|
|
|
const drivers = KIRI.driver;
|
|
|
|
|
const settings = data.settings;
|
|
|
|
|
const mode = settings.mode;
|
|
|
|
|
const driver = drivers[mode];
|
|
|
|
|
|
|
|
|
|
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) {
|
|
|
|
|
emit.layer = KIRI.codec.encode(layer, state)
|
|
|
|
|
}
|
|
|
|
|
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 || {};
|
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,
|
2020-11-26 09:10:20 -05:00
|
|
|
// output: KIRI.codec.encode(layers, state),
|
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
|
|
|
|
2020-11-08 17:35:40 -05:00
|
|
|
export: function(data, send) {
|
|
|
|
|
const mode = data.settings.mode;
|
|
|
|
|
const driver = KIRI.driver[mode];
|
|
|
|
|
|
|
|
|
|
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;
|
2020-11-08 17:35:40 -05:00
|
|
|
});
|
2020-11-08 19:38:02 -05:00
|
|
|
const { bounds, time, lines, bytes, distance, settings } = current.print;
|
2020-11-08 17:35:40 -05:00
|
|
|
|
|
|
|
|
send.done({
|
|
|
|
|
done: true,
|
2020-11-08 19:38:02 -05:00
|
|
|
output: output ? output : { bounds, time, lines, bytes, distance, settings }
|
2020-04-14 09:26:59 -04:00
|
|
|
});
|
|
|
|
|
},
|
2020-02-29 20:13:49 -05:00
|
|
|
|
2020-11-11 08:07:02 -05:00
|
|
|
colors: function(data, send) {
|
|
|
|
|
const { colors, max } = data;
|
|
|
|
|
const colorMap = {};
|
|
|
|
|
colors.forEach(color => {
|
|
|
|
|
colorMap[color] = KIRI.driver.FDM.rateToColor(color, max);
|
|
|
|
|
});
|
|
|
|
|
send.done(colorMap);
|
|
|
|
|
},
|
|
|
|
|
|
2020-11-09 13:57:18 -05:00
|
|
|
parse: function(args, send) {
|
|
|
|
|
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;
|
2021-01-24 00:13:09 -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 => {
|
2020-11-13 09:27:42 -05:00
|
|
|
const maxSpeed = print.maxSpeed;
|
2020-11-09 14:39:08 -05:00
|
|
|
const layers = KIRI.driver.FDM.prepareRender(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 });
|
2020-11-13 09:27:42 -05:00
|
|
|
send.done({parsed: KIRI.codec.encode(layers), maxSpeed});
|
2021-01-09 21:08:24 -05:00
|
|
|
}, {
|
|
|
|
|
fdm: mode === 'FDM',
|
|
|
|
|
belt: device.bedBelt
|
|
|
|
|
});
|
2020-02-29 20:13:49 -05:00
|
|
|
},
|
|
|
|
|
|
2020-11-09 23:01:41 -05:00
|
|
|
parse_svg: function(parsed, send) {
|
|
|
|
|
parsed.forEach(layer => {
|
|
|
|
|
layer.forEach(out => {
|
|
|
|
|
const { x, y, z } = out.point;
|
|
|
|
|
out.point = BASE.newPoint(x,y,z || 0);
|
|
|
|
|
});
|
|
|
|
|
});
|
2021-01-24 00:13:09 -05:00
|
|
|
const print = current.print = KIRI.newPrint(null, Object.values(wcache));
|
2020-11-09 23:01:41 -05:00
|
|
|
const layers = KIRI.driver.FDM.prepareRender(parsed, progress => {
|
|
|
|
|
send.data({ progress });
|
|
|
|
|
}, { thin: true });
|
|
|
|
|
send.done({parsed: KIRI.codec.encode(layers)});
|
|
|
|
|
},
|
|
|
|
|
|
2020-09-14 09:43:34 -04:00
|
|
|
config: function(data, send) {
|
|
|
|
|
const update = {};
|
|
|
|
|
if (data.base) {
|
|
|
|
|
update.base = data.base;
|
2020-11-03 11:19:13 -05:00
|
|
|
Object.assign(BASE.config, data.base);
|
2020-09-14 09:43:34 -04:00
|
|
|
} else {
|
|
|
|
|
console.log({invalid:data});
|
|
|
|
|
}
|
|
|
|
|
send.done({config: update});
|
2020-11-26 23:18:28 -05:00
|
|
|
},
|
|
|
|
|
|
|
|
|
|
image2mesh: function(info, send) {
|
|
|
|
|
let img = new png.PNG();
|
|
|
|
|
img.parse(info.png, (err, output) => {
|
|
|
|
|
let { width, height, data } = output;
|
|
|
|
|
let { bedDepth, bedWidth } = info.settings.device;
|
|
|
|
|
let imageAspect = height / width;
|
|
|
|
|
let deviceAspect = bedDepth / bedWidth;
|
|
|
|
|
let div = 1;
|
|
|
|
|
if (imageAspect < deviceAspect) {
|
|
|
|
|
div = width / bedWidth;
|
|
|
|
|
} else {
|
|
|
|
|
div = height / bedDepth;
|
|
|
|
|
}
|
|
|
|
|
let points =
|
|
|
|
|
width * height + // grid
|
2020-11-27 12:16:03 -05:00
|
|
|
height * 2 + 0 + // left/right
|
2020-11-27 15:03:25 -05:00
|
|
|
width * 2 + 0; // top/bottom
|
2020-11-27 12:16:03 -05:00
|
|
|
let flats =
|
|
|
|
|
((height-1) * (width-1)) + // surface
|
2020-11-27 15:03:25 -05:00
|
|
|
((height-1) * 2) + // left/right
|
|
|
|
|
((width-1) * 2) + // top/bottom
|
|
|
|
|
1; // base
|
2020-11-27 12:16:03 -05:00
|
|
|
// convert png to grayscale
|
|
|
|
|
let gray = new Uint8Array(width * height);
|
2020-12-06 15:58:28 -05:00
|
|
|
let alpha = new Uint8Array(width * height);
|
2020-11-27 12:16:03 -05:00
|
|
|
let gi = 0;
|
2020-11-27 14:42:55 -05:00
|
|
|
let invi = info.inv_image ? true : false;
|
|
|
|
|
let inva = info.inv_alpha ? true : false;
|
2020-11-27 15:03:25 -05:00
|
|
|
let border = info.border || 0;
|
2020-11-27 12:16:03 -05:00
|
|
|
for (let y = 0; y < height; y++) {
|
|
|
|
|
for (let x = 0; x < width; x++) {
|
2020-11-26 23:18:28 -05:00
|
|
|
let di = (x + width * y) * 4;
|
|
|
|
|
let r = data[di];
|
|
|
|
|
let g = data[di+1];
|
|
|
|
|
let b = data[di+2];
|
2020-11-27 14:42:55 -05:00
|
|
|
let a = data[di+3];
|
|
|
|
|
let v = ((r + g + b) / 3);
|
2020-12-06 15:58:28 -05:00
|
|
|
if (inva) a = 255 - a;
|
|
|
|
|
if (invi) v = 255 - v;
|
2020-11-27 15:03:25 -05:00
|
|
|
if (border) {
|
|
|
|
|
if (x < border || y < border || x > width-border-1 || y > height-border-1) {
|
|
|
|
|
v = 255;
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-12-06 15:58:28 -05:00
|
|
|
alpha[gi] = a;
|
|
|
|
|
gray[gi++] = v * (a / 255);
|
2020-11-27 12:16:03 -05:00
|
|
|
}
|
|
|
|
|
}
|
2020-11-27 13:06:56 -05:00
|
|
|
let blur = parseInt(info.blur || 0);
|
|
|
|
|
while (blur-- > 0) {
|
|
|
|
|
let blur = new Uint8Array(width * height);
|
|
|
|
|
for (let y = 0; y < height; y++) {
|
|
|
|
|
for (let x = 0; x < width; x++) {
|
|
|
|
|
let xl = Math.max(x-1,0);
|
|
|
|
|
let xr = Math.min(x+1,width-1);
|
|
|
|
|
let yu = Math.max(y-1,0);
|
|
|
|
|
let yd = Math.min(y+1,height-1);
|
2020-12-06 15:58:28 -05:00
|
|
|
let id = x + width * y;
|
|
|
|
|
blur[id] = ((
|
2020-11-27 13:06:56 -05:00
|
|
|
gray[xl + (width * yu)] +
|
|
|
|
|
gray[x + (width * yu)] +
|
|
|
|
|
gray[xr + (width * yu)] +
|
|
|
|
|
gray[xl + (width * y)] +
|
2020-12-06 17:19:07 -05:00
|
|
|
gray[x + (width * y)] * 8 + // self
|
2020-11-27 13:06:56 -05:00
|
|
|
gray[xr + (width * y)] +
|
|
|
|
|
gray[xl + (width * yd)] +
|
|
|
|
|
gray[x + (width * yd)] +
|
|
|
|
|
gray[xr + (width * yd)]
|
2020-12-06 17:19:07 -05:00
|
|
|
) / 16);
|
2020-11-27 13:06:56 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
gray = blur;
|
|
|
|
|
}
|
2020-11-27 12:16:03 -05:00
|
|
|
// create indexed mesh output
|
2020-11-27 14:42:55 -05:00
|
|
|
let base = parseInt(info.base || 0);
|
2020-11-27 12:16:03 -05:00
|
|
|
let verts = new Float32Array(points * 3);
|
|
|
|
|
let faces = new Uint32Array(flats * 6);
|
|
|
|
|
let w2 = width / 2;
|
|
|
|
|
let h2 = height / 2;
|
|
|
|
|
let vi = 0;
|
|
|
|
|
let ii = 0;
|
|
|
|
|
let VI = 0;
|
|
|
|
|
let VB = 0;
|
|
|
|
|
// create surface vertices & faces
|
|
|
|
|
for (let x = 0; x < width; x++) {
|
|
|
|
|
for (let y = 0; y < height; y++) {
|
2020-12-06 15:58:28 -05:00
|
|
|
let id = x + width * y;
|
|
|
|
|
let v = gray[id];
|
2020-11-27 12:16:03 -05:00
|
|
|
// create vertex @ x,y
|
2020-11-26 23:18:28 -05:00
|
|
|
verts[vi++] = (-w2 + x) / div;
|
|
|
|
|
verts[vi++] = (h2 - y) / div;
|
2020-12-06 15:58:28 -05:00
|
|
|
verts[vi++] = (v / 50) + (base * alpha[id] / 255);
|
2020-11-27 12:16:03 -05:00
|
|
|
VI++;
|
|
|
|
|
// create two surface faces on the rect between x-1,y-1 and x,y
|
2020-11-26 23:18:28 -05:00
|
|
|
if (x > 0 && y > 0) {
|
|
|
|
|
let p1 = (x - 1) * height + (y - 0);
|
|
|
|
|
let p2 = (x - 0) * height + (y - 1);
|
|
|
|
|
let p3 = (x - 0) * height + (y - 0);
|
|
|
|
|
let p4 = (x - 1) * height + (y - 1);
|
2020-11-27 12:16:03 -05:00
|
|
|
faces[ii++] = p1;
|
|
|
|
|
faces[ii++] = p3;
|
2021-02-11 18:40:17 -05:00
|
|
|
faces[ii++] = p2;
|
2020-11-27 12:16:03 -05:00
|
|
|
faces[ii++] = p1;
|
|
|
|
|
faces[ii++] = p2;
|
2021-02-11 18:40:17 -05:00
|
|
|
faces[ii++] = p4;
|
2020-11-26 23:18:28 -05:00
|
|
|
}
|
|
|
|
|
}
|
2020-11-26 23:49:44 -05:00
|
|
|
send.data({progress: x / width});
|
2020-11-26 23:18:28 -05:00
|
|
|
}
|
2020-11-27 12:16:03 -05:00
|
|
|
// create top vertices & faces
|
|
|
|
|
VB = VI;
|
|
|
|
|
let TL = VI;
|
2020-11-27 13:06:56 -05:00
|
|
|
for (let x = 0; x < width; x++) {
|
2020-11-27 12:16:03 -05:00
|
|
|
let y = 0;
|
|
|
|
|
verts[vi++] = (-w2 + x) / div;
|
|
|
|
|
verts[vi++] = (h2 - y) / div;
|
|
|
|
|
verts[vi++] = 0;
|
|
|
|
|
VI++;
|
|
|
|
|
// create two top faces on the rect x-1,0, x,z
|
|
|
|
|
if (x > 0) {
|
|
|
|
|
let p1 = VB + (x - 1);
|
|
|
|
|
let p2 = VB + (x - 0);
|
|
|
|
|
let p3 = (x * height);
|
|
|
|
|
let p4 = (x - 1) * height;
|
|
|
|
|
faces[ii++] = p1;
|
|
|
|
|
faces[ii++] = p3;
|
2020-11-28 08:21:25 -05:00
|
|
|
faces[ii++] = p2;
|
2020-11-27 12:16:03 -05:00
|
|
|
faces[ii++] = p1;
|
|
|
|
|
faces[ii++] = p4;
|
2020-11-28 08:21:25 -05:00
|
|
|
faces[ii++] = p3;
|
2020-11-27 12:16:03 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// create bottom vertices & faces
|
|
|
|
|
VB = VI;
|
|
|
|
|
let BL = VI;
|
|
|
|
|
for (let x = 0; x < width; x++) {
|
|
|
|
|
let y = height - 1;
|
|
|
|
|
verts[vi++] = (-w2 + x) / div;
|
|
|
|
|
verts[vi++] = (h2 - y) / div;
|
|
|
|
|
verts[vi++] = 0;
|
|
|
|
|
VI++;
|
|
|
|
|
// create two top faces on the rect x-1,0, x,z
|
|
|
|
|
if (x > 0) {
|
|
|
|
|
let p1 = VB + (x - 1);
|
|
|
|
|
let p2 = VB + (x - 0);
|
|
|
|
|
let p3 = (x * height) + y;
|
|
|
|
|
let p4 = (x - 1) * height + y;
|
|
|
|
|
faces[ii++] = p1;
|
|
|
|
|
faces[ii++] = p2;
|
|
|
|
|
faces[ii++] = p3;
|
|
|
|
|
faces[ii++] = p1;
|
|
|
|
|
faces[ii++] = p3;
|
|
|
|
|
faces[ii++] = p4;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// create left vertices & faces
|
|
|
|
|
VB = VI;
|
|
|
|
|
for (let y=0; y < height; y++) {
|
|
|
|
|
let x = 0;
|
|
|
|
|
verts[vi++] = (-w2 + x) / div;
|
|
|
|
|
verts[vi++] = (h2 - y) / div;
|
|
|
|
|
verts[vi++] = 0;
|
|
|
|
|
VI++;
|
|
|
|
|
// create two left faces on the rect y-1,0, y,z
|
|
|
|
|
if (y > 0) {
|
|
|
|
|
let p1 = VB + (y + 0);
|
|
|
|
|
let p2 = VB + (y - 1);
|
|
|
|
|
let p3 = 0 + (y - 1);
|
|
|
|
|
let p4 = 0 + (y - 0);
|
|
|
|
|
faces[ii++] = p1;
|
|
|
|
|
faces[ii++] = p3;
|
2020-11-28 08:21:25 -05:00
|
|
|
faces[ii++] = p2;
|
2020-11-27 12:16:03 -05:00
|
|
|
faces[ii++] = p1;
|
|
|
|
|
faces[ii++] = p4;
|
2020-11-28 08:21:25 -05:00
|
|
|
faces[ii++] = p3;
|
2020-11-27 12:16:03 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// create right vertices & faces
|
|
|
|
|
VB = VI;
|
|
|
|
|
let TR = VI;
|
|
|
|
|
for (let y=0; y < height; y++) {
|
|
|
|
|
let x = width - 1;
|
|
|
|
|
verts[vi++] = (-w2 + x) / div;
|
|
|
|
|
verts[vi++] = (h2 - y) / div;
|
|
|
|
|
verts[vi++] = 0;
|
|
|
|
|
VI++;
|
|
|
|
|
// create two right faces on the rect y-1,0, y,z
|
|
|
|
|
if (y > 0) {
|
|
|
|
|
let p1 = VB + (y + 0);
|
|
|
|
|
let p2 = VB + (y - 1);
|
|
|
|
|
let p3 = (x * height) + (y - 1);
|
|
|
|
|
let p4 = (x * height) + (y - 0);
|
|
|
|
|
faces[ii++] = p1;
|
|
|
|
|
faces[ii++] = p2;
|
|
|
|
|
faces[ii++] = p3;
|
|
|
|
|
faces[ii++] = p1;
|
|
|
|
|
faces[ii++] = p3;
|
|
|
|
|
faces[ii++] = p4;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
let BR = VI-1;
|
|
|
|
|
// create base two faces
|
|
|
|
|
faces[ii++] = TL;
|
|
|
|
|
faces[ii++] = TR;
|
|
|
|
|
faces[ii++] = BR;
|
|
|
|
|
faces[ii++] = TL;
|
|
|
|
|
faces[ii++] = BR;
|
|
|
|
|
faces[ii++] = BL;
|
|
|
|
|
// flatten for now until we support indexed mesh
|
|
|
|
|
// throughout KM (widget, storage, decimation)
|
2020-11-26 23:49:44 -05:00
|
|
|
let bigv = new Float32Array(ii * 3);
|
|
|
|
|
let bgi = 0;
|
|
|
|
|
for (let i=0; i<ii; i++) {
|
2020-11-27 12:16:03 -05:00
|
|
|
let iv = faces[i] * 3;
|
2020-11-26 23:49:44 -05:00
|
|
|
bigv[bgi++] = verts[iv];
|
|
|
|
|
bigv[bgi++] = verts[iv+1];
|
|
|
|
|
bigv[bgi++] = verts[iv+2];
|
|
|
|
|
}
|
2020-11-27 12:16:03 -05:00
|
|
|
// send.done({done: {verts, faces, bigv, vi, ii}}, [ bigv.buffer ]);
|
2020-11-26 23:49:44 -05:00
|
|
|
send.done({done: {bigv}}, [ bigv.buffer ]);
|
2020-11-26 23:18:28 -05:00
|
|
|
});
|
2021-02-01 16:39:22 -05:00
|
|
|
},
|
|
|
|
|
|
|
|
|
|
zip: function(data, send) {
|
|
|
|
|
let { files } = data;
|
|
|
|
|
let zip = new JSZip();
|
|
|
|
|
for (let file of files) {
|
|
|
|
|
zip.file(file.name, file.data);
|
|
|
|
|
}
|
|
|
|
|
zip.generateAsync({
|
|
|
|
|
type: "uint8array",
|
|
|
|
|
compression: "DEFLATE",
|
|
|
|
|
compressionOptions: { level: 3 },
|
|
|
|
|
streamFiles: true
|
|
|
|
|
}, progress => {
|
|
|
|
|
send.data(progress);
|
|
|
|
|
}).then(output => {
|
|
|
|
|
send.done(output);
|
|
|
|
|
});
|
2020-09-14 09:43:34 -04:00
|
|
|
}
|
2020-02-29 20:13:49 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
self.onmessage = function(e) {
|
2020-11-03 11:19:13 -05:00
|
|
|
let time_recv = time(),
|
2020-02-29 20:13:49 -05:00
|
|
|
msg = e.data,
|
|
|
|
|
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)
|
|
|
|
|
// });
|
|
|
|
|
// }
|
2020-02-29 20:13:49 -05:00
|
|
|
self.postMessage({
|
|
|
|
|
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)
|
|
|
|
|
// });
|
|
|
|
|
// }
|
2020-02-29 20:13:49 -05:00
|
|
|
self.postMessage({
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
if (output) self.postMessage({
|
|
|
|
|
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 {
|
|
|
|
|
console.log({kiri_msg:e});
|
|
|
|
|
}
|
|
|
|
|
};
|
2020-06-16 11:08:50 -04:00
|
|
|
|
2020-11-03 11:19:13 -05:00
|
|
|
// load kiri modules
|
|
|
|
|
KIRI.loader.forEach(fn => {
|
|
|
|
|
fn(dispatch);
|
|
|
|
|
});
|