mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-05-17 00:26:14 +03:00
Improved SnapmakerPrinterAgent filament sync (#13265)
* Improved SnapmakerPrinterAgent filament sync * Update src/slic3r/Utils/SnapmakerPrinterAgent.cpp Fixed missing assignment * fixed issues ---------
This commit is contained in:
@@ -19,6 +19,50 @@ T safe_at(const std::vector<T>& vec, int index, const T& fallback)
|
||||
return (index >= 0 && index < static_cast<int>(vec.size())) ? vec[index] : fallback;
|
||||
}
|
||||
|
||||
std::string find_closest_color_preset_by_vendor_and_type(const PresetCollection& filaments,
|
||||
const std::string& vendor_name,
|
||||
const std::string& filament_type,
|
||||
const std::string& color_rgba)
|
||||
{
|
||||
std::string best_match_id = "";
|
||||
int best_color_distance = 0xffffffff;
|
||||
|
||||
for (const auto& p : filaments.get_presets()) {
|
||||
if (p.is_visible && p.is_compatible &&
|
||||
// Filament profile must be detached from parent to be considered for matching
|
||||
filaments.get_preset_base(p) == &p && p.config.opt_string("filament_vendor", 0u) == vendor_name &&
|
||||
p.config.opt_string("filament_type", 0u) == filament_type) {
|
||||
// The printer returns RGBA in the format RRGGBBAA, but profiles store color as #RRGGBB,
|
||||
// so we must remove # and ignore alpha channel for distance calculation
|
||||
unsigned int target_color_value = std::stoul(color_rgba.substr(0, color_rgba.length() - 2), nullptr, 16);
|
||||
|
||||
std::string p_color = p.config.opt_string("default_filament_colour", 0u);
|
||||
unsigned int p_color_value;
|
||||
if (!p_color.empty()) {
|
||||
unsigned int hash_pos = p_color.find("#");
|
||||
p_color_value = std::stoul(p_color.substr(hash_pos != std::string::npos ? hash_pos + 1 : 0), nullptr, 16);
|
||||
} else {
|
||||
// Default to black if no color specified in profile. Assume other profiles might be a closer color match.
|
||||
// Could be a problem if the target color is also black and there exist a specific profile for that type, vendor and color
|
||||
// combination.
|
||||
p_color_value = 0;
|
||||
}
|
||||
|
||||
// Calculate Euclidean color distance in RGB space
|
||||
int dr = ((target_color_value & 0xff) - (p_color_value & 0xff));
|
||||
int dg = (((target_color_value >> 8) & 0xff) - ((p_color_value >> 8) & 0xff));
|
||||
int db = (((target_color_value >> 16) & 0xff) - ((p_color_value >> 16) & 0xff));
|
||||
unsigned int distance = dr * dr + dg * dg + db * db;
|
||||
|
||||
if (distance < best_color_distance) {
|
||||
best_color_distance = distance;
|
||||
best_match_id = p.filament_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
return best_match_id;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
SnapmakerPrinterAgent::SnapmakerPrinterAgent(std::string log_dir) : MoonrakerPrinterAgent(std::move(log_dir)) {}
|
||||
@@ -113,6 +157,7 @@ bool SnapmakerPrinterAgent::fetch_filament_info(std::string dev_id)
|
||||
auto filament_type = ptc.value("filament_type", std::vector<std::string>{});
|
||||
auto filament_sub_type = ptc.value("filament_sub_type", std::vector<std::string>{});
|
||||
auto filament_color = ptc.value("filament_color_rgba", std::vector<std::string>{});
|
||||
auto filament_vendor = ptc.value("filament_vendor", std::vector<std::string>{});
|
||||
|
||||
const int slot_count = static_cast<int>(filament_exist.size());
|
||||
if (slot_count == 0) {
|
||||
@@ -141,12 +186,27 @@ bool SnapmakerPrinterAgent::fetch_filament_info(std::string dev_id)
|
||||
if (tray.has_filament) {
|
||||
tray.tray_type = combine_filament_type(safe_at(filament_type, i, empty_str),
|
||||
safe_at(filament_sub_type, i, empty_str));
|
||||
auto* bundle = GUI::wxGetApp().preset_bundle;
|
||||
tray.tray_info_idx = bundle
|
||||
? bundle->filaments.filament_id_by_type(tray.tray_type)
|
||||
: map_filament_type_to_generic_id(tray.tray_type);
|
||||
tray.tray_color = safe_at(filament_color, i, default_color);
|
||||
|
||||
auto* bundle = GUI::wxGetApp().preset_bundle;
|
||||
// Try to find a matching preset for this filament based on vendor, type and color.
|
||||
// If not found, default to traditional search by type only or generic type mapping.
|
||||
if (bundle) {
|
||||
std::string vendor = safe_at(filament_vendor, i, empty_str);
|
||||
std::string filament_id = find_closest_color_preset_by_vendor_and_type(bundle->filaments, vendor, tray.tray_type,
|
||||
tray.tray_color);
|
||||
|
||||
if (!filament_id.empty()) {
|
||||
tray.tray_info_idx = filament_id;
|
||||
BOOST_LOG_TRIVIAL(warning) << "Filament sync: Found manufacturer-specific profile for slot " << i << ": "
|
||||
<< filament_id;
|
||||
} else {
|
||||
tray.tray_info_idx = bundle->filaments.filament_id_by_type(tray.tray_type);
|
||||
}
|
||||
} else {
|
||||
tray.tray_info_idx = map_filament_type_to_generic_id(tray.tray_type);
|
||||
}
|
||||
|
||||
// Extract NFC temperature data if available
|
||||
if (nfc_info.is_array() && i < static_cast<int>(nfc_info.size()) && nfc_info[i].is_object()) {
|
||||
auto& nfc_slot = nfc_info[i];
|
||||
|
||||
Reference in New Issue
Block a user