From d5cda790c0f13adf387d4b8b5ad72768642f5634 Mon Sep 17 00:00:00 2001 From: Stewart Allen Date: Fri, 12 Dec 2025 22:26:58 -0500 Subject: [PATCH] fix ball taper render in indexed mode --- src/kiri/core/function.js | 14 ++++++-------- src/kiri/core/main.js | 4 ++-- src/kiri/core/widgets.js | 22 ++++++++++++---------- src/kiri/mode/cam/anim-3d-be.js | 12 ++++++------ src/kiri/mode/cam/anim-3d-fe.js | 2 ++ src/kiri/mode/cam/client.js | 2 +- src/kiri/mode/cam/op-area.js | 2 +- src/kiri/mode/cam/tool.js | 11 ++++++++--- 8 files changed, 38 insertions(+), 31 deletions(-) diff --git a/src/kiri/core/function.js b/src/kiri/core/function.js index b17eb4dd..c1b3482f 100644 --- a/src/kiri/core/function.js +++ b/src/kiri/core/function.js @@ -73,7 +73,7 @@ function prepareSlices(callback, scale = 1, offset = 0) { let totalProgress; - api.widgets.opacity(COLOR.slicing_opacity); + api.widgets.setOpacity(COLOR.slicing_opacity); let segtimes = {}, segNumber = 0, @@ -325,12 +325,10 @@ function preparePreview(callback, scale = 1, offset = 0) { event.emit('preview.begin', pMode); if (isCam) { - api.widgets.opacity(isDark ? COLOR.cam_preview_opacity_dark : COLOR.cam_preview_opacity); - api.widgets.each(widget => { - widget.setColor(COLOR.cam_preview); - }); + api.widgets.setOpacity(isDark ? COLOR.cam_preview_opacity_dark : COLOR.cam_preview_opacity); + api.widgets.setColor(COLOR.cam_preview); } else if (offset === 0) { - api.widgets.opacity(COLOR.preview_opacity); + api.widgets.setOpacity(COLOR.preview_opacity); } let mark = Date.now(), @@ -374,7 +372,7 @@ function preparePreview(callback, scale = 1, offset = 0) { show.progress(0); if (!isCam) { - api.widgets.opacity(0); + api.widgets.setOpacity(0); } if (output.length) { @@ -463,7 +461,7 @@ function parseCode(code, type) { event.emit("code.load", {code, type}); view.set_preview(); - widgets.opacity(0); + widgets.setOpacity(0); client.parse({code, type, settings}, progress => { show.progress(progress, "parsing"); diff --git a/src/kiri/core/main.js b/src/kiri/core/main.js index ed2f9363..279aed3b 100644 --- a/src/kiri/core/main.js +++ b/src/kiri/core/main.js @@ -361,7 +361,7 @@ function updateSliderMax(set) { function hideSlices() { STACKS.clear(); - api.widgets.opacity(COLOR.model_opacity); + api.widgets.setOpacity(COLOR.model_opacity); api.widgets.each(function(widget) { widget.setWireframe(false); }); @@ -804,7 +804,7 @@ function setViewMode(mode) { updateSpeeds(); setVisibleLayer(); setWidgetVisibility(true); - api.widgets.opacity(1); + api.widgets.setOpacity(1); api.view.edges(api.local.getBoolean('model.edges')); break; case VIEWS.SLICE: diff --git a/src/kiri/core/widgets.js b/src/kiri/core/widgets.js index 3cfe2d62..10541e74 100644 --- a/src/kiri/core/widgets.js +++ b/src/kiri/core/widgets.js @@ -82,7 +82,7 @@ function meshes() { return out; } -function opacity(value) { +function setOpacity(value) { api.widgets.each(w => w.setOpacity(value)); api.space.update(); } @@ -103,16 +103,18 @@ export const widgets = { meshes, rename, replace, - opacity, + opacity(o) { setOpacity(o); console.trace('opacity() deprecated') }, annotate, setIndexed, setAxisIndex, - all() { return WIDGETS.slice() }, - add(w) { return WIDGETS.push(w) }, - remove(w) { return WIDGETS.remove(w) }, - filter(fn) { return WIDGETS = WIDGETS.filter(fn) }, - count() { return WIDGETS.length }, - each(fn) { WIDGETS.slice().forEach(widget => fn(widget)) }, - for(fn) { widgets.each(fn) }, - forid(id) { return WIDGETS.filter(w => w.id === id)[0] } + setColor(c,s) { api.widgets.each(widget => widget.setColor(c,undefined,s) )}, + setOpacity, + all() { return WIDGETS.slice() }, + add(w) { return WIDGETS.push(w) }, + remove(w) { return WIDGETS.remove(w) }, + filter(fn) { return WIDGETS = WIDGETS.filter(fn) }, + count() { return WIDGETS.length }, + each(fn) { WIDGETS.slice().forEach(widget => fn(widget)) }, + for(fn) { widgets.each(fn) }, + forid(id) { return WIDGETS.filter(w => w.id === id)[0] } }; diff --git a/src/kiri/mode/cam/anim-3d-be.js b/src/kiri/mode/cam/anim-3d-be.js index 4a194d14..b8c23ff7 100644 --- a/src/kiri/mode/cam/anim-3d-be.js +++ b/src/kiri/mode/cam/anim-3d-be.js @@ -288,15 +288,15 @@ function toolUpdate(toolid, send) { .add(sphere(frad, 20).translate(0, 0, -(tlen - frad * 2) / 2)) .add(cylinder(slen, srad, srad, 20, true).translate(0, 0, flen / 2)); } else if (tool.isTaperBall()) { - const trad = Math.max(tool.tipDiameter() / 2, 0.001); - const brad = trad; // ball radius equals tip radius - const taperLen = flen - brad; // taper length excludes ball + const { b, r } = tool.getBallTaperParams(); + // taper length excludes most of ball + const taperLen = flen - b; // shaft at top mesh = cylinder(slen, srad, srad, 20, true).translate(0, 0, slen / 2) // taper cone in middle - .add(cylinder(taperLen, trad, frad, 20, true).translate(0, 0, -taperLen / 2)) - // ball at bottom - .add(sphere(brad, 20).translate(0, 0, -(taperLen + brad))); + .add(cylinder(taperLen, b, frad, 20, true).translate(0, 0, -taperLen / 2)) + // exposed ball at bottom + .add(sphere(r, 20).translate(0, 0, -taperLen)); } else if (tool.isTaperMill()) { const trad = Math.max(tool.tipDiameter() / 2, 0.001); mesh = cylinder(slen, srad, srad, 20, true).translate(0, 0, slen / 2) diff --git a/src/kiri/mode/cam/anim-3d-fe.js b/src/kiri/mode/cam/anim-3d-fe.js index 2329bc59..c3a5791c 100644 --- a/src/kiri/mode/cam/anim-3d-fe.js +++ b/src/kiri/mode/cam/anim-3d-fe.js @@ -111,6 +111,8 @@ Object.assign(client, { color: 0x888888, side: THREE.DoubleSide }); + api.widgets.setColor(0x0055aa); + api.widgets.setOpacity(0.5); client.send("animate_setup2", { settings }, ondone); }, diff --git a/src/kiri/mode/cam/client.js b/src/kiri/mode/cam/client.js index ec7c98fc..5b9cea05 100644 --- a/src/kiri/mode/cam/client.js +++ b/src/kiri/mode/cam/client.js @@ -963,7 +963,7 @@ function validateTools(tools) { function animate() { env.isAnimate = true; - api.widgets.opacity(env.isParsed ? 0 : 0.75); + api.widgets.setOpacity(env.isParsed ? 0 : 0.75); api.hide.slider(); STACKS.clear(); animFn().animate(api); diff --git a/src/kiri/mode/cam/op-area.js b/src/kiri/mode/cam/op-area.js index eba7584f..22c45fe9 100644 --- a/src/kiri/mode/cam/op-area.js +++ b/src/kiri/mode/cam/op-area.js @@ -132,7 +132,7 @@ class OpArea extends CamOp { if (mode === 'clear') { let zMov = flatOff ?? 0; let zs = flats ? - flats.filter(z => z <= zTop && z >= zBottom).map(v => v + (zMov ?? 0)) : + flats.filter(z => z <= zTop && z >= zBottom).map(v => v + zMov) : down ? base_util.lerp(zTop, zBottom, down) : [ bounds.min.z ]; let zroc = 0; let zinc = 1 / zs.length; diff --git a/src/kiri/mode/cam/tool.js b/src/kiri/mode/cam/tool.js index df854f14..d06e121d 100644 --- a/src/kiri/mode/cam/tool.js +++ b/src/kiri/mode/cam/tool.js @@ -78,6 +78,13 @@ class Tool { return calcTaperAngle((flute_diam - taper_tip) / 2, flute_len); } + getBallTaperParams() { + let a = this.getTaperAngle() * DEG2RAD, + r = (this.tipDiameter()/2) * (1 + Math.sin(a)) / Math.cos(a), + b = r * Math.cos(a); + return { a, r, b }; + } + shaftLength() { return this.unitScale() * this.tool.shaft_len; } @@ -152,9 +159,7 @@ class Tool { toolOffset = [], maxo = -Infinity, // ball taper magic - a = this.getTaperAngle() * DEG2RAD, - r = (tip_dia/2) * (1 + Math.sin(a)) / Math.cos(a), - b = r * Math.cos(a), + { b, r } = this.getBallTaperParams(), pix_b = b / resolution, pix_r = r / resolution;