diff --git a/src/kiri/mode/fdm/work/init-work.js b/src/kiri/mode/fdm/work/init-work.js index 36686765..8e08a9ff 100644 --- a/src/kiri/mode/fdm/work/init-work.js +++ b/src/kiri/mode/fdm/work/init-work.js @@ -4,7 +4,6 @@ import { util } from '../../../../geo/base.js'; import { sliceOne, slicePost } from './slice.js'; import { fdm_prepare } from './prepare.js'; import { fdm_export } from './export.js'; -import { codec } from '../../../core/codec.js'; // noz = nozzle diameter // fil = filament diameter diff --git a/src/kiri/mode/fdm/work/prepare.js b/src/kiri/mode/fdm/work/prepare.js index 5ab342a5..f7f83f75 100644 --- a/src/kiri/mode/fdm/work/prepare.js +++ b/src/kiri/mode/fdm/work/prepare.js @@ -9,6 +9,7 @@ import { newPolygon, Polygon } from '../../../../geo/polygon.js'; import { polygons as POLY, fillArea } from '../../../../geo/polygons.js'; import { newPrint } from '../../../core/print.js'; import { newSlice } from '../../../core/slice.js'; +import { newWidget } from '../../../core/widget.js'; import { render } from '../../../core/render.js'; import { getRangeParameters } from '../core/params.js'; @@ -25,7 +26,7 @@ export async function fdm_prepare(widgets, settings, update) { widgets = widgets.filter(w => !w.track.ignore && !w.meta.disabled); let { device, process, controller, bounds } = settings, - { sliceHeight, firstSliceHeight, firstLayerRate } = process, + { sliceHeight, firstSliceHeight, firstLayerRate, sliceSupportNozzle } = process, { outputSeekrate, outputDraftShield, outputPurgeTower } = process, { bedWidth, bedDepth } = device, { lineType } = controller, @@ -85,11 +86,6 @@ export async function fdm_prepare(widgets, settings, update) { slice.tops.forEach(function(top) { tops.push(top.poly.clone()); }); - // collect support polygons - if (slice.supports) - slice.supports.forEach((support) => { - tops.push(support.clone()); - }); } if (outputDraftShield) { tops = POLY.union(tops,1,true); @@ -205,6 +201,7 @@ export async function fdm_prepare(widgets, settings, update) { preout.last().retract = true; } } + // recompute bounds for purge block offsets let bbounds = newBounds(); brims.forEach(brim => { @@ -224,13 +221,17 @@ export async function fdm_prepare(widgets, settings, update) { // find max layers (for updates) // generate list of used extruders for purge blocks - for (let widget of widgets) { - let extruder = widget.anno.extruder ?? 0; + for (let extruder of widgets.map(w => w.anno.extruder ?? 0)) { if (!extruders[extruder]) { extruders[extruder] = {}; extcount++; } } + // add support tool, if not already used + if (!extruders[sliceSupportNozzle]) { + extruders[sliceSupportNozzle] = {}; + extcount++; + } // determine size/location of purge blocks let blokw = Math.sqrt(outputPurgeTower || 0); @@ -295,10 +296,18 @@ export async function fdm_prepare(widgets, settings, update) { mkblok(blokw, blokh); // allocate tower space for extruders-1 locations + // for example, with colors, you only to swap once + // on each layer then start the next layer on the + // currently selected tool. let towers = extruders.slice(1).map((ext,i) => { return ext ? mkrec(i) : ext; }); + // console.log({ + // extruders: extruders.slice(), + // towers: towers.slice() + // }); + function linesToPoly(points) { let poly = newPolygon().setOpen(); let ping = 0; @@ -413,14 +422,31 @@ export async function fdm_prepare(widgets, settings, update) { widget.offset = offset; } + // for any widget with supports, create a new widget for them + for (let widget of widgets.slice()) { + let slices = []; + for (let slice of widget.slices) { + if (slice.supports) { + let nslice = newSlice(slice.z); + nslice.index = slice.index; + nslice.supports = slice.supports; + nslice.extruder = sliceSupportNozzle; + slices.push(nslice); + } + } + if (slices.length) { + let nwid = newWidget(null, widget.group); + nwid.support = true; + nwid.slices = slices; + nwid.offset = widget.offset; + widgets.push(nwid); + } + } + // create shuffled slice cake by z offset (slice.z + offset.z) let cake = []; let zrec = {}; for (let widget of widgets) { - // skip synthesized support widget(s) - if (!widget.mesh) { - continue; - } for (let slice of widget.slices) { slice.widget = widget; let z = (slice.z + widget.offset.z).round(2); @@ -1446,7 +1472,7 @@ function slicePrintPath(print, slice, startPoint, offset, output, opt = {}) { if (slice.tops) { out.appendAll(slice.tops); } - if (slice.supports) { + if (slice.supports && slice.widget.support) { out.appendAll(slice.supports); } diff --git a/src/kiri/mode/fdm/work/slice.js b/src/kiri/mode/fdm/work/slice.js index 76c56e71..6f751317 100644 --- a/src/kiri/mode/fdm/work/slice.js +++ b/src/kiri/mode/fdm/work/slice.js @@ -1045,6 +1045,7 @@ export function slicePost(settings, onupdate) { .sort((a,b) => { return a.slices[0].z - b.slices[0].z }); + // assign grid_id which can be embedded in gcode and // used by the controller to cancel objects during print let { bounds } = settings; @@ -1058,6 +1059,7 @@ export function slicePost(settings, onupdate) { }; widget.track.grid_id = tl.x * 100 + tl.y; } + // count extruders used let ext = []; for (let w of widgets) { @@ -1068,15 +1070,16 @@ export function slicePost(settings, onupdate) { } } } + // sort widgets by first slice Z widgets.sort((a,b) => { return a.slices[0].z - b.slices[0].z; }); - // give first widget a pass since it should have the anchor - widgets.shift(); + // remove anchor slices from other widgets (only with multi-material) if (ext.length > 1) { - for (let w of widgets) { + // give first widget a pass since it should have the anchor + for (let w of widgets.slice(1)) { w.slices = w.slices.filter(s => s.index >= 0); } }