diff --git a/resources/profiles/Snapmaker.json b/resources/profiles/Snapmaker.json index ab2433242e..9a6fab7942 100644 --- a/resources/profiles/Snapmaker.json +++ b/resources/profiles/Snapmaker.json @@ -1,6 +1,6 @@ { "name": "Snapmaker", - "version": "02.04.00.08", + "version": "02.04.00.09", "force_update": "0", "description": "Snapmaker configurations", "machine_model_list": [ diff --git a/resources/profiles/Snapmaker/machine/Snapmaker U1 (0.2 nozzle).json b/resources/profiles/Snapmaker/machine/Snapmaker U1 (0.2 nozzle).json index aebc032855..183e125c73 100644 --- a/resources/profiles/Snapmaker/machine/Snapmaker U1 (0.2 nozzle).json +++ b/resources/profiles/Snapmaker/machine/Snapmaker U1 (0.2 nozzle).json @@ -186,7 +186,6 @@ "before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\nTIMELAPSE_TAKE_FRAME\nDEFECT_DETECTION_DETECT", "machine_pause_gcode": "M600", "nozzle_volume": "143", - "support_multi_bed_types": "0", "layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]\nSET_PRINT_STATS_INFO TOTAL_LAYER={total_layer_count} CURRENT_LAYER={layer_num+1}", "default_print_profile": "0.10 Standard @Snapmaker U1 (0.2 nozzle)" } diff --git a/resources/profiles/Snapmaker/machine/Snapmaker U1 (0.4 nozzle).json b/resources/profiles/Snapmaker/machine/Snapmaker U1 (0.4 nozzle).json index 28ccfd0a29..6d2ec2cfe6 100644 --- a/resources/profiles/Snapmaker/machine/Snapmaker U1 (0.4 nozzle).json +++ b/resources/profiles/Snapmaker/machine/Snapmaker U1 (0.4 nozzle).json @@ -186,7 +186,6 @@ "before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\nTIMELAPSE_TAKE_FRAME\nDEFECT_DETECTION_DETECT", "default_print_profile": "0.20 Standard @Snapmaker U1 (0.4 nozzle)", "machine_pause_gcode": "M600", - "default_bed_type": "Textured PEI Plate", "layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]\nSET_PRINT_STATS_INFO TOTAL_LAYER={total_layer_count} CURRENT_LAYER={layer_num+1}", "nozzle_volume": "143", "resonance_avoidance": "1", diff --git a/resources/profiles/Snapmaker/machine/Snapmaker U1 (0.6 nozzle).json b/resources/profiles/Snapmaker/machine/Snapmaker U1 (0.6 nozzle).json index f4dff2f357..a6cb0d0bd3 100644 --- a/resources/profiles/Snapmaker/machine/Snapmaker U1 (0.6 nozzle).json +++ b/resources/profiles/Snapmaker/machine/Snapmaker U1 (0.6 nozzle).json @@ -187,6 +187,5 @@ "machine_pause_gcode": "M600", "layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]\nSET_PRINT_STATS_INFO TOTAL_LAYER={total_layer_count} CURRENT_LAYER={layer_num+1}", "nozzle_volume": "143", - "support_multi_bed_types": "0", "default_print_profile": "0.30 Standard @Snapmaker U1 (0.6 nozzle)" } diff --git a/resources/profiles/Snapmaker/machine/Snapmaker U1 (0.8 nozzle).json b/resources/profiles/Snapmaker/machine/Snapmaker U1 (0.8 nozzle).json index e356f4264b..ef4da1a516 100644 --- a/resources/profiles/Snapmaker/machine/Snapmaker U1 (0.8 nozzle).json +++ b/resources/profiles/Snapmaker/machine/Snapmaker U1 (0.8 nozzle).json @@ -187,6 +187,5 @@ "machine_pause_gcode": "M600", "layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]\nSET_PRINT_STATS_INFO TOTAL_LAYER={total_layer_count} CURRENT_LAYER={layer_num+1}", "nozzle_volume": "143", - "support_multi_bed_types": "0", "default_print_profile": "0.40 Standard @Snapmaker U1 (0.8 nozzle)" } diff --git a/resources/profiles/Snapmaker/machine/fdm_U1.json b/resources/profiles/Snapmaker/machine/fdm_U1.json index 7ee65878e6..717215b507 100644 --- a/resources/profiles/Snapmaker/machine/fdm_U1.json +++ b/resources/profiles/Snapmaker/machine/fdm_U1.json @@ -183,7 +183,8 @@ "scan_first_layer": "0", "nozzle_type": "undefine", "auxiliary_fan": "0", - "default_bed_type": "Textured PEI Plate", + "support_multi_bed_types": "1", + "default_bed_type": "4", "printable_area": [ "0.5x1", "270.5x1", diff --git a/src/libslic3r/Config.hpp b/src/libslic3r/Config.hpp index 509095cbfc..ef93f0d509 100644 --- a/src/libslic3r/Config.hpp +++ b/src/libslic3r/Config.hpp @@ -2982,6 +2982,8 @@ public: const double & opt_float(const t_config_option_key &opt_key, unsigned int idx) const; double & opt_float_nullable(const t_config_option_key &opt_key, unsigned int idx) { return this->option(opt_key)->get_at(idx); } const double & opt_float_nullable(const t_config_option_key &opt_key, unsigned int idx) const { return dynamic_cast(this->option(opt_key))->get_at(idx); } + FloatOrPercent & opt_float_or_percent_nullable(const t_config_option_key &opt_key, unsigned int idx) { return this->option(opt_key)->get_at(idx); } + const FloatOrPercent & opt_float_or_percent_nullable(const t_config_option_key &opt_key, unsigned int idx) const { return dynamic_cast(this->option(opt_key))->get_at(idx); } int& opt_int(const t_config_option_key &opt_key) { return this->option(opt_key)->value; } int opt_int(const t_config_option_key &opt_key) const { return dynamic_cast(this->option(opt_key))->value; } diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 8e2e9f713c..18d805936e 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -6726,6 +6726,7 @@ void GCode::append_full_config(const Print &print, std::string &str) "farthest_point_timelapse"sv, "compatible_printers"sv, "compatible_prints"sv, + "filament_colour_type"sv, "print_host"sv, "print_host_webui"sv, "printhost_apikey"sv, diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index 1177a5227d..c689c7ce78 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -3243,9 +3243,9 @@ double Model::findMaxSpeed(const ModelObject* object) { if (objectKey == "outer_wall_speed") externalPerimeterSpeedObj = object->config.get().opt_float_nullable(objectKey, 0); if (objectKey == "small_perimeter_speed") - smallPerimeterSpeedObj = object->config.get().opt_float_nullable(objectKey, 0); + smallPerimeterSpeedObj = object->config.get().opt_float_or_percent_nullable(objectKey, 0).get_abs_value(externalPerimeterSpeedObj); if (objectKey == "small_support_perimeter_speed") - smallSupportPerimeterSpeedObj = object->config.get().opt_float_nullable(objectKey, 0); + smallSupportPerimeterSpeedObj = object->config.get().opt_float_or_percent_nullable(objectKey, 0).get_abs_value(supportSpeedObj); } objMaxSpeed = std::max(perimeterSpeedObj, std::max(externalPerimeterSpeedObj, std::max(infillSpeedObj, std::max(solidInfillSpeedObj, std::max(topSolidInfillSpeedObj, std::max(supportSpeedObj, std::max(smallPerimeterSpeedObj, std::max(smallSupportPerimeterSpeedObj, objMaxSpeed)))))))); if (objMaxSpeed <= 0) objMaxSpeed = 250.; diff --git a/src/libslic3r/PresetBundle.cpp b/src/libslic3r/PresetBundle.cpp index 9e0fc61323..febfa5d4dc 100644 --- a/src/libslic3r/PresetBundle.cpp +++ b/src/libslic3r/PresetBundle.cpp @@ -5660,7 +5660,7 @@ void PresetBundle::update_multi_material_filament_presets(size_t to_delete_filam f_multiplier.resize(nozzle_nums, 1.f); } - if ( (num_filaments * num_filaments) != size_t(old_matrix.size() / old_nozzle_nums) ) { + if (old_matrix.size() != num_filaments * num_filaments * nozzle_nums) { // First verify if purging volumes presets for each extruder matches number of extruders std::vector& filaments = this->project_config.option("flush_volumes_vector")->values; while (filaments.size() < 2* num_filaments) { diff --git a/src/libslic3r/PrintApply.cpp b/src/libslic3r/PrintApply.cpp index e2e9bc737d..6d5dbb05f5 100644 --- a/src/libslic3r/PrintApply.cpp +++ b/src/libslic3r/PrintApply.cpp @@ -559,9 +559,11 @@ static inline bool model_volume_solid_or_modifier(const ModelVolume &mv) static inline Transform3f trafo_for_bbox(const Transform3d &object_trafo, const Transform3d &volume_trafo) { - Transform3d m = object_trafo * volume_trafo; - m.translation().x() = 0.; - m.translation().y() = 0.; + // Orca: Keep the volume's local XY offset for multipart overlap checks, but remove the object's bed placement. + Transform3d object_trafo_local = object_trafo; + object_trafo_local.translation().x() = 0.; + object_trafo_local.translation().y() = 0.; + Transform3d m = object_trafo_local * volume_trafo; return m.cast(); } diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index fdb20253d6..f9d895332a 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -10426,6 +10426,16 @@ int DynamicPrintConfig::update_values_from_multi_to_multi_2(const std::vector &variant_index, int stride) +{ + // A single-value object or region override applies to every nozzle variant. + std::vector indices = variant_index; + if (source.size() == 1 && !source.is_nil(0)) + std::fill(indices.begin(), indices.end(), 0); + target.set_to_index(&source, indices, stride); +} + //used for object/region config //use the smallest of multiple to single @@ -11503,7 +11513,7 @@ void update_static_print_config_from_dynamic(ConfigBase& config, const DynamicPr else { ConfigOptionVectorBase* opt_vec_src = static_cast(opt_src); const ConfigOptionVectorBase* opt_vec_dest = static_cast(opt_dest); - opt_vec_src->set_to_index(opt_vec_dest, variant_index, stride); + set_variant_override(*opt_vec_src, *opt_vec_dest, variant_index, stride); } } } diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 6029d5bd88..f51c1c6411 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -842,6 +842,9 @@ extern std::set printer_options_with_variant_1; extern std::set printer_options_with_variant_2; extern std::set empty_options; +void set_variant_override(ConfigOptionVectorBase &target, const ConfigOptionVectorBase &source, + const std::vector &variant_index, int stride = 1); + extern std::set filament_dev_options; extern void update_static_print_config_from_dynamic(ConfigBase& config, const DynamicPrintConfig& dest_config, std::vector variant_index, std::set& key_set1, int stride = 1); @@ -2394,6 +2397,55 @@ static void set_flush_volumes_matrix(std::vector &out_matrix, const std::vect } } +template +static bool has_zero_flush_volume_for_used_filaments(const std::vector &fv_matrix, + const std::vector &flush_multipliers, + const std::vector &used_filaments) +{ + if (used_filaments.size() < 2 || flush_multipliers.empty()) + return false; + + if (fv_matrix.size() % flush_multipliers.size() != 0) + return false; + + const size_t matrix_len = fv_matrix.size() / flush_multipliers.size(); + const size_t row_len = size_t(std::sqrt(double(matrix_len))); + if (row_len < 2 || row_len * row_len != matrix_len) + return false; + + std::vector filtered_filaments; + filtered_filaments.reserve(used_filaments.size()); + for (int filament_id : used_filaments) { + if (filament_id <= 0 || filament_id > int(row_len)) + continue; + if (std::find(filtered_filaments.begin(), filtered_filaments.end(), filament_id) == filtered_filaments.end()) + filtered_filaments.push_back(filament_id); + } + if (filtered_filaments.size() < 2) + return false; + + for (T multiplier : flush_multipliers) { + if (multiplier == 0) + return true; + } + + for (size_t nozzle_idx = 0; nozzle_idx < flush_multipliers.size(); nozzle_idx++) { + const size_t block_offset = nozzle_idx * matrix_len; + for (int from_id : filtered_filaments) { + for (int to_id : filtered_filaments) { + if (from_id == to_id) + continue; + + const size_t matrix_idx = block_offset + size_t(from_id - 1) * row_len + size_t(to_id - 1); + if (matrix_idx < fv_matrix.size() && fv_matrix[matrix_idx] == 0) + return true; + } + } + } + + return false; +} + size_t get_extruder_index(const GCodeConfig& config, unsigned int filament_id); } // namespace Slic3r diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index b2a92f11a6..8368de1a4f 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -3812,7 +3812,7 @@ static void apply_to_print_region_config(PrintRegionConfig &out, const DynamicPr else { ConfigOptionVectorBase* opt_vec_src = static_cast(my_opt); const ConfigOptionVectorBase* opt_vec_dest = static_cast(it->second.get()); - opt_vec_src->set_to_index(opt_vec_dest, variant_index, 1); + set_variant_override(*opt_vec_src, *opt_vec_dest, variant_index); } } } diff --git a/src/slic3r/GUI/ConnectPrinter.cpp b/src/slic3r/GUI/ConnectPrinter.cpp index b4cd7f4f2f..3e78e7fe5c 100644 --- a/src/slic3r/GUI/ConnectPrinter.cpp +++ b/src/slic3r/GUI/ConnectPrinter.cpp @@ -156,6 +156,8 @@ void ConnectPrinterDialog::on_input_enter(wxCommandEvent& evt) void ConnectPrinterDialog::on_button_confirm(wxCommandEvent &event) { wxString code = m_textCtrl_code->GetTextCtrl()->GetValue(); + if (code.empty()) + code = "88888888"; for (char c : code) { if (!(('0' <= c && c <= '9') || ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z'))) { show_error(this, _L("Invalid input")); @@ -163,7 +165,7 @@ void ConnectPrinterDialog::on_button_confirm(wxCommandEvent &event) } } if (m_obj) { - m_obj->set_user_access_code(code.ToStdString()); + m_obj->set_access_code(code.ToStdString()); } EndModal(wxID_OK); } diff --git a/src/slic3r/GUI/DeviceCore/DevManager.cpp b/src/slic3r/GUI/DeviceCore/DevManager.cpp index d13f8b7215..edc958ec53 100644 --- a/src/slic3r/GUI/DeviceCore/DevManager.cpp +++ b/src/slic3r/GUI/DeviceCore/DevManager.cpp @@ -15,6 +15,18 @@ using namespace nlohmann; +namespace { + // Orca: access_code and user_access_code used to be separate AppConfig keys before the two + // fields were merged; fall back to the legacy key so existing users' saved codes aren't lost. + std::string get_access_code_with_legacy_fallback(Slic3r::AppConfig* config, const std::string& dev_id) + { + std::string code = config->get("access_code", dev_id); + if (code.empty()) + code = config->get("user_access_code", dev_id); + return code; + } +} + namespace Slic3r { DeviceManager::DeviceManager(NetworkAgent* agent) @@ -48,8 +60,7 @@ namespace Slic3r obj->bind_sec_link = "secure"; obj->m_is_online = true; obj->last_alive = Slic3r::Utils::get_current_time_utc(); - obj->set_access_code(config->get("access_code", m.dev_id), false); - obj->set_user_access_code(config->get("user_access_code", m.dev_id), false); + obj->set_access_code(get_access_code_with_legacy_fallback(config, m.dev_id), false); if (obj->has_access_right()) { localMachineList.insert(std::make_pair(m.dev_id, obj)); } else { @@ -339,8 +350,7 @@ namespace Slic3r //load access code AppConfig* config = Slic3r::GUI::wxGetApp().app_config; if (config) { - obj->set_access_code(Slic3r::GUI::wxGetApp().app_config->get("access_code", dev_id), false); - obj->set_user_access_code(Slic3r::GUI::wxGetApp().app_config->get("user_access_code", dev_id), false); + obj->set_access_code(get_access_code_with_legacy_fallback(config, dev_id), false); } localMachineList.insert(std::make_pair(dev_id, obj)); @@ -382,7 +392,6 @@ namespace Slic3r obj->m_is_online = true; obj->last_alive = Slic3r::Utils::get_current_time_utc(); obj->set_access_code(access_code, false); - obj->set_user_access_code(access_code, false); update_local_machine(*obj); diff --git a/src/slic3r/GUI/DeviceManager.cpp b/src/slic3r/GUI/DeviceManager.cpp index ef85870461..f4befe78c1 100644 --- a/src/slic3r/GUI/DeviceManager.cpp +++ b/src/slic3r/GUI/DeviceManager.cpp @@ -449,9 +449,7 @@ bool MachineObject::HasRecentLanMessage() std::string MachineObject::get_access_code() const { - if (get_user_access_code().empty()) - return access_code; - return get_user_access_code(); + return access_code; } void MachineObject::set_access_code(std::string code, bool only_refresh) @@ -470,37 +468,6 @@ void MachineObject::set_access_code(std::string code, bool only_refresh) } } -void MachineObject::erase_user_access_code() -{ - this->user_access_code = ""; - AppConfig* config = GUI::wxGetApp().app_config; - if (config) { - GUI::wxGetApp().app_config->erase("user_access_code", get_dev_id()); - //GUI::wxGetApp().app_config->save(); - } -} - -void MachineObject::set_user_access_code(std::string code, bool only_refresh) -{ - this->user_access_code = code; - if (only_refresh && !code.empty()) { - AppConfig* config = GUI::wxGetApp().app_config; - if (config && !code.empty()) { - GUI::wxGetApp().app_config->set_str("user_access_code", get_dev_id(), code); - DeviceManager::update_local_machine(*this); - } - } -} - -std::string MachineObject::get_user_access_code() const -{ - AppConfig* config = GUI::wxGetApp().app_config; - if (config) { - return GUI::wxGetApp().app_config->get("user_access_code", get_dev_id()); - } - return ""; -} - std::string MachineObject::get_show_printer_type() const { std::string printer_type = this->printer_type; @@ -2907,7 +2874,6 @@ int MachineObject::parse_json(std::string tunnel, std::string payload, bool key_ std::string access_code = j_pre["system"]["access_code"].get(); if (!access_code.empty()) { set_access_code(access_code); - set_user_access_code(access_code); } } } diff --git a/src/slic3r/GUI/DeviceManager.hpp b/src/slic3r/GUI/DeviceManager.hpp index 2790e37cfa..33635fbe6e 100644 --- a/src/slic3r/GUI/DeviceManager.hpp +++ b/src/slic3r/GUI/DeviceManager.hpp @@ -113,7 +113,6 @@ private: std::string dev_name; std::string dev_ip; std::string access_code; - std::string user_access_code; // type, time stamp, delay std::vector> message_delay; @@ -228,11 +227,6 @@ public: std::string get_access_code() const; void set_access_code(std::string code, bool only_refresh = true); - /*user access code*/ - void set_user_access_code(std::string code, bool only_refresh = true); - void erase_user_access_code(); - std::string get_user_access_code() const; - //PRINTER_TYPE printer_type = PRINTER_3DPrinter_UKNOWN; std::string printer_type; /* model_id */ std::string get_show_printer_type() const; diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 303f9a2b76..a51a10296c 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -10602,9 +10602,8 @@ void GLCanvas3D::_set_warning_notification(EWarning warning, bool state) wxString region = L"en"; if (language.find("zh") == 0) region = L"zh"; - // Use the generic dual-nozzle PLA+PETG guide rather than the H2D-specific page - // so the link is relevant for all dual-extrusion printers, not just Bambu H2D. (#12073) - wxGetApp().open_browser_with_warning_dialog(wxString::Format(L"https://wiki.bambulab.com/%s/filament-acc/filament/pla-and-petg-dual-extrusion", region)); + // Although this link looks like it's only for the H2D, its guidance is generic. + wxGetApp().open_browser_with_warning_dialog(wxString::Format(L"https://wiki.bambulab.com/%s/filament-acc/filament/h2d-pla-and-petg-mutual-support", region)); return false; }); } @@ -10738,24 +10737,14 @@ bool GLCanvas3D::is_flushing_matrix_error() { if (!Sidebar::should_show_SEMM_buttons()) return false; + std::vector plate_extruders = wxGetApp().plater()->get_partplate_list().get_curr_plate()->get_extruders(true); + if (plate_extruders.size() < 2) + return false; + const auto &project_config = wxGetApp().preset_bundle->project_config; const std::vector &config_matrix = (project_config.option("flush_volumes_matrix"))->values; const std::vector &config_multiplier = (project_config.option("flush_multiplier"))->values; - - for (auto multiplier : config_multiplier) { - if (multiplier == 0) return true; - } - - int matrix_len = config_matrix.size() / config_multiplier.size(); - int row_len = std::sqrt(matrix_len); - for (int i = 0; i < config_matrix.size(); i++) - { - int relative_id = i % matrix_len; - int row_id = relative_id / row_len; - int col_id = relative_id % row_len; - if (row_id != col_id && config_matrix[i] == 0) return true; - } - return false; + return has_zero_flush_volume_for_used_filaments(config_matrix, config_multiplier, plate_extruders); } bool GLCanvas3D::_is_any_volume_outside() const diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 14edeb8038..db51bd9d8e 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -2166,7 +2166,6 @@ void GUI_App::init_networking_callbacks() obj->is_tunnel_mqtt = tunnel; obj->command_request_push_all(true); obj->command_get_version(); - obj->erase_user_access_code(); obj->command_get_access_code(); if (m_agent) m_agent->install_device_cert(obj->get_dev_id(), obj->is_lan_mode_printer()); @@ -2216,7 +2215,6 @@ void GUI_App::init_networking_callbacks() wxString text; if (msg == "5") { obj->set_access_code(""); - obj->erase_user_access_code(); text = wxString::Format(_L("Incorrect password")); wxGetApp().show_dialog(text); } else { @@ -8286,7 +8284,7 @@ bool GUI_App::show_modal_ip_address_enter_dialog(bool input_sn, wxString title) wxGetApp().app_config->save(); obj->set_dev_ip(ip_address.ToStdString()); - obj->set_user_access_code(access_code.ToStdString()); + obj->set_access_code(access_code.ToStdString()); } } }); diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 6aa7932c84..5594241988 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -1374,8 +1374,8 @@ void MainFrame::show_device(bool should_use_native) { const bool use_printer_agents = wxGetApp().app_config->get_bool("use_printer_agents"); - // The legacy page is appended when printer agents are enabled. Remove that - // extra page before switching back to the normal native/legacy layout. + // The web page is appended when printer agents are enabled. Remove that + // extra page before switching back to the normal native/Web layout. if (!use_printer_agents) { if ((idx = m_tabpanel->FindPage(m_printer_view)) != wxNOT_FOUND && idx != tpMonitor) { m_printer_view->Show(false); @@ -1435,10 +1435,10 @@ void MainFrame::show_device(bool should_use_native) { if ((idx = m_tabpanel->FindPage(m_printer_view)) == wxNOT_FOUND) { m_printer_view->Show(false); - m_tabpanel->AddPage(m_printer_view, _L("Device (legacy)"), std::string("tab_monitor_active"), + m_tabpanel->AddPage(m_printer_view, _L("Device (Web)"), std::string("tab_monitor_active"), std::string("tab_monitor_active"), false); } else { - m_tabpanel->SetPageText(idx, _L("Device (legacy)")); + m_tabpanel->SetPageText(idx, _L("Device (Web)")); } #ifdef _MSW_DARK_MODE @@ -4353,14 +4353,26 @@ void MainFrame::load_printer_url(wxString url, wxString apikey) void MainFrame::load_printer_url() { PresetBundle &preset_bundle = *wxGetApp().preset_bundle; - if (preset_bundle.use_bbl_device_tab() || wxGetApp().app_config->get_bool("use_printer_agents")) + if (preset_bundle.use_bbl_device_tab() && !wxGetApp().app_config->get_bool("use_printer_agents")) return; auto cfg = preset_bundle.printers.get_edited_preset().config; + if (cfg.opt_string("print_host").empty()) { + if (auto *device_manager = wxGetApp().getDeviceManager()) { + auto *machine = device_manager->get_selected_machine(); + if (!machine) { + auto machines = device_manager->get_my_machine_list(); + if (machines.size() == 1) + machine = machines.begin()->second; + } + if (machine && !machine->get_dev_ip().empty()) + cfg.opt_string("print_host") = machine->get_dev_ip(); + } + } wxString url = from_u8(PrintHost::get_print_host_webui(&cfg)); wxString apikey; const auto host_type = cfg.option>("host_type")->value; - if (cfg.has("printhost_apikey") && (host_type == htPrusaLink || host_type == htPrusaConnect)) + if (cfg.has("printhost_apikey") && host_type != htSimplyPrint) apikey = cfg.opt_string("printhost_apikey"); if (!url.empty()) { load_printer_url(url, apikey); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 847d98f398..fd307d32d2 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3279,7 +3279,9 @@ void Sidebar::update_all_preset_comboboxes() : MainFrame::PrintSelectType::eSendGcode; } - if (!use_native_device_tab || use_printer_agents) + if (use_printer_agents) + p_mainframe->load_printer_url(); + else if (!use_native_device_tab) p_mainframe->load_printer_url(url, apikey); @@ -11295,9 +11297,14 @@ void Plater::priv::on_tab_selection_changing(wxBookCtrlEvent& e) } } } else { - if (new_sel == MainFrame::tpMonitor && wxGetApp().preset_bundle != nullptr) { + const bool selecting_web_device_tab = main_frame->m_printer_view && + main_frame->m_tabpanel->GetPage(new_sel) == main_frame->m_printer_view; + if (selecting_web_device_tab) { + // Use the selected discovered machine when the preset has no host. + main_frame->load_printer_url(); + } else if (new_sel == MainFrame::tpMonitor && wxGetApp().preset_bundle != nullptr) { auto cfg = wxGetApp().preset_bundle->printers.get_edited_preset().config; - wxString url = cfg.opt_string("print_host_webui").empty() ? cfg.opt_string("print_host") : cfg.opt_string("print_host_webui"); + wxString url = from_u8(PrintHost::get_print_host_webui(&cfg)); if (main_frame->m_printer_view && url.empty()) { // It's missing_connection page, reload so that we can replay the gif image main_frame->m_printer_view->reload(); diff --git a/src/slic3r/GUI/ReleaseNote.cpp b/src/slic3r/GUI/ReleaseNote.cpp index 22f65f4a60..7b2d091176 100644 --- a/src/slic3r/GUI/ReleaseNote.cpp +++ b/src/slic3r/GUI/ReleaseNote.cpp @@ -1991,7 +1991,7 @@ void InputIpAddressDialog::workerThreadFunc(std::string str_ip, std::string str_ if (w.expired()) return; if (m_obj) { - m_obj->set_user_access_code(str_access_code); + m_obj->set_access_code(str_access_code); wxGetApp().getDeviceManager()->set_selected_machine(m_obj->get_dev_id()); } @@ -2055,6 +2055,11 @@ void InputIpAddressDialog::on_text(wxCommandEvent &evt) { auto str_ip = m_input_ip->GetTextCtrl()->GetValue(); auto str_access_code = m_input_access_code->GetTextCtrl()->GetValue(); + + if (str_access_code.empty()) { + str_access_code = "88888888"; + } + auto str_name = m_input_printer_name->GetTextCtrl()->GetValue().Strip(wxString::both); auto str_sn = m_input_sn->GetTextCtrl()->GetValue().Strip(wxString::both); bool invalid_access_code = true; @@ -2062,7 +2067,7 @@ void InputIpAddressDialog::on_text(wxCommandEvent &evt) for (char c : str_access_code) { if (!(('0' <= c && c <= '9') || ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z'))) { invalid_access_code = false; - return; + break; } } diff --git a/src/slic3r/GUI/SelectMachinePop.cpp b/src/slic3r/GUI/SelectMachinePop.cpp index 492199569e..96324fb4d8 100644 --- a/src/slic3r/GUI/SelectMachinePop.cpp +++ b/src/slic3r/GUI/SelectMachinePop.cpp @@ -704,7 +704,6 @@ void SelectMachinePopup::update_user_devices() } mobj->set_access_code(""); - mobj->erase_user_access_code(); } if (GUI::wxGetApp().plater()) diff --git a/src/slic3r/Utils/MoonrakerPrinterAgent.cpp b/src/slic3r/Utils/MoonrakerPrinterAgent.cpp index d21dce5070..cd3ef82b62 100644 --- a/src/slic3r/Utils/MoonrakerPrinterAgent.cpp +++ b/src/slic3r/Utils/MoonrakerPrinterAgent.cpp @@ -1359,7 +1359,6 @@ void MoonrakerPrinterAgent::announce_printhost_device() if (auto* app_config = GUI::wxGetApp().app_config) { const std::string access_code = device_info.api_key.empty() ? "88888888" : device_info.api_key; app_config->set_str("access_code", device_info.dev_id, access_code); - app_config->set_str("user_access_code", device_info.dev_id, access_code); } nlohmann::json payload; diff --git a/tests/libslic3r/test_config.cpp b/tests/libslic3r/test_config.cpp index 5bc825c3b2..12b161322d 100644 --- a/tests/libslic3r/test_config.cpp +++ b/tests/libslic3r/test_config.cpp @@ -235,6 +235,56 @@ SCENARIO("Config ini load/save interface", "[Config]") { } } +TEST_CASE("Flush-volume warning predicate respects used filament transitions", "[Config][Regression]") +{ + const std::vector multipliers = {1.0}; + + SECTION("Single used filament does not trigger warning with zero transition entries") + { + const std::vector matrix = { + 0.0, 0.0, + 0.0, 0.0 + }; + const std::vector used_filaments = {1}; + + REQUIRE_FALSE(has_zero_flush_volume_for_used_filaments(matrix, multipliers, used_filaments)); + } + + SECTION("Two used filaments trigger warning when transition flush entry is zero") + { + const std::vector matrix = { + 0.0, 0.0, + 0.0, 0.0 + }; + const std::vector used_filaments = {1, 2}; + + REQUIRE(has_zero_flush_volume_for_used_filaments(matrix, multipliers, used_filaments)); + } + + SECTION("Two used filaments do not trigger warning when transitions are non-zero") + { + const std::vector matrix = { + 0.0, 280.0, + 280.0, 0.0 + }; + const std::vector used_filaments = {1, 2}; + + REQUIRE_FALSE(has_zero_flush_volume_for_used_filaments(matrix, multipliers, used_filaments)); + } + + SECTION("Zero multiplier still triggers warning when multiple filaments are used") + { + const std::vector matrix = { + 0.0, 280.0, + 280.0, 0.0 + }; + const std::vector zero_multiplier = {0.0}; + const std::vector used_filaments = {1, 2}; + + REQUIRE(has_zero_flush_volume_for_used_filaments(matrix, zero_multiplier, used_filaments)); + } +} + // TODO: https://github.com/SoftFever/OrcaSlicer/issues/11269 - Is this test still relevant? Delete if not. // It was failing so at least "nozzle_type" and "extruder_printable_area" could not be serialized // and an exception was thrown, but "nozzle_type" has been around for at least 3 months now.