From f7643eb3be15f50a799dd8f5eb4e23484c183d23 Mon Sep 17 00:00:00 2001 From: "xun.zhang" Date: Tue, 15 Jul 2025 15:19:09 +0800 Subject: [PATCH] ENH: update prompt for filament mix printing jira: NONE Signed-off-by: xun.zhang Change-Id: I92c86edadd6720b0e566057bd2593605ee4a3f77 (cherry picked from commit a93f6a54a2be94807702e3c75bdb4c79d508f260) --- src/slic3r/GUI/GLCanvas3D.cpp | 14 ++++++++++++ src/slic3r/GUI/GLCanvas3D.hpp | 1 + src/slic3r/GUI/PartPlate.cpp | 42 +++++++++++++++++++++++++++++++++++ src/slic3r/GUI/PartPlate.hpp | 1 + 4 files changed, 58 insertions(+) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 1611918bdb..0c2e8202af 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -142,6 +142,12 @@ std::string& get_nozzle_filament_incompatible_text() { return nozzle_filament_incompatible_text; } +std::string& get_filament_mixture_warning_text(){ + static std::string filament_mixture_warning_text; + return filament_mixture_warning_text; +} + + static std::string format_number(float value) { std::ostringstream oss; @@ -3052,6 +3058,9 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re bool filament_nozzle_compatible = cur_plate->check_compatible_of_nozzle_and_filament(full_config_temp, wxGetApp().preset_bundle->filament_presets, get_nozzle_filament_incompatible_text()); _set_warning_notification(EWarning::NozzleFilamentIncompatible, !filament_nozzle_compatible); + bool filament_mixture_compatible = cur_plate->check_mixture_filament_compatible(full_config_temp, get_filament_mixture_warning_text()); + _set_warning_notification(EWarning::MixtureFilamentIncompatible, !filament_mixture_compatible); + bool model_fits = contained_min_one && !m_model->objects.empty() && !partlyOut && object_results.filaments.empty() && tpu_valid && filament_printable; post_event(Event(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, model_fits)); ppl.get_curr_plate()->update_slice_ready_status(model_fits); @@ -3070,6 +3079,7 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re _set_warning_notification(EWarning::MultiExtruderPrintableError,false); _set_warning_notification(EWarning::MultiExtruderHeightOutside,false); _set_warning_notification(EWarning::NozzleFilamentIncompatible,false); + _set_warning_notification(EWarning::MixtureFilamentIncompatible,false); post_event(Event(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, false)); } @@ -10124,6 +10134,10 @@ void GLCanvas3D::_set_warning_notification(EWarning warning, bool state) text = _u8L(get_nozzle_filament_incompatible_text()); break; } + case EWarning::MixtureFilamentIncompatible: { + text = _u8L(get_filament_mixture_warning_text()); + break; + } } //BBS: this may happened when exit the app, plater is null if (!wxGetApp().plater()) diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 4de222eb49..0c787ae729 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -394,6 +394,7 @@ class GLCanvas3D MixUsePLAAndPETG, PrimeTowerOutside, NozzleFilamentIncompatible, + MixtureFilamentIncompatible, }; class RenderStats diff --git a/src/slic3r/GUI/PartPlate.cpp b/src/slic3r/GUI/PartPlate.cpp index 1e666e2709..6c0164007d 100644 --- a/src/slic3r/GUI/PartPlate.cpp +++ b/src/slic3r/GUI/PartPlate.cpp @@ -1822,6 +1822,48 @@ bool PartPlate::check_mixture_of_pla_and_petg(const DynamicPrintConfig &config) return true; } +bool PartPlate::check_mixture_filament_compatible(const DynamicPrintConfig &config, std::string &error_msg) +{ + static std::unordered_map> incompatible_filament_pairs; + + auto add_incompatibility = [&](std::string filament_type1, std::string filament_type2) { + incompatible_filament_pairs[filament_type1].insert(filament_type2); + incompatible_filament_pairs[filament_type2].insert(filament_type1); + }; + + if (incompatible_filament_pairs.empty()) { add_incompatibility("PVA", "PETG"); } + + std::vector used_filaments = get_extruders(true); // 1 based idx + std::vector filament_types; + auto filament_type_opt = config.option("filament_type"); + for (auto filament : used_filaments) { + int filament_idx = filament - 1; + filament_types.push_back(filament_type_opt->values[filament_idx]); + }; + + { + std::unordered_set seen; + filament_types.erase(std::remove_if(filament_types.begin(), filament_types.end(), [&](const std::string &s) { return !seen.insert(s).second; }), filament_types.end()); + } + + std::vector> conflicts; + + for (size_t i = 0; i < filament_types.size(); i++) { + auto it = incompatible_filament_pairs.find(filament_types[i]); + if (it == incompatible_filament_pairs.end()) continue; + for (size_t j = i + 1; j < filament_types.size(); ++j) { + if (it->second.count(filament_types[j])) { conflicts.emplace_back(filament_types[i], filament_types[j]); } + } + } + + if (!conflicts.empty()) { + // TODO: add the full text if has multi conflict + auto conflict = conflicts.front(); + error_msg = GUI::format(_L("Mixing %1% with %2% in printing is not recommended.\n"), conflict.first, conflict.second); + } + return conflicts.empty(); +} + bool PartPlate::check_compatible_of_nozzle_and_filament(const DynamicPrintConfig &config, const std::vector &filament_presets, std::string &error_msg) { float nozzle_diameter = config.option("nozzle_diameter")->values[0]; diff --git a/src/slic3r/GUI/PartPlate.hpp b/src/slic3r/GUI/PartPlate.hpp index 298186ff25..708e0624ec 100644 --- a/src/slic3r/GUI/PartPlate.hpp +++ b/src/slic3r/GUI/PartPlate.hpp @@ -341,6 +341,7 @@ public: bool check_filament_printable(const DynamicPrintConfig & config, wxString& error_message); bool check_tpu_printable_status(const DynamicPrintConfig & config, const std::vector &tpu_filaments); bool check_mixture_of_pla_and_petg(const DynamicPrintConfig & config); + bool check_mixture_filament_compatible(const DynamicPrintConfig& config, std::string &error_msg); bool check_compatible_of_nozzle_and_filament(const DynamicPrintConfig & config, const std::vector& filament_presets, std::string& error_msg); /* instance related operations*/