From 9d733e50f9bbcbee78180f65c8dda00e7703a441 Mon Sep 17 00:00:00 2001 From: SoftFever Date: Sat, 22 Aug 2026 12:55:14 +0800 Subject: [PATCH] Fix prime tower and by-object brim with mixed filaments --- src/libslic3r/Print.cpp | 24 +++++++++++++++++++----- src/libslic3r/PrintConfig.cpp | 11 ++++++++++- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 33389d27c6..2bc4e9ee2a 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -2585,6 +2585,9 @@ void Print::process(long long *time_cost_with_cache, bool use_cache) std::vector::const_iterator print_object_instance_sequential_active; std::vector>> layers_to_print = GCode::collect_layers_to_print(*this); std::vector printExtruders; + // Per-object first-layer mixed-slot resolutions for the by-object remap below + // (BBS reads them from m_sequential_print_data->object_tool_ordering_map). + std::map> seq_mixed_resolution; // Cleared on every process so a print-sequence or selector-mode change can never leave // stale object pointers behind; repopulated below only by the sequential selector path. m_sequential_dynamic_orderings.clear(); @@ -2687,6 +2690,8 @@ void Print::process(long long *time_cost_with_cache, bool use_cache) } else { tool_ordering = ToolOrdering(*print_object, initial_extruder_id); tool_ordering.sort_and_build_data(*print_object, initial_extruder_id); + if (!tool_ordering.layer_tools().empty()) + seq_mixed_resolution[print_object->id()] = tool_ordering.layer_tools().front().mixed_filament_resolution; } if ((initial_extruder_id = tool_ordering.first_extruder()) != static_cast(-1)) { append(printExtruders, tool_ordering.tools_for_layer(layers_to_print.front().first).extruders); @@ -2722,14 +2727,23 @@ void Print::process(long long *time_cost_with_cache, bool use_cache) // Resolve mixed filament virtual slots to physical components so brim // extruder matching works correctly (mixed slot IDs are not present // in printExtruders after ToolOrdering::resolve_mixed_filaments). - if (m_config.print_sequence != PrintSequence::ByObject && !tool_ordering.layer_tools().empty()) { - const LayerTools &first_lt = tool_ordering.layer_tools().front(); + { + const LayerTools *first_lt = nullptr; + if (m_config.print_sequence != PrintSequence::ByObject && !tool_ordering.layer_tools().empty()) + first_lt = &tool_ordering.layer_tools().front(); for (auto &[obj_id, ext_1based] : objectExtruderMap) { if (ext_1based == 0) continue; - auto it = first_lt.mixed_filament_resolution.find(ext_1based - 1); - if (it != first_lt.mixed_filament_resolution.end()) - ext_1based = it->second + 1; + const std::map *resolution = nullptr; + if (first_lt) + resolution = &first_lt->mixed_filament_resolution; + else if (auto obj_it = seq_mixed_resolution.find(obj_id); obj_it != seq_mixed_resolution.end()) + resolution = &obj_it->second; + if (resolution) { + auto it = resolution->find(ext_1based - 1); + if (it != resolution->end()) + ext_1based = it->second + 1; + } } } std::vector> objPrintVec; diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 43559a3120..f2072c7860 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -2,6 +2,7 @@ #include "PrintConfigConstants.hpp" #include "ClipperUtils.hpp" #include "Config.hpp" +#include "FilamentMixer.hpp" #include "MaterialType.hpp" #include "I18N.hpp" #include "format.hpp" @@ -9669,7 +9670,15 @@ t_config_option_keys DynamicPrintConfig::normalize_fdm_2(int num_objects, int us ConfigOptionBool *enable_wrapping_opt = this->option("enable_wrapping_detection"); bool enable_wrapping = enable_wrapping_opt != nullptr && enable_wrapping_opt->value; - if (!is_smooth_timelapse && !enable_wrapping && (used_filaments == 1 || (ps_opt->value == PrintSequence::ByObject && num_objects > 1))) { + bool has_mixed_filament = false; + { + auto *mixed_opt = this->option("filament_is_mixed"); + if (mixed_opt) + has_mixed_filament = has_any_mixed_filament(mixed_opt->values); + } + if (!is_smooth_timelapse && !enable_wrapping + && ( (used_filaments == 1 && !has_mixed_filament) + || (ps_opt->value == PrintSequence::ByObject && num_objects > 1))) { if (ept_opt->value) { ept_opt->value = false; changed_keys.push_back("enable_prime_tower");