feat(config): keep per-(extruder x volume-type) slots in variant expansion

- 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.
This commit is contained in:
SoftFever
2026-07-11 00:51:10 +08:00
parent 7c8d086d9e
commit 13cd8d4864
7 changed files with 631 additions and 197 deletions
+16 -2
View File
@@ -468,6 +468,11 @@ enum FilamentMapMode {
fmmDefault
};
// All auto modes are ordered before fmmManual (see the enum ordering note above).
inline bool is_auto_filament_map_mode(FilamentMapMode mode) {
return mode < fmmManual;
}
// Dual-extruder purge control. Default reproduces the current
// per-extruder flush_multiplier + filament_prime_volume behaviour, so absent/default is inert.
// Saving -> reduce prime volume to 15 mm3; Fast -> use flush_multiplier_fast + filament_flush_temp_fast.
@@ -479,6 +484,10 @@ enum PrimeVolumeMode {
extern std::string get_extruder_variant_string(ExtruderType extruder_type, NozzleVolumeType nozzle_volume_type);
// Base slot lookup: scans a variant list (paired with its 1-based extruder/filament ids) for the
// entry matching the given extruder/volume type and id. Returns 0 when no entry matches.
extern int get_config_index_base(NozzleVolumeType volume_type, ExtruderType extruder_type, int variant_id_1based, const std::vector<std::string>& variant_list, const std::vector<int>& variant_ids_1based);
static std::set<NozzleVolumeType> get_valid_nozzle_volume_type() {
std::set<NozzleVolumeType> type;
for (int i = 0; i <= nvtMaxNozzleVolumeType; ++i) {
@@ -731,9 +740,14 @@ public:
//BBS
bool is_using_different_extruders();
bool support_different_extruders(int& extruder_count) const;
// Counts the config slots of a printer: one per (extruder x nozzle volume type) as described by
// extruder_nozzle_stats, or simply one per extruder when the stats are absent/mismatched.
// Fills nozzle_volume_types with each extruder's volume types in ascending enum order.
int get_extruder_nozzle_volume_count(int extruder_count, std::vector<std::vector<NozzleVolumeType>>& nozzle_volume_types) const;
int get_index_for_extruder(int extruder_or_filament_id, std::string id_name, ExtruderType extruder_type, NozzleVolumeType nozzle_volume_type, std::string variant_name, unsigned int stride = 1) const;
void update_values_to_printer_extruders(DynamicPrintConfig& printer_config, std::set<std::string>& key_set, std::string id_name, std::string variant_name, unsigned int stride = 1, unsigned int extruder_id = 0);
void update_values_to_printer_extruders_for_multiple_filaments(DynamicPrintConfig& printer_config, std::set<std::string>& key_set, std::string id_name, std::string variant_name);
std::vector<int> update_values_to_printer_extruders(DynamicPrintConfig& printer_config, int extruder_count, int extruder_nozzle_volume_count, std::vector<std::vector<NozzleVolumeType>>& nv_types,
std::set<std::string>& key_set, std::string id_name, std::string variant_name, unsigned int stride = 1, unsigned int extruder_id = 0, NozzleVolumeType filament_nvt = nvtStandard);
void update_values_to_printer_extruders_for_multiple_filaments(DynamicPrintConfig& printer_config, int extruder_count, int extruder_nozzle_volume_count, std::set<std::string>& key_set, std::string id_name, std::string variant_name);
void update_non_diff_values_to_base_config(DynamicPrintConfig& new_config, const t_config_option_keys& keys, const std::set<std::string>& different_keys, std::string extruder_id_name, std::string extruder_variant_name,
std::set<std::string>& key_set1, std::set<std::string>& key_set2);