fix(filament): PLA-Varianten (PLA+, Silk, Matte) korrekt erkennen und an OrcaSlicer übermitteln
All checks were successful
Nightly Build / build (push) Successful in 12m36s
All checks were successful
Nightly Build / build (push) Successful in 12m36s
- _normalize_material() normalisiert Drucker-Typen auf kanonische Keys - _TRAY_INFO_IDX erweitert um Silk/Matte/CF-Varianten und Schreibweisen - _default_filament_name() mappt Varianten auf korrekte Generic-Profile - Filament-Dropdown zeigt Hersteller-Profile der jeweiligen Variante - Material-Buttons: PLA+, PLA Silk, PLA Matte hinzugefügt Fixes #82
This commit is contained in:
@@ -1,4 +1,7 @@
|
||||
## Changes in this build
|
||||
|
||||
- Fix: wrong filament slot used in multicolor prints when T0 is unused — AMS box mapping now includes placeholder entries for all paint indices so the printer correctly matches T1/T2/T3 tool changes to the right slots (Issue #78)
|
||||
- Fix: Spoolman spool-slot assignment now persisted to config.ini and restored on bridge restart
|
||||
- Fix: Spoolman spool-slot assignment persistence was silently broken (NameError on config_loader swallowed by bare except) — now uses correct module reference and logs failures; per-printer isolation added so multi-printer setups no longer overwrite each other (Issue #80, PR #83 by @walterioo)
|
||||
- Fix: spool dropdown in print dialog showed "[object Object]" instead of vendor name (PR #83)
|
||||
- Fix: gate_spool_id in MMU object now populated from per-printer slot map instead of hardcoded -1 (PR #83)
|
||||
- Fix: PLA variants (PLA+, PLA Silk, PLA Matte) now recognized as their material family — correct tray_info_idx sent to printer, correct Generic profile synced to OrcaSlicer, and vendor profiles for the variant shown in slot editor dropdown (Issue #82)
|
||||
- UI: PLA+, PLA Silk and PLA Matte buttons added to slot material selector
|
||||
|
||||
@@ -1855,23 +1855,55 @@ class KobraXBridge:
|
||||
# `compatible_printers: []` (= mit allen Druckern kompatibel).
|
||||
_TRAY_INFO_IDX = {
|
||||
# Anycubic-eigene Kobra-X-Profile
|
||||
"PLA": "GFPLA",
|
||||
"PLA+": "GFPLA+",
|
||||
"PLA SILK": "GFPLA Silk",
|
||||
"PETG": "GFPETG",
|
||||
"ABS": "GFABS",
|
||||
"ASA": "GFASA",
|
||||
"TPU": "GFTPU 95A",
|
||||
"PVA": "GFPVA",
|
||||
"PLA": "GFPLA",
|
||||
"PLA+": "GFPLA+",
|
||||
"PLA SILK": "GFPLA Silk",
|
||||
"PLA-SILK": "GFPLA Silk",
|
||||
"PLASILK": "GFPLA Silk",
|
||||
"SILK PLA": "GFPLA Silk",
|
||||
"PLA MATTE": "GFPLA",
|
||||
"PLA-MATTE": "GFPLA",
|
||||
"PLA MARBLE": "GFPLA",
|
||||
"PLA WOOD": "GFPLA",
|
||||
"PETG": "GFPETG",
|
||||
"PETG+": "GFPETG",
|
||||
"ABS": "GFABS",
|
||||
"ASA": "GFASA",
|
||||
"TPU": "GFTPU 95A",
|
||||
"TPE": "GFTPU 95A",
|
||||
"PVA": "GFPVA",
|
||||
# Kein Anycubic-Kobra-X-Profil → Library-Fallback
|
||||
"PLA-CF": "OGFL98",
|
||||
"PETG-CF": "OGFG98",
|
||||
"PA": "OGFN99",
|
||||
"PA-CF": "OGFN98",
|
||||
"PC": "OGFC99",
|
||||
"HIPS": "OGFS98",
|
||||
"PLA-CF": "OGFL98",
|
||||
"PLA CF": "OGFL98",
|
||||
"PETG-CF": "OGFG98",
|
||||
"PETG CF": "OGFG98",
|
||||
"PA": "OGFN99",
|
||||
"PA-CF": "OGFN98",
|
||||
"PA CF": "OGFN98",
|
||||
"PC": "OGFC99",
|
||||
"HIPS": "OGFS98",
|
||||
}
|
||||
|
||||
# Normalisiert Material-Typ-Strings auf den kanonischen Key für _TRAY_INFO_IDX
|
||||
# und _default_filament_name. PLA-Varianten die nicht exakt matchen fallen
|
||||
# auf ihre Basisfamilie zurück (PLA+ → PLA+, PLA Matte → PLA, etc.).
|
||||
@staticmethod
|
||||
def _normalize_material(mat: str) -> str:
|
||||
m = mat.upper().strip().replace("-", " ").replace("_", " ")
|
||||
# Bekannte Varianten normalisieren
|
||||
_ALIASES = {
|
||||
"PLAPLUS": "PLA+", "PLA PLUS": "PLA+",
|
||||
"SILK PLA": "PLA SILK", "PLASILK": "PLA SILK",
|
||||
"PLA MATTE": "PLA MATTE", "PLA MARBLE": "PLA MARBLE",
|
||||
"PLA WOOD": "PLA WOOD",
|
||||
"TPE": "TPU",
|
||||
"PETG PLUS": "PETG+",
|
||||
"PA6": "PA", "PA12": "PA", "PA66": "PA",
|
||||
}
|
||||
if m in _ALIASES:
|
||||
return _ALIASES[m]
|
||||
return m
|
||||
|
||||
def _build_lane_data(self) -> dict:
|
||||
"""Baut BBL-AMS-JSON für OrcaSlicer DevFilaSystemParser::ParseV1_0.
|
||||
|
||||
@@ -1910,7 +1942,7 @@ class KobraXBridge:
|
||||
color_hex = color_raw[:6].upper() + "FF"
|
||||
else:
|
||||
color_hex = "FFFFFFFF"
|
||||
material = slot.get("type", "PLA").upper()
|
||||
material = self._normalize_material(slot.get("type", "PLA"))
|
||||
# User-Override aus config.ini [filament_profiles].slot_N_id
|
||||
# bekommt Vorrang vor dem Default-Mapping nach material-Type.
|
||||
# Vendor wird mitgesendet (tray_sub_brands + filament_vendor),
|
||||
@@ -2086,7 +2118,7 @@ class KobraXBridge:
|
||||
for _global_index, slot in slots:
|
||||
occupied = slot.get("status") == 5
|
||||
gate_status.append(1 if occupied else 0)
|
||||
material = (slot.get("type") or "PLA").upper() if occupied else ""
|
||||
material = self._normalize_material(slot.get("type") or "PLA") if occupied else ""
|
||||
gate_material.append(material)
|
||||
c = slot.get("color", [0, 0, 0]) if occupied else [0, 0, 0]
|
||||
# Happy Hare erwartet gate_color als RRGGBB OHNE '#' (Klipper-Limitation).
|
||||
@@ -2136,8 +2168,22 @@ class KobraXBridge:
|
||||
kann pro Slot eine konkrete Marke setzen wenn er das will."""
|
||||
if not material:
|
||||
return ""
|
||||
mat = material.upper().strip()
|
||||
mat = self._normalize_material(material)
|
||||
profs = self._load_orca_filaments()
|
||||
# Varianten-Mapping: Drucker meldet z.B. "PLA SILK", OrcaSlicer speichert
|
||||
# alle Varianten unter type=PLA mit dem Variant-Namen im name-Feld.
|
||||
_VARIANT_NAME = {
|
||||
"PLA SILK": "Generic PLA Silk",
|
||||
"PLA MATTE": "Generic PLA Matte",
|
||||
"PLA+": "Generic PLA",
|
||||
"PLA-CF": "Generic PLA-CF",
|
||||
"PETG-CF": "Generic PETG-CF",
|
||||
}
|
||||
if mat in _VARIANT_NAME:
|
||||
target = _VARIANT_NAME[mat]
|
||||
for p in profs:
|
||||
if p.get("vendor") == "Generic" and p.get("name") == target:
|
||||
return p["name"]
|
||||
def _match_type(p: dict) -> bool:
|
||||
pt = (p.get("type") or "").upper()
|
||||
return pt == mat or pt.startswith(mat + "-") or pt.startswith(mat + " ")
|
||||
|
||||
@@ -1413,7 +1413,14 @@ function doProfileImportUpload(files){
|
||||
// ── AMS Slot Edit ──
|
||||
var _slotEditIndex=-1;
|
||||
var _slotEditLoaded=false;
|
||||
var _MAT_PRESETS=['PLA','PETG','ABS','ASA','TPU','PA','PC','HIPS'];
|
||||
var _MAT_PRESETS=['PLA','PLA+','PLA SILK','PLA MATTE','PETG','ABS','ASA','TPU','PA','PC','HIPS'];
|
||||
function _normalizeMat(m){
|
||||
var s=m.toUpperCase().trim().replace(/-/g,' ').replace(/_/g,' ');
|
||||
var aliases={'PLAPLUS':'PLA+','PLA PLUS':'PLA+','SILK PLA':'PLA SILK','PLASILK':'PLA SILK',
|
||||
'PLA MATTE':'PLA','PLA MARBLE':'PLA','PLA WOOD':'PLA','TPE':'TPU',
|
||||
'PETG PLUS':'PETG+','PA6':'PA','PA12':'PA','PA66':'PA'};
|
||||
return aliases[s]||s;
|
||||
}
|
||||
var _BASE_MATERIAL_TYPES=['PLA','PETG','ABS','ASA','TPU','TPE','PA','PC','HIPS','PEI','PEEK'];
|
||||
function updateSlotEditFeedButton(){
|
||||
var btn=document.getElementById('btn-slot-edit-feed');
|
||||
@@ -1454,10 +1461,21 @@ function _fillSlotProfileDropdown(material, currentVendor, currentName){
|
||||
_loadOrcaFilaments(function(profiles){
|
||||
// Type-Filter: nur Profile vom passenden material zeigen (z.B. PLA → alle PLA-Varianten)
|
||||
var matU=(material||'').toUpperCase().trim();
|
||||
// PLA-Varianten: Drucker meldet "PLA SILK"/"PLA+"/"PLA MATTE", OrcaSlicer
|
||||
// speichert alle unter type=PLA — Namens-Keyword als Zusatzfilter.
|
||||
var _PLA_VARIANT_KW={'PLA SILK':'silk','PLA+':'pla+','PLA MATTE':'matte',
|
||||
'PLA MARBLE':'marble','PLA WOOD':'wood'};
|
||||
var variantKw=_PLA_VARIANT_KW[matU]||null;
|
||||
var baseMat=variantKw?'PLA':matU;
|
||||
var matched=profiles.filter(function(p){
|
||||
var pt=(p.type||'').toUpperCase();
|
||||
// PLA-CF, PLA-SILK etc. zählen auch zu PLA
|
||||
return matU==='' || pt===matU || pt.startsWith(matU+'-') || pt.startsWith(matU+' ');
|
||||
var nameL=(p.name||'').toLowerCase();
|
||||
// Basis-Typ muss passen
|
||||
var typeOk=baseMat===''||pt===baseMat||pt.startsWith(baseMat+'-')||pt.startsWith(baseMat+' ');
|
||||
if(!typeOk) return false;
|
||||
// Bei Variante: Name muss Keyword enthalten (z.B. "silk", "matte", "pla+")
|
||||
if(variantKw) return nameL.indexOf(variantKw)!==-1;
|
||||
return true;
|
||||
});
|
||||
sel.innerHTML='<option value="">'+tr('slot_edit_profile_default')+'</option>';
|
||||
// User-Profile (is_user) zuerst — eigene Optgroup '★ Eigene' an erster Stelle.
|
||||
@@ -1619,11 +1637,14 @@ function openSlotEdit(i){
|
||||
_renderCopyFromSlot(globalIdx);
|
||||
var mat=(slot.type||'PLA').toUpperCase();
|
||||
document.getElementById('slot-edit-mat').value=mat;
|
||||
// Normalisieren für Button-Highlighting: PLA-Varianten auf nächsten Preset mappen
|
||||
var matNorm=_normalizeMat(mat);
|
||||
var btns=document.getElementById('slot-mat-btns');
|
||||
btns.innerHTML=_MAT_PRESETS.map(function(m){
|
||||
var active=m===mat||m===matNorm;
|
||||
return '<button class="mat-preset-btn" data-mat="'+m+'" onclick="selectMatPreset(\''+m+'\')" '
|
||||
+'style="padding:4px 10px;border-radius:6px;border:1px solid var(--border);cursor:pointer;font-size:12px;'
|
||||
+(m===mat?'background:var(--accent);color:#fff':'background:var(--raised);color:var(--txt2)')+'">'+m+'</button>';
|
||||
+(active?'background:var(--accent);color:#fff':'background:var(--raised);color:var(--txt2)')+'">'+m+'</button>';
|
||||
}).join('');
|
||||
// OrcaSlicer-Profil-Dropdown: aktuellen User-Override für diesen Slot
|
||||
// aus /kx/filament/slots holen (enthält vendor+name+id).
|
||||
|
||||
Reference in New Issue
Block a user