diff --git a/src/kiri-mode/cam/prepare.js b/src/kiri-mode/cam/prepare.js
index 695cf02f..5c3b1dd0 100644
--- a/src/kiri-mode/cam/prepare.js
+++ b/src/kiri-mode/cam/prepare.js
@@ -89,6 +89,7 @@ function prepEach(widget, settings, print, firstPoint, update) {
output = print.output,
easeDown = process.camEaseDown,
depthFirst = process.camDepthFirst,
+ engageFactor = process.camFullEngage,
tolerance = 0,
drillDown = 0,
drillLift = 0,
@@ -99,6 +100,7 @@ function prepEach(widget, settings, print, firstPoint, update) {
layerOut = [],
printPoint,
isNewMode,
+ isPocket,
isContour,
isRough,
isLathe,
@@ -303,6 +305,13 @@ function prepEach(widget, settings, print, firstPoint, update) {
);
}
+ /**
+ * emit a cut or move operation from the current location to a new location
+ * @param {*} point destination for move
+ * @param {*} cut 1/true = cut, 0/false = move
+ * @param {*} moveLen typically = tool diameter used to trigger terrain detection
+ * @param {*} factor speed scale factor
+ */
function camOut(point, cut, moveLen = toolDiamMove, factor = 1) {
point = point.clone();
point.x += wmx;
@@ -453,7 +462,8 @@ function prepEach(widget, settings, print, firstPoint, update) {
} else {
printPoint = poly2polyEmit(polys, printPoint, function(poly, index, count) {
poly.forEachPoint(function(point, pidx, points, offset) {
- camOut(point.clone(), offset !== 0, undefined, count === 1 ? 0.5 : 1);
+ // scale speed of first cutting poly since it engages the full bit
+ camOut(point.clone(), offset !== 0, undefined, count === 1 ? engageFactor : 1);
}, poly.isClosed(), index);
}, { swapdir: false });
newLayer();
@@ -534,7 +544,8 @@ function prepEach(widget, settings, print, firstPoint, update) {
currentOp = op.op;
isLathe = currentOp.type === 'lathe';
isRough = currentOp.type === 'rough';
- isContour = currentOp.type === 'contour' || (currentOp.type === 'pocket' && currentOp.contour);
+ isPocket = currentOp.type === 'pocket';
+ isContour = currentOp.type === 'contour' || (isPocket && currentOp.contour);
let weight = op.weight();
newLayer(op.op);
op.prepare(ops, (progress, message) => {
@@ -559,14 +570,16 @@ function prepEach(widget, settings, print, firstPoint, update) {
function polyEmit(poly, index, count, fromPoint) {
let last = null;
+ // scale speed of first cutting poly since it engages the full bit
+ let scale = ((isRough || isPocket) && count === 1) ? engageFactor : 1;
if (easeDown && poly.isClosed()) {
last = poly.forEachPointEaseDown(function(point, offset) {
- camOut(point.clone(), offset > 0, undefined, isRough && count === 1 ? 0.5 : 1);
+ camOut(point.clone(), offset > 0, undefined, scale);
}, fromPoint);
} else {
poly.forEachPoint(function(point, pidx, points, offset) {
last = point;
- camOut(point.clone(), offset !== 0, undefined, isRough && count === 1 ? 0.5 : 1);
+ camOut(point.clone(), offset !== 0, undefined, scale);
}, poly.isClosed(), index);
}
newLayer();
diff --git a/src/kiri/conf.js b/src/kiri/conf.js
index 13d9f7b8..2f449291 100644
--- a/src/kiri/conf.js
+++ b/src/kiri/conf.js
@@ -600,6 +600,7 @@ const conf = exports({
camForceZMax: false,
camFirstZMax: false,
camToolInit: true,
+ camFullEngage: 0.8,
ops: [], // current ops
op2: [] // flip ops
}
diff --git a/src/kiri/init.js b/src/kiri/init.js
index b488c8c8..25ac325f 100644
--- a/src/kiri/init.js
+++ b/src/kiri/init.js
@@ -1908,7 +1908,7 @@ gapp.register("kiri.init", [], (root, exports) => {
/** CAM Settings */
- camTabs: newGroup(LANG.ct_menu, $('cam-tabs'), { modes:CAM, marker:true, driven, separator }),
+ _____: newGroup(LANG.ct_menu, $('cam-tabs'), { modes:CAM, marker:true, driven, separator }),
camTabsWidth: newInput(LANG.ct_wdth_s, {title:LANG.ct_wdth_l, convert:toFloat, bound:bound(0.005,100), units:true}),
camTabsHeight: newInput(LANG.ct_hght_s, {title:LANG.ct_hght_l, convert:toFloat, bound:bound(0.005,100), units:true}),
camTabsDepth: newInput(LANG.ct_dpth_s, {title:LANG.ct_dpth_l, convert:toFloat, bound:bound(0.005,100), units:true}),
@@ -1920,7 +1920,7 @@ gapp.register("kiri.init", [], (root, exports) => {
(ui.tabDun = newButton(undefined, onButtonClick, {icon:''})),
(ui.tabClr = newButton(undefined, onButtonClick, {icon:''}))
], {class:"ext-buttons f-row"}),
- camStock: newGroup(LANG.cs_menu, $('cam-stock'), { modes:CAM, driven, separator }),
+ _____: newGroup(LANG.cs_menu, $('cam-stock'), { modes:CAM, driven, separator }),
camStockX: newInput(LANG.cs_wdth_s, {title:LANG.cs_wdth_l, convert:toFloat, bound:bound(0,9999), units:true}),
camStockY: newInput(LANG.cs_dpth_s, {title:LANG.cs_dpth_l, convert:toFloat, bound:bound(0,9999), units:true}),
camStockZ: newInput(LANG.cs_hght_s, {title:LANG.cs_hght_l, convert:toFloat, bound:bound(0,9999), units:true}),
@@ -1929,7 +1929,7 @@ gapp.register("kiri.init", [], (root, exports) => {
camStockClipTo: newBoolean(LANG.cs_clip_s, onBooleanClick, {title:LANG.cs_clip_l}),
camStockIndexed: newBoolean(LANG.cs_indx_s, onBooleanClick, {title:LANG.cs_indx_l}),
camStockIndexGrid: newBoolean(LANG.cs_ishg_s, onBooleanClick, {title:LANG.cs_ishg_l, show:() => ui.camStockIndexed.checked}),
- camLimits: newGroup(LANG.cc_menu, $('cam-limits'), { modes:CAM, driven, separator }),
+ _____: newGroup(LANG.cc_menu, $('cam-limits'), { modes:CAM, driven, separator }),
camZAnchor: newSelect(LANG.ou_zanc_s, {title: LANG.ou_zanc_l, action:zAnchorSave, show:() => !ui.camStockIndexed.checked}, "zanchor"),
camZOffset: newInput(LANG.ou_ztof_s, {title:LANG.ou_ztof_l, convert:toFloat, units:true}),
camZBottom: newInput(LANG.ou_zbot_s, {title:LANG.ou_zbot_l, convert:toFloat, units:true, trigger: true}),
@@ -1937,21 +1937,24 @@ gapp.register("kiri.init", [], (root, exports) => {
camZClearance: newInput(LANG.ou_zclr_s, {title:LANG.ou_zclr_l, convert:toFloat, bound:bound(0.01,100), units:true}),
camFastFeedZ: newInput(LANG.cc_rzpd_s, {title:LANG.cc_rzpd_l, convert:toFloat, units:true}),
camFastFeed: newInput(LANG.cc_rapd_s, {title:LANG.cc_rapd_l, convert:toFloat, units:true}),
- camOutput: newGroup(LANG.ou_menu, $('cam-output'), { modes:CAM, driven, separator }),
+ _____: newGroup(LANG.ou_menu, $('cam-output'), { modes:CAM, driven, separator }),
camConventional: newBoolean(LANG.ou_conv_s, onBooleanClick, {title:LANG.ou_conv_l}),
camEaseDown: newBoolean(LANG.cr_ease_s, onBooleanClick, {title:LANG.cr_ease_l}),
camDepthFirst: newBoolean(LANG.ou_depf_s, onBooleanClick, {title:LANG.ou_depf_l}),
camToolInit: newBoolean(LANG.ou_toin_s, onBooleanClick, {title:LANG.ou_toin_l}),
+ separator: newBlank({ class:"set-sep", driven }),
camFirstZMax: newBoolean(LANG.ou_z1st_s, onBooleanClick, {title:LANG.ou_z1st_l}),
camForceZMax: newBoolean(LANG.ou_forz_s, onBooleanClick, {title:LANG.ou_forz_l}),
- camOrigin: newGroup(LANG.co_menu, $('cam-origin'), { modes:CAM, driven, separator }),
+ separator: newBlank({ class:"set-sep", driven }),
+ camFullEngage: newInput(LANG.ou_feng_s, {title:LANG.ou_feng_l, convert:toFloat, bound:bound(0.1,1.0)}),
+ _____: newGroup(LANG.co_menu, $('cam-origin'), { modes:CAM, driven, separator }),
camOriginTop: newBoolean(LANG.or_topp_s, onBooleanClick, {title:LANG.or_topp_l}),
camOriginCenter: newBoolean(LANG.or_cntr_s, onBooleanClick, {title:LANG.or_cntr_l}),
separator: newBlank({ class:"set-sep", driven }),
camOriginOffX: newInput(LANG.co_offx_s, {title:LANG.co_offx_l, convert:toFloat, units:true}),
camOriginOffY: newInput(LANG.co_offy_s, {title:LANG.co_offy_l, convert:toFloat, units:true}),
camOriginOffZ: newInput(LANG.co_offz_s, {title:LANG.co_offz_l, convert:toFloat, units:true}),
- camExpert: newGroup(LANG.op_xprt_s, $('cam-expert'), { group: "cam_expert", modes:CAM, marker: false, driven, separator }),
+ _____: newGroup(LANG.op_xprt_s, $('cam-expert'), { group: "cam_expert", modes:CAM, marker: false, driven, separator }),
camExpertFast: newBoolean(LANG.cx_fast_s, onBooleanClick, {title:LANG.cx_fast_l, show: () => !ui.camTrueShadow.checked }),
camTrueShadow: newBoolean(LANG.cx_true_s, onBooleanClick, {title:LANG.cx_true_l, show: () => !ui.camExpertFast.checked }),
diff --git a/web/kiri/lang/en.js b/web/kiri/lang/en.js
index df8cdd6a..ed4ee054 100644
--- a/web/kiri/lang/en.js
+++ b/web/kiri/lang/en.js
@@ -734,6 +734,8 @@ self.kiri.lang['en-us'] = {
ou_forz_l: "all moves between pockets will go to z max (above stock). this is usually required if you are not performing a roughing operation before pocketing operations.",
ou_z1st_s: "first z max",
ou_z1st_l: "first move in the job will be to Z max (travel distance above stock)",
+ ou_feng_s: "engage factor",
+ ou_feng_l: "speed scale (0.1-1) when endmill is fully engaged on a new cut. stepped over cuts when the endmill is less than fully engaged run at a factor of 1 relative to output speed. typically this relates to roughing or any operation with step over.",
// CAM STOCK
cs_menu: "stock",