diff --git a/rhino/gestaltung.py b/rhino/gestaltung.py index 718afb3..eaf322b 100644 --- a/rhino/gestaltung.py +++ b/rhino/gestaltung.py @@ -1387,16 +1387,24 @@ def _install_selection_listener(bridge): - Hatch hat _FILL_OWNER_KEY (= curve_id) → Curve um den gleichen Vektor mit-translaten (User hat Hatch alleine verschoben). """ - # Waehrend User-Transform-Command: elemente uebernimmt die Geometrie- - # Synchronisation. Hatch-Re-Create laeuft hier sowieso ins Leere weil - # Rhino bei Move Delete+Add statt Replace feuert. - if sc.sticky.get("_dossier_user_transform_active"): return if sc.sticky.get("_dossier_undo_active"): return if sc.sticky.get("_elemente_regen_busy"): return new_obj = args.NewRhinoObject if new_obj is None or new_obj.Id in _processing: return a = new_obj.Attributes + # Frueher Bail-out wenn das Objekt KEIN Hatch-Coupling hat — irrelevant. + # Erst NACH dieser Pruefung das user-transform-Skip, sonst wuerde die + # Hatch-Sync beim Verschieben einer normalen Polylinie nicht laufen + # (war der Fall nach dem Split: Hatch ging bei _Move nicht mehr mit). + hatch_id_str_quick = a.GetUserString(_FILL_KEY) + owner_id_str_quick = a.GetUserString(_FILL_OWNER_KEY) + if not hatch_id_str_quick and not owner_id_str_quick: + return + # Dossier-eigene Sources (wand_axis etc.) haben weder _FILL_KEY noch + # _FILL_OWNER_KEY — die werden hier oben rausgekickt. User-Transform- + # Skip war eigentlich nur fuer Dossier-Elemente gedacht; reine Hatch- + # gekoppelte Polylinien brauchen die Sync auch waehrend _Move. # Reverse-Direction: Hatch verschoben/rotiert/skaliert → Curve mitnehmen. # Wir nehmen die Outer-Boundary direkt aus der (bereits transformed) # Hatch — funktioniert fuer Move, Rotate, Scale, beliebige Transforms. @@ -1470,10 +1478,6 @@ def _install_selection_listener(bridge): """Wenn eine Curve geloescht wird, ihre gekoppelte Hatch mitloeschen. Wenn umgekehrt eine Hatch direkt geloescht wird, den Verweis auf der Curve aufraeumen damit beim naechsten Toggle keine Geister-Referenz steht.""" - # Waehrend User-Transform-Command: Rhino feuert Delete+Add fuer - # transformierte Objekte. Curve→Hatch-Cascade hier wuerde die Hatch - # killen obwohl sie gleich wieder benoetigt wird. - if sc.sticky.get("_dossier_user_transform_active"): return if sc.sticky.get("_dossier_undo_active"): return if sc.sticky.get("_elemente_regen_busy"): return obj = args.TheObject @@ -1486,7 +1490,10 @@ def _install_selection_listener(bridge): return # Schneller Bail-out: ohne Hatch-UserString interessiert uns das - # Event nicht. Vermeidet Print-Spam fuer Wand-Sub-Volumen etc. + # Event nicht. Vermeidet Print-Spam fuer Wand-Sub-Volumen etc. UND + # filtert den user-transform-Pfad: nur Hatch-gekoppelte Objekte + # brauchen die Sync (= Cascade-Delete + pending-Save fuer Recovery). + # Wand-Volumen werden nicht beruehrt. try: hatch_id_str = attrs.GetUserString(_FILL_KEY) except Exception: @@ -1551,10 +1558,6 @@ def _install_selection_listener(bridge): - Wenn das Objekt eben gerade als Teil eines Drag/Move geloescht wurde, stellen wir die Hatch mit den gemerkten Metadaten wieder her. - Sonst pruefen wir ob die Ebene ein Auto-Fill konfiguriert hat.""" - # Waehrend User-Transform-Command: elemente uebernimmt Geometrie-Sync. - # Auto-Fill hier wuerde unnoetige Hatches erzeugen weil das Objekt - # bereits eine geerbte Fill-UserString hat (vom Delete+Add im Move). - if sc.sticky.get("_dossier_user_transform_active"): return if sc.sticky.get("_dossier_undo_active"): return if sc.sticky.get("_elemente_regen_busy"): return obj = args.TheObject @@ -1565,6 +1568,9 @@ def _install_selection_listener(bridge): doc = Rhino.RhinoDoc.ActiveDoc # 1) Drag-Recovery: Hatch-Metadaten wurden gerade in on_delete gespeichert? + # MUSS auch waehrend User-Transform laufen (= das ist gerade DER Fall: + # Rhino's Move feuert Delete+Add, on_delete hat pending gespeichert, + # jetzt muss on_add die Hatch wiederherstellen). pending = _take_pending_hatch(obj.Id) if pending is not None: try: @@ -1580,7 +1586,10 @@ def _install_selection_listener(bridge): except Exception: pass return - # 2) Auto-Fill aus Ebenen-Definition + # 2) Auto-Fill aus Ebenen-Definition — nur ausserhalb User-Transform. + # Waehrend Move/Rotate werden Sub-Volumen erzeugt die kein Auto-Fill + # brauchen, und elemente uebernimmt die Coupling. + if sc.sticky.get("_dossier_user_transform_active"): return try: ok = _apply_ebene_fill(doc, obj) except Exception as ex: