# Dossier Rhino-8 Plugin für architektonisches Entwerfen mit smarten Bauteilen — Geschosse, Wände, Decken, Dächer, Öffnungen (Fenster/Türen), Treppen (gerade · L · Wendel). Teil der **OpenStudio-Suite** (mit Rapport als Schwestertool). Die React-UI wird in Rhinos Eto.Forms-WebView über `LoadHtml` (inline) eingebettet — die Plugin-Logik läuft in IronPython3 in Rhino 8 (Mac). ## Voraussetzungen | Tool | Version | |---|---| | Rhino | 8 (Mac · Windows untestet) | | Node.js | ≥ 20 (für Vite 8) | | npm | ≥ 10 | | Python | IronPython 3 (in Rhino integriert) | Optional — für den Standalone-Launcher: | Tool | Version | |---|---| | Rust toolchain | ≥ 1.77 (`rustup`) | | Plattform-Build-Tools | siehe [Tauri Prerequisites](https://v2.tauri.app/start/prerequisites/) | ## Setup ```bash git clone http://192.168.1.247:3000/karim/DOSSIER.git cd DOSSIER npm install ``` ## Entwicklung **React-UI bauen** (nach jeder UI-Änderung): ```bash npm run build # → dist/index.html (inline-fähig) ``` **Im Browser entwickeln** (HMR, ohne Rhino — für reine UI-Arbeit): ```bash npm run dev # http://localhost:5173 ``` **Plugin in Rhino starten:** In Rhino 8 das Hauptpanel über `_RunPythonScript` öffnen: ```python # Hauptmenu _RunPythonScript "/Users/karim/STUDIO/DOSSIER/rhino/rhinopanel.py" ``` Bei Änderungen am Python-Code Panels neu laden: ```python import importlib, sys, scriptcontext as sc # Bridges zuruecksetzen for k in list(sc.sticky.keys()): if any(p in k.lower() for p in ['elemente','gestaltung','oberleiste','massstab','ausschnitte','layouts','overrides','werkzeuge','dimensionen']): sc.sticky[k] = None # Module neu laden for m in list(sys.modules): if any(p in m for p in ['elemente','gestaltung','oberleiste','massstab','ausschnitte','layouts','overrides','werkzeuge','dimensionen','panel_base']): importlib.reload(sys.modules[m]) ``` ## Architektur ### Kommunikation React ↔ Python - **React → Python**: `document.title = "RHINOMSG::{json}"` (queue-basiert, 80 ms delay) - **Python → React**: `webview.ExecuteScript("window.onRhinoMessage({...})")` ### Datenmodell - **Geschosse** in `doc.Strings["dossier_ebenen"]` als JSON (Name, Höhe, OKFF, Typ). - **Smart-Elemente** (Wand, Decke, Dach, Öffnung, Treppe) als Rhino-Objekte mit UserStrings — `dossier_element_id`, `dossier_element_type`, etc. - **Source ↔ Volume Pattern**: jedes Element hat eine *Source-Geometrie* (Achse/Outline/Punkt) + ein generiertes *Volume* (Brep). Source-Änderungen triggern automatische Regeneration. ### Layer-Hierarchie ``` 10_GRUNDRISSE └── EG ├── 20_WÄNDE ├── 30_DECKEN ├── 31_DÄCHER └── 40_TREPPEN └── 1OG (gleiche Sublayer) 20_SCHNITTE 30_ANSICHTEN 00_RASTER · 01_VERMESSUNG · 40_SITUATION · 90_REFERENZEN · 99_KONSTRUKTION ``` ## Projektstruktur ``` . ├── src/ Frontend (React) │ ├── App.jsx Hauptpanel (Geschosse + Ebenen) │ ├── ElementeApp.jsx Smart-Elemente Panel │ ├── AusschnitteApp.jsx Ausschnitte (Detail-Views) │ ├── LayoutsApp.jsx Layouts + PDF-Export │ ├── MassstabApp.jsx Massstab/Display-Modes │ ├── DimensionenApp.jsx Objekt-Info (Position/Abmessungen) │ ├── OverridePanel.jsx Override-Regeln + Kombinationen │ ├── components/ EbenenManager, GeschossManager, ... │ └── lib/rhinoBridge.js React↔Python Bridge ├── rhino/ Backend (IronPython 3) │ ├── rhinopanel.py Haupt-Entry, Bridge-Pattern │ ├── panel_base.py BaseBridge + Panel-Registration │ ├── elemente.py Smart-Elemente (Wand/Decke/Dach/Oeffnung/Treppe) │ ├── ausschnitte.py Ausschnitte (Detail-Views) │ ├── layouts.py Layouts + PDF-Generierung │ ├── massstab.py Massstab/Display-Modes │ ├── overrides_panel.py Override-Regeln │ ├── dimensionen.py Objekt-Info Panel │ ├── gestaltung.py Gestaltung (Override-Editor) │ ├── werkzeuge.py Werkzeug-Sammlung │ └── oberleiste.py Top-Menue (verbindet alle Panels) ├── launcher/ Tauri-2 Standalone-Launcher (optional) ├── dist/ Gebaute React-App (npm run build) ├── public/ Statische Assets ├── icons_export/ Material-Icons als SVG └── vite.config.js `base: './'` (wichtig fuer file:// inline) ``` ## Bekannte Limitierungen - IronPython3-spezifisch: keine Umlaute in Source-Strings (`ue/oe/ae` statt `ü/ö/ä`); UTF-8-Header-Kommentar in allen `.py`-Files. - **Kein Docking** der Panels (Rhinos `RegisterPanel` schlägt fehl: `"constructor must accept uint, RhinoDoc or no params"`). Panels laufen daher als schwebende `forms.Form`-Fenster. - **`LoadHtml`-inline** statt `file://`-URL — Rhinos WKWebView blockiert sonst `