update_values_to_printer_extruders_for_multiple_filaments picks each
filament's value from the flattened (filament x variant) columns of every
per-filament variant option. When a column index fell past the end of the
option's values, it skipped that filament and left the zero the output
vector was created with.
The GUI always hands this function full columns, but the CLI does not:
- a CLI override of a single value, such as --nozzle-temperature=211 on a
four-filament project, came out as 211,0,0,0, so three filaments would
print at 0 C;
- loading fewer filament presets than the project has filaments left the
remaining filaments' columns missing, so filament_cooling_before_tower
came out as 10,10,0,0 and filament_ramming_volumetric_speed as -1,-1,0,0.
An out-of-range column now keeps the option's first value, the fallback
get_at() and the sibling gather step already use. The seven per-type copies
of the loop are replaced by that same gather_option_values helper, moved
above the function; it now takes its caller's name for its log lines. An
empty option, which has no first value, is given one registered default per
filament first; it used to be replaced with zeros.
On a partial load a filament whose preset was not loaded takes the first
filament's value rather than its own preset's, which the CLI does not load;
for the options seen in practice those agree.
- Print::update_filament_maps_to_config takes filament/volume/nozzle
maps, backfills an empty volume map from extruder types, rebuilds
filament_map_2, re-expands the per-filament variant arrays, and
recomputes retract overrides keyed by resolved slots
- grouping writes its result back in every non-sequential mode;
manual multi-nozzle grouping validates the user mapping and raises a
translatable error on deviation; the engine's concrete volume
assignment is deliberately not merged yet (per-filament arrays are
already consumed by filament id, so materializing High Flow now
would change motion before the layer-aware resolvers land)
- Print::apply treats the three map keys as engine outputs in auto
modes (erased from the diff and adopted), compares them against used
filaments in manual mode, and keeps the pre-expansion snapshot in
sync with the late normalization pass so rebuilt headers reflect the
sliced state instead of resurrecting stale values
- volume/nozzle maps and extruder_nozzle_stats join the invalidation
group of filament_map (wipe tower + skirt/brim)
- PresetBundle composes full configs with an optional per-filament
volume map (plate map, else defaults derived from each extruder's
flow type); project config keeps the map sized across filament
count changes
- PartPlate stores per-plate volume/nozzle maps; Plater injects them
at every slice-composition site (incl. g-code reload and wipe-tower
estimation); BackgroundSlicingProcess reads engine results back to
the plate in auto modes
- per-filament map trust guards relaxed to size-match everywhere now
that every producer sizes the map; single-filament explicit flow
assignments are honored
- tests: grouping volume maps stay concrete, merge semantics of
update_used_filament_values, single-filament override honoring
Motion g-code is byte-identical fleet-wide including Hybrid projects
(19-fixture gate + repro determinism double-slice). Header deltas:
the map keys now dump real values, and stale pre-normalization values
(e.g. enable_prime_tower on single-used-filament prints) no longer
leak into the config block.
- Print::get_nozzle_config_index / get_filament_config_indx resolve a
filament's variant slot per layer from the nozzle group result, with
hashed index caches; when no group result is published (sequential
prints), they fall back to the static filament->extruder mapping so
behavior is unchanged
- filament_map_2 caches each filament's resolved print-variant slot;
rebuilt in Print::apply after the filament_map diff handling and in
the filament-map write-back
- filament retract overrides now key by slot indices: apply_override
fallback indexing flips to 0-based, Print::apply passes
filament_map/extruder indices, the write-back passes filament_map_2
(identical resolution while slots equal extruders)
- filament_volume_map/filament_nozzle_map/filament_map_2/
filament_self_index become PrintConfig static members (required for
member access); grouping input guards tightened so their registered
1-element defaults are never mistaken for real per-filament maps
(single-filament manual mode keeps the mix-marker fallback)
- update_filament_self_index_cache refreshed at every full-config
assignment
- tests: 0-based apply_override fallback, get_config_index_base
hit/miss/mixed-type cases
The resolvers are not consumed by the g-code writer yet. Non-Hybrid
g-code is unchanged except the config header, which now serializes the
three new static keys (defaults until the per-filament producer lands);
verified by the 19-fixture byte gate: 3 added header lines per fixture,
zero motion changes.
- get_extruder_nozzle_volume_count derives per-extruder volume-type slot
lists from extruder_nozzle_stats (absent stats = one slot per extruder)
- update_values_to_printer_extruders learns the slot layout: when any
extruder mixes volume types, option arrays keep one slot per
(extruder x volume type), extruder-ascending then volume-ascending;
single-slot resolution takes the filament's volume type on mixed
extruders
- update_values_to_printer_extruders_for_multiple_filaments applies a
per-filament nozzle_volume_type override from filament_volume_map
(when sized to the filament count) and remaps filament_self_index
through the same pipeline as every other filament key
- get_config_index_base + is_auto_filament_map_mode helpers (consumers
land with the per-filament config-index resolvers)
- callers updated: PresetBundle composition paths, PrintApply (counts
hoisted above the extruder_applied guard), Print write-back
- new tests: slot counting, Hybrid slot expansion incl. stride 2,
per-filament override, non-Hybrid degeneracy
Non-Hybrid printers keep their variant layout and values (proven by a
19-fixture byte gate; the only header delta is filament_self_index now
flowing through the same variant pipeline as its sibling filament
keys). Hybrid slices grow the config-block variant arrays to one entry
per sub-nozzle volume type; motion g-code is unchanged until the
g-code writer consumes the new slots.