From 6d95474acf7414657a8df8f094733893924b264a Mon Sep 17 00:00:00 2001 From: Max Cahill Date: Wed, 25 Mar 2026 21:53:51 +1100 Subject: [PATCH] added basic finish cut capability to op area, must be used cutting inner first. --- src/kiri/mode/cam/app/cl-ops.js | 2 ++ src/kiri/mode/cam/work/op-area.js | 12 +++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/kiri/mode/cam/app/cl-ops.js b/src/kiri/mode/cam/app/cl-ops.js index ad6b364e..2bb231ea 100644 --- a/src/kiri/mode/cam/app/cl-ops.js +++ b/src/kiri/mode/cam/app/cl-ops.js @@ -778,6 +778,7 @@ export function createPopOps() { revbones: 'camAreaRevbones', ov_topz: 0, ov_botz: 0, + finish_cut: 0, }).inputs = { mode: UC.newSelect(LANG.mo_menu, { post: opRender }, "opmode"), tr_type: UC.newSelect(LANG.cc_offs_s, { title: LANG.cc_offs_l, show: isTrace }, "traceoff"), @@ -805,6 +806,7 @@ export function createPopOps() { sr_angle: UC.newInput(LANG.ca_sang_s, { title: LANG.ca_sang_l, convert: toFloat, bound: UC.bound(0, 360), show: isSurfaceLinear }), over: UC.newInput(LANG.cc_sovr_s, { title: LANG.cc_sovr_l, convert: toFloat, bound: UC.bound(0.001, 100.0), show: () => isClear() || isSurface() }), down: UC.newInput(LANG.cc_sdwn_s, { title: LANG.cc_sdwn_l, convert: toFloat, bound: UC.bound(0, 100.0), units, show: () => isClear() || isTrace() }), + finish_cut: UC.newInput("finish cut", { title: "finish cut", convert: toFloat, bound: UC.bound(0, 2.0), units, show: () => isClear() || isTrace() }), //todo: needs to check camInnerFirst refine: UC.newInput(LANG.cp_refi_s, { title: LANG.cp_refi_l, convert: toInt, show: isSurface }), sr_alter: UC.newBoolean(LANG.ca_altr_s, undefined, { title: LANG.ca_altr_l, show: isSurfaceLinear }), dogbones: UC.newBoolean(LANG.co_dogb_s, undefined, { title: LANG.co_dogb_l, show: isTrace }), diff --git a/src/kiri/mode/cam/work/op-area.js b/src/kiri/mode/cam/work/op-area.js index abf4c8ab..d95b720c 100644 --- a/src/kiri/mode/cam/work/op-area.js +++ b/src/kiri/mode/cam/work/op-area.js @@ -197,7 +197,17 @@ class OpArea extends CamOp { } else { POLY.subtract([ area ], shadow, clip, undefined, undefined, 0); } - POLY.offset(clip, [ firstOff, -toolOver ], { + //generate offsets to use + let offsets = [ firstOff ]; + //if we need a finish cut, add it + let finish_cut = op.finish_cut ?? 0; + if (finish_cut != 0) { //todo: this should check for camInnerFirst and warn if it is not true + offsets.push(-finish_cut); + } + //everything else uses the tool stepover + offsets.push(-toolOver); + //actually offset the walls inwards + POLY.offset(clip, [ firstOff, -finish_cut, -toolOver ], { count: op.walls ? 1 : (op.steps ?? 999), outs, flat: true, z: z - zMov, ...offopt }); // if we see no offsets, re-check the mesh bottom Z then exit