add volume rendering and use that for sla by default now

This commit is contained in:
Stewart Allen 2026-05-19 19:42:55 -04:00
commit 3be111af43
2 changed files with 77 additions and 10 deletions

View file

@ -212,6 +212,42 @@ export class Layers {
}
}
/**
* Add closed polygons as filled Z volumes.
* By default, the polygon Z is treated as the volume center. Pass
* { base:true } to treat polygon Z as the bottom face instead.
* @param {Polygon|Array<Polygon>} polys - Closed polygon(s), with inners preserved as voids
* @param {object} [options] - Options: {height, z, base, outline}
* @returns {Layers} This instance for chaining
*/
addZVolume(polys, options) {
const opts = options || {};
const height = opts.height || 1;
const faces = this.current.faces;
polys = Array.isArray(polys) ? polys.clone(true) : [ polys.clone(true) ];
for (let poly of polys) {
if (poly.open || poly.length < 3) {
continue;
}
let z = opts.z !== undefined ? opts.z : poly.getZ(),
zoff = opts.base ? z : z - height / 2,
volume = poly.setZ(0).extrude(height, { zadd: zoff });
faces.appendAll(volume);
if (opts.outline) {
this.addPolys([
poly.clone(true).setZ(zoff),
poly.clone(true).setZ(zoff + height)
]);
}
}
return this;
}
/**
* Add 2D polyline paths with width (usually FDM extrusion paths).
* Creates flat ribbons with vertex normals for lighting.

View file

@ -245,36 +245,67 @@ export function sla_slice(settings, widget, onupdate, ondone) {
});
};
const SLA_RENDER_THICK = true;
function doRender(widget) {
widget.slices.forEach(slice => {
const render = slice.output(), lopacity = 0.6, line = 0x010101;
const render = slice.output(),
height = slice.height || 0.05,
lopacity = SLA_RENDER_THICK ? 1 : 0.6,
line = 0x010101;
if (slice.unioned) {
slice.unioned.forEach(poly => {
poly = poly.clone(true);//.move(widget.track.pos);
render
.setLayer("layers", { line, face: 0x0099cc, lopacity })
.addAreas([poly], { outline: true });
renderSlicePoly(render, "layers", poly, {
line,
face: 0x0099cc,
lopacity,
height
});
});
} else if (slice.tops) {
slice.tops.forEach(top => {
let poly = top.poly;//.clone(true).move(widget.track.pos);
render
.setLayer("layers", { line, face: 0xfcba03, lopacity })
.addAreas([poly], { outline: true });
renderSlicePoly(render, "layers", poly, {
line,
face: 0xfcba03,
lopacity,
height
});
});
}
if (slice.supports) {
slice.supports.forEach(poly => {
render
.setLayer("support", { line, face: 0xfcba03, lopacity })
.addAreas([poly], { outline: true });
renderSlicePoly(render, "support", poly, {
line,
face: 0xfcba03,
lopacity,
height
});
});
}
});
}
function renderSlicePoly(render, layer, poly, options) {
let { line, face, lopacity, height } = options;
render.setLayer(layer, {
line,
face,
lopacity,
opacity: SLA_RENDER_THICK ? 1 : undefined
});
if (SLA_RENDER_THICK) {
render.addZVolume([poly], { height, outline: false });
} else {
render.addAreas([poly], { outline: true });
}
}
function computeSupports(widget, process, progress) {
let slices = widget.slices,
baseIndex = widget.lastraft ? widget.lastraft.index : 0,