add gcode parsing rotational interpolation, frame get

This commit is contained in:
Stewart Allen 2025-12-12 16:34:04 -05:00
commit f097829e34
3 changed files with 67 additions and 35 deletions

View file

@ -4,6 +4,7 @@ import { api } from './api.js';
import { load } from '../../load/file.js'; import { load } from '../../load/file.js';
import { newWidget } from './widget.js'; import { newWidget } from './widget.js';
import { VIEWS } from './consts.js'; import { VIEWS } from './consts.js';
import { widgets } from './widgets.js';
// add frame message api listener // add frame message api listener
window.addEventListener('message', msg => { window.addEventListener('message', msg => {
@ -46,10 +47,22 @@ window.addEventListener('message', msg => {
case "mode": send({mode: settings.mode()}); break; case "mode": send({mode: settings.mode()}); break;
case "device": send({device: settings.dev()}); break; case "device": send({device: settings.dev()}); break;
case "process": send({process: settings.proc()}); break; case "process": send({process: settings.proc()}); break;
case "widgets": send({widgets: widgets.all().map(w => {
return {
id: w.id,
meta: w.meta,
track: w.track,
}
})}); break;
default: send({all: settings}); break; default: send({all: settings}); break;
} }
if (data.set) switch (data.set) {
case "":
break;
}
if (data.features) { if (data.features) {
Object.assign(feature, data.features); Object.assign(feature, data.features);
api.show.controls(api.feature.controls); api.show.controls(api.feature.controls);

View file

@ -352,8 +352,8 @@ class Print {
// morph = false, // morph = false,
morph = true, morph = true,
bounds = scope.bounds = { bounds = scope.bounds = {
max: { x:-Infinity, y:-Infinity, z:-Infinity}, max: { x: -Infinity, y: -Infinity, z: -Infinity },
min: { x:Infinity, y:Infinity, z:Infinity} min: { x: Infinity, y: Infinity, z: Infinity }
}, },
pos = { pos = {
X: 0.0, X: 0.0,
@ -390,7 +390,7 @@ class Print {
hasmoved = false, hasmoved = false,
lastG = 'G1'; lastG = 'G1';
const output = scope.output = [ seq ]; const output = scope.output = [seq];
const beltaxis = { X: "X", Y: "Z", Z: "Y", E: "E", F: "F" }; const beltaxis = { X: "X", Y: "Z", Z: "Y", E: "E", F: "F" };
function LOG() { function LOG() {
@ -407,12 +407,13 @@ class Print {
*/ */
function processLine(line, axes) { function processLine(line, axes) {
const prevPoint = newPoint( const prevPoint = newPoint(
factor * pos.X , factor * pos.X,
factor * pos.Y , factor * pos.Y,
factor * pos.Z + dz factor * pos.Z + dz
) )
.add(xoff) .add(xoff)
.add(off); .add(off)
.setA(pos.A);
// apply origin offset // apply origin offset
// for (let layer of output) { // for (let layer of output) {
@ -424,7 +425,7 @@ class Print {
// } // }
// } // }
const point = prevPoint.clone() const point = prevPoint.clone();
line.forEach(tok => { line.forEach(tok => {
let axis = tok.charAt(0).toUpperCase(); let axis = tok.charAt(0).toUpperCase();
@ -440,31 +441,30 @@ class Print {
pos[axis] = val; pos[axis] = val;
if (axis == "X") point.x = factor * pos.X + xoff.x + off.x if (axis == "X") point.x = factor * pos.X + xoff.x + off.x
else if (axis == "Y") point.y = factor * pos.Y + xoff.y + off.y else if (axis == "Y") point.y = factor * pos.Y + xoff.y + off.y
else if (axis == "Z") point.z = factor * pos.Z + xoff.z + off.z + dz else if (axis == "Z") point.z = factor * pos.Z + xoff.z + off.z + dz;
} else { } else {
// mov[axis] = val;
pos[axis] += val; pos[axis] += val;
} }
// console.log("position updated",structuredClone(pos))
}); });
point.a = pos.A;
let center; let center;
if(axes.I !== undefined && axes.J !== undefined) { if (axes.I !== undefined && axes.J !== undefined) {
center = newPoint( center = newPoint(
factor* axes.I+ xoff.x, factor * axes.I + xoff.x,
factor* axes.J+ xoff.y, factor * axes.J + xoff.y,
0, 0,
); );
}else if(axes.R !== undefined) { } else if (axes.R !== undefined) {
center = newPoint( center = newPoint(
factor* Math.cos(axes.R * DEG2RAD), factor * Math.cos(axes.R * DEG2RAD),
factor* Math.sin(axes.R * DEG2RAD), factor * Math.sin(axes.R * DEG2RAD),
0, 0,
); );
} }
if(center){ if (center) {
center = center.add(prevPoint); center = center.add(prevPoint);
center.setZ((prevPoint.z+point.z)/2+dz); center.setZ((prevPoint.z + point.z) / 2 + dz);
} }
return { return {
center, center,
@ -473,7 +473,7 @@ class Print {
}; };
} }
function outputPoint(point,lastP,emit,{retract}) { function outputPoint(point, lastP, emit, { retract }) {
// non-move in a new plane means burp out // non-move in a new plane means burp out
// the old sequence and start a new one // the old sequence and start a new one
if (newlayer || (autolayer && seq.z != point.z)) { if (newlayer || (autolayer && seq.z != point.z)) {
@ -508,7 +508,7 @@ class Print {
} }
} }
// add point to current sequence // add point to current sequence
scope.addOutput(seq, point, emit, pos.F, tool, {retract}); scope.addOutput(seq, point, emit, pos.F, tool, { retract });
scope.lastPos = Object.assign({}, pos); scope.lastPos = Object.assign({}, pos);
scope.lastPosE = pos.E; scope.lastPosE = pos.E;
} }
@ -535,21 +535,13 @@ class Print {
const axes = {}; const axes = {};
lastG = g0 ? 'G0' : 'G1'; lastG = g0 ? 'G0' : 'G1';
const {point, prevPoint} = processLine(line,axes); let { point, prevPoint } = processLine(line, axes);
if (morph && belt) { if (morph && belt) {
point.y -= point.z * beltfact; point.y -= point.z * beltfact;
point.z *= beltfact; point.z *= beltfact;
} }
if (pos.A) {
let ip = new THREE.Vector3(pos.X, pos.Y, pos.Z)
.applyAxisAngle(XAXIS, -pos.A * DEG2RAD);
point.x = ip.x;
point.y = ip.y;
point.z = ip.z;
}
const retract = (fdm && pos.E < 0) || undefined; const retract = (fdm && pos.E < 0) || undefined;
const moving = g0 || (fdm && (pos.E <= 0 || !(axes.X || axes.Y || axes.Z))); const moving = g0 || (fdm && (pos.E <= 0 || !(axes.X || axes.Y || axes.Z)));
@ -567,7 +559,7 @@ class Print {
// always add moves to the current sequence // always add moves to the current sequence
if (moving) { if (moving) {
// console.log("move",structuredClone(point)) // console.log("move",structuredClone(point))
scope.addOutput(seq, point, 0, pos.F, tool,{retract}) scope.addOutput(seq, point, 0, pos.F, tool, { retract })
scope.lastPos = Object.assign({}, pos); scope.lastPos = Object.assign({}, pos);
return; return;
} }
@ -578,7 +570,32 @@ class Print {
seq.height = defh = height = pos.Z; seq.height = defh = height = pos.Z;
} }
outputPoint(point,prevPoint,1,{retract}) // interpolate rotational cuts for smooth display
if (point.a !== undefined && prevPoint.a !== undefined && point.a !== prevPoint.a) {
let dX = point.x - prevPoint.x;
let dY = point.y - prevPoint.y;
let dZ = point.z - prevPoint.z;
let dA = point.a - prevPoint.a;
let steps = Math.ceil(Math.abs(dA));
if (steps > 2) {
let pc = prevPoint.clone();
let iX = dX / steps;
let iY = dY / steps;
let iZ = dZ / steps;
let iA = dA / steps;
steps--;
while (steps-- > 0) {
pc.x += iX;
pc.y += iY;
pc.z += iZ;
pc.a += iA;
outputPoint(pc.clone(), prevPoint, moving ? 0 : 1, { lerp: true })
prevPoint = pc;
}
}
}
outputPoint(point, prevPoint, 1, { retract })
} }
const linemod = cam ? Math.ceil(lines.length / 2500) : 0; const linemod = cam ? Math.ceil(lines.length / 2500) : 0;
@ -594,7 +611,7 @@ class Print {
} }
if (line.indexOf('- LAYER ') > 0) { if (line.indexOf('- LAYER ') > 0) {
seq.height = defh; seq.height = defh;
const hd = line.replace('(','').replace(')','').split(' '); const hd = line.replace('(', '').replace(')', '').split(' ');
defh = parseFloat(hd[4]); defh = parseFloat(hd[4]);
if (fdm) dz = -defh / 2; if (fdm) dz = -defh / 2;
newlayer = true; newlayer = true;
@ -606,7 +623,7 @@ class Print {
line = line.trim().split(";")[0].split(" ").filter(v => v); line = line.trim().split(";")[0].split(" ").filter(v => v);
if (!line.length) return; if (!line.length) return;
const c0 = line[0].charAt(0); const c0 = line[0].charAt(0);
let cmd = ["X","Y","Z"].indexOf(c0) >= 0 ? lastG : line.shift(); let cmd = ["X", "Y", "Z"].indexOf(c0) >= 0 ? lastG : line.shift();
if (!cmd) return; if (!cmd) return;
if (cmd.charAt(0) === 'T') { if (cmd.charAt(0) === 'T') {
let ext = scope.settings.device.extruders; let ext = scope.settings.device.extruders;

View file

@ -53,9 +53,11 @@
clear: () => { send({ clear: true }) }, clear: () => { send({ clear: true }) },
parse: (data, type) => { send({ parse: data, type })}, parse: (data, type) => { send({ parse: data, type }) },
get: (scope) => { send({ get: scope })}, get: (scope) => { send({ get: scope }) },
set: (scope, data) => { send({ set: scope, data })},
setMode: (mode) => { send({ mode }) }, setMode: (mode) => { send({ mode }) },