diff --git a/src/kiri/conf.js b/src/kiri/conf.js index 07d7e698..e7d2fcd8 100644 --- a/src/kiri/conf.js +++ b/src/kiri/conf.js @@ -424,6 +424,7 @@ camOutlineSpeed: 800, camOutlinePlunge: 250, camOutlineWide: false, + camOutlineDogbone: false, camOutlineOut: true, camOutlineIn: false, camOutlineOn: true, diff --git a/src/kiri/init.js b/src/kiri/init.js index 36d6dde2..e3c96024 100644 --- a/src/kiri/init.js +++ b/src/kiri/init.js @@ -1594,6 +1594,7 @@ camOutlineDown: UC.newInput(LANG.cc_sdwn_s, {title:LANG.cc_sdwn_l, convert:UC.toFloat, modes:CAM, units:true}), camOutlineSpeed: UC.newInput(LANG.cc_feed_s, {title:LANG.cc_feed_l, convert:UC.toInt, modes:CAM, units:true}), camOutlinePlunge: UC.newInput(LANG.cc_plng_s, {title:LANG.cc_plng_l, convert:UC.toInt, modes:CAM, units:true}), + camOutlineDogbone: UC.newBoolean(LANG.co_dogb_s, onBooleanClick, {title:LANG.co_dogb_l, modes:CAM}), camOutlineIn: UC.newBoolean(LANG.co_olin_s, onBooleanClick, {title:LANG.co_olin_l, modes:CAM, show:() => { return !UI.camOutlineOut.checked }}), camOutlineOut: UC.newBoolean(LANG.co_olot_s, onBooleanClick, {title:LANG.co_olot_l, modes:CAM, show:() => { return !UI.camOutlineIn.checked }}), camOutlineWide: UC.newBoolean(LANG.co_wide_s, onBooleanClick, {title:LANG.co_wide_l, modes:CAM, show:() => { return !UI.camOutlineIn.checked }}), diff --git a/src/mode/cam/slice.js b/src/mode/cam/slice.js index 464016a0..fd14d613 100644 --- a/src/mode/cam/slice.js +++ b/src/mode/cam/slice.js @@ -477,6 +477,10 @@ offset = cutTabs(tabs, offset, slice.z); } + if (proc.camOutlineDogbone) { + CAM.addDogbones(offset, outlineToolDiam / 4); + } + // offset.xout(`slice ${slice.z}`); slice.camLines = offset; if (false) slice.output() @@ -567,7 +571,41 @@ ondone(); }; - CAM.traces = function computeTraces(settings, widget) { + CAM.addDogbones = function(poly, dist) { + if (Array.isArray(poly)) { + return poly.forEach(p => CAM.addDogbones(p, dist)); + } + let isCW = poly.isClockwise(); + let oldpts = poly.points.slice(); + let lastpt = oldpts[oldpts.length - 1]; + let lastsl = lastpt.slopeTo(oldpts[0]).toUnit(); + let newpts = [ ]; + for (let i=0; i 0) { + let newa = BASE.newSlopeFromAngle(lastsl.angle - adiff / 2); + newpts.push(lastpt.projectOnSlope(newa, dist)); + newpts.push(lastpt.clone()); + console.log('CW dogbone at', lastpt); + } else if (!isCW && adiff < 0) { + console.log('CCW dogbone at', lastpt); + let newa = BASE.newSlopeFromAngle(lastsl.angle - adiff / 2); + newpts.push(lastpt.projectOnSlope(newa, dist)); + newpts.push(lastpt.clone()); + } + lastsl = nextsl; + lastpt = nextpt; + if (i < oldpts.length) { + newpts.push(nextpt); + } + } + poly.points = newpts; + poly.length = newpts.length; + }; + + CAM.traces = function(settings, widget) { if (widget.traces) { // do no work if cached return false; diff --git a/src/mode/laser/driver.js b/src/mode/laser/driver.js index 3557eafe..2b6cebb8 100644 --- a/src/mode/laser/driver.js +++ b/src/mode/laser/driver.js @@ -173,11 +173,14 @@ for (let i=1; i= 10 && lastpt.distTo2D(nextpt) >= knifeTipOff) { - arc(lastpt, lastsl, nextsl, newpts); - // let tmp; - // newpts.push( tmp = lastpt.projectOnSlope(lastsl, knifeTipOff) ); - // newpts.push( lastpt.projectOnSlope(nextsl, knifeTipOff) ); + if (lastsl.angleDiff(nextsl) >= 10) { + if (lastpt.distTo2D(nextpt) >= knifeTipOff) { + arc(lastpt, lastsl, nextsl, newpts); + } else { + // todo handle short segments + // newpts.push(lastpt.projectOnSlope(lastsl, knifeTipOff) ); + // newpts.push( lastpt.projectOnSlope(nextsl, knifeTipOff) ); + } } newpts.push(nextpt); lastsl = nextsl; diff --git a/web/kiri/lang/en.js b/web/kiri/lang/en.js index 9c92f342..fd647275 100644 --- a/web/kiri/lang/en.js +++ b/web/kiri/lang/en.js @@ -289,6 +289,8 @@ kiri.lang['en-us'] = { // CNC OUTLINE co_menu: "outline", + co_dogb_s: "dogbones", + co_dogb_l: "insert dogbone cuts\ninto inside corners", co_wide_s: "wide cutout", co_wide_l: "widen outside cutout paths\nfor deep cuts in hard material", co_olin_s: "inside only",