diff --git a/src/geo/polygon.js b/src/geo/polygon.js index 952a0474..a397bb8f 100644 --- a/src/geo/polygon.js +++ b/src/geo/polygon.js @@ -70,6 +70,14 @@ export class Polygon { return bounds; } + getBound3D() { + let bounds = new THREE.Box3(); + for (let point of this.points) { + bounds.expandByPoint(point); + } + return bounds; + } + toPath2D(offset) { return paths.pointsToPath(this.points, offset, this.open); } @@ -985,7 +993,13 @@ export class Polygon { } minZ() { - return Math.min(...this.points.map(p => p.z)); + let minZ = Math.min(...this.points.map(p => p.z)); + if (this.inner) { + for (let i of this.inner) { + minZ = Math.min(minZ, i.minZ()); + } + } + return minZ; } avgZ() { diff --git a/src/kiri/mode/cam/cl-ops.js b/src/kiri/mode/cam/cl-ops.js index 01e0bffc..cfd40cc0 100644 --- a/src/kiri/mode/cam/cl-ops.js +++ b/src/kiri/mode/cam/cl-ops.js @@ -15,7 +15,9 @@ const { MODES } = api.const; const { uc: UC } = api; const { alerts, conf } = api; const { current: LANG } = api.language; +const { toInt, toFloat } = UC; +const units = true; let seed = Date.now(); function hasIndexing() { @@ -205,12 +207,12 @@ export function createPopOps() { }).inputs = { tool: UC.newSelect(LANG.cc_tool, {}, "tools"), sep: UC.newBlank({ class: "pop-sep" }), - spindle: UC.newInput(LANG.cc_spnd_s, { title: LANG.cc_spnd_l, convert: UC.toInt, show: hasSpindle }), - step: UC.newInput(LANG.cc_sovr_s, { title: LANG.cc_sovr_l, convert: UC.toFloat, bound: UC.bound(0.01, 1.0) }), - stepz: UC.newInput(LANG.cc_sdwn_s, { title: LANG.cc_sdwn_l, convert: UC.toFloat, units: true, bound: UC.bound(0, 100.0) }), - rate: UC.newInput(LANG.cc_feed_s, { title: LANG.cc_feed_l, convert: UC.toInt, units: true }), - down: UC.newInput(LANG.cc_loff_s, { title: LANG.cc_loff_l, convert: UC.toFloat, units: true }), - inset: UC.newInput(LANG.cc_lxyo_s, { title: LANG.cc_lxyo_l, convert: UC.toFloat, units: true, show: () => !env.popOp.level.rec.stock }), + spindle: UC.newInput(LANG.cc_spnd_s, { title: LANG.cc_spnd_l, convert: toInt, show: hasSpindle }), + step: UC.newInput(LANG.cc_sovr_s, { title: LANG.cc_sovr_l, convert: toFloat, bound: UC.bound(0.01, 1.0) }), + stepz: UC.newInput(LANG.cc_sdwn_s, { title: LANG.cc_sdwn_l, convert: toFloat, units, bound: UC.bound(0, 100.0) }), + rate: UC.newInput(LANG.cc_feed_s, { title: LANG.cc_feed_l, convert: toInt, units }), + down: UC.newInput(LANG.cc_loff_s, { title: LANG.cc_loff_l, convert: toFloat, units }), + inset: UC.newInput(LANG.cc_lxyo_s, { title: LANG.cc_lxyo_l, convert: toFloat, units, show: () => !env.popOp.level.rec.stock }), sep: UC.newBlank({ class: "pop-sep" }), stock: UC.newBoolean(LANG.cc_lsto_s, undefined, { title: LANG.cc_lsto_l }), }; @@ -235,14 +237,14 @@ export function createPopOps() { }).inputs = { tool: UC.newSelect(LANG.cc_tool, {}, "tools"), sep: UC.newBlank({ class: "pop-sep" }), - spindle: UC.newInput(LANG.cc_spnd_s, { title: LANG.cc_spnd_l, convert: UC.toInt, show: hasSpindle }), - rate: UC.newInput(LANG.cc_feed_s, { title: LANG.cc_feed_l, convert: UC.toInt, units: true }), - plunge: UC.newInput(LANG.cc_plng_s, { title: LANG.cc_plng_l, convert: UC.toInt, units: true }), + spindle: UC.newInput(LANG.cc_spnd_s, { title: LANG.cc_spnd_l, convert: toInt, show: hasSpindle }), + rate: UC.newInput(LANG.cc_feed_s, { title: LANG.cc_feed_l, convert: toInt, units }), + plunge: UC.newInput(LANG.cc_plng_s, { title: LANG.cc_plng_l, convert: toInt, units }), sep: UC.newBlank({ class: "pop-sep" }), - down: UC.newInput(LANG.cc_sdwn_s, { title: LANG.cc_sdwn_l, convert: UC.toFloat, units: true }), - step: UC.newInput(LANG.cc_sovr_s, { title: LANG.cc_sovr_l, convert: UC.toFloat, bound: UC.bound(0.01, 1.0) }), - leave: UC.newInput(LANG.cr_lsto_s, { title: LANG.cr_lsto_l, convert: UC.toFloat, units: true }), - leavez: UC.newInput(LANG.cr_lstz_s, { title: LANG.cr_lstz_l, convert: UC.toFloat, bound: UC.bound(0, 10), units: true }), + down: UC.newInput(LANG.cc_sdwn_s, { title: LANG.cc_sdwn_l, convert: toFloat, units }), + step: UC.newInput(LANG.cc_sovr_s, { title: LANG.cc_sovr_l, convert: toFloat, bound: UC.bound(0.01, 1.0) }), + leave: UC.newInput(LANG.cr_lsto_s, { title: LANG.cr_lsto_l, convert: toFloat, units }), + 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: hasIndexing }), voids: UC.newBoolean(LANG.cr_clrp_s, undefined, { title: LANG.cr_clrp_l }), @@ -251,8 +253,8 @@ export function createPopOps() { omitthru: UC.newBoolean(LANG.co_omit_s, undefined, { title: LANG.co_omit_l }), sep: UC.newBlank({ class: "pop-sep" }), exp: UC.newExpand("overrides"), - ov_topz: UC.newInput(LANG.ou_ztop_s, { title: LANG.ou_ztop_l, convert: UC.toFloat, units: true }), - ov_botz: UC.newInput(LANG.ou_zbot_s, { title: LANG.ou_zbot_l, convert: UC.toFloat, units: true }), + ov_topz: UC.newInput(LANG.ou_ztop_s, { title: LANG.ou_ztop_l, convert: toFloat, units }), + ov_botz: UC.newInput(LANG.ou_zbot_s, { title: LANG.ou_zbot_l, convert: toFloat, units }), ov_conv: UC.newBoolean(LANG.ou_conv_s, undefined, { title: LANG.ou_conv_l }), exp_end: UC.endExpand(), }; @@ -278,12 +280,12 @@ export function createPopOps() { }).inputs = { tool: UC.newSelect(LANG.cc_tool, {}, "tools"), sep: UC.newBlank({ class: "pop-sep" }), - spindle: UC.newInput(LANG.cc_spnd_s, { title: LANG.cc_spnd_l, convert: UC.toInt, show: hasSpindle }), - rate: UC.newInput(LANG.cc_feed_s, { title: LANG.cc_feed_l, convert: UC.toInt, units: true }), - plunge: UC.newInput(LANG.cc_plng_s, { title: LANG.cc_plng_l, convert: UC.toInt, units: true }), - down: UC.newInput(LANG.cc_sdwn_s, { title: LANG.cc_sdwn_l, convert: UC.toFloat, units: true }), - step: UC.newInput(LANG.cc_sovr_s, { title: LANG.cc_sovr_l, convert: UC.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: UC.toInt, bound: UC.bound(1, 500), show: () => env.popOp.outline.rec.wide }), + spindle: UC.newInput(LANG.cc_spnd_s, { title: LANG.cc_spnd_l, convert: toInt, show: hasSpindle }), + rate: UC.newInput(LANG.cc_feed_s, { title: LANG.cc_feed_l, convert: toInt, units }), + plunge: UC.newInput(LANG.cc_plng_s, { title: LANG.cc_plng_l, convert: toInt, units }), + down: UC.newInput(LANG.cc_sdwn_s, { title: LANG.cc_sdwn_l, convert: toFloat, units }), + 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" }), top: UC.newBoolean(LANG.co_clrt_s, undefined, { title: LANG.co_clrt_l }), inside: UC.newBoolean(LANG.co_olin_s, undefined, { title: LANG.co_olin_l, show: (op) => { return !op.inputs.outside.checked } }), @@ -295,8 +297,8 @@ export function createPopOps() { dogbones: UC.newBoolean(LANG.co_dogb_s, undefined, { title: LANG.co_dogb_l, show: (op) => { return !op.inputs.wide.checked } }), sep: UC.newBlank({ class: "pop-sep" }), exp: UC.newExpand("overrides"), - ov_topz: UC.newInput(LANG.ou_ztop_s, { title: LANG.ou_ztop_l, convert: UC.toFloat, units: true }), - ov_botz: UC.newInput(LANG.ou_zbot_s, { title: LANG.ou_zbot_l, convert: UC.toFloat, units: true }), + ov_topz: UC.newInput(LANG.ou_ztop_s, { title: LANG.ou_ztop_l, convert: toFloat, units }), + ov_botz: UC.newInput(LANG.ou_zbot_s, { title: LANG.ou_zbot_l, convert: toFloat, units }), ov_conv: UC.newBoolean(LANG.ou_conv_s, undefined, { title: LANG.ou_conv_l }), exp_end: UC.endExpand(), }; @@ -323,17 +325,17 @@ export function createPopOps() { tool: UC.newSelect(LANG.cc_tool, {}, "tools"), axis: UC.newSelect(LANG.cd_axis, {}, "xyaxis"), sep: UC.newBlank({ class: "pop-sep" }), - spindle: UC.newInput(LANG.cc_spnd_s, { title: LANG.cc_spnd_l, convert: UC.toInt, show: hasSpindle }), - rate: UC.newInput(LANG.cc_feed_s, { title: LANG.cc_feed_l, convert: UC.toInt, units: true }), + spindle: UC.newInput(LANG.cc_spnd_s, { title: LANG.cc_spnd_l, convert: toInt, show: hasSpindle }), + rate: UC.newInput(LANG.cc_feed_s, { title: LANG.cc_feed_l, convert: toInt, units }), sep: UC.newBlank({ class: "pop-sep" }), - step: UC.newInput(LANG.cc_sovr_s, { title: LANG.cc_sovr_l, convert: UC.toFloat, bound: UC.bound(0.01, 10.0) }), - leave: UC.newInput(LANG.cf_leav_s, { title: LANG.cf_leav_l, convert: UC.toFloat, bound: UC.bound(0, 100) }), + step: UC.newInput(LANG.cc_sovr_s, { title: LANG.cc_sovr_l, convert: toFloat, bound: UC.bound(0.01, 10.0) }), + leave: UC.newInput(LANG.cf_leav_s, { title: LANG.cf_leav_l, convert: toFloat, bound: UC.bound(0, 100) }), sep: UC.newBlank({ class: "pop-sep" }), - angle: UC.newInput(LANG.cf_angl_s, { title: LANG.cf_angl_l, convert: UC.toFloat, bound: UC.bound(45, 90), show: (op) => op.inputs.curves.checked }), - flatness: UC.newInput(LANG.ou_flat_s, { title: LANG.ou_flat_l, convert: UC.toFloat, bound: UC.bound(0, 1.0), units: false, round: 4 }), - tolerance: UC.newInput(LANG.ou_toll_s, { title: LANG.ou_toll_l, convert: UC.toFloat, bound: UC.bound(0, 10.0), units: true, round: 4 }), - reduction: UC.newInput(LANG.ou_redu_s, { title: LANG.ou_redu_l, convert: UC.toInt, bound: UC.bound(0, 10), units: false }), - // bridging: UC.newInput(LANG.ou_brdg_s, {title:LANG.ou_brdg_l, convert:UC.toFloat, bound:UC.bound(0,1000.0), units:true, round:4, show:(op) => op.inputs.curves.checked}), + angle: UC.newInput(LANG.cf_angl_s, { title: LANG.cf_angl_l, convert: toFloat, bound: UC.bound(45, 90), show: (op) => op.inputs.curves.checked }), + flatness: UC.newInput(LANG.ou_flat_s, { title: LANG.ou_flat_l, convert: toFloat, bound: UC.bound(0, 1.0), units: false, round: 4 }), + tolerance: UC.newInput(LANG.ou_toll_s, { title: LANG.ou_toll_l, convert: toFloat, bound: UC.bound(0, 10.0), units, round: 4 }), + reduction: UC.newInput(LANG.ou_redu_s, { title: LANG.ou_redu_l, convert: toInt, bound: UC.bound(0, 10), units: false }), + // bridging: UC.newInput(LANG.ou_brdg_s, {title:LANG.ou_brdg_l, convert:toFloat, bound:UC.bound(0,1000.0), units:true, round:4, show:(op) => op.inputs.curves.checked}), sep: UC.newBlank({ class: "pop-sep" }), curves: UC.newBoolean(LANG.cf_curv_s, undefined, { title: LANG.cf_curv_l }), inside: UC.newBoolean(LANG.cf_olin_s, undefined, { title: LANG.cf_olin_l }), @@ -357,17 +359,17 @@ export function createPopOps() { tool: UC.newSelect(LANG.cc_tool, {}, "tools"), // axis: UC.newSelect(LANG.cd_axis, {}, "xyaxis"), sep: UC.newBlank({ class: "pop-sep" }), - spindle: UC.newInput(LANG.cc_spnd_s, { title: LANG.cc_spnd_l, convert: UC.toInt, show: hasSpindle }), - rate: UC.newInput(LANG.cc_feed_s, { title: LANG.cc_feed_l, convert: UC.toInt, units: true }), + spindle: UC.newInput(LANG.cc_spnd_s, { title: LANG.cc_spnd_l, convert: toInt, show: hasSpindle }), + rate: UC.newInput(LANG.cc_feed_s, { title: LANG.cc_feed_l, convert: toInt, units }), sep: UC.newBlank({ class: "pop-sep" }), - step: UC.newInput(LANG.cc_sovr_s, { title: LANG.cc_sovr_l, convert: UC.toFloat, bound: UC.bound(0.01, 100.0) }), - angle: UC.newInput(LANG.cc_sang_s, { title: LANG.cc_sang_l, convert: UC.toFloat, bound: UC.bound(0.01, 180.0) }), + step: UC.newInput(LANG.cc_sovr_s, { title: LANG.cc_sovr_l, convert: toFloat, bound: UC.bound(0.01, 100.0) }), + angle: UC.newInput(LANG.cc_sang_s, { title: LANG.cc_sang_l, convert: toFloat, bound: UC.bound(0.01, 180.0) }), sep: UC.newBlank({ class: "pop-sep" }), - offStart: UC.newInput(LANG.ci_laso_s, { title: LANG.ci_laso_l, convert: UC.toFloat}), - offEnd: UC.newInput(LANG.ci_laeo_s, { title: LANG.ci_laeo_l, convert: UC.toFloat}), + offStart: UC.newInput(LANG.ci_laso_s, { title: LANG.ci_laso_l, convert: toFloat}), + offEnd: UC.newInput(LANG.ci_laeo_s, { title: LANG.ci_laeo_l, convert: toFloat}), sep: UC.newBlank({ class: "pop-sep" }), - tolerance: UC.newInput(LANG.ou_toll_s, { title: LANG.ou_toll_l, convert: UC.toFloat, bound: UC.bound(0, 10.0), units: true, round: 4 }), - leave: UC.newInput(LANG.cf_leav_s, { title: LANG.cf_leav_l, convert: UC.toFloat, bound: UC.bound(0, 100) }), + tolerance: UC.newInput(LANG.ou_toll_s, { title: LANG.ou_toll_l, convert: toFloat, bound: UC.bound(0, 10.0), units, round: 4 }), + leave: UC.newInput(LANG.cf_leav_s, { title: LANG.cf_leav_l, convert: toFloat, bound: UC.bound(0, 100) }), sep: UC.newBlank({ class: "pop-sep" }), linear: UC.newBoolean(LANG.ci_line_s, undefined, { title: LANG.ci_line_l }), // filter: UC.newRow([ UC.newButton(LANG.filter, contourFilter) ], {class:"ext-buttons f-row"}) @@ -408,22 +410,22 @@ export function createPopOps() { mode: UC.newSelect(LANG.cu_type_s, { title: LANG.cu_type_l }, "trace"), offset: UC.newSelect(LANG.cc_offs_s, { title: LANG.cc_offs_l, show: () => (env.poppedRec.mode === 'follow') }, "traceoff"), sep: UC.newBlank({ class: "pop-sep" }), - spindle: UC.newInput(LANG.cc_spnd_s, { title: LANG.cc_spnd_l, convert: UC.toInt, show: hasSpindle }), - rate: UC.newInput(LANG.cc_feed_s, { title: LANG.cc_feed_l, convert: UC.toInt, units: true }), - plunge: UC.newInput(LANG.cc_plng_s, { title: LANG.cc_plng_l, convert: UC.toInt, units: true }), + spindle: UC.newInput(LANG.cc_spnd_s, { title: LANG.cc_spnd_l, convert: toInt, show: hasSpindle }), + rate: UC.newInput(LANG.cc_feed_s, { title: LANG.cc_feed_l, convert: toInt, units }), + plunge: UC.newInput(LANG.cc_plng_s, { title: LANG.cc_plng_l, convert: toInt, units }), sep: UC.newBlank({ class: "pop-sep" }), - step: UC.newInput(LANG.cc_sovr_s, { title: LANG.cc_sovr_l, convert: UC.toFloat, bound: UC.bound(0.01, 1.0), show: (op) => env.popOp.trace.rec.mode === "clear" }), - down: UC.newInput(LANG.cc_sdwn_s, { title: LANG.cc_sdwn_l, convert: UC.toFloat, units: true }), - thru: UC.newInput(LANG.cc_thru_s, { title: LANG.cc_thru_l, convert: UC.toFloat, units: true }), - offover: UC.newInput(LANG.cc_offd_s, { title: LANG.cc_offd_l, convert: UC.toFloat, units: true, show: () => env.poppedRec.offset !== "none" || env.poppedRec.mode === "clear" }), + step: UC.newInput(LANG.cc_sovr_s, { title: LANG.cc_sovr_l, convert: toFloat, bound: UC.bound(0.01, 1.0), show: (op) => env.popOp.trace.rec.mode === "clear" }), + down: UC.newInput(LANG.cc_sdwn_s, { title: LANG.cc_sdwn_l, convert: toFloat, units }), + thru: UC.newInput(LANG.cc_thru_s, { title: LANG.cc_thru_l, convert: toFloat, units }), + offover: UC.newInput(LANG.cc_offd_s, { title: LANG.cc_offd_l, convert: toFloat, units, show: () => env.poppedRec.offset !== "none" || env.poppedRec.mode === "clear" }), sep: UC.newBlank({ class: "pop-sep", modes: MODES.CAM, xshow: zDogSep }), merge: UC.newBoolean(LANG.co_merg_s, undefined, { title: LANG.co_merg_l, show: () => !env.popOp.trace.rec.down }), dogbone: UC.newBoolean(LANG.co_dogb_s, undefined, { title: LANG.co_dogb_l, show: canDogBones }), revbone: UC.newBoolean(LANG.co_dogr_s, undefined, { title: LANG.co_dogr_l, show: canDogBonesRev }), exp: UC.newExpand("overrides"), sep: UC.newBlank({ class: "pop-sep" }), - ov_topz: UC.newInput(LANG.ou_ztop_s, { title: LANG.ou_ztop_l, convert: UC.toFloat, units: true }), - ov_botz: UC.newInput(LANG.ou_zbot_s, { title: LANG.ou_zbot_l, convert: UC.toFloat, units: true }), + ov_topz: UC.newInput(LANG.ou_ztop_s, { title: LANG.ou_ztop_l, convert: toFloat, units }), + ov_botz: UC.newInput(LANG.ou_zbot_s, { title: LANG.ou_zbot_l, convert: toFloat, units }), ov_conv: UC.newBoolean(LANG.ou_conv_s, undefined, { title: LANG.ou_conv_l }), exp_end: UC.endExpand(), sep: UC.newBlank({ class: "pop-sep" }), @@ -451,26 +453,26 @@ export function createPopOps() { }).inputs = { tool: UC.newSelect(LANG.cc_tool, {}, "tools"), sep: UC.newBlank({ class: "pop-sep" }), - spindle: UC.newInput(LANG.cc_spnd_s, { title: LANG.cc_spnd_l, convert: UC.toInt, show: hasSpindle }), - rate: UC.newInput(LANG.cc_feed_s, { title: LANG.cc_feed_l, convert: UC.toInt, units: true }), - plunge: UC.newInput(LANG.cc_plng_s, { title: LANG.cc_plng_l, convert: UC.toInt, units: true }), + spindle: UC.newInput(LANG.cc_spnd_s, { title: LANG.cc_spnd_l, convert: toInt, show: hasSpindle }), + rate: UC.newInput(LANG.cc_feed_s, { title: LANG.cc_feed_l, convert: toInt, units }), + plunge: UC.newInput(LANG.cc_plng_s, { title: LANG.cc_plng_l, convert: toInt, units }), sep: UC.newBlank({ class: "pop-sep" }), - step: UC.newInput(LANG.cc_sovr_s, { title: LANG.cc_sovr_l, convert: UC.toFloat, bound: UC.bound(0.01, 1.0) }), - down: UC.newInput(LANG.cc_sdwn_s, { title: LANG.cc_sdwn_l, convert: UC.toFloat, units: true, show: () => !env.poppedRec.contour }), + step: UC.newInput(LANG.cc_sovr_s, { title: LANG.cc_sovr_l, convert: toFloat, bound: UC.bound(0.01, 1.0) }), + down: UC.newInput(LANG.cc_sdwn_s, { title: LANG.cc_sdwn_l, convert: toFloat, units, show: () => !env.poppedRec.contour }), sep: UC.newBlank({ class: "pop-sep" }), - expand: UC.newInput(LANG.cp_xpnd_s, { title: LANG.cp_xpnd_l, convert: UC.toFloat, units: true, xshow: () => !env.poppedRec.contour }), - refine: UC.newInput(LANG.cp_refi_s, { title: LANG.cp_refi_l, convert: UC.toInt, show: () => env.poppedRec.contour }), - smooth: UC.newInput(LANG.cp_smoo_s, { title: LANG.cp_smoo_l, convert: UC.toInt }), - tolerance: UC.newInput(LANG.ou_toll_s, { title: LANG.ou_toll_l, convert: UC.toFloat, bound: UC.bound(0, 10.0), units: true, round: 4, show: () => env.poppedRec.contour }), - follow: UC.newInput(LANG.cp_foll_s, { title: LANG.cp_foll_l, convert: UC.toFloat }), + expand: UC.newInput(LANG.cp_xpnd_s, { title: LANG.cp_xpnd_l, convert: toFloat, units, xshow: () => !env.poppedRec.contour }), + refine: UC.newInput(LANG.cp_refi_s, { title: LANG.cp_refi_l, convert: toInt, show: () => env.poppedRec.contour }), + smooth: UC.newInput(LANG.cp_smoo_s, { title: LANG.cp_smoo_l, convert: toInt }), + tolerance: UC.newInput(LANG.ou_toll_s, { title: LANG.ou_toll_l, convert: toFloat, bound: UC.bound(0, 10.0), units, round: 4, show: () => env.poppedRec.contour }), + follow: UC.newInput(LANG.cp_foll_s, { title: LANG.cp_foll_l, convert: toFloat }), sep: UC.newBlank({ class: "pop-sep" }), contour: UC.newBoolean(LANG.cp_cont_s, undefined, { title: LANG.cp_cont_s }), engrave: UC.newBoolean(LANG.cp_engr_s, undefined, { title: LANG.cp_engr_l, show: () => env.poppedRec.contour }), outline: UC.newBoolean(LANG.cp_outl_s, undefined, { title: LANG.cp_outl_l }), exp: UC.newExpand("overrides"), sep: UC.newBlank({ class: "pop-sep" }), - ov_topz: UC.newInput(LANG.ou_ztop_s, { title: LANG.ou_ztop_l, convert: UC.toFloat, units: true }), - ov_botz: UC.newInput(LANG.ou_zbot_s, { title: LANG.ou_zbot_l, convert: UC.toFloat, units: true }), + ov_topz: UC.newInput(LANG.ou_ztop_s, { title: LANG.ou_ztop_l, convert: toFloat, units }), + ov_botz: UC.newInput(LANG.ou_zbot_s, { title: LANG.ou_zbot_l, convert: toFloat, units }), ov_conv: UC.newBoolean(LANG.ou_conv_s, undefined, { title: LANG.ou_conv_l }), exp_end: UC.endExpand(), sep: UC.newBlank({ class: "pop-sep" }), @@ -491,16 +493,16 @@ export function createPopOps() { }).inputs = { tool: UC.newSelect(LANG.cc_tool, {}, "tools"), sep: UC.newBlank({ class: "pop-sep" }), - spindle: UC.newInput(LANG.cc_spnd_s, { title: LANG.cc_spnd_l, convert: UC.toInt, show: hasSpindle }), - rate: UC.newInput(LANG.cc_plng_s, { title: LANG.cc_plng_l, convert: UC.toInt, units: true }), - down: UC.newInput(LANG.cc_sdwn_s, { title: LANG.cc_sdwn_l, convert: UC.toFloat, units: true }), - dwell: UC.newInput(LANG.cd_dwll_s, { title: LANG.cd_dwll_l, convert: UC.toFloat }), - lift: UC.newInput(LANG.cd_lift_s, { title: LANG.cd_lift_l, convert: UC.toFloat, units: true, show: () => !env.poppedRec.mark }), + spindle: UC.newInput(LANG.cc_spnd_s, { title: LANG.cc_spnd_l, convert: toInt, show: hasSpindle }), + rate: UC.newInput(LANG.cc_plng_s, { title: LANG.cc_plng_l, convert: toInt, units }), + down: UC.newInput(LANG.cc_sdwn_s, { title: LANG.cc_sdwn_l, convert: toFloat, units }), + dwell: UC.newInput(LANG.cd_dwll_s, { title: LANG.cd_dwll_l, convert: toFloat }), + lift: UC.newInput(LANG.cd_lift_s, { title: LANG.cd_lift_l, convert: toFloat, units, show: () => !env.poppedRec.mark }), mark: UC.newBoolean(LANG.cd_mark_s, undefined, { title: LANG.cd_mark_l, show: () => !env.poppedRec.fromTop }), fromTop: UC.newBoolean(LANG.cd_ftop_s, undefined, { title: LANG.cd_ftop_l, show: () => !env.poppedRec.mark }), sep: UC.newBlank({ class: "pop-sep" }), - thru: UC.newInput(LANG.cd_dtru_s, { title: LANG.cd_dtru_l, convert: UC.toFloat, units: true, show: () => !env.poppedRec.mark }), - precision: UC.newInput(LANG.cd_prcn_s, { title: LANG.cd_prcn_l, convert: UC.toFloat, units: true, show: () => !env.poppedRec.mark }), + thru: UC.newInput(LANG.cd_dtru_s, { title: LANG.cd_dtru_l, convert: toFloat, units, show: () => !env.poppedRec.mark }), + precision: UC.newInput(LANG.cd_prcn_s, { title: LANG.cd_prcn_l, convert: toFloat, units, show: () => !env.poppedRec.mark }), sep: UC.newBlank({ class: "pop-sep", }), actions: UC.newRow([ UC.newButton(LANG.select, () => selectHoles(true), { title: LANG.cd_seli_l }), @@ -523,16 +525,16 @@ export function createPopOps() { axis: UC.newSelect(LANG.cd_axis, {}, "regaxis"), points: UC.newSelect(LANG.cd_points, {show:() => env.poppedRec.axis !== '-'}, "regpoints"), sep: UC.newBlank({class:"pop-sep"}), - spindle: UC.newInput(LANG.cc_spnd_s, {title:LANG.cc_spnd_l, convert:UC.toInt, show:hasSpindle}), - rate: UC.newInput(LANG.cc_plng_s, {title:LANG.cc_plng_l, convert:UC.toInt, units:true}), - feed: UC.newInput(LANG.cc_feed_s, {title:LANG.cc_feed_l, convert:UC.toInt, units:true, show:() => env.poppedRec.axis === '-'}), + spindle: UC.newInput(LANG.cc_spnd_s, {title:LANG.cc_spnd_l, convert:toInt, show:hasSpindle}), + rate: UC.newInput(LANG.cc_plng_s, {title:LANG.cc_plng_l, convert:toInt, units:true}), + feed: UC.newInput(LANG.cc_feed_s, {title:LANG.cc_feed_l, convert:toInt, units:true, show:() => env.poppedRec.axis === '-'}), sep: UC.newBlank({class:"pop-sep"}), - down: UC.newInput(LANG.cc_sdwn_s, {title:LANG.cc_sdwn_l, convert:UC.toFloat, units:true}), - dwell: UC.newInput(LANG.cd_dwll_s, {title:LANG.cd_dwll_l, convert:UC.toFloat, show:() => env.poppedRec.axis !== '-'}), - lift: UC.newInput(LANG.cd_lift_s, {title:LANG.cd_lift_l, convert:UC.toFloat, units:true, show:() => env.poppedRec.axis !== '-'}), + down: UC.newInput(LANG.cc_sdwn_s, {title:LANG.cc_sdwn_l, convert:toFloat, units:true}), + dwell: UC.newInput(LANG.cd_dwll_s, {title:LANG.cd_dwll_l, convert:toFloat, show:() => env.poppedRec.axis !== '-'}), + lift: UC.newInput(LANG.cd_lift_s, {title:LANG.cd_lift_l, convert:toFloat, units:true, show:() => env.poppedRec.axis !== '-'}), sep: UC.newBlank({class:"pop-sep"}), - offset: UC.newInput(LANG.cd_rego_s, {title:LANG.cd_rego_l, convert:UC.toFloat, units:true, }), - thru: UC.newInput(LANG.cd_thru_s, {title:LANG.cd_thru_l, convert:UC.toFloat, units:true}), + offset: UC.newInput(LANG.cd_rego_s, {title:LANG.cd_rego_l, convert:toFloat, units:true, }), + thru: UC.newInput(LANG.cd_thru_s, {title:LANG.cd_thru_l, convert:toFloat, units:true}), }; createPopOp('helical', { @@ -556,15 +558,15 @@ export function createPopOps() { tool: UC.newSelect(LANG.cc_tool, {}, "tools"), offset: UC.newSelect(LANG.cc_offs_s, {title: LANG.cc_offs_l,}, "helicaloff"), sep: UC.newBlank({class:"pop-sep"}), - spindle: UC.newInput(LANG.cc_spnd_s, {title:LANG.cc_spnd_l, convert:UC.toInt, show:hasSpindle}), - rate: UC.newInput(LANG.cc_plng_s, {title:LANG.cc_plng_l, convert:UC.toFloat, units:true}), - feed: UC.newInput(LANG.cc_feed_s, {title:LANG.cc_feed_l, convert:UC.toFloat, units:true}), - down: UC.newInput(LANG.ch_sdwn_s, {title:LANG.ch_sdwn_l, convert:UC.toFloat, units:true}), + spindle: UC.newInput(LANG.cc_spnd_s, {title:LANG.cc_spnd_l, convert:toInt, show:hasSpindle}), + rate: UC.newInput(LANG.cc_plng_s, {title:LANG.cc_plng_l, convert:toFloat, units:true}), + feed: UC.newInput(LANG.cc_feed_s, {title:LANG.cc_feed_l, convert:toFloat, units:true}), + down: UC.newInput(LANG.ch_sdwn_s, {title:LANG.ch_sdwn_l, convert:toFloat, units:true}), startAng: UC.newInput(LANG.ch_stra_s, {title:LANG.ch_stra_l, convert:UC.toDegsFloat, bound:UC.bound(-360,360),show:() => env.poppedRec.forceStartAng}), - offOver: UC.newInput(LANG.cc_offd_s, {title:LANG.cc_offd_l, convert:UC.toFloat, units:true, bound:UC.bound(0,Infinity)}), + offOver: UC.newInput(LANG.cc_offd_s, {title:LANG.cc_offd_l, convert:toFloat, units:true, bound:UC.bound(0,Infinity)}), sep: UC.newBlank({class:"pop-sep"}), entry: UC.newBoolean(LANG.ch_entr_s,undefined, {title:LANG.ch_entr_l}), - entryOffset: UC.newInput(LANG.ch_ento_s, {title:LANG.ch_ento_l, convert:UC.toFloat, units:true, show:() => env.poppedRec.entry}), + entryOffset: UC.newInput(LANG.ch_ento_s, {title:LANG.ch_ento_l, convert:toFloat, units:true, show:() => env.poppedRec.entry}), reverse: UC.newBoolean(LANG.ch_rvrs_s,undefined, {title:LANG.ch_rvrs_l}), clockwise:UC.newBoolean(LANG.ch_clkw_s,undefined, {title:LANG.ch_clkw_l}), sep: UC.newBlank({class:"pop-sep"}), @@ -572,7 +574,7 @@ export function createPopOps() { forceStartAng: UC.newBoolean(LANG.ch_fsta_s, undefined, {title:LANG.ch_fsta_l }), fromTop: UC.newBoolean(LANG.cd_ftop_s,undefined, {title:LANG.cd_ftop_l}), sep: UC.newBlank({class:"pop-sep"}), - thru: UC.newInput(LANG.cd_thru_s, {title:LANG.cd_thru_l, convert:UC.toFloat, units:true}), + thru: UC.newInput(LANG.cd_thru_s, {title:LANG.cd_thru_l, convert:toFloat, units:true}), actions: UC.newRow([ UC.newButton(LANG.select, selectHelical, {title:LANG.cd_seli_l}), ], {class:"ext-buttons f-col"}) @@ -603,7 +605,7 @@ export function createPopOps() { degrees: 'camIndexAxis', absolute: 'camIndexAbs' }).inputs = { - degrees: UC.newInput(LANG.ci_degr_s, { title: LANG.ci_degr_l, convert: UC.toFloat, bound: UC.bound(-360, 360.0) }), + degrees: UC.newInput(LANG.ci_degr_s, { title: LANG.ci_degr_l, convert: toFloat, bound: UC.bound(-360, 360.0) }), absolute: UC.newBoolean(LANG.ci_abso_s, undefined, { title: LANG.ci_abso_l }), select: UC.newRow([UC.newButton(LANG.ci_face_s, angleTowardZUp)], { class: "ext-buttons f-row" }) }; @@ -630,12 +632,12 @@ export function createPopOps() { on: UC.newRow([UC.newButton(LANG.on, editOn)], { class: "ext-buttons f-row" }), off: UC.newRow([UC.newButton(LANG.off, editOff)], { class: "ext-buttons f-row" }), sep: UC.newBlank({ class: "pop-sep" }), - power: UC.newInput(LANG.cl_powr_s, { title: LANG.cl_powr_l, convert: UC.toFloat, bound: UC.bound(0, 1.0), show: () => !env.poppedRec.adapt }), - maxp: UC.newInput(LANG.cl_maxp_s, { title: LANG.cl_maxp_l, convert: UC.toFloat, bound: UC.bound(0, 1.0), show: () => env.poppedRec.adapt }), - minp: UC.newInput(LANG.cl_minp_s, { title: LANG.cl_minp_l, convert: UC.toFloat, bound: UC.bound(0, 1.0), show: () => env.poppedRec.adapt }), - maxz: UC.newInput(LANG.cl_maxz_s, { title: LANG.cl_maxz_l, convert: UC.toFloat, show: () => env.poppedRec.adapt }), - minz: UC.newInput(LANG.cl_minz_s, { title: LANG.cl_minz_l, convert: UC.toFloat, show: () => env.poppedRec.adapt }), - flatz: UC.newInput(LANG.cl_flaz_s, { title: LANG.cl_flaz_l, convert: UC.toFloat, show: () => env.poppedRec.flat }), + power: UC.newInput(LANG.cl_powr_s, { title: LANG.cl_powr_l, convert: toFloat, bound: UC.bound(0, 1.0), show: () => !env.poppedRec.adapt }), + maxp: UC.newInput(LANG.cl_maxp_s, { title: LANG.cl_maxp_l, convert: toFloat, bound: UC.bound(0, 1.0), show: () => env.poppedRec.adapt }), + minp: UC.newInput(LANG.cl_minp_s, { title: LANG.cl_minp_l, convert: toFloat, bound: UC.bound(0, 1.0), show: () => env.poppedRec.adapt }), + maxz: UC.newInput(LANG.cl_maxz_s, { title: LANG.cl_maxz_l, convert: toFloat, show: () => env.poppedRec.adapt }), + minz: UC.newInput(LANG.cl_minz_s, { title: LANG.cl_minz_l, convert: toFloat, show: () => env.poppedRec.adapt }), + flatz: UC.newInput(LANG.cl_flaz_s, { title: LANG.cl_flaz_l, convert: toFloat, show: () => env.poppedRec.flat }), sep: UC.newBlank({ class: "pop-sep" }), adapt: UC.newBoolean(LANG.cl_adap_s, undefined, { title: LANG.cl_adap_l }), adaptrp: UC.newBoolean(LANG.cl_adrp_s, undefined, { title: LANG.cl_adrp_l, show: () => env.poppedRec.adapt }), @@ -671,21 +673,21 @@ export function createPopOps() { tool: UC.newSelect(LANG.cc_tool, {}, "tools"), mode: UC.newSelect(LANG.mo_menu, {}, "opmode"), sep: UC.newBlank({ class: "pop-sep" }), - spindle: UC.newInput(LANG.cc_spnd_s, { title: LANG.cc_spnd_l, convert: UC.toInt, show: hasSpindle }), - rate: UC.newInput(LANG.cc_feed_s, { title: LANG.cc_feed_l, convert: UC.toInt, units: true }), - plunge: UC.newInput(LANG.cc_plng_s, { title: LANG.cc_plng_l, convert: UC.toInt, units: true }), + spindle: UC.newInput(LANG.cc_spnd_s, { title: LANG.cc_spnd_l, convert: toInt, show: hasSpindle }), + rate: UC.newInput(LANG.cc_feed_s, { title: LANG.cc_feed_l, convert: toInt, units }), + plunge: UC.newInput(LANG.cc_plng_s, { title: LANG.cc_plng_l, convert: toInt, units }), sep: UC.newBlank({ class: "pop-sep" }), - over: UC.newInput(LANG.cc_sovr_s, { title: LANG.cc_sovr_l, convert: UC.toFloat, bound: UC.bound(0.01, 1.0) }), - down: UC.newInput(LANG.cc_sdwn_s, { title: LANG.cc_sdwn_l, convert: UC.toFloat, units: true }), + over: UC.newInput(LANG.cc_sovr_s, { title: LANG.cc_sovr_l, convert: toFloat, bound: UC.bound(0.001, 100.0), units }), + down: UC.newInput(LANG.cc_sdwn_s, { title: LANG.cc_sdwn_l, convert: toFloat, bound: UC.bound(0, 100), units }), sep: UC.newBlank({ class: "pop-sep" }), - expand: UC.newInput(LANG.cp_xpnd_s, { title: LANG.cp_xpnd_l, convert: UC.toFloat, units: true }), - refine: UC.newInput(LANG.cp_refi_s, { title: LANG.cp_refi_l, convert: UC.toInt }), - smooth: UC.newInput(LANG.cp_smoo_s, { title: LANG.cp_smoo_l, convert: UC.toInt }), - tolerance: UC.newInput(LANG.ou_toll_s, { title: LANG.ou_toll_l, convert: UC.toFloat, bound: UC.bound(0, 10.0), units: true, round: 4 }), + expand: UC.newInput(LANG.cp_xpnd_s, { title: LANG.cp_xpnd_l, convert: toFloat, units }), + refine: UC.newInput(LANG.cp_refi_s, { title: LANG.cp_refi_l, convert: toInt }), + smooth: UC.newInput(LANG.cp_smoo_s, { title: LANG.cp_smoo_l, convert: toInt }), + tolerance: UC.newInput(LANG.ou_toll_s, { title: LANG.ou_toll_l, convert: toFloat, bound: UC.bound(0, 10.0), units, round: 4 }), exp: UC.newExpand("overrides"), sep: UC.newBlank({ class: "pop-sep" }), - ov_topz: UC.newInput(LANG.ou_ztop_s, { title: LANG.ou_ztop_l, convert: UC.toFloat, units: true }), - ov_botz: UC.newInput(LANG.ou_zbot_s, { title: LANG.ou_zbot_l, convert: UC.toFloat, units: true }), + ov_topz: UC.newInput(LANG.ou_ztop_s, { title: LANG.ou_ztop_l, convert: toFloat, units }), + ov_botz: UC.newInput(LANG.ou_zbot_s, { title: LANG.ou_zbot_l, convert: toFloat, units }), ov_conv: UC.newBoolean(LANG.ou_conv_s, undefined, { title: LANG.ou_conv_l }), exp_end: UC.endExpand(), sep: UC.newBlank({ class: "pop-sep" }), diff --git a/src/kiri/mode/cam/op-area.js b/src/kiri/mode/cam/op-area.js new file mode 100644 index 00000000..554cca5a --- /dev/null +++ b/src/kiri/mode/cam/op-area.js @@ -0,0 +1,102 @@ +/** Copyright Stewart Allen -- All Rights Reserved */ + +import { CamOp } from './op.js'; +import { Tool } from './tool.js'; +import { generate as Topo } from './topo3.js'; +import { newSlice } from '../../core/slice.js'; +import { newPolygon } from '../../../geo/polygon.js'; +import { polygons as POLY } from '../../../geo/polygons.js'; +import { util as base_util } from '../../../geo/base.js'; +import { calc_normal, calc_vertex } from '../../../geo/paths.js'; +import { CAM } from './driver-be.js'; + +const DEG2RAG = Math.PI / 180; + +class OpArea extends CamOp { + constructor(state, op) { + super(state, op); + } + + async slice(progress) { + const pocket = this; + let { op, state } = this; + let { tool, mode, down, over, follow, expand, plunge, smooth, tolerance } = op; + let { ov_topz, ov_botz, ov_conv } = op; + let { settings, widget, zBottom, tabs, color } = state; + let { addSlices, setToolDiam, cutTabs, healPolys, shadowAt, workarea } = state; + + let areaTool = new Tool(settings, tool); + let toolDiam = areaTool.fluteDiameter(); + + zBottom = ov_botz ? workarea.bottom_stock + ov_botz : zBottom; + + setToolDiam(toolDiam); + + // selected area polygons: surfaces and edges + let { devel, edgeangle } = settings.controller; + let groups = []; + let polys = []; + + function newGroup() { + groups.push(newSlice()); + return groups.peek(); + } + + // gather area selections + for (let arr of (op.areas[widget.id] ?? [])) { + polys.push(newPolygon().fromArray(arr)); + } + + // gather surface selections + let vert = widget.getGeoVertices({ unroll: true, translate: true }).map(v => v.round(4)); + let faces = CAM.surface_find(widget, (op.surfaces[widget.id] ?? []), (follow ?? edgeangle ?? 5) * DEG2RAG); + for (let face of faces) { + let i = face * 9; + polys.push(newPolygon() + .add(vert[i++], vert[i++], vert[i++]) + .add(vert[i++], vert[i++], vert[i++]) + .add(vert[i++], vert[i++], vert[i++]) + ); + } + + // connect open poly edge segments into closed loops (when possible) + // surface and edge selections produce open polygons by default + polys = POLY.nest(healPolys(polys)); + + // expand selections (flattens z variable polys) + if (Math.abs(expand) > 0) { + let nupolys = polys.filter(p => p.open); // set aside open + for (let p of polys.filter(p => !p.open)) { + let expanded = POLY.expand([ p ], expand); + if (expanded) { + POLY.setZ(expanded, p.minZ()); + nupolys.push(...expanded.flat()); + } + } + polys = nupolys; + } + + // process each area separately + for (let area of polys) { + let bounds = area.getBound3D(); + console.log({ area, bounds }); + + if (devel) newGroup().output() + .setLayer("areas", { line: 0xff8800 }, false) + .addPolys(polys); + } + + addSlices(groups); + } + + prepare(ops, progress) { + let { op, state, pockets } = this; + let { getPrintPoint , pocket, setTool, setSpindle, setTolerance } = ops; + let { process } = state.settings; + + setTool(op.tool, op.rate); + setSpindle(op.spindle); + } +} + +export { OpArea }; diff --git a/src/kiri/mode/cam/ops.js b/src/kiri/mode/cam/ops.js index 003a7dcc..79e4c7f0 100644 --- a/src/kiri/mode/cam/ops.js +++ b/src/kiri/mode/cam/ops.js @@ -1,39 +1,41 @@ /** Copyright Stewart Allen -- All Rights Reserved */ -import { OpXRay } from './op-xray.js'; -import { OpShadow } from './op-shadow.js'; -import { OpLevel } from './op-level.js'; -import { OpRough } from './op-rough.js'; -import { OpOutline } from './op-outline.js'; -import { OpContour } from './op-contour.js'; -import { OpPocket } from './op-pocket.js'; -import { OpLathe } from './op-lathe.js'; -import { OpTrace } from './op-trace.js'; -import { OpDrill } from './op-drill.js'; -import { OpRegister } from './op-register.js'; -import { OpLaserOn } from './op-laser-on.js'; -import { OpLaserOff } from './op-laser-off.js'; -import { OpGCode } from './op-gcode.js'; -import { OpIndex } from './op-index.js'; import { CamOp } from './op.js'; +import { OpArea } from './op-area.js'; +import { OpContour } from './op-contour.js'; +import { OpDrill } from './op-drill.js'; +import { OpGCode } from './op-gcode.js'; import { OpHelical } from './op-helical.js'; +import { OpIndex } from './op-index.js'; +import { OpLaserOff } from './op-laser-off.js'; +import { OpLaserOn } from './op-laser-on.js'; +import { OpLathe } from './op-lathe.js'; +import { OpLevel } from './op-level.js'; +import { OpOutline } from './op-outline.js'; +import { OpPocket } from './op-pocket.js'; +import { OpRegister } from './op-register.js'; +import { OpRough } from './op-rough.js'; +import { OpShadow } from './op-shadow.js'; +import { OpTrace } from './op-trace.js'; +import { OpXRay } from './op-xray.js'; export const ops = { - "xray": OpXRay, - "shadow": OpShadow, - "level": OpLevel, - "rough": OpRough, - "outline": OpOutline, + "area": OpArea, "contour": OpContour, - "pocket": OpPocket, - "lathe": OpLathe, - "trace": OpTrace, "drill": OpDrill, - "register": OpRegister, - "helical": OpHelical, - "laser on": OpLaserOn, - "laser off": OpLaserOff, + "flip": CamOp, "gcode": OpGCode, + "helical": OpHelical, "index": OpIndex, - "flip": CamOp + "laser off": OpLaserOff, + "laser on": OpLaserOn, + "lathe": OpLathe, + "level": OpLevel, + "outline": OpOutline, + "pocket": OpPocket, + "register": OpRegister, + "rough": OpRough, + "shadow": OpShadow, + "trace": OpTrace, + "xray": OpXRay }; diff --git a/src/kiri/mode/cam/slice.js b/src/kiri/mode/cam/slice.js index 28585e37..e9bde765 100644 --- a/src/kiri/mode/cam/slice.js +++ b/src/kiri/mode/cam/slice.js @@ -139,7 +139,6 @@ export async function cam_slice(settings, widget, onupdate, ondone) { alert(`invalid z bottom ${(zMin / units).round(3)} >= bounds z max ${(zMax / units).round(3)}`); } - let mark = Date.now(); let opList = []; let opSum = 0; let opTot = 0; @@ -158,6 +157,7 @@ export async function cam_slice(settings, widget, onupdate, ondone) { isIndexed, ops: opList, setAxisIndex, + setToolDiam, settings, shadowAt, slicer, @@ -209,6 +209,15 @@ export async function cam_slice(settings, widget, onupdate, ondone) { }); } + function setToolDiam(toolDiam) { + updateToolDiams(toolDiam); + if (tabs) { + tabs.forEach(tab => { + tab.off = POLY.expand([ tab.poly ], toolDiam / 2).flat(); + }); + } + } + function updateToolDiams(toolDiam) { minToolDiam = Math.min(minToolDiam, toolDiam); maxToolDiam = Math.max(maxToolDiam, toolDiam); @@ -233,9 +242,7 @@ export async function cam_slice(settings, widget, onupdate, ondone) { if (minZabove) { // const merge = shadow.length; // const plus = shadows[minZabove].length; - // const mark = Date.now(); shadow = POLY.union([...shadow, ...shadows[minZabove]], 0.001, true); - // console.log({merge, plus, equals: shadow.length, time: Date.now() - mark}); } return shadows[z] = POLY.setZ(shadow, z); } @@ -654,7 +661,7 @@ export function cylinder_poly_find(widget, face) { */ export async function holes(settings, widget, individual, rec, onProgress) { - let { tool, mark, precision } = rec //TODO: display some visual difference if mark is selected + let { tool, precision } = rec //TODO: display some visual difference if mark is selected let toolDiam = new Tool(settings, tool).fluteDiameter() let diam = individual ? 1 : toolDiam; // sets default diameter when select individual used