PHASE 1 — Bulk-Apply auf mehrere selektierte Raeume:
- Backend _cmd_apply_raum_stil: leere ids im Patch → nimmt automatisch
alle aktuell SELEKTIERTEN raum_outlines aus dem Doc (Bulk-Fallback)
- Frontend sendet leere ids fuer die Default-Bulk-Variante. User
selektiert N Raeume im Viewport → klickt Stil im Properties-Picker →
Stil wird auf alle angewendet. Inkludiert immer den Properties-Raum.
PHASE 2 — Stil-Manager als Settings-Tab:
- Neuer Tab "Raumstile" in ProjectSettings-Dialog
- Liste aller Stile mit Drag-Reorder (HTML5 native), Inline-Rename,
Duplicate (content_copy-Icon), Delete (mit Confirm)
- Mini-Preview: zeigt Layout-Struktur (z.B. "nummer·name / funktion / area")
und der Name wird mit Font/Bold/Italic des Stils gerendert als Vorschau
- Backend _cmd_reorder_raum_stile + _cmd_duplicate_raum_stil in elemente.py
- ProjectSettings-Bridge dispatcht direkt zu elemente.load/save_raum_stempel_stile
(kein Roundtrip via Elemente-Bridge noetig)
- STILE_UPDATED-Message nach jeder Op pusht die neue Liste zum Dialog
- params bei _open_project_settings enthalten jetzt raumStempelStile + fonts
Bridge-Exports: reorderRaumStile / duplicateRaumStil in rhinoBridge.js
Statt jeden Wert im Code zu konvertieren wird sichergestellt dass das
Doc in der gewuenschten Unit ist:
- defaults.unit ('meters'|'millimeters'|'centimeters') in
dossier_project_settings, Default 'meters'
- ProjectSettings-Dialog "Voreinstellungen" Tab: neue Sektion
"Arbeitseinheit" mit Toggle-Group fuer m/cm/mm
- get_project_unit() + get_project_unit_enum() Helper in rhinopanel
- startup._check_doc_unit() prueft beim Doc-Open ob ModelUnitSystem
matched — bei Mismatch Eto-MessageBox "Doc auf X umstellen?"
- "Yes" ruft _-Units _Model _<Unit> _Yes (Geometrie wird mit-skaliert)
- "No" setzt doc.Strings-Flag dossier_unit_checked → keine erneute Frage
- Check laeuft beim _on_doc_opened-Hook + initial fuer aktives Doc
Vorgehen ist deutlich sauberer als der vor-revert unit-aware Code
(135 Zeilen Konvertierungslogik vs 80 Zeilen Check+Convert).
Beim Hinzufuegen oder Importieren eines Library-Items wird automatisch
ein PNG-Thumbnail vom Item generiert (Top-View, 128x128) und in
library/previews/<id>.png abgelegt. Frontend rendert die Previews als
Base64-Data-URIs (sicher gegen WebKit-file://-Restriktionen).
library.py:
- _previews_dir(): legt previews/-Folder an
- _preview_rel_for(asset_rel): predictable PNG-Pfad pro Item
- _capture_thumbnail_of_objects(): hided andere Objekte temporaer,
switcht auf Top-Parallel, ZoomBoundingBox, CaptureToBitmap → PNG,
restored Viewport + Hidden-State
- read_preview_data_uri(): liest PNG + encoded als data:image/png;base64
- Hook in convert_to_3dm_via_import (vor Cleanup) + save_selection_to_asset
rhinopanel.py:
- _enrich_library_items_with_previews(): haengt previewDataUri an
jedes Item das ein preview-Feld hat
- Initial-Params + _send_library + ElementeBridge._cmd_list_library
liefern angereicherte Items
- _add_library_file + _save_selection_as_library setzen preview-Pfad
im Item wenn Thumbnail-Datei existiert
Frontend:
- SymbolPicker.ItemPreview: rendert <div backgroundImage> mit Base64-URI
wenn vorhanden, sonst Icon-Fallback
- ProjectSettingsDialog Symbole-Tab: List-Row + Detail-Identity zeigen
Thumbnail (32px in Liste, 56px im Detail), Icon nur als Fallback
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
User selektiert in Rhino → klickt im Symbole-Tab 'Aus Auswahl' →
Selection wird in eine .3dm-Datei verpackt + Library-Item entsteht
(oder bestehendes wird aktualisiert).
Backend (library.py):
- save_selection_to_asset(doc, target_name): erstellt File3dm aus der
aktuellen Selection, packt Geometry relativ zu BoundingBox.Min (Block-
Origin am Ursprung), schreibt nach library/assets/
Backend (ProjectSettingsBridge):
- SAVE_SELECTION_AS_LIBRARY-Handler: holt Selection, fragt bei neuen
Items via Rhino-GetString nach Name, schreibt .3dm, fuegt Item zum
Manifest oder updated bestehendes (variant '2d'/'3d')
Frontend (Symbole-Tab):
- List-Footer: 'Aus Datei' + 'Aus Auswahl' Pills (neues Item)
- Pro 2D/3D-Slot im Detail: 'Datei wählen' + 'Aus Auswahl' Pills
(Variante eines bestehenden Items befüllen)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Schema-Erweiterung:
- _PROJECT_SETTINGS_DEFAULTS hat jetzt 'project'-Block mit
name / number / address / bauherr / architekt / notes / projectZeroMum
- _normalize_project_meta stripped Strings + clampt mum als float
- load/save_project_settings handeln das 'project'-feld
- save_project_settings spiegelt projectZeroMum auch in den Legacy-Key
dossier_project_zero_mum (fuer Geschoss-Settings-Dialog)
- load_project_settings liest Legacy-Key als Fallback wenn neuer Wert
noch nicht gesetzt
UI:
- InlineTextField + TextareaField Helpers (Pill-Stil)
- Projektdaten-Section in Voreinstellungen-Tab:
Name, Projekt-Nr., Adresse, Bauherrschaft, Architekt:in,
EG-Nullpunkt m.ü.M (mit Hinweis auf Swisstopo-Nutzung), Notizen
Swisstopo:
- _cmd_open_swisstopo_dialog laedt Projekt-Adresse + sendet projectAddress
im SWISSTOPO_STATE
- SwisstopoApp: vorbelegt searchText mit projectAddress wenn Feld leer
ist (User-Input wird nicht ueberschrieben)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Material ist jetzt rein 3D — Section-Hatch (2D-Schnitt) wird nicht mehr
am Material definiert, sondern am Layer (via Rhino-Layer-Dialog oder
spaeter via Ebenen-Settings + neuer Hatch-Tab im Project-Settings).
Schema-Aenderungen:
- _normalize_material: hatch + scale entfernt
- _MATERIAL_LIBRARY (elemente.py): hatch + scale aus allen Builtin-Mats
- _get_all_materials: ohne hatch
- _send_state materials payload: nur {name, color}
- Library import_material: PBR + Texturen werden weitergegeben
Backend:
- _ensure_material_sublayer: erstellt Sublayer mit Color, RESETTET aber
alten SectionHatchIndex auf -1 (= "kein eigener Hatch") damit
Inheritance/User-Override greift. Vorher wurden alte Material-Hatch-
Werte da haengen geblieben.
Frontend:
- MaterialDetail: Schraffur-Section entfernt
- hatchPatterns-Prop entfernt
Konsequenz: existierende Waende verlieren ihren Section-Hatch beim
naechsten Regen. User definiert Section-Hatches jetzt auf Layer-Ebene.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>