diff --git a/src/libslic3r/PresetBundle.cpp b/src/libslic3r/PresetBundle.cpp index d2913db55e..07d20cfb8b 100644 --- a/src/libslic3r/PresetBundle.cpp +++ b/src/libslic3r/PresetBundle.cpp @@ -4452,8 +4452,17 @@ std::vector PresetBundle::get_filament_presets_for_machine(const std:: return compatible; } +int PresetBundle::get_filament_variant_index(const DynamicPrintConfig &filament_config, const DynamicPrintConfig &printer_config, + int extruder_id, NozzleVolumeType nozzle_volume_type) +{ + const auto *extruder_types = printer_config.option("extruder_type"); + const ExtruderType extruder_type = extruder_types && !extruder_types->empty() ? ExtruderType(extruder_types->get_at(extruder_id)) : etDirectDrive; + return std::max(0, filament_config.get_index_for_extruder(1, "", extruder_type, nozzle_volume_type, "filament_extruder_variant")); +} + bool PresetBundle::check_filament_temp_equation_by_printer_type_and_nozzle_for_mas_tray( - const std::string &printer_type, std::string& nozzle_diameter_str, std::string &setting_id, std::string &tag_uid, std::string &nozzle_temp_min, std::string &nozzle_temp_max, std::string& preset_setting_id) + const std::string &printer_type, std::string& nozzle_diameter_str, std::string &setting_id, std::string &tag_uid, std::string &nozzle_temp_min, std::string &nozzle_temp_max, std::string& preset_setting_id, + int extruder_id, NozzleVolumeType nozzle_volume_type) { bool is_equation = true; @@ -4476,13 +4485,15 @@ bool PresetBundle::check_filament_temp_equation_by_printer_type_and_nozzle_for_m // Compare only once if (!compared) { compared = true; + const Preset *printer = printers.find_preset(printer_str); + const int variant_index = printer ? get_filament_variant_index(preset->config, printer->config, extruder_id, nozzle_volume_type) : 0; bool min_temp_equation = false, max_temp_equation = false; int min_nozzle_temp = std::stoi(nozzle_temp_min); int max_nozzle_temp = std::stoi(nozzle_temp_max); ConfigOption *opt_min = const_cast(preset)->config.option("nozzle_temperature_range_low"); if (opt_min) { ConfigOptionInts *opt_min_ints = dynamic_cast(opt_min); - min_nozzle_temp = opt_min_ints->get_at(0); + min_nozzle_temp = opt_min_ints->get_at(variant_index); if (std::to_string(min_nozzle_temp) == nozzle_temp_min) min_temp_equation = true; else { @@ -4493,7 +4504,7 @@ bool PresetBundle::check_filament_temp_equation_by_printer_type_and_nozzle_for_m ConfigOption *opt_max = const_cast(preset)->config.option("nozzle_temperature_range_high"); if (opt_max) { ConfigOptionInts *opt_max_ints = dynamic_cast(opt_max); - max_nozzle_temp = opt_max_ints->get_at(0); + max_nozzle_temp = opt_max_ints->get_at(variant_index); if (std::to_string(max_nozzle_temp) == nozzle_temp_max) max_temp_equation = true; else { diff --git a/src/libslic3r/PresetBundle.hpp b/src/libslic3r/PresetBundle.hpp index 0db1f6d9b1..e09ce9dcb5 100644 --- a/src/libslic3r/PresetBundle.hpp +++ b/src/libslic3r/PresetBundle.hpp @@ -407,13 +407,22 @@ public: std::vector get_filament_presets_for_machine(const std::string &printer_type, const std::string &nozzle_diameter_str, bool include_user_presets); + // Orca: the variant index of a filament preset's per-variant options on extruder extruder_id of a printer + // preset, with the nozzle volume type the machine reports; 0 when the filament has no such variant. + static int get_filament_variant_index(const DynamicPrintConfig &filament_config, + const DynamicPrintConfig &printer_config, + int extruder_id, + NozzleVolumeType nozzle_volume_type); + // extruder_id and nozzle_volume_type identify the tray's nozzle, whose variant the temperature range is compared for. bool check_filament_temp_equation_by_printer_type_and_nozzle_for_mas_tray(const std::string &printer_type, std::string & nozzle_diameter_str, std::string & setting_id, std::string & tag_uid, std::string & nozzle_temp_min, std::string & nozzle_temp_max, - std::string & preset_setting_id); + std::string & preset_setting_id, + int extruder_id, + NozzleVolumeType nozzle_volume_type); Preset * get_similar_printer_preset(std::string printer_model, std::string printer_variant); PresetCollection prints; diff --git a/src/slic3r/GUI/AMSMaterialsSetting.cpp b/src/slic3r/GUI/AMSMaterialsSetting.cpp index f0fdf950a0..edd1827f16 100644 --- a/src/slic3r/GUI/AMSMaterialsSetting.cpp +++ b/src/slic3r/GUI/AMSMaterialsSetting.cpp @@ -1000,11 +1000,12 @@ void AMSMaterialsSetting::Popup(wxString filament, wxString sn, wxString temp_mi // update if nozzle_temperature_range is found + const int variant_index = get_filament_variant_index(*filament_it, nozzle_diameter_str); ConfigOption *opt_min = filament_it->config.option("nozzle_temperature_range_low"); if (opt_min) { ConfigOptionInts *opt_min_ints = dynamic_cast(opt_min); if (opt_min_ints) { - wxString text_nozzle_temp_min = wxString::Format("%d", opt_min_ints->get_at(0)); + wxString text_nozzle_temp_min = wxString::Format("%d", opt_min_ints->get_at(variant_index)); m_input_nozzle_min->GetTextCtrl()->SetValue(text_nozzle_temp_min); } } @@ -1012,7 +1013,7 @@ void AMSMaterialsSetting::Popup(wxString filament, wxString sn, wxString temp_mi if (opt_max) { ConfigOptionInts *opt_max_ints = dynamic_cast(opt_max); if (opt_max_ints) { - wxString text_nozzle_temp_max = wxString::Format("%d", opt_max_ints->get_at(0)); + wxString text_nozzle_temp_max = wxString::Format("%d", opt_max_ints->get_at(variant_index)); m_input_nozzle_max->GetTextCtrl()->SetValue(text_nozzle_temp_max); } } @@ -1218,6 +1219,21 @@ void AMSMaterialsSetting::on_select_cali_result(wxCommandEvent &evt) } } +int AMSMaterialsSetting::get_filament_variant_index(const Preset &filament, const std::string &nozzle_diameter_str) +{ + PresetBundle *preset_bundle = wxGetApp().preset_bundle; + if (!obj || !preset_bundle) + return 0; + const std::set printer_names = + preset_bundle->get_printer_names_by_printer_type_and_nozzle(DevPrinterConfigUtil::get_printer_display_name(obj->printer_type), nozzle_diameter_str); + const Preset *printer = printer_names.empty() ? nullptr : preset_bundle->printers.find_preset(*printer_names.begin()); + if (!printer) + return 0; + const int extruder_id = obj->get_extruder_id_by_ams_id(std::to_string(ams_id)); + return PresetBundle::get_filament_variant_index(filament.config, printer->config, obj->get_preset_extruder_index(extruder_id), + DevNozzle::ToNozzleVolumeType(obj->GetExtderSystem()->GetNozzleFlowType(extruder_id))); +} + void AMSMaterialsSetting::on_select_filament(wxCommandEvent &evt) { // Get the flag whether to open the filament setting dialog from the device page @@ -1249,11 +1265,12 @@ void AMSMaterialsSetting::on_select_filament(wxCommandEvent &evt) if (it->filament_id != filament_id) continue; // ) if nozzle_temperature_range is found + const int variant_index = get_filament_variant_index(*it, nozzle_diameter_str); ConfigOption* opt_min = it->config.option("nozzle_temperature_range_low"); if (opt_min) { ConfigOptionInts* opt_min_ints = dynamic_cast(opt_min); if (opt_min_ints) { - wxString text_nozzle_temp_min = wxString::Format("%d", opt_min_ints->get_at(0)); + wxString text_nozzle_temp_min = wxString::Format("%d", opt_min_ints->get_at(variant_index)); m_input_nozzle_min->GetTextCtrl()->SetValue(text_nozzle_temp_min); } } @@ -1261,7 +1278,7 @@ void AMSMaterialsSetting::on_select_filament(wxCommandEvent &evt) if (opt_max) { ConfigOptionInts* opt_max_ints = dynamic_cast(opt_max); if (opt_max_ints) { - wxString text_nozzle_temp_max = wxString::Format("%d", opt_max_ints->get_at(0)); + wxString text_nozzle_temp_max = wxString::Format("%d", opt_max_ints->get_at(variant_index)); m_input_nozzle_max->GetTextCtrl()->SetValue(text_nozzle_temp_max); } } diff --git a/src/slic3r/GUI/AMSMaterialsSetting.hpp b/src/slic3r/GUI/AMSMaterialsSetting.hpp index 2cbd58e9a9..4cfdde791d 100644 --- a/src/slic3r/GUI/AMSMaterialsSetting.hpp +++ b/src/slic3r/GUI/AMSMaterialsSetting.hpp @@ -150,6 +150,8 @@ protected: void update_widgets(); void update_filament_editing(bool is_printing); + // Orca: the variant index of the filament's per-variant options on the nozzle this tray feeds + int get_filament_variant_index(const Preset &filament, const std::string &nozzle_diameter_str); protected: StateColor m_btn_bg_green; diff --git a/src/slic3r/GUI/DeviceManager.cpp b/src/slic3r/GUI/DeviceManager.cpp index 7d9abdee12..29fd113d1f 100644 --- a/src/slic3r/GUI/DeviceManager.cpp +++ b/src/slic3r/GUI/DeviceManager.cpp @@ -5696,7 +5696,7 @@ void MachineObject::update_filament_list() PresetBundle *preset_bundle = Slic3r::GUI::wxGetApp().preset_bundle; // custom filament - typedef std::map> map_pair; + typedef std::map, std::vector>> map_pair; std::map map_list; for (auto &pair : m_nozzle_filament_data) { map_list[pair.second.printer_preset_name] = map_pair{}; @@ -5708,19 +5708,13 @@ void MachineObject::update_filament_list() for (const std::string &printer_str : printer_strs->values) { if (map_list.find(printer_str) != map_list.end()) { auto & filament_list = map_list[printer_str]; - ConfigOption *opt_min = const_cast(preset).config.option("nozzle_temperature_range_low"); - int min_temp = -1; - if (opt_min) { - ConfigOptionInts *opt_min_ints = dynamic_cast(opt_min); - min_temp = opt_min_ints->get_at(0); - } - ConfigOption *opt_max = const_cast(preset).config.option("nozzle_temperature_range_high"); - int max_temp = -1; - if (opt_max) { - ConfigOptionInts *opt_max_ints = dynamic_cast(opt_max); - max_temp = opt_max_ints->get_at(0); - } - filament_list[preset.filament_id] = std::make_pair(min_temp, max_temp); + // Every variant's range, so a change to any of them rechecks the trays + std::vector min_temps{-1}, max_temps{-1}; + if (auto *opt_min = preset.config.option("nozzle_temperature_range_low")) + min_temps = opt_min->values; + if (auto *opt_max = preset.config.option("nozzle_temperature_range_high")) + max_temps = opt_max->values; + filament_list[preset.filament_id] = std::make_pair(min_temps, max_temps); break; } } @@ -5856,10 +5850,13 @@ void MachineObject::check_ams_filament_valid() need_checked_filament_id[nozzle_diameter_str].insert(curr_tray->setting_id); try { std::string preset_setting_id; + const int extruder_id = ams->GetExtruderId(); bool is_equation = preset_bundle->check_filament_temp_equation_by_printer_type_and_nozzle_for_mas_tray(printer_model, nozzle_diameter_str, curr_tray->setting_id, curr_tray->tag_uid, curr_tray->nozzle_temp_min, - curr_tray->nozzle_temp_max, preset_setting_id); + curr_tray->nozzle_temp_max, preset_setting_id, + get_preset_extruder_index(extruder_id), + DevNozzle::ToNozzleVolumeType(m_extder_system->GetNozzleFlowType(extruder_id))); if (!is_equation) { BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " " << __LINE__ << " ams filament is not match min max temp and reset, ams_id: " << ams_id << " tray_id" << slot_id << "filament_id: " << curr_tray->setting_id; @@ -5924,7 +5921,9 @@ void MachineObject::check_ams_filament_valid() this->printer_type), nozzle_diameter_str, vt_tray.setting_id, vt_tray.tag_uid, vt_tray.nozzle_temp_min, - vt_tray.nozzle_temp_max, preset_setting_id); + vt_tray.nozzle_temp_max, preset_setting_id, + get_preset_extruder_index(index), + DevNozzle::ToNozzleVolumeType(m_extder_system->GetNozzleFlowType(index))); if (!is_equation) { BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " " << __LINE__ << " vt_tray filament is not match min max temp and reset, filament_id: " << vt_tray.setting_id; diff --git a/src/slic3r/GUI/DeviceManager.hpp b/src/slic3r/GUI/DeviceManager.hpp index b69e2f8f5a..94f867b93d 100644 --- a/src/slic3r/GUI/DeviceManager.hpp +++ b/src/slic3r/GUI/DeviceManager.hpp @@ -341,6 +341,8 @@ public: bool is_main_extruder_on_left() const { return false; } // only means the extruder is on the left hand when extruder id is 0 bool is_multi_extruders() const; int get_extruder_id_by_ams_id(const std::string& ams_id); + // Orca: the printer preset's extruder index of device extruder extder_id + int get_preset_extruder_index(int extder_id) const { return is_multi_extruders() ? (is_main_extruder_on_left() ? extder_id : 1 - extder_id) : 0; } /* E3D has extra nozzle flow type info */ bool has_extra_flow_type{false}; @@ -957,7 +959,8 @@ public: { std::set checked_filament; std::string printer_preset_name; - std::map> filament_list; // filament_id, pair + // filament_id, pair, one per filament variant + std::map, std::vector>> filament_list; }; std::map m_nozzle_filament_data; void update_filament_list(); diff --git a/tests/libslic3r/test_preset_bundle_loading.cpp b/tests/libslic3r/test_preset_bundle_loading.cpp index b1ec3903bb..addc33b468 100644 --- a/tests/libslic3r/test_preset_bundle_loading.cpp +++ b/tests/libslic3r/test_preset_bundle_loading.cpp @@ -5940,3 +5940,19 @@ TEST_CASE("A project's different settings always keep the preset bookkeeping key CHECK(keys.count(key) == 1); CHECK(PresetBundle::project_different_keys(std::string()).count("inherits") == 1); } + +// A connected machine's tray is checked against the filament variant of the nozzle it feeds. +TEST_CASE("A filament's variant index follows the extruder type and nozzle volume type", "[Preset]") +{ + DynamicPrintConfig filament; + filament.option("filament_extruder_variant", true)->values = {"Direct Drive Standard", "Direct Drive High Flow", + "Bowden Standard"}; + DynamicPrintConfig printer; + printer.option("extruder_type", true)->values = {etDirectDrive, etBowden}; + + CHECK(PresetBundle::get_filament_variant_index(filament, printer, 0, nvtStandard) == 0); + CHECK(PresetBundle::get_filament_variant_index(filament, printer, 0, nvtHighFlow) == 1); + CHECK(PresetBundle::get_filament_variant_index(filament, printer, 1, nvtStandard) == 2); + // the filament defines no Bowden High Flow variant + CHECK(PresetBundle::get_filament_variant_index(filament, printer, 1, nvtHighFlow) == 0); +}