From af583c7789375a7231e916b20d8c2fecab00b6c4 Mon Sep 17 00:00:00 2001 From: alves Date: Fri, 6 Feb 2026 18:53:25 +0800 Subject: [PATCH 1/9] feature fix api incorrect bug --- src/slic3r/GUI/SSWCP.cpp | 3 ++- src/slic3r/GUI/SSWCP.hpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/SSWCP.cpp b/src/slic3r/GUI/SSWCP.cpp index 65bb463280..16787a0b1e 100644 --- a/src/slic3r/GUI/SSWCP.cpp +++ b/src/slic3r/GUI/SSWCP.cpp @@ -6050,7 +6050,8 @@ std::unordered_set SSWCP::m_project_cmd_list = { }; std::unordered_set SSWCP::m_login_cmd_list = {"sw_UserLogin", "sw_UserLogout", "sw_GetUserLoginState", "sw_SubscribeUserLoginState", - UPDATE_PRIVACY_STATUS, GET_PRIVACY_STATUS}; + UPDATE_PRIVACY_STATUS, GET_PRIVACY_STATUS, + DOWNLOAD_FILE,FILE_VIEW, CANCEL_DOWNLOAD, DOWNLOAD_FILE_AND_OPEN}; std::unordered_set SSWCP::m_machine_manage_cmd_list = { "sw_GetLocalDevices", "sw_AddDevice", "sw_SubscribeLocalDevices", "sw_RenameDevice", "sw_SwitchModel", "sw_DeleteDevices" diff --git a/src/slic3r/GUI/SSWCP.hpp b/src/slic3r/GUI/SSWCP.hpp index 1e63ee53e1..b206f2c8be 100644 --- a/src/slic3r/GUI/SSWCP.hpp +++ b/src/slic3r/GUI/SSWCP.hpp @@ -31,7 +31,7 @@ using tcp = asio::ip::tcp; #define DELETE_CAMERA_TIMELAPSE "sw_DeleteCameraTimelapse" #define GET_DEVICEDATA_STORAGESPACE "sw_GetDeviceDataStorageSpace" #define DOWNLOAD_FILE "sw_DownloadFile" -#define DOWNLOAD_FILE_AND_OPEN "sw_DownloadFileAndOpen" +#define DOWNLOAD_FILE_AND_OPEN "sw_DownLoadFileAndOpen" #define CANCEL_DOWNLOAD "sw_CancelDownload" #define FILE_VIEW "sw_FileView" From 731549ca4f7a37b7cff7b416e73ab8bfb8b355ee Mon Sep 17 00:00:00 2001 From: alves Date: Mon, 9 Feb 2026 16:08:34 +0800 Subject: [PATCH 2/9] feature remove not work code. --- src/slic3r/GUI/GUI_App.cpp | 11 +---------- src/slic3r/Utils/PresetUpdater.cpp | 14 +++----------- 2 files changed, 4 insertions(+), 21 deletions(-) diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 958630d939..7965eb5493 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -6974,16 +6974,7 @@ bool GUI_App::config_wizard_startup() BOOST_LOG_TRIVIAL(info) << "finished run wizard"; return true; - } /*else if (get_app_config()->legacy_datadir()) { - // Looks like user has legacy pre-vendorbundle data directory, - // explain what this is and run the wizard - - MsgDataLegacy dlg; - dlg.ShowModal(); - - run_wizard(ConfigWizard::RR_DATA_LEGACY); - return true; - }*/ + } if (isAgree.empty()) { diff --git a/src/slic3r/Utils/PresetUpdater.cpp b/src/slic3r/Utils/PresetUpdater.cpp index 72c6498964..ba98076b51 100644 --- a/src/slic3r/Utils/PresetUpdater.cpp +++ b/src/slic3r/Utils/PresetUpdater.cpp @@ -1555,12 +1555,9 @@ PresetUpdater::~PresetUpdater() //BBS: refine the preset updater logic void PresetUpdater::sync(std::string http_url, std::string language, std::string plugin_version, PresetBundle *preset_bundle) { - //p->set_download_prefs(GUI::wxGetApp().app_config); + if (!p->enabled_version_check && !p->enabled_config_update) { return; } - // Copy the whole vendors data for use in the background thread - // Unfortunatelly as of C++11, it needs to be copied again - // into the closure (but perhaps the compiler can elide this). VendorMap vendors = preset_bundle ? preset_bundle->vendors : VendorMap{}; p->thread = std::thread([this, vendors, http_url, language, plugin_version]() { @@ -1582,10 +1579,7 @@ void PresetUpdater::sync(std::string http_url, std::string language, std::string return; this->p->sync_plugins(http_url, plugin_version); this->p->sync_printer_config(http_url); - //if (p->cancel) - // return; - //remove the tooltip currently - //this->p->sync_tooltip(http_url, language); + }); } @@ -1603,9 +1597,7 @@ static bool reload_configs_update_gui() // Reload global configuration auto* app_config = GUI::wxGetApp().app_config; - // System profiles should not trigger any substitutions, user profiles may trigger substitutions, but these substitutions - // were already presented to the user on application start up. Just do substitutions now and keep quiet about it. - // However throw on substitutions in system profiles, those shall never happen with system profiles installed over the air. + GUI::wxGetApp().preset_bundle->load_presets(*app_config, ForwardCompatibilitySubstitutionRule::EnableSilentDisableSystem); GUI::wxGetApp().load_current_presets(); GUI::wxGetApp().plater()->set_bed_shape(); From 38819edce4156e08e9457693290225e209aa77b1 Mon Sep 17 00:00:00 2001 From: alves Date: Mon, 9 Feb 2026 18:37:17 +0800 Subject: [PATCH 3/9] feature add dir for store the profile on ota dir. --- src/slic3r/Utils/PresetUpdater.cpp | 54 +++++++----------------------- 1 file changed, 13 insertions(+), 41 deletions(-) diff --git a/src/slic3r/Utils/PresetUpdater.cpp b/src/slic3r/Utils/PresetUpdater.cpp index ba98076b51..935254683b 100644 --- a/src/slic3r/Utils/PresetUpdater.cpp +++ b/src/slic3r/Utils/PresetUpdater.cpp @@ -232,7 +232,11 @@ struct PresetUpdater::priv void sync_resources(std::string http_url, std::map &resources, bool check_patch = false, std::string current_version="", std::string changelog_file=""); void sync_config(bool isAuto_check = true); void sync_update_flutter_resource(bool isAuto_check = true); - bool download_file(const std::string& url, const std::string& target_path, int timeout_sec = 30, bool* cancel_flag = nullptr); + bool download_file(const std::string& url, + const std::string& target_path, + const std::string& extract_path, + int timeout_sec = 30, + bool* cancel_flag = nullptr); void sync_tooltip(std::string http_url, std::string language); void sync_plugins(std::string http_url, std::string plugin_version); void sync_printer_config(std::string http_url); @@ -656,7 +660,8 @@ void PresetUpdater::priv::sync_resources(std::string http_url, std::map 0) { - //if (snapshot) { - // BOOST_LOG_TRIVIAL(info) << "Taking a snapshot..."; - // if (! GUI::Config::take_config_snapshot_cancel_on_error(*GUI::wxGetApp().app_config, Snapshot::SNAPSHOT_DOWNGRADE, "", - // _u8L("Continue and install configuration updates?"))) - // return false; - //} + BOOST_LOG_TRIVIAL(info) << format("[Orca Updater]:Deleting %1% incompatible bundles", updates.incompats.size()); for (auto &incompat : updates.incompats) { @@ -1481,12 +1479,6 @@ bool PresetUpdater::priv::perform_updates(Updates &&updates, bool snapshot) cons incompat.remove(); } } else if (updates.updates.size() > 0) { - //if (snapshot) { - // BOOST_LOG_TRIVIAL(info) << "Taking a snapshot..."; - // if (! GUI::Config::take_config_snapshot_cancel_on_error(*GUI::wxGetApp().app_config, Snapshot::SNAPSHOT_UPGRADE, "", - // _u8L("Continue and install configuration updates?"))) - // return false; - //} BOOST_LOG_TRIVIAL(info) << format("[Orca Updater]:Performing %1% updates", updates.updates.size()); @@ -1495,28 +1487,8 @@ bool PresetUpdater::priv::perform_updates(Updates &&updates, bool snapshot) cons if (update.can_install) update.install(); - //if (!update.is_directory) { - // vendor_path = update.source.parent_path().string(); - // vendor_name = update.vendor; - //} + } - - //if (!vendor_path.empty()) { - // PresetBundle bundle; - // // Throw when parsing invalid configuration. Only valid configuration is supposed to be provided over the air. - // bundle.load_vendor_configs_from_json(vendor_path, vendor_name, PresetBundle::LoadConfigBundleAttribute::LoadSystem, ForwardCompatibilitySubstitutionRule::Disable); - - // BOOST_LOG_TRIVIAL(info) << format("Deleting %1% conflicting presets", bundle.prints.size() + bundle.filaments.size() + bundle.printers.size()); - - // auto preset_remover = [](const Preset& preset) { - // BOOST_LOG_TRIVIAL(info) << '\t' << preset.file; - // fs::remove(preset.file); - // }; - - // for (const auto &preset : bundle.prints) { preset_remover(preset); } - // for (const auto &preset : bundle.filaments) { preset_remover(preset); } - // for (const auto &preset : bundle.printers) { preset_remover(preset); } - //} } return true; From 7c2ec323303bdd09f74b2f32c2e0fb80a40cba3e Mon Sep 17 00:00:00 2001 From: alves Date: Mon, 9 Feb 2026 19:09:45 +0800 Subject: [PATCH 4/9] fix resource remove old file before download. --- src/slic3r/Utils/PresetUpdater.cpp | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/slic3r/Utils/PresetUpdater.cpp b/src/slic3r/Utils/PresetUpdater.cpp index 935254683b..e8d7fb5f0a 100644 --- a/src/slic3r/Utils/PresetUpdater.cpp +++ b/src/slic3r/Utils/PresetUpdater.cpp @@ -808,8 +808,19 @@ void PresetUpdater::priv::sync_update_flutter_resource(bool isAuto_check) return; } - if (currentPresetVersion < remoteVersion) + if (currentPresetVersion < remoteVersion) { + + if (fs::exists(fileName)) + fs::remove(fileName); + + fs::path tmpPath = fileName; + auto dirPath = tmpPath.parent_path() / "profiles/flutter_web"; + + if (fs::exists(dirPath)) + fs::remove_all(dirPath); + download_file(fileUrl, fileName, "../ota/profiles/"); + } else { if (!isAuto_check) { wxCommandEvent* evt = new wxCommandEvent(EVT_NO_WEB_RESOURCE_UPDATE); @@ -917,8 +928,18 @@ void PresetUpdater::priv::sync_config(bool isAuto_check) return; } - if (currentPresetVersion < remoteVersion) + if (currentPresetVersion < remoteVersion) { + if (fs::exists(fileName)) + fs::remove(fileName); + + fs::path tmpPath = fileName; + auto dirPath = tmpPath.parent_path() / "profiles/profiles"; + + if (fs::exists(dirPath)) + fs::remove_all(dirPath); + download_file(fileUrl, fileName, "../ota/profiles/profiles/"); + } else { if (!isAuto_check) { wxCommandEvent* evt = new wxCommandEvent(EVT_NO_PRESET_UPDATE); From cc36dc029570b3841e1cd9f4014ca56e9818f8ca Mon Sep 17 00:00:00 2001 From: alves Date: Wed, 11 Feb 2026 16:30:36 +0800 Subject: [PATCH 5/9] fix sync request lead to question. --- src/slic3r/GUI/GUI_App.cpp | 2 +- src/slic3r/Utils/PresetUpdater.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 7965eb5493..a3c8a56824 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -4893,7 +4893,7 @@ void GUI_App::check_new_version_sf(bool show_tips, bool by_user) BOOST_LOG_TRIVIAL(fatal) << "request server soft update data error:" << errorMsg; } }) - .perform_sync(); + .perform(); } void GUI_App::process_network_msg(std::string dev_id, std::string msg) { diff --git a/src/slic3r/Utils/PresetUpdater.cpp b/src/slic3r/Utils/PresetUpdater.cpp index e8d7fb5f0a..5a63091190 100644 --- a/src/slic3r/Utils/PresetUpdater.cpp +++ b/src/slic3r/Utils/PresetUpdater.cpp @@ -710,7 +710,7 @@ bool PresetUpdater::priv::download_file(const std::string& url, res = true; }) .timeout_max(timeout_sec) - .perform_sync(); + .perform(); if (fs::exists(tmp_path)) { fs::remove(tmp_path); @@ -835,7 +835,7 @@ void PresetUpdater::priv::sync_update_flutter_resource(bool isAuto_check) BOOST_LOG_TRIVIAL(fatal) << "request server flutter update data error:" << errorMsg; } }) - .perform_sync(); + .perform(); } // Orca: sync config update for currect App version void PresetUpdater::priv::sync_config(bool isAuto_check) @@ -954,7 +954,7 @@ void PresetUpdater::priv::sync_config(bool isAuto_check) BOOST_LOG_TRIVIAL(fatal) << "request server preset update data error:" << errorMsg; } }) - .perform_sync(); + .perform(); } void PresetUpdater::priv::sync_tooltip(std::string http_url, std::string language) From fa8aa5682bf92f298d1e1ce6e2186745281ad4f3 Mon Sep 17 00:00:00 2001 From: alves Date: Wed, 25 Feb 2026 15:54:46 +0800 Subject: [PATCH 6/9] feature add flutter version profile version for soft start and log it. --- src/common_func/common_func.cpp | 38 +++++++++++++++++++++++++++++++++ src/common_func/common_func.hpp | 2 ++ src/slic3r/GUI/GUI_App.cpp | 4 +++- 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/src/common_func/common_func.cpp b/src/common_func/common_func.cpp index 410e31568f..3a0ecaef1f 100644 --- a/src/common_func/common_func.cpp +++ b/src/common_func/common_func.cpp @@ -71,6 +71,44 @@ namespace common #endif // _WIN32 return machineId; } + std::string get_profile_version() + { + std::string versionFilePath = ""; +#ifdef _WIN32 + + + + PWSTR pszPath = nullptr; + char* path = new char[MAX_PATH](); + size_t pathLength = 0; + HRESULT hr = SHGetKnownFolderPath(FOLDERID_RoamingAppData, 0, nullptr, &pszPath); + if (SUCCEEDED(hr)) { + wcstombs_s(&pathLength, path, MAX_PATH, pszPath, MAX_PATH); + CoTaskMemFree(pszPath); + } + + std::string filePath = path; + versionFilePath = filePath + "\\" + std::string("Snapmaker_Orca\\system\\Snapmaker.json"); + delete[] path; +#elif __APPLE__ + const char* home_env = getenv("HOME"); + versionFilePath = home_env; + versionFilePath = versionFilePath + "/Library/Application Support/Snapmaker_Orca/system/Snapmaker.json"; +#else + + +#endif + std::ifstream json_file(versionFilePath); + if (!json_file.is_open()) { + std::ifstream json_file(versionFilePath); + return ""; + } + nlohmann::json json_data; + json_file >> json_data; + std::string str_version = json_data.value("version", ""); + + return str_version; + } std::string get_flutter_version() { diff --git a/src/common_func/common_func.hpp b/src/common_func/common_func.hpp index 3711d18b86..a9b8f737d3 100644 --- a/src/common_func/common_func.hpp +++ b/src/common_func/common_func.hpp @@ -23,6 +23,8 @@ namespace common std::string get_flutter_version(); + std::string get_profile_version(); + std::string getMachineId(); std::string getLocalArea(); diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index a3c8a56824..51fed40c67 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -1082,7 +1082,9 @@ GUI_App::GUI_App() m_page_http_server.setPort(PAGE_HTTP_PORT); m_page_http_server.set_request_handler(HttpServer::web_server_handle_request); m_page_http_server.start(); - + BOOST_LOG_TRIVIAL(info) << "[Flutter] Version:"< Date: Wed, 25 Feb 2026 19:15:59 +0800 Subject: [PATCH 7/9] fix data invalid bug. --- src/slic3r/Utils/PresetUpdater.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/slic3r/Utils/PresetUpdater.cpp b/src/slic3r/Utils/PresetUpdater.cpp index 5a63091190..9ba542d878 100644 --- a/src/slic3r/Utils/PresetUpdater.cpp +++ b/src/slic3r/Utils/PresetUpdater.cpp @@ -681,7 +681,7 @@ bool PresetUpdater::priv::download_file(const std::string& url, .on_error([&url](std::string body, std::string error, unsigned http_status) { BOOST_LOG_TRIVIAL(error) << "Download failed: " << url << ", HTTP status: " << http_status << ", error: " << error; }) - .on_complete([&](std::string body, unsigned http_status) { + .on_complete([&, target_path, extract_path, tmp_path](std::string body, unsigned http_status) { if (http_status != 200) { BOOST_LOG_TRIVIAL(error) << "Download failed with HTTP status: " << http_status; return; @@ -707,7 +707,7 @@ bool PresetUpdater::priv::download_file(const std::string& url, } extract_file(target_path, extract_path); BOOST_LOG_TRIVIAL(info) << "Download completed: " << target_path; - res = true; + }) .timeout_max(timeout_sec) .perform(); From 70634275ef9ff2c6e8edda9d8b432c0712d7dfa0 Mon Sep 17 00:00:00 2001 From: alves Date: Wed, 25 Feb 2026 19:36:25 +0800 Subject: [PATCH 8/9] fix mac import flutter resource failed bug. --- src/slic3r/Utils/PresetUpdater.cpp | 53 ++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 17 deletions(-) diff --git a/src/slic3r/Utils/PresetUpdater.cpp b/src/slic3r/Utils/PresetUpdater.cpp index 9ba542d878..0b8459bf6e 100644 --- a/src/slic3r/Utils/PresetUpdater.cpp +++ b/src/slic3r/Utils/PresetUpdater.cpp @@ -324,7 +324,7 @@ bool PresetUpdater::priv::extract_file(const fs::path &source_path, const fs::pa { bool res = true; std::string file_path = source_path.string(); - std::string parent_path = (!dest_path.empty() ? dest_path : source_path.parent_path()).string(); + fs::path parent_path = !dest_path.empty() ? dest_path : source_path.parent_path(); mz_zip_archive archive; mz_zip_zero_struct(&archive); @@ -335,6 +335,7 @@ bool PresetUpdater::priv::extract_file(const fs::path &source_path, const fs::pa } mz_uint num_entries = mz_zip_reader_get_num_files(&archive); + fs::path base_path = parent_path.lexically_normal(); mz_zip_archive_file_stat stat; // we first loop the entries to read from the archive the .amf file only, in order to extract the version from it @@ -342,30 +343,48 @@ bool PresetUpdater::priv::extract_file(const fs::path &source_path, const fs::pa { if (mz_zip_reader_file_stat(&archive, i, &stat)) { - std::string dest_file = parent_path+"/"+stat.m_filename; - if (stat.m_is_directory) { - fs::path dest_path(dest_file); - if (!fs::exists(dest_path)) - fs::create_directories(dest_path); - continue; + fs::path full_dest = (base_path / stat.m_filename).lexically_normal(); + // Reject paths that escape base (e.g. ".." in zip entry) + std::string rel_str = full_dest.lexically_relative(base_path).generic_string(); + if (rel_str.empty() || rel_str.find("..") == 0) { + BOOST_LOG_TRIVIAL(warning) << "[Orca Updater]Unzip: skip invalid path "< Date: Thu, 26 Feb 2026 18:14:20 +0800 Subject: [PATCH 9/9] fix build failed bug . --- src/libslic3r/Config.hpp | 14 ++------------ src/libslic3r/GCodeWriter.hpp | 6 +----- src/libslic3r/Print.hpp | 7 +------ 3 files changed, 4 insertions(+), 23 deletions(-) diff --git a/src/libslic3r/Config.hpp b/src/libslic3r/Config.hpp index 842779f427..6c1f3c5b22 100644 --- a/src/libslic3r/Config.hpp +++ b/src/libslic3r/Config.hpp @@ -422,17 +422,12 @@ public: // This function is useful to split values from multiple extrder / filament settings into separate configurations. void set_at(const ConfigOption *rhs, size_t i, size_t j) override { - // SM Orca: Debug logging - BOOST_LOG_TRIVIAL(error) << "ConfigOptionVector::set_at: START - this->values.size()=" << this->values.size() - << ", i=" << i << ", j=" << j; - // It is expected that the vector value has at least one value, which is the default, if not overwritten. assert(! this->values.empty()); if (this->values.size() <= i) { // Resize this vector, fill in the new vector fields with the copy of the first field. T v = this->values.front(); this->values.resize(i + 1, v); - BOOST_LOG_TRIVIAL(error) << "ConfigOptionVector::set_at: resized to " << this->values.size(); } if (rhs->type() == this->type()) { @@ -449,8 +444,7 @@ public: before_ss << this->values[k]; } before_ss << "]"; - BOOST_LOG_TRIVIAL(error) << "ConfigOptionVector::set_at: before this->values=" << before_ss.str(); - + // Log other vector std::stringstream other_ss; other_ss << "["; @@ -459,8 +453,6 @@ public: other_ss << other->values[k]; } other_ss << "]"; - BOOST_LOG_TRIVIAL(error) << "ConfigOptionVector::set_at: other->values=" << other_ss.str() - << ", other->get_at(" << j << ")=" << other->get_at(j); this->values[i] = other->get_at(j); @@ -472,12 +464,10 @@ public: after_ss << this->values[k]; } after_ss << "]"; - BOOST_LOG_TRIVIAL(error) << "ConfigOptionVector::set_at: after this->values[" << i << "]=" << this->values[i] - << ", full=" << after_ss.str(); + } else if (rhs->type() == this->scalar_type()) { this->values[i] = static_cast*>(rhs)->value; - BOOST_LOG_TRIVIAL(error) << "ConfigOptionVector::set_at: assigned scalar value=" << this->values[i]; } else throw ConfigurationError("ConfigOptionVector::set_at(): Assigning an incompatible type"); } diff --git a/src/libslic3r/GCodeWriter.hpp b/src/libslic3r/GCodeWriter.hpp index cdb5070e40..67e7e09621 100644 --- a/src/libslic3r/GCodeWriter.hpp +++ b/src/libslic3r/GCodeWriter.hpp @@ -136,11 +136,7 @@ public: // 映射表为空或没有该耗材的映射,使用默认模运算映射 physical_extruder_id = filament_idx % m_physical_extruder_count; } - // SM Orca: 日志 - 映射查询 - BOOST_LOG_TRIVIAL(info) << "GCodeWriter::get_physical_extruder: filament_id=" << filament_idx - << " -> physical_extruder_id=" << physical_extruder_id - << " (map_size=" << m_filament_extruder_map.size() << ", physical_count=" << m_physical_extruder_count << ")" - << (it != m_filament_extruder_map.end() ? " [from_map]" : " [default_mod]"); + return physical_extruder_id; } diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index bb394865f7..2a5e8c9553 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -907,16 +907,11 @@ public: if (physical_count == 0) { // 防止除零,使用安全的默认值 physical_extruder_id = 0; - BOOST_LOG_TRIVIAL(warning) << "Print::get_physical_extruder: nozzle_diameter is empty! Using default physical_extruder=0"; + } else { physical_extruder_id = filament_idx % physical_count; } } - // SM Orca: 日志 - 映射查询 - BOOST_LOG_TRIVIAL(info) << "Print::get_physical_extruder: filament_id=" << filament_idx - << " -> physical_extruder_id=" << physical_extruder_id - << " (map_size=" << m_filament_extruder_map.size() << ")" - << (it != m_filament_extruder_map.end() ? " [from_map]" : " [default_mod]"); return physical_extruder_id; } // SM Orca: Initialize filament-to-physical-extruder mapping table