339 lines
11 KiB
JavaScript
339 lines
11 KiB
JavaScript
/** Copyright 2014-2019 Stewart Allen -- All Rights Reserved */
|
|
|
|
if (self.window) {
|
|
|
|
if (!self.kiri) self.kiri = {};
|
|
|
|
var loc = self.location,
|
|
host = loc.hostname,
|
|
port = loc.port,
|
|
proto = loc.protocol,
|
|
pre = host.indexOf(".space") > 0 || host === "localhost" ?
|
|
proto + "//" + host + ":" + port :
|
|
"",
|
|
time = function() { return new Date().getTime() },
|
|
KIRI = self.kiri,
|
|
BASE = self.base,
|
|
seqid = 1,
|
|
running = {},
|
|
slicing = {},
|
|
worker = null;
|
|
|
|
// new moto.Ajax(function(body) {
|
|
// console.log({body:body});
|
|
// var blob = new Blob([body], {type : 'application/json'});
|
|
// worker = new Worker(URL.createObjectURL(blob));
|
|
// }).request(pre + "/code/worker.js/");
|
|
|
|
function send(fn, data, onreply, async, zerocopy) {
|
|
var seq = seqid++;
|
|
|
|
running[seq] = {fn:onreply, async:async||false};
|
|
|
|
worker.postMessage({
|
|
seq: seq,
|
|
task: fn,
|
|
time: time(),
|
|
data: data
|
|
}, zerocopy);
|
|
}
|
|
|
|
KIRI.work = {
|
|
isSlicing : function() {
|
|
var current = 0;
|
|
for (var key in slicing) { current++ }
|
|
return current > 0;
|
|
},
|
|
|
|
restart : function() {
|
|
if (worker) worker.terminate();
|
|
|
|
for (var key in slicing) {
|
|
slicing[key]({error: "cancelled slicing"});
|
|
}
|
|
slicing = {};
|
|
running = {};
|
|
|
|
worker = new Worker(pre + "/code/worker.js/" + exports.VERSION);
|
|
|
|
worker.onmessage = function(e) {
|
|
var now = time(),
|
|
reply = e.data,
|
|
record = running[reply.seq],
|
|
onreply = record.fn;
|
|
|
|
if (reply.done) delete running[reply.seq];
|
|
|
|
// calculate and replace recv time
|
|
reply.time_recv = now - reply.time_recv;
|
|
|
|
onreply(reply.data, reply);
|
|
};
|
|
},
|
|
|
|
decimate : function(vertices, callback) {
|
|
var vertices = vertices.buffer.slice(0);
|
|
send("decimate", vertices, function(output) {
|
|
callback(output);
|
|
});
|
|
},
|
|
|
|
clear : function(widget) {
|
|
send("clear", widget ? {id:widget.id} : {}, function(reply) {
|
|
// console.log({clear:reply});
|
|
});
|
|
},
|
|
|
|
slice : function(settings, widget, callback) {
|
|
var vertices = widget.getGeoVertices().buffer.slice(0);
|
|
slicing[widget.id] = callback;
|
|
send("slice", {
|
|
id: widget.id,
|
|
settings: settings,
|
|
vertices: vertices,
|
|
position: widget.mesh.position
|
|
}, function(reply) {
|
|
if (reply.done || reply.error) delete slicing[widget.id];
|
|
callback(reply);
|
|
}, null, [vertices]);
|
|
},
|
|
|
|
printSetup : function(settings, callback) {
|
|
send("printSetup", {settings:settings}, function(reply) {
|
|
callback(reply);
|
|
});
|
|
},
|
|
|
|
printGCode : function(callback) {
|
|
var gcode = [],
|
|
start = BASE.util.time();
|
|
send("printGCode", {}, function(reply) {
|
|
if (reply.line) {
|
|
gcode.push(reply.line);
|
|
} else {
|
|
if (!reply.gcode) reply.gcode = gcode.join("\n");
|
|
// console.log({printGCode:(BASE.util.time() - start)});
|
|
callback(reply);
|
|
}
|
|
});
|
|
},
|
|
|
|
sliceToGCode : function(settings, vertices, callback) {
|
|
var wid = new Date().toString(36);
|
|
var vertices = widget.getGeoVertices().buffer.slice(0);
|
|
send("slice", {settings:settings, id:wiwd, vertices:vertices, position:{x:0,y:0,z:0}}, function(reply) {
|
|
send("printSetup", {settings:settings}, function(reply) {
|
|
send("printGCode", {}, function(reply) {
|
|
callback(reply);
|
|
});
|
|
}, null, [vertices]);
|
|
callback(reply);
|
|
});
|
|
}
|
|
};
|
|
|
|
// start first worker
|
|
KIRI.work.restart();
|
|
|
|
} else {
|
|
|
|
module = { exports: {} };
|
|
|
|
var loc = self.location,
|
|
host = loc.hostname,
|
|
ver = exports.VERSION,
|
|
time = function() { return new Date().getTime() };
|
|
|
|
console.log("kiri | init work | " + ver);
|
|
|
|
// when running the server in 'web' mode, the obfuscated code is served as a
|
|
// unified ball via /code/work.js -- otherwise, map "localhost" to "debug"
|
|
// to debug unobfuscated code. if not, /js/ paths will 404.
|
|
if (host !== 'grid.space' && host !== 'debug') {
|
|
try {
|
|
[
|
|
"license","ext-n3d","ext-clip","add-array",
|
|
"add-three","geo","geo-point","geo-debug","geo-bounds",
|
|
"geo-line","geo-slope","geo-polygon","geo-polygons","geo-gyroid",
|
|
"kiri-fill","kiri-slice","kiri-slicer","kiri-driver-fdm","kiri-driver-cam",
|
|
"kiri-driver-laser","kiri-widget","kiri-pack","kiri-print","kiri-codec"
|
|
].forEach(function(scr) {
|
|
importScripts(["/js/",scr,".js","/v"+ver].join(''));
|
|
})
|
|
} catch (e) {
|
|
console.log("unable to load worker scripts. kiri is likely in debug mode.");
|
|
}
|
|
} else {
|
|
importScripts("/code/work.js/"+ver);
|
|
base.debug.disable();
|
|
}
|
|
|
|
var base = self.base,
|
|
moto = self.moto,
|
|
dbug = base.debug,
|
|
util = base.util,
|
|
kiri = self.kiri,
|
|
Widget = kiri.Widget,
|
|
currentPrint,
|
|
cache = {};
|
|
|
|
var dispatch = {
|
|
decimate: function(vertices, send) {
|
|
vertices = new Float32Array(vertices),
|
|
vertices = Widget.pointsToVertices(Widget.verticesToPoints(vertices, true));
|
|
send.done(vertices);
|
|
},
|
|
|
|
slice: function(data, send) {
|
|
var settings = data.settings,
|
|
vertices = new Float32Array(data.vertices),
|
|
position = data.position,
|
|
points = Widget.verticesToPoints(vertices);
|
|
|
|
send.data({update:0.05, updateStatus:"slicing"});
|
|
|
|
var widget = kiri.newWidget(data.id).setPoints(points),
|
|
last = util.time(),
|
|
now;
|
|
|
|
// do it here so cancel can work
|
|
cache[data.id] = widget;
|
|
|
|
// fake mesh object to satisfy printing
|
|
widget.mesh = {
|
|
widget: widget,
|
|
position: position
|
|
};
|
|
|
|
widget.slice(settings, function(error) {
|
|
if (error) {
|
|
delete cache[data.id];
|
|
send.data({error: error});
|
|
} else {
|
|
var slices = widget.slices || [];
|
|
send.data({send_start: time()});
|
|
send.data({
|
|
topo: settings.synth.sendTopo ? widget.topo : null,
|
|
stats: widget.stats,
|
|
slices: slices.length
|
|
});
|
|
slices.forEach(function(slice,index) {
|
|
send.data({index: index, slice: slice.encode()});
|
|
})
|
|
send.data({send_end: time()});
|
|
}
|
|
send.done({done: true});
|
|
// cache results for future printing
|
|
// cache[data.id] = widget;
|
|
}, function(update, msg) {
|
|
now = util.time();
|
|
if (now - last < 10 && update < 0.99) return;
|
|
// on update
|
|
send.data({update: (0.05 + update * 0.95), updateStatus: msg});
|
|
last = now;
|
|
});
|
|
},
|
|
|
|
printSetup: function(data, send) {
|
|
var widgets = [], key;
|
|
for (key in cache) {
|
|
if (cache.hasOwnProperty(key)) widgets.push(cache[key]);
|
|
}
|
|
|
|
send.data({update:0.05, updateStatus:"preview"});
|
|
|
|
currentPrint = kiri.newPrint(data.settings, widgets, data.id);
|
|
currentPrint.setup(false, function(update, msg) {
|
|
send.data({
|
|
update: update,
|
|
updateStatus: msg
|
|
});
|
|
}, function() {
|
|
send.done({
|
|
done: true,
|
|
output: currentPrint.encodeOutput()
|
|
});
|
|
});
|
|
},
|
|
|
|
printGCode: function(data, send) {
|
|
currentPrint.exportGCode(false, function(gcode) {
|
|
send.done({
|
|
gcode: gcode,
|
|
lines: currentPrint.lines,
|
|
bytes: currentPrint.bytes,
|
|
bounds: currentPrint.bounds,
|
|
distance: currentPrint.distance,
|
|
time: currentPrint.time
|
|
});
|
|
}, function(line) {
|
|
send.data({line:line});
|
|
});
|
|
},
|
|
|
|
clear: function(data, send) {
|
|
if (!data.id) {
|
|
cache = {};
|
|
currentPrint = null;
|
|
send.done({ clear: true });
|
|
return;
|
|
}
|
|
var had = cache[data.id] !== undefined;
|
|
delete cache[data.id];
|
|
send.done({
|
|
id: data.id,
|
|
had: had,
|
|
has: cache[data.id] !== undefined
|
|
});
|
|
},
|
|
};
|
|
|
|
self.onmessage = function(e) {
|
|
var time_recv = util.time(),
|
|
msg = e.data,
|
|
run = dispatch[msg.task],
|
|
send = {
|
|
data : function(data,direct) {
|
|
self.postMessage({
|
|
seq: msg.seq,
|
|
task: msg.task,
|
|
done: false,
|
|
data: data
|
|
},direct);
|
|
},
|
|
done : function(data,direct) {
|
|
self.postMessage({
|
|
seq: msg.seq,
|
|
task: msg.task,
|
|
done: true,
|
|
data: data
|
|
},direct);
|
|
}
|
|
};
|
|
|
|
if (run) {
|
|
var time_xfer = (time_recv - msg.time),
|
|
output = run(msg.data, send),
|
|
time_send = util.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: util.time(),
|
|
data: output
|
|
});
|
|
} else {
|
|
console.log({kiri_msg:e});
|
|
}
|
|
};
|
|
|
|
// catch clipper alerts and convert to console messages
|
|
self.alert = function(o) {
|
|
console.log(o);
|
|
};
|
|
|
|
}
|