start synthesizing a different support style widget to allow for alternate tool use

This commit is contained in:
Stewart Allen 2026-01-09 22:08:18 -05:00
commit e565426ff6
3 changed files with 45 additions and 17 deletions

View file

@ -4,7 +4,6 @@ import { util } from '../../../../geo/base.js';
import { sliceOne, slicePost } from './slice.js'; import { sliceOne, slicePost } from './slice.js';
import { fdm_prepare } from './prepare.js'; import { fdm_prepare } from './prepare.js';
import { fdm_export } from './export.js'; import { fdm_export } from './export.js';
import { codec } from '../../../core/codec.js';
// noz = nozzle diameter // noz = nozzle diameter
// fil = filament diameter // fil = filament diameter

View file

@ -9,6 +9,7 @@ import { newPolygon, Polygon } from '../../../../geo/polygon.js';
import { polygons as POLY, fillArea } from '../../../../geo/polygons.js'; import { polygons as POLY, fillArea } from '../../../../geo/polygons.js';
import { newPrint } from '../../../core/print.js'; import { newPrint } from '../../../core/print.js';
import { newSlice } from '../../../core/slice.js'; import { newSlice } from '../../../core/slice.js';
import { newWidget } from '../../../core/widget.js';
import { render } from '../../../core/render.js'; import { render } from '../../../core/render.js';
import { getRangeParameters } from '../core/params.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); widgets = widgets.filter(w => !w.track.ignore && !w.meta.disabled);
let { device, process, controller, bounds } = settings, let { device, process, controller, bounds } = settings,
{ sliceHeight, firstSliceHeight, firstLayerRate } = process, { sliceHeight, firstSliceHeight, firstLayerRate, sliceSupportNozzle } = process,
{ outputSeekrate, outputDraftShield, outputPurgeTower } = process, { outputSeekrate, outputDraftShield, outputPurgeTower } = process,
{ bedWidth, bedDepth } = device, { bedWidth, bedDepth } = device,
{ lineType } = controller, { lineType } = controller,
@ -85,11 +86,6 @@ export async function fdm_prepare(widgets, settings, update) {
slice.tops.forEach(function(top) { slice.tops.forEach(function(top) {
tops.push(top.poly.clone()); tops.push(top.poly.clone());
}); });
// collect support polygons
if (slice.supports)
slice.supports.forEach((support) => {
tops.push(support.clone());
});
} }
if (outputDraftShield) { if (outputDraftShield) {
tops = POLY.union(tops,1,true); tops = POLY.union(tops,1,true);
@ -205,6 +201,7 @@ export async function fdm_prepare(widgets, settings, update) {
preout.last().retract = true; preout.last().retract = true;
} }
} }
// recompute bounds for purge block offsets // recompute bounds for purge block offsets
let bbounds = newBounds(); let bbounds = newBounds();
brims.forEach(brim => { brims.forEach(brim => {
@ -224,13 +221,17 @@ export async function fdm_prepare(widgets, settings, update) {
// find max layers (for updates) // find max layers (for updates)
// generate list of used extruders for purge blocks // generate list of used extruders for purge blocks
for (let widget of widgets) { for (let extruder of widgets.map(w => w.anno.extruder ?? 0)) {
let extruder = widget.anno.extruder ?? 0;
if (!extruders[extruder]) { if (!extruders[extruder]) {
extruders[extruder] = {}; extruders[extruder] = {};
extcount++; extcount++;
} }
} }
// add support tool, if not already used
if (!extruders[sliceSupportNozzle]) {
extruders[sliceSupportNozzle] = {};
extcount++;
}
// determine size/location of purge blocks // determine size/location of purge blocks
let blokw = Math.sqrt(outputPurgeTower || 0); let blokw = Math.sqrt(outputPurgeTower || 0);
@ -295,10 +296,18 @@ export async function fdm_prepare(widgets, settings, update) {
mkblok(blokw, blokh); mkblok(blokw, blokh);
// allocate tower space for extruders-1 locations // 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) => { let towers = extruders.slice(1).map((ext,i) => {
return ext ? mkrec(i) : ext; return ext ? mkrec(i) : ext;
}); });
// console.log({
// extruders: extruders.slice(),
// towers: towers.slice()
// });
function linesToPoly(points) { function linesToPoly(points) {
let poly = newPolygon().setOpen(); let poly = newPolygon().setOpen();
let ping = 0; let ping = 0;
@ -413,14 +422,31 @@ export async function fdm_prepare(widgets, settings, update) {
widget.offset = offset; 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) // create shuffled slice cake by z offset (slice.z + offset.z)
let cake = []; let cake = [];
let zrec = {}; let zrec = {};
for (let widget of widgets) { for (let widget of widgets) {
// skip synthesized support widget(s)
if (!widget.mesh) {
continue;
}
for (let slice of widget.slices) { for (let slice of widget.slices) {
slice.widget = widget; slice.widget = widget;
let z = (slice.z + widget.offset.z).round(2); let z = (slice.z + widget.offset.z).round(2);
@ -1446,7 +1472,7 @@ function slicePrintPath(print, slice, startPoint, offset, output, opt = {}) {
if (slice.tops) { if (slice.tops) {
out.appendAll(slice.tops); out.appendAll(slice.tops);
} }
if (slice.supports) { if (slice.supports && slice.widget.support) {
out.appendAll(slice.supports); out.appendAll(slice.supports);
} }

View file

@ -1045,6 +1045,7 @@ export function slicePost(settings, onupdate) {
.sort((a,b) => { .sort((a,b) => {
return a.slices[0].z - b.slices[0].z return a.slices[0].z - b.slices[0].z
}); });
// assign grid_id which can be embedded in gcode and // assign grid_id which can be embedded in gcode and
// used by the controller to cancel objects during print // used by the controller to cancel objects during print
let { bounds } = settings; let { bounds } = settings;
@ -1058,6 +1059,7 @@ export function slicePost(settings, onupdate) {
}; };
widget.track.grid_id = tl.x * 100 + tl.y; widget.track.grid_id = tl.x * 100 + tl.y;
} }
// count extruders used // count extruders used
let ext = []; let ext = [];
for (let w of widgets) { for (let w of widgets) {
@ -1068,15 +1070,16 @@ export function slicePost(settings, onupdate) {
} }
} }
} }
// sort widgets by first slice Z // sort widgets by first slice Z
widgets.sort((a,b) => { widgets.sort((a,b) => {
return a.slices[0].z - b.slices[0].z; 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) // remove anchor slices from other widgets (only with multi-material)
if (ext.length > 1) { 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); w.slices = w.slices.filter(s => s.index >= 0);
} }
} }