modularize print export

This commit is contained in:
Stewart Allen 2020-03-10 10:40:57 -04:00
commit c74dd09643
8 changed files with 505 additions and 445 deletions

View file

@ -50,7 +50,6 @@ self.kiri.license = exports.LICENSE;
selectedMeshes = [],
localFilterKey ='kiri-gcode-filters',
localFilters = js2o(SDB.getItem(localFilterKey)) || [],
OCTOPRINT = null,
// ---------------
widget_selected_color = 0xbbff00,
widget_deselected_color = 0xffff00,
@ -63,7 +62,6 @@ self.kiri.license = exports.LICENSE;
sliced_opacity = 0.0,
sliced_opacity_cam = 0.25,
// ---------------
printSeq = parseInt(SDB['kiri-print-seq'] || SDB['print-seq'] || "0") + 1,
renderMode = 4,
viewMode = VIEWS.ARRANGE,
layoutOnAdd = true,
@ -184,7 +182,7 @@ self.kiri.license = exports.LICENSE;
function: {
slice: prepareSlices,
print: preparePrint,
export: exportPrint,
export: function() { KIRI.export() },
clear: clearWidgetCache
},
hide: {
@ -207,6 +205,10 @@ self.kiri.license = exports.LICENSE;
movedSet : function(b) { mouseMoved = b }
},
opacity,
print: {
get: function() { return currentPrint },
clear: clearPrint
},
probe: {
local : function() { return false },
grid : function() { return false },
@ -667,401 +669,9 @@ self.kiri.license = exports.LICENSE;
updateSliderMax(true);
showSlices();
if (typeof(callback) === 'function') callback();
})
}
function exportPrint() {
if (!currentPrint) {
preparePrint(exportPrint);
return;
}
STATS.add(`ua_${getModeLower()}_export`);
switch (settings.mode) {
case 'LASER': return exportPrintLaser();
case 'FDM': return exportPrintGCODE();
case 'CAM': return exportPrintGCODE();
}
}
function exportPrintGCODE() {
if (!currentPrint) {
preparePrint(exportPrint);
return;
}
currentPrint.exportGCode(true, function(gcode) {
exportGCode(gcode);
});
}
function exportPrintLaser() {
if (!currentPrint) {
preparePrint(exportPrintLaser);
return;
}
var filename = "laser-"+(new Date().getTime().toString(36));
function download_svg() {
saveAs(new Blob(
[currentPrint.exportSVG($('print-color').value)],
{type:"application/octet-stream"}),
$('print-filename').value + ".svg");
}
function download_dxf() {
saveAs(new Blob(
[currentPrint.exportDXF()],
{type:"application/octet-stream"}),
$('print-filename').value + ".dxf");
}
function download_gcode() {
saveAs(new Blob(
[currentPrint.exportLaserGCode()],
{type:"application/octet-stream"}),
$('print-filename').value + ".gcode");
}
ajax("/kiri/output-laser.html", function(html) {
let segments = 0;
currentPrint.output.forEach(layer => { segments += layer.length });
UI.print.innerHTML = html;
$('print-filename').value = filename;
$('print-lines').value = segments;
$('print-close').onclick = hideModal;
$('print-svg').onclick = download_svg;
$('print-dxf').onclick = download_dxf;
$('print-lg').onclick = download_gcode;
showModal('print');
});
}
function exportGCode(gcode) {
SDB['kiri-print-seq'] = printSeq++;
var pre = (MODE === MODES.CAM ? "cnc-" : "print-") + (printSeq.toString().padStart(3,"0")),
filename = pre,// + (new Date().getTime().toString(36)),
fileext = settings.device.gcodeFExt || "gcode",
codeproc = settings.device.gcodeProc,
octo_host,
octo_apik,
grid_host,
grid_apik,
grid_target,
grid_targets = {},
grid_local,
grid_uuid;
// run gcode post processor function (when supplied and valid)
if (codeproc && self[codeproc]) {
gcode = self[codeproc](gcode);
}
function getBlob() {
return new Blob(
[gcode],
{type:"application/octet-stream"});
}
function sendto_octoprint() {
if (!(octo_host && octo_apik)) return;
var form = new FormData(),
ajax = new XMLHttpRequest(),
host = octo_host.value.toLowerCase(),
apik = octo_apik.value;
if (host.indexOf("http") !== 0) {
alert2("host missing protocol (http:// or https://)");
return;
if (typeof(callback) === 'function') {
callback();
}
if (SECURE && !isSecure(host)) {
alert2("host must begin with 'https' on a secure site");
return;
}
SDB['octo-host'] = host.trim();
SDB['octo-apik'] = apik.trim();
filename = $('print-filename').value;
form.append("file", getBlob(), filename+"."+fileext);
ajax.onreadystatechange = function() {
if (ajax.readyState === 4) {
var status = ajax.status;
STATS.add(`ua_${getModeLower()}_print_octo_${status}`);
if (status >= 200 && status < 300) {
hideModal();
} else {
alert2("octoprint error\nstatus: "+status+"\nmessage: "+ajax.responseText);
}
}
};
ajax.upload.addEventListener('progress', function(evt) {
setProgress(Math.ceil(evt.loaded/evt.total), "sending");
});
ajax.open("POST", host+"/api/files/local");
ajax.setRequestHeader("X-Api-Key", apik);
ajax.send(form);
}
function gridhost_tracker(host,key) {
ajax(host+"/api/check?key="+key, function(data) {
data = js2o(data);
DBUG.log(data);
if (!(data.done || data.error)) {
setTimeout(function() { gridhost_tracker(host,key) }, 1000);
}
});
}
function gridlocal_probe(ev, devs) {
if (ev && ev.code !== 'Enter') return;
if (!devs && API.probe.local(gridlocal_probe)) return;
grid_local = devs;
let html = [];
for (let uuid in devs) {
let dev = devs[uuid];
html.push(`<option id="gl-${uuid}" value="${uuid}">${dev.stat.device.name}</option>`);
}
$('grid-local').innerHTML = html.join('\n');
}
function sendto_gridlocal() {
let uuid = $('grid-local').value;
let dev = grid_local[uuid];
if (dev) {
let file = $('print-filename').value;
fetch(
`/api/grid_send?uuid=${uuid}&file=${encodeURIComponent(file + "." + fileext)}`,
{method: "POST", body: gcode}
)
.then(t => t.text())
.then(t => {
STATS.add(`ua_${getModeLower()}_print_local_ok`);
console.log({grid_spool_said: t});
})
.catch(e => {
STATS.add(`ua_${getModeLower()}_print_local_err`);
console.log({grid_local_spool_error: e});
})
.finally(() => {
hideModal();
});
}
}
function admin_gridlocal() {
let dev = grid_local[$('grid-local').value];
if (dev && dev.stat && dev.stat.device) {
let dsd = dev.stat.device;
window.open(`http://${dsd.addr[0]}:${dsd.port || 4080}`, "_grid_admin");
}
}
function gridhost_probe(ev, host) {
if (ev && ev.code !== 'Enter') return;
if (!(grid_host && grid_apik)) return;
if (host) grid_host.value = host;
var xhtr = new XMLHttpRequest(),
host = grid_host.value,
apik = grid_apik.value,
target = grid_target.value;
if (!apik) $('gpapik').style.display = 'none';
if (!host && API.probe.grid(gridhost_probe)) return;
if (!host) return;
xhtr.onreadystatechange = function() {
if (xhtr.readyState === 4) {
if (xhtr.status >= 200 && xhtr.status < 300) {
SDB['grid-host'] = host;
SDB['grid-apik'] = apik;
var res = JSON.parse(xhtr.responseText);
var sel = false;
var match = false;
var first = null;
var html = [];
grid_targets = {};
for (var key in res) {
first = first || key;
if (!SDB['grid-target']) {
SDB['grid-target'] = key;
sel = true;
} else {
sel = SDB['grid-target'] === key;
}
match = match || sel;
grid_targets[html.length] = key;
html.push(
"<option id='gpo-'" + key + " value='" +key + "'" +
(sel ? " selected" : "") +
">" +
(res[key].comment || key) +
"</option>"
);
}
if (!match) {
SDB['grid-target'] = first;
}
grid_target.innerHTML = html.join('\n');
} else if (xhtr.status === 401) {
$('gpapik').style.display = '';
} else {
SDB.removeItem('grid-host');
SDB.removeItem('grid-apik');
console.log("invalid grid:host url");
}
}
};
xhtr.open("GET", host + "/api/active?key=" + apik);
xhtr.send();
}
function sendto_gridhost() {
if (!(grid_host && grid_apik)) return;
var xhtr = new XMLHttpRequest(),
host = grid_host.value,
apik = grid_apik.value,
target = SDB['grid-target'] || '';
if (target === '') {
alert2('invalid or missing target');
return;
}
if (host.indexOf("http") !== 0) {
alert2("host missing protocol (http:// or https://)");
return;
}
if (host.indexOf("://") < 0) {
alert2("host:port malformed");
return;
}
if (SECURE && !isSecure(host)) {
alert2("host must begin with 'https' on a secure site");
return;
}
SDB['grid-host'] = host.trim();
SDB['grid-apik'] = apik.trim();
xhtr.onreadystatechange = function() {
if (xhtr.readyState === 4) {
var status = xhtr.status;
STATS.add(`ua_${getModeLower()}_print_grid_${status}`);
if (status >= 200 && status < 300) {
var json = js2o(xhtr.responseText);
gridhost_tracker(host,json.key);
ajax(host+"/api/wait?key="+json.key, function(data) {
data = js2o(data);
DBUG.log(data);
alert2("print to "+target+": "+data.status, 600);
});
} else {
alert2("grid:host error\nstatus: "+status+"\nmessage: "+xhtr.responseText, 10000);
}
setProgress(0);
}
};
xhtr.upload.addEventListener('progress', function(evt) {
setProgress(Math.ceil(evt.loaded/evt.total), "sending");
});
filename = $('print-filename').value;
xhtr.open("POST",
host + "/api/print?" +
"filename=" + filename +
"&target=" + target +
"&key=" + apik +
"&time=" + Math.round(currentPrint.time) +
"&length=" + Math.round(currentPrint.distance) +
"&image=" + filename
);
xhtr.setRequestHeader("Content-Type", "text/plain");
xhtr.send(screenShot ? [gcode,screenShot].join("\0") : gcode);
hideModal();
}
function download() {
filename = $('print-filename').value;
saveAs(getBlob(), filename + "." + fileext);
}
function pad(v) {
v = v.toString();
return v.length < 2 ? '0' + v : v;
}
function calcWeight() {
try {
$('print-weight').value = (
UTIL.round((Math.PI * UTIL.sqr(currentPrint.settings.device.filamentSize/2)) * currentPrint.distance * 1.25 / 1000, 2)
);
} catch (e) { }
}
function calcTime() {
var floor = Math.floor,
time = floor(currentPrint.time),
hours = floor(time / 3600),
newtime = time - hours * 3600,
mins = floor(newtime / 60),
secs = newtime - mins * 60;
$('mill-time').value = $('print-time').value = [pad(hours),pad(mins),pad(secs)].join(':');
}
ajax("/kiri/output-gcode.html", function(html) {
UI.print.innerHTML = html;
$('print-close').onclick = hideModal;
$('print-download').onclick = download;
$('print-octoprint').onclick = sendto_octoprint;
$('print-gridhost').onclick = sendto_gridhost;
$('print-gridlocal').onclick = sendto_gridlocal;
$('admin-gridlocal').onclick = admin_gridlocal;
$('print-filament-row').style.display = MODE === MODES.FDM ? '' : 'none';
$('mill-info').style.display = MODE === MODES.CAM ? '' : 'none';
$('print-filename').value = filename;
$('print-filesize').value = currentPrint.bytes;
$('print-filament').value = Math.round(currentPrint.distance);
$('grid-host').onkeyup = gridhost_probe;
$('grid-apik').onkeyup = gridhost_probe;
calcTime();
if (MODE === MODES.FDM) calcWeight();
octo_host = $('octo-host');
octo_apik = $('octo-apik');
if (MODE === MODES.CAM) {
$('send-to-octoprint').style.display = 'none';
} else {
$('send-to-octoprint').style.display = '';
}
if (OCTOPRINT) {
$('ophost').style.display = 'none';
$('opapik').style.display = 'none';
$('ophint').style.display = 'none';
$('send-to-gridhost').style.display = 'none';
}
octo_host.value = SDB['octo-host'] || '';
octo_apik.value = SDB['octo-apik'] || '';
grid_host = $('grid-host');
grid_apik = $('grid-apik');
grid_target = $('grid-target');
grid_target.onchange = function(ev) {
SDB['grid-target'] = grid_targets[grid_target.selectedIndex];
};
grid_host.value = SDB['grid-host'] || '';
grid_apik.value = SDB['grid-apik'] || '';
gridhost_probe();
gridlocal_probe();
showModal('print');
});
}
@ -1154,7 +764,9 @@ self.kiri.license = exports.LICENSE;
setProgress(0);
showSlices(preserveLayer);
setOpacity(settings.mode === 'CAM' ? sliced_opacity_cam : sliced_opacity);
if (callback && typeof callback === 'function') callback();
if (callback && typeof callback === 'function') {
callback();
}
}
// update slider window
updateDialogLeft();
@ -1753,22 +1365,6 @@ self.kiri.license = exports.LICENSE;
SDB.setItem('ws-settings', JSON.stringify(settings));
}
function saveWorkspace() {
saveSettings();
var newWidgets = [],
oldWidgets = js2o(SDB.getItem('ws-widgets'), []);
forAllWidgets(function(widget) {
newWidgets.push(widget.id);
oldWidgets.remove(widget.id);
widget.saveState();
});
SDB.setItem('ws-widgets', o2js(newWidgets));
oldWidgets.forEach(function(wid) {
Widget.deleteFromState(wid);
});
alert2("workspace saved", 1);
}
function loadFiles(files) {
for (var i=0; i<files.length; i++) {
var reader = new FileReader(),
@ -1803,16 +1399,20 @@ self.kiri.license = exports.LICENSE;
// alert2("drag/drop STL files onto platform to import\nreload page to return to last saved state");
}
// kiri api
function getSettings() {
return settings;
}
// kiri api
function putSettings(newset) {
settings = newset;
saveSettings()
restoreWorkspace(null, true);
function saveWorkspace() {
saveSettings();
var newWidgets = [],
oldWidgets = js2o(SDB.getItem('ws-widgets'), []);
forAllWidgets(function(widget) {
newWidgets.push(widget.id);
oldWidgets.remove(widget.id);
widget.saveState();
});
SDB.setItem('ws-widgets', o2js(newWidgets));
oldWidgets.forEach(function(wid) {
Widget.deleteFromState(wid);
});
alert2("workspace saved", 1);
}
function restoreWorkspace(ondone, skipwidgets) {
@ -1917,6 +1517,16 @@ self.kiri.license = exports.LICENSE;
showDialog("catalog");
}
function getSettings() {
return settings;
}
function putSettings(newset) {
settings = newset;
saveSettings()
restoreWorkspace(null, true);
}
function editNamedSetting(e) {
var mode = getMode(),
name = e.target.getAttribute("name"),