From 9c8c9ff30bdcabc49117367676b695d8c12b62c9 Mon Sep 17 00:00:00 2001 From: Stewart Allen Date: Sat, 18 Oct 2025 01:03:58 -0400 Subject: [PATCH] add lathe start/end offset option, fix large step precision --- notes.md | 1 - src/kiri/core/conf.js | 2 ++ src/kiri/mode/cam/cl-ops.js | 7 ++++- src/kiri/mode/cam/topo4.js | 61 ++++++++++++++++++++++--------------- src/kiri/run/minion.js | 1 - src/moto/space.js | 2 -- web/kiri/lang/en.js | 10 +++--- 7 files changed, 49 insertions(+), 35 deletions(-) diff --git a/notes.md b/notes.md index 56c74577..e39f50d8 100644 --- a/notes.md +++ b/notes.md @@ -32,7 +32,6 @@ * `B` multi-extruder rendering of raft fails to offset the rest of the print * `B` multi-extruder purge blocks fail to generate properly for rafts -* `F` new parameter to cap output flow rate (on printer device) * `F` new parameters for bridging speed / bridge fan control * `F` convert ranges to z offsets while continuing to show layer # * `F` support pillar top/bottom should conform to part diff --git a/src/kiri/core/conf.js b/src/kiri/core/conf.js index 83c02e83..ae5512d5 100644 --- a/src/kiri/core/conf.js +++ b/src/kiri/core/conf.js @@ -497,6 +497,8 @@ export const conf = { camLatheSpeed: 500, camLatheSpindle: 1000, camLatheTool: 1000, + camLatheOffStart: 0, + camLatheOffEnd: 0, camLevelDown: 0, camLevelInset: 0.5, camLevelOver: 0.75, diff --git a/src/kiri/mode/cam/cl-ops.js b/src/kiri/mode/cam/cl-ops.js index eb9232dd..5d05ed31 100644 --- a/src/kiri/mode/cam/cl-ops.js +++ b/src/kiri/mode/cam/cl-ops.js @@ -350,7 +350,9 @@ export function createPopOps() { tolerance: 'camTolerance', filter: 'camContourFilter', leave: 'camContourLeave', - linear: 'camLatheLinear' + linear: 'camLatheLinear', + offStart: 'camLatheOffStart', + offEnd: 'camLatheOffEnd' }).inputs = { tool: UC.newSelect(LANG.cc_tool, {}, "tools"), // axis: UC.newSelect(LANG.cd_axis, {}, "xyaxis"), @@ -361,6 +363,9 @@ export function createPopOps() { step: UC.newInput(LANG.cc_sovr_s, { title: LANG.cc_sovr_l, convert: UC.toFloat, bound: UC.bound(0.01, 100.0) }), angle: UC.newInput(LANG.cc_sang_s, { title: LANG.cc_sang_l, convert: UC.toFloat, bound: UC.bound(0.01, 180.0) }), sep: UC.newBlank({ class: "pop-sep" }), + offStart: UC.newInput(LANG.ci_laso_s, { title: LANG.ci_laso_l, convert: UC.toFloat}), + offEnd: UC.newInput(LANG.ci_laeo_s, { title: LANG.ci_laeo_l, convert: UC.toFloat}), + sep: UC.newBlank({ class: "pop-sep" }), tolerance: UC.newInput(LANG.ou_toll_s, { title: LANG.ou_toll_l, convert: UC.toFloat, bound: UC.bound(0, 10.0), units: true, round: 4 }), leave: UC.newInput(LANG.cf_leav_s, { title: LANG.cf_leav_l, convert: UC.toFloat, bound: UC.bound(0, 100) }), sep: UC.newBlank({ class: "pop-sep" }), diff --git a/src/kiri/mode/cam/topo4.js b/src/kiri/mode/cam/topo4.js index 3a60e611..f29934c2 100644 --- a/src/kiri/mode/cam/topo4.js +++ b/src/kiri/mode/cam/topo4.js @@ -39,7 +39,7 @@ export class Topo { y: axis === "y" }, tolerance = op.tolerance, - resolution = tolerance ? tolerance : 1 / Math.sqrt(density / (span.x * span.y)), + resolution = (tolerance ? tolerance : 1 / Math.sqrt(density / (span.x * span.y))).round(5), step = this.step = (tool.traceOffset() * 2) * op.step, angle = this.angle = op.angle || 1; @@ -58,10 +58,13 @@ export class Topo { this.tool = tool.generateProfile(resolution).profile; this.maxo = tool.profileDim.maxo * resolution; this.diam = tool.fluteDiameter(); + this.unit = tool.unitScale(); this.zoff = widget.track.top || 0; this.leave = op.leave || 0; this.linear = op.linear || false; this.lineColor = state.settings.controller.dark ? 0xffff00 : 0x555500; + this.offStart = op.offStart ?? 0; + this.offEnd = op.offEnd ?? 0; onupdate(0, "lathe"); @@ -85,8 +88,8 @@ export class Topo { } async slice(onupdate) { - const { vertices, resolution, tabverts, zoff } = this; - + const { vertices, resolution, tabverts, zoff, offStart, offEnd, tool, unit } = this; + const { minions } = self.kiri_worker; const range = this.range = { min: Infinity, max: -Infinity }; const box = this.box = new THREE.Box2(); @@ -100,9 +103,10 @@ export class Topo { range.max = Math.max(range.max, x); } - // add tool radius to slice min/max range ot fully carve part - range.min -= this.diam / 2; - range.max += this.diam / 2; + // add tool diameter to slice min/max range to fully carve part + range.min += offStart * unit; + range.max -= offEnd * unit; + range.max += resolution * 2; // merge in tab vertices here so they don't affect slice range / dimensions for (let i = 0, l = tabverts.length; i < l; i += 3) { @@ -115,26 +119,31 @@ export class Topo { // re-create shared vertex array for workers this.vertices = [].appendAll(vertices).appendAll(tabverts).toFloat32().toShared(); + const zSpan = range.max - range.min; const shards = Math.ceil(Math.min(25, vertices.length / 27000)); - const step = (range.max - range.min) / shards; + const totalSteps = Math.ceil(zSpan / resolution); + const stardSteps = Math.ceil(totalSteps / shards); + const stepWidth = stardSteps * resolution; - let index = 0; let slices = this.slices = []; - let slice = { min: range.min, max: range.min + step, index }; - - // console.log({ shards, step, range, resolution }); - for (let z = range.min; z <= range.max; z += resolution) { - // console.log({ z }); - if (z > slice.max) { - slices.push(slice); - slice = { min: z, max: z + step, index }; - } - index++; + for (let i=0; i 1) { return await this.sliceMinions(onupdate); } else { @@ -218,10 +227,10 @@ export class Topo { const tlen = tool.length; const slen = slices.length; - const sinc = Math.max(1, Math.ceil(step / resolution)); const heights = []; - // cull slice lines to only the ones in range (5x faster) + // console.log({ tlen, slen, sinc, slices: slices.map(s => s.z) }); + // cull slice lines to only the ones in range (~5x faster) const oslices = []; for (let slice of slices) { const lines = slice.lines; @@ -245,7 +254,9 @@ export class Topo { // iterate over all slices (real x = z) // find max real z using z ray intersect from tool point to slice lines + offset let lz = 0; - for (let si = 0; si < slen; si += sinc) { + for (let sz = 0; ; sz += step) { + let si = Math.ceil(sz / resolution); + if (si >= oslices.length) break; const rx = oslices[si].z; let mz = -Infinity; // iterate over tool offsets @@ -282,7 +293,7 @@ export class Topo { } if (mz === -Infinity && xo === 0 && yo === 0) { // tool tip is off the model - continue; + // continue; } } if (mz === -Infinity) { diff --git a/src/kiri/run/minion.js b/src/kiri/run/minion.js index ae1c2920..412da396 100644 --- a/src/kiri/run/minion.js +++ b/src/kiri/run/minion.js @@ -315,7 +315,6 @@ const funcs = self.minion = { const topo4 = Object.assign(new Topo4(), cache.lathe); const heights = topo4.lathePath(stmp, tool); - reply({ seq, heights }); } }; diff --git a/src/moto/space.js b/src/moto/space.js index 8aa5047d..45101885 100644 --- a/src/moto/space.js +++ b/src/moto/space.js @@ -98,7 +98,6 @@ let WIN = self.window || {}, fontColor = '#333333', fontScale = 1.4, // computed relative to grid size rulerColor, - axisColor, axesOn = true, volumeOn = true, viewControl, @@ -388,7 +387,6 @@ function setPlatformColor(color) { function setFont(options) { if (options.color) fontColor = options.color; if (options.scale) fontScale = options.scale; - if (options.axisColor) axisColor = options.axisColor; if (options.rulerColor) rulerColor = options.rulerColor; updateRulers(); } diff --git a/web/kiri/lang/en.js b/web/kiri/lang/en.js index da85f39a..ea00c48b 100644 --- a/web/kiri/lang/en.js +++ b/web/kiri/lang/en.js @@ -393,7 +393,7 @@ self.lang['en-us'] = { fc_menu: "cooling", // FDM FIRST LAYER - fl_menu: "base layer", + fl_menu: "base", fl_lahi_s: "layer height", fl_lahi_l: ["height of each slice","in millimeters","should be >= slice height"], fl_rate_s: "shell speed", @@ -654,6 +654,10 @@ self.lang['en-us'] = { ci_face_l: "select face to rotate facing up", ci_line_s: "linear", ci_line_l: "make linear passes along X then rotate Y", + ci_laso_s: "offset start", + ci_laso_l: ["x offet from left of part. negative values are outside of the part. in workspace units"], + ci_laeo_s: "offset end", + ci_laeo_l: ["x offet from right of part. negative values are outside of the part. in workspace units"], // CNC LASER On/Off Operations (Carvera) cl_powr_s: "power", @@ -675,10 +679,6 @@ self.lang['en-us'] = { cl_maxz_s: "max z height", cl_maxz_l: ["highest Z band position. when set to 0, uses the highest Z point of the workspace"], - - - - // CNC CUTOUT TABS ct_menu: "tabs", ct_angl_s: "angle",