From 2097f8d6e23dc74ef1c6627daf7510f3c76fa3de Mon Sep 17 00:00:00 2001 From: Stewart Allen Date: Tue, 9 Dec 2025 21:35:45 -0500 Subject: [PATCH] start to add back outline features --- src/kiri/core/conf.js | 2 + src/kiri/mode/cam/cl-ops.js | 7 +++ src/kiri/mode/cam/op-area.js | 6 +-- src/kiri/mode/cam/op-outline.js | 83 +++++++++++++++++++++++---------- src/kiri/mode/cam/op-rough.js | 22 ++++----- web/kiri/lang/en.js | 4 ++ 6 files changed, 86 insertions(+), 38 deletions(-) diff --git a/src/kiri/core/conf.js b/src/kiri/core/conf.js index 84650664..b90bbc67 100644 --- a/src/kiri/core/conf.js +++ b/src/kiri/core/conf.js @@ -428,6 +428,7 @@ export const conf = { camAreaTrace: "none", camAreaSurface: "linear", camAreaDirection: "climb", + camAreaEdgeOnly: false, camAreaAngle: 0, camAreaOver: 0.4, camAreaDown: 1, @@ -534,6 +535,7 @@ export const conf = { camOutlineRevbone: false, camOutlineDown: 3, camOutlineIn: false, + camOutlineOut: true, camOutlineOmitThru: false, camOutlineOver: 0.4, camOutlineOverCount: 1, diff --git a/src/kiri/mode/cam/cl-ops.js b/src/kiri/mode/cam/cl-ops.js index e728fd45..94631153 100644 --- a/src/kiri/mode/cam/cl-ops.js +++ b/src/kiri/mode/cam/cl-ops.js @@ -265,6 +265,8 @@ export function createPopOps() { dogbones: 'camOutlineDogbone', revbones: 'camOutlineRevbone', omitthru: 'camOutlineOmitThru', + outside: 'camOutlineOut', + inside: 'camOutlineIn', wide: 'camOutlineWide', ov_topz: 0, ov_botz: 0, @@ -279,7 +281,10 @@ export function createPopOps() { step: UC.newInput(LANG.cc_sovr_s, { title: LANG.cc_sovr_l, convert: toFloat, bound: UC.bound(0.01, 1.0), show: () => env.popOp.outline.rec.wide }), steps: UC.newInput(LANG.cc_sovc_s, { title: LANG.cc_sovc_l, convert: toInt, bound: UC.bound(1, 500), show: () => env.popOp.outline.rec.wide }), sep: UC.newBlank({ class: "pop-sep" }), + inside: UC.newBoolean(LANG.co_olin_s, undefined, { title: LANG.co_olin_l, show: (op) => { return !op.inputs.outside.checked } }), + outside: UC.newBoolean(LANG.co_olot_s, undefined, { title: LANG.co_olot_l, show: (op) => { return !op.inputs.inside.checked } }), omitthru: UC.newBoolean(LANG.co_omit_s, undefined, { title: LANG.co_omit_l }), + sep: UC.newBlank({ class: "pop-sep" }), wide: UC.newBoolean(LANG.co_wide_s, undefined, { title: LANG.co_wide_l }), dogbones: UC.newBoolean(LANG.co_dogb_s, undefined, { title: LANG.co_dogb_l, show: (op) => { return !op.inputs.wide.checked } }), revbones: UC.newBoolean(LANG.co_dogr_s, undefined, { title: LANG.co_dogr_l, show: () => env.poppedRec.dogbones }), @@ -674,6 +679,7 @@ export function createPopOps() { follow: 'camAreaFollow', refine: 'camAreaRefine', outline: 'camAreaOutline', + edgeonly: 'camAreaEdgeOnly', tolerance: 'camTolerance', dogbones: 'camAreaDogbones', revbones: 'camAreaRevbones', @@ -690,6 +696,7 @@ export function createPopOps() { UC.newButton("surface", surfaceAdd), ], { class: "ext-buttons f-row" }), outline: UC.newBoolean(LANG.cp_outl_s, undefined, { title: LANG.cp_outl_l }), + edgeonly: UC.newBoolean("edges only", undefined, { title: "edges only", show: isClear }), expand: UC.newInput(LANG.cp_xpnd_s, { title: LANG.cp_xpnd_l, convert: toFloat, units }), smooth: UC.newInput(LANG.cp_smoo_s, { title: LANG.cp_smoo_l, convert: toInt, xshow: isSurface }), follow: UC.newInput(LANG.cp_foll_s, { title: LANG.cp_foll_l, convert: toFloat }), diff --git a/src/kiri/mode/cam/op-area.js b/src/kiri/mode/cam/op-area.js index 8abbc602..940e1764 100644 --- a/src/kiri/mode/cam/op-area.js +++ b/src/kiri/mode/cam/op-area.js @@ -26,7 +26,7 @@ class OpArea extends CamOp { async slice(progress) { let { op, state } = this; - let { tool, mode, down, over, follow, expand, outline, smooth } = op; + let { tool, mode, down, over, follow, edgeonly, expand, outline, smooth } = op; let { ov_topz, ov_botz, direction, rename } = op; let { settings, widget, tabs, color } = state; let { addSlices, setToolDiam, cutTabs, shadowAt, workarea } = state; @@ -137,7 +137,7 @@ class OpArea extends CamOp { let layers = slice.output(); let shadow = await shadowAt(z); let tool_shadow = POLY.offset(shadow, [ toolDiam / 2 - ts_off ], { count: 1, z }); - // for roughing backward compatability + // for roughing/outline backward compatability if (op.omitthru) { shadow = shadow.clone(true); for (let poly of shadow.filter(p => p.inner)) { @@ -156,7 +156,7 @@ class OpArea extends CamOp { let clip = []; POLY.subtract([ area ], shadow, clip, undefined, undefined, 0); POLY.offset(clip, [ -toolDiam / 2, -toolOver ], { - count: 999, outs, flat: true, z, minArea: 0 + count: edgeonly ? 1 : 999, outs, flat: true, z, minArea: 0 }); // if we see no offsets, re-check the mesh bottom Z then exit if (outs.length === 0) { diff --git a/src/kiri/mode/cam/op-outline.js b/src/kiri/mode/cam/op-outline.js index 4fc8fbba..80db9b11 100644 --- a/src/kiri/mode/cam/op-outline.js +++ b/src/kiri/mode/cam/op-outline.js @@ -14,37 +14,72 @@ class OpOutline extends CamOp { async slice(progress) { let { op, state } = this; - let { shadow, tool, widget } = state; + let { dogbones, down, inside, omitthru, outside, ov_botz, ov_topz } = op; + let { plunge, rate, rename, revbones, spindle, tool } = op; + let { shadow, widget } = state; + let shadow_base = shadow.base; if (!(shadow_base && shadow_base.length)) { throw 'missing shadow base'; } - let areas = POLY.flatten(POLY.expand(shadow.base, tool.fluteDiameter() / 2 - 0.001)); - let cutout = { - areas: { [widget.id]: areas.map(p => p.toArray()) }, - dogbones: op.dogbones, - down: op.down, - expand: 0, - mode: 'trace', - outline: op.omitthru, - ov_botz: op.ov_botz, - ov_topz: op.ov_topz, - plunge: op.plunge, - rate: op.rate, - rename: op.rename ?? "outline", - revbones: op.revbones, - smooth: 0, - spindle: op.spindle, - surfaces: {}, - tool: op.tool, - tr_type: 'none', - }; - this.op_cutout = new OpArea(state, cutout); - return this.op_cutout.slice(progress); + + let ops_list = this.ops_list = [ ]; + + if (outside) { + let areas = POLY.flatten(POLY.expand(shadow.base, state.tool.fluteDiameter() / 2 - 0.001)); + ops_list.push(new OpArea(state, { + areas: { [widget.id]: areas.map(p => p.toArray()) }, + dogbones, + down, + expand: 0, + mode: 'trace', + outline: omitthru, + ov_botz, + ov_topz, + plunge, + rate, + rename: rename ?? "outline", + revbones, + smooth: 0, + spindle, + surfaces: {}, + tool, + tr_type: 'none', + })); + } else { + let areas = shadow.base.clone(true); + ops_list.push(new OpArea(state, { + areas: { [widget.id]: areas.map(p => p.toArray()) }, + dogbones, + down, + edgeonly: true, + expand: 0, + mode: 'clear', + ov_botz, + ov_topz, + plunge, + rate, + rename: rename ?? "outline", + revbones, + smooth: 0, + spindle, + surfaces: {}, + tool, + })); + if (!inside) { + // add outline + } + } + + for (let op of this.ops_list) { + await op.slice(progress); + } } async prepare(ops, progress) { - return this.op_cutout.prepare(ops, progress); + for (let op of this.ops_list) { + await op.prepare(ops, progress); + } } } diff --git a/src/kiri/mode/cam/op-rough.js b/src/kiri/mode/cam/op-rough.js index 601075b0..6ec1388d 100644 --- a/src/kiri/mode/cam/op-rough.js +++ b/src/kiri/mode/cam/op-rough.js @@ -30,8 +30,9 @@ class OpRough extends CamOp { } let areas = POLY.flatten(POLY.expand(shadowBase, tool.fluteDiameter() / 2 - 0.001)); + let ops_list = this.ops_list = [ ]; - let rough = { + ops_list.push(new OpArea(state, { rename: op.rename ?? "rough", spindle: op.spindle, tool: op.tool, @@ -50,13 +51,10 @@ class OpRough extends CamOp { ov_topz: op.ov_topz, areas: { [widget.id]: areas.map(p => p.toArray()) }, surfaces: {} - }; - - this.op_rough = new OpArea(state, rough); - await this.op_rough.slice(progress); + })); if (cutOutside) { - let cutout = { + ops_list.push(new OpArea(state, { rename: op.rename ?? "rough", spindle: op.spindle, tool: op.tool, @@ -72,16 +70,18 @@ class OpRough extends CamOp { ov_topz: op.ov_topz, areas: { [widget.id]: areas.map(p => p.toArray()) }, surfaces: {} - }; - this.op_cutout = new OpArea(state, cutout); - await this.op_cutout.slice(progress); + })); } + for (let op of this.ops_list) { + await op.slice(progress); + } } async prepare(ops, progress) { - await this.op_rough.prepare(ops, progress); - if (this.op_cutout) await this.op_cutout.prepare(ops, progress); + for (let op of this.ops_list) { + await op.prepare(ops, progress); + } } } diff --git a/web/kiri/lang/en.js b/web/kiri/lang/en.js index f94002be..adfd0d45 100644 --- a/web/kiri/lang/en.js +++ b/web/kiri/lang/en.js @@ -555,6 +555,10 @@ self.lang['en-us'] = { co_omit_l: "eliminate thru holes", co_olen_s: "enable", co_olen_l: "enabled outline cutting", + co_olin_s: "inside only", + co_olin_l: ["limit cutting to","inside part boundaries"], + co_olot_s: "outside only", + co_olot_l: ["limit cutting to","exterior part boundaries","which can be thought of","as the shadow outline"], // CNC CONTOUR cn_menu: "contour",