diff --git a/src/slic3r/GUI/AMSMaterialsSetting.cpp b/src/slic3r/GUI/AMSMaterialsSetting.cpp index 0c470f5254..17f93961d4 100644 --- a/src/slic3r/GUI/AMSMaterialsSetting.cpp +++ b/src/slic3r/GUI/AMSMaterialsSetting.cpp @@ -544,11 +544,24 @@ void AMSMaterialsSetting::on_select_reset(wxCommandEvent& event) { } if (obj) { - if(m_is_third){ + if (m_is_third || is_virtual_tray()) { obj->command_ams_filament_settings(ams_id, slot_id, ams_filament_id, ams_setting_id, std::string(col_buf), m_filament_type, nozzle_temp_min_int, nozzle_temp_max_int); } + if (is_virtual_tray()) { + int vt_slot_idx = ams_id == VIRTUAL_TRAY_MAIN_ID ? MAIN_EXTRUDER_ID : DEPUTY_EXTRUDER_ID; + while (obj->vt_slot.size() <= vt_slot_idx) { + obj->vt_slot.push_back(DevAmsTray(std::to_string(obj->vt_slot.size() == MAIN_EXTRUDER_ID ? VIRTUAL_TRAY_MAIN_ID : VIRTUAL_TRAY_DEPUTY_ID))); + } + + auto &vt_tray = obj->vt_slot[vt_slot_idx]; + vt_tray.reset(); + vt_tray.id = std::to_string(ams_id); + vt_tray.color = std::string(col_buf); + vt_tray.set_hold_count(); + } + // set k / n value if (!obj->GetCalib()->IsVersionInited() && obj->get_printer_series() == PrinterSeries::SERIES_P1P) { // set extrusion cali ratio @@ -727,10 +740,30 @@ void AMSMaterialsSetting::on_select_ok(wxCommandEvent& event) // set filament - if (m_is_third) { + if (m_is_third || is_virtual_tray()) { obj->command_ams_filament_settings(ams_id, slot_id, ams_filament_id, ams_setting_id, std::string(col_buf), m_filament_type, nozzle_temp_min_int, nozzle_temp_max_int); } + if (is_virtual_tray()) { + int vt_slot_idx = ams_id == VIRTUAL_TRAY_MAIN_ID ? MAIN_EXTRUDER_ID : DEPUTY_EXTRUDER_ID; + while (obj->vt_slot.size() <= vt_slot_idx) { + obj->vt_slot.push_back(DevAmsTray(std::to_string(obj->vt_slot.size() == MAIN_EXTRUDER_ID ? VIRTUAL_TRAY_MAIN_ID : VIRTUAL_TRAY_DEPUTY_ID))); + } + + auto &vt_tray = obj->vt_slot[vt_slot_idx]; + vt_tray.id = std::to_string(ams_id); + vt_tray.setting_id = ams_filament_id; + vt_tray.filament_setting_id = ams_setting_id; + vt_tray.m_fila_type = m_filament_type; + vt_tray.color = std::string(col_buf); + vt_tray.nozzle_temp_min = std::to_string(nozzle_temp_min_int); + vt_tray.nozzle_temp_max = std::to_string(nozzle_temp_max_int); + vt_tray.is_bbl = !m_is_third; + vt_tray.set_hold_count(); + vt_tray.hold_count = HOLD_COUNT_MAX * 5; + obj->ams_version = -1; + } + //reset param wxString k_text = m_input_k_val->GetTextCtrl()->GetValue(); wxString n_text = m_input_n_val->GetTextCtrl()->GetValue(); diff --git a/src/slic3r/GUI/AmsMappingPopup.cpp b/src/slic3r/GUI/AmsMappingPopup.cpp index 87f82adaaa..171b0d2fbe 100644 --- a/src/slic3r/GUI/AmsMappingPopup.cpp +++ b/src/slic3r/GUI/AmsMappingPopup.cpp @@ -29,6 +29,7 @@ #include "DeviceCore/DevFilaSystem.h" #include "DeviceCore/DevFilaSwitch.h" #include "DeviceCore/DevMappingNozzle.h" +#include "DeviceCore/DevUtilBackend.h" #include "DeviceTab/wgtDeviceNozzleSelect.h" #include "DeviceTab/wgtMsgPanel.h" @@ -1120,6 +1121,28 @@ bool AmsMapingPopup::is_match_material(std::string material) const return m_tag_material == material ? true : false; } +bool AmsMapingPopup::is_ext_slot_compatible_with_current_filament(int ams_id) const +{ + if (!devPrinterUtil::IsVirtualSlot(ams_id)) { + return true; + } + + auto nozzle_group_res = DevUtilBackend::GetNozzleGroupResult(wxGetApp().plater()); + if (!nozzle_group_res) { + return true; + } + + const auto& nozzle_infos = nozzle_group_res->get_nozzles_for_filament(m_current_filament_id); + if (nozzle_infos.empty()) { + return true; + } + + const int required_logic_extruder = (ams_id == VIRTUAL_TRAY_MAIN_ID) ? LOGIC_R_EXTRUDER_ID : LOGIC_L_EXTRUDER_ID; + return std::any_of(nozzle_infos.begin(), nozzle_infos.end(), [required_logic_extruder](const auto& nozzle_info) { + return nozzle_info.extruder_id == required_logic_extruder; + }); +} + void AmsMapingPopup::on_left_down(wxMouseEvent &evt) { @@ -1148,8 +1171,7 @@ void AmsMapingPopup::on_left_down(wxMouseEvent &evt) } if (item->m_tray_data.type == TrayType::EMPTY) return; - if (m_show_type == ShowType::LEFT_AND_RIGHT_DYNAMIC && devPrinterUtil::IsVirtualSlot(item->m_ams_id)) return; - + if (m_show_type == ShowType::LEFT_AND_RIGHT_DYNAMIC && !is_ext_slot_compatible_with_current_filament(item->m_ams_id)) return; if ((m_show_type == ShowType::LEFT && item->GetParent()->GetName() == "left") || (m_show_type == ShowType::RIGHT && item->GetParent()->GetName() == "right") || m_show_type == ShowType::LEFT_AND_RIGHT || diff --git a/src/slic3r/GUI/AmsMappingPopup.hpp b/src/slic3r/GUI/AmsMappingPopup.hpp index 1944089c6f..bbf0ed6f45 100644 --- a/src/slic3r/GUI/AmsMappingPopup.hpp +++ b/src/slic3r/GUI/AmsMappingPopup.hpp @@ -342,6 +342,7 @@ class AmsMapingPopup : public PopupWindow void set_current_filament_id(int id) { m_current_filament_id = id; }; int get_current_filament_id(){return m_current_filament_id;}; bool is_match_material(std::string material) const; + bool is_ext_slot_compatible_with_current_filament(int ams_id) const; void on_left_down(wxMouseEvent &evt); virtual void OnDismiss() wxOVERRIDE; virtual bool ProcessLeftDown(wxMouseEvent &event) wxOVERRIDE; diff --git a/src/slic3r/GUI/AmsMappingPopupUpdate.cpp b/src/slic3r/GUI/AmsMappingPopupUpdate.cpp index cc47e8404f..d3096b9f59 100644 --- a/src/slic3r/GUI/AmsMappingPopupUpdate.cpp +++ b/src/slic3r/GUI/AmsMappingPopupUpdate.cpp @@ -40,6 +40,18 @@ namespace Slic3r::GUI { +static wxString s_external_spool_with_switcher_tip() +{ + return _L("External spool can be selected while Filament Track Switch is installed. " + "Route the filament through the external buffer or bypass the Filament Track Switch directly to the selected toolhead. " + "Printer firmware may still reject unsupported routes."); +} + +static wxString s_external_spool_wrong_nozzle_tip() +{ + return _L("This external spool is connected to the other nozzle. Select the external spool for the nozzle used by this filament."); +} + static void _add_containers(const AmsMapingPopup* win, std::list& one_slot_containers, @@ -486,8 +498,7 @@ void AmsMapingPopup::update_ams_tips(MachineObject* obj) } if (obj && obj->GetFilaSwitch()->IsInstalled()) { - const auto& msg = _L("External spools is not supported since Filament Track Switch has been installed. If you want to use external spool, please uninstall it."); - m_ams_tips_msg_panel->AddMessage(msg, "#FF6F00", ""); + m_ams_tips_msg_panel->AddMessage(s_external_spool_with_switcher_tip(), "#FF6F00", ""); } m_ams_tips_msg_panel->Layout(); @@ -580,10 +591,13 @@ void AmsMapingPopup::add_ams_mapping(std::vector tray_data, if (m_use_in_sync_dialog) { if (can_pick_the_item) { if (m_show_type == ShowType::LEFT_AND_RIGHT_DYNAMIC) { - can_pick_the_item = !devPrinterUtil::IsVirtualSlot(m_mapping_item->m_ams_id); - if (!can_pick_the_item) { - item_tooltip_msg = _L( - "External spools is not supported since Filament Track Switch has been installed. If you want to use external spool, please uninstall it."); + if (devPrinterUtil::IsVirtualSlot(m_mapping_item->m_ams_id)) { + if (is_ext_slot_compatible_with_current_filament(m_mapping_item->m_ams_id)) { + item_tooltip_msg = s_external_spool_with_switcher_tip(); + } else { + can_pick_the_item = false; + item_tooltip_msg = s_external_spool_wrong_nozzle_tip(); + } } } } @@ -595,10 +609,13 @@ void AmsMapingPopup::add_ams_mapping(std::vector tray_data, can_pick_the_item = (m_show_type == ShowType::LEFT); } else if (parent == m_right_marea_panel) { if (m_show_type == ShowType::LEFT_AND_RIGHT_DYNAMIC) { - can_pick_the_item = !devPrinterUtil::IsVirtualSlot(m_mapping_item->m_ams_id); - if (!can_pick_the_item) { - item_tooltip_msg = _L( - "External spools is not supported since Filament Track Switch has been installed. If you want to use external spool, please uninstall it."); + if (devPrinterUtil::IsVirtualSlot(m_mapping_item->m_ams_id)) { + if (is_ext_slot_compatible_with_current_filament(m_mapping_item->m_ams_id)) { + item_tooltip_msg = s_external_spool_with_switcher_tip(); + } else { + can_pick_the_item = false; + item_tooltip_msg = s_external_spool_wrong_nozzle_tip(); + } } } else if (m_show_type != ShowType::RIGHT) { can_pick_the_item = false; @@ -693,4 +710,4 @@ void AmsMapingPopup::add_ext_ams_mapping(TrayData tray_data, MappingItem* item) item->set_tray_index("Ext"); } -} // namespace Slic3r::GUI \ No newline at end of file +} // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/DeviceManager.cpp b/src/slic3r/GUI/DeviceManager.cpp index b4e4bed7db..9f89ea77b5 100644 --- a/src/slic3r/GUI/DeviceManager.cpp +++ b/src/slic3r/GUI/DeviceManager.cpp @@ -772,6 +772,9 @@ DevAmsTray *MachineObject::get_curr_tray() if (cur_ams_id.compare(std::to_string(VIRTUAL_TRAY_MAIN_ID)) == 0) { return &vt_slot[0]; } + if (cur_ams_id.compare(std::to_string(VIRTUAL_TRAY_DEPUTY_ID)) == 0 && vt_slot.size() > DEPUTY_EXTRUDER_ID) { + return &vt_slot[DEPUTY_EXTRUDER_ID]; + } DevAms* curr_ams = get_curr_Ams(); if (!curr_ams) return nullptr; @@ -1671,7 +1674,8 @@ int MachineObject::command_ams_filament_settings(int ams_id, int slot_id, std::s int tag_slot_id = slot_id; if (tag_ams_id == VIRTUAL_TRAY_MAIN_ID || tag_ams_id == VIRTUAL_TRAY_DEPUTY_ID) { - tag_tray_id = VIRTUAL_TRAY_DEPUTY_ID; + tag_slot_id = 0; + tag_tray_id = tag_ams_id; } else { tag_tray_id = tag_slot_id; } @@ -3440,7 +3444,14 @@ int MachineObject::parse_json(std::string tunnel, std::string payload, bool key_ if (jj.contains("vir_slot") && jj["vir_slot"].is_array()) { for (auto it = jj["vir_slot"].begin(); it != jj["vir_slot"].end(); it++) { - auto vslot = parse_vt_tray(it.value().get()); + auto parsed_vslot = parse_vt_tray(it.value().get()); + const DevAmsTray *current_vslot = nullptr; + if (parsed_vslot.id == std::to_string(VIRTUAL_TRAY_MAIN_ID) && vt_slot.size() > MAIN_EXTRUDER_ID) { + current_vslot = &vt_slot[MAIN_EXTRUDER_ID]; + } else if (parsed_vslot.id == std::to_string(VIRTUAL_TRAY_DEPUTY_ID) && vt_slot.size() > DEPUTY_EXTRUDER_ID) { + current_vslot = &vt_slot[DEPUTY_EXTRUDER_ID]; + } + auto vslot = parse_vt_tray(it.value().get(), current_vslot); if (vslot.id == std::to_string(VIRTUAL_TRAY_MAIN_ID)) { auto it = std::next(vt_slot.begin(), 0); @@ -3464,7 +3475,8 @@ int MachineObject::parse_json(std::string tunnel, std::string payload, bool key_ } else if (jj.contains("vt_tray")) { - auto main_slot = parse_vt_tray(jj["vt_tray"].get()); + const DevAmsTray *current_vslot = vt_slot.size() > MAIN_EXTRUDER_ID ? &vt_slot[MAIN_EXTRUDER_ID] : nullptr; + auto main_slot = parse_vt_tray(jj["vt_tray"].get(), current_vslot); main_slot.id = std::to_string(VIRTUAL_TRAY_MAIN_ID); @@ -3537,16 +3549,22 @@ int MachineObject::parse_json(std::string tunnel, std::string payload, bool key_ if (jj.contains("tray_id")) { tray_id = jj["tray_id"].get(); } - if (ams_id == 255 && tray_id == VIRTUAL_TRAY_MAIN_ID) { + if ((ams_id == VIRTUAL_TRAY_MAIN_ID || ams_id == VIRTUAL_TRAY_DEPUTY_ID) && tray_id == ams_id) { + int vt_slot_idx = ams_id == VIRTUAL_TRAY_MAIN_ID ? MAIN_EXTRUDER_ID : DEPUTY_EXTRUDER_ID; + while (vt_slot.size() <= vt_slot_idx) { + vt_slot.push_back(DevAmsTray(std::to_string(vt_slot.size() == MAIN_EXTRUDER_ID ? VIRTUAL_TRAY_MAIN_ID : VIRTUAL_TRAY_DEPUTY_ID))); + } + BOOST_LOG_TRIVIAL(info) << "ams_filament_setting, parse tray info"; - vt_slot[0].nozzle_temp_max = std::to_string(jj["nozzle_temp_max"].get()); - vt_slot[0].nozzle_temp_min = std::to_string(jj["nozzle_temp_min"].get()); - vt_slot[0].color = jj["tray_color"].get(); - vt_slot[0].setting_id = jj["tray_info_idx"].get(); + vt_slot[vt_slot_idx].id = std::to_string(ams_id); + vt_slot[vt_slot_idx].nozzle_temp_max = std::to_string(jj["nozzle_temp_max"].get()); + vt_slot[vt_slot_idx].nozzle_temp_min = std::to_string(jj["nozzle_temp_min"].get()); + vt_slot[vt_slot_idx].color = jj["tray_color"].get(); + vt_slot[vt_slot_idx].setting_id = jj["tray_info_idx"].get(); //vt_tray.type = jj["tray_type"].get(); - vt_slot[0].m_fila_type = setting_id_to_type(vt_slot[0].setting_id, jj["tray_type"].get()); + vt_slot[vt_slot_idx].m_fila_type = setting_id_to_type(vt_slot[vt_slot_idx].setting_id, jj["tray_type"].get()); // delay update - vt_slot[0].set_hold_count(); + vt_slot[vt_slot_idx].set_hold_count(); } else { auto ams = m_fila_system->GetAmsById(std::to_string(ams_id)); if (ams) { @@ -4068,7 +4086,7 @@ bool MachineObject::is_firmware_info_valid() } -DevAmsTray MachineObject::parse_vt_tray(json vtray) +DevAmsTray MachineObject::parse_vt_tray(json vtray, const DevAmsTray *current_tray) { auto vt_tray = DevAmsTray(std::to_string(VIRTUAL_TRAY_MAIN_ID)); vt_tray.ams_type = DevAmsType::EXT_SPOOL; @@ -4101,7 +4119,8 @@ DevAmsTray MachineObject::parse_vt_tray(json vtray) } ams_support_virtual_tray = true; - if (vt_tray.hold_count > 0) { + if (current_tray && current_tray->id == vt_tray.id && current_tray->hold_count > 0) { + vt_tray = *current_tray; vt_tray.hold_count--; } else { diff --git a/src/slic3r/GUI/DeviceManager.hpp b/src/slic3r/GUI/DeviceManager.hpp index 84094b8fe6..a4f75703c7 100644 --- a/src/slic3r/GUI/DeviceManager.hpp +++ b/src/slic3r/GUI/DeviceManager.hpp @@ -784,7 +784,7 @@ class MachineObject /*vi slot data*/ std::vector vt_slot; - DevAmsTray parse_vt_tray(json vtray); + DevAmsTray parse_vt_tray(json vtray, const DevAmsTray *current_tray = nullptr); /*get ams slot info*/ bool contains_tray(const std::string &ams_id, const std::string &tray_id) const; diff --git a/src/slic3r/GUI/StatusPanel.cpp b/src/slic3r/GUI/StatusPanel.cpp index 672f1046cc..b113b87c3c 100644 --- a/src/slic3r/GUI/StatusPanel.cpp +++ b/src/slic3r/GUI/StatusPanel.cpp @@ -4017,14 +4017,7 @@ void sGetSwitchInfo(MachineObject* obj, return; } - if (obj->GetFilaSwitch()->IsInstalled()) { - if (devPrinterUtil::IsVirtualSlot(ams_id)) { - const auto& err_info = _L("\"Load\" or \"Unload\" is not supported for external spool while using Filament Track Switch."); - load_error_info = err_info; - unload_error_info = err_info; - return; - } - + if (obj->GetFilaSwitch()->IsInstalled() && !devPrinterUtil::IsVirtualSlot(ams_id)) { if (!obj->GetFilaSwitch()->IsReady()) { const auto& err_info = _L("The Filament Track Switch has not been setup. Please setup on printer."); load_error_info = err_info;