From 6639a32b0c3fa667dfc2a7605dfe512525dadc86 Mon Sep 17 00:00:00 2001 From: HanifKoh <76276251+HanifKoh@users.noreply.github.com> Date: Wed, 7 Oct 2026 14:58:49 +0800 Subject: [PATCH 1/5] Remove using namespace std from json_diff.hpp (#16222) The directive sat at global scope in a header that DeviceManager.hpp includes, so most of the GUI compiled with all of std in the global namespace. 42 files had come to rely on it, mostly for string, vector and unordered_map, four of them for the ""sv and ""ms literals. Those sites are qualified. GCodeViewer.cpp spelled the type as std::vector<::string>, which only resolved through the directive. The files that use the ""sv and ""ms literals get a file-scope "using namespace std::string_view_literals;" or "using namespace std::chrono_literals;", as other sources already do. --- src/slic3r/GUI/AMSMaterialsSetting.cpp | 4 ++-- src/slic3r/GUI/Auxiliary.cpp | 6 +++--- src/slic3r/GUI/CalibrationWizardPresetPage.cpp | 6 +++--- src/slic3r/GUI/CreatePresetsDialog.cpp | 8 ++++---- src/slic3r/GUI/DeviceCore/DevFilaSystem.cpp | 2 +- src/slic3r/GUI/DeviceCore/DevMappingNozzle.cpp | 2 +- src/slic3r/GUI/DeviceCore/DevNozzleSystem.cpp | 4 ++-- src/slic3r/GUI/DeviceErrorDialog.cpp | 2 +- src/slic3r/GUI/DeviceManager.cpp | 3 ++- src/slic3r/GUI/EditGCodeDialog.cpp | 6 +++--- src/slic3r/GUI/Field.cpp | 8 ++++---- src/slic3r/GUI/GCodeViewer.cpp | 4 +++- src/slic3r/GUI/GLCanvas3D.cpp | 2 ++ src/slic3r/GUI/GUI_App.cpp | 6 +++--- src/slic3r/GUI/GUI_ObjectList.cpp | 4 ++-- src/slic3r/GUI/Gizmos/GizmoObjectManipulation.cpp | 2 ++ src/slic3r/GUI/HMS.cpp | 14 +++++++------- src/slic3r/GUI/Jobs/PrintJob.cpp | 2 +- src/slic3r/GUI/NotificationManager.cpp | 10 +++++----- src/slic3r/GUI/PartSkipDialog.cpp | 8 ++++---- src/slic3r/GUI/PartSkipDialog.hpp | 6 +++--- src/slic3r/GUI/Plater.cpp | 8 ++++---- src/slic3r/GUI/Preferences.cpp | 4 ++-- src/slic3r/GUI/Project.cpp | 2 +- src/slic3r/GUI/SelectMachine.cpp | 8 ++++---- src/slic3r/GUI/SelectMachine.hpp | 2 +- src/slic3r/GUI/SendToPrinter.cpp | 2 +- src/slic3r/GUI/StatusPanel.hpp | 4 ++-- src/slic3r/GUI/SyncAmsInfoDialog.cpp | 4 ++-- src/slic3r/GUI/Tab.cpp | 2 +- src/slic3r/GUI/WebGuideDialog.cpp | 10 +++++----- src/slic3r/GUI/Widgets/AMSControl.cpp | 2 +- src/slic3r/GUI/Widgets/AMSControl.hpp | 4 ++-- src/slic3r/GUI/Widgets/AMSItem.cpp | 6 +++--- src/slic3r/GUI/Widgets/AMSItem.hpp | 12 ++++++------ src/slic3r/Utils/json_diff.hpp | 3 --- 36 files changed, 93 insertions(+), 89 deletions(-) diff --git a/src/slic3r/GUI/AMSMaterialsSetting.cpp b/src/slic3r/GUI/AMSMaterialsSetting.cpp index 66e87ac3af..83dd6a2d07 100644 --- a/src/slic3r/GUI/AMSMaterialsSetting.cpp +++ b/src/slic3r/GUI/AMSMaterialsSetting.cpp @@ -974,8 +974,8 @@ bool AMSMaterialsSetting::Show(bool show) static void _collect_filament_info(const wxString& shown_name, const Preset& filament, - unordered_map& query_filament_vendors, - unordered_map& query_filament_types) + std::unordered_map& query_filament_vendors, + std::unordered_map& query_filament_types) { query_filament_vendors[shown_name] = filament.config.get_filament_vendor(); query_filament_types[shown_name] = filament.config.get_filament_type(); diff --git a/src/slic3r/GUI/Auxiliary.cpp b/src/slic3r/GUI/Auxiliary.cpp index 1827032b29..85f6533c1c 100644 --- a/src/slic3r/GUI/Auxiliary.cpp +++ b/src/slic3r/GUI/Auxiliary.cpp @@ -856,14 +856,14 @@ void AuxiliaryPanel::Split(const std::string &src, const std::string &separator, dest.clear(); index = str.find_first_of(separator, start); do { - if (index != string::npos) { + if (index != std::string::npos) { substring = str.substr(start, index - start); dest.push_back(substring); start = index + separator.size(); index = str.find(separator, start); - if (start == string::npos) break; + if (start == std::string::npos) break; } - } while (index != string::npos); + } while (index != std::string::npos); // the last part substring = str.substr(start); diff --git a/src/slic3r/GUI/CalibrationWizardPresetPage.cpp b/src/slic3r/GUI/CalibrationWizardPresetPage.cpp index e49ebfb787..3ed3ca66df 100644 --- a/src/slic3r/GUI/CalibrationWizardPresetPage.cpp +++ b/src/slic3r/GUI/CalibrationWizardPresetPage.cpp @@ -1307,7 +1307,7 @@ void CalibrationPresetPage::stripWhiteSpace(std::string& str) { if (str == "") { return; } - string::iterator cur_it; + std::string::iterator cur_it; cur_it = str.begin(); while (cur_it != str.end()) { @@ -2597,7 +2597,7 @@ void CalibrationPresetPage::update_multi_extruder_filament_combobox(const std::s int ams_id_int = 0; try { if (!ams_id.empty()) - ams_id_int = stoi(ams_id.c_str()); + ams_id_int = std::stoi(ams_id.c_str()); } catch (...) {} @@ -2685,7 +2685,7 @@ void CalibrationPresetPage::update_filament_combobox(std::string ams_id) int ams_id_int = 0; try { if (!ams_id.empty()) - ams_id_int = stoi(ams_id.c_str()); + ams_id_int = std::stoi(ams_id.c_str()); } catch (...) {} diff --git a/src/slic3r/GUI/CreatePresetsDialog.cpp b/src/slic3r/GUI/CreatePresetsDialog.cpp index efe7bc16ba..c7c9cd2760 100644 --- a/src/slic3r/GUI/CreatePresetsDialog.cpp +++ b/src/slic3r/GUI/CreatePresetsDialog.cpp @@ -347,7 +347,7 @@ static std::string get_curr_timestmp() // return timestampString; } -static void get_filament_compatible_printer(Preset* preset, vector& printers) +static void get_filament_compatible_printer(Preset* preset, std::vector& printers) { auto compatible_printers = dynamic_cast(preset->config.option("compatible_printers")); if (compatible_printers == nullptr) return; @@ -1581,7 +1581,7 @@ void CreateFilamentPresetDialog::sort_printer_by_nozzle(std::vector nozzle_diameter = nozzle_diameter_map; std::sort(printer_name_to_filament_preset.begin(), printer_name_to_filament_preset.end(), - [&nozzle_diameter](const std::pair &a, const std::pair &b) { + [&nozzle_diameter](const std::pair &a, const std::pair &b) { size_t nozzle_index_a = a.first.find(" nozzle"); size_t nozzle_index_b = b.first.find(" nozzle"); if (nozzle_index_a == std::string::npos || nozzle_index_b == std::string::npos) return a.first < b.first; @@ -3143,7 +3143,7 @@ void CreatePrinterPresetDialog::set_current_visible_printer() wxArrayString CreatePrinterPresetDialog::printer_preset_sort_with_nozzle_diameter(const VendorProfile &vendor_profile, float nozzle_diameter) { - std::vector> preset_sort; + std::vector> preset_sort; auto get_nozzle_size_for_printer_model = [this](const std::string & model_name) -> size_t { auto iter = m_printer_name_to_preset.find(model_name); @@ -4964,7 +4964,7 @@ wxBoxSizer *CreatePresetForPrinterDialog::create_selected_filament_preset_sizer( m_selected_printer->Bind(wxEVT_COMBOBOX, [this](wxCommandEvent &e) { wxString printer_name = m_selected_printer->GetStringSelection(); - std::unordered_map>>::iterator filament_iter = m_printer_compatible_filament_presets.find(into_u8(printer_name)); + std::unordered_map>>::iterator filament_iter = m_printer_compatible_filament_presets.find(into_u8(printer_name)); if (m_printer_compatible_filament_presets.end() != filament_iter) { filament_choice_to_filament_preset.clear(); wxArrayString filament_choices; diff --git a/src/slic3r/GUI/DeviceCore/DevFilaSystem.cpp b/src/slic3r/GUI/DeviceCore/DevFilaSystem.cpp index 8644047e64..14d78fba1f 100644 --- a/src/slic3r/GUI/DeviceCore/DevFilaSystem.cpp +++ b/src/slic3r/GUI/DeviceCore/DevFilaSystem.cpp @@ -160,7 +160,7 @@ DevAms::~DevAms() m_trays.clear(); } -static unordered_map s_ams_display_formats = { +static std::unordered_map s_ams_display_formats = { {DevAms::AMS, "AMS-%d"}, {DevAms::AMS_LITE, "AMS Lite-%d"}, {DevAms::N3F, "AMS 2 PRO-%d"}, diff --git a/src/slic3r/GUI/DeviceCore/DevMappingNozzle.cpp b/src/slic3r/GUI/DeviceCore/DevMappingNozzle.cpp index 5eb0defa93..95081f5382 100644 --- a/src/slic3r/GUI/DeviceCore/DevMappingNozzle.cpp +++ b/src/slic3r/GUI/DeviceCore/DevMappingNozzle.cpp @@ -250,7 +250,7 @@ int DevNozzleMappingCtrl::CtrlGetAutoNozzleMappingV1(Slic3r::GUI::Plater* plater void DevNozzleMappingCtrl::ParseAutoNozzleMapping(const json& print_jj) { - if (print_jj.contains("command") && print_jj["command"].get() == "get_auto_nozzle_mapping") { + if (print_jj.contains("command") && print_jj["command"].get() == "get_auto_nozzle_mapping") { if (print_jj.contains("sequence_id") && print_jj["sequence_id"] == m_sequence_id) { Clear(); DevJsonValParser::ParseVal(print_jj, "result", m_result); diff --git a/src/slic3r/GUI/DeviceCore/DevNozzleSystem.cpp b/src/slic3r/GUI/DeviceCore/DevNozzleSystem.cpp index 98d5d5bd5f..14c29817ef 100644 --- a/src/slic3r/GUI/DeviceCore/DevNozzleSystem.cpp +++ b/src/slic3r/GUI/DeviceCore/DevNozzleSystem.cpp @@ -426,7 +426,7 @@ void DevNozzleSystem::ClearNozzles() // ---- parsing ---------------------------------------------------------------------------------------- -static unordered_map _str2_nozzle_flow_type = { +static std::unordered_map _str2_nozzle_flow_type = { {"S", NozzleFlowType::S_FLOW}, {"H", NozzleFlowType::H_FLOW}, {"A", NozzleFlowType::S_FLOW}, @@ -436,7 +436,7 @@ static unordered_map _str2_nozzle_flow_type = { {"B", NozzleFlowType::E_FLOW}, // E3D High Flow -> nvtE3DHighFlow }; -static unordered_map _str2_nozzle_type = { +static std::unordered_map _str2_nozzle_type = { {"00", NozzleType::ntStainlessSteel}, {"01", NozzleType::ntHardenedSteel}, {"05", NozzleType::ntTungstenCarbide} diff --git a/src/slic3r/GUI/DeviceErrorDialog.cpp b/src/slic3r/GUI/DeviceErrorDialog.cpp index de578f78ed..23b7f3a665 100644 --- a/src/slic3r/GUI/DeviceErrorDialog.cpp +++ b/src/slic3r/GUI/DeviceErrorDialog.cpp @@ -368,7 +368,7 @@ wxString DeviceErrorDialog::parse_error_level(int error_code) } } -static const std::unordered_set s_jump_liveview_error_codes = { "0300-8003", "0300-8002", "0300-800A"}; +static const std::unordered_set s_jump_liveview_error_codes = { "0300-8003", "0300-8002", "0300-800A"}; wxString DeviceErrorDialog::show_error_code(int error_code) { if (m_error_code == error_code) { return wxEmptyString;} diff --git a/src/slic3r/GUI/DeviceManager.cpp b/src/slic3r/GUI/DeviceManager.cpp index 3729387040..30e7282c0e 100644 --- a/src/slic3r/GUI/DeviceManager.cpp +++ b/src/slic3r/GUI/DeviceManager.cpp @@ -110,6 +110,7 @@ using json = nlohmann::json; class wxWindow; namespace fs = boost::filesystem; +using namespace std::chrono_literals; #define CALI_DEBUG #define MINUTE_30 1800000 //ms @@ -3103,7 +3104,7 @@ int MachineObject::parse_json(std::string tunnel, std::string payload, bool key_ DevFirmwareVersionInfo ver_info; ver_info.name = (*it)["name"].get(); if ((*it).contains("product_name")) - ver_info.product_name = wxString::FromUTF8((*it)["product_name"].get()); + ver_info.product_name = wxString::FromUTF8((*it)["product_name"].get()); if ((*it).contains("sw_ver")) ver_info.sw_ver = (*it)["sw_ver"].get(); if ((*it).contains("sw_new_ver")) diff --git a/src/slic3r/GUI/EditGCodeDialog.cpp b/src/slic3r/GUI/EditGCodeDialog.cpp index 917ff56013..2ef70ab82b 100644 --- a/src/slic3r/GUI/EditGCodeDialog.cpp +++ b/src/slic3r/GUI/EditGCodeDialog.cpp @@ -294,8 +294,8 @@ wxDataViewItem EditGCodeDialog::add_presets_placeholders() // Orca: create subgroups from the pages of the tabs - auto init_from_tab = [this, full_config](wxDataViewItem parent, Tab* tab, const set& preset_keys){ - set extra_keys(preset_keys); + auto init_from_tab = [this, full_config](wxDataViewItem parent, Tab* tab, const std::set& preset_keys){ + std::set extra_keys(preset_keys); for (const auto& page : tab->m_pages) { // ORCA: Pull icons from tabs for subgroups, icons are hidden on tabs std::string icon_name = "empty"; // use empty icon if not defined @@ -549,7 +549,7 @@ void ParamsNode::RefreshSearch(const wxString& search_text) if (GetEnabledChildren().empty()) if (auto pos = text.find(search_text); IsParamNode() && pos != wxString::npos) { - m_highlight_index = make_unique>(pos, search_text.Len()); + m_highlight_index = make_unique>(pos, search_text.Len()); Enable(); } else { Disable(); diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp index 05ab99bae1..fda86e854d 100644 --- a/src/slic3r/GUI/Field.cpp +++ b/src/slic3r/GUI/Field.cpp @@ -702,11 +702,11 @@ void Field::get_value_by_opt_type(wxString& str, const bool check_value/* = true set_value(str, true); } } else if (m_opt.opt_key == "sparse_infill_rotate_template" || m_opt.opt_key == "solid_infill_rotate_template") { - string ustr(str.utf8_string()); + std::string ustr(str.utf8_string()); if (!ConfigOptionFloats::validate_string(ustr)) { - string v; + std::string v; std::smatch match; - string ps = (m_opt.opt_key == "sparse_infill_rotate_template") ? + std::string ps = (m_opt.opt_key == "sparse_infill_rotate_template") ? u8"[BT][!]?|[#][\\d]+[!]?|[+\\-]?[\\d.]+[%]?[*]?[\\d]*[/NnZz$LlUuQq~^|#]?[+\\-]?[\\d.]*[%#\'\"cm]?[m]?[BT]?[!*]?" : u8"[#][\\d]+[!]?|[+\\-]?[\\d.]+[%]?[*]?[\\d]*[/NnZz$LlUuQq~^|#]?[+\\-]?[\\d.]*[%#\'\"cm]?[m]?[!*]?"; @@ -729,7 +729,7 @@ void Field::get_value_by_opt_type(wxString& str, const bool check_value/* = true } break; } else if (m_opt.opt_key == "extra_solid_infills") { - string ustr(str.utf8_string()); + std::string ustr(str.utf8_string()); // New rule: accept either interval form (N or N#K) or explicit list (e.g. 1,7,9), with optional quotes. const std::regex rx_interval(u8R"(^\s*['"]?\s*\d+\s*(?:#\s*\d*)?\s*['"]?\s*$)"); // List entries may be plain numbers or number with optional #K count, e.g., 5, 9#2, 18 diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 4727ed0871..f21ce9ac15 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -94,6 +94,8 @@ #include "slic3r/GUI/Gizmos/GizmoObjectManipulation.hpp" #include "slic3r/GUI/PartPlate.hpp" +using namespace std::string_view_literals; + namespace Slic3r { class PrintBase; } @@ -3184,7 +3186,7 @@ void GCodeViewer::render_legend_color_arr_recommen(float window_padding) float ams_item_height = 0; float filament_group_item_align_width = 0; { - float three_words_width = imgui.calc_text_size(std::string_view("ABC")).x; + float three_words_width = imgui.calc_text_size("ABC"sv).x; const int line_capacity = 4; for (const auto& extruder_filaments : {m_left_extruder_filament,m_right_extruder_filament }) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 4f6c54fac5..6ad3e80dc0 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -177,6 +177,8 @@ extern wxPopupWindow* wxCurrentPopupWindow; #endif #endif +using namespace std::string_view_literals; + static constexpr const float TRACKBALLSIZE = 0.8f; static Slic3r::ColorRGBA DEFAULT_BG_LIGHT_COLOR = { 0.906f, 0.906f, 0.906f, 1.0f }; diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 499ac6f23d..11cde7e5f2 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -9040,7 +9040,7 @@ std::map GUI_App::get_delete_cache_presets_lock() void GUI_App::process_delete_presets() { - std::map delete_cache_presets = get_delete_cache_presets_lock(); + std::map delete_cache_presets = get_delete_cache_presets_lock(); for (auto it = delete_cache_presets.begin(); it != delete_cache_presets.end();) { if (it->first.empty()) continue; std::string del_setting_id = it->first; @@ -10068,7 +10068,7 @@ bool is_soluble_filament(int extruder_id) return support_option->get_at(0); }; -bool has_filaments(const std::vector& model_filaments) { +bool has_filaments(const std::vector& model_filaments) { auto &filament_presets = Slic3r::GUI::wxGetApp().preset_bundle->filament_presets; if (!Slic3r::GUI::wxGetApp().plater()) return false; auto model_objects = Slic3r::GUI::wxGetApp().plater()->model().objects; @@ -10103,7 +10103,7 @@ bool is_support_filament(int extruder_id, bool strict_check) Slic3r::ConfigOptionBools *support_option = dynamic_cast(filament->config.option("filament_is_support")); if(!strict_check &&(filament_type == "PETG" || filament_type == "PLA")) { - std::vector model_filaments; + std::vector model_filaments; if (filament_type == "PETG") model_filaments.emplace_back("PLA"); else { diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index fd6da1beef..47e391b2ed 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -1108,7 +1108,7 @@ void ObjectList::update_name_column_width() const } } - GetColumn(colName)->SetWidth(max(0, client_size.x - (others_width)*em)); + GetColumn(colName)->SetWidth(std::max(0, client_size.x - (others_width)*em)); } void ObjectList::set_filament_column_hidden(const bool hide) const @@ -3970,7 +3970,7 @@ wxDataViewItem ObjectList::add_settings_item(wxDataViewItem parent_item, const D if (config->opt_float("layer_height") == object_cfg->opt_float("layer_height")) { SettingsFactory::Bundle new_cat_options; for (auto cat_opt : cat_options) { - std::vector temp; + std::vector temp; for (auto value : cat_opt.second) { if (value != "layer_height") temp.push_back(value); diff --git a/src/slic3r/GUI/Gizmos/GizmoObjectManipulation.cpp b/src/slic3r/GUI/Gizmos/GizmoObjectManipulation.cpp index 72f08318c6..bb76a171b8 100644 --- a/src/slic3r/GUI/Gizmos/GizmoObjectManipulation.cpp +++ b/src/slic3r/GUI/Gizmos/GizmoObjectManipulation.cpp @@ -44,6 +44,8 @@ #define MAX_NUM 9999.99 #define MAX_SIZE std::string_view{"9999.99"} +using namespace std::string_view_literals; + namespace Slic3r { namespace GUI diff --git a/src/slic3r/GUI/HMS.cpp b/src/slic3r/GUI/HMS.cpp index 0a5dba5a0e..2234d1afb4 100644 --- a/src/slic3r/GUI/HMS.cpp +++ b/src/slic3r/GUI/HMS.cpp @@ -33,7 +33,7 @@ static const char* HMS_LOCAL_IMG_PATH = "hms/local_image"; // the local HMS info // Orca: dev-id-type set trimmed to the devices Orca ships local HMS images for -static unordered_set package_dev_id_types {"094", "239", "093", "22E"}; +static std::unordered_set package_dev_id_types {"094", "239", "093", "22E"}; // Orca: HMS should be disabled when stealth mode is on or networking is not installed static bool should_disable_hms() @@ -345,17 +345,17 @@ wxString HMSQuery::query_hms_msg(const std::string& dev_id, const std::string& l return _query_hms_msg(dev_id.substr(0, 3), long_error_code, lang_code); } -string HMSQuery::get_dev_id_type(const MachineObject* obj) const +std::string HMSQuery::get_dev_id_type(const MachineObject* obj) const { if (obj) { return obj->get_dev_id().substr(0, 3); } - return string(); + return std::string(); } -wxString HMSQuery::_query_hms_msg(const string& dev_id_type, const string& long_error_code, const string& lang_code) +wxString HMSQuery::_query_hms_msg(const std::string& dev_id_type, const std::string& long_error_code, const std::string& lang_code) { if (long_error_code.empty()) { @@ -426,9 +426,9 @@ wxString HMSQuery::_query_hms_msg(const string& dev_id_type, const string& long_ return wxEmptyString; } -bool HMSQuery::_is_internal_error(const string &dev_id_type, - const string &error_code, - const string &lang_code) +bool HMSQuery::_is_internal_error(const std::string &dev_id_type, + const std::string &error_code, + const std::string &lang_code) { init_hms_info(dev_id_type); auto iter = m_hms_info_jsons.find(dev_id_type); diff --git a/src/slic3r/GUI/Jobs/PrintJob.cpp b/src/slic3r/GUI/Jobs/PrintJob.cpp index 9e5e2cc7c4..b6b420969f 100644 --- a/src/slic3r/GUI/Jobs/PrintJob.cpp +++ b/src/slic3r/GUI/Jobs/PrintJob.cpp @@ -335,7 +335,7 @@ void PrintJob::process(Ctl &ctl) auto origin_profile_id = model_info->metadata_items.find(BBL_DESIGNER_PROFILE_ID_TAG); if (origin_profile_id != model_info->metadata_items.end()) { try { - params.origin_profile_id = stoi(origin_profile_id->second.c_str()); + params.origin_profile_id = std::stoi(origin_profile_id->second.c_str()); } catch(...) {} } diff --git a/src/slic3r/GUI/NotificationManager.cpp b/src/slic3r/GUI/NotificationManager.cpp index 7a7050429d..3e91d19cdd 100644 --- a/src/slic3r/GUI/NotificationManager.cpp +++ b/src/slic3r/GUI/NotificationManager.cpp @@ -536,12 +536,12 @@ void NotificationManager::PopNotification::count_lines() return; // handle with marks - if (pos_start == string::npos && pos_end == string::npos) { + if (pos_start == std::string::npos && pos_end == std::string::npos) { pos_start = text.find(error_start); - if (pos_start != string::npos) { + if (pos_start != std::string::npos) { text.erase(pos_start, error_start.length()); pos_end = text.find(error_end); - if (pos_end != string::npos) { + if (pos_end != std::string::npos) { text.erase(pos_end, error_end.length()); } } @@ -675,7 +675,7 @@ void NotificationManager::PopNotification::bbl_render_block_notif_text(ImGuiWrap if (m_text1.size() > m_endlines[i]) last_end += (m_text1[m_endlines[i]] == '\n' || m_text1[m_endlines[i]] == ' ' ? 1 : 0); - if (pos_start != string::npos && pos_end != string::npos && m_endlines[i] - line.length() >= pos_start && m_endlines[i] <= pos_end) { + if (pos_start != std::string::npos && pos_end != std::string::npos && m_endlines[i] - line.length() >= pos_start && m_endlines[i] <= pos_end) { push_style_color(ImGuiCol_Text, m_ErrorColor, m_state == EState::FadingOut, m_current_fade_opacity); imgui.text(line.c_str()); ImGui::PopStyleColor(); @@ -737,7 +737,7 @@ void NotificationManager::PopNotification::render_text(ImGuiWrapper& imgui, cons if (m_text1.size() > m_endlines[i]) last_end += (m_text1[m_endlines[i]] == '\n' || m_text1[m_endlines[i]] == ' ' ? 1 : 0); - if (pos_start != string::npos && pos_end != string::npos&& m_endlines[i] - line.length() >= pos_start && m_endlines[i] <= pos_end) { + if (pos_start != std::string::npos && pos_end != std::string::npos&& m_endlines[i] - line.length() >= pos_start && m_endlines[i] <= pos_end) { push_style_color(ImGuiCol_Text, m_ErrorColor, m_state == EState::FadingOut, m_current_fade_opacity); imgui.text(line.c_str()); ImGui::PopStyleColor(); diff --git a/src/slic3r/GUI/PartSkipDialog.cpp b/src/slic3r/GUI/PartSkipDialog.cpp index ddf0d10965..4c0557abea 100644 --- a/src/slic3r/GUI/PartSkipDialog.cpp +++ b/src/slic3r/GUI/PartSkipDialog.cpp @@ -86,7 +86,7 @@ PartSkipDialog::PartSkipDialog(wxWindow *parent) : DPIDialog(parent, wxID_ANY, _ { std::time_t t = std::time(0); std::stringstream buf; - buf << put_time(std::localtime(&t), "%a_%b_%d_%H_%M_%S/"); + buf << std::put_time(std::localtime(&t), "%a_%b_%d_%H_%M_%S/"); m_timestamp = buf.str(); SetBackgroundColour(*wxWHITE); @@ -402,7 +402,7 @@ std::string PartSkipDialog::create_tmp_path() return tmp_path; } -bool PartSkipDialog::is_local_file_existed(const std::vector &local_paths) +bool PartSkipDialog::is_local_file_existed(const std::vector &local_paths) { for (auto path : local_paths) { if (!std::filesystem::exists(path)) { return false; } @@ -703,8 +703,8 @@ void PartSkipDialog::InitDialogUI() m_parts_state.clear(); m_parts_name.clear(); - string pick_img = m_local_paths[0]; - string slice_info = m_local_paths[2]; + std::string pick_img = m_local_paths[0]; + std::string slice_info = m_local_paths[2]; m_switch_drag_btn->SetIcon("canvas_drag"); m_switch_drag_btn->SetBackgroundColor(*wxWHITE); diff --git a/src/slic3r/GUI/PartSkipDialog.hpp b/src/slic3r/GUI/PartSkipDialog.hpp index f1aef1f022..4e4f7b6bb6 100644 --- a/src/slic3r/GUI/PartSkipDialog.hpp +++ b/src/slic3r/GUI/PartSkipDialog.hpp @@ -139,11 +139,11 @@ private: boost::shared_ptr m_file_sys; std::string m_timestamp; std::string m_tmp_path; - std::vector m_local_paths; - std::vector m_target_paths; + std::vector m_local_paths; + std::vector m_target_paths; std::string create_tmp_path(); - bool is_local_file_existed(const std::vector &local_paths); + bool is_local_file_existed(const std::vector &local_paths); void DownloadPartsFile(); void OnFileSystemEvent(wxCommandEvent &event); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 707bed30b1..76ccac2838 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -357,7 +357,7 @@ wxDEFINE_EVENT(EVT_NOTICE_FULL_SCREEN_CHANGED, IntEvent); #define PRINTER_PANEL_RADIUS (6) // ORCA #define BTN_SYNC_SIZE (wxSize(FromDIP(96), FromDIP(98))) -static string get_diameter_string(float diameter) +static std::string get_diameter_string(float diameter) { std::ostringstream stream; // ORCA ensure 0.25 returned as 0.25. previous code returned as 0.2 because of std::setprecision(1) stream << std::fixed << std::setprecision(2) << diameter; // Use 2 decimals to capture 0.25 / 0.15 reliably @@ -6323,7 +6323,7 @@ void Sidebar::sync_ams_list(bool is_from_big_sync_btn) } // BBS:Record consumables information before synchronization - std::vector color_before_sync; + std::vector color_before_sync; std::vector is_support_before; DynamicPrintConfig& project_config = wxGetApp().preset_bundle->project_config; ConfigOptionStrings* color_opt = project_config.option("filament_colour"); @@ -12762,7 +12762,7 @@ void Plater::priv::on_select_preset(wxCommandEvent &evt) Vec3d old_plate_pos = old_plate->get_center_origin(); // BBS: Save the model in the current platelist - std::vector > plate_object; + std::vector > plate_object; for (size_t i = 0; i < old_plate_list.get_plate_count(); ++i) { PartPlate* plate = old_plate_list.get_plate(i); std::vector obj_idxs; @@ -17975,7 +17975,7 @@ bool Plater::load_files(const wxArrayString& filenames) // Orca: Iters through given paths and imports files from zip then remove zip from paths // returns true if zip files were found - auto handle_zips = [this](vector& paths) { // NOLINT(*-no-recursion) - Recursion is intended and should be managed properly + auto handle_zips = [this](std::vector& paths) { // NOLINT(*-no-recursion) - Recursion is intended and should be managed properly bool res = false; for (auto it = paths.begin(); it != paths.end();) { if (boost::algorithm::iends_with(it->string(), ".zip")) { diff --git a/src/slic3r/GUI/Preferences.cpp b/src/slic3r/GUI/Preferences.cpp index 735b02f58b..27e101745e 100644 --- a/src/slic3r/GUI/Preferences.cpp +++ b/src/slic3r/GUI/Preferences.cpp @@ -378,7 +378,7 @@ wxBoxSizer *PreferencesDialog::create_item_combobox(wxString title, wxString too auto current_setting = app_config->get(param); if (!current_setting.empty()) { - auto compare = [current_setting](string possible_setting) { return current_setting == possible_setting; }; + auto compare = [current_setting](std::string possible_setting) { return current_setting == possible_setting; }; auto iterator = find_if(config_name_index.begin(), config_name_index.end(), compare); if (iterator != config_name_index.end()) current_index = static_cast(iterator - config_name_index.begin()); @@ -1714,7 +1714,7 @@ void PreferencesDialog::create_items() g_sizer->Add(create_item_title(_L("Project")), 1, wxEXPAND); std::vector projectLoadSettingsBehaviourOptions = {_L("Load All"), _L("Ask When Relevant"), _L("Always Ask"), _L("Load Geometry Only")}; - std::vector projectLoadSettingsConfigOptions = { OPTION_PROJECT_LOAD_BEHAVIOUR_LOAD_ALL, OPTION_PROJECT_LOAD_BEHAVIOUR_ASK_WHEN_RELEVANT, OPTION_PROJECT_LOAD_BEHAVIOUR_ALWAYS_ASK, OPTION_PROJECT_LOAD_BEHAVIOUR_LOAD_GEOMETRY }; + std::vector projectLoadSettingsConfigOptions = { OPTION_PROJECT_LOAD_BEHAVIOUR_LOAD_ALL, OPTION_PROJECT_LOAD_BEHAVIOUR_ASK_WHEN_RELEVANT, OPTION_PROJECT_LOAD_BEHAVIOUR_ALWAYS_ASK, OPTION_PROJECT_LOAD_BEHAVIOUR_LOAD_GEOMETRY }; auto item_project_load = create_item_combobox(_L("Load behavior"), _L("Should printer/filament/process settings be loaded when opening a 3MF file?"), SETTING_PROJECT_LOAD_BEHAVIOUR, projectLoadSettingsBehaviourOptions, projectLoadSettingsConfigOptions); g_sizer->Add(item_project_load); diff --git a/src/slic3r/GUI/Project.cpp b/src/slic3r/GUI/Project.cpp index a0ed54cfe2..0680878999 100644 --- a/src/slic3r/GUI/Project.cpp +++ b/src/slic3r/GUI/Project.cpp @@ -239,7 +239,7 @@ void ProjectPanel::on_reload(wxCommandEvent& evt) } bool has_content = false; - for (const string& v : { + for (const std::string& v : { update_type, license, model_name, diff --git a/src/slic3r/GUI/SelectMachine.cpp b/src/slic3r/GUI/SelectMachine.cpp index 3a23889c6c..a885dcd058 100644 --- a/src/slic3r/GUI/SelectMachine.cpp +++ b/src/slic3r/GUI/SelectMachine.cpp @@ -182,7 +182,7 @@ std::string get_nozzle_volume_type_cloud_string(NozzleVolumeType nozzle_volume_t static int s_nozzle_mapping_last_request_time = 0; std::vector SelectMachineDialog::MACHINE_BED_TYPE_STRING; -std::vector SelectMachineDialog::MachineBedTypeString; +std::vector SelectMachineDialog::MachineBedTypeString; void SelectMachineDialog::init_machine_bed_types() { if (MACHINE_BED_TYPE_STRING.size() == 0) { @@ -2748,8 +2748,8 @@ void SelectMachineDialog::on_ok_btn(wxCommandEvent &event) std::vector confirm_text; // check more than one using in same external spool - std::unordered_set main_external_spool_filas; - std::unordered_set deputy_external_spool_filas; + std::unordered_set main_external_spool_filas; + std::unordered_set deputy_external_spool_filas; for (const auto& mapping_info : m_ams_mapping_result) { if (mapping_info.ams_id == VIRTUAL_AMS_MAIN_ID_STR){ main_external_spool_filas.insert(mapping_info.filament_id); @@ -5239,7 +5239,7 @@ void SelectMachineDialog::update_show_status(MachineObject* obj_) /*Check high temperture slicing*/ if (m_print_type == PrintFromType::FROM_NORMAL) { - std::set high_temp_filaments; + std::set high_temp_filaments; std::unordered_set known_fila_soften_extruders; std::unordered_set unknown_fila_soften_extruders; auto preset_full_config = wxGetApp().preset_bundle->full_config(); diff --git a/src/slic3r/GUI/SelectMachine.hpp b/src/slic3r/GUI/SelectMachine.hpp index a0515dd20c..31ce752a2e 100644 --- a/src/slic3r/GUI/SelectMachine.hpp +++ b/src/slic3r/GUI/SelectMachine.hpp @@ -337,7 +337,7 @@ private: wxColour m_colour_bold_color{wxColour(38, 46, 48)}; StateColor m_btn_bg_enable; - std::unordered_map m_checkbox_list; + std::unordered_map m_checkbox_list; std::list m_checkbox_list_order; std::shared_ptr m_token = std::make_shared(0); diff --git a/src/slic3r/GUI/SendToPrinter.cpp b/src/slic3r/GUI/SendToPrinter.cpp index 370baf29d1..7e98fbe85e 100644 --- a/src/slic3r/GUI/SendToPrinter.cpp +++ b/src/slic3r/GUI/SendToPrinter.cpp @@ -126,7 +126,7 @@ void SendToPrinterDialog::stripWhiteSpace(std::string& str) { if (str == "") { return; } - string::iterator cur_it; + std::string::iterator cur_it; cur_it = str.begin(); while (cur_it != str.end()) { diff --git a/src/slic3r/GUI/StatusPanel.hpp b/src/slic3r/GUI/StatusPanel.hpp index af908c0c80..cd297eefe8 100644 --- a/src/slic3r/GUI/StatusPanel.hpp +++ b/src/slic3r/GUI/StatusPanel.hpp @@ -171,7 +171,7 @@ public: std::string current_nozzle_loc = ""; wxColour m_colour; - string m_file_name; + std::string m_file_name; bool m_ams_loading{false}; void doRender(wxDC &dc); ExtruderImage(wxWindow *parent, wxWindowID id, int nozzle_num, const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize); @@ -244,7 +244,7 @@ protected: { wxString local_image_url; //local image path std::string img_url_paths; // oss url path - vector image_broad; + std::vector image_broad; bool is_selected; bool is_uploaded; // load wxBoxSizer * image_tb_broad = nullptr; diff --git a/src/slic3r/GUI/SyncAmsInfoDialog.cpp b/src/slic3r/GUI/SyncAmsInfoDialog.cpp index 61998dc963..d6049451b9 100644 --- a/src/slic3r/GUI/SyncAmsInfoDialog.cpp +++ b/src/slic3r/GUI/SyncAmsInfoDialog.cpp @@ -1576,7 +1576,7 @@ bool SyncAmsInfoDialog::is_nozzle_type_match(DevExtderSystem data, wxString &err } } - vector map_extruders = {1, 0}; + std::vector map_extruders = {1, 0}; // The default two extruders are left, right, but the order of the extruders on the machine is right, left. std::vector flow_type_of_machine; @@ -1676,7 +1676,7 @@ void SyncAmsInfoDialog::stripWhiteSpace(std::string &str) { if (str == "") { return; } - string::iterator cur_it; + std::string::iterator cur_it; cur_it = str.begin(); while (cur_it != str.end()) { diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index e08745666c..143025399f 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -2257,7 +2257,7 @@ void Tab::on_value_change(const std::string& opt_key, const boost::any& value) wxGetApp().plater()->update(); } - string opt_key_without_idx = opt_key.substr(0, opt_key.find('#')); + std::string opt_key_without_idx = opt_key.substr(0, opt_key.find('#')); if (opt_key_without_idx == "long_retractions_when_cut") { unsigned char activate = boost::any_cast(value); diff --git a/src/slic3r/GUI/WebGuideDialog.cpp b/src/slic3r/GUI/WebGuideDialog.cpp index b5b48d413e..b3e0aa7cd6 100644 --- a/src/slic3r/GUI/WebGuideDialog.cpp +++ b/src/slic3r/GUI/WebGuideDialog.cpp @@ -1682,13 +1682,13 @@ int GuideFrame::SaveProfileData() return 0; } -void StringReplace(string &strBase, string strSrc, string strDes) +void StringReplace(std::string &strBase, std::string strSrc, std::string strDes) { - string::size_type pos = 0; - string::size_type srcLen = strSrc.size(); - string::size_type desLen = strDes.size(); + std::string::size_type pos = 0; + std::string::size_type srcLen = strSrc.size(); + std::string::size_type desLen = strDes.size(); pos = strBase.find(strSrc, pos); - while ((pos != string::npos)) { + while ((pos != std::string::npos)) { strBase.replace(pos, srcLen, strDes); pos = strBase.find(strSrc, (pos + desLen)); } diff --git a/src/slic3r/GUI/Widgets/AMSControl.cpp b/src/slic3r/GUI/Widgets/AMSControl.cpp index c5015c9ddc..2fe4ac6014 100644 --- a/src/slic3r/GUI/Widgets/AMSControl.cpp +++ b/src/slic3r/GUI/Widgets/AMSControl.cpp @@ -1052,7 +1052,7 @@ void AMSControl::UpdateAms(const std::string &series_name, /*update humidity popup*/ if (m_percent_humidity_dry_popup->IsShown()) { - string target_id = m_percent_humidity_dry_popup->get_owner_ams_id(); + std::string target_id = m_percent_humidity_dry_popup->get_owner_ams_id(); for (const auto& the_info : ams_info) { if (target_id == the_info.ams_id) diff --git a/src/slic3r/GUI/Widgets/AMSControl.hpp b/src/slic3r/GUI/Widgets/AMSControl.hpp index f4c83667c2..99146a01a6 100644 --- a/src/slic3r/GUI/Widgets/AMSControl.hpp +++ b/src/slic3r/GUI/Widgets/AMSControl.hpp @@ -63,7 +63,7 @@ protected: std::string m_dev_id; std::vector> m_item_ids{ {}, {} }; - std::vector> pair_id; + std::vector> pair_id; int m_total_ext_count = 1; AMSextruder *m_extruder{nullptr}; @@ -181,7 +181,7 @@ public: std::tuple isFilaSwitchReady(); void show_switcher_status(bool show); - void UpdatePassRoad(string ams_id, AMSPassRoadType type, AMSPassRoadSTEP step); + void UpdatePassRoad(std::string ams_id, AMSPassRoadType type, AMSPassRoadSTEP step); void CreateAms(); void CreateAmsDoubleNozzle(const std::string &series_name, const std::string& printer_type); void CreateAmsSingleNozzle(const std::string &series_name, const std::string &printer_type); diff --git a/src/slic3r/GUI/Widgets/AMSItem.cpp b/src/slic3r/GUI/Widgets/AMSItem.cpp index ef3643e531..95418f79a2 100644 --- a/src/slic3r/GUI/Widgets/AMSItem.cpp +++ b/src/slic3r/GUI/Widgets/AMSItem.cpp @@ -634,7 +634,7 @@ void AMSextruderImage::doRender(wxDC &dc) } -AMSextruderImage::AMSextruderImage(wxWindow *parent, wxWindowID id, string file_name, const wxSize& size, const wxPoint &pos) +AMSextruderImage::AMSextruderImage(wxWindow *parent, wxWindowID id, std::string file_name, const wxSize& size, const wxPoint &pos) { wxWindow::Create(parent, id, pos, size); SetBackgroundColour(StateColor::darkModeColorFor(*wxWHITE)); @@ -823,7 +823,7 @@ void SwitcherImage::doRender(wxDC &dc) Layout(); } -SwitcherImage::SwitcherImage(wxWindow *parent, wxWindowID id, string file_name, const wxSize& size, const wxPoint &pos) +SwitcherImage::SwitcherImage(wxWindow *parent, wxWindowID id, std::string file_name, const wxSize& size, const wxPoint &pos) { wxWindow::Create(parent, id, pos, size); SetBackgroundColour(StateColor::darkModeColorFor(*wxWHITE)); @@ -899,7 +899,7 @@ void AMSextruder::OnAmsLoading(bool load, int nozzle_id, wxColour col /*= AMS_CO } /*return true if something is updated*/ -bool AMSextruder::updateNozzleNum(int nozzle_num, const string& series_name) +bool AMSextruder::updateNozzleNum(int nozzle_num, const std::string& series_name) { if (m_nozzle_num == nozzle_num && m_series_name == series_name) return false; m_series_name = series_name; diff --git a/src/slic3r/GUI/Widgets/AMSItem.hpp b/src/slic3r/GUI/Widgets/AMSItem.hpp index 55c0a3ca8d..c17b4ad59d 100644 --- a/src/slic3r/GUI/Widgets/AMSItem.hpp +++ b/src/slic3r/GUI/Widgets/AMSItem.hpp @@ -393,10 +393,10 @@ public: bool m_show_state = {false}; wxColour m_colour; ScalableBitmap m_ams_extruder; - string m_file_name; + std::string m_file_name; bool m_ams_loading{ false }; void doRender(wxDC &dc); - AMSextruderImage(wxWindow *parent, wxWindowID id, string file_name, const wxSize& size, const wxPoint &pos = wxDefaultPosition); + AMSextruderImage(wxWindow *parent, wxWindowID id, std::string file_name, const wxSize& size, const wxPoint &pos = wxDefaultPosition); ~AMSextruderImage(); }; @@ -444,10 +444,10 @@ public: bool m_show_state = {false}; wxColour m_colour; ScalableBitmap m_switcher; - string m_file_name; + std::string m_file_name; // bool m_ams_loading{ false }; void doRender(wxDC &dc); - SwitcherImage(wxWindow *parent, wxWindowID id, string file_name, const wxSize& size, const wxPoint &pos = wxDefaultPosition); + SwitcherImage(wxWindow *parent, wxWindowID id, std::string file_name, const wxSize& size, const wxPoint &pos = wxDefaultPosition); ~SwitcherImage(); }; @@ -456,7 +456,7 @@ class AMSextruder : public wxWindow { private: int m_nozzle_num = -1; - string m_series_name; + std::string m_series_name; public: void TurnOn(wxColour col); @@ -466,7 +466,7 @@ public: void msw_rescale(); void has_ams(bool hams) {m_has_vams = hams; Refresh();}; void no_ams_mode(bool mode) {m_none_ams_mode = mode; Refresh();}; - bool updateNozzleNum(int nozzle_num, const std::string& series_name = string()); + bool updateNozzleNum(int nozzle_num, const std::string& series_name = std::string()); bool m_none_ams_mode{true}; bool m_has_vams{false}; diff --git a/src/slic3r/Utils/json_diff.hpp b/src/slic3r/Utils/json_diff.hpp index bb88e78c7f..df097dc78c 100644 --- a/src/slic3r/Utils/json_diff.hpp +++ b/src/slic3r/Utils/json_diff.hpp @@ -7,9 +7,6 @@ #include "nlohmann/json.hpp" - -using namespace std; - class json_diff { private: From 662a8e340d5edd7fa5fbcf59c645a7bc931d216d Mon Sep 17 00:00:00 2001 From: HanifKoh <76276251+HanifKoh@users.noreply.github.com> Date: Wed, 7 Oct 2026 15:51:21 +0800 Subject: [PATCH 2/5] Support the 02.08.04 Bambu Network Plug-in Series (#16202) The 02.08.02 series appended queue_plate_id to PrintParams and nothing after it changed the ABI OrcaSlicer calls, so adding the field brings the current layout up to 02.08.04. Make 02.08.04 the latest series and drop 02.08.01 from the whitelist: its PrintParams no longer matches, and its malformed bind table is refused by dyld on macOS 27, so it cannot load there. A stored 02.08.01 falls back to the latest series through the existing unsupported-version path. --- src/slic3r/Utils/BBLNetworkPlugin.cpp | 3 +- src/slic3r/Utils/bambu_networking.hpp | 11 ++-- tests/slic3rutils/test_network_versions.cpp | 65 ++++++++++++--------- 3 files changed, 45 insertions(+), 34 deletions(-) diff --git a/src/slic3r/Utils/BBLNetworkPlugin.cpp b/src/slic3r/Utils/BBLNetworkPlugin.cpp index 5cffe6468d..bae9ce85a8 100644 --- a/src/slic3r/Utils/BBLNetworkPlugin.cpp +++ b/src/slic3r/Utils/BBLNetworkPlugin.cpp @@ -596,7 +596,8 @@ PrintParams_Legacy BBLNetworkPlugin::as_legacy(PrintParams& param) } // Every PrintParams field except the four the 02.08.01 series added -// (task_timelapse_use_internal, extruder_cali_manual_mode, svc_context, slicer_uid). +// (task_timelapse_use_internal, extruder_cali_manual_mode, svc_context, slicer_uid) and the +// queue_plate_id 02.08.02 appended. PrintParams_0203 BBLNetworkPlugin::as_0203(PrintParams& param) { PrintParams_0203 p; diff --git a/src/slic3r/Utils/bambu_networking.hpp b/src/slic3r/Utils/bambu_networking.hpp index 30c33c6c73..54079ee0bd 100644 --- a/src/slic3r/Utils/bambu_networking.hpp +++ b/src/slic3r/Utils/bambu_networking.hpp @@ -336,6 +336,7 @@ struct PrintParams { bool try_emmc_print; std::string svc_context; std::string slicer_uid; + std::string queue_plate_id; }; struct TaskQueryParams @@ -412,7 +413,7 @@ enum class NetworkAbi { Unsupported, // no generation in this build can call it - never dispatch through it Legacy, // 01.10.01: PrintParams_Legacy; send_message/send_message_to_printer take no flag V0203, // 02.03.00: PrintParams_0203; bind takes no dev_model - Current, // 02.08.01: the layouts and signatures this build declares directly + Current, // 02.08.04: the layouts and signatures this build declares directly }; struct NetworkLibraryVersion { @@ -425,10 +426,12 @@ struct NetworkLibraryVersion { }; // Every row names the generation that can call it, so a series can never be offered without a -// host-side ABI for it. Series with no generation - 02.01.01, 02.00.02 and older - must stay out; -// is_supported_network_version() is the gate that keeps them from loading. +// host-side ABI for it. Series with no generation - 02.08.01 (whose PrintParams lacks the +// queue_plate_id that 02.08.02 appended, and whose malformed bind table macOS 27 refuses to +// load), 02.01.01, 02.00.02 and older - must stay out; is_supported_network_version() is the +// gate that keeps them from loading. static const NetworkLibraryVersion AVAILABLE_NETWORK_VERSIONS[] = { - {"02.08.01", "02.08.01", nullptr, true, nullptr, NetworkAbi::Current}, + {"02.08.04", "02.08.04", nullptr, true, nullptr, NetworkAbi::Current}, {"02.03.00", "02.03.00", nullptr, false, "An older plug-in series. Features that need newer plug-in support, such as print-failure " "snapshots in the device error dialog, are unavailable.", NetworkAbi::V0203}, diff --git a/tests/slic3rutils/test_network_versions.cpp b/tests/slic3rutils/test_network_versions.cpp index ad352e0bfa..cac2c1543e 100644 --- a/tests/slic3rutils/test_network_versions.cpp +++ b/tests/slic3rutils/test_network_versions.cpp @@ -78,31 +78,34 @@ TEST_CASE("Series and managed classification", "[NetworkVersions]") TEST_CASE_METHOD(PluginFolderFixture, "Managed builds fold into the series; customs are surfaced", "[NetworkVersions]") { - add_plugin("02.08.01.55"); // managed, same series -> folded into the 02.08.01 row + add_plugin("02.08.04.60"); // managed, same series -> folded into the 02.08.04 row add_plugin("02.09.00.10"); // managed, unknown series -> not listed + add_plugin("02.08.01.55"); // managed, series this build no longer has an ABI for -> not listed add_plugin("02.03.00.62"); // managed, older whitelisted series -> folded into 02.03.00 add_plugin("02.01.01.52"); // managed, series with no ABI in this build -> not listed - add_plugin("02.08.01_custom"); // custom, whitelisted series -> listed under it - add_plugin("02.08.01.52-dev"); // custom (dash-suffixed), whitelisted series -> listed + add_plugin("02.08.04_custom"); // custom, whitelisted series -> listed under it + add_plugin("02.08.04.52-dev"); // custom (dash-suffixed), whitelisted series -> listed auto versions = get_all_available_versions(); // The specific managed build never gets its own row - the series represents it. - REQUIRE(count_version(versions, "02.08.01.55") == 0); - REQUIRE(count_version(versions, "02.08.01") == 1); + REQUIRE(count_version(versions, "02.08.04.60") == 0); + REQUIRE(count_version(versions, "02.08.04") == 1); REQUIRE(count_version(versions, "02.09.00.10") == 0); + REQUIRE(count_version(versions, "02.08.01.55") == 0); + REQUIRE(count_version(versions, "02.08.01") == 0); REQUIRE(count_version(versions, "02.03.00.62") == 0); REQUIRE(count_version(versions, "02.03.00") == 1); REQUIRE(count_version(versions, "02.01.01.52") == 0); // Custom-named builds are distinct files kept under their own name. - REQUIRE(count_version(versions, "02.08.01_custom") == 1); - REQUIRE(count_version(versions, "02.08.01.52-dev") == 1); + REQUIRE(count_version(versions, "02.08.04_custom") == 1); + REQUIRE(count_version(versions, "02.08.04.52-dev") == 1); // Newest series first, its customs nested under it (suffix sort: "" < ".52-dev" < "_custom"), // then older series, legacy last. - REQUIRE(versions[0].version == "02.08.01"); - REQUIRE(versions[1].version == "02.08.01.52-dev"); - REQUIRE(versions[2].version == "02.08.01_custom"); + REQUIRE(versions[0].version == "02.08.04"); + REQUIRE(versions[1].version == "02.08.04.52-dev"); + REQUIRE(versions[2].version == "02.08.04_custom"); REQUIRE(versions[3].version == "02.03.00"); REQUIRE(versions.back().version == BAMBU_NETWORK_AGENT_VERSION_LEGACY); @@ -111,9 +114,9 @@ TEST_CASE_METHOD(PluginFolderFixture, "Managed builds fold into the series; cust REQUIRE_FALSE(versions[3].is_latest); // Customs sort/render nested under their series (non-empty suffix, base = the series). - REQUIRE(versions[1].base_version == "02.08.01"); + REQUIRE(versions[1].base_version == "02.08.04"); REQUIRE_FALSE(versions[1].suffix.empty()); - REQUIRE(versions[2].base_version == "02.08.01"); + REQUIRE(versions[2].base_version == "02.08.04"); REQUIRE_FALSE(versions[2].suffix.empty()); // "(Latest)" is the series row, never a nested custom build. @@ -123,20 +126,20 @@ TEST_CASE_METHOD(PluginFolderFixture, "Managed builds fold into the series; cust REQUIRE_FALSE(versions[2].is_latest); // The stored default that drives download and update-check decisions is now the series. - REQUIRE(std::string(get_latest_network_version()) == "02.08.01"); + REQUIRE(std::string(get_latest_network_version()) == "02.08.04"); } TEST_CASE_METHOD(PluginFolderFixture, "Only the loaded series is marked installed", "[NetworkVersions]") { - add_plugin("02.08.01.55"); - add_plugin("02.08.01_custom"); + add_plugin("02.08.04.60"); + add_plugin("02.08.04_custom"); - // The loaded plug-in reports its full build (02.08.01.55); the series row is what gets marked. + // The loaded plug-in reports its full build (02.08.04.60); the series row is what gets marked. { - auto versions = get_all_available_versions("02.08.01.55"); + auto versions = get_all_available_versions("02.08.04.60"); int marked = 0; for (const auto& info : versions) - if (info.is_loaded) { ++marked; REQUIRE(info.version == "02.08.01"); } + if (info.is_loaded) { ++marked; REQUIRE(info.version == "02.08.04"); } REQUIRE(marked == 1); } @@ -152,10 +155,10 @@ TEST_CASE_METHOD(PluginFolderFixture, "Only the loaded series is marked installe // A loaded custom build matches its own row, never the bare series. { - auto versions = get_all_available_versions("02.08.01_custom"); + auto versions = get_all_available_versions("02.08.04_custom"); int marked = 0; for (const auto& info : versions) - if (info.is_loaded) { ++marked; REQUIRE(info.version == "02.08.01_custom"); } + if (info.is_loaded) { ++marked; REQUIRE(info.version == "02.08.04_custom"); } REQUIRE(marked == 1); } @@ -167,11 +170,11 @@ TEST_CASE_METHOD(PluginFolderFixture, "Only the loaded series is marked installe TEST_CASE("Only whitelisted series pass the load gate", "[NetworkVersions]") { // Each whitelisted series, its builds, and custom-named builds of that series. - REQUIRE(is_supported_network_version("02.08.01")); - REQUIRE(is_supported_network_version("02.08.01.52")); - REQUIRE(is_supported_network_version("02.08.01.55")); - REQUIRE(is_supported_network_version("02.08.01_custom")); - REQUIRE(is_supported_network_version("02.08.01.52-dev")); + REQUIRE(is_supported_network_version("02.08.04")); + REQUIRE(is_supported_network_version("02.08.04.52")); + REQUIRE(is_supported_network_version("02.08.04.60")); + REQUIRE(is_supported_network_version("02.08.04_custom")); + REQUIRE(is_supported_network_version("02.08.04.52-dev")); REQUIRE(is_supported_network_version("02.03.00")); REQUIRE(is_supported_network_version("02.03.00.62")); REQUIRE(is_supported_network_version("02.03.00.70")); @@ -179,6 +182,9 @@ TEST_CASE("Only whitelisted series pass the load gate", "[NetworkVersions]") REQUIRE(is_supported_network_version(BAMBU_NETWORK_AGENT_VERSION_LEGACY)); // Series whitelisted by previous Orca releases that no generation here can call. + REQUIRE_FALSE(is_supported_network_version("02.08.01")); + REQUIRE_FALSE(is_supported_network_version("02.08.01.55")); + REQUIRE_FALSE(is_supported_network_version("02.08.01_custom")); REQUIRE_FALSE(is_supported_network_version("02.01.01.52")); REQUIRE_FALSE(is_supported_network_version("02.00.02.50")); @@ -198,9 +204,9 @@ TEST_CASE("Each version resolves to the ABI generation that can call it", "[Netw { // The generation is keyed on the series, so every build of a series - including the // custom-named ones - resolves to the same one. - CHECK(network_plugin_abi("02.08.01") == NetworkAbi::Current); - CHECK(network_plugin_abi("02.08.01.55") == NetworkAbi::Current); - CHECK(network_plugin_abi("02.08.01.52-dev") == NetworkAbi::Current); + CHECK(network_plugin_abi("02.08.04") == NetworkAbi::Current); + CHECK(network_plugin_abi("02.08.04.60") == NetworkAbi::Current); + CHECK(network_plugin_abi("02.08.04.52-dev") == NetworkAbi::Current); CHECK(network_plugin_abi("02.03.00") == NetworkAbi::V0203); CHECK(network_plugin_abi("02.03.00.62") == NetworkAbi::V0203); CHECK(network_plugin_abi("02.03.00_custom") == NetworkAbi::V0203); @@ -208,6 +214,7 @@ TEST_CASE("Each version resolves to the ABI generation that can call it", "[Netw // Anything the load gate rejects must dispatch through nothing at all, rather than // defaulting to a layout it does not share. + CHECK(network_plugin_abi("02.08.01.55") == NetworkAbi::Unsupported); CHECK(network_plugin_abi("02.01.01.52") == NetworkAbi::Unsupported); CHECK(network_plugin_abi("02.00.02.50") == NetworkAbi::Unsupported); CHECK(network_plugin_abi("02.09.00.10") == NetworkAbi::Unsupported); @@ -234,7 +241,7 @@ TEST_CASE_METHOD(PluginFolderFixture, "Legacy series never adopts discovered bui // With nothing else on disk, the series holds "(Latest)" even though its library is // not installed. for (const auto& info : versions) { - if (info.version == "02.08.01") { + if (info.version == "02.08.04") { REQUIRE(info.is_latest); REQUIRE_FALSE(info.is_loaded); } From a56d1bf33e81d7081e4e3464cdb71a43157eeea4 Mon Sep 17 00:00:00 2001 From: HanifKoh <76276251+HanifKoh@users.noreply.github.com> Date: Wed, 7 Oct 2026 15:51:49 +0800 Subject: [PATCH 3/5] Keep a Project's Changed Values on Extruder Variants It Doesn't List (#16107) A project's listed settings are carried onto its base preset by update_non_diff_values_to_base_config, which matched variants by exact name and id. A variant the base gained after the project was saved got the base's value, while the same value in a user preset now falls back to the preset's first variant of that extruder. So an old project opened with its printer preset already modified, and saving it wrote the base's values into the 3MF. The function now maps variants with map_variant_indices, as update_diff_values_to_child_config does: a base variant the project does not list takes the project's first variant of the same extruder. The variant lists themselves stay the base's, so a fallback never writes one variant's name over another's. --- src/libslic3r/PrintConfig.cpp | 28 ++--- tests/libslic3r/test_config.cpp | 104 ++++++++++++++++++ .../libslic3r/test_preset_bundle_loading.cpp | 5 +- 3 files changed, 122 insertions(+), 15 deletions(-) diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 832ff9b3b4..c9bd957ab1 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -11520,12 +11520,18 @@ void DynamicPrintConfig::update_non_diff_values_to_base_config(DynamicPrintConfi int cur_variant_count = cur_extruder_variants.size(); int target_variant_count = target_extruder_variants.size(); + // A base variant this config does not list (the base gained it after the config was saved, or the + // config lists none) takes this config's first variant of the same extruder, as a user preset's + // values do in update_diff_values_to_child_config. Left unmatched, the base's value would silently + // replace the user's. variant_index.resize(target_variant_count, -1); if (cur_variant_count == 0) { // Defensive: target_variant_count may be 0 if the preset doesn't carry extruder_variant_name. // In that case keep variant_index empty and let the downstream size checks produce a useful error. if (!variant_index.empty()) - variant_index[0] = 0; + // This config's one value belongs to the extruder of the base's first variant. + variant_index = map_variant_indices(target_extruder_variants, target_extruder_ids, {}, + target_extruder_ids.empty() ? std::vector() : std::vector{target_extruder_ids[0]}); } else if ((cur_extruder_ids.size() > 0) && cur_variant_count != cur_extruder_ids.size()){ //should not happen @@ -11538,18 +11544,7 @@ void DynamicPrintConfig::update_non_diff_values_to_base_config(DynamicPrintConfi %extruder_variant_name %target_variant_count %extruder_id_name %target_extruder_ids.size(); } else { - for (int i = 0; i < target_variant_count; i++) - { - for (int j = 0; j < cur_variant_count; j++) - { - if ((target_extruder_variants[i] == cur_extruder_variants[j]) - &&(target_extruder_ids.empty() || (target_extruder_ids[i] == cur_extruder_ids[j]))) - { - variant_index[i] = j; - break; - } - } - } + variant_index = map_variant_indices(target_extruder_variants, target_extruder_ids, cur_extruder_variants, cur_extruder_ids); } for (auto& opt : keys) { @@ -11574,6 +11569,13 @@ void DynamicPrintConfig::update_non_diff_values_to_base_config(DynamicPrintConfi if (cur_variant_count > target_variant_count) continue; + // The variant lists are the base's layout itself, which every other value is + // carried onto: a variant this config lacks keeps its own name and id. + if (opt == extruder_id_name || opt == extruder_variant_name) { + opt_src->set(opt_target); + continue; + } + int stride = 1; if (key_set2.find(opt) != key_set2.end()) stride = 2; diff --git a/tests/libslic3r/test_config.cpp b/tests/libslic3r/test_config.cpp index 553e94b1c0..738e8539d2 100644 --- a/tests/libslic3r/test_config.cpp +++ b/tests/libslic3r/test_config.cpp @@ -538,6 +538,110 @@ SCENARIO("update_diff_values_to_child_config keeps a child's values on variants } } +SCENARIO("update_non_diff_values_to_base_config keeps a project's changed values on variants it does not list", + "[Config][Variant]") { + std::set no_keys; + auto variants = [](std::initializer_list names) { return new Slic3r::ConfigOptionStrings(names); }; + + GIVEN("A filament base with three variants") { + Slic3r::DynamicPrintConfig base; + base.set_key_value("filament_extruder_variant", + variants({"Direct Drive Standard", "Bowden Standard", "Direct Drive High Flow"})); + base.set_deserialize_strict("nozzle_temperature", "220,220,220"); + + WHEN("the project was saved when the base had only its first variant") { + Slic3r::DynamicPrintConfig project; + project.set_key_value("filament_extruder_variant", variants({"Direct Drive Standard"})); + project.set_deserialize_strict("nozzle_temperature", "199"); + + AND_WHEN("the project lists the value as changed") { + project.update_non_diff_values_to_base_config(base, project.keys(), {"nozzle_temperature"}, "", "filament_extruder_variant", + Slic3r::filament_options_with_variant, no_keys); + THEN("the project's value applies to every variant") { + REQUIRE(project.opt_serialize("nozzle_temperature") == "199,199,199"); + } + } + AND_WHEN("the project does not list the value as changed") { + project.update_non_diff_values_to_base_config(base, project.keys(), {}, "", "filament_extruder_variant", + Slic3r::filament_options_with_variant, no_keys); + THEN("the base's values replace it") { + REQUIRE(project.opt_serialize("nozzle_temperature") == "220,220,220"); + } + } + } + WHEN("the project lists every variant, in another order") { + Slic3r::DynamicPrintConfig project; + project.set_key_value("filament_extruder_variant", + variants({"Bowden Standard", "Direct Drive High Flow", "Direct Drive Standard"})); + project.set_deserialize_strict("nozzle_temperature", "190,205,199"); + project.update_non_diff_values_to_base_config(base, project.keys(), {"nozzle_temperature"}, "", "filament_extruder_variant", + Slic3r::filament_options_with_variant, no_keys); + THEN("each variant keeps its own value") { + REQUIRE(project.opt_serialize("nozzle_temperature") == "199,190,205"); + } + } + WHEN("the project lists no variants") { + Slic3r::DynamicPrintConfig project; + project.set_deserialize_strict("nozzle_temperature", "199"); + project.update_non_diff_values_to_base_config(base, project.keys(), {"nozzle_temperature"}, "", "filament_extruder_variant", + Slic3r::filament_options_with_variant, no_keys); + THEN("the project's value applies to every variant") { + REQUIRE(project.opt_serialize("nozzle_temperature") == "199,199,199"); + } + } + } + + GIVEN("A two-extruder printer base with two variants per extruder") { + Slic3r::DynamicPrintConfig base; + base.set_key_value("printer_extruder_variant", + variants({"Direct Drive Standard", "Direct Drive High Flow", "Direct Drive Standard", "Direct Drive High Flow"})); + base.set_key_value("printer_extruder_id", new Slic3r::ConfigOptionInts({1, 1, 2, 2})); + base.set_deserialize_strict("retraction_length", "0.8,0.8,0.8,0.8"); + + WHEN("the project lists only the Standard variant of each extruder") { + Slic3r::DynamicPrintConfig project; + project.set_key_value("printer_extruder_variant", variants({"Direct Drive Standard", "Direct Drive Standard"})); + project.set_key_value("printer_extruder_id", new Slic3r::ConfigOptionInts({1, 2})); + project.set_deserialize_strict("retraction_length", "1.1,2.2"); + project.update_non_diff_values_to_base_config(base, project.keys(), {"retraction_length"}, "printer_extruder_id", "printer_extruder_variant", + Slic3r::printer_options_with_variant_1, + Slic3r::printer_options_with_variant_2); + THEN("each extruder's High Flow variant takes that extruder's value") { + REQUIRE(project.opt_serialize("retraction_length") == "1.1,1.1,2.2,2.2"); + } + } + WHEN("the project lists only the Standard variant of each extruder, and the variant lists as changed") { + Slic3r::DynamicPrintConfig project; + project.set_key_value("printer_extruder_variant", variants({"Direct Drive Standard", "Direct Drive Standard"})); + project.set_key_value("printer_extruder_id", new Slic3r::ConfigOptionInts({1, 2})); + project.set_deserialize_strict("machine_max_speed_x", "300,100,400,150"); + base.set_deserialize_strict("machine_max_speed_x", "500,200,500,200,500,200,500,200"); + project.update_non_diff_values_to_base_config(base, project.keys(), + {"machine_max_speed_x", "printer_extruder_id", "printer_extruder_variant"}, + "printer_extruder_id", "printer_extruder_variant", + Slic3r::printer_options_with_variant_1, + Slic3r::printer_options_with_variant_2); + THEN("the variant lists are the base's") { + REQUIRE(project.opt_serialize("printer_extruder_variant") == base.opt_serialize("printer_extruder_variant")); + REQUIRE(project.opt_serialize("printer_extruder_id") == "1,1,2,2"); + } + THEN("each extruder's High Flow variant takes that extruder's pair of limits") { + REQUIRE(project.opt_serialize("machine_max_speed_x") == "300,100,300,100,400,150,400,150"); + } + } + WHEN("the project lists no variants") { + Slic3r::DynamicPrintConfig project; + project.set_deserialize_strict("retraction_length", "1.1"); + project.update_non_diff_values_to_base_config(base, project.keys(), {"retraction_length"}, "printer_extruder_id", "printer_extruder_variant", + Slic3r::printer_options_with_variant_1, + Slic3r::printer_options_with_variant_2); + THEN("only the first extruder's variants take the project's value") { + REQUIRE(project.opt_serialize("retraction_length") == "1.1,1.1,0.8,0.8"); + } + } + } +} + // SCENARIO("DynamicPrintConfig JSON serialization", "[Config]") { // WHEN("DynamicPrintConfig is serialized and deserialized") { // auto now = std::chrono::high_resolution_clock::now(); diff --git a/tests/libslic3r/test_preset_bundle_loading.cpp b/tests/libslic3r/test_preset_bundle_loading.cpp index 7dfba69cbd..e2ff2a2322 100644 --- a/tests/libslic3r/test_preset_bundle_loading.cpp +++ b/tests/libslic3r/test_preset_bundle_loading.cpp @@ -6228,8 +6228,9 @@ TEST_CASE("A per-variant project value maps onto its base preset's variant layou base_finder(&base, calls)); CHECK(config.option("print_extruder_variant")->values == std::vector{"Direct Drive Standard", "Direct Drive High Flow"}); - // The listed key keeps the project's Standard value and takes High Flow from the base. - check_double_vector(config.option("outer_wall_speed")->values, {100., 300.}); + // The listed key keeps the project's Standard value, and High Flow, which the project does not + // list, takes it too, as a user preset's value does. + check_double_vector(config.option("outer_wall_speed")->values, {100., 100.}); check_double_vector(config.option("inner_wall_speed")->values, {250., 350.}); } From ff8aebe76f0c700305e9fea04fa15ace5bd4b321 Mon Sep 17 00:00:00 2001 From: HanifKoh <76276251+HanifKoh@users.noreply.github.com> Date: Wed, 7 Oct 2026 15:52:18 +0800 Subject: [PATCH 4/5] Allow Unsigned Executable Memory in the macOS Entitlements (#16203) The Bambu network plug-in's code protector rewrites one page of its own signed __TEXT after loading. The hardened runtime tolerates that until the page is evicted; the next read of it then kills OrcaSlicer with CODESIGNING Invalid Page. Bambu Studio signs with allow-unsigned-executable-memory for this reason; with it added, the same build survives critical memory pressure that killed it in 30 s without. --- scripts/disable_validation.entitlements | 5 +++++ src/dev-utils/platform/osx/entitlements.plist | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/scripts/disable_validation.entitlements b/scripts/disable_validation.entitlements index 123d12a53e..af12034ce0 100644 --- a/scripts/disable_validation.entitlements +++ b/scripts/disable_validation.entitlements @@ -4,5 +4,10 @@ com.apple.security.cs.disable-library-validation + + com.apple.security.cs.allow-unsigned-executable-memory + diff --git a/src/dev-utils/platform/osx/entitlements.plist b/src/dev-utils/platform/osx/entitlements.plist index 59274f955f..5ba7ca02e3 100644 --- a/src/dev-utils/platform/osx/entitlements.plist +++ b/src/dev-utils/platform/osx/entitlements.plist @@ -5,5 +5,10 @@ com.apple.security.cs.disable-library-validation + + com.apple.security.cs.allow-unsigned-executable-memory + From f9ddb23804e3a03cfd300fbeb909dc7f276e9eaf Mon Sep 17 00:00:00 2001 From: HanifKoh <76276251+HanifKoh@users.noreply.github.com> Date: Wed, 7 Oct 2026 15:54:53 +0800 Subject: [PATCH 5/5] Keep Each Filament's Device Drying Values When the CLI Merges Filaments (#16157) The device drying options hold several values per filament, as many as the filament preset gives, and a project stores them as the filaments' values one after another. The CLI filament merge wrote them like an option with one value per filament, putting each preset's first value at the filament's own index, so a project with three filaments whose preset gives "1", "0" was exported with 1;1;1;0;1;0 where the GUI writes 1;0;1;0;1;0. The merge now leaves these options out of the per-filament pass and rebuilds them afterwards from every filament's values in slot order. Without a fixed number of values per filament one slot cannot be replaced in place, so the stored values are kept when any slot has no config to rebuild from. --- src/OrcaSlicer.cpp | 11 ++++++++ src/libslic3r/PrintConfig.cpp | 16 +++++++++++ src/libslic3r/PrintConfig.hpp | 5 ++++ .../test_config_variant_expansion.cpp | 27 +++++++++++++++++++ 4 files changed, 59 insertions(+) diff --git a/src/OrcaSlicer.cpp b/src/OrcaSlicer.cpp index a2e4e20374..7104d1bbcb 100644 --- a/src/OrcaSlicer.cpp +++ b/src/OrcaSlicer.cpp @@ -3618,6 +3618,9 @@ int CLI::run(int argc, char **argv) { if (opt_key == "compatible_prints" || opt_key == "compatible_printers" || opt_key == "model_id" || opt_key == "dev_model_name" || opt_key == "filament_settings_id") continue; + // rebuilt from every filament after this loop + if (filament_dev_options.find(opt_key) != filament_dev_options.end()) + continue; ConfigOption *opt = m_print_config.option(opt_key, true); if (opt == nullptr) { // opt_key does not exist in this ConfigBase and it cannot be created, because it is not defined by this->def(). @@ -3681,6 +3684,14 @@ int CLI::run(int argc, char **argv) } } + // The stored values cannot be told apart per filament, so they are kept as they are unless every slot has a config. + std::vector filament_configs(filament_count, nullptr); + for (size_t index = 0; index < load_filaments_config.size(); index++) + if (load_filaments_index[index] >= 1 && load_filaments_index[index] <= filament_count) + filament_configs[load_filaments_index[index] - 1] = &load_filaments_config[index]; + if (std::find(filament_configs.begin(), filament_configs.end(), nullptr) == filament_configs.end()) + set_filament_dev_options(m_print_config, filament_configs); + if (m_print_config.option("filament_extruder_variant")) { std::vector& filament_self_indice = m_print_config.option("filament_self_index", true)->values; int index_size = m_print_config.option("filament_extruder_variant")->size(); diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index c9bd957ab1..59a01bc5ff 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -10822,6 +10822,22 @@ void normalize_filament_values_to_variants(DynamicPrintConfig &config) } } +void set_filament_dev_options(DynamicPrintConfig &config, const std::vector &filament_configs) +{ + for (const std::string &key : filament_dev_options) { + if (std::none_of(filament_configs.begin(), filament_configs.end(), [&key](const DynamicPrintConfig *filament) { return filament->has(key); })) + continue; + const ConfigOption *default_value = print_config_def.get(key)->default_value.get(); + auto *dst = static_cast(config.option(key, true)); + dst->clear(); + for (const DynamicPrintConfig *filament : filament_configs) { + const auto *src = static_cast(filament->has(key) ? filament->option(key) : default_value); + if (!src->empty()) + dst->append(src); + } + } +} + //used for object/region config //use the smallest of multiple to single diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index acf6bd5335..beff23933a 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -928,6 +928,11 @@ void normalize_filament_values_to_variants(DynamicPrintConfig &config); extern std::set filament_dev_options; +// Orca: a filament_dev_options option holds several values per filament, and how many is up to the +// filament preset, so one filament's values cannot be replaced in place. This rebuilds each option from +// filament_configs, one config per filament in slot order, as the filaments' values one after another. +void set_filament_dev_options(DynamicPrintConfig &config, const std::vector &filament_configs); + 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); extern void compute_filament_override_value(const std::string& opt_key, const ConfigOption *opt_old_machine, const ConfigOption *opt_new_machine, const ConfigOption *opt_new_filament, const DynamicPrintConfig& new_full_config, t_config_option_keys& diff_keys, DynamicPrintConfig& filament_overrides, std::vector& f_map_indices); diff --git a/tests/libslic3r/test_config_variant_expansion.cpp b/tests/libslic3r/test_config_variant_expansion.cpp index 240a6e25fa..0df6eb976f 100644 --- a/tests/libslic3r/test_config_variant_expansion.cpp +++ b/tests/libslic3r/test_config_variant_expansion.cpp @@ -799,3 +799,30 @@ TEST_CASE("A per-variant filament option read with a single value gives it to ev config.load_from_ini_string("pressure_advance = 0.021", ForwardCompatibilitySubstitutionRule::Disable); REQUIRE(config.option("pressure_advance")->values == std::vector({0.021, 0.021, 0.021})); } + +// The device drying options hold several values per filament, as many as each filament preset gives. +TEST_CASE("The device drying options are rebuilt as each filament's values in slot order", "[Config]") +{ + DynamicPrintConfig two_values, one_value, no_value; + two_values.option("filament_dev_ams_drying_ams_limitations", true)->values = {"1", "0"}; + two_values.option("filament_dev_ams_drying_temperature", true)->values = {45., 45., 55., 55.}; + one_value.option("filament_dev_ams_drying_ams_limitations", true)->values = {"1"}; + one_value.option("filament_dev_ams_drying_temperature", true)->values = {65., 65., 75., 75.}; + + // values a project stored for three other filaments + DynamicPrintConfig config; + config.option("filament_dev_ams_drying_ams_limitations", true)->values = {"0", "0", "0"}; + config.option("filament_dev_chamber_drying_time", true)->values = {12., 8., 12.}; + + set_filament_dev_options(config, {&two_values, &one_value, &two_values}); + REQUIRE(config.option("filament_dev_ams_drying_ams_limitations")->values == + std::vector({"1", "0", "1", "1", "0"})); + REQUIRE(config.option("filament_dev_ams_drying_temperature")->values == + std::vector({45., 45., 55., 55., 65., 65., 75., 75., 45., 45., 55., 55.})); + // an option no filament defines keeps the stored values + REQUIRE(config.option("filament_dev_chamber_drying_time")->values == std::vector({12., 8., 12.})); + + // a filament without the option takes the option's default + set_filament_dev_options(config, {&two_values, &no_value}); + REQUIRE(config.option("filament_dev_ams_drying_ams_limitations")->values == std::vector({"1", "0", ""})); +}