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(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> = {};
|
||||
let motionThisLine: number | null = null;
|
||||
for (const [letter, value] of words) {
|
||||
switch (letter) {
|
||||
case 'G':
|
||||
if (value === 0 || value === 1 || value === 2 || value === 3) {
|
||||
st.motion = value;
|
||||
motionThisLine = value;
|
||||
} else if (value === 20) st.scale = 25.4;
|
||||
else if (value === 21) st.scale = 1;
|
||||
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 (motionThisLine === null && !hasCoord) continue; // no movement on this line
|
||||
if ('Z' in axis) st.z = axis['Z']!; // track depth even on pure-Z moves
|
||||
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 target = resolveTarget(st, axis);
|
||||
|
|
@ -88,7 +90,6 @@ export function parseGcode(text: string): ParseResult {
|
|||
}
|
||||
st.x = target[0];
|
||||
st.y = target[1];
|
||||
if ('Z' in axis) st.z = axis['Z']!;
|
||||
}
|
||||
|
||||
return { segments, warnings };
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ describe('flattenArc', () => {
|
|||
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
|
||||
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);
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue