rework tab cutting to work with indexed rotations

This commit is contained in:
Stewart Allen 2025-11-27 10:32:41 -05:00
commit 6af1bda1ab
3 changed files with 72 additions and 11 deletions

View file

@ -16,6 +16,10 @@ import { holeSelOn, selectHolesDone, clearHolesRec } from './cl-hole.js';
import { surfaceOn, surfaceDone } from './cl-surface.js';
import { helicalOn, helicalDone } from './cl-helical.js';
import { originSelectDone } from './cl-origin.js';
import { Widget, newWidget } from '../../core/widget.js';
import { space } from '../../../moto/space.js';
const { BufferGeometryUtils } = THREE;
const DEG2RAD = Math.PI / 180;
const RAD2DEG = 180 / Math.PI;
@ -606,6 +610,20 @@ export function init() {
updateStock();
opRender();
api.uc.setVisible($('layer-animate'), env.isAnimate && env.isCamMode);
if (!env.isCamMode) {
return;
}
// remove tab synth
api.widgets.filter((widget) => {
if (widget.track.synth) {
space.world.remove(widget.mesh);
Widget.Groups.remove(widget);
}
return !widget.track.synth
});
});
api.event.on("settings.saved", (settings) => {
@ -786,8 +804,25 @@ export function init() {
// COMMON TAB/TRACE EVENT HANDLERS
api.event.on("slice.begin", () => {
if (env.isCamMode) {
clearPops();
if (!env.isCamMode) {
return;
}
clearPops();
for (let group of Widget.Groups.list()) {
let root = group[0];
for (let tab of Object.values(root.tabs)) {
let geo = tab.box.geometry.clone();
if (geo.index) geo = geo.toNonIndexed();
geo.translate(tab.x, tab.y, tab.z);
let bbg = BufferGeometryUtils.mergeGeometries([ geo ]);
let sw = newWidget(null, group);
let fwp = group[0].track.pos;
sw.loadGeometry(bbg);
sw._move(fwp.x, fwp.y, fwp.z);
api.widgets.add(sw);
sw.track.synth = true;
sw.track.indexed = root.track.indexed;
}
}
});

View file

@ -17,7 +17,7 @@ export class OpIndex extends CamOp {
throw 'index op requires indexed stock';
}
let { widget, updateSlicer, computeShadows, setAxisIndex } = state;
this.degrees = setAxisIndex(op.degrees, op.absolute);
this.degrees = await setAxisIndex(op.degrees, op.absolute);
// force recompute of topo
widget.topo = undefined;
updateSlicer();

View file

@ -20,6 +20,10 @@ import { CAM } from './driver-be.js';
* @param {Function} output
*/
export async function cam_slice(settings, widget, onupdate, ondone) {
if (widget.track.synth) return ondone();
let tabW = widget.group.filter(w => w != widget);
let proc = settings.process,
sliceAll = widget.slices = [],
camOps = widget.camops = [],
@ -189,6 +193,30 @@ export async function cam_slice(settings, widget, onupdate, ondone) {
};
let tracker = setSliceTracker({ rotation: 0 });
async function updateTab(tab) {
tab.setAxisIndex(isIndexed ? -axisIndex : 0)
let ts = new cam_slicer(tab);
let si = Object.keys(ts.zList).map(k => parseFloat(k));
si = [ ...si.map(v => v-0.01), ...si.map(v => v+0.01) ];
let zt = Math.max(...si);
let zb = Math.min(...si);
let shadow;
await ts.slice(si, { each: data => {
if (shadow) {
shadow = POLY.union([...shadow, ...data.polys]);
} else {
shadow = data.polys;
}
}});
return {
top: zt,
poly: shadow[0],
pos: { z: (zt+zb)/2 },
dim: { z: (zt-zb) },
NEW: true
}
}
function updateSlicer() {
slicer = state.slicer = new cam_slicer(widget);
}
@ -231,10 +259,14 @@ export async function cam_slice(settings, widget, onupdate, ondone) {
return shadows[z] = POLY.setZ(shadow, z);
}
function setAxisIndex(degrees = 0, absolute = true) {
async function setAxisIndex(degrees = 0, absolute = true) {
axisIndex = absolute ? degrees : (axisIndex || 0) + degrees;
axisRotation = (Math.PI / 180) * axisIndex;
widget.setAxisIndex(isIndexed ? -axisIndex : 0);
state.tabs = tabs = [];
for (let tab of tabW) {
tabs.push(await updateTab(tab));
}
return isIndexed ? -axisIndex : 0;
}
@ -299,7 +331,7 @@ export async function cam_slice(settings, widget, onupdate, ondone) {
}
// call slice() function on all ops in order
setAxisIndex();
await setAxisIndex();
updateSlicer();
for (let op of opList) {
let weight = op.weight();
@ -325,12 +357,6 @@ export async function cam_slice(settings, widget, onupdate, ondone) {
zTop,
workarea: workover
});
// console.log({
// op,
// workover,
// bounds: structuredClone(bounds),
// stock: structuredClone(stock)
// });
await op.slice((progress, message) => {
onupdate((opSum + (progress * weight)) / opTot, message || op.type());
});