From 0feca8d4429c8e7e51f924ed9493ab47c3367e34 Mon Sep 17 00:00:00 2001 From: SoftFever Date: Fri, 17 Jul 2026 02:49:45 +0800 Subject: [PATCH] Port accessory firmware versions, cold-pull state and filament checks --- src/slic3r/GUI/DeviceCore/DevCalib.cpp | 14 +++- src/slic3r/GUI/DeviceManager.cpp | 103 +++++++++++++++++++++++++ src/slic3r/GUI/DeviceManager.hpp | 20 +++++ 3 files changed, 135 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/DeviceCore/DevCalib.cpp b/src/slic3r/GUI/DeviceCore/DevCalib.cpp index fdbcdc9728..cf7ee1d90e 100644 --- a/src/slic3r/GUI/DeviceCore/DevCalib.cpp +++ b/src/slic3r/GUI/DeviceCore/DevCalib.cpp @@ -267,8 +267,18 @@ void DevCalib::ExtrusionCalibGetResultParse(const json &jj) auto ams_id = f.value("ams_id", 0); auto slot_id = f.value("slot_id", 0); if(f.contains("tray_id")){ - // Orca: no GetTrayIdByAmsSlotId in Orca DevFilaSystem; standard AMS tray formula - f["tray_id"] = ams_id * 4 + slot_id; + // Orca: Orca's DevFilaSystem has no GetTrayIdByAmsSlotId; mirror its + // semantics via a reverse lookup over GetTrayIndexMap() (correct for + // non-4-slot AMS layouts, unlike a fixed ams_id*4+slot_id formula). + int mapped_tray_id = -1; + const auto tray_ams_slot_map = GetOwner()->GetFilaSystem()->GetTrayIndexMap(); + for (const auto& item : tray_ams_slot_map) { + if (item.second.first == ams_id && item.second.second == slot_id) { + mapped_tray_id = item.first; + break; + } + } + f["tray_id"] = mapped_tray_id; } } } diff --git a/src/slic3r/GUI/DeviceManager.cpp b/src/slic3r/GUI/DeviceManager.cpp index 2942b9cf27..f2a808c189 100644 --- a/src/slic3r/GUI/DeviceManager.cpp +++ b/src/slic3r/GUI/DeviceManager.cpp @@ -74,6 +74,46 @@ int get_tray_id_by_ams_id_and_slot_id(int ams_id, int slot_id) } } +// Orca: REF-additive stringing-prone filament chain, now ported (post-review). +// Consumers arrive in resync clusters 5 (PrintOptionsDialog) and 7 (SelectMachine). +namespace { + +// Stringing-prone filament IDs per nozzle-diameter bucket. +// Mirrors the printer firmware tables (see g_leak_pron_idx_for_0_4 / _0_6_0_8). +// Keep these in sync with firmware when new stringing-prone filaments are added. +const std::unordered_set g_stringing_prone_for_0_4 = { + "GFA11", // PLA Aero + "GFU90", // TPU 90A + "GFU00", // TPU 95A HF + "GFU02", // Generic TPU for AMS + "GFU98", // TPU for AMS +}; + +const std::unordered_set g_stringing_prone_for_0_6_0_8 = { + "GFA11", // PLA Aero + "GFU00", // TPU 95A HF +}; + +// Pick the right table for the given nozzle diameter; returns nullptr if the +// nozzle bucket has no entries (e.g. 0.2 mm) or the diameter is invalid. +const std::unordered_set* pick_stringing_set(float nozzle_diameter) +{ + if (!(nozzle_diameter > 0.f)) return nullptr; + if (nozzle_diameter < 0.3f) return nullptr; // 0.2 nozzle: empty + if (nozzle_diameter < 0.5f) return &g_stringing_prone_for_0_4; + return &g_stringing_prone_for_0_6_0_8; // 0.6 / 0.8 nozzles +} + +} // namespace + +bool Slic3r::is_stringing_prone_filament(const std::string& filament_id, float nozzle_diameter) +{ + if (filament_id.empty()) return false; + const auto* set = pick_stringing_set(nozzle_diameter); + if (!set) return false; + return set->count(filament_id) > 0; +} + wxString Slic3r::get_stage_string(int stage) { switch(stage) { @@ -719,6 +759,35 @@ std::string MachineObject::get_filament_display_type(const std::string& ams_id, return this->get_tray(ams_id, tray_id).get_display_filament_type(); } +// Orca: REF-additive, now ported (post-review). Adapted to Orca's kept fila model: +// filament id resolved via MachineObject::get_filament_id (tray setting_id / tray_info_idx). +bool MachineObject::any_loaded_filament_is_stringing_prone() const +{ + if (print_job_filament_mapping.empty()) return false; + + std::vector nozzle_diameters; + if (m_extder_system) { + for (const auto& ext : m_extder_system->GetExtruders()) { + const float d = ext.GetNozzleDiameter(); + if (d > 0.f) nozzle_diameters.push_back(d); + } + } + if (nozzle_diameters.empty()) return false; + + for (uint16_t v : print_job_filament_mapping) { + if (v == 0xFFFF) continue; + const int ams_id = (v >> 8) & 0xFF; + const int slot_id = v & 0xFF; + const std::string fid = this->get_filament_id(std::to_string(ams_id), std::to_string(slot_id)); + if (fid.empty()) continue; + for (float d : nozzle_diameters) { + if (Slic3r::is_stringing_prone_filament(fid, d)) + return true; + } + } + return false; +} + void MachineObject::_parse_ams_status(int ams_status) { ams_status_sub = ams_status & 0xFF; @@ -737,6 +806,8 @@ void MachineObject::_parse_ams_status(int ams_status) ams_status_main = AmsStatusMain::AMS_STATUS_MAIN_SELF_CHECK; } else if (ams_status_main_int == (int) AmsStatusMain::AMS_STATUS_MAIN_DEBUG) { ams_status_main = AmsStatusMain::AMS_STATUS_MAIN_DEBUG; + } else if (ams_status_main_int == (int) AmsStatusMain::AMS_STATUS_MAIN_COLD_PULL) { // Orca: REF-additive, now ported (post-review) + ams_status_main = AmsStatusMain::AMS_STATUS_MAIN_COLD_PULL; } else { ams_status_main = AmsStatusMain::AMS_STATUS_MAIN_UNKNOWN; } @@ -888,6 +959,10 @@ void MachineObject::clear_version_info() laser_version_info = DevFirmwareVersionInfo(); cutting_module_version_info = DevFirmwareVersionInfo(); extinguish_version_info = DevFirmwareVersionInfo(); + // Orca: REF-additive accessory firmware versions, now ported (post-review) + rotary_version_info = DevFirmwareVersionInfo(); + exhaustfan_version_info = DevFirmwareVersionInfo(); + amshub_version_info = DevFirmwareVersionInfo(); filatrack_version_info = DevFirmwareVersionInfo(); module_vers.clear(); // Drop cached rack-hotend (WTM) firmware alongside the module list. @@ -905,11 +980,17 @@ void MachineObject::store_version_info(const DevFirmwareVersionInfo& info) cutting_module_version_info = info; } else if (info.isExtinguishSystem()) { extinguish_version_info = info; + } else if (info.isRotary()) { // Orca: REF-additive, now ported (post-review) + rotary_version_info = info; } else if (info.isWTM()) { // Route rack-hotend / extruder-nozzle firmware into the nozzle system so // the rack upgrade UI can read per-nozzle versions. isWTM() is false for every non-rack // printer's modules, so this branch never fires outside H2C. m_nozzle_system->AddFirmwareInfoWTM(info); + } else if (info.isExhaustFan()) { // Orca: REF-additive, now ported (post-review) + exhaustfan_version_info = info; + } else if (info.isHmshub()) { // Orca: REF-additive, now ported (post-review) + amshub_version_info = info; } else if (info.isFilaTrackSwitch()) { filatrack_version_info = info; } @@ -3283,6 +3364,7 @@ int MachineObject::parse_json(std::string tunnel, std::string payload, bool key_ int flag3 = jj["flag3"].get(); is_support_filament_setting_inprinting = get_flag_bits(flag3, 3); is_enable_ams_np = get_flag_bits(flag3, 9); + is_support_filament_32_colors = get_flag_bits(flag3, 17); // Orca: REF-additive, now ported (post-review) } } if (!key_field_only) { @@ -5076,6 +5158,16 @@ bool MachineObject::check_enable_np(const json& print) const return false; } +// Orca: REF-additive, now ported (post-review). Consumer is the SelectMachine +// color-quantity send gate (arrives in cluster 7). 0 = no explicit upper bound. +int MachineObject::get_max_filament_color_count() const +{ + if (is_support_filament_32_colors) return 32; + if (is_enable_ams_np && !is_series_x()) return 20; + if (!is_series_x() && !is_series_o()) return 16; + return 0; +} + void MachineObject::parse_new_info(json print) { is_enable_np = check_enable_np(print); @@ -5238,6 +5330,17 @@ void MachineObject::parse_new_info(json print) } } + /* Orca: REF-additive, now ported (post-review). Per-filament-index AMS slot mapping + (task-level state). Consumers arrive in clusters 5/7. */ + if (print.contains("mapping") && print["mapping"].is_array()) { + std::vector new_mapping; + new_mapping.reserve(print["mapping"].size()); + for (const auto& v : print["mapping"]) { + new_mapping.push_back(static_cast(v.get())); + } + print_job_filament_mapping = std::move(new_mapping); + } + /*aux*/ std::string aux = print["aux"].get(); diff --git a/src/slic3r/GUI/DeviceManager.hpp b/src/slic3r/GUI/DeviceManager.hpp index 272d3e8377..234a412dad 100644 --- a/src/slic3r/GUI/DeviceManager.hpp +++ b/src/slic3r/GUI/DeviceManager.hpp @@ -96,6 +96,11 @@ class DevStorage; class DevUpgrade; // Orca: adopt DeviceCore split struct DevPrintTaskRatingInfo; +// Orca: REF-additive, now ported (post-review). Returns true when filament_id (e.g. "GFA11", +// "GFU00") is on the stringing-prone list for the given nozzle diameter (mm), bucketed per +// nozzle size to mirror the printer firmware. +bool is_stringing_prone_filament(const std::string& filament_id, float nozzle_diameter); + class MachineObject { @@ -398,6 +403,10 @@ public: DevFirmwareVersionInfo laser_version_info; DevFirmwareVersionInfo cutting_module_version_info; DevFirmwareVersionInfo extinguish_version_info; + // Orca: REF-additive accessory firmware versions, now ported (post-review) + DevFirmwareVersionInfo rotary_version_info; + DevFirmwareVersionInfo exhaustfan_version_info; + DevFirmwareVersionInfo amshub_version_info; DevFirmwareVersionInfo filatrack_version_info; std::map module_vers; std::map new_ver_list; @@ -695,6 +704,12 @@ public: boost::thread* get_slice_info_thread { nullptr }; boost::thread* get_model_task_thread { nullptr }; + // Orca: REF-additive, now ported (post-review). Per-filament-index AMS slot mapping + // reported by the printer in print.mapping. Up to 32 entries, each value packs + // (ams_id << 8) | slot_id; 0xFFFF means unused. + std::vector print_job_filament_mapping; + bool any_loaded_filament_is_stringing_prone() const; + /* job attr */ int jobState_ = 0; @@ -912,6 +927,11 @@ public: /*for more extruder*/ bool is_enable_np{ false }; bool is_enable_ams_np{ false }; + bool is_support_filament_32_colors{ false }; // Orca: REF-additive, now ported (post-review) + + // Orca: REF-additive, now ported (post-review). Max filament color count for the send + // gate; returns 0 when there is no explicit upper bound. + int get_max_filament_color_count() const; /** * Virtual Tray (vt_slot) - External/manual filament loading slots.