2020-04-13 17:42:40 -04:00
|
|
|
/** Copyright 2014-2019 Stewart Allen -- All Rights Reserved */
|
|
|
|
|
|
|
|
|
|
"use strict";
|
|
|
|
|
|
|
|
|
|
let gs_kiri_sla = exports;
|
|
|
|
|
|
|
|
|
|
(function() {
|
|
|
|
|
|
|
|
|
|
if (!self.kiri) self.kiri = { };
|
|
|
|
|
if (!self.kiri.driver) self.kiri.driver = { };
|
|
|
|
|
if (self.kiri.driver.SLA) return;
|
|
|
|
|
|
|
|
|
|
let KIRI = self.kiri,
|
|
|
|
|
BASE = self.base,
|
|
|
|
|
DBUG = BASE.debug,
|
|
|
|
|
UTIL = BASE.util,
|
|
|
|
|
CONF = BASE.config,
|
|
|
|
|
POLY = BASE.polygons,
|
|
|
|
|
SLA = KIRI.driver.SLA = {
|
|
|
|
|
slice,
|
|
|
|
|
printSetup,
|
2020-04-13 21:52:05 -04:00
|
|
|
printExport,
|
|
|
|
|
printDownload,
|
|
|
|
|
printRender
|
2020-04-13 17:42:40 -04:00
|
|
|
},
|
|
|
|
|
SLICER = KIRI.slicer,
|
|
|
|
|
newPoint = BASE.newPoint;
|
|
|
|
|
|
|
|
|
|
/**
|
2020-04-13 21:52:05 -04:00
|
|
|
* DRIVER SLICE CONTRACT - runs in worker
|
2020-04-13 17:42:40 -04:00
|
|
|
*
|
|
|
|
|
* @param {Object} settings
|
|
|
|
|
* @param {Widget} Widget
|
|
|
|
|
* @param {Function} onupdate (called with % complete and optional message)
|
|
|
|
|
* @param {Function} ondone (called when complete with an array of Slice objects)
|
|
|
|
|
*/
|
|
|
|
|
function slice(settings, widget, onupdate, ondone) {
|
|
|
|
|
let process = settings.process,
|
|
|
|
|
device = settings.device;
|
|
|
|
|
|
2020-04-13 19:28:17 -04:00
|
|
|
// calculate % complete and call onupdate()
|
|
|
|
|
function doupdate(slices, index, from, to, msg) {
|
|
|
|
|
onupdate(0.5 + (from + ((index / slices.length) * (to - from))) * 0.5, msg);
|
|
|
|
|
}
|
2020-04-13 17:42:40 -04:00
|
|
|
|
2020-04-13 19:28:17 -04:00
|
|
|
// for each slice, performe a function and call doupdate()
|
|
|
|
|
function forSlices(slices, from, to, fn, msg) {
|
|
|
|
|
slices.forEach(function(slice) {
|
|
|
|
|
fn(slice);
|
|
|
|
|
doupdate(slices, slice.index, from, to, msg)
|
|
|
|
|
});
|
2020-04-13 17:42:40 -04:00
|
|
|
}
|
|
|
|
|
|
2020-04-13 19:28:17 -04:00
|
|
|
SLICER.sliceWidget(widget, {
|
|
|
|
|
height: process.slaSlice || 0.05
|
|
|
|
|
}, function(slices) {
|
2020-04-13 17:42:40 -04:00
|
|
|
widget.slices = slices;
|
2020-04-13 19:28:17 -04:00
|
|
|
// reset for solids and support projections
|
|
|
|
|
slices.forEach(function(slice) {
|
|
|
|
|
slice.invalidateFill();
|
|
|
|
|
slice.invalidateSolids();
|
|
|
|
|
slice.invalidateSupports();
|
|
|
|
|
slice.isSolidFill = false;
|
|
|
|
|
});
|
|
|
|
|
forSlices(slices, 0.0, 0.2, (slice) => {
|
|
|
|
|
slice.doShells(1, 0);
|
|
|
|
|
// slice.tops.forEach(top => { top.solids = [] });
|
|
|
|
|
}, "slice");
|
|
|
|
|
forSlices(slices, 0.2, 0.4, (slice) => {
|
|
|
|
|
slice.doDiff(0.00001, 0.005);
|
|
|
|
|
}, "delta");
|
|
|
|
|
forSlices(slices, 0.4, 0.5, (slice) => {
|
|
|
|
|
slice.projectFlats(process.slaSolids || 5);
|
|
|
|
|
slice.projectBridges(process.slaSolids || 5);
|
|
|
|
|
}, "project");
|
|
|
|
|
forSlices(slices, 0.5, 0.6, (slice) => {
|
|
|
|
|
slice.doSolidsFill(undefined, undefined, 0.00001);
|
|
|
|
|
}, "solid");
|
2020-04-13 17:42:40 -04:00
|
|
|
ondone();
|
2020-04-13 19:28:17 -04:00
|
|
|
}, function(update) {
|
|
|
|
|
return onupdate(0.0 + update * 0.5);
|
|
|
|
|
});
|
2020-04-13 17:42:40 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
2020-04-13 21:52:05 -04:00
|
|
|
* DRIVER PRINT CONTRACT - runs in worker
|
2020-04-13 17:42:40 -04:00
|
|
|
* @param {Object} print state object
|
|
|
|
|
* @param {Function} update incremental callback
|
|
|
|
|
*/
|
|
|
|
|
function printSetup(print, update) {
|
|
|
|
|
let widgets = print.widgets,
|
|
|
|
|
settings = print.settings,
|
|
|
|
|
device = settings.device,
|
|
|
|
|
process = settings.process,
|
2020-04-14 09:26:59 -04:00
|
|
|
output = print.images = [],
|
|
|
|
|
layermax = 0,
|
|
|
|
|
width = 2560,
|
|
|
|
|
height = 1440,
|
|
|
|
|
width2 = width/2,
|
2020-04-14 09:49:41 -04:00
|
|
|
height2 = height/2,
|
|
|
|
|
scaleX = width / device.bedWidth,
|
|
|
|
|
scaleY = height / device.bedDepth;
|
2020-04-14 09:26:59 -04:00
|
|
|
|
|
|
|
|
widgets.forEach(widget => {
|
|
|
|
|
layermax = Math.max(widget.slices.length);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
for (let index=0; index < layermax; index++) {
|
|
|
|
|
let layer = new OffscreenCanvas(width,height);
|
|
|
|
|
let ctx = layer.getContext('2d');
|
|
|
|
|
ctx.fillStyle = 'rgb(200, 0, 0)';
|
|
|
|
|
let count = 0;
|
|
|
|
|
widgets.forEach(widget => {
|
|
|
|
|
let slice = widget.slices[index];
|
|
|
|
|
if (slice) {
|
|
|
|
|
slice.tops.map(top => top.poly).forEach(poly => {
|
|
|
|
|
ctx.beginPath();
|
|
|
|
|
poly.forEachPoint((p,i) => {
|
|
|
|
|
if (i === 0) {
|
2020-04-14 09:49:41 -04:00
|
|
|
ctx.moveTo(p.x * scaleX + width2, p.y * scaleY + height2);
|
2020-04-14 09:26:59 -04:00
|
|
|
} else {
|
2020-04-14 09:49:41 -04:00
|
|
|
ctx.lineTo(p.x * scaleX + width2, p.y * scaleY + height2);
|
2020-04-14 09:26:59 -04:00
|
|
|
}
|
|
|
|
|
}, true);
|
|
|
|
|
ctx.fill();
|
|
|
|
|
count++;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
output.push(ctx.getImageData(0,0,width,height));
|
|
|
|
|
update(index / layermax);
|
|
|
|
|
|
|
|
|
|
if (count === 0) break;
|
|
|
|
|
}
|
2020-04-13 17:42:40 -04:00
|
|
|
|
2020-04-13 21:52:05 -04:00
|
|
|
// in theory sends back pre-gcode print preview data
|
|
|
|
|
update(1);
|
2020-04-13 17:42:40 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
2020-04-13 21:52:05 -04:00
|
|
|
* DRIVER PRINT CONTRACT - runs in worker
|
|
|
|
|
* @param {Object} print state object
|
2020-04-14 09:26:59 -04:00
|
|
|
* @param {Function} online streaming reply
|
|
|
|
|
* @param {Function} ondone last reply
|
2020-04-13 17:42:40 -04:00
|
|
|
*/
|
2020-04-14 09:26:59 -04:00
|
|
|
function printExport(print, online, ondone) {
|
2020-04-13 21:52:05 -04:00
|
|
|
let widgets = print.widgets,
|
2020-04-13 17:42:40 -04:00
|
|
|
settings = print.settings,
|
|
|
|
|
device = settings.device,
|
|
|
|
|
process = settings.process,
|
2020-04-13 21:52:05 -04:00
|
|
|
output = print.output;
|
2020-04-13 17:42:40 -04:00
|
|
|
|
2020-04-14 09:26:59 -04:00
|
|
|
print.images.forEach(image => {
|
|
|
|
|
online(image.data, [image.data.buffer]);
|
|
|
|
|
});
|
|
|
|
|
|
2020-04-13 21:52:05 -04:00
|
|
|
// in theory converts print data from printSetup to gcode
|
2020-04-14 09:26:59 -04:00
|
|
|
// online("pex.line");
|
|
|
|
|
ondone({width:2560,height:1440});
|
2020-04-13 21:52:05 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// runs in browser main
|
|
|
|
|
function printRender(print) {
|
|
|
|
|
let widgets = print.widgets,
|
|
|
|
|
settings = print.settings,
|
|
|
|
|
device = settings.device,
|
|
|
|
|
process = settings.process;
|
|
|
|
|
|
|
|
|
|
for (let index=0; ; index++) {
|
|
|
|
|
let layer = KIRI.newLayer(print.group);
|
|
|
|
|
print.printView.push(layer);
|
|
|
|
|
|
|
|
|
|
let count = 0;
|
|
|
|
|
widgets.forEach(widget => {
|
|
|
|
|
let slice = widget.slices[index];
|
|
|
|
|
if (!slice) {
|
|
|
|
|
return;
|
2020-04-13 17:42:40 -04:00
|
|
|
}
|
2020-04-13 21:52:05 -04:00
|
|
|
slice.tops.map(top => top.poly).forEach(poly => {
|
|
|
|
|
layer.poly(poly, 0x888888, true, false);
|
|
|
|
|
count++;
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
layer.render();
|
|
|
|
|
|
|
|
|
|
if (count === 0) {
|
|
|
|
|
// TODO fix with contract for exposing layer count
|
|
|
|
|
// hack uses expected gcode output array in print object
|
|
|
|
|
print.output = print.printView;
|
|
|
|
|
break;
|
2020-04-13 17:42:40 -04:00
|
|
|
}
|
|
|
|
|
}
|
2020-04-13 21:52:05 -04:00
|
|
|
}
|
2020-04-13 17:42:40 -04:00
|
|
|
|
2020-04-13 21:52:05 -04:00
|
|
|
// runs in browser main
|
2020-04-14 09:26:59 -04:00
|
|
|
function printDownload(API, lines, done) {
|
2020-04-13 21:52:05 -04:00
|
|
|
let filename = "print-"+(new Date().getTime().toString(36));
|
|
|
|
|
|
|
|
|
|
API.ajax("/kiri/output-sla.html", html => {
|
|
|
|
|
API.ui.print.innerHTML = html;
|
|
|
|
|
$('print-filename').value = filename;
|
2020-04-14 09:26:59 -04:00
|
|
|
$('print-layers').value = lines.length;
|
2020-04-13 21:52:05 -04:00
|
|
|
$('print-close').onclick = API.modal.hide;
|
|
|
|
|
$('print-photons').onclick = download_photons;
|
|
|
|
|
$('print-photon').onclick = download_photon;
|
|
|
|
|
$('print-pws').onclick = download_pws;
|
2020-04-14 09:26:59 -04:00
|
|
|
|
|
|
|
|
let canvas = $('print-canvas');
|
|
|
|
|
let ctx = canvas.getContext('2d');
|
|
|
|
|
let img = ctx.createImageData(done.width, done.height);
|
2020-04-14 09:49:41 -04:00
|
|
|
let imgDV = new DataView(img.data.buffer);
|
|
|
|
|
|
|
|
|
|
// canvas.setAttribute('width', done.width/2);
|
|
|
|
|
// canvas.setAttribute('height', done.height/2);
|
2020-04-14 09:26:59 -04:00
|
|
|
|
|
|
|
|
let range = $('print-range');
|
|
|
|
|
range.value = 0;
|
|
|
|
|
range.min = 0;
|
2020-04-14 09:49:41 -04:00
|
|
|
range.max = lines.length - 1;
|
2020-04-14 09:26:59 -04:00
|
|
|
range.oninput = function() {
|
2020-04-14 09:49:41 -04:00
|
|
|
let lineDV = new DataView(lines[range.value].buffer);
|
|
|
|
|
for (let i=0; i<lineDV.byteLength; i+=4) {
|
|
|
|
|
imgDV.setUint32(i, lineDV.getUint32(i));
|
|
|
|
|
}
|
2020-04-14 09:26:59 -04:00
|
|
|
ctx.putImageData(img,0,0);
|
|
|
|
|
};
|
|
|
|
|
|
2020-04-13 21:52:05 -04:00
|
|
|
API.modal.show('print');
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function download_photons() { }
|
|
|
|
|
function download_photon() { }
|
|
|
|
|
function download_pws() { }
|
2020-04-13 17:42:40 -04:00
|
|
|
|
|
|
|
|
})();
|