Commit Graph

34 Commits

Author SHA1 Message Date
karim 700cc11956 Oberleiste-Mittelweg: BAR_H 22, Font zurueck 11, Logo 17 — Toolbar-Gap bleibt
User: vorher zu klein. Mittelding zwischen 24 (original) und 20 (zu klein):
- BAR_H 20 → 22, PILL_H 18 → 20, Sep 18 → 20
- Select-Font 10 → 11, Padding 22/10 → 24/12, Caret 8 → 9
- BarButton Icon 12 → 13
- View-Toggle Font 9 → 10, Icon 12 → 13, Padding 8 → 10, Gap 3 → 4
- Live-Zoom Font 10 → 11, MinWidth 56 → 60
- Custom-Input Width 90 → 100, Padding 10 → 12, Font 10 → 11
- Logo 15 → 17

Toolbar-Gap 6 + Padding 3/10/6 bleiben (User: "find ich gut").

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 22:39:58 +02:00
karim 66d6e63959 Oberleiste etwas kleiner — BAR_H 24→20, Fonts 11→10, Logo 18→15
User-Wunsch: alles etwas kleiner. Konsistent runter:
- BAR_H 24 → 20 (Selects, Buttons, View-Toggle, Live-Zoom, Massstab-Input)
- PILL_H 20 → 18 (Legacy-Pills)
- Sep 22 → 18 hoch, 4 → 3 Margin
- Toolbar-Gap 8 → 6, Padding 4/12/8 → 3/10/6
- Logo "DOSSIER." 18 → 15
- Select-Font 11 → 10, Padding 26/12 → 22/10, Caret-Pos 10 → 8
- View-Toggle: Font 10 → 9, Icon 13 → 12, Padding 10 → 8
- BarButton Icon 13 → 12
- Live-Zoom Font 11 → 10, MinWidth 64 → 56, Padding 12 → 10
- Custom-Massstab-Input: Width 100 → 90, Font 11 → 10

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 22:36:06 +02:00
karim cf40c03602 Zurueck zum Vectorworks-Look — Custom Pill-Chrome statt raw native HTML
User-Klaerung: erwartet wird der polierte Vectorworks-Style, nicht rohe
macOS-HTML-Form-Elemente. Vectorworks ist custom-gestylt um nativ
auszusehen, aber mit konsistentem Toolbar-Polish.

Zurueckgerollt:
- BarSelect: Pill-Container (bg-item, border, border-radius 999) +
  Custom-SVG-Caret aus --select-arrow. appearance:none. Icon roh links
  (Userpraferenz). joinedRight macht rechte Pill-Kante flach.
- BarButton: Pill-Container mit border + border-radius 999. active=true
  setzt accent-Background + bg-panel-Iconfarbe (klare Toggle-Anzeige).
  joinedLeft macht linke Kante flach fuer Verkettung.
- View-Toggle (Top/Front/Right/Iso/Persp): Segmented-Pill-Gruppe analog
  Vectorworks. Innere Kanten ohne Border, Aussenkanten gerundet.
  Active-Button: accent-fill + Bold.
- Custom-Massstab-Input: Pill-Chrome zurueck.

.native-control CSS-Klasse bleibt definiert (zukuenftige Verwendung), wird
aber in der Oberleiste nicht mehr referenziert.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 22:28:17 +02:00
karim e19bbafe38 .native-control auch fuer Buttons — View-Toggle + BarButton system-nativ
User-Screenshot: dropdowns waren native, aber View-Toggle (Top/Front/...)
und die Icon-Buttons (Camera/Gear/Zoom/etc.) sahen weiterhin custom aus.

Grund: globales `button { border: none; background: none; }` strippt das
System-Push-Button-Styling fuer alle <button>s. `.native-control` deckte
nur select + input ab.

Fix:
- `.native-control` erweitert auf `button.native-control`: revert auf
  alle Button-Reset-Properties → WebKit rendert macOS-Push-Button-Chrome
- `.is-active`-Modifier: bold + accent-Tint fuer Toggle-Active-State
  (macOS-Native hat keinen "pressed-Toggle"-Look fuer normale Buttons)
- BarButton: className="native-control" + active=true → is-active
- View-Toggle (Top/Front/Right/Iso/Persp): pill-Container weg,
  individuelle native buttons mit is-active wenn matchView() true

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 22:18:37 +02:00
karim 8ad9e23838 .native-control Opt-out: global select-Style ueberschrieb das System-Native
User-Screenshot: dropdowns sehen immer noch wie pills aus. Grund: das
globale `select { appearance: none; background-image: var(--select-arrow);
border-radius: 999px; ... }` in index.css uebermalte die Inline-Resets von
BarSelect — globale CSS-Specificity gewann.

Fix:
- Neue `.native-control`-Klasse in index.css setzt mit `revert` alle
  pill-Overrides zurueck → WebKit/macOS rendert wieder Default-Combobox
- BarSelect: className="native-control" am <select>
- Custom-Massstab-Input: className="native-control"

Andere Selects im Projekt behalten den pill-Look (Ebenen-/Geschoss-Manager
etc.) — nur die Oberleiste opt-out.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 22:14:53 +02:00
karim 536d42f097 BarSelect/BarButton: bare native chrome auch im Ruhezustand
User-Wunsch: nicht nur das Popup, auch das Feld selber soll system-nativ
aussehen. Vorher hatten die <select>-Elemente noch pill-Background +
Border + Radius — das uebermalte WebKits Native-Look.

BarSelect: alle Styling-Overrides entfernt (background/border/border-radius
weg). Nur Hoehe/Breite/Font/colorScheme bleibt — macOS rendert jetzt das
gewoelbte System-Combobox-Feld inkl. nativem Drop-Caret.

BarButton: analog umgestellt — kein eigener Container, native <button>-
Chrome. active-State via accent-color (CSS) + Icon-Tint.

Custom-Mode-Massstab-Input (1:N): pill-Styling weg, nativer <input>.

joinedRight/joinedLeft Props bleiben akzeptiert aber sind no-ops — native
Felder lassen sich nicht visuell verketten.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 22:12:15 +02:00
karim 2e6dc44923 BarSelect: system-natives <select> + colorScheme:dark (Versuch Vectorworks-Style)
User-Wunsch: Dropdowns wie bei Vectorworks — also nativer OS-Look statt
Custom-Caret + custom Popup.

BarSelect umgebaut:
- appearance:none entfernt → WebKit/macOS rendert seinen eigenen Down-Caret
- custom <Icon arrow_drop_down> entfernt
- pill-Container weg, das <select>-Element selbst traegt jetzt direkt das
  pill-Styling (Hintergrund, Border, Border-Radius)
- colorScheme: 'dark' inline und auch global in index.css gesetzt
  damit macOS-Native-Controls die Dark-Mode-Variante rendern

index.css:
- :root color-scheme: light (default)
- @prefers-color-scheme: dark → color-scheme: dark
- Wirkt auf alle nativen Controls (selects, scrollbars, checkboxen)

Resultat: Klick auf ein Dropdown oeffnet das echte macOS-Popup-Menue
(wie in Vectorworks) statt das HTML-Browser-Dropdown.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 22:08:56 +02:00
karim c8286b931b About-Dialog als eigenes Fenster (Eto-Form + WebView) statt Inline-Modal
User-Feedback: About sollte nicht als overlay im Panel erscheinen sondern
ein echtes OS-Fenster sein wie Kamera/Masse-Settings.

Neu:
- rhino/about.py: open_as_window() via panel_base.open_satellite_window
  (read-only, kein Bridge-Save/Cancel-Callback noetig)
- src/AboutApp.jsx: gleiche Inhalte wie der vorige Modal — Versionen,
  Autor, Website, Lizenz — in einer 440x380 Eto-Form
- src/main.jsx: mode 'about' → AboutApp
- openAbout() in rhinoBridge.js sendet OPEN_ABOUT an Oberleiste
- OberleisteBridge handler OPEN_ABOUT → about.open_as_window()

OberleisteApp:
- Logo-onClick aufgeräumt: openAbout() statt setAboutOpen(true)
- aboutOpen-State und die AboutModal-Komponente entfernt

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 22:07:23 +02:00
karim 76572968ca Oberleiste: Icon roh + Pill-Dropdowns, About-Modal, Overrides/Kombi migriert
User-Feedback: Icon-Box war zu plakativ, lieber roh daneben + Pill-Form.
Versionsnummer raus, Logo-Klick → About-Fenster.

BarSelect umgebaut:
- Icon roh links (vorher: separates Icon-Kompartiment mit Border)
- Select-Container pill-foermig (border-radius 999, vorher 4)
- joinedRight wird zu flachen rechten Pill-Kanten (statt rechteck)

BarButton: pill-foermig + joinedLeft mit flacher linker Kante.

View-Toggle: Pill-Container statt Rechteck.
Massstab Live-Zoom-Chip: Pill-Form.
Custom-Scale-Input: Pill-Form.

Logo:
- Versionsnummer-Span entfernt
- ganzes Logo wird zu Klick-Button → AboutModal-State
- AboutModal: zentrierter Backdrop-Dialog mit Launcher/Plugin-Versionen,
  Autor (Karim Gabriele Varano), Website (gabrielevarano.ch),
  Lizenz (Proprietaer)

Overrides + Kombi migriert (war noch im alten Stack-Layout):
- Overrides: BarButton (Toggle) + BarSelect (Preset) joinedRight + BarButton
  (Settings) joinedLeft, palette-Icon fuer Preset-Picker
- Kombi: BarSelect (layers-Icon) mit allen Aktionen im Dropdown
  (Speichern, Loeschen, Bearbeiten) + BarButton (edit) joinedLeft
- Stack-Layout (label-Spalte + 2 Reihen) ist weg, jetzt inline

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 22:00:07 +02:00
karim c22aef6b65 Oberleiste Vectorworks-Style: Icon links + rechteckige Bar-Widgets
User-Referenz: Vectorworks Topbar. Drei Cues uebernommen:
- Icon-Kompartiment links im Dropdown (statt UPPERCASE Group-Label oben)
- Rechteckige Form mit dezenter Trennlinie zwischen Icon-Box und Inhalt
- Verbundene Widgets (Select + Settings-Gear) als eine visuelle Einheit

Neue Komponenten in OberleisteApp.jsx:
- BarSelect: [Icon | Native-Select | Caret] in einer 24px-Container-Box.
  appearance:none entfernt den nativen Pfeil, eigener arrow_drop_down rechts.
  joinedRight-Flag fuer nahtloses Anschliessen an einen BarButton.
- BarButton: quadratischer Icon-Button, joinedLeft kein doppelter Border,
  active=true → Accent-Background (fuer Toggles wie Print-View).

Migrierte Gruppen:
- View: 5 Toggle-Buttons in einem zusammenhaengenden Rahmen (kein Group-Label),
  selektierter Button accent-gefuellt analog VW Custom-View-Highlight
- Display: BarSelect (lightbulb icon)
- Masse: BarSelect joinedRight + BarButton joinedLeft (zahnrad)
- Massstab: Live-Zoom-Chip (eigene Box), BarSelect (straighten icon),
  BarButton (percent / fit_screen / center_focus_strong)
- Print/Edit-Toggle: BarButton mit active-State

Stack-Block (Overrides + Kombi) bleibt erst — separate Architektur,
nicht im Vectorworks-Vergleich enthalten. Migration spaeter wenn Bedarf.

PILL_H bleibt fuer nicht-migrierte Stellen, BAR_H = 24 fuer die neuen.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 21:52:36 +02:00
karim 2ee4688fe3 Masse-Dropdown in Oberleiste + Satellite-Settings statt Dimensionen-Inline
User-Feedback: Mass-Style passt nicht ins Dimensionen-Panel, und der
Name "Mass-Style" gefaellt nicht. Umzug in die Oberleiste (analog Display)
+ Zahnrad oeffnet eigenes Settings-Fenster. UI-Begriff jetzt "Masse".

Frontend:
- OberleisteApp: neue Gruppe "Masse" mit Preset-Dropdown + Zahnrad-Button
  zwischen Display und Massstab
- MasseSettingsApp.jsx (neu): Satellite-Fenster mit Name/Raum-Rundung/
  Mass-Dezimalstellen/Mass-Einheit + Picker + Add/Delete
- DimensionenApp: MassStyleSection raus
- rhinoBridge: setMasseActive + openMasseSettings (Topbar);
  masseSetActive/masseSavePreset/masseDeletePreset (Settings-Fenster)

Backend:
- rhino/masse_settings.py (neu): Bridge fuer das Satellite-Fenster,
  Topics SET_ACTIVE / SAVE / DELETE, triggert regen_all_rooms + topbar refresh
- mass_style.regen_all_rooms(doc): neue cross-modul-Helper, queued
  Raum-Regen fuer alle raum_outline-Objekte
- oberleiste.py: massePresets + masseActiveId im State, SET_MASSE_ACTIVE
  + OPEN_MASSE_SETTINGS handler, Signature update
- dimensionen.py: Mass-Style-Endpoints + State raus (sind jetzt im
  OberleisteBridge bzw. MasseSettingsBridge)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 21:29:23 +02:00
karim 0b4b25cf47 Mass-Style Preset (Raum-Rundung + Dim-Format) + Rundung als Dropdown
Frontend:
- RaumProperties Rundung: 5er-Button-Reihe → Dropdown mit "Aus Mass-Style"
  als erstem Eintrag (leer = Default aus aktivem Preset uebernehmen)
- Dach-Typ + Mansarde-Variante: text-only Button-Reihen → Dropdowns
- Mass-Style-Section neu im DimensionenApp ganz oben:
  - Picker fuer aktives Preset
  - + (neu mit aktuellen Werten als Vorlage) / Loeschen
  - Inline-Editor: Name, Raum-Rundung, Mass-Dezimalstellen, Mass-Einheit

Backend (rhino/mass_style.py — neu):
- doc.Strings["dossier_mass_styles"]: JSON-Liste der Presets
- doc.Strings["dossier_mass_style_active"]: aktive Preset-ID
- list_presets/save_preset/delete_preset/get_active_id/set_active_id
- Convenience: raum_rundung_default(doc), dim_dezimalstellen_default(doc)
- Default-Presets bei erster Initialisierung: 1:50 / 1:100 / 1:500

elemente.py:
- _read_meta: raum_rundung leer wenn UserString fehlt (vorher gezwungen "0.1")
- _resolve_raum_rundung(meta, doc): per-Raum-Override > Mass-Style-Default
- _make_raum_stamp_text + state-send nutzen Resolver
- State sendet rundung (raw, kann "" sein) + rundungEffective + areaFmt
  damit React-Panel "Aus Mass-Style" anzeigen kann

dimensionen.py:
- Bridge-Endpoints MASS_STYLE_SET_ACTIVE / SAVE / DELETE
- _broadcast_raum_regen: bei Preset-Wechsel alle Raeume queuen → Stempel-
  Flaechen kommen mit neuer Default-Rundung
- _compute_state liefert massStyles + massStyleActive + signature update

NOCH NICHT verdrahtet: Mass-Linien-Formatierung (dimDezimalstellen,
dimEinheit) — Datenmodell ist da, Anwendung auf Rhino-Dimension-Renderer
folgt in einem naechsten Schritt.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 21:18:15 +02:00
karim b69dd8e279 Kamera-Panel + Iso-Button in der Oberleiste
Oberleiste:
- View-Gruppe: Iso-Button neu zwischen Right und Persp
- matchView: Iso = parallel ohne orthogonalen Standard-Namen,
  Perspektive = !parallel — beide via Projektions-Flag unterschieden
  (Rhino-Viewport-Name ist oft "Perspective" fuer beide)
- Camera-Knopf (Icon: videocam) oeffnet das neue Kamera-Panel
- SET_VIEW Backend: 'Iso' faelltt auf kamera._set_iso(vp, "NE")
- OPEN_KAMERA_PANEL Handler

Kamera-Panel (neu — rhino/kamera.py + src/KameraApp.jsx):
- Viewport-Name + Projektions-Toggle (Persp/Parallel)
- 4 Iso-Quick-Buttons (NW/NE/SE/SW) — true-iso 35°/45°,
  Kamera-Distanz auto aus Szenen-BBox
- Vec3-Felder fuer Kamera-Position + Blick-Ziel (numerisch
  editierbar, m)
- Distanz read-only
- Brennweite (mm) bei Persp, Frustum-Breite (m) bei Parallel
- Zoom-Extents-Button
- Presets: speichern + anwenden + loeschen, persistiert in
  doc.Strings["dossier_kamera_presets"] (JSON)
- Eto-Form-Satelliten-Fenster (420x600) via panel_base.open_satellite_window

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 20:41:50 +02:00
karim b14eb1e5dd Ebenen-Manager: Eye-Logik analog Geschosse + 'Alle anzeigen'-Mode
Eye-Knopf bleibt jetzt auch in „Nur aktive"-Mode sichtbar (dimmend, statt
zu verschwinden). Klick auf Eye in „Nur aktive" oder „Alle anzeigen"
wechselt automatisch zu „Ausgewählte" damit die Aktion wirkt.

Backend (layer_builder.apply_visibility): neuer e_mode 'all_force'
ueberschreibt das Eye-Flag (zeigt alle Ebenen). 'all' respektiert weiter
das Flag (= „Ausgewählte" im UI).

Frontend (EbenenManager):
- MODES: 'all_force'=„Alle anzeigen" hinzu, 'all' umbenannt zu „Ausgewählte"
- EbeneRow: eyeIcon/eyeOpacity/eyeTitle nach Mode, analog GeschossManager
- handleToggleVisible + Master-Eye: bei active/all_force → onModeChange('all')

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 13:26:25 +02:00
karim b425421fdd Swisstopo + OSM Importer + Höhenlinien + Bulk-Op Performance
Swisstopo Iter 3:
- Ortho-Drape: TIN-Mesh aus Terrain-Grid mit per-vertex UVs + PictureFrame-Material
- Project-Cache: TIFs werden neben .3dm gespeichert (SMB-shareable)
- Layer-Restruktur: 80_swisstopo/{Terrain, Luftbild} Sub-Ebenen
- TIFs direkt (kein PNG-Downsampling) für volle Auflösung
- UV-Inset gegen weisse Streifen zwischen Kacheln
- Hoehenlinien (2D, swissALTI3D) auf aktives Geschoss OKFF projiziert
- TIN-Mesh + Schichtenmodell aus Contours (separate Optionen)
- TLM3D entfernt (swisstopo liefert nur GDB/SHP, kein DXF)

OSM Importer (neu):
- rhino/osm.py: Overpass-API-Client
- src/OsmApp.jsx: React-Dialog mit Adresse + Radius + 7 Kategorien
- Strassen/Gebäude/Wasser/Wasserläufe/Parks/Wald/Fusswege (Codes 7101-7107)
- ElementeApp: PillGroup "Importer" mit Swisstopo + OSM Buttons

Sub-Ebenen — rekursiv durch hierarchische Ebenen:
- Visibility-Toggle: slimEbene rekursiv (children bleiben erhalten)
- Settings-Dialog: _find_sublayer_by_code_recursive + _replace_in_tree
- Hatch Auto-Fill: refresh_layer_fills + _fill_signature + _ebene_fill_for_layer
  alle rekursiv durch children
- EbenenSettingsApp: flattenEbenen-Helper

Bulk-Op Performance (Delete/Cut/etc.):
- _USER_BULK_CMDS + _BULK_ACTIVE_KEY Sticky-Flag
- CommandBegin: doc.Views.RedrawEnabled = False + Listener-Bail aktiv
- CommandEnd: RedrawEnabled restore + 1× Redraw + Selection-Refresh
- Bail-outs in dimensionen.on_idle/on_select, elemente._on_idle_selection,
  gestaltung.on_idle_flush/on_delete
- Verhindert das sichtbare "Runterzählen" pro Element bei Bulk-Delete

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 02:42:45 +02:00
karim 85f09390bc Ortho-Foto sichtbar (PictureFrame) + Oberleiste-Polish
Swisstopo Ortho
- AddPictureFrame statt Mesh+Material — Rhinos eigener Picture-Pfad mit
  embedBitmap=True + selfIllumination=True macht die Textur in allen
  Display-Modi sichtbar (Wireframe / Shaded / Rendered / Raytraced)
- asMesh=False (Brep-Variante) — asMesh=True ist auf Mac Rhino 8 broken
  (alle Pictures landen am gleichen Punkt unabhaengig von der Plane)
- Per-Tile Sub-Ebenen unter 80_swisstopo (z.B. 80_swisstopo/2763-1254_Ortho)
  via dossier_ebenen JSON registriert → erscheinen im Dossier-Ebenen-Manager
  mit eigener Visibility
- target_layer_idx wird vor AddPictureFrame als Active-Layer gesetzt,
  Picture landet direkt auf richtigem Sub-Layer (Move-danach broeselte
  das Material)
- Regex-Fix in _parse_swisstopo_tile_bbox: Separator zwischen den beiden
  Coords MUSS Hyphen sein, sonst matcht es faelschlich auf `_YEAR_EAST_`
  Patterns wie `_2025_2763_`

Oberleiste
- DOSSIER. Logo (Krungthep + Petrol-Punkt) + Launcher-Version
  (via __LAUNCHER_VERSION__ Vite-Define aus launcher/package.json)
- Overrides + Kombi vertikal gestapelt, gleiche Label-Spalte + Dropdown-
  Breite → Dropdowns auf gleicher X-Linie
- View-Icons neu zugeordnet:
    Top=view_quilt (Raster), Front=north (Pfeil), Persp=view_in_ar (3D)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 00:44:19 +02:00
karim afb59b6626 Swisstopo Iter 2 + hierarchische Ebenen + 0-Kote m.ü.M
Swisstopo
- swissBUILDINGS3D 3.0 + Variant-Toggle (separated/solid) im Dialog
- Auto-Fallback auf 2.0 wenn 3.0-Tiles ueber 200 MB sind (Stadt-Fall)
- Defensiver Variant-Filter auf 3 Ebenen (Item, Asset, ZIP-Extract) — keine
  Doppelimporte mehr
- Auto-Skala korrigiert jetzt die importierten Objekte (×1000) statt die
  User-bbox zu schrumpfen — Buildings bleiben in m-Doc-Skala
- merge_grids: XYZ-Tiles werden vor dem Mesh-Bau vereint, kein 1m-Streifen
  zwischen Tiles mehr
- Layer-Konsolidierung: Build_*/Roof_*/Wall_*/Floor_* DWG-Source-Layer
  werden auf Sub-Sub-Layer unter 81_Swissbuildings/{Build,Roof,Wall,Floor}
  gemappt; solid-Variante landet flach direkt auf dem Parent
- 0-Kote m.ü.M (Projekt-Nullpunkt) wird beim Import als Z-Offset angewandt

Hierarchische Ebenen
- dossier_ebenen unterstuetzt jetzt 'children'-Array (rekursiv)
- layer_builder.build_layers rekursiv (Parent + Children unter jedem Geschoss)
- apply_visibility/update_layer_style/set_ebene_visible/set_ebene_locked
  walken den Tree (Sub-Sub-Layer mit gleichem Code-Prefix werden mit-gepflegt)
- EbenenManager mit Chevron-Toggle + Indent pro Level + Context-Menue-Item
  'Sub-Ebene hinzufuegen'
- rhinoBridge.applyVisibility schickt Children-Tree (nicht nur Top-Level) —
  sonst kommen Sub-Toggles nicht beim Backend an
- Visibility-Key in App.jsx rekursiv durch Children — useEffect feuert jetzt
  auch bei Sub-Eye-Toggles

0-Kote m.ü.M
- Eingabefeld im Geschoss-Settings-Dialog (projektweit)
- Speicherung als dossier_project_zero_mum in doc.Strings
- Wird im Swisstopo-Import als Z-Offset (m + doc-units) angewandt

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-19 23:21:45 +02:00
karim 4111f12f32 Swisstopo Importer: STAC-API + Terrain-Mesh + Ortho-Drape (Iteration 1)
Frontend:
- src/SwisstopoApp.jsx NEU: Satelliten-Fenster mit Adresse-Suche, Radius-
  Wahl, Daten-Checkboxen (Gebäude/Terrain/Luftbild), Origin-Handling, Live-
  Log
- ElementeApp Swisstopo-Gruppe: Importer-Button + Karte-Button

Backend:
- rhino/swisstopo.py NEU: STAC-API-Client, Geocoding via swisstopo Search,
  LV95↔WGS84-Konvertierung, GeoTIFF/XYZ-Cache, mesh_from_grid + Ortho-Material
- swissBUILDINGS3D 2.0 (DXF/DWG) via STAC; Per-Tile-Filter (_NNNN-NN_)
  schuetzt vor versehentlichem Download der 3.5 GB National-Geodatabase
- swissALTI3D als XYZ-ZIP mit zipfile-Extraction, raeumliches Sub-Sampling
  statt Zeilen-Step (keine Streifen mehr im Terrain-Mesh)
- SWISSIMAGE 10cm GeoTIFF als RenderMaterial-DiffuseBitmap mit planarem
  UV-Mapping auf den Terrain-Mesh-bbox

Robustheit:
- Auto-Skala-Erkennung: Rhinos DXF-Parser scaliert je nach \$INSUNITS auf
  unerwartete Doc-Units; wir messen aus ersten 50 Objekten + snappen auf
  Zehnerpotenz (1, 0.001, 1000)
- bbox + origin_shift in doc-units (m_to_unit aus UnitScale + Auto-Detect)
- Tags via UserString dossier_swisstopo_kind=buildings/terrain fuer
  Replace-Detection bei erneutem Import desselben Gebiets
- BBox-Clip jetzt OPTIONAL (Default OFF, Checkbox) — bei InstanceReferences
  GetBoundingBox + Delete teuer
- Batch-Transform via System.Collections.Generic.List[Guid] statt
  Python-Loop (Python.NET-Overload-Match)
- Listener-Suppression in elemente.py + gestaltung.py + dimensionen.py
  via sticky dossier_swisstopo_busy — kein Per-Object-Spam mehr bei
  Selection/Add/Delete waehrend 5000+ Imports
- Auto-Zoom via view.ZoomBoundingBox(combined) statt Select-Loop
- Year-Dedupe auf Tile-Coord (Pattern YYYY oder YYYY-MM unterstuetzt) fuer
  alle Collections — aeltere Versionen werden ausgefiltert
- Download-Safety: > 200 MB wird abgebrochen + Live-Progress alle 2 MB
  mit UI-Yield via Rhino.RhinoApp.Wait()

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-19 18:22:48 +02:00
karim 222b00c113 Zeichnungsmanager Master-Controls + Scheren + Startup-Perf + Oeffnung-Preview
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>
2026-05-19 04:36:56 +02:00
karim 95031ee2c0 Panels poliert: Ebenenkombi in Oberleiste, Satelliten-Dialoge, Caps weg, Perf
- 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>
2026-05-19 03:58:28 +02:00
karim e3918cb155 Overrides-Fenster aufgeräumt + Rule-Templates
UX-Cleanup:
- Globaler AN/AUS-Toggle entfernt — den gibt's bereits in der
  Oberleiste, doppelt war redundant.
- Reload/Refresh-Button entfernt — Backend re-applied automatisch
  bei jeder Regel-Aenderung, manuelles Reload nicht noetig.
- + (Neue Regel) wurde aus dem Header in eine neue Sektion
  UNTER der Kombinationen-Card verschoben.

Neues Feature: Rule-Templates (einzelne wiederverwendbare Regeln)
- Storage: ~/Library/.../override_rule_templates.json (cross-doc,
  parallel zu den Kombinationen-Presets)
- API in overrides.py: list/save/load/delete_rule_template
- Bridge-Messages: SAVE_RULE_TEMPLATE, DELETE_RULE_TEMPLATE,
  ADD_FROM_TEMPLATE
- State enthaelt jetzt ruleTemplates: [{name, rule}]

UI:
- Neuer Bereich "Neue Regel" unter Kombinationen: [+ leer] +
  [+ Aus Vorlage ▼ dropdown]
- Vorlage waehlen → insert auf hoechste Prio (gleich wie addRule)
- Im Dropdown unten: "🗑 <name> loeschen" zum Entfernen einer Vorlage
- Im Rule-Kontextmenue: neuer Eintrag "Als Vorlage speichern…"
  fragt nach Name, speichert die Regel cross-doc

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-19 02:10:31 +02:00
karim 42d9c1e27b Overrides als Satelliten-Fenster vom Oberleiste-Gear öffnen
OVERRIDES war als gedocktes Panel zu schmal. Jetzt: kein Panel mehr,
sondern ein echtes Rhino-Fenster (Eto.Form + WebView, frei verschieb-
und resizable), das vom Oberleiste-Gear-Button geoeffnet wird.

panel_base.open_satellite_window:
- Akzeptiert jetzt optional einen `bridge`-Parameter. Wenn gegeben,
  wird die Custom-Bridge (z.B. OverridesBridge) statt der einfachen
  inline SAVE/CANCEL-Bridge benutzt. So koennen vollwertige Panels
  (mit bidirektionalem Mess-Verkehr) als Satellite-Fenster laufen.

overrides_panel.py:
- register_and_open entfaellt — Overrides wird nicht mehr als Panel
  registriert.
- Neue Funktion open_as_window(): erstellt OverridesBridge, registriert
  sie in sticky["overrides_bridge"] und oeffnet als Satellite-Window.
  Listener werden lazy beim ersten Aufruf installiert
  (_ensure_listeners_once).

oberleiste.py:
- OPEN_OVERRIDES_PANEL ruft jetzt overrides_panel.open_as_window()
  statt RhinoUI.Panels.OpenPanel().

OberleisteApp.jsx:
- Settings-Gear (ToolButton mit icon="settings") nach dem Preset-
  Dropdown im Overrides-Bereich. Click ruft openOverridesPanel() →
  oeffnet das Satelliten-Fenster.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-19 01:39:07 +02:00
karim b1b2090b3e Satelliten-Dialoge: embedded-Mode + GeschossDialog auch als echtes Fenster
Zwei Dinge:

1. embedded-Mode in den Dialog-Komponenten — wenn TRUE, kein Backdrop +
   keine MaxWidth-Constraint, das Dialog fuellt das ganze WebView statt
   wie ein kleines zentriertes Fenster IN dem WebView gerendert zu werden
   (= "Fenster im Fenster"-Effekt). Betroffen:
   - GeschossSettingsDialog
   - EbenenSettingsDialog
   - GeschossDialog
   Satelliten-Apps (GeschossSettingsApp, EbenenSettingsApp,
   GeschossDialogApp) passen jetzt `embedded` durch.

2. GeschossDialog (= der grosse Mehrfach-Editor hinter dem Pencil-Button)
   laeuft jetzt auch als Satelliten-Fenster — selbe Architektur wie die
   Settings-Dialoge. Backend hat neuen Handler _open_geschoss_dialog und
   neuen Message OPEN_GESCHOSS_DIALOG. Auf Save: ganze z-Liste replace
   + _apply(save_z=True).

GeschossManager braucht den inline-Dialog-State nicht mehr; Pencil-Button
ruft openGeschossDialog(zeichnungsebenen).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-19 01:30:28 +02:00
karim 1ba0bda429 Settings-Dialoge in echten Rhino-Fenstern (Eto.Form + WebView)
Statt Overlay-im-Panel oeffnet sich der Settings-Dialog jetzt als
echtes Rhino-Fenster (verschiebbar, resizable, mehrere parallel).

Infrastruktur in panel_base.py:
- load_inline akzeptiert jetzt `params` (dict) und injiziert sie
  als window.PANEL_PARAMS — Satelliten-Apps lesen ihren initialen
  State daraus.
- Neue Funktion open_satellite_window(mode, params, title, size,
  on_save, on_cancel): erstellt Eto.Forms.Form mit eingebetteter
  WebView, eigenem Inline-Bridge fuer SAVE/CANCEL-Messages, ruft
  Callbacks auf und schliesst das Fenster.

Backend rhinopanel.py:
- Neue Message-Handler OPEN_GESCHOSS_SETTINGS und OPEN_EBENEN_SETTINGS.
- _open_geschoss_settings: oeffnet das Satelliten-Fenster mit dem
  Geschoss als Payload. on_save: replace im doc.Strings z-Liste +
  _apply(save_z=True).
- _open_ebenen_settings: gleich, aber fuer Ebene + hatchPatterns.

Neue React-Entries:
- GeschossSettingsApp.jsx: wrappt GeschossSettingsDialog, liest
  window.PANEL_PARAMS, schickt SAVE/CANCEL direkt via document.title-
  Bridge.
- EbenenSettingsApp.jsx: gleich fuer EbenenSettingsDialog.

main.jsx-Switch erweitert um 'geschoss_settings' und 'ebenen_settings'.

GeschossManager und EbenenManager:
- Inline-Dialog-State und -Rendering entfernt.
- onSettings ruft jetzt openGeschossSettings(z) / openEbenenSettings(e)
  in der Bridge auf → Backend oeffnet das Satelliten-Fenster.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-19 01:15:12 +02:00
karim e6a39531f4 Zeichnungsebenen-+: Standard = Zeichnung statt Geschoss
User-Wunsch: das '+' im Zeichnungsebenen-Panel soll standardmaessig
eine NICHT-Geschoss-Zeichnung anlegen (z.B. Bemassung, Plangrafik,
Möblierung). Wer ein Geschoss will:
- Row-Settings-Cog -> isGeschoss umschalten, ODER
- Bearbeiten-Dialog (Pencil) -> Geschoss direkt anlegen

addQuick erstellt jetzt {isGeschoss: false, name: 'Zeichnung N'}.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-19 00:56:45 +02:00
karim 581f366437 Ebene/Zeichnungsebene Erzeugen: window.prompt raus (macOS WKWebView-Bug)
Symptom: erster +-Klick hat funktioniert, alle weiteren nicht (kein
APPLY im Log). Diagnose: macOS WKWebView in Rhino blockiert
WIEDERHOLTE window.prompt-Aufrufe — der erste zeigt einen Dialog,
nachfolgende returnen direkt null. Mein `if (!name) return`
beendet dann ohne Add → kein APPLY → User sieht nichts.

Plus: das nach Anlegen direkt onActiveChange(code) erzeugte einen
SET_ACTIVE_LAYER race (Layer war noch nicht durch build_layers
erstellt → Warning "Sublayer mit Code X nicht gefunden").

Beide Probleme weg durch:

- EbenenManager.addNew: silent append mit Default-Name "NEU",
  Code-Feld bekommt autoEdit-Fokus → User kann direkt tippen,
  Tab springt zum Name-Feld. Code = nextFreeAfter(activeCode) bleibt
  (eine nach der aktiven).
- GeschossManager.addQuick: silent append mit Default-Name
  "NOG" (basiert auf Anzahl Geschosse), kein onActiveChange.
  User editiert ueber den Geschoss-Settings-Cog am Row falls
  noetig.

Tradeoff: keine Dialog-Bestätigung mehr wie ursprünglich vom User
gewünscht — aber dafür funktioniert's überhaupt. Falls Dialog
wieder gewünscht, müsste ein React-Modal statt window.prompt her.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-19 00:43:45 +02:00
karim f14f84ca36 Ebene/Zeichnungsebene nach Anlegen direkt aktiv setzen
Wahrscheinliche Wurzel von "kann nicht erstellen": neue Ebene
wurde zwar zur Liste hinzugefuegt, aber nicht aktiv markiert
→ keine Pill-Highlight → User sah sie nicht (vor allem wenn sie
am Listen-Ende auftauchte) und dachte es funktioniert nicht.

Fix: nach addNew/addQuick `onActiveChange(code|id)` aufrufen.
Die neue Ebene wird in der Liste als aktiv markiert (Pill-Highlight),
ist sofort auffaellig + neue Geometrie landet direkt darauf.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-19 00:36:15 +02:00
karim d63bca1ad8 Ebene-Add: Code = activeCode + nächste freie Nummer + Debug-Logs
Feature: neue Ebenen kriegen jetzt einen Code direkt nach dem
aktuell angewaehlten (z.B. active="20" → "21" oder naechste freie
darunter). Vorher war's Max+1 → sprang auf "100", neue Ebene landet
am Listen-Ende und wirkte „unsichtbar" weil weit unten.

Debug-Logs eingebaut um zu diagnostizieren warum Anlegen aus User-
Sicht nicht funktioniert:
- [EBENEN-UI] addNew → bei jedem Click + im Ebenen-Panel
- [ZEICHNUNGSEBENEN-UI] addQuick → bei jedem Click + im Z-Panel
- [EBENEN-UI/ZEICHNUNGSEBENEN-UI] structureKey diff → wenn der
  Auto-Apply-useEffect feuert
- [EBENEN-UI/ZEICHNUNGSEBENEN-UI] applyAll firing now → wenn der
  Debounce-Timer am Ende den Backend-Call macht
- [EBENEN-BE] APPLY from mode=X → Backend-Receiver
- [EBENEN-BE] mode=X: y from doc.Strings n=N → was aus doc.Strings
  als Fallback geladen wurde

So sehen wir wo's stockt — UI feuert nicht, Debounce klemmt,
Backend kriegt's nicht, oder build_layers schmeisst still.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-19 00:29:46 +02:00
karim 10690f4514 Ebene + Zeichnungsebene Erzeugen: Dialog mit Name-Input (wie Kombi)
UX-Beschwerde: addNew/addQuick haben still im Hintergrund eine Ebene
am Listenende hinzugefuegt. User sah das Ergebnis nicht weil scroll-
abhaengig oder ueberhaupt — "kann gar nicht erstellen". Bei Ebenen-
Kombinationen geht's via window.prompt, das ist klar.

Beide auf gleiche Prompt-UX umgebaut:

EbenenManager.addNew:
- Prompt "Name für neue Ebene:" mit Default "NEU"
- Bei Cancel/leer: kein Add
- Bei OK: Ebene mit UPPERCASE-Name + auto-generiertem Code, Code-
  Feld bekommt sofort den Edit-Mode (User kann ihn schnell anpassen).

GeschossManager.addQuick:
- Prompt "Name für neue Zeichnungsebene (Geschoss):" mit Default
  basiert auf Anzahl Geschosse (z.B. "3OG" wenn 2 vorhanden).
- Bei OK: neuer Eintrag als Geschoss (isGeschoss=true) mit hoehe=3.0
  und schnitthoehe=1.0 — die Default-Werte. Wegen recalcOkff zeigt
  er automatisch das richtige OKFF.

Vorher war addQuick auf `isGeschoss=false` (= Beschriftungs-Eintrag,
kein Geschoss), das war ein Konventions-Mismatch zur User-Erwartung.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-19 00:16:36 +02:00
karim c4c9e56b2c Beide Ebenen-Panels: Section-Header raus, Action-Buttons in Sichtbarkeit-Row
Der Section-Header mit dem Panel-Namen ("Ebenen" / "Zeichnungsebenen")
war redundant — der Panel-Tab in Rhino hat den Namen schon. Stattdessen
direkt mit der Sichtbarkeit-Dropdown beginnen.

EbenenManager:
- `<Section>`-Wrapper entfernt, Section-Import raus.
- "+"-Button neben der Sichtbarkeit-Dropdown (flex: 1).

GeschossManager:
- Gleich. "+"- und Edit-Buttons (Bleistift) neben der Sichtbarkeit-
  Dropdown.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-19 00:02:26 +02:00
karim cbabc12064 Ebenen-Split: applyVisibility null-safe machen
App.jsx ruft jetzt `applyVisibility(null, [], activeCode, ebenen, null, eMode)`
— die fremde Slice ist leer/null weil das Panel sie nicht besitzt. Das
crashte mit "Cannot read properties of null (reading 'id')" weil der Code
`a.activeZ.id` blind dereferenzierte. Resultat: "Script error." in
window.onerror → leere Panel-UI.

Fix: Array.isArray-Guard + null-Check fuer activeZ. Backend mergt
fehlende Felder mit doc.Strings.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-18 23:55:13 +02:00
karim a458b4c47d Ebenen-Panel in zwei UI-Panels splitten: Zeichnungsebenen + Ebenen
UX: Geschoss-Liste und globale Layer-Liste lebten bisher in einem
Panel und mussten beide gescrollt werden. Jetzt zwei getrennte Tabs.

Backend (rhino/rhinopanel.py):
- Selbe EbenenBridge-Klasse, zwei Mode-Instanzen ("ebenen" +
  "zeichnungsebenen"). Beide registrieren sich in sticky-Slots
  (`ebenen_bridge_ref` / `zeichnungsebenen_bridge_ref`).
- `_broadcast_state(doc)` Helper: liest aktuell Zustand aus doc.Strings
  und schickt STATE_SYNC an beide Bridges. Wird nach jeder state-
  aendernden Aktion gefeuert (apply, set_active_zeichnungsebene,
  toggle_clipping, remove/update ebene, layer-table-event).
- `handle(APPLY)`: wenn nur eine Slice (z oder e) im Payload, fehlende
  aus doc.Strings nachladen → Backend baut mit vollem Zustand.
- `_apply_visibility`: zMode/eMode/activeId/activeCode aus Payload
  ODER aus doc.Strings (dossier_z_mode/dossier_e_mode/dossier_active_id/
  dossier_active_code) faellen lassen — Split-Sends werden korrekt
  gemergt.
- Layer-Table-Event broadcastet jetzt statt nur das eine Panel zu
  benachrichtigen.
- Zweite `register_and_open("zeichnungsebenen", ...)` Zeile mit eigener
  GUID + Icon "levels".

Frontend:
- Neues src/ZeichnungsebenenApp.jsx: enthaelt nur GeschossManager,
  haelt Zeichnungsebenen + activeId + zMode lokal, schickt
  applyAll([z], []) und applyVisibility mit leerer Ebenen-Slice.
- src/App.jsx geschrumpft: nur noch EbenenManager + AusschnittLayer-
  Dialog. Haelt Ebenen + activeCode + eMode + Combinations. Schickt
  applyAll([], [e]) und applyVisibility mit leerer Z-Slice.
- src/main.jsx: neuer case fuer mode="zeichnungsebenen" → lädt
  ZeichnungsebenenApp.

Existierende User mit altem DOSSIERUI.rhw Workspace muessen das neue
Panel einmal manuell oeffnen (Rechtsklick Panel-Area → Panel hinzu-
fuegen → "Zeichnungsebenen"); Rhino persistiert die Anordnung danach.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-18 23:42:02 +02:00
karim 961b3c0396 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>
2026-05-18 01:50:45 +02:00
karim 9dc191be4f Initial commit — Dossier Rhino 8 Plugin
OpenStudio-Suite Architektur-Plugin fuer Rhino 8 (Mac):
- Smart-Elemente: Wand, Decke, Dach (Pult/Sattel/Walm/Mansarde),
  Oeffnungen (Fenster/Tueren mit Rahmen + Sims + Glas + Fluegel),
  Treppen (gerade · L · Wendel mit Schrittmass-Validierung)
- Live-Previews mit Step-Lines + Soll-Range-Clamping
- Bidirektionale Selection-Sync zwischen Source-Linie und Volume
- Geschoss-/Ebenen-Verwaltung mit OKFF-Persistenz
- Layouts mit PDF-Export
- Ausschnitte / Massstab / Override-Regeln
- Petrol-Gruen Theme (Rapport-konform)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 04:27:41 +02:00