Fenster/Tueren LoD + Stile + Phase-3-Ausschnitt-Darstellung + UI-Konsistenz

Fenster/Tueren:
- 3-stufige SIA-400-Darstellung pro Element: einfach (1:100, flache
  Scheibe ohne Tiefe in Wand-Mittelebene), standard (1:50, Rahmen +
  Glas + Sims), detail (1:20, Doppelverglasung).
- Aussenseite-Flag mit Auto-Detection aus der Click-Richtung beim
  Setzen — Sim sitzt automatisch aussen. Im Panel als Umkehren-Toggle.
- Tueren-Rahmen-Typ Zarge|Block — Blockrahmen ragt seitlich raus.
- Rahmen-Offset (m von Wand-Innenseite) ersetzt das 3-Preset Lage-
  Feld. Wirkt auch in der einfachen Darstellung (Pane sitzt auf der
  Rahmen-Mittelebene, nicht in Wand-Mitte).
- Sims nur AUSSEN. Innen entfaellt — der Sim ist gleichzeitig der
  visuelle Indikator fuer die Aussenseite.
- Oeffnungs-Stile: list/save/delete-API mit 6 Default-Presets
  (Fenster Standard/Gross/Bandlage, Tuer Innen/Eingang/Verglast).
  Style-ID per UserString am Objekt persistiert. Im Panel BarCombo
  mit "Aktuelle als Stil speichern…". Beim Rhino-Command "Stil"-
  Option zum Picken vor dem Klick.

Ausschnitt-Darstellung (Phase 3):
- Doc-Level Override dossier_aktive_darstellung gewinnt vor per-
  Object-Setting. Wechsel triggert Regen aller Oeffnungen via neuer
  regenerate_all_oeffnungen-API.
- Ausschnitt-Capture speichert die Darstellung mit, Restore wendet
  sie an und regeneriert.
- Oberleiste-Quick-Switch BarCombo mit 4 Optionen.
- AusschnittSettings-Dialog: Darstellungs-Dropdown.

Gestaltung (SectionStyle Phase 2):
- _set_section_style schreibt per-Object SectionHatchIndex/Scale/
  Rotation/Color mit Multi-Fallback (Property-Namen varieren je
  Rhino-Build). _selection_summary liest die selben zurueck.
- HatchEditor als shared Component fuer Fill + Section.
- geometryKind ignoriert DOSSIER-Source-Curves damit Wand-Selektion
  (Axis + Volume) als 3D klassifiziert wird.

UI-Konsistenz Panels:
- Ebenenkombi zurueck als eigene Section oben im Ebenen-Panel,
  Modelldarstellung-Dropdown an die freigewordene Position in der
  Oberleiste (Row 1 Col 2 im 2x2-Preset-Block).
- BarCombo erweitert: stretch-Prop (Pill waechst auf Container-
  Breite), onSecond/secondIcon/secondTitle fuer 2. Trailing-Button,
  gearIcon-Prop. Plus-Slot immer ganz aussen rechts, Settings-Slot
  direkt nach dem Caret.
- Ebenen + Zeichnungsebenen visuell kohaerent: identisches Padding
  (1px 12px 1px 0), Chevron/Spacer-Slot 12px, Master-Row mit Eye
  16x16 + Lock 14x14, gleiche Border + Borderfarbe. Eye-Icons in
  beiden Panels untereinander ausgerichtet.
- Properties-Container ohne Border (war zuvor accent-gruen, dann
  border — User wollte gar nichts mehr).
- ElementList raus aus dem Elemente-Panel (Uebersicht via Tree-
  Window erreichbar). NeuesElement bleibt voll sichtbar bei
  Selektion (kein Collapse), Properties oben.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-22 12:34:15 +02:00
parent 9ae8574ab0
commit 0c5f8055a5
13 changed files with 899 additions and 220 deletions
+35 -6
View File
@@ -327,6 +327,8 @@ class AusschnittBridge(panel_base.BaseBridge):
elif t == "DELETE": self._delete(p.get("id"))
elif t == "SET_FOLDER": self._set_field(p.get("id"), "folder", p.get("folder") or "")
elif t == "SET_SCALE": self._set_field(p.get("id"), "scale", p.get("scale") or "")
elif t == "SET_DARSTELLUNG": self._set_field(p.get("id"), "darstellung",
p.get("darstellung") or "")
elif t == "DUPLICATE": self._duplicate(p.get("id"))
elif t == "ADD_FOLDER": self._add_folder(p.get("name"))
elif t == "REMOVE_FOLDER": self._remove_folder(p.get("name"))
@@ -494,13 +496,21 @@ class AusschnittBridge(panel_base.BaseBridge):
print("[AUSSCHNITTE] Live-Skala (Fallback):", ex)
if not scale_str and prior_scale:
scale_str = prior_scale # Perspective -> alten Wert nicht ueberschreiben
# Darstellungs-Override aus dem aktuellen Doc-Setting uebernehmen.
# Leer = "kein Override, per-Object respektieren".
darst = ""
try:
import elemente
darst = elemente.get_aktive_darstellung(doc) or ""
except Exception: pass
return {
"id": existing_id or "snap_" + uuid.uuid4().hex[:8],
"name": name,
"scale": scale_str,
"camera": _capture_camera(vp),
"layers": _capture_layers(doc),
"dossier": _capture_dossier_state(doc),
"id": existing_id or "snap_" + uuid.uuid4().hex[:8],
"name": name,
"scale": scale_str,
"camera": _capture_camera(vp),
"layers": _capture_layers(doc),
"dossier": _capture_dossier_state(doc),
"darstellung": darst,
}
def _save(self, name):
@@ -558,6 +568,21 @@ class AusschnittBridge(panel_base.BaseBridge):
rhinopanel._notify_oberleiste_combs()
except Exception: pass
_apply_dossier_state(doc, snap.get("dossier") or snap.get("pause") or {})
# Darstellung anwenden + Oeffnungen regenerieren
try:
import elemente
new_darst = snap.get("darstellung") or ""
cur_darst = elemente.get_aktive_darstellung(doc) or ""
if new_darst != cur_darst:
elemente.set_aktive_darstellung(doc, new_darst)
elemente.regenerate_all_oeffnungen(doc)
# Oberleiste-Topbar muss neuen Wert spiegeln
try:
b = sc.sticky.get("oberleiste_bridge")
if b is not None: b._send_state(force=True)
except Exception: pass
except Exception as ex:
print("[AUSSCHNITTE] darstellung apply:", ex)
# Overrides: nur anwenden wenn das Snap "applyOverrides" gesetzt hat.
# Sonst bleibt der aktuelle User-Override-State unangetastet.
if snap.get("applyOverrides"):
@@ -786,6 +811,7 @@ class AusschnittBridge(panel_base.BaseBridge):
"overridesEnabled": bool(sn.get("overridesEnabled", False)),
"overridesPreset": sn.get("overridesPreset") or "",
"layerCombination": sn.get("layerCombination") or "",
"darstellung": sn.get("darstellung") or "",
},
"displayModes": display_modes,
"overridesPresets": overrides_presets,
@@ -815,6 +841,9 @@ class AusschnittBridge(panel_base.BaseBridge):
target["overridesPreset"] = (settings.get("overridesPreset") or "").strip()
# Ebenenkombi
target["layerCombination"] = (settings.get("layerCombination") or "").strip()
# Darstellung (SIA-400 LoD Override fuer diesen Ausschnitt)
darst = (settings.get("darstellung") or "").strip()
target["darstellung"] = darst if darst in ("einfach", "standard", "detail") else ""
outer._store(d, snaps)
outer._send_list()
print("[AUSSCHNITTE] Settings fuer '{}' aktualisiert".format(target.get("name")))