hide spindle speed when not applicable. rename some cam ops vars
This commit is contained in:
parent
23e927e0d4
commit
1d2cdc9a15
6 changed files with 106 additions and 89 deletions
9
notes.md
9
notes.md
|
|
@ -45,13 +45,10 @@
|
||||||
# CAM
|
# CAM
|
||||||
|
|
||||||
* `B` fails in pancaking (clone) when there are no sliced layers (like z bottom too high)
|
* `B` fails in pancaking (clone) when there are no sliced layers (like z bottom too high)
|
||||||
* `B` linear finishing should extend beyond part boundaries by tool radius
|
* `B` contouring should extend beyond part boundaries by tool radius
|
||||||
* `B` outside cutting direction in roughing mode inverted
|
* `B` outside cutting direction in roughing mode inverted
|
||||||
* `F` z bounded slices (extension of z bottom offset feature)
|
* `F` z bounded slices (extension of z bottom offset feature)
|
||||||
* `F` use arcs to connect hard angles
|
* `F` use arcs to connect hard angles
|
||||||
* `F` do not rough areas that go all the way through the part
|
|
||||||
https://github.com/GridSpace/grid-apps/issues/20
|
|
||||||
* `F` send gcode to cncjs
|
|
||||||
* `F` lead-in milling
|
* `F` lead-in milling
|
||||||
* `F` trapezoidal tabs (in the Z axis)
|
* `F` trapezoidal tabs (in the Z axis)
|
||||||
* `F` ease-in and ease-out especially on tab cut-out start/stop
|
* `F` ease-in and ease-out especially on tab cut-out start/stop
|
||||||
|
|
@ -62,9 +59,9 @@
|
||||||
* `F` warn when part > stock or cuts go outside bed
|
* `F` warn when part > stock or cuts go outside bed
|
||||||
* `F` add M03 tool feedrate support
|
* `F` add M03 tool feedrate support
|
||||||
* `P` refactor slicing around flats w/ interpolation instead of culling
|
* `P` refactor slicing around flats w/ interpolation instead of culling
|
||||||
* `P` disable topo generation when no linear xy and no depth first
|
* `P` disable topo generation when no contour xy and no depth first
|
||||||
* `P` store tab and camshell polys in widget.topo to minimize z on edge moves
|
* `P` store tab and camshell polys in widget.topo to minimize z on edge moves
|
||||||
* `P` linear finishing is going back to z top too often
|
* `P` contouring is going back to z top too often
|
||||||
* `P` option to skip milling holes that would be drilled
|
* `P` option to skip milling holes that would be drilled
|
||||||
* `P` crossing open space check point is outside camshell before returning max z
|
* `P` crossing open space check point is outside camshell before returning max z
|
||||||
* `P` background worker to speculatively generate topo maps (and maybe pre-slicing)
|
* `P` background worker to speculatively generate topo maps (and maybe pre-slicing)
|
||||||
|
|
|
||||||
|
|
@ -1360,7 +1360,7 @@
|
||||||
|
|
||||||
camRough: UC.newGroup(LANG.cr_menu, null, {modes:CAM, marker:true}),
|
camRough: UC.newGroup(LANG.cr_menu, null, {modes:CAM, marker:true}),
|
||||||
camRoughTool: UC.newSelect(LANG.cc_tool, {modes:CAM}),
|
camRoughTool: UC.newSelect(LANG.cc_tool, {modes:CAM}),
|
||||||
camRoughSpindle: UC.newInput(LANG.cc_spnd_s, {title:LANG.cc_spnd_l, convert:UC.toInt, modes:CAM}),
|
camRoughSpindle: UC.newInput(LANG.cc_spnd_s, {title:LANG.cc_spnd_l, convert:UC.toInt, modes:CAM, visible:spindleShow}),
|
||||||
camRoughOver: UC.newInput(LANG.cc_sovr_s, {title:LANG.cc_sovr_l, convert:UC.toFloat, bound:UC.bound(0.1,1.0), modes:CAM}),
|
camRoughOver: UC.newInput(LANG.cc_sovr_s, {title:LANG.cc_sovr_l, convert:UC.toFloat, bound:UC.bound(0.1,1.0), modes:CAM}),
|
||||||
camRoughDown: UC.newInput(LANG.cc_sdwn_s, {title:LANG.cc_sdwn_l, convert:UC.toFloat, modes:CAM}),
|
camRoughDown: UC.newInput(LANG.cc_sdwn_s, {title:LANG.cc_sdwn_l, convert:UC.toFloat, modes:CAM}),
|
||||||
camRoughSpeed: UC.newInput(LANG.cc_feed_s, {title:LANG.cc_feed_l, convert:UC.toInt, modes:CAM}),
|
camRoughSpeed: UC.newInput(LANG.cc_feed_s, {title:LANG.cc_feed_l, convert:UC.toInt, modes:CAM}),
|
||||||
|
|
@ -1372,7 +1372,7 @@
|
||||||
camRoughOn: UC.newBoolean(LANG.enable, onBooleanClick, {modes:CAM}),
|
camRoughOn: UC.newBoolean(LANG.enable, onBooleanClick, {modes:CAM}),
|
||||||
camOutline: UC.newGroup(LANG.co_menu, null, {modes:CAM, marker:true}),
|
camOutline: UC.newGroup(LANG.co_menu, null, {modes:CAM, marker:true}),
|
||||||
camOutlineTool: UC.newSelect(LANG.cc_tool, {modes:CAM}),
|
camOutlineTool: UC.newSelect(LANG.cc_tool, {modes:CAM}),
|
||||||
camOutlineSpindle: UC.newInput(LANG.cc_spnd_s, {title:LANG.cc_spnd_l, convert:UC.toInt, modes:CAM}),
|
camOutlineSpindle: UC.newInput(LANG.cc_spnd_s, {title:LANG.cc_spnd_l, convert:UC.toInt, modes:CAM, visible:spindleShow}),
|
||||||
camOutlineOver: UC.newInput(LANG.cc_sovr_s, {title:LANG.cc_sovr_l, convert:UC.toFloat, bound:UC.bound(0.05,1.0), modes:CAM}),
|
camOutlineOver: UC.newInput(LANG.cc_sovr_s, {title:LANG.cc_sovr_l, convert:UC.toFloat, bound:UC.bound(0.05,1.0), modes:CAM}),
|
||||||
camOutlineDown: UC.newInput(LANG.cc_sdwn_s, {title:LANG.cc_sdwn_l, convert:UC.toFloat, modes:CAM}),
|
camOutlineDown: UC.newInput(LANG.cc_sdwn_s, {title:LANG.cc_sdwn_l, convert:UC.toFloat, modes:CAM}),
|
||||||
camOutlineSpeed: UC.newInput(LANG.cc_feed_s, {title:LANG.cc_feed_l, convert:UC.toInt, modes:CAM}),
|
camOutlineSpeed: UC.newInput(LANG.cc_feed_s, {title:LANG.cc_feed_l, convert:UC.toInt, modes:CAM}),
|
||||||
|
|
@ -1382,7 +1382,7 @@
|
||||||
camOutlineOn: UC.newBoolean(LANG.cf_watr_s, onBooleanClick, {title:LANG.cf_watr_l, modes:CAM}),
|
camOutlineOn: UC.newBoolean(LANG.cf_watr_s, onBooleanClick, {title:LANG.cf_watr_l, modes:CAM}),
|
||||||
camContour: UC.newGroup(LANG.cn_menu, null, {modes:CAM, marker:true}),
|
camContour: UC.newGroup(LANG.cn_menu, null, {modes:CAM, marker:true}),
|
||||||
camContourTool: UC.newSelect(LANG.cc_tool, {modes:CAM}),
|
camContourTool: UC.newSelect(LANG.cc_tool, {modes:CAM}),
|
||||||
camContourSpindle: UC.newInput(LANG.cc_spnd_s, {title:LANG.cc_spnd_l, convert:UC.toInt, modes:CAM}),
|
camContourSpindle: UC.newInput(LANG.cc_spnd_s, {title:LANG.cc_spnd_l, convert:UC.toInt, modes:CAM, visible:spindleShow}),
|
||||||
camContourSpeed: UC.newInput(LANG.cc_feed_s, {title:LANG.cc_feed_l, convert:UC.toInt, modes:CAM}),
|
camContourSpeed: UC.newInput(LANG.cc_feed_s, {title:LANG.cc_feed_l, convert:UC.toInt, modes:CAM}),
|
||||||
camContourAngle: UC.newInput(LANG.cf_angl_s, {title:LANG.cf_angl_l, convert:UC.toFloat, bound:UC.bound(45,90), modes:CAM}),
|
camContourAngle: UC.newInput(LANG.cf_angl_s, {title:LANG.cf_angl_l, convert:UC.toFloat, bound:UC.bound(45,90), modes:CAM}),
|
||||||
camContourCurves: UC.newBoolean(LANG.cf_curv_s, onBooleanClick, {title:LANG.cf_curv_l, modes:CAM}),
|
camContourCurves: UC.newBoolean(LANG.cf_curv_s, onBooleanClick, {title:LANG.cf_curv_l, modes:CAM}),
|
||||||
|
|
@ -1391,11 +1391,12 @@
|
||||||
camContourYOn: UC.newBoolean(LANG.cf_liny_s, onBooleanClick, {title:LANG.cf_liny_l, modes:CAM}),
|
camContourYOn: UC.newBoolean(LANG.cf_liny_s, onBooleanClick, {title:LANG.cf_liny_l, modes:CAM}),
|
||||||
// camTracing: UC.newGroup(LANG.cu_menu, null, {modes:CAM, marker:true}),
|
// camTracing: UC.newGroup(LANG.cu_menu, null, {modes:CAM, marker:true}),
|
||||||
// camTraceTool: UC.newSelect(LANG.cc_tool, {modes:CAM}),
|
// camTraceTool: UC.newSelect(LANG.cc_tool, {modes:CAM}),
|
||||||
|
// camTraceSpeed: UC.newInput(LANG.cc_feed_s, {title:LANG.cc_feed_l, convert:UC.toInt, modes:CAM}),
|
||||||
// camTracingSep: UC.newBlank({class:"pop-sep"}),
|
// camTracingSep: UC.newBlank({class:"pop-sep"}),
|
||||||
// camTraceEnable: UC.newBoolean(LANG.enable, onBooleanClick, {title:'todo', modes:CAM}),
|
// camTraceOn: UC.newBoolean(LANG.enable, onBooleanClick, {title:'todo', modes:CAM}),
|
||||||
camDrill: UC.newGroup(LANG.cd_menu, null, {modes:CAM, marker:true}),
|
camDrill: UC.newGroup(LANG.cd_menu, null, {modes:CAM, marker:true}),
|
||||||
camDrillTool: UC.newSelect(LANG.cc_tool, {modes:CAM}),
|
camDrillTool: UC.newSelect(LANG.cc_tool, {modes:CAM}),
|
||||||
camDrillSpindle: UC.newInput(LANG.cc_spnd_s, {title:LANG.cc_spnd_l, convert:UC.toInt, modes:CAM}),
|
camDrillSpindle: UC.newInput(LANG.cc_spnd_s, {title:LANG.cc_spnd_l, convert:UC.toInt, modes:CAM, visible:spindleShow}),
|
||||||
camDrillDown: UC.newInput(LANG.cd_plpr_s, {title:LANG.cd_plpr_l, convert:UC.toFloat, modes:CAM}),
|
camDrillDown: UC.newInput(LANG.cd_plpr_s, {title:LANG.cd_plpr_l, convert:UC.toFloat, modes:CAM}),
|
||||||
camDrillDownSpeed: UC.newInput(LANG.cc_plng_s, {title:LANG.cc_plng_l, convert:UC.toFloat, modes:CAM}),
|
camDrillDownSpeed: UC.newInput(LANG.cc_plng_s, {title:LANG.cc_plng_l, convert:UC.toFloat, modes:CAM}),
|
||||||
camDrillDwell: UC.newInput(LANG.cd_dwll_s, {title:LANG.cd_dwll_l, convert:UC.toFloat, modes:CAM}),
|
camDrillDwell: UC.newInput(LANG.cd_dwll_s, {title:LANG.cd_dwll_l, convert:UC.toFloat, modes:CAM}),
|
||||||
|
|
@ -1530,6 +1531,10 @@
|
||||||
layerMoves: UC.newBoolean(LANG.la_move, onLayerToggle, {modes:GCODE})
|
layerMoves: UC.newBoolean(LANG.la_move, onLayerToggle, {modes:GCODE})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function spindleShow() {
|
||||||
|
return settings().device.spindleMax > 0;
|
||||||
|
}
|
||||||
|
|
||||||
// slider setup
|
// slider setup
|
||||||
const slbar = 30;
|
const slbar = 30;
|
||||||
const slbar2 = slbar * 2;
|
const slbar2 = slbar * 2;
|
||||||
|
|
|
||||||
|
|
@ -305,7 +305,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function addModeControls(el, options) {
|
function addModeControls(el, options) {
|
||||||
options = options || {};
|
let opt = options || {};
|
||||||
el.__show = true;
|
el.__show = true;
|
||||||
el.__modeSave = null;
|
el.__modeSave = null;
|
||||||
el.showMe = function() {
|
el.showMe = function() {
|
||||||
|
|
@ -325,16 +325,17 @@
|
||||||
else el.hideMe();
|
else el.hideMe();
|
||||||
};
|
};
|
||||||
el.setMode = function(mode) {
|
el.setMode = function(mode) {
|
||||||
let show = options.expert === undefined || (options.expert === letExpert);
|
let show = opt.expert === undefined || (opt.expert === letExpert);
|
||||||
el.setVisible(el.hasMode(mode) && show);
|
let disp = opt.visible ? opt.visible() : true;
|
||||||
|
el.setVisible(el.hasMode(mode) && show && disp);
|
||||||
}
|
}
|
||||||
el.hasMode = function(mode) {
|
el.hasMode = function(mode) {
|
||||||
if (mode === NOMODE) return false;
|
if (mode === NOMODE) return false;
|
||||||
if (!el.modes) return true;
|
if (!el.modes) return true;
|
||||||
return el.modes.contains(mode);
|
return el.modes.contains(mode);
|
||||||
}
|
}
|
||||||
if (options.modes) {
|
if (opt.modes) {
|
||||||
el.modes = options.modes;
|
el.modes = opt.modes;
|
||||||
hasModes.push(el);
|
hasModes.push(el);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -236,6 +236,7 @@
|
||||||
if (!union) {
|
if (!union) {
|
||||||
union = tops;
|
union = tops;
|
||||||
} else {
|
} else {
|
||||||
|
// replace slice's tops with unioned tops
|
||||||
tops.appendAll(union);
|
tops.appendAll(union);
|
||||||
union = POLY.union(tops);
|
union = POLY.union(tops);
|
||||||
slice.tops = [];
|
slice.tops = [];
|
||||||
|
|
@ -261,11 +262,13 @@
|
||||||
let holes = slice.gatherTopPolyInners([]).clone();
|
let holes = slice.gatherTopPolyInners([]).clone();
|
||||||
if (last) {
|
if (last) {
|
||||||
let inter = [];
|
let inter = [];
|
||||||
|
// find intersection of hole below and hole in this layer
|
||||||
holes.forEach(hole => {
|
holes.forEach(hole => {
|
||||||
last.forEach(poly => {
|
last.forEach(hole_under => {
|
||||||
inter.appendAll(hole.intersect(poly));
|
inter.appendAll(hole.intersect(hole_under));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
// filter dup polygons (which intersect can produce)
|
||||||
last = inter.filter((poly, index, arr) => {
|
last = inter.filter((poly, index, arr) => {
|
||||||
for (let i=index+1, il=arr.length; i<il; i++) {
|
for (let i=index+1, il=arr.length; i<il; i++) {
|
||||||
if (arr[i].isEquivalent(poly)) return false;
|
if (arr[i].isEquivalent(poly)) return false;
|
||||||
|
|
@ -501,7 +504,7 @@
|
||||||
onupdate(0.20 + (gridx/stepsx) * 0.50, "topo tracing");
|
onupdate(0.20 + (gridx/stepsx) * 0.50, "topo tracing");
|
||||||
}
|
}
|
||||||
|
|
||||||
// do x linear finishing
|
// x contouring
|
||||||
if (proc.camContourXOn) {
|
if (proc.camContourXOn) {
|
||||||
startTime = time();
|
startTime = time();
|
||||||
// emit slice per X
|
// emit slice per X
|
||||||
|
|
@ -558,7 +561,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// do y linear finishing
|
// y contouring
|
||||||
if (proc.camContourYOn) {
|
if (proc.camContourYOn) {
|
||||||
startTime = time();
|
startTime = time();
|
||||||
// emit slice per Y
|
// emit slice per Y
|
||||||
|
|
@ -635,7 +638,7 @@
|
||||||
* @param {number} bounds shell offset
|
* @param {number} bounds shell offset
|
||||||
* @returns {Object} shell
|
* @returns {Object} shell
|
||||||
*/
|
*/
|
||||||
function createFacingSlices(slice, shell, diameter, overlap, pocket) {
|
function createLevelPaths(slice, shell, diameter, overlap, pocket) {
|
||||||
let outer = [],
|
let outer = [],
|
||||||
offset = [];
|
offset = [];
|
||||||
|
|
||||||
|
|
@ -673,7 +676,7 @@
|
||||||
* @param {boolean} true for pocket only mode
|
* @param {boolean} true for pocket only mode
|
||||||
* @returns {Object} shell or newly generated shell
|
* @returns {Object} shell or newly generated shell
|
||||||
*/
|
*/
|
||||||
function createRoughingSlices(slice, shell, diameter, stock, overlap, pocket, holes) {
|
function createRoughPaths(slice, shell, diameter, stock, overlap, pocket, holes) {
|
||||||
let tops = slice.gatherTopPolys([]).clone(true),
|
let tops = slice.gatherTopPolys([]).clone(true),
|
||||||
outer = [],
|
outer = [],
|
||||||
offset = [];
|
offset = [];
|
||||||
|
|
@ -796,7 +799,7 @@
|
||||||
* @param {number} tool diameter
|
* @param {number} tool diameter
|
||||||
* @param {boolean} pocket only
|
* @param {boolean} pocket only
|
||||||
*/
|
*/
|
||||||
function createFinishingSlices(slice, shell, diameter, pocket) {
|
function createOutlinePaths(slice, shell, diameter, pocket) {
|
||||||
if (slice.tops.length === 0) return shell;
|
if (slice.tops.length === 0) return shell;
|
||||||
|
|
||||||
let tops = slice.gatherTopPolys([]).clone(true),
|
let tops = slice.gatherTopPolys([]).clone(true),
|
||||||
|
|
@ -845,48 +848,50 @@
|
||||||
unitsName = settings.controller.units,
|
unitsName = settings.controller.units,
|
||||||
units = unitsName === 'in' ? 25.4 : 1,
|
units = unitsName === 'in' ? 25.4 : 1,
|
||||||
roughToolDiam = getToolDiameter(conf, proc.camRoughTool),
|
roughToolDiam = getToolDiameter(conf, proc.camRoughTool),
|
||||||
finishToolDiam = getToolDiameter(conf, proc.camOutlineTool),
|
outlineToolDiam = getToolDiameter(conf, proc.camOutlineTool),
|
||||||
|
contourToolDiam = getToolDiameter(conf, proc.camContourTool),
|
||||||
drillToolDiam = getToolDiameter(conf, proc.camDrillTool),
|
drillToolDiam = getToolDiameter(conf, proc.camDrillTool),
|
||||||
procRough = proc.camRoughOn && proc.camRoughDown && roughToolDiam,
|
|
||||||
procFinish = proc.camOutlineOn && proc.camOutlineDown && finishToolDiam,
|
|
||||||
procFinishX = proc.camContourXOn && proc.camOutlinePlunge && finishToolDiam,
|
|
||||||
procFinishY = proc.camContourYOn && proc.camOutlinePlunge && finishToolDiam,
|
|
||||||
anyFinish = procFinish || procFinishX || procFinishY,
|
|
||||||
procFacing = proc.camRoughOn && proc.camZTopOffset,
|
procFacing = proc.camRoughOn && proc.camZTopOffset,
|
||||||
|
procRough = proc.camRoughOn && proc.camRoughDown && roughToolDiam,
|
||||||
|
procOutline = proc.camOutlineOn && proc.camOutlineDown && outlineToolDiam,
|
||||||
|
procContourX = proc.camContourXOn && proc.camOutlinePlunge && contourToolDiam,
|
||||||
|
procContourY = proc.camContourYOn && proc.camOutlinePlunge && contourToolDiam,
|
||||||
|
procContour = procContourX || procContourY,
|
||||||
procDrill = proc.camDrillingOn && proc.camDrillDown && proc.camDrillDownSpeed,
|
procDrill = proc.camDrillingOn && proc.camDrillDown && proc.camDrillDownSpeed,
|
||||||
|
procTrace = proc.camTraceOn,
|
||||||
sliceDepth = Math.max(0.1, Math.min(proc.camRoughDown, proc.camOutlineDown) / 3) * units,
|
sliceDepth = Math.max(0.1, Math.min(proc.camRoughDown, proc.camOutlineDown) / 3) * units,
|
||||||
pocketOnlyRough = proc.camRoughPocket,
|
pocketOnlyRough = proc.camRoughPocket,
|
||||||
pocketOnlyFinish = proc.camOutlinePocket,
|
pocketOnlyOutline = proc.camOutlinePocket,
|
||||||
addTabsRough = procRough && proc.camTabsOn && !pocketOnlyRough,
|
addTabsRough = procRough && proc.camTabsOn && !pocketOnlyRough,
|
||||||
addTabsFinish = procFinish && proc.camTabsOn && !pocketOnlyFinish,
|
addTabsOutline = procOutline && proc.camTabsOn && !pocketOnlyOutline,
|
||||||
tabWidth = proc.camTabsWidth * units,
|
tabWidth = proc.camTabsWidth * units,
|
||||||
tabHeight = proc.camTabsHeight * units,
|
tabHeight = proc.camTabsHeight * units,
|
||||||
mesh = widget.mesh,
|
|
||||||
bounds = widget.getBoundingBox(),
|
bounds = widget.getBoundingBox(),
|
||||||
|
mesh = widget.mesh,
|
||||||
zMin = Math.max(bounds.min.z, proc.camZBottom) * units,
|
zMin = Math.max(bounds.min.z, proc.camZBottom) * units,
|
||||||
camRoughStock = proc.camRoughStock * units,
|
camRoughStock = proc.camRoughStock * units,
|
||||||
shellRough,
|
shellRough,
|
||||||
shellFinish,
|
shellOutline,
|
||||||
facePolys,
|
facePolys,
|
||||||
thruHoles;
|
thruHoles;
|
||||||
|
|
||||||
if (settings.stock.x + 0.00001 < bounds.max.x - bounds.min.x) {
|
if (settings.stock.x + 0.00001 < bounds.max.x - bounds.min.x) {
|
||||||
return ondone('stock X too small for part. disable or use offset stock');
|
return ondone('stock X too small for part. disable stock or use offset stock');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (settings.stock.y + 0.00001 < bounds.max.y - bounds.min.y) {
|
if (settings.stock.y + 0.00001 < bounds.max.y - bounds.min.y) {
|
||||||
return ondone('stock Y too small for part. disable or use offset stock');
|
return ondone('stock Y too small for part. disable stock or use offset stock');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (settings.stock.z + 0.00001 < bounds.max.z - bounds.min.z) {
|
if (settings.stock.z + 0.00001 < bounds.max.z - bounds.min.z) {
|
||||||
return ondone('stock Z too small for part. disable or use offset stock');
|
return ondone('stock Z too small for part. disable stock or use offset stock');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sliceDepth <= 0.05) {
|
if (sliceDepth <= 0.05) {
|
||||||
return ondone(`invalid slice depth (${sliceDepth.toFixed(2)} ${unitsName})`);
|
return ondone(`invalid slice depth (${sliceDepth.toFixed(2)} ${unitsName})`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(procRough || anyFinish || procFacing || procDrill)) {
|
if (!(procFacing || procRough || procOutline || procContour || procDrill)) {
|
||||||
return ondone("no processes selected");
|
return ondone("no processes selected");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -894,7 +899,7 @@
|
||||||
const addCutoutTabs = function(slice, toolDiam) {
|
const addCutoutTabs = function(slice, toolDiam) {
|
||||||
// too high
|
// too high
|
||||||
if (slice.z > zMin + tabHeight) return;
|
if (slice.z > zMin + tabHeight) return;
|
||||||
// no tops / traces
|
// skip if no tops | traces
|
||||||
if (slice.tops.length === 0) return;
|
if (slice.tops.length === 0) return;
|
||||||
|
|
||||||
let trace, index, maxArea = 0, tmpArea;
|
let trace, index, maxArea = 0, tmpArea;
|
||||||
|
|
@ -911,22 +916,23 @@
|
||||||
// required to match computed order of cutouts
|
// required to match computed order of cutouts
|
||||||
trace.setClockwise();
|
trace.setClockwise();
|
||||||
|
|
||||||
let count = proc.camTabsCount;
|
let count = proc.camTabsCount,
|
||||||
let angle = proc.camTabsAngle;
|
angle = proc.camTabsAngle,
|
||||||
let angle_inc = 360 / count;
|
angle_inc = 360 / count,
|
||||||
let center = BASE.newPoint(0,0,slice.z);
|
center = BASE.newPoint(0,0,slice.z),
|
||||||
let offset = (tabWidth + toolDiam) / 2;
|
offset = (tabWidth + toolDiam) / 2,
|
||||||
let ints = [];
|
ints = [],
|
||||||
let segs = [];
|
segs = [];
|
||||||
|
|
||||||
while (count-- > 0) {
|
while (count-- > 0) {
|
||||||
let slope = BASE.newSlopeFromAngle(angle);
|
let slope = BASE.newSlopeFromAngle(angle),
|
||||||
let normal = BASE.newSlopeFromAngle(angle + 90);
|
normal = BASE.newSlopeFromAngle(angle + 90),
|
||||||
let c1 = center.projectOnSlope(normal, offset);
|
c1 = center.projectOnSlope(normal, offset),
|
||||||
let c2 = center.projectOnSlope(normal, -offset);
|
c2 = center.projectOnSlope(normal, -offset),
|
||||||
let o1 = c1.projectOnSlope(slope, 10000);
|
o1 = c1.projectOnSlope(slope, 10000),
|
||||||
let o2 = c2.projectOnSlope(slope, 10000);
|
o2 = c2.projectOnSlope(slope, 10000),
|
||||||
let int1 = trace.intersections(c1, o1).pop();
|
int1 = trace.intersections(c1, o1).pop(),
|
||||||
let int2 = trace.intersections(c2, o2).pop();
|
int2 = trace.intersections(c2, o2).pop();
|
||||||
if (int1 && int2) {
|
if (int1 && int2) {
|
||||||
ints.push(int1);
|
ints.push(int1);
|
||||||
ints.push(int2);
|
ints.push(int2);
|
||||||
|
|
@ -935,6 +941,7 @@
|
||||||
// segs.push(newPolygon([c1,o1]));
|
// segs.push(newPolygon([c1,o1]));
|
||||||
// segs.push(newPolygon([c2,o2]));
|
// segs.push(newPolygon([c2,o2]));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ints.length) {
|
if (ints.length) {
|
||||||
ints.push(ints.shift());
|
ints.push(ints.shift());
|
||||||
for (let i=0; i<ints.length; i+=2) {
|
for (let i=0; i<ints.length; i+=2) {
|
||||||
|
|
@ -947,32 +954,38 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// called when horizontal slicing complete
|
// called when z-index slicing complete
|
||||||
const camSlicesDone = function(slices) {
|
const camSlicesDone = function(slices) {
|
||||||
|
|
||||||
|
// return outermost (bottom layer) "top" polys
|
||||||
const camShell = pancake(slices, function(update) {
|
const camShell = pancake(slices, function(update) {
|
||||||
onupdate(0.25 + update * 0.15, "shelling");
|
onupdate(0.25 + update * 0.15, "shelling");
|
||||||
});
|
});
|
||||||
|
|
||||||
const camShellPolys = shellRough = facePolys = camShell.gatherTopPolys([]);
|
// set all default shells
|
||||||
|
const camShellPolys = shellRough = shellOutline = facePolys = camShell.gatherTopPolys([]);
|
||||||
|
|
||||||
if (procRough && !pocketOnlyRough) {
|
if (procRough) {
|
||||||
// expand shell by half tool diameter + stock to leave
|
if (pocketOnlyRough) {
|
||||||
shellRough = facePolys = POLY.expand(shellRough, (roughToolDiam / 2) + camRoughStock, 0);
|
// expand shell minimally triggering a clean
|
||||||
} else {
|
shellRough = POLY.expand(shellRough, 0.01, 0);
|
||||||
// expand shell minimally triggering a clean
|
} else {
|
||||||
shellRough = facePolys = POLY.expand(shellRough, 0.01, 0);
|
// expand shell by half tool diameter + stock to leave
|
||||||
|
shellRough = facePolys = POLY.expand(shellRough, (roughToolDiam / 2) + camRoughStock, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (anyFinish && pocketOnlyRough && !pocketOnlyFinish) {
|
if (procOutline) {
|
||||||
facePolys = POLY.expand(shellRough, (roughToolDiam / 2) + camRoughStock, 0);
|
if (pocketOnlyOutline) {
|
||||||
|
// expand shell minimally triggering a clean
|
||||||
|
shellOutline = POLY.expand(shellOutline, -outlineToolDiam / 2, 0);
|
||||||
|
} else {
|
||||||
|
// expand shell by half tool diameter (not needed because only one offset)
|
||||||
|
// shellOutline = POLY.expand(shellOutline, outlineToolDiam / 2, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (anyFinish && pocketOnlyFinish) {
|
// clear area from top of stock to top of part
|
||||||
shellFinish = POLY.expand(camShellPolys, -finishToolDiam/2, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// hollow area from top of stock to top of part
|
|
||||||
if (procFacing) {
|
if (procFacing) {
|
||||||
let ztop = bounds.max.z,
|
let ztop = bounds.max.z,
|
||||||
zpos = ztop + (proc.camZTopOffset * units),
|
zpos = ztop + (proc.camZTopOffset * units),
|
||||||
|
|
@ -1002,7 +1015,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (procFinish) {
|
if (procOutline) {
|
||||||
let selected = [];
|
let selected = [];
|
||||||
selectSlices(slices, proc.camOutlineDown * units, CPRO.OUTLINE, selected);
|
selectSlices(slices, proc.camOutlineDown * units, CPRO.OUTLINE, selected);
|
||||||
sliceAll.appendAll(selected);
|
sliceAll.appendAll(selected);
|
||||||
|
|
@ -1060,8 +1073,9 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
// we need topo for safe travel moves when roughing and finishing
|
// we need topo for safe travel moves when roughing and finishing
|
||||||
// not generated when drilling-only. then all z moves use bounds max
|
// not generated when drilling-only. then all z moves use bounds max.
|
||||||
if (procRough || anyFinish)
|
// also generates x and y contouring when selected
|
||||||
|
if (procRough || procOutline || procContour)
|
||||||
generateTopoMap(widget, settings, function(slices) {
|
generateTopoMap(widget, settings, function(slices) {
|
||||||
sliceAll.appendAll(slices);
|
sliceAll.appendAll(slices);
|
||||||
// todo union rough / finish shells
|
// todo union rough / finish shells
|
||||||
|
|
@ -1072,12 +1086,12 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
// prepare for tracing paths
|
// prepare for tracing paths
|
||||||
let tool;
|
let traceTool;
|
||||||
let profile;
|
let traceToolProfile;
|
||||||
if (procFinish) {
|
if (procTrace) {
|
||||||
tool = getToolById(conf, proc.camOutlineTool);
|
traceTool = getToolById(conf, proc.camTraceTool);
|
||||||
if (tool.type !== 'endmill') {
|
if (traceTool.type !== 'endmill') {
|
||||||
profile = createToolProfile(conf, proc.camOutlineTool, widget.topo);
|
traceToolProfile = createToolProfile(conf, proc.camTraceTool, widget.topo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1089,18 +1103,18 @@
|
||||||
switch (slice.camMode) {
|
switch (slice.camMode) {
|
||||||
case CPRO.FACING:
|
case CPRO.FACING:
|
||||||
modekey = "facing";
|
modekey = "facing";
|
||||||
createFacingSlices(slice, facePolys, roughToolDiam, proc.camRoughOver, pocketOnlyRough);
|
createLevelPaths(slice, facePolys, roughToolDiam, proc.camRoughOver, pocketOnlyRough);
|
||||||
break;
|
break;
|
||||||
case CPRO.ROUGH:
|
case CPRO.ROUGH:
|
||||||
modekey = "roughing";
|
modekey = "roughing";
|
||||||
createRoughingSlices(slice, shellRough, roughToolDiam, camRoughStock, proc.camRoughOver, pocketOnlyRough, thruHoles);
|
createRoughPaths(slice, shellRough, roughToolDiam, camRoughStock, proc.camRoughOver, pocketOnlyRough, thruHoles);
|
||||||
if (addTabsRough) addCutoutTabs(slice, roughToolDiam);
|
if (addTabsRough) addCutoutTabs(slice, roughToolDiam);
|
||||||
break;
|
break;
|
||||||
case CPRO.OUTLINE:
|
case CPRO.OUTLINE:
|
||||||
modekey = "finishing";
|
modekey = "finishing";
|
||||||
if (profile) findTracingPaths(widget, slice, tool, profile);
|
createOutlinePaths(slice, shellOutline, outlineToolDiam, pocketOnlyOutline);
|
||||||
createFinishingSlices(slice, shellFinish, finishToolDiam, pocketOnlyFinish);
|
if (addTabsOutline) addCutoutTabs(slice, outlineToolDiam);
|
||||||
if (addTabsFinish) addCutoutTabs(slice, finishToolDiam);
|
if (traceToolProfile) findTracingPaths(widget, slice, traceTool, traceToolProfile);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
onupdate(0.90 + (index / sliceAll.length) * 0.10, modekey);
|
onupdate(0.90 + (index / sliceAll.length) * 0.10, modekey);
|
||||||
|
|
@ -1213,8 +1227,8 @@
|
||||||
origin = newPoint(originx + wmx, originy + wmy, zmax),
|
origin = newPoint(originx + wmx, originy + wmy, zmax),
|
||||||
output = print.output,
|
output = print.output,
|
||||||
modes = CPRO,
|
modes = CPRO,
|
||||||
depthFirst = process.camDepthFirst,
|
|
||||||
easeDown = process.camEaseDown,
|
easeDown = process.camEaseDown,
|
||||||
|
depthFirst = process.camDepthFirst,
|
||||||
tolerance = process.camTolerance * units,
|
tolerance = process.camTolerance * units,
|
||||||
drillDown = process.camDrillDown * units,
|
drillDown = process.camDrillDown * units,
|
||||||
drillLift = process.camDrillLift * units,
|
drillLift = process.camDrillLift * units,
|
||||||
|
|
|
||||||
|
|
@ -230,7 +230,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function addModeControls(el, options) {
|
function addModeControls(el, options) {
|
||||||
options = options || {};
|
let opt = options || {};
|
||||||
el.__show = true;
|
el.__show = true;
|
||||||
el.__modeSave = null;
|
el.__modeSave = null;
|
||||||
el.showMe = function() {
|
el.showMe = function() {
|
||||||
|
|
@ -250,7 +250,7 @@
|
||||||
else el.hideMe();
|
else el.hideMe();
|
||||||
};
|
};
|
||||||
el.setMode = function(mode) {
|
el.setMode = function(mode) {
|
||||||
let show = options.expert === undefined || (options.expert === letExpert);
|
let show = opt.expert === undefined || (opt.expert === letExpert);
|
||||||
el.setVisible(el.hasMode(mode) && show);
|
el.setVisible(el.hasMode(mode) && show);
|
||||||
}
|
}
|
||||||
el.hasMode = function(mode) {
|
el.hasMode = function(mode) {
|
||||||
|
|
@ -258,8 +258,8 @@
|
||||||
if (!el.modes) return true;
|
if (!el.modes) return true;
|
||||||
return el.modes.contains(mode);
|
return el.modes.contains(mode);
|
||||||
}
|
}
|
||||||
if (options.modes) {
|
if (opt.modes) {
|
||||||
el.modes = options.modes;
|
el.modes = opt.modes;
|
||||||
hasModes.push(el);
|
hasModes.push(el);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -239,7 +239,7 @@ kiri.lang['en-us'] = {
|
||||||
cc_feed_l: "max cutting speed in\nworkspace units / minute",
|
cc_feed_l: "max cutting speed in\nworkspace units / minute",
|
||||||
cc_plng_s: "plunge rate",
|
cc_plng_s: "plunge rate",
|
||||||
cc_plng_l: "max z axis speed in\nworkspace units / minute",
|
cc_plng_l: "max z axis speed in\nworkspace units / minute",
|
||||||
cc_pock_s: "pocket only",
|
cc_pock_s: "inside only",
|
||||||
cc_pock_l: "constrain cuts to\npart boundaries",
|
cc_pock_l: "constrain cuts to\npart boundaries",
|
||||||
|
|
||||||
// CNC COMMON
|
// CNC COMMON
|
||||||
|
|
@ -299,7 +299,7 @@ kiri.lang['en-us'] = {
|
||||||
ct_wdth_l: "width in workspace units",
|
ct_wdth_l: "width in workspace units",
|
||||||
ct_hght_s: "height",
|
ct_hght_s: "height",
|
||||||
ct_hght_l: "height in workspace units",
|
ct_hght_l: "height in workspace units",
|
||||||
ct_nabl_l: "enable or disable tabs\ntab generation skipped when\npocket only mode enabled",
|
ct_nabl_l: "enable or disable tabs\ntab generation skipped when\ninside only mode enabled",
|
||||||
|
|
||||||
// FDM RAFT
|
// FDM RAFT
|
||||||
fr_menu: "raft",
|
fr_menu: "raft",
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue