From feca4902d12000c8b9b0c1c84111c16d5b012176 Mon Sep 17 00:00:00 2001 From: Stewart Allen Date: Sun, 8 Nov 2020 19:38:02 -0500 Subject: [PATCH] restore sla slice, preview, export --- app.js | 1 - src/kiri/export.js | 80 ++++++----------- src/kiri/layer.js | 149 -------------------------------- src/kiri/worker.js | 12 ++- src/mode/cam/export.js | 29 ++----- src/mode/fdm/export.js | 27 ++---- src/mode/fdm/slice.js | 189 +---------------------------------------- src/mode/sla/client.js | 101 +++------------------- src/mode/sla/driver.js | 13 ++- src/mode/sla/export.js | 2 +- src/mode/sla/slice.js | 15 ++-- 11 files changed, 77 insertions(+), 541 deletions(-) delete mode 100644 src/kiri/layer.js diff --git a/app.js b/app.js index bbe7a66f..8fe0841c 100644 --- a/app.js +++ b/app.js @@ -263,7 +263,6 @@ const script = { "kiri/db", "kiri/slice", "kiri/render", - // "kiri/slicer", "mode/fdm/driver", "mode/fdm/client", "mode/sla/driver", diff --git a/src/kiri/export.js b/src/kiri/export.js index 933807b1..50b1b948 100644 --- a/src/kiri/export.js +++ b/src/kiri/export.js @@ -30,7 +30,7 @@ case 'LASER': return callExport(); case 'FDM': return callExport(options); case 'CAM': return callExport(options); - case 'SLA': return exportSLA(); + case 'SLA': return callExportSLA(options); } } else { API.function.prepare(function() { @@ -40,55 +40,25 @@ } function callExport(options) { - if (isPrepared()) { - const gcode = []; - KIRI.client.export(API.conf.get(), (line) => { - gcode.push(line); - }, (output) => { - exportGCodeDialog(gcode.join('\n'), output); - }); - } else { - API.function.prepare(function() { exportPrint(options) }); - } + const gcode = []; + KIRI.client.export(API.conf.get(), (line) => { + gcode.push(line); + }, (output) => { + exportGCodeDialog(gcode.join('\n'), output); + }); } - function exportSLADialog(currentPrint) { - if (isPrepared()) { - if (currentPrint.exported) { - KIRI.driver.SLA.printDownload(currentPrint); - return; + function callExportSLA(options) { + const preview = []; + KIRI.client.export(API.conf.get(), (line) => { + API.show.progress(line.progress, "exporting"); + if (line.data) { + preview.push(line.data); } - let lines = []; - let times = {}; - let mark = Date.now(); - let seq = 1; - let segment; - currentPrint.export(true, function(line) { - if (line.message) { - if (segment && segment !== line.message) { - let now = Date.now(); - times[`${seq++}_${segment}`] = now - mark; - mark = now; - } - segment = line.message; - } - if (line.progress) { - API.show.progress(line.progress, "exporting"); - } - if (line.data) { - lines.push(line.data); - } - }, function(done) { - currentPrint.exported = true; - times[`${seq++}_${segment}`] = Date.now() - mark; - console.log(times); - API.show.progress(0); - currentPrint.sla = { lines, done, API }; - KIRI.driver.SLA.printDownload(currentPrint); - }); - } else { - API.function.prepare(exportSLA); - } + }, (output) => { + API.show.progress(0); + KIRI.driver.SLA.printDownload(preview, output, API); + }); } function exportLaserDialog(currentPrint) { @@ -132,7 +102,7 @@ }); } - function exportGCodeDialog(gcode, currentPrint) { + function exportGCodeDialog(gcode, info) { SDB['kiri-print-seq'] = printSeq++; let settings = API.conf.get(), @@ -395,8 +365,8 @@ "filename=" + filename + "&target=" + target + "&key=" + apik + - "&time=" + Math.round(currentPrint.time) + - "&length=" + Math.round(currentPrint.distance) + + "&time=" + Math.round(info.time) + + "&length=" + Math.round(info.distance) + "&image=" + filename ); xhtr.setRequestHeader("Content-Type", "text/plain"); @@ -420,9 +390,9 @@ let density = $('print-density'); $('print-weight').value = ( (Math.PI * UTIL.sqr( - currentPrint.settings.device.extruders[0].extFilament / 2 + info.settings.device.extruders[0].extFilament / 2 )) * - currentPrint.distance * + info.distance * (parseFloat(density.value) || 1.25) / 1000 ).toFixed(2); @@ -434,7 +404,7 @@ function calcTime() { let floor = Math.floor, - time = floor(currentPrint.time), + time = floor(info.time), hours = floor(time / 3600), newtime = time - hours * 3600, mins = floor(newtime / 60), @@ -454,8 +424,8 @@ $('print-filament-head').style.display = fdm ? '' : 'none'; $('print-filament-info').style.display = fdm ? '' : 'none'; $('print-filename').value = filename; - $('print-filesize').value = UTIL.comma(currentPrint.bytes); - $('print-filament').value = Math.round(currentPrint.distance); + $('print-filesize').value = UTIL.comma(info.bytes); + $('print-filament').value = Math.round(info.distance); calcTime(); if (fdm) { calcWeight(); diff --git a/src/kiri/layer.js b/src/kiri/layer.js deleted file mode 100644 index 2c7ad6e1..00000000 --- a/src/kiri/layer.js +++ /dev/null @@ -1,149 +0,0 @@ -/** Copyright Stewart Allen -- All Rights Reserved */ - -"use strict"; - -(function() { - - return; // todo remove - if (self.kiri.Layer) return; - - const KIRI = self.kiri, - POLY = self.base.polygons, - shininess = 15, - specular = 0x444444, - emissive = 0x101010, - metalness = 0, - roughness = 0.3, - newMesh = createPhongMesh; - - KIRI.Layer = Layer; - KIRI.newLayer = function() { return new Layer() }; - - function Layer(view) { } - - Layer.renderSetup = function() { - const API = KIRI.api, UC = API.uc, UI = API.ui; - const dyn = UI.dyn = {}; - const layers = $("layers"); - UC.setGroup(layers); - layers.innerHTML = ''; - return Layer; - }; - - Layer.renderSlices = function(slices) { - if (slices && slices.length) { - slices.forEach(slice => Layer.renderSlice(slice)); - } - return Layer; - }; - - Layer.renderSlice = function(slice) { - let group = new THREE.Group(); - let render = slice.render; - let view = slice.view; - - if (!render) return; - - function addPoly(vertices, poly) { - const points = poly.points, len = points.length; - for (let i=1; i { - ctrl.group.forEach(mat => { - mat.visible = ctrl.toggle.checked; - }); - }) - }; - } - const ctrl = DYN[layer]; - ctrl.toggle.checked = true; - - const { polys, lines, faces, paths } = data; - if (polys.length || lines.length) { - const mat = new THREE.LineBasicMaterial({ color: data.color.line }); - const geo = new THREE.Geometry(), vert = geo.vertices; - for (let i=0, il=polys.length; i { - const { index, faces, z } = path; - const geo = new THREE.BufferGeometry(); - geo.setAttribute('position', new THREE.BufferAttribute(faces, 3)); - geo.setIndex(index); - geo.computeFaceNormals(); - geo.computeVertexNormals(); - const mesh = new THREE.Mesh(geo, mat); - mesh.position.z = z; - mesh.castShadow = true; - mesh.receiveShadow = true; - group.add(mesh); - }); - ctrl.group.push(mat); - } - } - - slice.view.add(group); - }; - - function createStandardMesh(data) { - return new THREE.MeshStandardMaterial({ - emissive, - roughness, - metalness, - transparent: data.color.opacity != 1, - opacity: data.color.opacity, - color: data.color.face, - side: THREE.DoubleSide - }); - } - - function createPhongMesh(data) { - return new THREE.MeshPhongMaterial({ - shininess, - specular, - transparent: data.color.opacity != 1, - opacity: data.color.opacity, - color: data.color.face, - side: THREE.DoubleSide - }); - } -})(); diff --git a/src/kiri/worker.js b/src/kiri/worker.js index 5b2e06e4..01589539 100644 --- a/src/kiri/worker.js +++ b/src/kiri/worker.js @@ -138,14 +138,18 @@ KIRI.worker = { return send.done() } - const output = driver.export(current.print, function(line) { - send.data({line}); + let output; + driver.export(current.print, function(line, direct) { + send.data({line}, direct); + }, function(done) { + // SLA workaround + output = done; }); - const { bounds, time, lines, bytes, distance } = current.print; + const { bounds, time, lines, bytes, distance, settings } = current.print; send.done({ done: true, - output: { bounds, time, lines, bytes, distance } + output: output ? output : { bounds, time, lines, bytes, distance, settings } }); }, diff --git a/src/mode/cam/export.js b/src/mode/cam/export.js index d45cef6f..9e7efda8 100644 --- a/src/mode/cam/export.js +++ b/src/mode/cam/export.js @@ -24,7 +24,7 @@ /** * @returns {Array} gcode lines */ - CAM.export = function printExport(print, online) { + CAM.export = function(print, online) { let widget = print.widgets[0]; if (!widget) return; @@ -80,26 +80,17 @@ }, append; - if (online) { - append = function(line) { - if (line) { - lines++; - bytes += line.length; - output.append(line); - } - if (!line || output.length > 1000) { - online(output.join("\n")); - output = []; - } - }; - } else { - append = function(line) { - if (!line) return; - output.append(line); + append = function(line) { + if (line) { lines++; bytes += line.length; + output.append(line); } - } + if (!line || output.length > 1000) { + online(output.join("\n")); + output = []; + } + }; function filterEmit(array, consts) { if (!array) return; @@ -317,8 +308,6 @@ print.lines = lines; print.bytes = bytes + lines - 1; print.bounds = runbox; - - return online ? null : output.join("\n"); }; })(); diff --git a/src/mode/fdm/export.js b/src/mode/fdm/export.js index 686ed608..2d2f7c91 100644 --- a/src/mode/fdm/export.js +++ b/src/mode/fdm/export.js @@ -79,26 +79,17 @@ if (v >= 0) pause.push(v); }); - if (online) { - append = function(line) { - if (line) { - lines++; - bytes += line.length; - output.append(line); - } - if (!line || output.length > 1000) { - online(output.join("\n")); - output = []; - } - }; - } else { - append = function(line) { - if (!line) return; - output.append(line); + append = function(line) { + if (line) { lines++; bytes += line.length; + output.append(line); } - } + if (!line || output.length > 1000) { + online(output.join("\n")); + output = []; + } + }; function appendSub(line) { append(print.constReplace(line, subst)); @@ -375,8 +366,6 @@ print.lines = lines; print.bytes = bytes + lines - 1; print.time = time; - - return online ? null : output.join("\n"); }; })(); diff --git a/src/mode/fdm/slice.js b/src/mode/fdm/slice.js index d35b21e3..62aeb423 100644 --- a/src/mode/fdm/slice.js +++ b/src/mode/fdm/slice.js @@ -218,191 +218,6 @@ doRender(slice); }, "render"); - // let polish = spro.polishLayers; - // // experimental polishing - // if (polish) { - // let polish_layer = Math.floor(polish); - // let polish_step = Math.max(polish - polish_layer || 1, 0.25); - // widget.polish = {}; - // let px = []; - // let py = []; - // // compute x polishing slices - // SLICER.sliceWidget(widget, { - // height: nozzleSize * polish_step, - // swapX: true, - // swapY: false, - // simple: true - // }, (polish_done => { - // widget.polish.x = polish_done - // .filter(s => s.groups.length) - // .map(s => s.groups) - // .forEach(p => px.appendAll(p)); - // }), (polish_update) => { - // // console.log({polish_update}); - // }); - // // compute y polishing slices - // SLICER.sliceWidget(widget, { - // height: nozzleSize * polish_step, - // swapX: false, - // swapY: true, - // simple: true - // }, (polish_done => { - // widget.polish.y = polish_done - // .filter(s => s.groups.length) - // .map(s => s.groups) - // .forEach(p => py.appendAll(p)); - // }), (polish_update) => { - // // console.log({polish_update}); - // }); - // // apply polishing finishes to layers - // forSlices(1.0, 1.0, (slice) => { - // if (polish_layer >= 2) { - // let sai = (slice.index - polish_layer); - // if (sai % (polish_layer-1) !== 0) { - // return; - // } - // } - // if (slice.index >= polish_layer) { - // let sd = slice; - // for (let i=0; i { - // - // let polys = []; - // pa.forEach(p => { - // // rotate and test for self-intersection (points under model) - // p.ensureXY(); - // let ox = p._aligned == 'yz' ? 0.1 : 0; - // let oy = p._aligned == 'yz' ? 0 : 0.1; - // p.forEachPoint(pt => { - // let int = p.intersections( - // pt.offset(ox,oy,0), - // pt.offset(ox*10000,oy*10000,0)); - // if (int.length > 0) { - // pt._under = true; - // } - // }); - // p.restoreXY(); - // - // let lastp = undefined; - // let poly = []; - // // look for qualifying segments - // p.forEachSegment((p1, p2) => { - // // eliminate segments that projected up - // // intersect with the polygon (bottom faces) - // if (p1._under || p2._under) { - // return; - // } - // // skip when both below layer range - // if (p1.z < zb && p2.z < zb) { - // return; - // } - // // skip when both above layer range - // if (p1.z > zt && p2.z > zt) { - // return; - // } - // // skip vertical - // if (p1.x === p2.x && p1.y === p2.y) { - // return; - // } - // // skip horizontal - // // if (p1.z === p2.z) { - // // return; - // // } - // // order points lowest to highest - // let swap = false; - // if (p1.z > p2.z) { - // let t = p2; - // p2 = p1; - // p1 = t; - // swap = true; - // } - // let trimlo = false; - // let trimhi = false; - // if (p1.z < zb) { - // trimlo = true; - // } - // if (p2.z > zt) { - // trimhi = true; - // } - // let xaxis = p1.x === p2.x; - // if (xaxis) { - // p1 = BASE.newPoint(p1.y,p1.z,p1.x); - // p2 = BASE.newPoint(p2.y,p2.z,p2.x); - // } else { - // p1 = BASE.newPoint(p1.x,p1.z,p1.y); - // p2 = BASE.newPoint(p2.x,p2.z,p2.y); - // } - // let slope = BASE.newSlope(p1, p2); - // let angle = slope.angle; - // if (angle > 80 && angle < 100) { - // return; - // } - // let len = p1.distTo2D(p2); - // let np1 = p1; - // if (trimlo) { - // let zunder = zb - p1.y; - // let zover = p2.y - zb; - // let zdelt = p2.y - p1.y; - // let pct = zunder / zdelt; - // np1 = p1.follow(slope, len * pct); - // } - // if (trimhi) { - // let zunder = zt - p1.y; - // let zover = p2.y - zt; - // let zdelt = p2.y - p1.y; - // let pct = zover / zdelt; - // p2 = p2.follow(slope.invert(), len * pct); - // } - // p1 = np1; - // if (xaxis) { - // p1 = BASE.newPoint(p1.z,p1.x,p1.y); - // p2 = BASE.newPoint(p2.z,p2.x,p2.y); - // } else { - // p1 = BASE.newPoint(p1.x,p1.z,p1.y); - // p2 = BASE.newPoint(p2.x,p2.z,p2.y); - // } - // if (!lastp) { - // poly.push(p1); - // poly.push(p2); - // } else if (p1.isMergable2D(lastp)) { - // // } else if (p1.isEqual(lastp)) { - // poly.push(p2); - // cont++; - // } else if (poly.length) { - // polys.push(poly); - // poly = [p1, p2]; - // } - // lastp = p2; - // }); - // if (poly.length) { - // polys.push(poly); - // } - // }); - // pout.push(polys); - // polys = []; - // }); - // - // if (pout.length && slice.tops.length) { - // slice.tops[0].polish = { - // x: pout[0] - // .map(a => BASE.newPolygon(a).setOpen()) - // // .filter(p => p.perimeter() > nozzleSize) - // , - // y: pout[1] - // .map(a => BASE.newPolygon(a).setOpen()) - // // .filter(p => p.perimeter() > nozzleSize) - // }; - // } - // } - // }); - // } - // report slicing complete ondone(); } @@ -799,6 +614,10 @@ * 'expand' is used for top offsets in SLA mode */ function doDiff(slice, minArea, sla, fakedown) { + if (slice.index === 0 && !fakedown) { + return; + } + const top = slice, down = slice.down || (fakedown ? newSlice(-1) : null), topInner = sla ? top.topPolys() : top.topInners(), diff --git a/src/mode/sla/client.js b/src/mode/sla/client.js index 7a9f01fc..d862e3d1 100644 --- a/src/mode/sla/client.js +++ b/src/mode/sla/client.js @@ -19,98 +19,17 @@ }); }; - SLA.sliceRender = function(widget) { - // legacy debug - return; - - widget.slices.forEach(slice => { - let layers = slice.layers, - outline = layers.outline, - support = layers.support; - - if (slice.solids.unioned) { - // console.log('solid', slice.index) - slice.solids.unioned.forEach(poly => { - poly = poly.clone(true);//.move(widget.track.pos); - outline.poly(poly, 0x010101, true); - outline.solid(poly, 0x0099cc); - }); - } else if (slice.tops) { - // console.log('top', slice.index) - slice.tops.forEach(top => { - let poly = top.poly;//.clone(true).move(widget.track.pos); - outline.poly(poly, 0x010101, true, false); - outline.solid(poly, 0xfcba03); - }); - } - - if (slice.supports) { - // console.log('support', slice.index) - slice.supports.forEach(poly => { - //poly = poly.clone(true).move(widget.track.pos); - support.poly(poly, 0x010101, true, false); - support.solid(poly, 0xfcba03); - }); - } - - slice.renderDiff(); - slice.renderSolidOutlines(); - - outline.renderAll(); - support.renderAll(); - }); - } - - SLA.printRender = function(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); - let count = 0; - - widgets.forEach(widget => { - let slice = widget.slices[index]; - if (!slice) { - return; - } - count++; - let polys = slice.solids.unioned; - if (!polys) polys = slice.tops.map(t => t.poly); - if (slice.supports) polys.appendAll(slice.supports); - polys.forEach(poly => { - poly = poly.clone(true).move(widget.track.pos); - layer.poly(poly, 0x777777, true); - layer.solid(poly, 0x0099cc); - }); - }); - - layer.renderSolid(); - 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; - return; - } - - print.printView.push(layer); - } - } - - SLA.printDownload = function(print) { - let { API, lines, done } = print.sla; - let filename = `print-${new Date().getTime().toString(36)}`; + SLA.printDownload = function(preview, output, API) { + const lines = preview; + const { file, width, height } = output; + const filename = `print-${new Date().getTime().toString(36)}`; API.ajax("/kiri/output-sla.html", html => { API.ui.print.innerHTML = html; - let printset = print.settings, - process = printset.process, - device = printset.device, + let settings = API.conf.get(), + process = settings.process, + device = settings.device, print_sec = (process.slaBaseLayers * process.slaBaseOn) + (lines.length - process.slaBaseLayers) * process.slaLayerOn; @@ -148,17 +67,17 @@ switch (device.deviceName) { case 'Anycubic.Photon': download.innerText += " .photon"; - download.onclick = () => { saveFile(API, done.file, ".photon") }; + download.onclick = () => { saveFile(API, file, ".photon") }; break; case 'Anycubic.Photon.S': download.innerText += " .photons"; - download.onclick = () => { saveFile(API, done.file, ".photons") }; + download.onclick = () => { saveFile(API, file, ".photons") }; break; } let canvas = $('print-canvas'); let ctx = canvas.getContext('2d'); - let img = ctx.createImageData(done.height, done.width); + let img = ctx.createImageData(height, width); let imgDV = new DataView(img.data.buffer); let range = $('print-range'); range.value = 0; diff --git a/src/mode/sla/driver.js b/src/mode/sla/driver.js index 15da5983..f650307b 100644 --- a/src/mode/sla/driver.js +++ b/src/mode/sla/driver.js @@ -11,7 +11,7 @@ SLA = KIRI.driver.SLA = { // init, // src/mode/sla/client.js // slice, // src/mode/sla/slice.js - printSetup, + prepare, // export, // src/mode/sla/export.js // printDownload, // src/mode/sla/client.js legacy: false @@ -19,13 +19,10 @@ if (SLA.legacy) console.log("SLA Driver in Legacy Mode"); - /** - * DRIVER PRINT CONTRACT - runs in worker - * @param {Object} print state object - * @param {Function} update incremental callback - */ - function printSetup(print, update) { + // runs in worker. would usually be in src/mode/sla/prepare.js + function prepare(widgets, settings, update) { + self.worker.print = KIRI.newPrint(settings, widgets); update(1); - }; + } })(); diff --git a/src/mode/sla/export.js b/src/mode/sla/export.js index f0b0a104..a26166bb 100644 --- a/src/mode/sla/export.js +++ b/src/mode/sla/export.js @@ -15,7 +15,7 @@ * @param {Function} online streaming reply * @param {Function} ondone last reply */ - SLA.printExport = function(print, online, ondone) { + SLA.export = function(print, online, ondone) { let widgets = print.widgets, settings = print.settings, device = settings.device, diff --git a/src/mode/sla/slice.js b/src/mode/sla/slice.js index b1b326ba..55568f4e 100644 --- a/src/mode/sla/slice.js +++ b/src/mode/sla/slice.js @@ -6,6 +6,7 @@ let KIRI = self.kiri, BASE = self.base, + POLY = BASE.polygons, UTIL = BASE.util, SLA = KIRI.driver.SLA, FDM = KIRI.driver.FDM.share, @@ -120,14 +121,12 @@ slices[i-1].up = slices[i]; slices[i].down = slices[i-1]; } - // reset for solids and support projections - // slices.forEach(function(slice) { - // slice.invalidateFill(); - // slice.invalidateSolids(); - // slice.invalidateSupports(); - // slice.isSolidFill = false; - // }); let solidLayers = Math.round(process.slaShell / process.slaSlice); + // setup solid fill + slices.forEach(function(slice) { + slice.solids = []; + }); + // compute total work for progress bar work_total = [ 5, // shell 10, // diff @@ -147,7 +146,7 @@ }, "slice"); forSlices(slices, 10, (slice) => { if (slice.synth) return; - FDM.doDiff(slice, 0.000001, 0.005, true, !process.slaOpenBase); + FDM.doDiff(slice, 0.000001, true, !process.slaOpenBase); }, "delta"); if (solidLayers) { forSlices(slices, 10, (slice) => {