Commit Graph

9 Commits

Author SHA1 Message Date
karim 13a5e1eb7a AGPL-3.0 Dual-Lizenz + Pill-Stil-UI + Section-Style-Overhaul + Plan-Mode-Template
Lizenz:
- AGPL-3.0 LICENSE-File im Repo-Root (GNU Volltext)
- SPDX-Header + Copyright in allen Source-Files (Python/JSX/JS/Rust)
- license-Feld in package.json + Cargo.toml
- About-App komplett neu: Dual-Lizenz-Block (AGPL + Commercial),
  openbureau-Branding, Version-Pills, made-in-Switzerland-Footer

UI-Restyle (3 Wellen) — alle Dialoge + Satellites + Panel-Sidebars
auf gemeinsamen Pill-Stil aus BarControls (BarToggle/BarButton/BarCombo):
- Welle 1: GeschossDialog/Settings, AusschnittSettings, LayoutDialog
- Welle 2: ConfirmDeleteEbene, Kamera, MasseSettings, Osm, Swisstopo,
  TextEditor, AusschnittLayerDialog, LayerCombinations
- Welle 3: LayoutsApp, MassstabApp, WerkzeugeApp, OverridesApp,
  ZeichnungsebenenApp; Werkzeuge mit ElementeApp-PillGroup-Layout

GeschossDialog Header-Refactor: +Geschoss/+Zeichnung in Toolbar oben,
move-Pfeile-Spalte breiter (kein Overlap mit G-Haken)

Ausschnitte Rows als Pills, kein Outer-Border ums Suchfeld

Section-Style komplett neu (gestaltung.py + GestaltungApp.jsx):
- ObjectSectionAttributesSource.FromObject (richtiger Enum-Name fuer Mac)
- HatchPatternPrintColor + BoundaryPrintColor mit-setzen (Display = Print)
- BoundaryColor nur bei explizitem User-Override, sonst Rhino-Default
- background_color_hex Parameter (BackgroundFillMode=SolidColor)
- Readback aus GetCustomSectionStyle statt direkt aus Attributes
- UI: Schnittkante > Section Style > Solid-Fill mit proper SectionHead
- 'Boundary' (3D Pen) -> 'Background' weil sich's wie Section-Hintergrund verhaelt

Plan-Mode 'Dossier Plan' via Template:
- rhino/templates/dossier_plan.ini wird direkt geladen
- Fallback auf Technical-Clone + ini-Patch wenn Template fehlt
- Auto-Cleanup von Orphan-Modes vor Import (Name- oder Guid-Match)
- ClipSectionUsage=1 + TechnicalMask=15 als bekannte Soll-Werte
- Bei Template-Pfad keine ini-Patches (1:1 wie User exportiert)
- Sanity-Print listet alle registrierten Modes nach Anlegen

Bridge-Unification: 4 Settings-Apps (Ebenen/Project/Geschoss*Dialog)
benutzen jetzt chunkende send() statt eigene bridgeSend ohne Chunk-
Logik -> grosse Payloads (Hatch-Refs etc.) kommen nicht mehr truncated
bei Python an (loeste 'JSON-Fehler char 990'-Regression in Ebenen-
Settings)

Library-Imports robust: 'import library' jetzt Top-Level in elemente.py
+ rhinopanel.py (statt Lazy in Methoden) -> 'No module named library'-
Crashes weg auch wenn sys.path zwischendurch resettet wird

Tools fuer Display-Mode-Maintenance:
- _clean_display_modes.py (loescht alle Custom-Modes, Built-ins bleiben)
- _inspect_plan_mode.py / _inspect_obj_section.py / _inspect_obj_boundary.py
  (Diagnose-Skripte fuer SectionStyle-Property-Reverse-Engineering)
- _reset_rhino_settings.sh (Backup + Nuke der Rhino-Settings als
  letzte Bastion gegen korrupte Display-Modes)
2026-05-26 17:09:18 +02:00
karim e1b63aa4e6 Library-Thumbnails: Auto-Capture + Base64-Preview in der UI
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>
2026-05-25 19:07:33 +02:00
karim 827bd8d4d7 Library: Format-Konvertierung beim Import (.dwg/.obj/.fbx/.dae/.stl/...)
User kann jetzt im Symbole-Tab Dateien in vielen Formaten waehlen — Rhino
konvertiert automatisch nach .3dm via _-Import + File3dm.Write.

library.py — convert_to_3dm_via_import():
- Snapshot der existierenden Object-IDs im aktiven Doc
- User-Selection sichern
- _-Import scripted ausfuehren → neue Objekte in Doc
- Diff -> neue Objekte sammeln
- BoundingBox.Min als Origin → in File3dm packen
- f3.Write nach library/assets/<name>.3dm
- Neue Objekte aus Doc wieder loeschen + User-Selection restoren
- sticky 'dossier_library_import_busy' + 'dossier_swisstopo_busy' damit
  unsere Listener nichts cascaden waehrend Doc kurzzeitig die Importe haelt

rhinopanel.py — _add_library_file():
- .3dm: copy_to_assets (wie bisher)
- .dwg/.dxf/.obj/.fbx/.dae/.stl/.3ds/.skp/.iges/.step/.ply: konvertieren
- Sonst LIBRARY_ERROR

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-25 18:45:58 +02:00
karim 68b9d14453 Auswahl als Library-Item speichern (Step 3)
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>
2026-05-25 04:05:48 +02:00
karim c993935b17 Symbole-Tab in Project-Settings (Library-Item-Management)
Project-Settings hat jetzt 5 Tabs. Neuer 'Symbole'-Tab managt die
Dossier-Library: List/Detail wie Materialien, mit 2D + 3D Slot pro Item.

Backend (library.py):
- save_manifest, update_item, delete_item, add_item — full CRUD aufs
  library.json
- copy_to_assets: kopiert User-Dateien in library/assets/ mit
  Konflikt-Resolution (auto-suffix)

Backend (rhinopanel.py / ProjectSettingsBridge):
- _send_library: aktuelle Items + libraryRoot an Frontend
- _add_library_file: File-Picker (.3dm direkt; .dwg/.obj/etc. zeigt
  Hinweis fuer kuenftige Konvertierung), kopiert + appended ans Item
  (variant 2d/3d) oder erstellt neues Item
- _update_library_item: patch by id
- _delete_library_item: entfernt Eintrag aus Manifest
- LIBRARY_ITEMS + LIBRARY_ERROR Messages ans Frontend

Frontend:
- Neuer 'Symbole'-Tab mit List/Detail
- Liste: Name, Type-Icon, '2D'/'3D' Status-Badge
- Detail rechts: Name-Edit (live persist on blur), Type-Toggle
  (Symbol/Objekt), 2D/3D-File-Slots mit Datei-Picker, Tags-Editor
- 'Neues Objekt' Button im Listen-Footer

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-25 03:58:41 +02:00
karim 8184f559fc Symbol-Funktion in Elemente-Panel (Phase S1+S2)
Schema (library.py):
- Item-Format erweitert: files2d + files3d (Backwards-compat zu 'files')
- _build_variant_block + _place_instance + Layer-Routing pro Variante
- import_item akzeptiert at_point + layer2d/layer3d
- _ensure_block_definition mit variant-Suffix (dossier_lib_<id>_2d/_3d)

Backend (elemente.py):
- _layer_path_symbole(geschoss_name, variant) → <geschoss>::40_SYMBOLE::
  SYMBOLE_2D bzw. SYMBOLE_3D
- Default-Ebene 40 SYMBOLE via _find_ebene_sublayer_name
- LIST_LIBRARY-Handler: sendet Library-Manifest als LIBRARY_LIST
- CREATE_SYMBOL-Handler: interactive GetPoint im aktiven Viewport,
  laedt Block-Def + platziert Instanz(en) auf den richtigen Ebenen
- Pair-Items (2D+3D) werden an gleichem Punkt beidseitig platziert →
  Top zeigt 2D-Layer, Persp zeigt 3D-Layer wenn User entsprechend
  Sichtbarkeit setzt

Frontend:
- SymbolPicker Modal-Component: Grid mit Symbol/Object-Cards, Search,
  Type-Filter (Alle/Symbole/Objekte), Doppelklick = Pick
- Symbol-Button in ElementeApp (PillGroup "Library") oeffnet Modal +
  triggert listLibrary() fuer aktuelle Items
- createSymbol(id) → Backend → GetPoint → Place

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-25 03:31:54 +02:00
karim 8d3b3af882 Material/Ebene-Separation: Hatch raus aus Material (Refactor a)
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>
2026-05-25 02:10:04 +02:00
karim f760d1c54b Library Phase A.2 (Symbol/Object-Import) + Oberleiste-Pill-Restyle
Library Phase A.2:
- import_symbol/import_object via File3dm.Read + InstanceDefinitions.Add
- Stabile Block-Namen 'dossier_lib_<libraryId>' fuer Dedupe
- Seed-Manifest erweitert um Nordpfeil (symbol) + Laubbaum (object)
- ItemCard rendert type-spezifische Preview (Color-Swatch fuer material,
  Material-Icon fuer symbol/object)

Oberleiste-Pill-Restyle:
- OberleisteApp: Version unter DOSSIER-Logo, Settings-Icons vertikal
  gestapelt
- ProjectSettingsDialog: Pill-Tabs, BarToggle-Footer, MaterialRow mit
  Hover-Highlight, Header entfernt (Eto.Form hat eigenen)
- LibraryBrowser: BarButton-Reload, Pill-Typ-Filter, MaterialCard mit
  BarToggle-Pill, Header entfernt
- Globaler select-Stil: bg-input statt bg-item (dunkler im Dark-Mode,
  konsistent zu Oberleiste-BarCombo)

Routing:
- OberleisteBridge delegiert OPEN_PROJECT_SETTINGS + OPEN_LIBRARY an
  EbenenBridge (sticky ebenen_bridge_ref) — vorher kamen die Messages an
  der falschen Bridge an und wurden verschluckt

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-24 16:57:42 +02:00
karim a308ba62d2 Projekt-Settings-Dialog + Library Phase A + Material-Merger
- Project-Settings-Dialog (Voreinstellungen Geschoss/Schnitt + Material-Editor)
  ueber Zahnrad-Icon in Oberleiste; Defaults werden in schnitte.pick_schnitt
  + GeschossManager als Vorgabe genommen, pro-Element-Werte unangetastet
- Dossier-Library Phase A (lokal, read-only): rhino/library.py + LibraryBrowser
  Satellite; Seed-Manifest unter ~/Library/Application Support/Dossier/library/
- Material-Merger: _get_all_materials(doc) merged builtin _MATERIAL_LIBRARY
  mit Projekt-Settings-Materialien (inkl. Library-Imports); Wand-Erstellung,
  Sub-Layer-Anlage + Elemente-Material-Dropdown ziehen jetzt aus dem Merge

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-24 02:19:09 +02:00