feat(moonraker): Bridge-Filament-Hint (tray_info_idx + vendor) respektieren
KX-Bridge sendet bereits konkrete Filament-IDs und Vendor-Hints im AMS-JSON, aber MoonrakerPrinterAgent überschreibt sie unbedingt mit filament_id_by_type() → erstes sichtbares Preset alphabetisch gewinnt. Patch: - AmsTrayData um filament_vendor erweitert - Liest tray_info_idx + filament_vendor aus Bridge-JSON - Wenn tray_info_idx leer + vendor vorhanden: Vendor+Type+Color-Match (gleiche Logik wie SnapmakerPrinterAgent) - Sonst: alter filament_id_by_type-Fallback (unverändertes Verhalten) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -37,6 +37,48 @@ struct WsEndpoint
|
||||
bool secure = false;
|
||||
};
|
||||
|
||||
// Find best-matching visible filament preset by vendor + type + color.
|
||||
// Same algorithm as SnapmakerPrinterAgent's helper. Allows the KX-Bridge
|
||||
// (which knows the user's slot brand selection) to direct OrcaSlicer to a
|
||||
// specific preset instead of falling back to "first sichtbares PETG" lookup.
|
||||
std::string find_closest_color_preset_by_vendor_and_type(const Slic3r::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;
|
||||
if (vendor_name.empty() || filament_type.empty()) return best_match_id;
|
||||
|
||||
auto parse_color = [](const std::string& s) -> unsigned int {
|
||||
if (s.empty()) return 0;
|
||||
std::string h = s;
|
||||
if (!h.empty() && h.front() == '#') h.erase(0, 1);
|
||||
if (h.size() >= 8) h = h.substr(0, 6); // strip alpha
|
||||
try { return std::stoul(h, nullptr, 16); } catch (...) { return 0; }
|
||||
};
|
||||
|
||||
unsigned int target = parse_color(color_rgba);
|
||||
|
||||
for (const auto& p : filaments.get_presets()) {
|
||||
if (!(p.is_visible && p.is_compatible)) continue;
|
||||
if (filaments.get_preset_base(p) != &p) continue;
|
||||
if (p.config.opt_string("filament_vendor", 0u) != vendor_name) continue;
|
||||
if (p.config.opt_string("filament_type", 0u) != filament_type) continue;
|
||||
|
||||
unsigned int pc = parse_color(p.config.opt_string("default_filament_colour", 0u));
|
||||
int dr = ((target ) & 0xff) - ((pc ) & 0xff);
|
||||
int dg = ((target >> 8) & 0xff) - ((pc >> 8) & 0xff);
|
||||
int db = ((target >> 16) & 0xff) - ((pc >> 16) & 0xff);
|
||||
unsigned int distance = dr * dr + dg * dg + db * db;
|
||||
if (distance < (unsigned int)best_color_distance) {
|
||||
best_color_distance = (int)distance;
|
||||
best_match_id = p.filament_id;
|
||||
}
|
||||
}
|
||||
return best_match_id;
|
||||
}
|
||||
|
||||
bool parse_ws_endpoint(const std::string& base_url, WsEndpoint& endpoint)
|
||||
{
|
||||
if (base_url.empty()) {
|
||||
@@ -806,10 +848,22 @@ bool MoonrakerPrinterAgent::fetch_moonraker_filament_data(std::vector<AmsTrayDat
|
||||
tray.nozzle_temp = safe_json_int(lane_obj, "nozzle_temp");
|
||||
tray.has_filament = !tray.tray_type.empty();
|
||||
has_populated_lane = has_populated_lane || tray.has_filament;
|
||||
// Bridge-Hints: tray_info_idx (konkrete Filament-ID) + filament_vendor.
|
||||
// KX-Bridge sendet beide, wenn der User in der Bridge-UI ein konkretes
|
||||
// Slot-Profil gewählt hat (Polymaker/eSUN/…).
|
||||
tray.tray_info_idx = safe_json_string(lane_obj, "tray_info_idx");
|
||||
tray.filament_vendor = safe_json_string(lane_obj, "filament_vendor");
|
||||
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);
|
||||
if (tray.tray_info_idx.empty() && bundle && !tray.filament_vendor.empty()) {
|
||||
std::string mid = find_closest_color_preset_by_vendor_and_type(
|
||||
bundle->filaments, tray.filament_vendor, tray.tray_type, tray.tray_color);
|
||||
if (!mid.empty()) tray.tray_info_idx = mid;
|
||||
}
|
||||
if (tray.tray_info_idx.empty()) {
|
||||
tray.tray_info_idx = bundle
|
||||
? bundle->filaments.filament_id_by_type(tray.tray_type)
|
||||
: map_filament_type_to_generic_id(tray.tray_type);
|
||||
}
|
||||
|
||||
max_lane_index = std::max(max_lane_index, lane_index);
|
||||
trays.push_back(tray);
|
||||
|
||||
@@ -94,6 +94,7 @@ protected:
|
||||
std::string tray_type; // Material type (e.g., "PLA", "ASA")
|
||||
std::string tray_color; // Raw color (#RRGGBB, 0xRRGGBB, or RRGGBBAA)
|
||||
std::string tray_info_idx; // Setting ID (optional)
|
||||
std::string filament_vendor; // Vendor hint from bridge (optional, KX-Bridge sendet das)
|
||||
int bed_temp = 0; // Optional
|
||||
int nozzle_temp = 0; // Optional
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user