diff --git a/release.md b/release.md index 1df43237..35647ede 100644 --- a/release.md +++ b/release.md @@ -6,6 +6,7 @@ Full docs @ https://docs.grid.space/projects/kiri-moto # Release 3.9 * more graceful handling of security contexts blocking SharedArrayBuffer +* CAM add calcualtion of taper length from angle * CAM add open poly-line offsetting with trace op * CAM clearly delineate ops reachable or not on timeline * CAM add 4th axis lathe operation for debug and testing (can be optimized) diff --git a/src/kiri-mode/cam/tool.js b/src/kiri-mode/cam/tool.js index 52340bf5..e0b26b5d 100644 --- a/src/kiri-mode/cam/tool.js +++ b/src/kiri-mode/cam/tool.js @@ -10,6 +10,7 @@ const { driver } = kiri; const { CAM } = driver; const HPI = Math.PI/2; +const RAD2DEG = 180/Math.PI; class Tool { constructor(settings, id, number) { @@ -70,6 +71,15 @@ class Tool { return diam ? diam * step : step; } + setTaperLengthFromAngle(angle) { + const rad = (this.flute_diam - this.taper_tip) / 2; + return this.flute_len = CAM.calcTaperLength(rad, angle); + } + + getTaperAngle() { + return CAM.calcTaperAngle((this.flute_diam - this.taper_tip) / 2, this.flute_len); + } + shaftLength() { return this.unitScale() * this.tool.shaft_len; } @@ -95,8 +105,8 @@ class Tool { shaft_offset = this.fluteLength(), flute_diameter = this.fluteDiameter(), shaft_diameter = this.shaftDiameter(), - shaft_radius = shaft_diameter / 2, - shaft_pix_float = shaft_diameter / resolution, + max_diameter = Math.max(flute_diameter, shaft_diameter), + shaft_pix_float = max_diameter / resolution, shaft_pix_int = Math.round(shaft_pix_float), shaft_radius_pix_float = shaft_pix_float / 2, flute_radius = flute_diameter / 2, @@ -133,7 +143,7 @@ class Tool { toolOffset.push(dx, dy, z_offset); } else if (shaft_offset && larger_shaft && dist_from_center <= shaft_radius_pix_float) { // shaft offset points - toolOffset.push(dx, dy, -shaft_offset); + // toolOffset.push(dx, dy, -shaft_offset); } } } @@ -155,6 +165,14 @@ class Tool { CAM.Tool = Tool; +CAM.calcTaperAngle = function(rad, len) { + return (Math.atan(rad / len) * RAD2DEG).round(1); +}; + +CAM.calcTaperLength = function(rad, angle) { + return rad / Math.tan(angle); +}; + CAM.getToolDiameter = function(settings, id) { return new CAM.Tool(settings, id).fluteDiameter(); }; diff --git a/src/kiri/init.js b/src/kiri/init.js index 388a1e89..40eadeb6 100644 --- a/src/kiri/init.js +++ b/src/kiri/init.js @@ -1150,10 +1150,16 @@ gapp.register("kiri.init", [], (root, exports) => { ui.toolFluteLen.value = tool.flute_len; ui.toolShaftDiam.value = tool.shaft_diam; ui.toolShaftLen.value = tool.shaft_len; - // ui.toolTaperAngle.value = tool.taper_angle || 70; ui.toolTaperTip.value = tool.taper_tip || 0; ui.toolMetric.checked = tool.metric; ui.toolType.selectedIndex = ['endmill','ballmill','tapermill'].indexOf(tool.type); + if (tool.type === 'tapermill') { + ui.toolTaperAngle.value = kiri.driver.CAM.calcTaperAngle( + (tool.flute_diam - tool.taper_tip) / 2, tool.flute_len + ); + } else { + ui.toolTaperAngle.value = 0; + } renderTool(tool); } @@ -1179,7 +1185,7 @@ gapp.register("kiri.init", [], (root, exports) => { function renderTool(tool) { let type = selectedTool.type; let taper = type === 'tapermill'; - // ui.toolTaperAngle.disabled = taper ? undefined : 'true'; + ui.toolTaperAngle.disabled = taper ? undefined : 'true'; ui.toolTaperTip.disabled = taper ? undefined : 'true'; $('tool-view').innerHTML = ''; setTimeout(() => { @@ -1255,17 +1261,31 @@ gapp.register("kiri.init", [], (root, exports) => { }, 10); } - function updateTool() { + function updateTool(ev) { selectedTool.name = ui.toolName.value; selectedTool.number = parseInt(ui.toolNum.value); selectedTool.flute_diam = parseFloat(ui.toolFluteDiam.value); selectedTool.flute_len = parseFloat(ui.toolFluteLen.value); selectedTool.shaft_diam = parseFloat(ui.toolShaftDiam.value); selectedTool.shaft_len = parseFloat(ui.toolShaftLen.value); - // selectedTool.taper_angle = parseFloat(ui.toolTaperAngle.value); selectedTool.taper_tip = parseFloat(ui.toolTaperTip.value); selectedTool.metric = ui.toolMetric.checked; selectedTool.type = ['endmill','ballmill','tapermill'][ui.toolType.selectedIndex]; + if (selectedTool.type === 'tapermill') { + const CAM = kiri.driver.CAM; + const rad = (selectedTool.flute_diam - selectedTool.taper_tip) / 2; + if (ev && ev.target === ui.toolTaperAngle) { + const angle = parseFloat(ev.target.value); + const len = CAM.calcTaperLength(rad, angle * DEG2RAD); + selectedTool.flute_len = len; + ui.toolTaperAngle.value = angle; + ui.toolFluteLen.value = selectedTool.flute_len.round(4); + } else { + ui.toolTaperAngle.value = CAM.calcTaperAngle(rad, selectedTool.flute_len); + } + } else { + ui.toolTaperAngle.value = 0; + } renderTools(); ui.toolSelect.selectedIndex = selectedTool.order; setToolChanged(true); @@ -1662,7 +1682,7 @@ gapp.register("kiri.init", [], (root, exports) => { toolFluteLen: $('tool-flen'), toolShaftDiam: $('tool-sdiam'), toolShaftLen: $('tool-slen'), - // toolTaperAngle: $('tool-tangle'), + toolTaperAngle: $('tool-tangle'), toolTaperTip: $('tool-ttip'), toolMetric: $('tool-metric'), @@ -2383,6 +2403,7 @@ gapp.register("kiri.init", [], (root, exports) => { ui.toolShaftDiam, updateTool, ui.toolShaftLen, updateTool, ui.toolTaperTip, updateTool, + ui.toolTaperAngle, updateTool, $('rot_x'), selectionRotate, $('rot_y'), selectionRotate, $('rot_z'), selectionRotate diff --git a/web/kiri/index.html b/web/kiri/index.html index 38ae42d1..6798a352 100644 --- a/web/kiri/index.html +++ b/web/kiri/index.html @@ -407,7 +407,7 @@