mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-08-05 17:17:42 +00:00
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:
@@ -1212,7 +1212,7 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_
|
||||
|
||||
//BBS: process the filament_map related logic
|
||||
std::unordered_set<std::string> print_diff_set(print_diff.begin(), print_diff.end());
|
||||
if (print_diff_set.find("filament_map_mode") == print_diff_set.end())
|
||||
if (!print_diff_set.empty() && print_diff_set.find("filament_map_mode") == print_diff_set.end())
|
||||
{
|
||||
FilamentMapMode map_mode = new_full_config.option<ConfigOptionEnum<FilamentMapMode>>("filament_map_mode", true)->value;
|
||||
if (is_auto_filament_map_mode(map_mode)) {
|
||||
@@ -1224,9 +1224,29 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_
|
||||
old_opt->set(new_opt);
|
||||
m_config.filament_map = *new_opt;
|
||||
}
|
||||
if (print_diff_set.find("filament_volume_map") != print_diff_set.end()) {
|
||||
print_diff_set.erase("filament_volume_map");
|
||||
//full_config_diff.erase("filament_volume_map");
|
||||
ConfigOptionInts* old_opt = m_full_print_config.option<ConfigOptionInts>("filament_volume_map", true);
|
||||
ConfigOptionInts* new_opt = new_full_config.option<ConfigOptionInts>("filament_volume_map", true);
|
||||
old_opt->set(new_opt);
|
||||
m_config.filament_volume_map = *new_opt;
|
||||
}
|
||||
if (print_diff_set.find("filament_nozzle_map") != print_diff_set.end()) {
|
||||
print_diff_set.erase("filament_nozzle_map");
|
||||
//full_config_diff.erase("filament_nozzle_map");
|
||||
ConfigOptionInts* old_opt = m_full_print_config.option<ConfigOptionInts>("filament_nozzle_map", true);
|
||||
ConfigOptionInts* new_opt = new_full_config.option<ConfigOptionInts>("filament_nozzle_map", true);
|
||||
old_opt->set(new_opt);
|
||||
m_config.filament_nozzle_map = *new_opt;
|
||||
}
|
||||
}
|
||||
else {
|
||||
print_diff_set.erase("extruder_ams_count");
|
||||
if (map_mode == fmmManual) {
|
||||
// filament_nozzle_map is an engine output, not a GUI input, in manual mode
|
||||
print_diff_set.erase("filament_nozzle_map");
|
||||
}
|
||||
std::vector<int> old_filament_map = m_config.filament_map.values;
|
||||
std::vector<int> new_filament_map = new_full_config.option<ConfigOptionInts>("filament_map", true)->values;
|
||||
|
||||
@@ -1243,8 +1263,32 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (same_map)
|
||||
if (same_map) {
|
||||
print_diff_set.erase("filament_map");
|
||||
|
||||
// The extruder retract overrides are keyed by the (unchanged) filament map;
|
||||
// recompute them and drop diffs whose recomputed value matches the current
|
||||
// config, so a cosmetic reordering of unused filaments does not invalidate.
|
||||
const auto& retract_keys = print_config_def.extruder_retract_keys();
|
||||
const std::string filament_prefix = "filament_";
|
||||
std::vector<int> old_f_map_indices(old_filament_map.size(), 0);
|
||||
for (size_t i = 0; i < old_filament_map.size(); i++)
|
||||
old_f_map_indices[i] = old_filament_map[i] - 1;
|
||||
|
||||
for (const auto& rk : retract_keys) {
|
||||
if (print_diff_set.find(rk) == print_diff_set.end())
|
||||
continue;
|
||||
const ConfigOption* opt_old = m_config.option(rk);
|
||||
const ConfigOption* opt_new_m = new_full_config.option(rk);
|
||||
const ConfigOption* opt_new_f = new_full_config.option(filament_prefix + rk);
|
||||
if (opt_old && opt_new_m && opt_new_f) {
|
||||
std::unique_ptr<ConfigOption> opt_recomputed(opt_new_m->clone());
|
||||
opt_recomputed->apply_override(opt_new_f, old_f_map_indices);
|
||||
if (*opt_old == *opt_recomputed)
|
||||
print_diff_set.erase(rk);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (print_diff_set.size() != print_diff.size())
|
||||
@@ -1265,11 +1309,12 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_
|
||||
{
|
||||
ExtruderType extruder_type = (ExtruderType)(opt_extruder_type->get_at(filament_maps[index] - 1));
|
||||
NozzleVolumeType nozzle_volume_type = (NozzleVolumeType)(opt_nozzle_volume_type->get_at(filament_maps[index] - 1));
|
||||
// Orca: the per-filament volume map is only trustworthy when a producer explicitly sized it
|
||||
// to the filament count; the registered default is a 1-element vector (see
|
||||
// Orca: honour the per-filament volume map only when a producer sized it to the filament
|
||||
// count; mis-sized maps (stale project values, CLI runs until the per-filament synthesis
|
||||
// lands there) must not be indexed per filament (see
|
||||
// update_values_to_printer_extruders_for_multiple_filaments for the same guard).
|
||||
if ((extruder_volume_type_count > extruder_count) && opt_filament_volume_maps
|
||||
&& filament_maps.size() > 1 && opt_filament_volume_maps->values.size() == filament_maps.size())
|
||||
&& opt_filament_volume_maps->values.size() == filament_maps.size())
|
||||
nozzle_volume_type = (NozzleVolumeType)(opt_filament_volume_maps->values[index]);
|
||||
m_config.filament_map_2.values[index] = new_full_config.get_index_for_extruder(filament_maps[index], "print_extruder_id", extruder_type, nozzle_volume_type, "print_extruder_variant");
|
||||
}
|
||||
@@ -1694,6 +1739,12 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_
|
||||
m_default_object_config.apply_only(new_full_config, new_changed_keys, true);
|
||||
// Handle changes to regions config defaults
|
||||
m_default_region_config.apply_only(new_full_config, new_changed_keys, true);
|
||||
// Orca: keep the pre-expansion snapshot in sync with this late normalization pass.
|
||||
// The engine map write-back rebuilds m_full_print_config from m_ori_full_print_config
|
||||
// after slicing; a stale snapshot would resurrect the un-normalized values (e.g.
|
||||
// enable_prime_tower on a single-filament print) in the dumped config and spuriously
|
||||
// re-invalidate the g-code on the next apply.
|
||||
m_ori_full_print_config.apply_only(new_full_config, new_changed_keys, true);
|
||||
m_full_print_config = std::move(new_full_config);
|
||||
update_filament_self_index_cache();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user