feat(engine): wire the per-filament volume-map producer pipeline

- 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.
This commit is contained in:
SoftFever
2026-07-11 04:38:31 +08:00
parent 18b9279c26
commit 03a704df7c
15 changed files with 429 additions and 70 deletions
+8 -3
View File
@@ -175,7 +175,8 @@ public:
const DynamicPrintConfig &project_config,
std::vector<Preset> &in_filament_presets,
bool apply_extruder,
std::optional<std::vector<int>> filament_maps_new);
std::optional<std::vector<int>> filament_maps_new,
std::optional<std::vector<int>> filament_volume_maps_new = std::nullopt);
// ORCA: utility function to find the vendor for a given preset name
static std::string find_preset_vendor(const std::string& preset_name, Preset::Type type);
@@ -383,10 +384,14 @@ public:
bool has_defauls_only() const
{ return prints.has_defaults_only() && filaments.has_defaults_only() && printers.has_defaults_only(); }
DynamicPrintConfig full_config(bool apply_extruder = true, std::optional<std::vector<int>>filament_maps = std::nullopt) const;
DynamicPrintConfig full_config(bool apply_extruder = true, std::optional<std::vector<int>>filament_maps = std::nullopt, std::optional<std::vector<int>> filament_volume_maps = std::nullopt) const;
// full_config() with the some "useless" config removed.
DynamicPrintConfig full_config_secure(std::optional<std::vector<int>>filament_maps = std::nullopt) const;
// Default per-filament nozzle-volume types: each filament inherits the volume type of the
// extruder it maps to (1-based f_maps), Standard when unknown.
std::vector<int> get_default_nozzle_volume_types_for_filaments(std::vector<int>& f_maps);
// Per-extruder flush matrix [extruder_id][from_filament][to_filament] in mm^3, optionally scaled
// by the per-extruder flush_multiplier (or flush_multiplier_fast when prime_volume_mode==Fast).
// Used by the print-dispatch nozzle-mapping flush-weight estimate.
@@ -543,7 +548,7 @@ private:
/*ConfigSubstitutions load_config_file_config_bundle(
const std::string &path, const boost::property_tree::ptree &tree, ForwardCompatibilitySubstitutionRule compatibility_rule);*/
DynamicPrintConfig full_fff_config(bool apply_extruder, std::optional<std::vector<int>> filament_maps=std::nullopt) const;
DynamicPrintConfig full_fff_config(bool apply_extruder, std::optional<std::vector<int>> filament_maps=std::nullopt, std::optional<std::vector<int>> filament_volume_maps=std::nullopt) const;
DynamicPrintConfig full_sla_config() const;
// Orca: used for validation only