diff --git a/src/kiri-mode/cam/animate2.js b/src/kiri-mode/cam/animate2.js index 4f374c32..21cfa963 100644 --- a/src/kiri-mode/cam/animate2.js +++ b/src/kiri-mode/cam/animate2.js @@ -478,20 +478,26 @@ kiri.load(() => { if (!np || !lp) { return renderPath(send); } - const dx = np.x - lp.x, dy = np.y - lp.y, dz = np.z - lp.z; - const dist = Math.sqrt(dx*dx + dy*dy + dz*dz); + let dx = np.x - lp.x, + dy = np.y - lp.y, + dz = np.z - lp.z, + da = Math.abs((np.a || 0) - (lp.a || 0)), + dr = (da / 360) * (2 * Math.PI * Math.max(np.z, lp.z)), + dist = Math.sqrt(dx*dx + dy*dy + dz*dz + dr*dr); + moveDist += dist; // skip moves that are less than grid resolution if (moveDist < rezstep) { + // console.log('skip', moveDist, rezstep, next); renderPath(send); return; } - const md = Math.max(Math.abs(dx), Math.abs(dy), Math.abs(dz)); + const md = Math.max(Math.abs(dx), Math.abs(dy), Math.abs(dz), dr); const st = Math.ceil(md / rezstep); const mx = dx / st, my = dy / st, mz = dz / st; - const sd = Math.sqrt(mx*mx + my*my + mz*mz); + const sd = Math.sqrt(mx*mx + my*my + mz*mz + dr*dr); const moves = []; for (let i=0, x=lp.x, y=lp.y, z=lp.z; i { - if (out.gcode) { + if (out.gcode || out.type === 'lerp') { return; } if (out.tool && out.tool !== ctool) { diff --git a/src/kiri-mode/cam/prepare.js b/src/kiri-mode/cam/prepare.js index 56b3527d..2fe9ef30 100644 --- a/src/kiri-mode/cam/prepare.js +++ b/src/kiri-mode/cam/prepare.js @@ -259,7 +259,7 @@ function prepEach(widget, settings, print, firstPoint, update) { * @param {number} [speed] speed * @param {number} [tool] tool */ - function layerPush(point, emit, speed, tool) { + function layerPush(point, emit, speed, tool, type) { const dz = (point && lastPush && lastPush.point) ? point.z - lastPush.point.z : 0; if (dz < 0 && speed > plungeRate) { speed = plungeRate; @@ -291,7 +291,7 @@ function prepEach(widget, settings, print, firstPoint, update) { } print.addOutput(layerOut, point, power, speed, tool, 'laser'); } else { - print.addOutput(layerOut, point, emit, speed, tool); + print.addOutput(layerOut, point, emit, speed, tool, type); } lastPush = { point, emit, speed, tool }; return point; @@ -319,11 +319,6 @@ function prepEach(widget, settings, print, firstPoint, update) { point.y += wmy; point.z += zadd; - // carry rotation forward when not overridden - if (point.a === undefined && lastPoint) { - point.a = lastPoint.a; - } - // console.log(point.z); if (nextIsMove) { cut = 0; @@ -332,6 +327,32 @@ function prepEach(widget, settings, print, firstPoint, update) { let rate = feedRate * factor; + // carry rotation forward when not overridden + if (point.a === undefined && lastPoint) { + point.a = lastPoint.a; + } else if (lastPoint && point.a !== undefined && lastPoint.a !== undefined) { + let DA = lastPoint.a - point.a; + let MZ = Math.max(lastPoint.z, point.z) + // find arc length + let AL = (Math.abs(DA) / 360) * (2 * Math.PI * MZ); + if (AL >= 1) { + let lerp = base.util.lerp(lastPoint.a, point.a, 1); + // create interpolated point set for rendering and animation + // console.log({ DA, MZ, AL }, lerp.length); + for (let a of lerp) { + let lp = point.clone().setA(a); + // console.log(lp.a, lp.x, lp.y, lp.z); + lastPoint = layerPush( + lp, + cut ? 1 : 0, + rate, + tool, + "lerp" + ); + } + } + } + // before first point, move cutting head to point above it // then set that new point as the lastPoint if (!lastPoint) { diff --git a/src/kiri/print.js b/src/kiri/print.js index dabf4a00..b4443b6f 100644 --- a/src/kiri/print.js +++ b/src/kiri/print.js @@ -44,7 +44,7 @@ class Print { addOutput(array, point, emit, speed, tool, type) { let { lastPoint, lastEmit, lastOut } = this; // drop duplicates (usually intruced by FDM bisections) - if (lastPoint && point) { + if (lastPoint && point && type !== 'lerp') { // nested due to uglify confusing browser const { x, y, z } = lastPoint; if (point.x == x && point.y == y && point.z == z && lastEmit == emit) { diff --git a/src/kiri/render.js b/src/kiri/render.js index f2fc6ed6..20ef141d 100644 --- a/src/kiri/render.js +++ b/src/kiri/render.js @@ -159,10 +159,12 @@ async function path(levels, update, opts = {}) { let outPoint = out.point; // rotate 4th axis indexed points // todo -- add spark lines - if (outPoint && outPoint.a) { + if (outPoint && outPoint.a !== undefined) { let { point } = out; + // calculate rotated point let p2 = new THREE.Vector3(point.x, point.y, point.z) .applyAxisAngle(XAXIS, point.a * DEG2RAD); + // reconstruct point point for display without A axis outPoint = base.newPoint(p2.x, p2.y, p2.z); // let sp = base.newPoint(outPoint.x * 1.1, outPoint.y * 1.1, outPoint.z * 1.1); // sparks.push(outPoint, sp);