Projekt-Settings-Dialog + Library Phase A + Material-Merger

- Project-Settings-Dialog (Voreinstellungen Geschoss/Schnitt + Material-Editor)
  ueber Zahnrad-Icon in Oberleiste; Defaults werden in schnitte.pick_schnitt
  + GeschossManager als Vorgabe genommen, pro-Element-Werte unangetastet
- Dossier-Library Phase A (lokal, read-only): rhino/library.py + LibraryBrowser
  Satellite; Seed-Manifest unter ~/Library/Application Support/Dossier/library/
- Material-Merger: _get_all_materials(doc) merged builtin _MATERIAL_LIBRARY
  mit Projekt-Settings-Materialien (inkl. Library-Imports); Wand-Erstellung,
  Sub-Layer-Anlage + Elemente-Material-Dropdown ziehen jetzt aus dem Merge

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-24 02:19:09 +02:00
parent ee01c7ebdc
commit a308ba62d2
13 changed files with 1087 additions and 56 deletions
+30 -5
View File
@@ -2038,6 +2038,29 @@ _MATERIAL_LIBRARY = {
}
def _get_all_materials(doc):
"""Builtin _MATERIAL_LIBRARY + Projekt-Settings-Materialien gemerged.
Returns dict[name] -> {color, hatch, scale}. Projekt-Settings (inkl.
Library-Imports) ueberschreibt builtin bei Namensgleichheit, sodass
der User builtin-Defaults pro Projekt anpassen kann."""
merged = {n: dict(m) for n, m in _MATERIAL_LIBRARY.items()}
try:
import rhinopanel
ps = rhinopanel.load_project_settings(doc) if doc else None
if isinstance(ps, dict):
for m in ps.get("materials", []):
n = m.get("name")
if not n: continue
merged[n] = {
"color": m.get("color", "#888888"),
"hatch": m.get("hatch", "Solid"),
"scale": float(m.get("scale", 1.0) or 1.0),
}
except Exception as ex:
print("[ELEMENTE] _get_all_materials:", ex)
return merged
def _set_layer_section_hatch(doc, layer_idx, hatch_name, scale=1.0,
rotation=0.0):
"""Konfiguriert Rhinos native Section-Hatch-Properties am Layer.
@@ -2073,9 +2096,10 @@ def _ensure_material_sublayer(doc, geschoss_name, material_name):
mit Material-Farbe + Section-Hatch konfiguriert. Liefert Layer-Index.
Bei leerem oder unbekanntem Material: Fallback auf das normale
Wand-Volume-Layer (= Standard fuer Solid-Waende)."""
if not material_name or material_name not in _MATERIAL_LIBRARY:
all_mats = _get_all_materials(doc)
if not material_name or material_name not in all_mats:
return _ensure_layer(doc, _layer_path_volume(doc, geschoss_name))
mat = _MATERIAL_LIBRARY[material_name]
mat = all_mats[material_name]
parent_path = _layer_path_volume(doc, geschoss_name)
full_path = "{}::{}".format(parent_path, material_name)
idx = _ensure_layer(doc, full_path)
@@ -5127,8 +5151,9 @@ def _regenerate_element_body(doc, element_id, src_obj, meta, geom, geschoss_name
mat_name = lay_def.get("material", "") if is_layered else ""
effective_color = color
target_layer = layer
if mat_name and mat_name in _MATERIAL_LIBRARY:
effective_color = _MATERIAL_LIBRARY[mat_name]["color"]
all_mats = _get_all_materials(doc)
if mat_name and mat_name in all_mats:
effective_color = all_mats[mat_name]["color"]
target_layer = _ensure_material_sublayer(doc, geschoss_name,
mat_name)
if target_layer < 0: target_layer = layer
@@ -5838,7 +5863,7 @@ class ElementeBridge(panel_base.BaseBridge):
"materials": [
{"name": n, "color": m["color"],
"hatch": m.get("hatch", ""), "scale": m.get("scale", 1.0)}
for n, m in _MATERIAL_LIBRARY.items()],
for n, m in _get_all_materials(doc).items()],
"oeffStyles": list_oeff_styles(doc),
}
self.send("STATE", payload)