add slice bridge annotations to slow print. fix thin shell depth for identifying outside faces

This commit is contained in:
Stewart Allen 2025-09-22 18:07:35 -04:00
commit 6bf15373b6
3 changed files with 50 additions and 20 deletions

View file

@ -169,13 +169,15 @@ function thin_type_3(params) {
// produce trace from outside of poly inward no more than max inset
let noodleWidth = offsetN * count;
let { noodle, remain } = top.poly.noodle(noodleWidth);
for (let n of POLY.flatten(noodle).sort((a,b) => a.depth - b.depth)) {
n.shell = [1,-1][Math.floor(n.depth / 2)];
// console.log('map', n.depth, n.shell, n.length, n.area().round(3));
}
// re-expand inner offset so fill offsets align properly with expectation
remain = POLY.offset(remain, offsetN / 2);
// render inset "noodle"
// shells.appendAll(noodle);
let debugNoodle = false;
let debugRemain = false;
let debugExtrusion = false;
@ -190,11 +192,14 @@ function thin_type_3(params) {
let lines = [];
let polys = [];
for (let i=0; i<count; i++) {
// show inset "noodle"
if (debugNoodle) polys.push(...noodle);
outer: for (let i=0; i<count; i++) {
let next = [];
// process each top level noodle separately
for (let n of noodle)
for (let n of noodle.sort((a,b) => b.area() - a.area()))
trace_noodle(
[ n ],
noodleWidth,
@ -202,7 +207,7 @@ function thin_type_3(params) {
i === 0 ? midR : midR * 1.25,
i === 0 ? maxR : maxF,
{
shell: i + 1,
shell: n.shell,
lines,
polys,
remain: next,
@ -234,9 +239,17 @@ function thin_type_3(params) {
if (polys.length) shells.push(...polys);
// create shell depth annotation that will survive serialization
top.thin_sort = traces.map(a => a.shell);
top.thin_sort = traces.map(t => t.shell);
// console.log({ this: (self.kiri_minion?.name ?? self.kiri_worker), traces });
// remove point.segment markers for codec encoding between minion and worker
for (let trace of traces) {
for (let pt of trace) {
delete pt.s;
}
}
// console.log({ traces: traces.map(t => [t.length, t.shell]) });
// console.log({ this: (self.kiri_minion?.name ?? self.kiri_worker), traces, polys });
return { traces, last: remain };
}
@ -255,6 +268,8 @@ function trace_noodle(noodle, noodleWidth, minR, midR, maxR, opt = {}) {
shell = 0
} = opt;
// increment shell with direction (1=outside, -1=inside)
let shellAdd = shell > 0 ? 1 : -1;
let sstep = 1 / shellStep;
let insets = [];
let scale = 1000;
@ -265,6 +280,7 @@ function trace_noodle(noodle, noodleWidth, minR, midR, maxR, opt = {}) {
join: ClipperLib.JoinType.jtRound,
arc: (1/dstep) * 4
});
while (inset && inset.length) {
dtotl += dstep;
for (let p of POLY.flatten(inset, [])) {
@ -434,9 +450,10 @@ function trace_noodle(noodle, noodleWidth, minR, midR, maxR, opt = {}) {
if (poly.parent) {
inner.push(nupoly);
}
let sadd = shellAdd > 0 ? (poly.parent ? shellAdd : 0) : (poly.parent ? 0 : shellAdd);
let ltpo;
let trace = [];
trace.shell = poly.parent ? shell : -shell; // shell number (- for inner/hole)
trace.shell = shell + sadd;
poly.segment(minR, true).forEachSegment((p1, p2) => {
let np1 = { x:(p1.x+p2.x)/2, y:(p1.y+p2.y)/2 };
let len = pointDist(p1, p2);
@ -548,19 +565,15 @@ function trace_noodle(noodle, noodleWidth, minR, midR, maxR, opt = {}) {
let ret = POLY.nest(
POLY.flatten(setA, [], true).map(p => {
return p.clean().simplify();
}).flat()
}).flat().map(p => {
p.shell = shell + shellAdd;
return p;
})
).filter(p => p.area() >= minArea);
remain.push(...ret);
}
// remove point.segment markers for codec encoding between minion and worker
for (let trace of traces) {
for (let pt of trace) {
delete pt.s;
}
}
return { lines, polys, remain, traces };
}

View file

@ -805,10 +805,10 @@ function slicePrintPath(print, slice, startPoint, offset, output, opt = {}) {
shellOrder = {"out-in":-1,"in-out":1,"alternate":-2}[process.sliceShellOrder] || -1,
sparseMult = process.outputSparseMult,
coastDist = process.outputCoastDist || 0,
finishSpeed = opt.speed || process.outputFinishrate,
firstShellSpeed = process.firstLayerRate,
firstFillSpeed = process.firstLayerFillRate,
firstPrintMult = process.firstLayerPrintMult,
finishSpeed = firstLayer ? firstShellSpeed : (opt.speed || process.outputFinishrate),
printSpeed = opt.speed || (firstLayer ? firstShellSpeed : process.outputFeedrate),
fillSpeed = opt.speed || opt.fillSpeed || (firstLayer ? firstFillSpeed || firstShellSpeed : process.outputFeedrate),
infillSpeed = process.sliceFillRate || opt.infillSpeed || fillSpeed || printSpeed,
@ -834,15 +834,21 @@ function slicePrintPath(print, slice, startPoint, offset, output, opt = {}) {
z = slice.z,
lastPoly;
// support alternating shell order
// support alternating shell order
if (Math.abs(shellOrder) > 1 && slice.index % 2 === 1) {
shellOrder = -shellOrder;
}
// update fill speed when solids detected
if (slice.finishSolids) {
fillSpeed = process.sliceSolidRate || finishSpeed;
}
// override: adapt bridge layer speed
if (slice.isBridgeLayer) {
fillSpeed /= 2;
}
// apply first layer extrusion multipliers
if (firstLayer) {
fillMult *= firstPrintMult;

View file

@ -498,6 +498,7 @@ export function fdm_slice(settings, widget, onupdate, ondone) {
let spaceMult = slice.index === 0 ? process.firstLayerLineMult || 1 : 1;
let isBottom = slice.index < bottomLayers;
let isTop = topLayers && slice.index > slices.length - topLayers - 1;
let isTopBase = isTop && slice.index === slices.length - topLayers;
let isDense = range.sliceFillSparse > 0.995;
let isSolid = (isBottom || ((isTop || isDense) && !vaseMode)) && !isSynth;
let solidWidth = isSolid ? range.sliceFillWidth || 1 : 0;
@ -505,6 +506,10 @@ export function fdm_slice(settings, widget, onupdate, ondone) {
let fillSpace = fillSpacing * spaceMult * solidWidth;
doSolidLayerFill(slice, fillSpace, sliceFillAngle);
}
if (isTopBase) {
// mark the first top solid supporting layer as a bridge
slice.isBridgeLayer = true;
}
sliceFillAngle = (sliceFillAngle + 90.0) % 360;
}, "solid layers");
@ -1386,7 +1391,10 @@ export function projectFlats(slice, count, expand) {
export function projectBridges(slice, count) {
if (!slice.up || !slice.bridges) return;
// these flats are marked for finishing print speed
if (slice.bridges.length) slice.finishSolids = true;
if (slice.bridges.length) {
slice.finishSolids = true;
slice.isBridgeLayer = true;
}
projectSolid(slice, slice.bridges, count, true, true);
};
@ -1746,6 +1754,9 @@ function fillSupportPolys(args) {
* @returns {*}
*/
function projectSolid(slice, polys, count, up, first) {
if (slice && !up && count === 1) {
slice.isBridgeLayer = true;
}
if (!slice || count <= 0) {
return;
}