From 9aae90880ce213a591c97512b61cdff19e3a7182 Mon Sep 17 00:00:00 2001 From: Stewart Allen Date: Sat, 6 Jul 2024 15:40:58 -0400 Subject: [PATCH] comments and tweaks on belt slicing --- src/kiri-mode/fdm/client.js | 7 +++--- src/kiri-mode/fdm/prepare.js | 23 +++++++++--------- src/kiri-mode/fdm/slice.js | 3 +++ src/kiri-run/worker.js | 9 ++----- src/kiri/client.js | 46 ++++++++++++++++-------------------- src/kiri/function.js | 17 +++++++++---- 6 files changed, 53 insertions(+), 52 deletions(-) diff --git a/src/kiri-mode/fdm/client.js b/src/kiri-mode/fdm/client.js index dfcdb4f7..e640ab82 100644 --- a/src/kiri-mode/fdm/client.js +++ b/src/kiri-mode/fdm/client.js @@ -258,6 +258,7 @@ FDM.init = function(kiri, api) { updateVisiblity(); // synth support widget for each widget group + // iow, create support meshes based on support widget annotation let synth = []; for (let group of kiri.Widget.Groups.list()) { let merge = group.filter(w => w.sups).map(w => Object.values(w.sups)).flat(); @@ -290,10 +291,9 @@ FDM.init = function(kiri, api) { } }); api.event.on("key.esc", () => { - if (!isFdmMode) { - return; + if (isFdmMode) { + func.sdone() } - func.sdone() }); api.event.on("selection.scale", () => { if (isFdmMode) { @@ -304,7 +304,6 @@ FDM.init = function(kiri, api) { api.event.on("widget.delete", widget => { if (isFdmMode) { clearRanges(); - return; } }); api.event.on("widget.duplicate", (widget, oldwidget) => { diff --git a/src/kiri-mode/fdm/prepare.js b/src/kiri-mode/fdm/prepare.js index e517d9c4..b8f9bc95 100644 --- a/src/kiri-mode/fdm/prepare.js +++ b/src/kiri-mode/fdm/prepare.js @@ -13,9 +13,9 @@ // dep: kiri-mode.fdm.driver gapp.register("kiri-mode.fdm.prepare", [], (root, exports) => { -const { base, kiri, noop } = root; -const { consts, driver, newSlice, utils, render } = kiri; -const { config, polygons, paths, util, newPoint, newPolygon, Polygon } = base; +const { base, kiri } = root; +const { consts, driver, newSlice, render } = kiri; +const { polygons, paths, util, newPoint, newPolygon, Polygon } = base; const { poly2polyEmit, tip2tipEmit } = paths; const { numOrDefault } = util; const { fillArea } = polygons; @@ -34,10 +34,10 @@ FDM.prepare = async function(widgets, settings, update) { // filter ignored widgets widgets = widgets.filter(w => !w.track.ignore && !w.meta.disabled); - let { device, process, controller, bounds, mode } = settings, - { sliceHeight, firstSliceHeight, firstLayerRate, sliceSupportOutline } = process, + let { device, process, controller, bounds } = settings, + { sliceHeight, firstSliceHeight, firstLayerRate } = process, { outputSeekrate, outputDraftShield, outputPurgeTower } = process, - { bedWidth, bedDepth, filamentSource } = device, + { bedWidth, bedDepth } = device, { lineType } = controller, printPoint = newPoint(0,0,0), print = self.worker.print = kiri.newPrint(settings, widgets), @@ -45,7 +45,6 @@ FDM.prepare = async function(widgets, settings, update) { isBelt = device.bedBelt, isThin = lineType === "line", isFlat = lineType === "flat", - isPalette = filamentSource === 'palette3', useRaft = process.outputRaft || false, firstLayerHeight = isBelt ? sliceHeight : firstSliceHeight || sliceHeight, layerno = 0, @@ -135,14 +134,14 @@ FDM.prepare = async function(widgets, settings, update) { POLY.expand(brims, nozzle * 4, 0, null, 1) : brims; function raft(height, angle, spacing, speed, extrude, outline) { - let slice = kiri.newSlice(zoff + height / 2); + let slice = newSlice(zoff + height / 2); for (let brim of rafts) { // use first point of first brim as start point if (printPoint === null) printPoint = brim.first(); let t = slice.addTop(brim); if (outline) t.traces = [ brim ]; t.inner = POLY.expand([ brim ], nozzle * -0.8, 0, null, 1); - t.fill_lines = POLY.fillArea(t.inner, angle, spacing, []); + t.fill_lines = fillArea(t.inner, angle, spacing, []); t.isRaft = true; } offset.z = slice.z; @@ -238,7 +237,7 @@ FDM.prepare = async function(widgets, settings, update) { if (!slice.supports) { continue; } - let sslice = kiri.newSlice(slice.z); + let sslice = newSlice(slice.z); sslice.extruder = process.sliceSupportNozzle; sslice.supports = slice.supports.slice(); sslice.height = slice.height; @@ -315,10 +314,10 @@ FDM.prepare = async function(widgets, settings, update) { noz = exi.extNozzle, pos = {x:blokpos.x + walkpos.x * i, y:blokpos.y + walkpos.y * i, z:0}, rect = newPolygon().centerRectangle(pos, blok.x, blok.y), - full = linesToPoly(POLY.fillArea([ + full = linesToPoly(fillArea([ newPolygon().centerRectangle(pos, blok.x - noz, blok.y - noz) ], angle, noz)), - sparse = rect.area() > 10 ? linesToPoly(POLY.fillArea([ + sparse = rect.area() > 10 ? linesToPoly(fillArea([ newPolygon().centerRectangle(pos, blok.x - noz, blok.y - noz) ], angle + 90, noz * thin)) : newPolygon(), rec = { diff --git a/src/kiri-mode/fdm/slice.js b/src/kiri-mode/fdm/slice.js index e647f7e0..c8af9701 100644 --- a/src/kiri-mode/fdm/slice.js +++ b/src/kiri-mode/fdm/slice.js @@ -596,9 +596,12 @@ FDM.slice = function(settings, widget, onupdate, ondone) { } } } + // experimental emboss text on a flat underside of an object + // in belt mode only if (process.pooch && self.OffscreenCanvas) { const { length, width, height, text } = process.pooch; let firstZ, firstI, lastZ, lastI, minX = 0, maxX = 0, maxY = 0; + // locate suitable flat spot for (let slice of slices) { let { belt } = slice; if (!belt.touch) { diff --git a/src/kiri-run/worker.js b/src/kiri-run/worker.js index da8b18b6..226140ab 100644 --- a/src/kiri-run/worker.js +++ b/src/kiri-run/worker.js @@ -271,13 +271,6 @@ kiri.worker = { cache: wcache, - decimate(data, send) { - let { vertices, options } = data; - vertices = new Float32Array(vertices), - vertices = base.pointsToVertices(base.verticesToPoints(vertices, options)); - send.done(vertices); - }, - snap(data, send) { current.snap = data; send.done(); @@ -297,6 +290,7 @@ kiri.worker = { } }, + // purge all sync data clear(data, send) { // current.snap = null; current.print = null; @@ -346,6 +340,7 @@ kiri.worker = { send.done(data.id); }, + // belt mode rotate widgets 45 degrees on X axis before slicing rotate(data, send) { let { settings } = data; if (!settings.device.bedBelt) { diff --git a/src/kiri/client.js b/src/kiri/client.js index 9f82ef98..5b6b8213 100644 --- a/src/kiri/client.js +++ b/src/kiri/client.js @@ -137,15 +137,6 @@ const client = exports({ restarting = false; }, - decimate(vertices, options, callback) { - let alert = kiri.api.show.alert('processing model', 1000); - vertices = vertices.buffer.slice(0); - send("decimate", {vertices, options}, (output) => { - kiri.api.hide.alert(alert); - callback(output); - }); - }, - config(obj) { send("config", obj, noop); }, @@ -171,27 +162,27 @@ const client = exports({ // send list of currently valid widgets send("sync", { valid: widgets.map(w => w.id) }, () => {}); // sync any widget that has changed - widgets.forEach(widget => { - if (widget.modified || !syncd[widget.id]) { - syncd[widget.id] = true; - let vertices = widget.getGeoVertices(); - send("sync", { - id: widget.id, - meta: widget.meta, - group: widget.group.id, - track: widget.track, - vertices: copy ? vertices.slice() : vertices, - position: widget.mesh.position, - }, done => { - widget.modified = false; - }); - } - }); + for (let widget of widgets.filter(w => w.modified || !syncd[w.id])) { + syncd[widget.id] = true; + let vertices = widget.getGeoVertices(); + send("sync", { + id: widget.id, + meta: widget.meta, + group: widget.group.id, + track: widget.track, + vertices: copy ? vertices.slice() : vertices, + position: widget.mesh.position, + }, done => { + widget.modified = false; + }); + } }, + // for belt / angled printing rotate(settings, callback) { send("rotate", { settings }, reply => { if (reply.group) { + // collect post-rotation data for slice/preview renders for (let widget of kiri.Widget.Groups.forid(reply.group)) { widget.belt = reply.belt; } @@ -201,6 +192,7 @@ const client = exports({ }); }, + // called once for each widget slice(settings, widget, callback) { send("slice", { id: widget.id, @@ -217,10 +209,13 @@ const client = exports({ }); }, + // called once after each widget is sliced + // performs merged actions that consider all widget slice data sliceAll(settings, callback) { send("sliceAll", { settings }, callback); }, + // turn widget slices into unified path output prepare(settings, update, done) { send("prepare", { settings }, reply => { if (reply.progress) { @@ -235,6 +230,7 @@ const client = exports({ }); }, + // convert path output to gcode or other target file output export(settings, online, ondone) { send("export", { settings }, reply => { if (reply.line) { diff --git a/src/kiri/function.js b/src/kiri/function.js index e6e72672..ffacb2d1 100644 --- a/src/kiri/function.js +++ b/src/kiri/function.js @@ -27,12 +27,15 @@ function prepareSlices(callback, scale = 1, offset = 0) { const { stacks } = kiri; if (view.is_arrange()) { + // in arrange mode, create a screenshot at the start slicing + // this can be used later by exports and rendered on some devices let snap = space.screenshot(); view.snapshot = snap.substring(snap.indexOf(",") + 1); client.snap(space.screenshot2({width: 640})); } if (mode.is_sla() && !callback) { + // in SLA mode, slice and preview are the same thing callback = preparePreview; } @@ -43,6 +46,7 @@ function prepareSlices(callback, scale = 1, offset = 0) { const mark = Date.now(); // force layout in belt mode when widget exceeds bed length + // which has the side-effect (intended) of increasing the bed size if (widgets.length && isBelt) { let doLayout = false; for (let w of widgets) { @@ -115,18 +119,23 @@ function prepareSlices(callback, scale = 1, offset = 0) { stacks.clear(); if (isBelt) { - // force re-sync in belt mode + // clearing cache causes data to be re-sent to worker client.clear(); + // we send copies of vertices in belt mode only (possibly obsolete?) + client.sync(undefined, true); + // belt op required to rotate meshes for slicing + client.rotate(settings); + } else { + // send updated vertices if widget has been rotated/scaled + client.sync(); } - client.sync(undefined, isBelt); - client.rotate(settings); function sliceNext() { if (toSlice.length) { // while more widgets to slice sliceWidget(toSlice.shift()) } else { - // once all slicing done, run sliceAll() once + // once all slicing done, run sliceAll() once for all widgets client.sliceAll(settings, sliceDone); } }