Skip to content

Set magnet positions as keep-out zones the toolpath routes around #64

Description

@BernardJen

Summary

Let the operator set where the hold-down magnets actually are, and have the generated
toolpath route around them — not just warn about them.

Motivation

#9 covers recommending and visualising magnet positions, but closes with an explicit scope
limit:

Magnets are preview/advisory only — they do not affect generated plot paths.

That is the part that matters in practice. The operator does not place magnets where the app
suggests — the sheet, the tape and the previous job decide that — so the useful direction is
the reverse: tell the app where the magnets went, and let it keep the carriage off them.

Nothing in the pipeline is obstacle-aware today. Travel between strokes is a single straight
G1 from the end of one stroke to the start of the next
(src/plot/gcode.ts:86):

lines.push(`G1 X${fmt(start.x)} Y${fmt(start.y)} F${travel}`);

orderPolylines (src/plot/gcode.ts:26) picks that next stroke purely
by nearest distance, so on an A0 bed a travel leg can cross the full sheet — straight over a
magnet. The pen or knife carriage then strikes it, which at travel feed drags the sheet, loses
the work origin (no limit switches, $22=0 — nothing recovers a lost origin) and ruins the job.

Proposal

Magnets become real geometry in the plot pipeline, not an overlay.

  • Set positions: click to place a magnet marker on the canvas at a paper-mm position;
    drag to move, delete to remove. Each magnet has a radius (its physical size plus a safety
    margin) — one global default in settings, overridable per magnet. Persisted with the
    session, and on the gateway (Persist app settings on the gateway (shared across clients) #14) since the magnets outlive a browser tab.
    • Worth considering: a jog-to-set flow like the registration wizard's — jog the carriage
      over each magnet and press Set, which records the magnet exactly where the machine
      can reach it rather than where the canvas says it is.
  • Route travel around them — a pure src/plot/ function, avoid.ts: given a travel
    segment and a set of circular keep-out zones, return a short detour polyline that clears
    them (tangent-based detour around each intersected circle is enough for circles this
    sparse; no general path planner needed). generateGcode emits the detour as pen-up G1
    moves instead of the single straight leg.
  • Refuse to cut through one: if cut/draw geometry — not travel — falls inside a magnet
    zone, no routing can fix it. Block the plot with a clear warning naming the overlap, since
    this is the case that breaks the machine rather than the drawing.
  • Feed the same zones into stroke ordering, so the nearest-stroke choice prefers a next
    stroke it can reach without a detour. Nice-to-have; correct routing comes first.

Acceptance criteria

  • Operator can add, move, remove and size magnet markers; positions persist across reload.
  • Travel moves that would cross a magnet zone are re-routed clear of it, and the detour is
    visible in the preview.
  • Geometry (not travel) overlapping a magnet zone blocks the plot with a warning that says
    which magnet and which stroke.
  • The avoidance transform is pure and unit-tested in src/plot/__tests__/ — segment
    clear of a zone is untouched, segment through a zone detours, chord grazing the edge,
    overlapping zones, start or end point inside a zone.
  • Plot-time estimate accounts for the detours (estimatePlotTime already measures whatever
    G-code it is given, so this should follow for free — confirm).
  • Hardware-verified: a job whose travel crosses a magnet completes without the carriage
    touching it (leave unchecked until the operator confirms on the machine — see AGENTS.md).

Relationship

Extends #9 past its "advisory only" note — #9 can stay as the recommend/visualise overlay and
this issue is the routing behaviour on top of it, or #9 folds into this one at triage. The
jog-to-set flow reuses the registration wizard (v1.2.0). Magnet size/margin settings belong on
the Settings page (#57), shared state on #14. Part of epic #10.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestneeds-triageMaintainer needs to evaluate this issue

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions