feat(engine): resolve per-variant config columns for raw filament reads on the export path

When a per-layer nozzle grouping migrates a filament across nozzle
variants, the write-back turns two groups of config arrays from
filament-indexed into column-indexed: the per-variant filament options
(one column per variant a filament uses) and the merged extruder
retract overrides (resized to the column count by apply_override).
Export-path readers that still indexed them with the raw filament id
read a neighbor's column for every filament ordered after a migrating
one: toolchange/standby temperatures (M104/M109), retraction lengths
and feedrates, wipe distance, z-hop types, air-filtration keys, and -
through the Extruder's cached flow term - the extrusion E of every
move.

Now every such read resolves its column through the existing
layer-aware resolver (get_filament_config_index ->
Print::get_filament_config_indx), which returns the raw filament id
whenever no per-layer grouping result is published, so static prints
are byte-inert by construction. The Extruder itself has no layer
knowledge, so it gains an injected config column (set_config_index,
default = filament id) that the generator refreshes at the only two
resolution-changing events - layer change and writer toolchange - and
that re-syncs the cached e_per_mm3 flow term. Old-filament reads
resolve at the current layer, which is safe because the per-layer maps
are gap-filled carry-forward. Whole-array placeholder copies
(toolchange temperature overrides) are rebuilt in filament order,
mirroring the existing per-variant placeholder remap. The resolvers
move to the public section so non-friend helpers (ooze prevention) can
resolve too.

Documented, deliberately unchanged: the wipe tower's per-filament
parameter rows (no layer dimension; tower x per-layer grouping is a
follow-up), travel_slope's physical-extruder read, estimator pre-heat
bookkeeping temps, and index-0 header diagnostics.

Verification: new Extruder column-injection scenario (defaults, column
follow + flow-cache rescale, filament-indexed reads unaffected, reset
semantics) and a migrating write-back case proving the column shift for
filaments ordered after a migrator and the resolver tracking it (11 +
14 assertions); suites green (libslic3r 48998/169, fff_print 655/61);
20/20 pinned-slice byte gate bit-identical (incl. sequential repro x2
deterministic).
This commit is contained in:
SoftFever
2026-07-12 14:30:39 +08:00
parent abbd420f2a
commit 582017235c
9 changed files with 275 additions and 64 deletions

View File

@@ -2969,6 +2969,8 @@ void GCodeProcessor::apply_config(const PrintConfig& config)
for (size_t i = 0; i < filament_count; ++ i) {
m_extruder_offsets[i] = to_3d(config.extruder_offset.get_at(filament_map[i] - 1).cast<float>().eval(), 0.f);
m_extruder_colors[i] = static_cast<unsigned char>(i);
// Orca: pre-heat bookkeeping reads the filament's first per-variant column by design;
// it feeds estimation-side heat-up modelling only, never the emitted commands.
m_filament_nozzle_temp_first_layer[i] = static_cast<int>(config.nozzle_temperature_initial_layer.get_at(i));
m_filament_nozzle_temp[i] = static_cast<int>(config.nozzle_temperature.get_at(i));
if (m_filament_nozzle_temp[i] == 0) {