diff --git a/src/kiri-mode/cam/client.js b/src/kiri-mode/cam/client.js index b60fcce8..54a1f05c 100644 --- a/src/kiri-mode/cam/client.js +++ b/src/kiri-mode/cam/client.js @@ -1263,6 +1263,7 @@ CAM.init = function(kiri, api) { rate: 'camRoughSpeed', plunge: 'camRoughPlunge', leave: 'camRoughStock', + leavez: 'camRoughStockZ', all: 'camRoughAll', voids: 'camRoughVoid', flats: 'camRoughFlat', @@ -1278,6 +1279,7 @@ CAM.init = function(kiri, api) { 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}), 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}), @@ -1290,6 +1292,7 @@ CAM.init = function(kiri, api) { tool: 'camOutlineTool', spindle: 'camOutlineSpindle', step: 'camOutlineOver', + steps: 'camOutlineOverCount', down: 'camOutlineDown', rate: 'camOutlineSpeed', plunge: 'camOutlinePlunge', @@ -1308,6 +1311,7 @@ CAM.init = function(kiri, api) { 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:() => popOp.outline.rec.wide}), + steps: UC.newInput(LANG.cc_sovc_s, {title:LANG.cc_sovc_l, convert:UC.toInt, bound:UC.bound(1,5), show:() => 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 }}), diff --git a/src/kiri-mode/cam/export.js b/src/kiri-mode/cam/export.js index b2bdfd80..a9ac695b 100644 --- a/src/kiri-mode/cam/export.js +++ b/src/kiri-mode/cam/export.js @@ -43,6 +43,7 @@ CAM.export = function(print, online) { cmdToolChange = device.gcodeChange || [ "M6 T{tool}" ], cmdSpindle = device.gcodeSpindle || [ "M3 S{speed}" ], cmdDwell = device.gcodeDwell || [ "G4 P{time}" ], + axis = { X: 'X', Y: 'Y', Z: 'Z', A: 'A', F: 'F'}, dev = settings.device, spro = settings.process, maxZd = spro.camFastFeedZ, @@ -258,27 +259,27 @@ CAM.export = function(print, online) { pos.x = newpos.x; runbox.min.x = Math.min(runbox.min.x, pos.x); runbox.max.x = Math.max(runbox.max.x, pos.x); - nl.append(space).append("X").append(add0(consts.pos_x = pos.x * factor)); + nl.append(space).append(axis.X).append(add0(consts.pos_x = pos.x * factor)); } if (dy || newpos.y !== pos.y) { pos.y = newpos.y; runbox.min.y = Math.min(runbox.min.y, pos.y); runbox.max.y = Math.max(runbox.max.y, pos.y); - nl.append(space).append("Y").append(add0(consts.pos_y = pos.y * factor)); + nl.append(space).append(axis.Y).append(add0(consts.pos_y = pos.y * factor)); } if (dz || newpos.z !== pos.z) { pos.z = newpos.z; runbox.min.z = Math.min(runbox.min.z, pos.z); runbox.max.z = Math.max(runbox.max.z, pos.z); - nl.append(space).append("Z").append(add0(consts.pos_z = pos.z * factor)); + nl.append(space).append(axis.Z).append(add0(consts.pos_z = pos.z * factor)); } if (da) { pos.a = newpos.a; - nl.append(space).append("A").append(add0(consts.pos_a = pos.a * factor)); + nl.append(space).append(axis.A).append(add0(consts.pos_a = pos.a * factor)); } if (newFeed) { pos.f = feed; - nl.append(space).append("F").append(add0(consts.feed = feed * factor, true)); + nl.append(space).append(axis.F).append(add0(consts.feed = feed * factor, true)); } // temp hack to support RML1 dialect from a file extensions trigger @@ -287,7 +288,7 @@ CAM.export = function(print, online) { if (newFeed) { append(`VS${feed};`); } - nl = [ "Z", add0(pos.x * factor), ",", add0(pos.y * factor), ",", add0(pos.z * factor), ";" ]; + nl = [ axis.Z, add0(pos.x * factor), ",", add0(pos.y * factor), ",", add0(pos.z * factor), ";" ]; } else { nl = [ "PU", add0(pos.x * factor), ",", add0(pos.y * factor), ";" ]; } @@ -348,6 +349,11 @@ CAM.export = function(print, online) { compact_output = true; stripComments = true; space = ''; + } if (line.indexOf(";; AXISMAP ") === 0) { + let axmap = JSON.parse(line.substring(11).trim()); + for (let key in axmap) { + axis[key] = axmap[key]; + } } else { gcodePre.push(line); } diff --git a/src/kiri-mode/cam/ops.js b/src/kiri-mode/cam/ops.js index f3dbb5d4..8e8a77ca 100644 --- a/src/kiri-mode/cam/ops.js +++ b/src/kiri-mode/cam/ops.js @@ -182,7 +182,8 @@ class OpRough extends CamOp { let roughIn = op.inside; let roughTop = op.top; let roughDown = op.down; - let roughLeave = op.leave; + let roughLeave = op.leave || 0; + let roughLeaveZ = op.leavez || 0; let roughStock = op.all && isIndexed; let toolDiam = new CAM.Tool(settings, op.tool).fluteDiameter(); let trueShadow = process.camTrueShadow === true; @@ -210,7 +211,7 @@ class OpRough extends CamOp { for (let z = zstart; zsteps > 0; zsteps--) { let slice = shadowTop.slice.clone(false); slice.z = z; - slice.camLines = POLY.setZ(facing.clone(true), slice.z); + slice.camLines = POLY.setZ(facing.clone(true), slice.z + roughLeaveZ); slice.output() .setLayer("face", {face: color, line: color}) .addPolys(slice.camLines); @@ -383,10 +384,10 @@ class OpRough extends CamOp { }); slice.camLines = offset; - if (roughLeave) { + if (roughLeaveZ) { // offset roughing in Z as well to minimize // tool marks on curved surfaces - const roughLeaveZ = 1 * Math.min(roughDown, roughLeave / 2); + // const roughLeaveZ = 1 * Math.min(roughDown, roughLeave / 2); slice.camLines.forEach(p => { p.setZ(p.getZ() + roughLeaveZ); }); @@ -409,7 +410,7 @@ class OpRough extends CamOp { let add = last.clone(true); add.z -= zneg; add.camLines = last.camLines.clone(true); - add.camLines.forEach(p => p.setZ(add.z)); + add.camLines.forEach(p => p.setZ(add.z + roughLeaveZ)); // add.tops.forEach(top => top.poly.setZ(add.z)); // add.shadow = last.shadow.clone(true); slices.push(add); @@ -535,7 +536,7 @@ class OpOutline extends CamOp { let shadow = []; let slices = []; let intopt = { - down: true, min: 0, fit: true, off: 0.01, + down: true, min: zBottom, fit: true, off: 0.01, max: op.top ? zMax + ztOff : undefined }; let indices = slicer.interval(op.down, intopt); @@ -663,6 +664,7 @@ class OpOutline extends CamOp { } else { if (op.wide) { let stepover = toolDiam * op.step; + for (let c = (op.steps || 1); c > 0; c--) offset.slice().forEach(op => { // clone removes inners but the real solution is // to limit expanded shells to through holes diff --git a/src/kiri/conf.js b/src/kiri/conf.js index 0eee9a71..dc75c7b5 100644 --- a/src/kiri/conf.js +++ b/src/kiri/conf.js @@ -470,6 +470,7 @@ const conf = exports({ camRoughSpeed: 1000, camRoughPlunge: 250, camRoughStock: 0, + camRoughStockZ: 0, camRoughAll: true, camRoughVoid: false, camRoughFlat: true, @@ -482,6 +483,7 @@ const conf = exports({ camOutlineTop: true, camOutlineDown: 3, camOutlineOver: 0.4, + camOutlineOverCount: 1, camOutlineSpeed: 800, camOutlinePlunge: 250, camOutlineWide: false, diff --git a/src/kiri/print.js b/src/kiri/print.js index a5e3328d..c1305c93 100644 --- a/src/kiri/print.js +++ b/src/kiri/print.js @@ -533,7 +533,9 @@ class Print { }); break; case 'G10': - seq.last().retract = true; + if (seq && seq.length) { + seq.last().retract = true; + } break; case 'G11': break; diff --git a/web/kiri/lang/en.js b/web/kiri/lang/en.js index a38b1bc9..7097ea73 100644 --- a/web/kiri/lang/en.js +++ b/web/kiri/lang/en.js @@ -445,6 +445,8 @@ self.kiri.lang['en-us'] = { cc_spnd_l: ["spindle speed in","revolutions / minute"], cc_sovr_s: "step over", cc_sovr_l: ["a fraction of tool diameter between 0 and 1. values greater than 0.49 may result in uncut areas or undesirable artifacts."], + cc_sovc_s: "wide steps", + cc_sovc_l: ["number of wide cutout steps"], cc_sang_s: "step angle", cc_sang_l: ["rotation in degrees between lathe axial points"], cc_sdwn_s: "step down", @@ -479,6 +481,8 @@ self.kiri.lang['en-us'] = { cr_menu: "rough", cr_lsto_s: "leave stock", cr_lsto_l: ["horizontal offset from vertical faces","stock to leave for finishing pass","in workspace units"], + cr_lstz_s: "leave stock z", + cr_lstz_l: ["vertical offset for roughing passes in workspace units. best for roughing curved surfaces."], cr_ease_s: "ease down", cr_ease_l: ["plunge cuts will","spiral down or ease","along a linear path"], cr_clst_s: "clear stock",