Files
HartOMat/review-report.md
T
Hartmut ee6eb34b4c feat: GPU rendering + material matching + perf improvements
- GPU: fix Cycles device activation order — set compute_device_type
  BEFORE engine init, re-set AFTER open_mainfile wipes preferences
- GPU: remove _mark_sharp_and_seams edit-mode loop (redundant with
  Blender 5.0 shade_smooth_by_angle), saves ~200s/render on 175 parts
- Material: fix _AFN suffix mismatch — build AF-stripped mat_map keys
  and add prefix fallback in _apply_material_library (blender_render.py)
- Material: production GLB now uses get_material_library_path() which
  checks active AssetLibrary instead of empty legacy system setting
- Admin: RenderTemplateTable multi-select output types (M2M frontend)
- Admin: MaterialLibraryPanel replaced with link to Asset Libraries
- UX: move Toaster to top-left to avoid dispatch button overlap
- SQLAlchemy: add .unique() to all RenderTemplate M2M collection queries
- Logging: flush=True on all Blender progress prints, stdout reconfigure

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08 19:05:03 +01:00

2.7 KiB

Review Report: Optimized Material Substitution Algorithm

Datum: 2026-03-07

Ergebnis: ⚠️ Kleinigkeiten


Gefundene Probleme

[products.py:510] Prefix-Matching ohne Mindestlänge-Guard

Schwere: Gering

Der Prefix-Fallback in build_materials_from_excel prüft cad_norm.startswith(excel_norm) ohne Mindestlänge für excel_norm:

if excel_norm and cad_norm and (
    cad_norm.startswith(excel_norm) or excel_norm.startswith(cad_norm)
):

Wenn ein Excel-Eintrag nach Normalisierung sehr kurz wird (z.B. "f" aus f-12345678.prt), trifft der Präfix-Check auf fast alle CAD-Namen die mit f_ beginnen. Schaeffler-Teilenamen sind zwar praktisch immer lang genug, aber das Risiko eines Fehlmatches bei atypischen Einträgen existiert.

Empfehlung: Guard hinzufügen: len(excel_norm) >= 5 and len(cad_norm) >= 5.


[export_gltf.py:122] Prefix-Fallback iteriert über unsortierte dict-Keys

Schwere: Gering

for key, val in mat_map_lower.items():
    if lower_base.startswith(key) or key.startswith(lower_base):
        mat_name = val
        break

mat_map_lower hat keine garantierte Sortierung nach Schlüssellänge. Wenn ein kurzer Key ("ring") und ein langer Key ("ring_inner_seal") beide die Präfix-Bedingung erfüllen, gewinnt der erste in dict-Reihenfolge — nicht zwangsläufig der spezifischste Match.

Empfehlung: Keys nach Länge absteigend sortieren: sorted(mat_map_lower.items(), key=lambda x: len(x[0]), reverse=True) — längster Match gewinnt = spezifischster Match.


Positiv aufgefallen

  • Task 1 korrekt und robust: while prev != base_name Loop für nested Suffixe terminiert sicher und deckt _AF0_AF1-Fälle ab.
  • _re.IGNORECASE korrekt gesetzt in export_gltf.py — deckt _AF0 wie auch _af0.
  • _normalize_part_token_name Reihenfolge stimmt: _af\d+ wird VOR Hyphen→Underscore-Konvertierung gestrippt, Regex funktioniert zuverlässig.
  • Hash-Suffix-Stripping \d{4,}: Mindestlänge 4 verhindert False-Positives bei legitimen kurzen Nummern in Teilenamen.
  • print() in Blender-Script korrekt: Blender-Scripts laufen als Subprocess, stdout wird vom Caller geloggt — logging wäre hier falsch.
  • Kein DB-Schema geändert: Keine Migration nötig, korrekt erkannt und ausgelassen.
  • Tuple-Erweiterung auf 4 Elemente: excel_entries korrekt auf (tokens, raw, material, excel_norm) erweitert, keine alten Stellen übersehen.

Empfehlung

Zwei geringe Probleme (Mindestlänge-Guard + Sortierung nach Key-Länge). Beide sind je eine Zeile Fix und verhindern Fehlmatches bei atypischen Eingaben. Können direkt inline gepatcht werden, kein erneutes Review nötig.