Commit Graph
4 Commits
Author SHA1 Message Date
Clifford GarwoodandClaude Opus 5.5 53dad9f4fb Include what the IMEX code uses
Upstream's clang-tidy gate now checks that the lines a pull request changes
include the header for every symbol they use. The IMEX sources, their tests,
and the lines this PR adds to shared files relied on the precompiled header and
transitive includes. This adds the includes clang-tidy names; no code changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 11:55:18 -04:00
Clifford GarwoodandClaude Opus 5 dafc4ce39c Rework the parallel modes editor from the UI review
Addresses the interface notes on the IDEX/IQEX modes editor.

Add Mode moves from below the rows to the top of the panel, beside a "?" button
that now carries the overview text as its tooltip. At the bottom the button
shifted down the page every time a mode was added, so where it sat depended on
how many modes already existed. It is an Orca Button in the Confirm style, width
matched to the mode column it creates a row in, and the panel opens on the
legend rather than on a paragraph.

Remove moves out of the right-hand column, where it sat one icon away from
Edit -- a destructive control beside the one pressed most -- to under the name
field it deletes, and its icon becomes a boxed minus rather than an X, which
read as "close". Reset joins Edit in the right-hand column, which is now
top-aligned so the icons hold position regardless of row height. Tool tiles are
square at 24px, and the header spacer tracks that width so the column titles
stay over their columns when the grid changes shape.

The two text fields were landing on GTK's near-black default border, invisible
against the panel: measured 45,45,49 against a 43,43,43 background, where the
settings fields above use 74,74,81. wxTextCtrl cannot color its own border, so
each sits in a one pixel frame taking the color TextInput derives for the
theme, and carries wxBORDER_NONE so Windows and macOS do not draw a native edge
inside it. The G-code boxes also take the monospace face EditGCodeDialog uses.

Bed zone fills drop to roughly half opacity in the Standard theme. They cover
whole quadrants for a whole session, so at swatch saturation they dominate the
scene. The collision strip is dimmed less, since it marks where a head hits
something. The deuteranopia, tritanopia and high contrast themes keep their
alphas: those are chosen for discriminability, which is the opposite trade.

Also fixes the icon size never applying. All four ScalableButton call sites
passed eight arguments, so the size bound to use_default_disabled_bitmap and
bmp_px_cnt kept its default of 16. Both are passed now.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-30 23:38:37 -04:00
Clifford GarwoodandClaude Opus 5 6c67fcfe07 Read IMEX geometry defaults from print_config_def instead of literals
Five sites carried a hardcoded fallback for imex_tools_per_gantry that had
to match the value registered in print_config_def, with nothing enforcing
the agreement, and several explanatory comments miscounted the sites they
described or cited stale line numbers.

Add imex_cfg_int/_float/_bool/_enum<T> to IMEXHelpers, which return the
value registered for the key when it is absent from the config, so the
registration is the single source and there is nothing left to keep in
sync. Route every read of the IMEX geometry keys through them: 32 call
sites across IMEXZones, PartPlate, GCodeViewer and Tab. The only direct
lookup left is the bail in PartPlate::imex_multicolor_block_reason, which
must not default because it reports a routing conflict and a defaulted
grid would produce a false warning.

imex_cfg_enum uses dynamic_cast on both halves rather than the type()
comparison the others use: every ConfigOptionEnum<T> reports coEnum, so a
type() check cannot tell one enum type from another and would cast a
ConfigOptionEnum<OtherEnum> to the requested T. The ConfigOptionPercent :
ConfigOptionFloat inheritance that rules dynamic_cast out for the float
accessor has no analogue for enums.

Correct the comments that prompted this: the cache-key input list in
PartPlate named five inputs for a nine-part key, the ImexMarkerKey note
in GCodeViewer called imex_tool_layout an input only the preview reads
when the plate keys it too, and four file:line citations pointed at the
wrong lines. Values are unchanged at every converted site; cache key
strings keep their existing representation.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-04 20:34:04 -04:00
Clifford GarwoodandClaude Opus 5 fcfda6c835 Move the IMEX bed-zone geometry into libslic3r
Closes review comment 16, and fixes three defects the move exposed.

PartPlate::calc_imex_zones() was 392 lines deciding where every zone, collision
strip and safety margin sits, in the GUI layer, with no test coverage. The three
wxGetApp() calls that kept it there were all in its first 25 lines, fetching two
configs. The geometry now lives in compute_imex_zone_layout(); the wrapper fetches
the configs, calls it, and clips the returned rects to the bed outline for the
GLModels, which is the only part needing GUI types. libslic3r gained no wx
dependency: it takes DynamicPrintConfig directly, so the option lookups moved
verbatim rather than through a hand-written value struct that could drift.

The move is otherwise exact -- verified by a line-for-line diff of every
arithmetic expression against the original, and by running 15 scenarios through
the extracted code against hand-derived values. The only deletion is a lambda that
was never called.

Three fixes on top, each of which needed the code to be testable:

- An off-grid or absent Primary left pri_col/pri_row at their (0,0) initialisers
  and built a layout from them, reporting the whole bed as the clear primary zone
  and the whole bed as a blocked mirror zone at once; under
  imex_firmware_managed_zones it shifted the slice by the bed centre. Guarding on
  the resolved primary head covers both routes. Reachable only from a hand-edited
  preset or a 3MF authored against another printer -- the editor pins Primary to
  tool 0 -- but that is the same class the unresolved-mode fallback handles.
- imex_nozzle_clearance_x/y fell back to 0.0 where PrintConfig registers 30.0.
  Both strip loops are gated on the value being positive, so the fallback emitted
  no collision strips at all while the preview still drew 30 mm toolhead boxes.
- The collision-strip loop asked each mirror head for its own grid cell, but an
  aggregated gantry's cell is pinned to the primary's column and expanded into a
  full-width row strip. Where the representative's column differed from the
  primary's, no boundary matched and the plate came back with no strips and no
  margin bands -- an object flush against the shared boundary sliced without a
  warning while the far carriage occupied it. Present since Span aggregation was
  added in 4966d0fae8 and carried out of PartPlate verbatim. The flags now come
  from the painted cells; an exhaustive sweep of the reachable grid, role and
  layout space (1,630,720 configurations) shows the only behaviour change is the
  missing strips appearing.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-03 00:55:04 -04:00