fix: parser skips non-drawing moves; clean up TS build
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
c5c1b5e5c2
commit
960d453f57
3 changed files with 26 additions and 6 deletions
|
|
@ -47,4 +47,23 @@ describe('parseGcode', () => {
|
||||||
expect(segments).toHaveLength(1);
|
expect(segments).toHaveLength(1);
|
||||||
expect(warnings).toHaveLength(0);
|
expect(warnings).toHaveLength(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('does not emit segments for pure-Z plunge moves but keeps drawing XY after', () => {
|
||||||
|
const { segments } = parseGcode(`G21 G90\nG1 X5 Y0\nG1 Z-3\nG1 X10 Y0`);
|
||||||
|
expect(segments).toHaveLength(2);
|
||||||
|
expect(segments[1]!.points).toEqual([[5, 0], [10, 0]]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not emit a segment or warning for a bare motion word', () => {
|
||||||
|
const { segments, warnings } = parseGcode(`G21 G90\nG2\nG1 X5 Y0`);
|
||||||
|
expect(segments).toHaveLength(1);
|
||||||
|
expect(warnings).toHaveLength(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('still flattens a full-circle arc where start == end', () => {
|
||||||
|
const { segments } = parseGcode(`G21 G90\nG0 X10 Y0\nG2 X10 Y0 I-10 J0`);
|
||||||
|
const arc = segments[1]!;
|
||||||
|
expect(arc.kind).toBe('cut');
|
||||||
|
expect(arc.points.length).toBeGreaterThan(4);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -39,13 +39,11 @@ export function parseGcode(text: string): ParseResult {
|
||||||
}
|
}
|
||||||
|
|
||||||
const axis: Record<string, number> = {};
|
const axis: Record<string, number> = {};
|
||||||
let motionThisLine: number | null = null;
|
|
||||||
for (const [letter, value] of words) {
|
for (const [letter, value] of words) {
|
||||||
switch (letter) {
|
switch (letter) {
|
||||||
case 'G':
|
case 'G':
|
||||||
if (value === 0 || value === 1 || value === 2 || value === 3) {
|
if (value === 0 || value === 1 || value === 2 || value === 3) {
|
||||||
st.motion = value;
|
st.motion = value;
|
||||||
motionThisLine = value;
|
|
||||||
} else if (value === 20) st.scale = 25.4;
|
} else if (value === 20) st.scale = 25.4;
|
||||||
else if (value === 21) st.scale = 1;
|
else if (value === 21) st.scale = 1;
|
||||||
else if (value === 90) st.absolute = true;
|
else if (value === 90) st.absolute = true;
|
||||||
|
|
@ -61,8 +59,12 @@ export function parseGcode(text: string): ParseResult {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const hasCoord = 'X' in axis || 'Y' in axis || 'Z' in axis;
|
if ('Z' in axis) st.z = axis['Z']!; // track depth even on pure-Z moves
|
||||||
if (motionThisLine === null && !hasCoord) continue; // no movement on this line
|
const hasXY = 'X' in axis || 'Y' in axis;
|
||||||
|
const hasArc = 'I' in axis || 'J' in axis || 'R' in axis;
|
||||||
|
// Only XY motion (or an arc, including full circles) yields a drawable segment.
|
||||||
|
// This skips bare motion words (e.g. `G1`), pure-Z plunges, and modal/comment lines.
|
||||||
|
if (!hasXY && !hasArc) continue;
|
||||||
|
|
||||||
const start: Vec2 = [st.x, st.y];
|
const start: Vec2 = [st.x, st.y];
|
||||||
const target = resolveTarget(st, axis);
|
const target = resolveTarget(st, axis);
|
||||||
|
|
@ -88,7 +90,6 @@ export function parseGcode(text: string): ParseResult {
|
||||||
}
|
}
|
||||||
st.x = target[0];
|
st.x = target[0];
|
||||||
st.y = target[1];
|
st.y = target[1];
|
||||||
if ('Z' in axis) st.z = axis['Z']!;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return { segments, warnings };
|
return { segments, warnings };
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ describe('flattenArc', () => {
|
||||||
it('CW arc sweeps the other way (midpoint has negative y)', () => {
|
it('CW arc sweeps the other way (midpoint has negative y)', () => {
|
||||||
// centre (0,0), radius 10, from (10,0) CW to (0,10) → goes the long way through y<0
|
// centre (0,0), radius 10, from (10,0) CW to (0,10) → goes the long way through y<0
|
||||||
const pts = flattenArc([10, 0], [0, 10], [0, 0], true, 0.1);
|
const pts = flattenArc([10, 0], [0, 10], [0, 0], true, 0.1);
|
||||||
const mid = pts[Math.floor(pts.length / 2)];
|
const mid = pts[Math.floor(pts.length / 2)]!;
|
||||||
expect(mid[1]).toBeLessThan(0);
|
expect(mid[1]).toBeLessThan(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue