Snapshot: Wand/Öffnung Multi-Surface-Select + Z-Drag + Brüstungs-Mitnahme

Stable working state after a long iteration session. The plugin now supports:
- Multi-Surface-Select für alle Element-Typen (Türen/Fenster/Treppen/Tragwerk)
- Wand-Z-Drag → unbound mode (UK/OK-Override, Wand vom Geschoss entkoppelt)
- Wand-Z-Drag nimmt verknüpfte Öffnungen mit (Brüstung += delta_z via Idle-Pfad)
- Öffnungs-XY-Drag snapt direktional auf Wand-Tangente
- Öffnungs-Z-Drag passt Brüstung an (Fenster sofort sync, Tür deferred)
- Wand-Delete kaskadiert Öffnungen (deferred via Idle, robust gegen _Rotate/_Move)
- Source-Cascade beim Öffnungs-Delete (deferred analog Wand-Kaskade)
- Listener-Cleanup robust gegen _reset_panels.py Reload (Refs in
  _dossier_runtime_event_refs gespeichert, vor Re-Install deregistriert)
- _count_same_id_type filtert IsDeleted (verhindert Source-Duplikat-Bug bei Move)
- Frontend: Brüstungs-Slider für Tür ("Schwelle"), Flügel-Block nur bei Fenster

Plus aus früherer Phase dieser Session:
- Dossier-Launcher Auto-Load via Rhinos StartupCommands-XML
- Default-Pfad zeigt auf gebundeltes startup.py (out-of-the-box für neue User)
- Splash-Window beim Plugin-Load mit native macOS rounded corners
- Diverse Launcher-Verbesserungen (Brüstungs-Default, tauri.conf, capabilities)

Known issue: bei Multi-Select-Move mit vielen Sub-Volumen kann sporadisch
"Unable to transform" auftreten (Rhinos Move-Operation kollidiert mit Wand-
Regen). Tür-spezifischer Defer-Pfad mildert das, Fenster läuft sync.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-18 01:50:45 +02:00
parent 1180d7bedf
commit 961b3c0396
52 changed files with 10760 additions and 765 deletions
+82 -3
View File
@@ -1,4 +1,4 @@
# ! python3
#! python 3
# -*- coding: utf-8 -*-
"""
overrides.py
@@ -70,6 +70,9 @@ _GEST_FILL_KEY = "ebenen_fill_hatch_id" # auf Curve
_ORIG_HP = "dossier_or_hatch_pidx" # auf Hatch — original PatternIndex
_ORIG_HS = "dossier_or_hatch_scale" # auf Hatch — original PatternScale
_HATCH_OVERRIDDEN = "dossier_or_hatch_done" # "1" wenn Hatch aktuell overridden
_ORIG_HC_SRC = "dossier_or_hatch_csrc" # auf Hatch — original ColorSource
_ORIG_HC = "dossier_or_hatch_color" # auf Hatch — original Color
_HATCH_COLOR_OVERRIDDEN = "dossier_or_hatch_color_done"
_FROM_LAYER = Rhino.DocObjects.ObjectColorSource.ColorFromLayer
_FROM_OBJECT = Rhino.DocObjects.ObjectColorSource.ColorFromObject
@@ -342,6 +345,7 @@ def _restore_original(doc, obj):
# Hatch separat zuruecksetzen — kann auch ohne Curve-Override
# passiert sein (z.B. wenn Override nur den Pattern aendert)
_restore_hatch(doc, obj)
_restore_hatch_color(doc, obj)
if a.GetUserString(_OVERRIDDEN) != "1":
return False
try:
@@ -481,6 +485,74 @@ def _restore_hatch(doc, curve_obj):
return False
def _apply_hatch_color_override(doc, curve_obj, color_hex):
"""Setzt ObjectColor + ColorSource des verlinkten Hatches auf color_hex.
Backup wird einmalig auf dem Hatch in UserStrings gesichert."""
h = _find_linked_hatch(doc, curve_obj)
if h is None: return False
try:
ha = h.Attributes
if ha.GetUserString(_HATCH_COLOR_OVERRIDDEN) != "1":
try:
ha.SetUserString(_ORIG_HC_SRC, str(int(ha.ColorSource)))
ha.SetUserString(_ORIG_HC, _color_to_hex(ha.ObjectColor))
ha.SetUserString(_HATCH_COLOR_OVERRIDDEN, "1")
doc.Objects.ModifyAttributes(h, ha, True)
except Exception as ex:
print("[OVERRIDES] hatch-color backup:", ex)
new_a = h.Attributes.Duplicate()
new_a.ColorSource = _FROM_OBJECT
new_a.ObjectColor = _hex_to_color(color_hex)
try:
new_a.PlotColorSource = Rhino.DocObjects.ObjectPlotColorSource.PlotColorFromObject
new_a.PlotColor = new_a.ObjectColor
except Exception: pass
doc.Objects.ModifyAttributes(h, new_a, True)
return True
except Exception as ex:
print("[OVERRIDES] _apply_hatch_color_override:", ex)
return False
def _restore_hatch_color(doc, curve_obj):
"""Stellt ColorSource + ObjectColor des verlinkten Hatches aus Backup
wieder her."""
h = _find_linked_hatch(doc, curve_obj)
if h is None: return False
a = h.Attributes
if a.GetUserString(_HATCH_COLOR_OVERRIDDEN) != "1": return False
try:
orig_src = a.GetUserString(_ORIG_HC_SRC) or "1" # default ColorFromObject
orig_col = a.GetUserString(_ORIG_HC) or "#f5f5f5"
new_a = h.Attributes.Duplicate()
# ColorSource zuruecksetzen — Enum.ToObject ist in IronPython3
# zuverlaessiger als der direkte int->Enum-Konstruktor.
try:
val = int(orig_src)
new_a.ColorSource = System.Enum.ToObject(
Rhino.DocObjects.ObjectColorSource, val)
except Exception:
new_a.ColorSource = _FROM_OBJECT
try:
new_a.ObjectColor = _hex_to_color(orig_col)
except Exception:
new_a.ObjectColor = Drawing.Color.FromArgb(245, 245, 245)
# PlotColor mit-resetten
try:
new_a.PlotColorSource = (
Rhino.DocObjects.ObjectPlotColorSource.PlotColorFromObject)
new_a.PlotColor = new_a.ObjectColor
except Exception: pass
for k in (_ORIG_HC_SRC, _ORIG_HC, _HATCH_COLOR_OVERRIDDEN):
try: new_a.SetUserString(k, "")
except Exception: pass
doc.Objects.ModifyAttributes(h, new_a, True)
return True
except Exception as ex:
print("[OVERRIDES] _restore_hatch_color:", ex)
return False
def _apply_to_object(doc, obj, overrides):
"""Setzt die Override-Werte am Objekt. Sichert vorher Originale."""
if not overrides: return False
@@ -498,6 +570,11 @@ def _apply_to_object(doc, obj, overrides):
new_a.PlotColor = col
except Exception: pass
changed = True
# Verlinkten Hatch (Gestaltung-Fuellung) auch einfaerben — sonst
# bleibt die Fuellung in der Original-Farbe waehrend die Outline schon
# die Override-Farbe traegt.
try: _apply_hatch_color_override(doc, obj, overrides["color"])
except Exception: pass
if "lineweight" in overrides:
try:
new_a.PlotWeightSource = _LW_FROM_OBJ
@@ -574,8 +651,10 @@ def restore_all(doc):
if _restore_original(doc, obj):
n += 1
else:
# Vielleicht nur Hatch-Override
if _restore_hatch(doc, obj):
# Vielleicht nur Hatch-Override (Pattern und/oder Color)
r1 = _restore_hatch(doc, obj)
r2 = _restore_hatch_color(doc, obj)
if r1 or r2:
n += 1
try: doc.Views.Redraw()
except Exception: pass