grid-apps-cmms/js/kiri-driver-sla.js

236 lines
7.8 KiB
JavaScript
Raw Normal View History

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,
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) {
ctx.moveTo(p.x * scaleX + width2, p.y * scaleY + height2);
2020-04-14 09:26:59 -04:00
} else {
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);
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;
range.max = lines.length - 1;
2020-04-14 09:26:59 -04:00
range.oninput = function() {
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
})();