UI:
- GeschossManager: Master-Eye + Master-Lock im Header (analog EbenenManager).
Scheren-Button pro Geschoss togglet hasClipping. Auge ganz links wie bei
Ebenen. Eye-Logik klar 4-Wege: aktive Z immer hell+on, in 'active'/'all_force'
fuer non-active gedimmt, sonst spiegelt Flag direkt. Schrift wird NIE gegrayt.
Neuer Mode 'all_force' = "Alle anzeigen" (ignoriert Eye), 'all' jetzt mit
Label "Ausgewaehlte" (respektiert Eye). Klick aufs Auge in 'active'/'all_force'
wechselt automatisch in "Ausgewaehlte" damit Aktion sofort wirkt.
- layer_builder.apply_visibility: neuer z_mode 'all_force' vor visible-Check —
zeigt jede Z auch wenn Eye=false war.
- elemente._cmd_create_oeffnung: gruene Live-Preview (vertikales Oeffnungs-
Rechteck + Breiten-Marker + Diagonale) waehrend Fenster/Tuer-Platzierung
entlang der Wand-Achse. Brueest-Offset aus Geschoss-UK korrekt im Z.
Performance Cold-Start:
- panel_base: Inlined-HTML als Modul-Cache (1x build, n-mal mount). Pro
Panel-Mount nur noch str.replace + LoadHtml. Spart bei 10 Panels 9x
~395 KB Disk-Read + Regex-Pass. Cache-Key = mtime von dist/index.html.
- Timing-Instrumentierung: _t_mark + print_startup_summary. Hook in startup.py
feuert 3s nach Plugin-Load + listet Wall-time, Top-10, Aggregat pro Phase.
- OberleisteBridge: Command-Enumeration (~1000 Commands) jetzt lazy via
Rhino.RhinoApp.Idle statt synchron im __init__. Cold-Start nicht blockiert,
Autocomplete kommt ~1 Frame spaeter.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Ebenenkombination raus aus Ebenen-Panel, in Oberleiste-Topbar +
Editor-Satellite (AusschnittLayerDialog embedded). doc.Strings
haelt active_comb_name, auto-clear bei manueller Eye/Lock-Aenderung.
- EbenenSettingsDialog jetzt Satellite mit Ebene-Picker-Dropdown
(auto-save on switch via SAVE_KEEP).
- Per-Ausschnitt Einstellungen-Satellite (Massstab, Display, Overrides,
Ebenenkombi). Alte 'Sichtbarkeit bearbeiten'-Option entfernt.
- Layouts/Ausschnitte: Top-Header weg, Sticky-Footer mit Anzahl +
Aktionen. LayoutDialog ist jetzt Satellite mit Format-Live-Preview.
- Panel-Captions + Default-Ebenen-Namen auf Mixed-Case (Ausschnitte,
Ebenen, Waende ...). Nur DOSSIER bleibt caps.
- DimensionenApp: Card-Optik raus, REF-Wuerfel mit Kreisen statt
Quadraten + Hover-Scale.
- GeschossManager angeglichen an EbenenManager: Rechtsklick-Menue,
Lock-Button, Delete-X, Duplizieren. layer_builder honoriert z.locked.
- Active Sublayer folgt jetzt dem Geschoss-Wechsel (gleicher Code
unter neuem Parent).
Performance Geschoss-Wechsel:
- elemente._send_state() ersetzt durch _notify_active_geschoss()
(Partial-Push statt 200+ Elements re-enumerieren).
- _apply_visibility dedupe via sticky last-applied-signature
(STATE_SYNC-Echo loopt nicht mehr durch alle Layer).
- _update_clipping nur wenn alt oder neu hasClipping=True.
- Redundante doc.Views.Redraw() im CPlane-Pfad entfernt — die folgende
apply_visibility-Roundtrip redrawt 30ms spaeter ohnehin.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Rhinos Mirror/Copy/Array kopiert selektierte Objekte mit ihren UserString-
Metadaten → Duplikat-IDs im Doc (z.B. zwei `wand_axis` mit gleicher
`id=wall_xxx`). Resultat: unser System sieht beide als „dasselbe Element",
fasst sie verkoppelt an, Pure-Transform wird konfus, Original wand_volume
wandert mit weil bb-snapshot matched.
Fix in `_on_command_end`, BEVOR Pure-Transform-Detection laeuft:
1. Snapshot speichert jetzt `obj_ids`-Set aller pre-Command Rhino-Object-Ids.
2. Pass A: alle neuen Sources (obj.Id nicht im Snapshot) deren UserString-id
bereits in `sources_snap` existiert → identifiziert als Mirror/Copy-
Duplikat, neue UUID generiert (gleicher Prefix wie bei Original-Erzeugung).
3. Pass B: alle neuen Volumes mit id = alter-renamed-Source → bekommen die
neue ID + `oeff_parent` wird umgehaengt wenn ihre Eltern-Wand renamed.
4. Pass C: neue oeffnung_points kriegen `oeff_parent` auf renamed Wand
umgehaengt.
5. Pass D: alle gesammelten Renames atomar via ModifyAttributes anwenden.
Resultat: Mirror-Kopie ist nach CommandEnd ein vollstaendig eigenstaendiges
Element mit eigenen IDs + intakter Parent-Cascade. Pure-Transform sieht
saubere Snapshot-vs-aktuell-Bilanz (Originale=Identity, Kopien außerhalb
des Snapshots → keine Action erforderlich, Rhino hat sie schon geometrisch
korrekt platziert).
Funktioniert generisch fuer Mirror, Copy, Array — alle dup-id-erzeugenden
Operationen. Im Log: `[ELEMENTE] mirror/copy-Duplikate: N Objs neu-ID'd`.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Erweitert die bisherige Pure-Translate-Optimierung auf beliebige
Rigid-2D-Transforms (Translation + Z-Rotation). Statt nur einen
Delta-Vektor zu detektieren, wird pro Source ein Rigid-Transform aus
Snapshot-vs-aktueller-Geometrie berechnet:
- Curve-Sources: aus Endpunkten Drehwinkel + Translation ableiten.
- Length-Aenderung der Curve → Scale/End-Grip → abort_pure.
- Z-Aenderung der Curve → Z-Drag → abort_pure (UK_OVER-Schreibung
geht weiter ueber Regen-Pfad).
- Point-Sources: nur Translation aus Position.
Konsistenz-Check: alle Curve-Transforms muessen identisch sein,
Point-Positionen muessen `canonical(old_pos) == new_pos` erfuellen.
Sonst → Regen.
Bei pure_transform != None: Transform auf alle Geometries der
Cascade anwenden die nicht schon von Rhinos Move/Rotate
transformed wurden. Volumes via bb-Snapshot-Check, Sources via
identity-transform-check.
Resultat: einzelne Wand + Oeffnungen rotieren → instant statt
~100-200ms Regen.
Mirror-Limitation: Einzelne Wand-Spiegelung wird als 180°-Rotation
interpretiert (matched die Endpunkte). Bei symmetrischen Volumen
unsichtbar; bei asymmetrischen Fenstern visuell anders als ein
echter Mirror. Mehrere Walls gleichzeitig spiegeln triggert
all_consistent=False → Regen-Fallback (korrekt). Bekannte
Einschraenkung, separater Fix nötig.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Bug: Bei Rotation um einen externen Punkt liegt der Öffnungs-Punkt
nach Rhinos Transform NICHT mehr auf der alten Achse → migrate's
ClosestPoint(current_pos) snappte zum nächsten Endpunkt der alten
Achse → relative=1 → alle Öffnungen landeten am gleichen Ende der
neuen Achse (= „bei Referenzpunkt der Drehung").
Fix: Migrate nutzt jetzt die PRE-TRANSFORM Position aus dem Snapshot
(via `old_positions` Parameter). Aufrufer im CommandEnd-Regen-Pfad
sammelt die alten Positionen aus `sources_snap` und gibt sie weiter.
Migrate setzt opening_point.Z jetzt auch konsistent auf
`wall_uk + brüstung` statt nur `brüstung` — vermeidet Brüstung-Drop
beim nachfolgenden _apply_oeffnung_constraint.
Constraint überspringt XY-Projektion wenn Wand gerade migriert
wurde (`_dossier_migrated_walls` sticky-Set) — sonst würde
ClosestPoint(pt_old) auf neuer rotierter Achse die Position wieder
verschieben.
Debug-Logs in _apply_wand_z_drag_constraint + Wand-Regen bleiben
drin — haben bei der Eingrenzung des UK_OVER-Bugs geholfen, kosten
nichts.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Funktionierender Stand der Move/Rotate-Pipeline mit Eltern-Kind-Cascade
und sauberer Brüstung-Semantik:
- Pure-Translate hierarchisch: nur Sources mit echtem Delta + ihre Kinder
(Öffnungen → Wand) folgen mit. Wand folgt NICHT der Öffnung.
- Orphan-Detection: Öffnung ohne mitbewegter Eltern-Wand → Regen-Fallback
(sonst bleibt Cutout am alten Ort im Wand-Brep).
- Brüstung = relativ zur Wand-UK (Archicad/Revit-Konvention). Bei Wand-
Z-Drag wird UK_OVER angepasst, Brüstung bleibt; Öffnungs-Punkt wandert
via Snapshot+Delta mit. Keine Doppel-Addition mehr.
- Opening-Punkt wird beim Erzeugen direkt auf UK+brüstung platziert
(sonst Brüstung-Drop beim ersten Move).
- Undo-Record umschliesst Rhinos Move + unseren Regen in einem Cmd+Z-
Schritt → keine doppelten Elemente nach Undo.
- RedrawEnabled-Suppression event-getriggert (erst beim ersten Replace-
Event nach User-Klick) → Rubber-Band + Drag-Vorschau bleiben sichtbar.
- _Undo/_Redo: Event-Handler komplett aussetzen → kein Regen-Storm.
- Gestaltung-Listener während User-Transform + Regen stumm, danach
einmaliger Selection-Refresh.
Enthält Debug-Logs in _apply_wand_z_drag_constraint + Wand-Regen
für offenen Bug: bei gemeinsamer Z-Verschiebung (Wand+Fenster+Tür)
landen Öffnungen manchmal über der Wand — UK_OVER scheint nicht
durchzukommen. Logs sollen das eingrenzen.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Im CommandEnd-Batch wird jetzt zuerst auf pure-translate gecheckt:
- Alle bewegten Source-Geometrien haben EXAKT denselben Delta-Vektor
- Beide Endpunkte einer Wand-Achse haben gleichen Vektor (= kein End-Grip-
Drag, kein Rotate/Scale)
- Keine Z-Komponente in den Deltas (= kein Brüstungs-Property-Change)
Wenn alle Bedingungen erfüllt: REINE TRANSLATION aller Geometrien um den
Delta-Vektor. Sub-Volumen die schon von Rhinos Multi-Select-Move
transformed wurden (BBox-Center verschoben) werden geskippt; nur die
unbewegten kriegen Translate(vec). KEIN Wand-Regen, KEIN Boolean-Diff →
instant.
Snapshot um Volume-BBox-Centers erweitert für die Same-Position-
Detection. Bei Property-Änderung (Brüstung/Höhe/Breite/Rotate) fällt's
automatisch auf den vollen Regen-Pfad zurück.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
`_regenerate_element_body` Wand-Pfad: alle Öffnungs-Cutouts werden jetzt in
EINEM BooleanDifference-Call pro Wand-Schicht subtrahiert (statt N einzelne
Calls). Bei einer 3-schichtigen Wand mit 2 Öffnungen: 3 Boolean-Ops statt 6.
Plus: Toleranz auf 0.001 m (= 1 mm) festgesetzt. Architektur-Genauigkeit
reicht, und Boolean-Diff läuft mit dieser Toleranz spürbar schneller als
mit feineren Werten.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
elemente.py:
- Idle-Pfad Brüstungs-Mitnahme entfernt — war Duplikat zur CommandEnd-Logik
und konnte je nach Reihenfolge entweder doppelt anwenden oder gar nicht
(race condition mit `_elemente_wand_z_delta` Sticky-Reset).
- `float(z_delta)` mit try/except für ValueError/TypeError gewrapped —
vorher konnte ein korruptes Sticky-Tuple den Idle/CommandEnd-Pass crashen.
- `_elemente_replace_selected_ids` wird nach Migrate consumiert (auf None
gesetzt). Sonst blieb eine stale Liste hängen und beeinflusste spätere
unverwandte Migrations.
- Einrückung im CommandEnd-Brüstungs-Block normalisiert.
Dead Files:
- `rhino/startup.py3` entfernt — veraltetes Backup ohne Marker-Code für den
Launcher-Splash. `rhino/startup.py` ist die aktuelle Version.
- `rhino/__pycache__` aufgeräumt (war eh in .gitignore).
Kein funktionales Verhalten geändert. Audit-Findings HIGH/MEDIUM bereinigt.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
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>
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>