for area offsets, disable wasm (lacks features) and use round joins for offsets (better tool paths for cnc)

This commit is contained in:
Stewart Allen 2025-12-13 15:48:30 -05:00
commit d5b6d4c080
7 changed files with 66 additions and 46 deletions

View file

@ -3,6 +3,7 @@
import { base } from '../../geo/base.js';
import { avgc } from './utils.js';
import { util as mesh_util } from '../../mesh/util.js';
import { tool as mesh_tool } from '../../mesh/tool.js';
import { verticesToPoints } from '../../geo/points.js';
import { newPoint } from '../../geo/point.js';
import { newPolygon } from '../../geo/polygon.js';
@ -158,7 +159,12 @@ class Widget {
* @param {Float32Array} vertices
* @returns {Widget}
*/
loadVertices(data, options = { index: false }) {
loadVertices(data, options = { normalize: false }) {
if (options.normalize) {
console.time('mesh normalize')
data = new mesh_tool({ precision: 0.001 }).normalizeVertices(data).toFloat32();
console.timeEnd('mesh normalize');
}
// console.trace({ loadVertices: this.id, worker: this.inWorker, data });
let vertices,
autoscale = false;
@ -859,9 +865,9 @@ class Widget {
// find closest shadow above and use to speed up delta shadow gen
let zover = Object.keys(shadows).map(v => parseFloat(v)).filter(v => v > z);
let minZabove = Math.min(Infinity, ...zover);
let shadow = this.#computeShadowAt(z, minZabove);
let shadow = this.#computeShadowAt(z - 0.01, minZabove);
if (minZabove < Infinity) {
shadow = POLY.union([...shadow, ...shadows[minZabove]], 0.001, true);
shadow = POLY.union([...shadow, ...shadows[minZabove]], 0.001, true, { wasm: false });
}
return shadows[z] = POLY.setZ(shadow, z);
}
@ -953,7 +959,7 @@ class Widget {
.add(a[1].x, a[1].y, a[1].z)
.add(a[2].x, a[2].y, a[2].z);
});
polys = POLY.union(polys, 0, true);
polys = POLY.union(polys, 0, true, { wasm: false });
// for a more perfect union, pump shadows to merge very close lines
// todo: create clipper only version that avoids round trip thru geo classes

View file

@ -246,8 +246,8 @@ export function createPopOps() {
leavez: UC.newInput(LANG.cr_lstz_s, { title: LANG.cr_lstz_l, convert: toFloat, bound: UC.bound(0, 10), units }),
sep: UC.newBlank({ class: "pop-sep" }),
all: UC.newBoolean(LANG.cr_clst_s, undefined, { title: LANG.cr_clst_l, show: () => !env.poppedRec.inside || env.poppedRec.all }),
inside: UC.newBoolean(LANG.cr_olin_s, undefined, { title: LANG.cr_olin_l, show: () => !env.poppedRec.all || env.poppedRec.inside }),
flats: UC.newBoolean(LANG.cr_clrf_s, undefined, { title: LANG.cr_clrf_l }),
inside: UC.newBoolean(LANG.cr_olin_s, undefined, { title: LANG.cr_olin_l, show: () => !env.poppedRec.all || env.poppedRec.inside }),
omitthru: UC.newBoolean(LANG.co_omit_s, undefined, { title: LANG.co_omit_l }),
sep: UC.newBlank({ class: "pop-sep" }),
exp: UC.newExpand("overrides"),

View file

@ -117,6 +117,13 @@ class OpArea extends CamOp {
for (let area of polys) {
let bounds = area.getBounds3D();
let ts_off = toolDiam / 2 - ts_eps;
let offopt = {
join: ClipperLib.JoinType.jtRound,
clean: true,
simple: false,
cleanDist: 10,
minArea: 0.01,
};
if (outline) {
// remove inner voids when processing outline only
@ -143,8 +150,8 @@ class OpArea extends CamOp {
let layers = slice.output();
let shadow = await shadowAt(z);
let tool_shadow = [
...POLY.offset(shadow, [ ts_off ], { count: 1, z }),
...POLY.offset(shadow, [ -ts_off ], { count: 1, z }),
...POLY.offset(shadow, [ ts_off ], { count: 1, z, ...offopt }),
...POLY.offset(shadow, [ -ts_off ], { count: 1, z, ...offopt }),
];
// for roughing/outline backward compatability
if (op.omitthru) {
@ -156,7 +163,7 @@ class OpArea extends CamOp {
let firstOff = -(toolDiam / 2 + (op.leave_xy ?? 0));
POLY.subtract([ area ], shadow, clip, undefined, undefined, 0);
POLY.offset(clip, [ firstOff, -toolOver ], {
count: op.steps ?? 999, outs, flat: true, z: z - zMov, minArea: 0
count: op.steps ?? 999, outs, flat: true, z: z - zMov, ...offopt
});
// if we see no offsets, re-check the mesh bottom Z then exit
if (outs.length === 0) {
@ -261,8 +268,8 @@ class OpArea extends CamOp {
slice.tool_shadow = [
area,
...shadow,
...POLY.offset(shadow, [ ts_off ], { count: 1, z }),
...POLY.offset(shadow, [ -ts_off ], { count: 1, z }),
...POLY.offset(shadow, [ ts_off ], { count: 1, z, ...offopt }),
...POLY.offset(shadow, [ -ts_off ], { count: 1, z, ...offopt }),
];
// add tabs to travel boundaries
if (tabs) {