add basic thin wall handling and default to on

This commit is contained in:
Stewart Allen 2025-09-24 23:59:31 -04:00
commit 0349ea5169
4 changed files with 44 additions and 47 deletions

View file

@ -338,7 +338,7 @@ export const conf = {
outputLoops: 0, outputLoops: 0,
outputInvertX: false, outputInvertX: false,
outputInvertY: false, outputInvertY: false,
sliceDetectThin: "off", sliceDetectThin: "basic",
sliceMinHeight: 0, sliceMinHeight: 0,
sliceAdaptive: false, sliceAdaptive: false,
zHopDistance: 0.2, zHopDistance: 0.2,

View file

@ -115,6 +115,7 @@ const LISTS = {
], ],
thin: [ thin: [
{ name: "off" }, { name: "off" },
{ name: "basic" },
{ name: "adaptive" }, { name: "adaptive" },
{ name: "legacy 1" }, { name: "legacy 1" },
{ name: "legacy 2" } { name: "legacy 2" }

View file

@ -137,18 +137,21 @@ class Print {
printSpeed = minSpeed + (printSpeed - minSpeed) * (perimeter / process.outputShortPoly); printSpeed = minSpeed + (printSpeed - minSpeed) * (perimeter / process.outputShortPoly);
} }
let lpo;
poly.forEachPoint((point, pos, points, count) => { poly.forEachPoint((point, pos, points, count) => {
if (first || point.skip) { if (point.skip && lpo?.skip) {
scope.addOutput(output, point, 0, moveSpeed, tool);
} else if (first) {
// if (point.skip) console.log({ skip: point }); // if (point.skip) console.log({ skip: point });
if (first && options.onfirst) { if (options.onfirst) {
options.onfirst(point); options.onfirst(point);
} }
// move to first output point on poly // move to first output point on poly
let out = scope.addOutput(output, point, 0, moveSpeed, tool); let out = scope.addOutput(output, point, 0, moveSpeed, tool);
if (first && options.onfirstout) { if (options.onfirstout) {
options.onfirstout(out); options.onfirstout(out);
} }
if (first) first = false; first = false;
} else { } else {
let seglen = last.distTo2D(point); let seglen = last.distTo2D(point);
if (coastDist && shellMult && perimeter - seglen <= coastDist) { if (coastDist && shellMult && perimeter - seglen <= coastDist) {
@ -159,10 +162,12 @@ class Print {
shellMult = 0; shellMult = 0;
} }
perimeter -= seglen; perimeter -= seglen;
// increase mult by % of point moved relative to nozzle radius
let multOut = shellMult + (point.moved ?? 0);
// to increase shellMult when point.inc set for collapsed points // to increase shellMult when point.inc set for collapsed points
scope.addOutput(output, point, shellMult, printSpeed, tool); scope.addOutput(output, point, multOut, printSpeed, tool);
} }
last = point; last = lpo = point;
}, close, closest.index); }, close, closest.index);
this.lastPoly = poly; this.lastPoly = poly;

View file

@ -7,6 +7,7 @@ import { polygons as POLY, fillArea } from '../../../geo/polygons.js';
import { getRangeParameters } from './driver.js'; import { getRangeParameters } from './driver.js';
import { slicer } from '../../../geo/slicer.js'; import { slicer } from '../../../geo/slicer.js';
import { Point } from '../../../geo/point.js'; import { Point } from '../../../geo/point.js';
import { Slope } from '../../../geo/slope.js';
slicer.slicePost.FDM = slicePost; slicer.slicePost.FDM = slicePost;
@ -69,7 +70,7 @@ export function slicePost(data, options) {
}; };
function offset_default(params) { function offset_default(params) {
let { z, top, count, top_poly, offset1, offsetN, wasm, last, gaps } = params; let { z, top, count, top_poly, offset1, offsetN, wasm, last, gaps, thin } = params;
let first; let first;
@ -104,16 +105,31 @@ function offset_default(params) {
} }
); );
if (!thin) {
return { last, gaps };
}
const deltaBig = 160;
const deltSmall = 20;
// look for close points on adjacent segmented polys and merge // look for close points on adjacent segmented polys and merge
let test_polys = first !== last ? [ ...first, ...last ] : last; let test_polys = first !== last ? [ ...first, ...last ] : last;
let thin_test = POLY.flatten(test_polys).map(poly => { let test_flats = POLY.flatten(test_polys);
// pre-compute segment angles
for (let poly of test_flats)
poly.forEachSegment((p0, p1) => {
p0.angle = new Slope(p0, p1);
});
// segment each poly to be tested
let thin_test = test_flats.map(poly => {
return { return {
poly, poly,
points: poly.segment(offset1, true).points points: poly.segment(offset1, true).points
} }
}); });
if (false)
for (let pi=0, pil=thin_test.length; pi<pil; pi++) { for (let pi=0, pil=thin_test.length; pi<pil; pi++) {
for (let pj=pi; pj<pil; pj++) { for (let pj=pi; pj<pil; pj++) {
let prec0 = thin_test[pi]; let prec0 = thin_test[pi];
@ -123,18 +139,19 @@ function offset_default(params) {
let moved = false; let moved = false;
for (let i=0; i<pp0.length; i++) { for (let i=0; i<pp0.length; i++) {
let p0 = pp0[i]; let p0 = pp0[i];
if (p0.moved) continue; if (p0.moved !== undefined) continue;
for (let j=0; j<pp1.length; j++) { for (let j=0; j<pp1.length; j++) {
let p1 = pp1[j]; let p1 = pp1[j];
if (p1.moved) continue; if (p1.moved !== undefined) continue;
if (p0 === p1 || p0.segment === p1.segment) { if (p0 === p1 || p0.segment === p1.segment) continue;
continue;
}
let dist = p0.distTo2D(p1); let dist = p0.distTo2D(p1);
if (dist < offset1) { if (dist < offset1) {
let diff = p0.segment.angle.angleDiff(p1.segment.angle,false);
if (p0.segment === p1.segment && diff < deltaBig) continue;
if (p0.segment !== p1.segment && diff > deltSmall && diff < deltaBig) continue;
// merge points marking point offset and skip // merge points marking point offset and skip
let mid = p0.midPointTo(p1); let mid = p0.midPointTo(p1);
let inc = p0.distTo2D(mid); let inc = p0.distTo2D(mid) / offset1;
moved = p0.moved = p1.moved = inc; moved = p0.moved = p1.moved = inc;
p1.skip = true; p1.skip = true;
p0.x = p1.x = mid.x; p0.x = p1.x = mid.x;
@ -154,36 +171,6 @@ function offset_default(params) {
} }
} }
// for (let poly of poly.segment(offset1, true)) {
// let ps = poly.segment(offset1, true);
// let pp = ps.points;
// let moved = false;
// pp.push(pp[0]);
// for (let i=0; i<pp.length; i++) {
// let p0 = pp[i];
// if (p0.moved) continue;
// for (let j=i+1; j<pp.length; j++) {
// let p1 = pp[j];
// if (p1.moved) continue;
// if (p0.segment === p1.segment) {
// continue;
// }
// if (p0.distTo2D(p1) < offset1) {
// // merge points marking point offset and skip
// let mid = p0.midPointTo(p1);
// let inc = p0.distTo2D(mid);
// moved = p0.moved = p1.moved = inc;
// p1.skip = true;
// p0.x = p1.x = mid.x;
// p0.y = p1.y = mid.y;
// }
// }
// }
// if (moved) {
// poly.points = pp;
// }
// }
return { last, gaps }; return { last, gaps };
} }
@ -712,8 +699,12 @@ export function doTopShells(z, top, count, offset1, offsetN, fillOffset, opt = {
case "adaptive": case "adaptive":
ret = thin_type_3({ z, top, count, offsetN }); ret = thin_type_3({ z, top, count, offsetN });
break; break;
case "basic":
default: default:
ret = offset_default({ z, top, count, top_poly, offset1, offsetN, wasm }); ret = offset_default({
z, top, count, top_poly, offset1, offsetN, wasm,
thin: opt.thinType === 'basic'
});
break; break;
} }
last = ret.last ?? last; last = ret.last ?? last;