Material Phase B Stufe 4: PBR auf Rhino-Material applied + Auto-Regen

_ensure_pbr_material baut ein vollständiges Rhino-Material aus dem
Project-Settings-dict:
- ToPhysicallyBased() + BaseColor/Roughness/Metallic/Opacity/OpacityIor
- Diffuse-/Bump-/Transparency-Texture via SetBitmapTexture etc.
- UV-Repeat = 1/uvScaleM
- Cache per Signature (Color+PBR+Texture-Pfade)

_get_all_materials liefert jetzt full-dicts (nicht mehr nur color/hatch/
scale) damit Wand-Regen Zugriff auf PBR + Texturen hat.

Wand-Regen: wenn voll-dict aus Project-Settings vorliegt → PBR-Material,
sonst Fallback auf legacy _ensure_material(hex).

Auto-Regen on Save:
- PBR-Material-Cache + Legacy-Material-Cache invalidieren
- Alle wand_axis im Doc regenerieren (in EINEM Undo-Record)
- User aendert Material-Properties -> existierende Waende updaten sofort

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-24 17:33:38 +02:00
parent 0bf891641f
commit c63bdd5bc1
2 changed files with 186 additions and 16 deletions
+37
View File
@@ -706,12 +706,49 @@ class EbenenBridge(panel_base.BaseBridge):
}
save_project_settings(doc2, new_settings)
_broadcast_state(doc2)
# Material-Cache invalidieren (PBR-Cache hashed Color+Texturen+
# PBR-Werte — wenn der User ein Material aendert, muss der
# Cache leer sein, sonst kriegen Waende stale Material-Indizes).
try:
import scriptcontext as sc
sc.sticky["_dossier_pbr_material_cache"] = {}
sc.sticky["_dossier_material_cache"] = {}
except Exception: pass
try:
import scriptcontext as sc
eb = sc.sticky.get("elemente_bridge")
if eb is not None: eb._send_state()
except Exception as ex:
print("[PROJECT-SETTINGS] elemente refresh:", ex)
# Alle wand_axis im Doc regenen damit Material-Aenderungen
# (PBR/Texturen/Hatch) auf existing Waende durchschlagen.
try:
import elemente
undo_serial = doc2.BeginUndoRecord("Material-Update Regen")
prev_redraw = doc2.Views.RedrawEnabled
doc2.Views.RedrawEnabled = False
wall_ids = []
for obj in doc2.Objects:
m = elemente._read_meta(obj)
if m and m.get("type") == "wand_axis":
wall_ids.append(m["id"])
# Chain-Anchor regent automatisch alle members — wir koennen
# trotzdem alle einzeln triggern, _REGEN_BUSY-Guard verhindert
# Doppel-Arbeit. Einfacher als Anchor-Election hier.
try:
for wid in wall_ids:
try: elemente._regenerate_element(doc2, wid)
except Exception as ex:
print("[PROJECT-SETTINGS] regen", wid, ex)
finally:
doc2.Views.RedrawEnabled = prev_redraw
try: doc2.EndUndoRecord(undo_serial)
except Exception: pass
try: doc2.Views.Redraw()
except Exception: pass
print("[PROJECT-SETTINGS] {} Waende regenert".format(len(wall_ids)))
except Exception as ex:
print("[PROJECT-SETTINGS] wall regen:", ex)
panel_base.open_satellite_window(
"project_settings",
params=params,