Snapshot 2: Move/Rotate-Performance + Hatch↔Curve bidirektional

Performance-Optimierungen für User-Transform-Commands (_Move/_Rotate/etc):
- CommandBegin/End-Listener: Mein Code schläft während Rhinos Transform läuft
  komplett (Replace-Handler early-return). Beim CommandEnd vergleicht ein
  batch-Pass den Pre-Transform-Snapshot mit dem aktuellen State und macht
  EINEN konfliktfreien Sync-Regen pro betroffener Wand. Kein "Unable to
  transform"-Konflikt mehr, deutlich snappier.
- Sub-Volumen non-destruktiv: doc.Objects.Replace statt Delete+AddBrep wenn
  die Anzahl gleich bleibt (= häufiger Fall bei Brüstung/Höhe/XY-Drag).
- Migrate-Skip bei reinem Z-Drag: spart die Pass durch alle Öffnungen wenn
  XY unverändert ist.
- Sync-Regen-Deduplizierung im Batch via _dossier_skip_sync_regen Flag.
- Display-Suppress während des gesamten CommandEnd-Batch (kein sichtbares
  „Aufbauen" von Sub-Volumen).

Plus Gestaltung-Fix:
- Hatch→Curve Reverse-Sync via Hatch.Get3dCurves(outer=True): User kann die
  Hatch alleine verschieben/rotieren/skalieren → Curve folgt mit derselben
  Transform. Vorher nur Curve→Hatch.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-18 13:21:16 +02:00
parent 961b3c0396
commit 2dde46cb85
2 changed files with 250 additions and 22 deletions
+37 -1
View File
@@ -1374,11 +1374,47 @@ def _install_selection_listener(bridge):
except Exception: pass
def on_replace(sender, args):
"""Hatch der zugehoerigen Curve mitziehen wenn Curve veraendert wird."""
"""Sync Curve↔Hatch bei Move/Replace:
- Curve hat _FILL_KEY (= hatch_id) → Hatch via Hatch.Create neu auf die
aktuelle Curve aufsetzen (existierender Pfad).
- Hatch hat _FILL_OWNER_KEY (= curve_id) → Curve um den gleichen
Vektor mit-translaten (User hat Hatch alleine verschoben).
"""
new_obj = args.NewRhinoObject
if new_obj is None or new_obj.Id in _processing:
return
a = new_obj.Attributes
# 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.
if isinstance(new_obj.Geometry, rg.Hatch):
owner_id_str = a.GetUserString(_FILL_OWNER_KEY)
if not owner_id_str:
return
try:
owner_id = System.Guid(owner_id_str)
except Exception:
return
doc2 = Rhino.RhinoDoc.ActiveDoc
owner_obj = doc2.Objects.FindId(owner_id)
if owner_obj is None or owner_obj.IsDeleted:
return
try:
new_curves = new_obj.Geometry.Get3dCurves(True)
except Exception as ex:
print("[GESTALTUNG] hatch.Get3dCurves:", ex)
return
if not new_curves or len(new_curves) == 0:
return
new_curve = new_curves[0]
_processing.add(owner_id)
try:
doc2.Objects.Replace(owner_id, new_curve)
except Exception as ex:
print("[GESTALTUNG] hatch→curve replace:", ex)
finally:
_processing.discard(owner_id)
return
hatch_id_str = a.GetUserString(_FILL_KEY)
if not hatch_id_str:
return