diff --git a/src/kiri/conf.js b/src/kiri/conf.js index faadefb6..313078e3 100644 --- a/src/kiri/conf.js +++ b/src/kiri/conf.js @@ -404,6 +404,7 @@ camRoughPlunge: 250, camRoughStock: 0, camRoughVoid: false, + camRoughIn: false, camRoughOn: true, camOutlineTool: 1000, camOutlineSpindle: 1000, diff --git a/src/kiri/init.js b/src/kiri/init.js index 01d238c9..be0afc40 100644 --- a/src/kiri/init.js +++ b/src/kiri/init.js @@ -1441,6 +1441,7 @@ camRoughPlunge: UC.newInput(LANG.cc_plng_s, {title:LANG.cc_plng_l, convert:UC.toInt, modes:CAM, units:true}), camRoughStock: UC.newInput(LANG.cr_lsto_s, {title:LANG.cr_lsto_l, convert:UC.toFloat, modes:CAM, units:true}), camRoughVoid: UC.newBoolean(LANG.cr_clrp_s, onBooleanClick, {title:LANG.cr_clrp_l, modes:CAM}), + camRoughIn: UC.newBoolean(LANG.cr_olin_s, onBooleanClick, {title:LANG.cr_olin_l, modes:CAM}), camRoughSep: UC.newBlank({class:"pop-sep"}), camRoughOn: UC.newBoolean(LANG.enable, onBooleanClick, {modes:CAM}), camOutline: UC.newGroup(LANG.co_menu, null, {modes:CAM, marker:true}), @@ -1479,7 +1480,7 @@ camDrillingOn: UC.newBoolean(LANG.enable, onBooleanClick, {modes:CAM}), camDrillSep: UC.newBlank({class:"pop-sep"}), camDrillReg: UC.newSelect(LANG.cd_regi_s, {modes:CAM, title:LANG.cd_regi_l}, "drillreg"), - camTabs: UC.newGroup(LANG.ct_menu, null, {modes:CAM, marker:true, show:() => { return UI.camOutlineOn.checked }}), + camTabs: UC.newGroup(LANG.ct_menu, null, {modes:CAM, marker:true, show:() => { return UI.camOutlineOn.checked || UI.camRoughOn.checked }}), camTabsAngle: UC.newInput(LANG.ct_angl_s, {title:LANG.ct_angl_l, convert:UC.toInt, bound:UC.bound(0,360), modes:CAM}), camTabsCount: UC.newInput(LANG.ct_numb_s, {title:LANG.ct_numb_l, convert:UC.toInt, bound:UC.bound(1,20), modes:CAM}), camTabsWidth: UC.newInput(LANG.ct_wdth_s, {title:LANG.ct_wdth_l, convert:UC.toFloat, bound:UC.bound(0.1,100), modes:CAM, units:true}), diff --git a/src/mode/cam/slice.js b/src/mode/cam/slice.js index d0fd5a95..a85c6e1f 100644 --- a/src/mode/cam/slice.js +++ b/src/mode/cam/slice.js @@ -45,7 +45,7 @@ roughDown = procRough ? proc.camRoughDown : Infinity, outlineDown = procOutline ? proc.camOutlineDown : Infinity, sliceDepth = Math.max(0.1, Math.min(roughDown, outlineDown) / 3), - addTabsOutline = procOutlineOn && proc.camTabsOn, + addTabsOutline = (procOutlineOn || procRough) && proc.camTabsOn, tabWidth = proc.camTabsWidth, tabHeight = proc.camTabsHeight, bounds = widget.getBoundingBox(), @@ -122,11 +122,9 @@ tslices.push(data.slice); // sliceAll.push(data.slice); // data.slice.output() - // .setLayer("debug", {face: 0xff0000, line: 0}) - // // .addFlats(POLY.setZ(tshadow.clone(true), data.z), {offset: 1, outline: true}); - // // .addPolys(POLY.setZ(tshadow.clone(true), data.z)); - // .addPaths(POLY.setZ(tshadow.clone(true), data.z)); - updateOp(index, total); + // .setLayer("debug", {line: 0x888800, thin: true }) + // .addPolys(POLY.setZ(tshadow.clone(true), data.z), { thin: true }); + // updateOp(index, total); }, genso: true }); let shadowTop = terrain[terrain.length - 1]; @@ -194,13 +192,16 @@ }); shadow = POLY.nest(shadow); + const insideOnly = proc.camRoughIn; + // expand shadow by half tool diameter + stock to leave - let shell = POLY.offset(shadow, (roughToolDiam / 4) + camRoughStock); + const sadd = insideOnly ? roughToolDiam / 4 : roughToolDiam / 2; + const shell = POLY.offset(shadow, sadd + camRoughStock); nextOp(); slices.forEach((slice, index) => { - let shadow = slice.shadow; - let offset = [shell.clone(true),shadow.clone(true)].flat(); + // let shadow = slice.shadow; + let offset = [shell.clone(true),slice.shadow.clone(true)].flat(); let flat = POLY.flatten(offset, [], true); let nest = POLY.setZ(POLY.nest(flat), slice.z); // slice.tops[0].inner = nest; @@ -222,10 +223,25 @@ } }); + // add outside pass if not inside only + if (!insideOnly) { + const outside = POLY.offset(shadow, roughToolDiam * proc.camRoughOver, {z: slice.z}); + if (outside) { + offset.appendAll(outside); + if (addTabsOutline && slice.z <= zMin + tabHeight) { + offset = addCutoutTabs(offset, slice.z, roughToolDiam, tabWidth, proc.camTabsCount, proc.camTabsAngle); + } + } + } + if (!offset) return; slice.camLines = offset; slice.output() + // .setLayer("rough shadow", {line: 0x00aa00}) + // .addPolys(shadow) + // .setLayer("rough shell", {line: 0xaa0000}) + // .addPolys(shell) .setLayer("roughing", {face: 0, line: 0}) .addPolys(offset); updateOp(index, slices.length); diff --git a/web/kiri/lang/en.js b/web/kiri/lang/en.js index 9d49da08..ca1a7e54 100644 --- a/web/kiri/lang/en.js +++ b/web/kiri/lang/en.js @@ -272,6 +272,8 @@ kiri.lang['en-us'] = { cr_ease_l: "plunge cuts will\nspiral down or ease\nalong a linear path", cr_clrp_s: "clear voids", cr_clrp_l: "mill out through pockets\ninstead of just the outline", + cr_olin_s: "inside only", + cr_olin_l: "limit cutting to\ninside part boundaries", // CNC OUTLINE co_menu: "outline",