merge overlapping tabs

This commit is contained in:
Stewart Allen 2025-12-11 22:47:24 -05:00
commit 0df0e14f32
2 changed files with 26 additions and 5 deletions

View file

@ -37,8 +37,8 @@ class OpArea extends CamOp {
let smoothVal = (smooth ?? 0) / 10;
let toolDiam = areaTool.fluteDiameter();
let toolOver = areaTool.getStepSize(over);
let zTop = ov_topz ? workarea.bottom_stock + ov_topz : workarea.top_z;
let zBottom = ov_botz ? workarea.bottom_stock + ov_botz : Math.max(workarea.bottom_z, workarea.bottom_part) + workarea.bottom_cut;
let zTop = workarea.top_z;
let zBottom = Math.max(workarea.bottom_z, workarea.bottom_part) + workarea.bottom_cut;
let shadowBase = state.shadow.base;
let thruHoles = state.shadow.holes;
@ -181,7 +181,7 @@ class OpArea extends CamOp {
outs = omitInner(outs);
}
// add tabs to travel boundaries
if (tabs) {
if (tabs.length) {
let tab_shadows = tabs.filter(t => t.top >= z).map(t => t.poly);
if (tab_shadows) tool_shadow.push(...tab_shadows);
}
@ -244,7 +244,7 @@ class OpArea extends CamOp {
// add dogbones when specified
if (op.dogbones) outs.forEach(out => out.addDogbones(toolDiam / 5, op.revbones));
// cut tabs when present
if (tabs) outs = cutTabs(tabs, outs);
if (tabs.length) outs = cutTabs(tabs, outs);
// support legacy outline features
if (op.omitouter) {
outs = omitOuter(outs);

View file

@ -21,7 +21,28 @@ import { util } from '../../../geo/base.js';
export async function cam_slice(settings, widget, onupdate, ondone) {
if (widget.track.synth) return ondone();
// get tab widgets
let tabW = widget.group.filter(w => w != widget);
// merge overlapping tabs
for (let i=0; i<tabW.length; i++) {
for (let j=i+1; j<tabW.length; j++) {
let t1 = tabW[i];
let t2 = tabW[j];
let b1 = t1.mesh.getBoundingBox();
let b2 = t2.mesh.getBoundingBox();
if (b1.intersectsBox(b2)) {
let a = t1.getVertices().array;
let b = t2.getVertices().array;
let arr = new Float32Array(a.length + b.length);
arr.set(a, 0);
arr.set(b, a.length);
t1.loadVertices(arr);
t2.del = true;
}
}
}
// filter merged tabs
tabW = tabW.filter(tw => !tw.del);
let proc = settings.process,
camOps = widget.camops = [],
@ -41,7 +62,7 @@ export async function cam_slice(settings, widget, onupdate, ondone) {
color = dark ? 0xbbbbbb : 0;
minToolDiam = Infinity;
maxToolDiam = -Infinity;
tabs = widget.anno.tab;
tabs = widget.anno.tab ?? [];
unsafe = proc.camExpertFast;
units = settings.controller.units === 'in' ? 25.4 : 1;