Skip to content

feat(renderer): opt-in retraction/deretraction markers (E9 phase 1, #148) - #168

Merged
sobechestnut-dev merged 1 commit into
devfrom
feat/148-retraction-markers-impl
Jul 24, 2026
Merged

feat(renderer): opt-in retraction/deretraction markers (E9 phase 1, #148)#168
sobechestnut-dev merged 1 commit into
devfrom
feat/148-retraction-markers-impl

Conversation

@sobechestnut-dev

Copy link
Copy Markdown

First E9 implementation phase (DD-009 D1).

Flagged deviation, maintainer-approved: D1's premise — that the IR already records Retract/Unretract kinds — was wrong. E-only retractions emit no segment; they existed only as stats counts. I verified this and, per your approval, added a small additive IR change: a sparse retractions events channel ({x,y,z,kind,srcByte,segIndex}, origin-relative) kept out of the main segment stream, so segment indices, scrub, and layer ranges are untouched. Recorded as a D1 amendment in the DD.

  • Parser records retract (E<0) / unretract (E>0) events with position + segIndex; capability retractions: known|unavailable.
  • Renderer: opt-in always-on-top markers (setShowRetractions, warm=retract / cool=unretract), clipped by the layer/scrub window; capability-honest.
  • Controller + Vue/React/Svelte: showRetractions prop (default off). Demo gains a toggle, enabled only when the IR has events.

Verified live in-browser (calicat): markers land exactly on object boundaries/seams; the toggle drives 0 → thousands of marker pixels. Focused parser + renderer tests added. Native goldens regenerated — additive retractions capability only, geometry unchanged (5 FDM prints now report known, CNC/edge unavailable).

markers

Refs #148 · #162 · DD-009

🤖 Generated with Claude Code

)

DD-009 D1 (amended at implementation — see the DD). The premise that the
IR already positioned retractions was wrong: E-only retraction moves emit
no segment, so retractions existed only as stats counts. Corrected with a
small additive IR change.

- toolpath-core: new sparse `retractions` events channel on ToolpathIR
  ({x,y,z,kind,srcByte,segIndex}, origin-relative), kept OUT of the main
  segment stream so segment indices/scrub/layer ranges are untouched;
  builder.addRetraction(); capability `retractions`.
- gcode-parser: records retract (E<0) / unretract (E>0) events with
  position + segIndex; capability known when present, else unavailable.
  Partial-preview slices carry none (markers resolve on the final IR).
- gcode-renderer-three: opt-in always-on-top Points marker layer
  (setShowRetractions; warm=retract, cool=unretract), clipped to the
  current layer/scrub window; hasRetractions getter; raw printer coords
  (root rotation handles Z-up→Y-up, cf. updateMarker); excluded from
  clearToolpathGeometry (owns its lifecycle).
- controller + Vue/React/Svelte adapters: showRetractions option/prop
  (default off). Demo: a Show-retractions toggle, enabled only when the
  IR carries events.

Tests: parser event recording (position/kind/segIndex/origin-relative,
no extra segments); renderer markers (off by default, capability-gated,
scrub-clipped). Native goldens regenerated (additive retractions
capability only; geometry unchanged). Verified LIVE in-browser: calicat
markers land on object boundaries/seams (warm/cool), toggle drives
0→thousands of marker pixels.

Refs #148, #162, DD-009

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@sobechestnut-dev
sobechestnut-dev merged commit d40d180 into dev Jul 24, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant