Browser-BIM (cad): semantisches Modell, abgeleitete 2D/3D-Sichten, Zeichenwerkzeuge

Standalone-Browser-Port von DOSSIER. Enthaelt das semantische Modell mit
Plan-/3D-Ableitung, Zeichen- und Editierwerkzeuge, Rhino-artiges Befehlssystem,
dockbares Panel-System, Resource-Manager, DXF/.lin/.pat-Import, i18n (de/en)
sowie Projektdokumentation und Probe-Harness.
This commit is contained in:
2026-06-30 20:52:27 +02:00
commit ca859c4aa4
157 changed files with 37921 additions and 0 deletions
+566
View File
@@ -0,0 +1,566 @@
# Swisstopo-Geodaten & SIA-Flächenstandards im Browser-BIM
> Stand: 2026-06-29 · Recherche für das Standalone-Browser-BIM (React + TS + Three.js),
> Port von **DOSSIER** (Rhino-Plugin). Ziel: (A) Schweizer Geodaten (Höhenmodell,
> Orthofoto, 3D-Gebäude, Parzellen) direkt im Browser laden, (B) Standort-Kontext
> (Gelände + Parzelle + Nachbargebäude) für ein Projekt importieren, (C) SIA-416-
> Flächen/Volumen + Raumschemata berechnen wie in DOSSIER.
>
> Bezug zur ROADMAP: Swisstopo/Terrain/OSM = **Phase 4** (Kontext/Daten); SIA-416-
> Räume + Bilanz-CSV = **Phase 2**. Beide sind dort bereits als ⭐-Features gelistet.
**Alle in diesem Dokument genannten geo.admin.ch-Endpunkte wurden am 2026-06-29 live
gegen die echte API getestet** (curl + CORS-Header-Check). Wo „verifiziert" steht,
liegt eine echte Antwort vor.
---
## Teil A — Swisstopo-APIs & Dienste aus dem Browser
### A.0 Das Wichtigste vorweg: CORS & Lizenz
Zwei Fragen entscheiden, ob ein Dienst *ohne Backend-Proxy* aus einer reinen
Browser-App nutzbar ist: CORS und Lizenz. Beide sind hier günstig.
**CORS (live verifiziert):** Alle relevanten Hosts senden `access-control-allow-origin: *`:
| Host | Dienst | CORS | Range-Requests |
|---|---|---|---|
| `api3.geo.admin.ch` | REST (height, profile, identify, find, search) | ✅ `*` | — |
| `data.geo.admin.ch` | STAC-API + Daten-Assets (COG-GeoTIFF, XYZ.zip) | ✅ `*` | ✅ `206 Partial Content`, `accept-ranges`/`content-range` vorhanden |
| `wmts.geo.admin.ch` | WMTS-Kacheln | ✅ `*` | — |
| `3d.geo.admin.ch` | 3D-Tiles (`tileset.json` + glTF) | ✅ `*` | — |
**Konsequenz:** Höhenabfrage, Geocoding, Parzellen-Identify, Karten-/Orthofoto-
Kacheln, **COG-GeoTIFF-Höhenmodell per Range-Request** und 3D-Tiles sind **direkt aus
dem Browser ohne eigenen Proxy** abrufbar. Das ist ein großer Vorteil gegenüber vielen
anderen nationalen Geodiensten.
**Lizenz:** swisstopo/geo.admin.ch ist **Open Government Data**: „The acquisition and
use of data or services is free of charge, subject to the provisions on fair use."
Kommerzielle Nutzung ist erlaubt, Einbindung in (auch kommerzielle) Web-Apps explizit
gedeckt. Pflicht-Attribution: **`© swisstopo`** (bzw. „© Data: swisstopo"). „Fair use"
= z.B. Web-App mit Ø 20'000 Nutzern/Tag ok; aggressives Bot-Scraping vermeiden. Haftung
ausgeschlossen, ~98% Verfügbarkeit. [Terms of use FSDI](https://www.geo.admin.ch/en/general-terms-of-use-fsdi)
> ⚠️ **Korrektur zu DOSSIER & zur Doku:** Die offizielle REST-Doku notiert beim
> *Height*-Service „This service is not freely accessible (fee required)". Das ist
> **in der Praxis falsch / veraltet**: Der Endpunkt antwortet anonym, ohne Key, mit
> `200` und CORS `*` (verifiziert, siehe A.1). DOSSIERs Aussage „alle APIs offen, ohne
> Auth, ohne Key" deckt sich mit der gemessenen Realität. Wir verlassen uns aber nicht
> blind darauf, sondern behandeln 402/429 defensiv (Retry/Backoff, Cache).
### A.1 Höhenabfrage — Height-Service (Einzelpunkt)
Punkt-Höhe (DTM) aus swissALTI3D/DTM. **Verifiziert:**
```
GET https://api3.geo.admin.ch/rest/services/height?easting=2600000&northing=1200000&sr=2056
→ {"height":"555.5"}
```
Parameter:
- `easting`, `northing` — LV95 (`sr=2056`) oder LV03 (`sr=21781`). **Pflicht.**
- `sr``2056` (LV95) angeben, sonst Default `21781`.
- `elevation_model``DTM2` (= swissALTI3D, 2 m), `DTM25` (Default), `COMB`.
(Im Tal lieferten DTM2/DTM25/COMB denselben Wert; im Steilgelände kann DTM2 genauer sein.)
- `callback` — JSONP (brauchen wir wegen CORS nicht).
Nutzung im Tool: **Projekt-Nullpunkt-Z** bzw. „Gebäude auf Gelände setzen" — eine
einzelne Höhe an der Projekt-Koordinate. Antwortzeit ~50150 ms. Quelle:
[GeoAdmin REST Height](https://geoadmin.readthedocs.io/en/latest/services/sdiservices.html)
### A.2 Höhenprofil — Profile-Service (Schnittlinie)
Höhen entlang einer Polylinie — ideal für **Geländeschnitt** unter einem
Gebäude-Schnitt. **Verifiziert** (echte Werte zurück):
```
GET https://api3.geo.admin.ch/rest/services/profile.json
?geom={"type":"LineString","coordinates":[[2600000,1200000],[2600200,1200000]]}
&sr=2056&nb_points=3
→ [{"alts":{"COMB":555.5,"DTM2":555.5,"DTM25":555.5},"dist":0,"easting":2600000,"northing":1200000},
{"alts":{...},"dist":100,...}, {"dist":200,...}]
```
Parameter: `geom` (GeoJSON-LineString, max 6'000 Punkte), `sr`, `nb_points` (Anzahl
Stützpunkte, Default 200), `elevation_models`, `offset` (Glättung). Auch als
`profile.csv`. → Für 2D-Geländeschnitte **ohne** Mesh-Download. Quelle:
[GeoAdmin REST Profile](https://geoadmin.readthedocs.io/en/latest/services/sdiservices.html)
### A.3 swissALTI3D — Höhenmodell als COG-GeoTIFF (Mesh-Quelle) ⭐
Das ist der **Schlüssel für das Gelände-Mesh im Browser**. swissALTI3D ist das präzise
DTM der Schweiz (ohne Vegetation/Bebauung), Auflösung 0.5 m / 2 m, alle 6 Jahre
aktualisiert ([swissALTI3D](https://www.swisstopo.admin.ch/en/height-model-swissalti3d)).
Bezug über die **STAC-API** (verifiziert — Tile `swissalti3d_2019_2599-1198`):
```
GET https://data.geo.admin.ch/api/stac/v1/collections/ch.swisstopo.swissalti3d/items
?bbox=<lonMin,latMin,lonMax,latMax>&limit=...
```
Jedes 1×1-km-Tile liefert pro Auflösung **zwei** Asset-Typen:
| Asset | Typ | Browser-tauglich? |
|---|---|---|
| `..._0.5_2056_5728.tif` / `..._2_2056_5728.tif` | **Cloud-Optimized GeoTIFF**, **EPSG:2056** | ✅ **direkt** via `geotiff.js` + Range |
| `..._0.5_2056_5728.xyz.zip` / `..._2_..._xyz.zip` | ASCII-XYZ (E N Z) in ZIP | ✅ via `fflate` entpacken (so macht es DOSSIER) |
**Verifiziert:** `data.geo.admin.ch` liefert auf das `.tif` ein `206 Partial Content`
mit `content-range` bei `Range:`-Header und CORS `*`. Das bedeutet: **`geotiff.js`
liest nur den benötigten Ausschnitt eines COG per HTTP-Range, ohne das ganze File zu
laden** — perfekt für eine Browser-App. Bbox in WGS84 für STAC, Tile-Daten dann in
LV95-Metern (kein Reprojizieren der Z-Werte nötig). Quelle:
[STAC tech docs](https://docs.geo.admin.ch/) · COG-Tile live geprüft.
### A.4 SWISSIMAGE / Karten — WMTS-Kacheln
Orthofoto (10 cm) und Landeskarten als Kacheln. RESTful-URL-Template:
```
https://wmts.geo.admin.ch/1.0.0/<Layer>/default/<Time>/<TileMatrixSet>/<z>/<TileCol>/<TileRow>.<ext>
```
Beispiel-Layer:
- `ch.swisstopo.swissimage` — Orthofoto, `.jpeg`
- `ch.swisstopo.pixelkarte-farbe` — Landeskarte farbig, `.jpeg`
- `ch.kantone.cadastralwebmap-farbe`**Katasterplan (AV)**, `.png`
TileMatrixSets: **`2056` (LV95)**, `21781`, `3857` (Web-Mercator), `4326`. Zoom 028
(4000 m → 0.1 m); Zoom 27/28 nur für wenige Layer (swissimage, Kataster). Für 3D in
Three.js am einfachsten **`3857`** (Standard-Slippy-Map-Schema, z/x/y), z.B.
```
https://wmts.geo.admin.ch/1.0.0/ch.swisstopo.swissimage/default/current/3857/{z}/{x}/{y}.jpeg
```
Für planimetrisch exakte 2D-Arbeit besser **`2056`**. CORS `*` (verifiziert). Quellen:
[WMTS docs](https://docs.geo.admin.ch/visualize-data/wmts.html) ·
[WMTS service](https://wmts.geo.admin.ch/) ·
[WMTS EPSG:2056 CodePen](https://codepen.io/geoadmin/pen/GZKEam).
> Es gibt zusätzlich klassisches **WMS** (`https://wms.geo.admin.ch/`, GetMap mit
> beliebiger BBox/Größe, ebenfalls EPSG:2056). Für ein einzelnes georeferenziertes
> Orthofoto-Rechteck unter dem Modell ist ein WMS-GetMap manchmal praktischer als
> WMTS-Kacheln zu stitchen. [WMS docs](https://docs.geo.admin.ch/visualize-data/wms.html)
### A.5 swissBUILDINGS3D — Nachbargebäude (3D)
Zwei Wege:
**(a) 3D-Tiles (Streaming, Cesium-Format)** — `glTF`/`tileset.json`, für große Gebiete:
```
https://3d.geo.admin.ch/<Layer>/<Version>/<Time>/tileset.json
```
Layer u.a. `ch.swisstopo.swissbuildings3d.3d`, `ch.swisstopo.swisstlm3d.3d`,
`ch.swisstopo.swissnames3d.3d`, `ch.swisstopo.vegetation.3d`. `Version` = `v1`, `Time`
optional (ISO `YYYYMMDD`, weglassen = aktuellste). CORS `*` (verifiziert auf
`tileset.json`). Direkt für CesiumJS gedacht; in **reinem Three.js** über
`@loaders.gl/3d-tiles` oder den `3DTilesRendererJS` (NASA-AMMOS/`three.js`-Community)
ladbar. [3D-Tiles docs](https://docs.geo.admin.ch/visualize-data/3d-tiles.html) ·
[Switzerland in 3D](https://www.swisstopo.admin.ch/en/switzerland-in-3d)
**(b) STAC-Tiles als CAD/Mesh-Datei (Download pro Tile)** — so macht es DOSSIER:
Collections `ch.swisstopo.swissbuildings3d_3_0` (neu; in Städten z.T. >700 MB Tiles)
und `ch.swisstopo.swissbuildings3d_2` (1-km-Tiles, ~50 MB, stabil). Assets in
`.dxf/.dwg/.obj/.ifc` (+ `.zip`), Varianten `solid`/`separated`. Für den **Import als
echte, editierbare Massen** ins eigene Modell ist der OBJ/IFC-Tile-Weg besser als
3D-Tiles (die sind read-only Visualisierung). swissBUILDINGS3D: >3 Mio Gebäude,
Lage-/Höhengenauigkeit 3050 cm.
**Empfehlung:** Für „Nachbarschaft als Kontext anzeigen" (Phase 4 Start) **3D-Tiles
streamen** (kein Download, kein Parsing). Wenn der Nutzer Nachbargebäude als Geometrie
*braucht* (Verschattung, Abstand), **STAC-OBJ-Tile** laden und als Mesh importieren.
### A.6 Parzelle / Kataster (AV) — Identify-Service ⭐
**Verifiziert** — Parzellen-Polygon aus einer Koordinate, in LV95:
```
GET https://api3.geo.admin.ch/rest/services/api/MapServer/identify
?geometry=2600423,1199521&geometryType=esriGeometryPoint
&imageDisplay=100,100,96&mapExtent=2600323,1199421,2600523,1199621
&tolerance=2&layers=all:ch.kantone.cadastralwebmap-farbe
&returnGeometry=true&geometryFormat=geojson&sr=2056
→ {"results":[{"type":"Feature","bbox":[...],
"geometry":{"type":"Polygon","coordinates":[[ [2600377.1,1199523.7], ... ]]},
"attributes":{"number":"698","egris_egrid":"CH507635214670","ak":"BE", ...}}]}
```
- Parzellen-Layer: **`ch.kantone.cadastralwebmap-farbe`** (liefert `number`,
`egris_egrid` = EGRID, Kanton; mit `returnGeometry=true&geometryFormat=geojson` das
**Parzellen-Polygon in LV95-Metern** → direkt als Grundstücksgrenze importierbar).
- Gebäudeadressen: `ch.swisstopo.amtliches-gebaeudeadressverzeichnis`; Gebäude-/
Wohnungsregister `ch.bfs.gebaeude_wohnungs_register` (EGID).
- Pflichtparameter: `geometry`, `geometryType` (`esriGeometryPoint|...Polygon|...Envelope`),
`mapExtent`, `imageDisplay`, `tolerance`; `sr=2056`; max 50 Features/Request.
Quellen: [Identify features](https://docs.geo.admin.ch/access-data/identify-features.html) ·
[GeoAdmin REST Identify/Find](https://geoadmin.readthedocs.io/en/latest/services/sdiservices.html) ·
Live-Antwort oben.
### A.7 Geocoding — SearchServer (Adresse → LV95)
**Verifiziert** (Adresse → Koordinate, deckt sich mit DOSSIERs `geocode()`):
```
GET https://api3.geo.admin.ch/rest/services/api/SearchServer
?searchText=Bundesplatz 3 Bern&type=locations&origins=address&sr=2056&limit=1
→ results[0].attrs: { label:"Bundesplatz 3 <b>3011 Bern</b>", lat:46.94677, lon:7.44419,
geom_st_box2d:"BOX(2600423.26 1199521.11, ...)", origin:"address", ... }
```
- `type=locations`, `origins` aus `{address, parcel, gg25, gazetteer, zipcode, district,
kantone}`, `sr=2056`. **Im LV95-Modus liefert die Geo-Admin-Konvention `y`=East,
`x`=North** (DOSSIER liest genau so: `e=attrs.y`, `n=attrs.x`). Labels enthalten
`<b>`-Tags (strippen).
- `type=featuresearch` + `features=<layer>` durchsucht Attribute (z.B. Parzellennummer).
Quelle: [Search](https://docs.geo.admin.ch/access-data/search.html) · Live-Antwort oben.
### A.8 Koordinatensystem LV95 / EPSG:2056 & Transformationen
Intern rechnet das BIM-Tool in **Metern** (ROADMAP-Konvention) und verschiebt den
Projekt-Ursprung nahe (0,0,0); LV95-Koordinaten sind ~2.6 Mio / 1.2 Mio Meter groß und
würden bei `float32` (Three.js) zu **Jitter** führen → **Origin-Shift Pflicht** (siehe B.3).
DOSSIER macht genau das (`origin_shift`/`shift_lv95`, typ. bbox-Center → 0/0/0).
Transformations-Optionen:
1. **`proj4` (npm `proj4@2.20.9`)** — universell, exakt. EPSG:2056-Definition:
```js
proj4.defs("EPSG:2056",
"+proj=somerc +lat_0=46.9524055555556 +lon_0=7.43958333333333 +k_0=1 "+
"+x_0=2600000 +y_0=1200000 +ellps=bessel "+
"+towgs84=674.374,15.056,405.346,0,0,0,0 +units=m +no_defs +type=crs");
const [e,n] = proj4("EPSG:4326","EPSG:2056",[lon,lat]); // WGS84→LV95
```
Genauigkeit mit dieser 3-Parameter-`towgs84` ~1 m (für Kontext-Import völlig
ausreichend). Types: `@types/proj4`. Quellen:
[epsg.io/2056](https://epsg.io/2056) · [proj4js](https://github.com/proj4js/proj4js).
2. **Näherungsformeln (CH1903→WGS84, swisstopo)** — DOSSIERs Ansatz, ~1 m genau,
**0 Dependencies** (zwei kleine Funktionen `lv95_to_wgs84`/`wgs84_to_lv95`).
1:1 nach TS portierbar; gut, wenn man `proj4` nicht ziehen will. Reicht, weil
STAC-Queries ohnehin nur eine grobe WGS84-Bbox brauchen und alle *Daten* schon in
LV95 kommen.
3. **swisstopo REFRAME Web-API** — cm-genaue offizielle Umrechnung (LV95↔WGS84,
LN02↔Bessel). Nur nötig, wenn Vermessungs-Genauigkeit verlangt wird. REST, online.
[REFRAME Web](https://www.swisstopo.admin.ch/en/rest-api-geoservices-reframe-web)
**Empfehlung:** `proj4` mit fester EPSG:2056-Def (eine Abhängigkeit, exakt genug,
wartungsarm) — oder, wenn Dependency-Geiz, DOSSIERs Formeln portieren. REFRAME nur bei
Bedarf nachrüsten.
### A.9 Endpoint-Übersicht (Spickzettel)
| Zweck | Endpoint | Frei/CORS | Format |
|---|---|---|---|
| Punkt-Höhe | `api3…/rest/services/height` | ✅ ✅ | JSON |
| Höhenprofil (Schnitt) | `api3…/rest/services/profile.json` | ✅ ✅ | JSON/CSV |
| Gelände-Mesh (COG) | STAC `…/swissalti3d/items` → `.tif` (COG, 2056) | ✅ ✅ Range | GeoTIFF |
| Gelände (ASCII) | STAC `…/swissalti3d` → `.xyz.zip` | ✅ ✅ | XYZ in ZIP |
| Orthofoto/Karte | `wmts…/1.0.0/<layer>/…/{z}/{x}/{y}.jpeg` | ✅ ✅ | Kacheln |
| 3D-Nachbargebäude (stream) | `3d…/ch.swisstopo.swissbuildings3d.3d/v1/tileset.json` | ✅ ✅ | 3D-Tiles/glTF |
| 3D-Gebäude (Datei) | STAC `…/swissbuildings3d_2` → `.obj/.ifc` | ✅ ✅ | OBJ/IFC |
| Parzelle/Kataster | `api3…/MapServer/identify` `layers=all:ch.kantone.cadastralwebmap-farbe` | ✅ ✅ | GeoJSON |
| Geocoding | `api3…/SearchServer?type=locations` | ✅ ✅ | JSON |
---
## Teil B — Standort-Kontext importieren (Terrain + Parzelle + Nachbargebäude)
So bekommt ein Projekt seinen realen Kontext „auf Knopfdruck". Der Ablauf folgt
DOSSIER (`rhino/swisstopo.py`), übersetzt auf Browser-Libs.
### B.1 Pipeline (End-to-End)
```
Adresse/Parzelle ──SearchServer──▶ Zentrum (E,N) in LV95
├─ radius r ──▶ bbox_LV95 (E±r, N±r) ──proj4/Formeln──▶ bbox_WGS84
├─[Parzelle] identify(cadastralwebmap, point) ─▶ Polygon (LV95) ─▶ Grundstücksgrenze (Ebene 01 Vermessung)
├─[Gelände] STAC(swissalti3d, bbox_WGS84) ─▶ COG .tif(2056)
│ └─ geotiff.js readRasters(window) ─▶ Höhen-Grid (E,N,Z, m)
│ └─ Three.js BufferGeometry (Grid→Mesh) [optional: TIN, Höhenlinien, Volumen]
├─[Orthofoto] WMTS swissimage ─▶ Textur auf Gelände-Mesh ODER georef. Plane
└─[Nachbarn] 3D-Tiles streamen (Anzeige) ODER STAC swissbuildings3d_2 .obj ─▶ Mesh-Import
(Weltweit/ausserhalb CH: OSM-Overpass als Fallback, siehe B.5)
──▶ alle Geometrien um origin_shift (bbox-Center→0/0/0) verschoben, Z aus ALTI3D
```
### B.2 Gelände-Mesh aus swissALTI3D (Kern, Phase 4)
**Empfohlener Browser-Weg (COG + geotiff.js):**
1. STAC-Query mit `bbox_WGS84` → Liste der überlappenden Tiles; pro Tile das
gewünschte COG-Asset (`_2_2056_` für 2 m, `_0.5_2056_` für 0.5 m).
2. `geotiff.js`: `const tiff = await fromUrl(href)` → COG; `image.readRasters({window})`
liest **nur den Ausschnitt** (Range-Requests, da CORS+Range bestätigt). Ergebnis ist
ein reguläres Z-Raster mit bekanntem Origin/PixelScale (LV95-Meter) aus den
GeoKeys/`image.getOrigin()`/`image.getResolution()`.
3. Raster → **`THREE.BufferGeometry`**: ein Vertex pro Rasterpunkt
`(EshiftE, NshiftN, ZshiftZ)`, Faces als zwei Dreiecke pro Zelle (DOSSIER:
`mesh_from_grid`, gleiche Logik), `computeVertexNormals()`. Bei 0.5 m wird das Mesh
groß → bei Bedarf raumräumlich sub-samplen (DOSSIER macht ganzzahliges Sub-Sampling
auf dem **globalen** LV95-Raster, damit Nachbar-Tiles nahtlos zusammenpassen).
4. Mehrere Tiles: erst zu **einem** Grid mergen (gemeinsamer Origin/Step), dann meshen —
sonst entstehen Nähte (DOSSIER: `merge_grids`).
**Alternativweg (XYZ, exakt wie DOSSIER):** `.xyz.zip` laden → mit **`fflate`**
(npm, schnellster Inflate im Browser) entpacken → ASCII `E N Z` parsen → gleiches Grid.
Robust, aber überträgt mehr Bytes als der COG-Range-Weg. Für den Port empfehle ich
**COG primär, XYZ als Fallback**.
Bibliotheken: `geotiff@3.0.5`, `fflate` (XYZ-Variante), `three@0.185.0`.
[geotiff.js](https://github.com/geotiffjs/geotiff.js/) ·
[3D-Terrain aus GeoTIFF mit Three.js](https://spatial-dev.guru/2024/11/30/creating-3d-terrain-maps-from-geotiff-files-with-three-js/).
**Ableitungen wie in DOSSIER** (alle aus dem Grid, in Phase 4 portierbar):
- **Höhenlinien** (Marching-Squares auf dem Grid; npm `d3-contour` oder
`marchingsquares`) — für 2D-Plan.
- **TIN / Patch** (Delaunay aus den Punkten; npm `delaunator`) — alternatives Mesh.
- **Geschlossenes Gelände-Volumen** (Boden N m unter tiefstem Punkt) → gefüllte
Querschnitte beim Schnitt-Cut (DOSSIER `terrainVolume`/`terrainVolumeDepth`).
### B.3 Origin-Shift (Pflicht)
LV95-Koordinaten (~2.6e6) sprengen `float32`. Beim Import einmal
`shift = (eCenter, nCenter, zRef)` festlegen, **alle** Geometrien `shift` rechnen, und
`shift` am Projekt persistieren (für Re-Import / Geo-Referenz / Norden). DOSSIER:
`origin_shift`/`shift_lv95`, plus „Auto-Zoom auf Import" (ROADMAP §11). Damit bleibt das
Modell metergenau und der Rückweg in echte LV95-Koordinaten (Export, weitere
swisstopo-Abfragen) ist `+ shift`.
### B.4 Parzelle + Orthofoto
- **Parzelle:** `identify(...cadastralwebmap..., returnGeometry=true, geometryFormat=geojson)`
→ Polygon (LV95) → `shift` → als geschlossene Polylinie auf Ebene **`01 Vermessung`**.
Attribute `number`/`egris_egrid` am Objekt/Projekt speichern.
- **Orthofoto:** WMTS `swissimage`-Kacheln über die Modell-Bbox stitchen → eine Textur,
als Material auf das Gelände-Mesh **oder** auf eine georeferenzierte Plane (DOSSIER:
`add_ortho_plane`, mit UV-Shift gegen Tile-Nähte). Für 3D ist `3857` einfacher, für
exakte 2D-Lage `2056`.
### B.5 OSM-Overpass als weltweiter Fallback (Phase 4)
Ausserhalb der Schweiz (oder wenn nur 2D-Footprints/Straßen reichen): DOSSIER hat einen
**Overpass-Importer** (`https://overpass-api.de/api/interpreter`, POST) mit 7 Kategorien
(Straßen/Gebäude/Wasser/Wasserläufe/Grün/Wege). Liefert OSM-Ways → Polylinien. Im
Browser identisch nutzbar (`fetch` POST). Overpass koordiniert in WGS84 → mit
`proj4`→LV95→`shift`. Hinweis: Overpass-CORS ist beim Haupt-Server meist offen, kann
aber je nach Mirror variieren; ggf. anderen Mirror wählen.
[Overpass API](https://overpass-api.de/).
### B.6 Was sich von DOSSIER **nicht** 1:1 portieren lässt
- **Rhino-`_-Import`** für DXF/DWG/OBJ und **`_-MeshPatch`/Delaunay**-Commands gibt es im
Browser nicht → ersetzen durch JS-Parser/Algorithmen (OBJ: `three`-`OBJLoader`;
Delaunay: `delaunator`; Contours: `d3-contour`).
- **Filesystem-Cache neben der `.3dm`** → Browser: **IndexedDB**-Cache (Cache-API für
Kacheln). Passt zur ROADMAP-Phase 5 (IndexedDB-Persistenz).
- IFC-Import von swissBUILDINGS3D 3.0 → über **web-ifc** (ohnehin im Stack, Phase 4).
---
## Teil C — SIA 416 (Flächen/Volumen) & SIA 421 + DOSSIER-Logik
### C.1 SIA 416 — Flächen- und Volumenhierarchie
**SIA 416:2003** „Flächen und Volumen von Gebäuden" ist die in der CH gültige Norm und
Berechnungsbasis für Kostenplanung/Flächennachweise. Sie kennt vier Bereiche:
**GSF** (Grundstück), **GF** (Geschossflächen), **AGF** (Aussengeschossflächen), **GV**
(Volumen). Maßgeblich ist die effektive Geometrie (keine fiktiven Zuschläge mehr).
Quellen: [SIA 416 Übersicht (siworks/DBV)](https://diebauherrenvertretung.ch/sia146/) ·
[SIA-Shop 416/2003](https://shop.sia.ch/normenwerk/architekt/sia%20416/dfi/D/Product) ·
[Flächenkennzahlen SIA 416 (Ginesta, PDF)](https://www.ginesta.ch/resources/public/lava3/media/kcfinder/files/Fl%C3%A4chenkennzahlen%20SIA%20416%20Norm.pdf).
**Hierarchie & Formeln (verifiziert):**
```
GSF Grundstücksfläche
GF Geschossfläche = KF + NGF
├─ KF Konstruktionsfläche (Wände/Stützen; tragend KFT + nicht tragend KFN)
└─ NGF Nettogeschossfläche = NF + VF + FF
├─ NF Nutzfläche = HNF + NNF
│ ├─ HNF Hauptnutzfläche (zweckbestimmte Hauptnutzung: Wohnen, Büro …)
│ └─ NNF Nebennutzfläche (Lager, Bad/WC, Abstell-, Nebenräume)
├─ VF Verkehrsfläche (Erschließung: Flure, Treppen, Lifte)
└─ FF Funktionsfläche (Gebäudetechnik: Heizung, Lüftung, Technik)
AGF Aussengeschossfläche (Balkone, Terrassen, gedeckte Aussenflächen)
GV Gebäudevolumen [m³]
```
| Abk. | Deutsch | Inhalt (Kurz) |
|---|---|---|
| GSF | Grundstücksfläche | Parzellenfläche (aus Kataster, Teil A.6) |
| GF | Geschossfläche | allseits umschlossene + überdeckte Grundrissflächen, geschossweise |
| KF | Konstruktionsfläche | Bauteile (Wände/Stützen), nicht begehbar; KFT tragend / KFN nicht tragend |
| NGF | Nettogeschossfläche | begehbare Fläche innerhalb der Umschließung = NF+VF+FF |
| NF | Nutzfläche | tatsächlich nutzbar = HNF+NNF |
| HNF | Hauptnutzfläche | zweckbestimmte Hauptnutzung |
| NNF | Nebennutzfläche | dienende Nebenräume (Lager, Bad, WC) |
| VF | Verkehrsfläche | horizontale/vertikale Erschließung |
| FF | Funktionsfläche | Gebäudetechnik |
| AGF | Aussengeschossfläche | Balkone/Terrassen u.ä. |
| GV | Gebäudevolumen | umbauter Raum [m³] |
> **Versionshinweis:** Es kursiert eine Revision **SIA 416:2017** mit präzisierten
> Begriffen, in der Praxis wird aber breit weiter **416:2003** referenziert. Für unser
> Tool reicht die Klassifikation **HNF/NNF/VF/FF/GF/AGF + Bilanz**; die genaue Auflage
> nur als Label dokumentieren. Verbindliche Definitionen stehen im kostenpflichtigen
> Normtext (SIA-Shop) — die hier zitierten freien Quellen stimmen in der Struktur überein.
### C.2 SIA 421 — Flächengliederung für Bewirtschaftung/Vermietung
**SIA 421:2006** „Flächengliederung und Mengenangaben" (Korrigenda C1:2014) baut auf der
SIA-416-Systematik auf und **gliedert Flächen für Immobilien-Bewirtschaftung und
Vermietung** (Mietflächen, Nutzungseinheiten, Zuordnung von VF/FF zu Mietern). Relevant,
sobald wir **Mietflächen-/Bewirtschaftungs-Auswertungen** wollen (über den reinen
Architektur-Nachweis hinaus). Für den ersten Wurf **nicht zwingend** — SIA 416 reicht
für Flächennachweis und Raumschema. SIA 421 ist die natürliche Erweiterung, wenn
Property-Management-Features kommen. Quellen:
[SIA 421:2006 (PDF Inhalt)](https://shop.sia.ch/d475e3f9-10c9-48aa-9be8-657784ea519b/F/DownloadAnhang) ·
[Korrigenda C1:2014 (PDF)](https://www.sia.ch/fileadmin/content/download/sia-norm/korrigenda_sn/421-C1_2014_d.pdf).
### C.3 Wie DOSSIER SIA macht (Vorlage für den Port)
Quellcode: `rhino/elemente.py` (Räume) + `rhino/elemente_uebersicht.py` (Bilanz/CSV).
Kernpunkte, die wir 1:1 übernehmen:
**Datenmodell pro Raum.** Ein Raum ist eine **geschlossene Outline-Curve** + ein
**Text-Stempel**. Klassifikation über das Feld `dossier_raum_sia` mit Werten
`{"", hnf, nnf, vf, ff, gf, agf}` (`_RAUM_SIA_KINDS`). Weitere Felder: `name`, `nummer`,
`funktion` (`wohnen|schlafen|bad|kueche|essen|flur|…`), `personen` (für
Personenbelegung/Brandschutz), Rundung, Stempel-Layout.
**Flächen-/Umfangsberechnung** (`_raum_amp`): Fläche aus `AreaMassProperties` (≙ in JS
**Shoelace-Formel** über das Polygon), Umfang = Kurvenlänge, plus Zentroid für den
Stempel. Im Browser: Polygon-Fläche selbst rechnen (Shoelace), kein Mesh nötig — exakt
und schnell. Rundungsstufen (`_format_area`): `exakt|0.01|0.1|0.5|1` (z.B. `0.5` =
`round(a*2)/2`).
**SIA-Bilanz** (`compute_sia_bilanz`, `scope = total | geschoss:<id>`): summiert
Raumflächen je Klasse, dann:
```
NF = HNF + NNF
NGF = NF + VF + FF (GF/AGF separat aggregiert, zählen nicht in NGF)
```
(genau die Formeln aus C.1). Ergebnis je Geschoss + Total.
**Farb-/Darstellungs-Konvention** (`_SIA_COLORS_HEX`, Pastell): HNF rot `#e8a8a8`,
NNF orange `#e8c498`, VF gelb `#e8d878`, FF hellblau `#a8c8e0`, GF grau `#d0d0d0`,
AGF hellgrün `#c0d8c0`. Umgesetzt als **regelbasierte Overrides** (`_build_sia_preset_rules`,
Preset „SIA-Raeume"): Bedingung `user_string == code` → Outline-Farbe + Solid-Hatch.
→ Passt 1:1 zur geplanten **Overrides-Engine** (ROADMAP §2c/§11).
**Export** (`_cmd_export_raeume`, `_export_bilanz`): CSV, **Semikolon + UTF-8-BOM**
(CH/DE-Excel), Dezimal-Komma. Raumliste: Nummer; Name; Geschoss; Funktion; SIA; Fläche;
Fläche gerundet; Umfang. Bilanz: eine Spalte je Geschoss + Total, Zeilen je Kategorie.
→ Im Browser: Blob + Download (kein SaveFileDialog), gleiche CSV-Struktur. Optional
direkt `.xlsx` via `sheetjs`/`exceljs`.
**Layer-Routing:** GF→`61_GF`, AGF→`62_AGF`, Rest→`60_RAEUME` (`_layer_path_for_raum_sia`)
— damit Geschossflächen-Outlines getrennt schalt-/exportierbar sind. Übersetzt sich auf
unsere Ebenen-Codes (`60 Räume`).
**Was wir im Port besser/anders machen:**
- Fläche per **Shoelace** statt Rhino-Mass-Props (0 Deps).
- Bilanz **reaktiv** aus dem semantischen Modell (Zustand-Store) statt Doc-Scan.
- **Space = Slab-/Raum-Polygon mit `siaClass`** im Datenmodell (ROADMAP:
`Space { boundary, name }`), Bilanz als abgeleitete Sicht.
---
## Teil D — Umsetzungsplan (Endpunkte · Libs · Phase)
Reihenfolge orientiert sich an der ROADMAP (SIA = Phase 2, Geo = Phase 4) und an „größter
Nutzen zuerst, geringste Abhängigkeit zuerst".
### Phase 2 — SIA-Räume (kein Netz, reine Logik) ⭐
**Endpunkte:** keine. **Libs:** keine (Shoelace selbst), optional `exceljs`/`sheetjs` für
.xlsx.
1. `Space`-Modell: `{ boundary[], geschossId, name, nummer, funktion, siaClass∈{hnf,nnf,vf,ff,gf,agf}, personen }`.
2. `computeArea` (Shoelace) + Umfang; Rundungsstufen (`exakt|0.01|0.1|0.5|1`) wie DOSSIER `_format_area`.
3. `computeSiaBilanz(scope)` → `{hnf,nnf,nf,vf,ff,ngf,gf,agf,count,personen}` mit
`nf=hnf+nnf`, `ngf=nf+vf+ff`.
4. SIA-Farbpalette + Stil-Override (Outline-Farbe/Solid-Fill) in der Overrides-Engine.
5. Raumstempel-Renderer (Felder-Layout) + **CSV-Export** (Semikolon, UTF-8-BOM, Komma)
für Raumliste **und** Bilanz.
*Ergebnis:* SIA-416-Flächennachweis + Raumschema, Excel-kompatibel — vor jeder Geo-Arbeit nutzbar.
### Phase 4a — Geo-Grundlage: Koordinaten + Standortabfrage
**Endpunkte:** `SearchServer` (Geocoding), `height` (Punkt-Z), `identify`
(Parzelle, `cadastralwebmap-farbe`). **Libs:** `proj4@2.20.9` (+ `@types/proj4`).
1. `proj4`-EPSG:2056-Def + Helfer `lv95↔wgs84`, `bboxLv95→bboxWgs84` (DOSSIER-Logik).
2. **Origin-Shift**-Mechanik + Persistenz am Projekt (`shift = bbox-Center`), Auto-Zoom.
3. Adresssuche → Zentrum; „Gelände-Höhe holen" (height); „Parzelle holen" → Polygon auf
Ebene `01 Vermessung` (+ EGRID/Nummer am Projekt).
*Ergebnis:* Projekt ist georeferenziert; Parzelle + Adresse + Geländehöhe vorhanden.
### Phase 4b — Gelände-Mesh + Orthofoto
**Endpunkte:** STAC `swissalti3d` (COG `.tif`, 2056) + `profile.json`; WMTS `swissimage`.
**Libs:** `geotiff@3.0.5`, `three@0.185.0`, optional `fflate` (XYZ-Fallback),
`d3-contour`/`marchingsquares` (Höhenlinien), `delaunator` (TIN).
1. STAC-Query (bbox) → COG-Tiles; `geotiff.js` Range-Read → Grid; Tiles mergen.
2. Grid → `THREE.BufferGeometry` (DOSSIER `mesh_from_grid`/`merge_grids`); Sub-Sampling
auf globalem LV95-Raster; Normalen.
3. Optional: Höhenlinien (2D-Plan), TIN, geschlossenes Volumen (Schnitt-Füllung).
4. WMTS-`swissimage`-Kacheln → Textur auf Mesh/Plane (DOSSIER `add_ortho_plane`).
5. Geländeschnitt im 2D-Plan via `profile.json` entlang der Schnittlinie.
*Ergebnis:* echtes Gelände mit Orthofoto unter dem Gebäude; Geländeschnitte.
### Phase 4c — Nachbargebäude + weltweiter Fallback
**Endpunkte:** 3D-Tiles `ch.swisstopo.swissbuildings3d.3d/v1/tileset.json` (Anzeige)
**oder** STAC `swissbuildings3d_2` `.obj/.ifc` (Import); OSM `overpass-api.de`.
**Libs:** `@loaders.gl/3d-tiles@4.4.3` **oder** `3DTilesRendererJS`; `three`-`OBJLoader`;
`web-ifc` (für 3.0-IFC); `proj4`.
1. Kontext-Anzeige: 3D-Tiles in den Three-Scenegraph streamen (kein Download).
2. Bedarf an echter Geometrie (Verschattung/Abstand): STAC-OBJ-Tile → Mesh-Import → `shift`.
3. Ausserhalb CH / nur 2D: Overpass-POST → Ways → Polylinien (Ebene `70 OSM`).
*Ergebnis:* Nachbarschaftskontext (CH 3D, weltweit OSM).
### Querschnitt (alle Geo-Phasen)
- **Caching:** IndexedDB für STAC-Antworten + COG-Bytes + Kacheln (ersetzt DOSSIERs
Disk-Cache); Cache-Schlüssel = Tile-ID/URL.
- **Defensive HTTP:** Timeouts, Retry/Backoff, 402/429 abfangen, Größen-Limit pro Tile
(DOSSIER: 200-MB-Guard).
- **Attribution:** „© swisstopo" sichtbar einblenden, „© OpenStreetMap-Mitwirkende" bei OSM.
- **Worker:** GeoTIFF-Parsing + Mesh-Bau im Web-Worker (Comlink, ROADMAP-Stack), UI bleibt flüssig.
### Empfohlener Library-Satz (npm, aktuell)
`proj4@2.20.9` · `geotiff@3.0.5` · `three@0.185.0` · `fflate` (XYZ) ·
`@loaders.gl/3d-tiles@4.4.3` *oder* `3DTilesRendererJS` · `delaunator` ·
`d3-contour` · `web-ifc` (im Stack) · `exceljs`/`sheetjs` (optional, .xlsx).
---
## Quellen
- GeoAdmin REST (height/profile/identify/find/search): https://geoadmin.readthedocs.io/en/latest/services/sdiservices.html
- GeoAdmin Tech-Docs (Hub): https://docs.geo.admin.ch/
- Identify Features: https://docs.geo.admin.ch/access-data/identify-features.html
- Search: https://docs.geo.admin.ch/access-data/search.html
- WMTS: https://docs.geo.admin.ch/visualize-data/wmts.html · https://wmts.geo.admin.ch/
- WMS: https://docs.geo.admin.ch/visualize-data/wms.html
- 3D-Tiles: https://docs.geo.admin.ch/visualize-data/3d-tiles.html
- swissALTI3D: https://www.swisstopo.admin.ch/en/height-model-swissalti3d
- Switzerland in 3D / swissBUILDINGS3D: https://www.swisstopo.admin.ch/en/switzerland-in-3d
- Terms of use (FSDI / OGD): https://www.geo.admin.ch/en/general-terms-of-use-fsdi
- REFRAME Web-API: https://www.swisstopo.admin.ch/en/rest-api-geoservices-reframe-web
- EPSG:2056 Definition: https://epsg.io/2056
- proj4js: https://github.com/proj4js/proj4js
- geotiff.js: https://github.com/geotiffjs/geotiff.js/
- Three.js-Terrain aus GeoTIFF: https://spatial-dev.guru/2024/11/30/creating-3d-terrain-maps-from-geotiff-files-with-three-js/
- WMTS EPSG:2056 Beispiel: https://codepen.io/geoadmin/pen/GZKEam
- Overpass API: https://overpass-api.de/
- SIA 416 (Übersicht): https://diebauherrenvertretung.ch/sia146/ · https://shop.sia.ch/normenwerk/architekt/sia%20416/dfi/D/Product
- SIA 416 Flächenkennzahlen (PDF): https://www.ginesta.ch/resources/public/lava3/media/kcfinder/files/Fl%C3%A4chenkennzahlen%20SIA%20416%20Norm.pdf
- SIA 421:2006 (PDF) + Korrigenda C1:2014: https://shop.sia.ch/d475e3f9-10c9-48aa-9be8-657784ea519b/F/DownloadAnhang · https://www.sia.ch/fileadmin/content/download/sia-norm/korrigenda_sn/421-C1_2014_d.pdf
- DOSSIER-Quellcode (Vorlage): `rhino/swisstopo.py`, `rhino/osm.py`, `rhino/elemente.py` (Räume/SIA), `rhino/elemente_uebersicht.py` (Bilanz/CSV)
+197
View File
@@ -0,0 +1,197 @@
# Technologie-Auswahl: Browser-basiertes BIM-Tool (DOSSIER-Port)
> **Kontext:** Standalone, browser-basiertes BIM-Werkzeug (React + TypeScript + Three.js) als Port des DOSSIER Rhino-Plugins. Keine Server-Abhaengigkeit gewuenscht (alles client-side). Recherchestand: Juni 2026.
>
> **Leitprinzip:** Wo immer moeglich auf einem echten B-Rep-Geometriekernel (OCCT) aufbauen, weil ein BIM-Werkzeug exakte 2D-Ableitungen (Schnitte, verdeckte Kanten, Bemassung) braucht — das ist mit reinen Dreiecksnetzen nicht sauber loesbar. Mesh-Booleans (Manifold) als schnelle Ergaenzung fuer Importgeometrie und Vorschau.
---
## 1. Geometriekernel im Browser (Solids + Booleans)
Das ist das schwierigste und zugleich wichtigste Problem. Drei ernsthafte Optionen, die alle im Browser (WASM) laufen.
### Optionen
**A) opencascade.js (OCCT als WASM)**
Port des vollstaendigen OpenCASCADE-Kernels (OCCT) nach WebAssembly via Emscripten. Voller B-Rep-Kernel: NURBS-Flaechen, exakte boolesche Operationen, Fillets/Chamfers, STEP/IGES-Import/-Export, Meshing. TypeScript-Bindings vorhanden. Die neueren Versionen (V3-Linie) zielen explizit auf moderne Bundler.
- Repo: <https://github.com/donalffons/opencascade.js/>
- Doku: <https://opencascade-js.vercel.app/>
- npm: <https://www.npmjs.com/package/opencascade.js>
- **Lizenz:** OCCT steht unter **LGPL-2.1 mit OCCT-Exception** (seit 6.7.0). Kommerzielle Nutzung ohne Lizenzgebuehren/Royalties erlaubt, sofern man (a) sichtbar darauf hinweist, dass die Software OCCT nutzt, und (b) eine Kopie der OCCT-Lizenz mitliefert. Die Exception entschaerft das statische-Linking-Problem fuer Header/Templates. Quellen: <https://dev.opencascade.org/resources/licensing>, <https://spdx.org/licenses/OCCT-exception-1.0.html>
- **Trade-offs:** Sehr grosse WASM-Binaries (zweistelliger MB-Bereich je nach Custom-Build), steile Lern- und API-Kurve (rohe OCCT-C++-API durchgereicht), Build-Pflege aufwendig.
**B) replicad (Abstraktion ueber opencascade.js)***empfohlene Basis*
replicad ist eine schlanke, idiomatische TypeScript-Schicht ueber opencascade.js. Es liefert genau die High-Level-Bausteine, die ein BIM-Tool braucht: Sketches/Blueprints, Extrude/Revolve/Loft, Booleans, Fillet/Chamfer — und entscheidend: **HLR-Projektionen** (`drawProjection`) und 2D-Drawings mit SVG-Export. Laeuft per Design im **Web Worker** und gibt Dreiecksnetze an den Main-Thread fuer Three.js zurueck.
- Doku/Library-Guide: <https://replicad.xyz/docs/use-as-a-library/>
- API: <https://replicad.xyz/docs/api/>
- **Lizenz:** **MIT** (eigene Schicht) — der OCCT/LGPL-Hinweis gilt weiterhin fuer das eingebettete WASM. Repo: <https://github.com/sgenoud/replicad>
- **Trade-offs:** Erbt OCCT-WASM-Groesse und -Robustheitsgrenzen; kleineres Team/Bus-Faktor als OCCT selbst. Man kann jederzeit „unter die Haube" auf rohes opencascade.js durchgreifen, wenn die Abstraktion nicht ausreicht.
**C) Manifold (manifold-3d, WASM)***empfohlen als schnelle Mesh-Ergaenzung*
Geometrie-Bibliothek fuer topologisch robuste **Dreiecksnetze**. Bietet den (laut Autor) ersten garantiert mannigfaltigen Mesh-Boolean-Algorithmus — extrem schnell und robust gegen Randfaelle. Stark parallelisiert.
- Repo: <https://github.com/elalish/manifold>
- npm: <https://www.npmjs.com/package/manifold-3d> (aktuell v3.5.x, Juni 2026)
- **Lizenz:** **Apache-2.0** (sehr permissiv, ideal). Bestaetigt: <https://github.com/elalish/manifold>
- **Trade-offs:** **Nur Meshes, kein B-Rep** — keine exakten NURBS-Flaechen, keine echten Fillets auf Krümmungen, kein STEP. Fuer ein BIM-Tool, das exakte Plaene/Schnitte ableiten will, alleine nicht ausreichend, aber unschlagbar fuer schnelle Booleans auf importierter Mesh-Geometrie und Live-Vorschau. **Wichtig:** unterstuetzt `slice(z)` und `project()` (siehe Abschnitt 3).
**D) three-bvh-csg (nur erwähnt, nicht empfohlen als Kernel)**
Sehr schnelle CSG direkt auf Three.js-BufferGeometry (auf three-mesh-bvh). >100x schneller als BSP-basierte Three.js-CSG-Libs. Aber: erklaert selbst, dass Resultate „aufgrund numerischer Praezision nicht garantiert 2-mannigfaltig" sind und verweist fuer CAD-Robustheit ausdruecklich auf Manifold.
- Repo: <https://github.com/gkjohnson/three-bvh-csg>
- Forum: <https://discourse.threejs.org/t/three-bvh-csg-a-library-for-performing-fast-csg-operations/42713>
- **Trade-offs:** Gut fuer Live-Vorschau/visuelles Schneiden, ungeeignet als verlaesslicher Modellierkernel.
### Empfehlung (Kernel)
**replicad (= opencascade.js) als primaerer B-Rep-Kernel im Web Worker; Manifold als schneller Mesh-Boolean-Pfad fuer Import-/Vorschaugeometrie.** Diese Zweiteilung deckt sowohl „exakte BIM-Geometrie + 2D-Ableitung" (OCCT) als auch „schnell + robust auf beliebigen Meshes" (Manifold) ab. three-bvh-csg nur, falls man interaktives Echtzeit-Schneiden visuell braucht.
---
## 2. 2D-Ableitung aus 3D: verdeckte Kanten (HLR) + Schnittgenerierung
Kernfrage des DOSSIER-Ports: aus 3D-Solids saubere 2D-Zeichnungen (sichtbare/verdeckte Kanten, Schnitte) erzeugen — im Browser.
### Optionen
**A) OCC HLRBRep via replicad `drawProjection` — empfohlen**
OCCT enthaelt zwei HLR-Algorithmen: `HLRBRep_Algo` (exakt, auf der echten B-Rep) und `HLRBRep_PolyAlgo` (auf polyederisierter Naeherung, schneller, aber polygonal). Quellen: <https://dev.opencascade.org/doc/refman/html/class_h_l_r_b_rep.html>, <https://dev.opencascade.org/doc/occt-7.7.0/refman/html/class_h_l_r_b_rep___poly_algo.html>
replicad macht genau das im Browser nutzbar: `drawProjection(shape, camera)` liefert ein Objekt mit **`{ visible, hidden }`** — getrennte sichtbare und verdeckte Kantenzuege, die man unterschiedlich stylen kann (z.B. verdeckt = gestrichelt). Konkretes Beispiel aus der Doku:
```js
const { drawProjection, ProjectionCamera } = replicad;
const camera = new ProjectionCamera(corner).lookAt(center);
const { visible, hidden } = drawProjection(shape, camera);
// visible/hidden sind Drawings -> .toSVG()
```
- Beispiel: <https://replicad.xyz/docs/examples/projections/>
- Verwandte API: `makeProjectedEdges`, `ProjectionCamera`, `Drawing.toSVG()` / `toSVGPaths()` (<https://replicad.xyz/docs/api/classes/Drawing/>)
- **Das ist der entscheidende Grund, replicad/OCCT zu nehmen:** exakte verdeckte-Kanten-Berechnung auf echtem B-Rep ist mit Mesh-Tools nicht serioes machbar.
- **Trade-offs:** HLR ist rechenintensiv (deshalb Worker + Caching pro Ansicht/Kamera); `HLRBRep_Algo` exakt aber langsam, `PolyAlgo` schneller aber genaehert.
**B) Schnitte (Sections) via OCCT**
Echte Schnitte ueber Schnitt mit einer Ebene/Halbraum (`BRepAlgoAPI_Section` bzw. Boolean mit Schnittkoerper) ergeben exakte Schnittkanten als B-Rep-Edges, die wiederum nach SVG/DXF gehen. In replicad ueber Booleans + Projektion abbildbar.
**C) Manifold `slice()` / `project()` — schnelle Mesh-Variante**
`Manifold.slice(z)` gibt den Querschnitt parallel zur X-Y-Ebene auf Hoehe `z` als `CrossSection` (2D-Polygone, intern Clipper2); `Manifold.project()` die projizierte Aussenkontur. Quellen: <https://manifoldcad.org/docs/jsapi/>, <https://manifoldcad.org/docs/html/classmanifold_1_1_cross_section.html>
- **Trade-offs:** liefert **keine** verdeckte/sichtbare-Kanten-Trennung und keine Innenkanten-Semantik wie HLR — nur die geometrische Schnitt-/Projektionskontur des Meshes. Gut fuer Plan-Schnittkonturen (siehe Abschnitt 3), ungenuegend fuer vollwertige Ansichts-Zeichnungen mit verdeckten Kanten.
### Empfehlung (2D-Ableitung)
**HLR und Ansichts-Zeichnungen ueber replicad `drawProjection` (OCC HLRBRep) im Worker, mit Caching pro Kamera/Ansicht. Echte Schnitte ueber OCCT-Section-Boolean. Manifold `slice()` als schneller Pfad nur fuer reine Schnittkonturen (z.B. Plan-Cut auf Mesh-Importen).**
---
## 3. Plan-Ansicht: Clipping bei `cutHeight`
Verhalten: horizontaler Schnitt auf einstellbarer Hoehe (Grundriss), darüber Abschneiden, Schnittflaechen markieren.
### Optionen
**A) Three.js Clipping Planes (`clippingPlanes` / `localClippingEnabled`)**
Three.js bietet globale (`renderer.clippingPlanes`) und material-lokale (`material.clippingPlanes`) Schnittebenen; `renderer.localClippingEnabled` ist standardmaessig aus (Null-Kosten, bis aktiviert). Quellen: <https://threejs.org/docs/#api/en/materials/Material.clippingPlanes>, <https://threejs.org/examples/webgl_clipping.html>
- **Pro:** GPU-seitig, dynamisch (Slider auf `cutHeight` = `plane.constant` aendern, kein Geometrie-Rebuild), sehr fluessig.
- **Contra:** Clipping schneidet nur visuell — es entstehen **offene** Querschnitte (keine Deckflaeche). Fuer „Schnittflaeche fuellen/markieren" braucht man entweder einen Stencil-Cap-Trick oder eine echte Schnittkontur (Abschnitt 2). `clipIntersection = true` kann Material-Reinitialisierung pro Frame und FPS-Einbrueche verursachen — moeglichst vermeiden. Quelle: <https://github.com/mrdoob/three.js/issues/18675>
**B) Object Culling / Sichtbarkeit nach Hoehe**
Elemente oberhalb `cutHeight` per Bounding-Box/Etagen-Metadaten ausblenden (`object.visible = false`).
- **Pro:** trivial, keine Shader-Kosten, nutzt BIM-Etagensemantik.
- **Contra:** grobkoernig (ganze Objekte, kein praeziser Schnitt mitten durch ein Bauteil).
**C) Echte Schnittgeometrie pro Etage (OCCT/Manifold) fuer den 2D-Plan**
Fuer die exportierbare 2D-Grundriss-Zeichnung den echten Schnitt auf `cutHeight` rechnen (OCCT-Section bzw. `Manifold.slice(z)`), Schnittflaechen schraffieren (Abschnitt 6).
### Empfehlung (Plan-Clipping)
**Hybrid:** Im 3D-Viewport **Three.js Clipping Planes** fuer das interaktive Abschneiden (Slider direkt auf `plane.constant`), kombiniert mit **Object-Culling** ueber Etagen-Metadaten fuer Grob-Performance. Schnittflaechen-Caps via Stencil-Technik. Fuer die **exportierbare** 2D-Grundriss-Zeichnung die **echte** Schnittkontur ueber OCCT/Manifold berechnen statt nur GPU-Clipping. `clipIntersection` meiden.
---
## 4. Import: DWG/DXF, IFC, STL, OBJ, XYZ-Punktwolken
### DXF / DWG
- **DXF lesen:** `dxf-parser` (gdsestimating) — robust, weit verbreitet, parst DXF-Strings zu JS-Objekten. Repo: <https://github.com/gdsestimating/dxf-parser>. Zum reinen 2D-Anzeigen: `dxf-viewer` (vagran). <https://github.com/vagran/dxf-viewer>
- **DWG lesen (binaer!):** `@mlightcad/libredwg-web` — LibreDWG nach WASM, parst **DWG** (und DXF) direkt im Browser/Node ohne Backend. Aktuell v3.x. Repo: <https://github.com/mlightcad/libredwg-web>, npm: <https://www.npmjs.com/package/@mlightcad/libredwg-web>
- **Achtung Qualitaet/Limits:** DWG-Parsing ist speicherintensiv (kann >2 GB RAM ziehen); libredwg-web erzwingt WASM-Heap-Limits, sehr grosse DWGs koennen scheitern. Im Default-Build sind DXF-Parsing und DWG-Schreiben deaktiviert, um die WASM-Groesse zu senken — DXF also lieber mit `dxf-parser` lesen. Quelle: <https://medium.com/@mlightcad/parsing-autocad-dwg-files-in-the-browser-without-relying-on-the-backend-9067c5d9abf0>
- **Lizenz:** LibreDWG ist **GPL-3.0** — das ist fuer ein proprietaeres Produkt heikel. Wenn das Produkt nicht GPL sein soll, DWG-Import entweder ueber einen separaten Out-of-Process-Konverter kapseln oder Nutzer bitten, vorab nach DXF zu exportieren. **DWG-Lizenzfrage vor Integration klaeren.**
- **Referenz-Implementierung:** `cad-viewer` (mlightcad) zeigt vollstaendigen browser-only DXF/DWG-Viewer/Editor. <https://github.com/mlightcad/cad-viewer>
### IFC (BIM-Kern)
- **web-ifc (ThatOpen/engine_web-ifc):** IFC lesen/schreiben in JS „at native speeds" via WASM. De-facto-Standard fuer Open-BIM im Browser. Repo: <https://github.com/ThatOpen/engine_web-ifc>, Doku: <https://thatopen.github.io/engine_web-ifc/docs/>. **Lizenz: MPL-2.0** (datei-basiertes Copyleft, fuer proprietaere Apps i.d.R. unkritisch). Quelle: <https://spdx.org/licenses/MPL-2.0.html>
- **ThatOpen Components + Fragments:** Hoehere Ebene — `components` (Tools für BIM-Apps), `fragments` (kompaktes Binaerformat auf Google FlatBuffers). Typisch: ~100 MB IFC -> ~10 MB Fragments, >10x schnelleres Laden; Konvertierung lauft worker-basiert. Doku: <https://docs.thatopen.com/Tutorials/Fragments/Fragments/IfcImporter/>, Repo: <https://github.com/ThatOpen/engine_fragment>. IfcImporter setzt web-ifc (>=0.0.72) voraus.
- **Empfehlung:** IFC einmal mit web-ifc parsen, in **Fragments** cachen, danach aus Fragments laden.
### STL / OBJ / XYZ-Punktwolken
- **Standard-Three.js-Loader** decken alles ab: `STLLoader` (ASCII+Binaer), `OBJLoader`, `XYZLoader` (XYZ/XYZRGB -> BufferGeometry), `PCDLoader`. Quellen: <https://threejs.org/docs/#examples/en/loaders/PCDLoader>, <https://deepwiki.com/mrdoob/three.js/4.2-model-format-loaders>. Three.js ist **MIT**.
- **Punktwolken-Performance:** Naive Darstellung skaliert nicht — ~17 Mio. Punkte ruckeln deutlich. Strategien: Downsampling, **LOD/Culling**, Hintergrund-/Streaming-Laden. Fuer sehr grosse Wolken Out-of-Core-Octree-Renderer (z.B. Potree-Ansatz) erwaegen statt eines einzelnen `Points`-Objekts. Quellen: <https://discourse.threejs.org/t/render-large-point-cloud-data-in-threejs/57331>, <https://discourse.threejs.org/t/performance-issues-rendering-large-ply-point-cloud-in-three-js-downsampling-and-background-loading/69135>
### Empfehlung (Import)
**IFC: web-ifc + Fragments (ThatOpen).** **DXF: dxf-parser.** **DWG: libredwg-web — aber GPL-Lizenz vorab klaeren / kapseln.** **STL/OBJ/XYZ/PCD: native Three.js-Loader, mit LOD/Downsampling fuer grosse Punktwolken (Potree-Pattern bei Bedarf).**
---
## 5. Vektor-Export: SVG -> PDF (Print) und DXF
### SVG -> PDF
- **svg2pdf.js (yWorks) + jsPDF — empfohlen.** Reine JS-Loesung, laeuft im Browser, erhaelt **echte Vektoren** (kein Rasterisieren via html2canvas!), was fuer druckfaehige Plaene entscheidend ist. Integriert sich ueber `doc.svg(element, ...)`. Kompatibel mit jsPDF v2/v3/v4. Repo: <https://github.com/yWorks/svg2pdf.js/>. Lizenz: svg2pdf.js **MIT**, jsPDF **MIT**.
- **Trade-off:** SVG-Feature-Abdeckung ist sehr gut, aber nicht 100% — exotische Filter/Pattern koennen abweichen; Schraffuren als explizite Linien (statt CSS-Filter) exportieren erhoeht Treffsicherheit.
- **Alternative/ergaenzend:** `pdf-lib` (MIT) fuer Seitenmontage, Mehrseitigkeit, Metadaten, Zusammenfuehren — kann mit jsPDF-Output kombiniert werden. (`html2canvas`+jsPDF bewusst **vermeiden**, da Raster statt Vektor.)
### DXF-Export
- **@tarikjabiri/dxf (dxfjs/writer) — empfohlen.** Moderner, in TypeScript geschriebener DXF-Generator fuer Node + Browser. Unterstuetzt u.a. **Blocks, Hatches, Insert, Image** — d.h. Schraffuren lassen sich als echte DXF-Hatches exportieren (wichtig fuer CAD-Weiterverarbeitung). npm: <https://www.npmjs.com/package/@tarikjabiri/dxf>, Doku: <https://dxf.vercel.app/>, Repo: <https://github.com/tarikjabiri/js-dxf>. Lizenz: MIT.
- Einfachere Alternative: `dxf-writer` (Vorlaeufer, weniger Features).
### Empfehlung (Export)
**SVG -> PDF: svg2pdf.js + jsPDF (Vektor, nicht Raster), optional pdf-lib fuer Seitenmontage. DXF-Export: @tarikjabiri/dxf mit echten Hatch-Entities.** Interner Zwischenschritt: 2D-Geometrie als SVG-Paths halten (replicad `Drawing.toSVGPaths()`), daraus sowohl PDF als auch DXF erzeugen.
---
## 6. Schraffuren / Muster in SVG/Canvas bei Massstab
### Optionen & Erkenntnisse
- **SVG `<pattern>` mit `patternUnits="userSpaceOnUse"`** ist der richtige Weg fuer massstaebliche Schraffuren: das Muster skaliert NICHT mit der Form (im Gegensatz zu `objectBoundingBox`), sondern bleibt im Weltkoordinaten-Raster — exakt, was man fuer „mm pro Linie im Plan" braucht. Dichte/Winkel ueber `patternTransform`. Quellen: <https://www.w3.org/TR/2015/WD-SVG2-20150915/pservers.html>, <https://www.codegenes.net/blog/simple-fill-pattern-in-svg-diagonal-hatching/>
- **Performance:** Pattern-Layer werden bei jedem Layout-/Zoom-Schritt neu gerechnet; `userSpaceOnUse` vermeidet teures Rescaling und ist hier zugleich der schnellere und der korrekte Weg. Quelle: <https://oreillymedia.github.io/Using_SVG/extras/ch19-performance.html>
- **SVG vs. Canvas:** Fuer technische Zeichnungen ist SVG qualitativ klar ueberlegen (Vektor, exporttauglich nach PDF/DXF). Canvas wird erst bei sehr vielen einfachen Elementen schneller. Quellen: <https://felt.com/blog/from-svg-to-canvas-part-1-making-felt-faster>, <https://www.yworks.com/blog/svg-canvas-webgl>
- **Skalierungs-Strategie:** Bei sehr dichten Schraffuren ueber grosse Flaechen kann die Linienzahl explodieren -> entweder als Pattern-Kachel rendern (eine Definition, vielfach referenziert, statt tausende Einzellinien) **oder** beim Export Schraffuren in echte Linien/Hatch-Entities aufloesen (DXF-Hatch, Abschnitt 5).
### Empfehlung (Schraffuren)
**SVG `<pattern>` mit `patternUnits="userSpaceOnUse"` als primaerer Renderpfad** (massstabskorrekt, exportierbar, performant durch Kachel-Referenzierung). Bei extrem grossen/dichten Flaechen Canvas-Overlay nur fuer die reine Bildschirm-Vorschau erwaegen; fuer Export immer SVG -> svg2pdf.js bzw. echte DXF-Hatches.
---
## 7. WebGPU vs. WebGL + Worker-Offloading der WASM-Geometrie
### Rendering: WebGPU vs. WebGL
- **Reifegrad:** Seit Three.js r171 (Sept. 2025) ist der **WebGPURenderer produktionsreif** mit `import * as THREE from 'three/webgpu'` und **automatischem WebGL2-Fallback** — kein eigener Fallback-Code noetig. Quelle: <https://www.utsubo.com/blog/webgpu-threejs-migration-guide>
- **Browser-Abdeckung:** Chrome/Edge 113 (Mai 2023), Safari 26.0 (Sept. 2025), Firefox 141 (Juli 2025). ~95% der Nutzer WebGPU-faehig, restliche ~5% bekommen WebGL2-Fallback. Quelle: <https://vr.org/articles/webgpu-baseline-2026-three-js-webxr-default>
- **Performance (nuanciert):** Bei draw-call-lastigen Szenen (viele Bauteile/Etagen) gewinnt WebGPU deutlich (bei ~10'000 Draw-Calls ~50 FPS WebGPU vs. ~30 FPS WebGL); bei wenigen grossen Meshes kann WebGL noch gleichauf oder schneller sein. Compute-Shader (Punktwolken, Culling) sind ein WebGPU-Alleinstellungsmerkmal. Quellen: <https://medium.com/@sudenurcevik/upgrading-performance-moving-from-webgl-to-webgpu-in-three-js-4356e84e4702>, <https://altersquare.io/three-js-vs-webgpu-2026-large-scale-construction-viewers/>
- **Vorsicht:** Es gibt weiterhin Szenarien, in denen WebGPU langsamer ist als WebGL — daher messen, nicht blind migrieren. Quelle: <https://github.com/mrdoob/three.js/issues/31055>
### Worker-Offloading der WASM-Geometrie
- **Pflicht, nicht optional:** OCCT/replicad-Berechnungen (Booleans, HLR, Section) gehoeren in einen **Web Worker**, sonst blockiert die UI. replicad ist genau dafuer gebaut (WASM im Worker, Mesh zurueck an den Main-Thread). Quelle: <https://replicad.xyz/docs/use-as-a-library/>
- **Muster:** Worker laedt das (grosse) WASM einmal; Kommunikation via Comlink o.ae.; Geometrie als Transferable (ArrayBuffer) zuruecksenden, um Kopierkosten zu sparen. Manifold (WASM) ebenso im Worker betreiben; Manifold ist intern stark parallelisiert.
### Empfehlung (Performance)
**Three.js `three/webgpu`-Renderer mit automatischem WebGL2-Fallback** (gratis Abwaertskompatibilitaet, Vorteil bei vielen Draw-Calls/Etagen). **Alle WASM-Geometrie (OCCT/replicad + Manifold) konsequent in Web Worker(n)**, Ergebnis als Transferables. WebGPU-Compute fuer Punktwolken-/Culling-Beschleunigung als spaeteres Optimierungs-Upside. Vor groesserer WebGPU-Optimierung mit der echten Szene benchmarken.
---
## Empfehlung (Zusammenfassung)
| Thema | Wahl | Warum |
|---|---|---|
| **Geometriekernel (Solids/Booleans)** | **replicad** (= opencascade.js/OCCT) im Worker; **Manifold** als Mesh-Boolean-Ergaenzung | Echter B-Rep-Kernel noetig fuer exakte BIM-Geometrie + 2D-Ableitung; Manifold (Apache-2.0) schnell+robust fuer Mesh-Importe/Vorschau |
| **2D-Ableitung (HLR/Schnitt)** | **replicad `drawProjection`** (OCC HLRBRep, liefert `{visible, hidden}`); OCCT-Section fuer Schnitte | Einziger seriöser Weg fuer verdeckte/sichtbare Kanten auf echtem B-Rep im Browser; Manifold `slice()` nur fuer reine Konturen |
| **Plan-Clipping (`cutHeight`)** | **Three.js Clipping Planes** + **Object-Culling** (Etagen); echte Schnittkontur (OCCT/Manifold `slice`) fuer Export | GPU-Clipping fluessig & dynamisch fuer Viewport; Culling fuer Grob-Performance; exakte Kontur nur fuer druckbaren Plan |
| **Import IFC** | **web-ifc + Fragments** (ThatOpen) | De-facto Open-BIM-Standard, native Speed, ~10x kleineres/schnelleres Fragments-Caching; MPL-2.0 |
| **Import DXF / DWG** | **dxf-parser** (DXF) / **libredwg-web** (DWG) | Bewaehrt & browser-only; **DWG = GPL-3.0 -> Lizenz vorab klaeren/kapseln**, RAM-Limits bei grossen Dateien |
| **Import STL/OBJ/XYZ/PCD** | **Native Three.js-Loader** + LOD/Downsampling | Out of the box (MIT); grosse Punktwolken brauchen Octree/Potree-Pattern |
| **SVG -> PDF (Print)** | **svg2pdf.js + jsPDF** (+ pdf-lib optional) | Echte Vektoren statt Raster -> druckfaehig; MIT-Lizenzen |
| **DXF-Export** | **@tarikjabiri/dxf** | TS, Browser-faehig, echte Hatch-/Block-Entities fuer CAD-Weiterverarbeitung; MIT |
| **Schraffuren/Muster** | **SVG `<pattern>` mit `userSpaceOnUse`** | Massstabskorrekt (skaliert nicht mit Form), exportierbar, performant via Kachel-Referenz |
| **Rendering** | **Three.js `three/webgpu`** mit WebGL2-Fallback | Produktionsreif seit r171, ~95% Abdeckung, Vorteil bei vielen Draw-Calls; gratis Fallback |
| **WASM-Offloading** | **Web Worker** fuer OCCT/replicad + Manifold, Transferables | UI bleibt reaktiv; replicad ist dafuer gebaut; spart Kopierkosten |
---
### Wichtigste Risiken / offene Punkte
1. **DWG-Lizenz (LibreDWG = GPL-3.0):** Vor Integration klaeren — sonst proprietaeres Produkt gefaehrdet. Option: separater Konvertierungs-Service oder DXF-Pflicht beim Import.
2. **OCCT-WASM-Groesse & Build-Pflege:** zweistellige MB; Custom-Build/Tree-Shaking und Lazy-Loading im Worker einplanen.
3. **HLR-Kosten:** `drawProjection` pro Ansicht cachen; ggf. `PolyAlgo` fuer schnelle Vorschau, `HLRBRep_Algo` fuer den finalen Plan.
4. **WebGPU nicht blind:** mit echter Szene benchmarken — es gibt Faelle, in denen WebGL noch fuehrt.
+590
View File
@@ -0,0 +1,590 @@
# UX/UI-Patterns moderner Browser-CAD/BIM-Tools — Research & Leitplanken
> Recherche für unser Browser-BIM (React + TS + Three.js, DOSSIER-Port, Wohnbau,
> CH/SIA-Kontext). Ziel: konkrete, **übernehmbare** Interaktions- und UI-Muster.
> Stand: 2026-06-29.
>
> Untersucht: **Arcol**, **Snaptrude**, **TestFit**, **Onshape** (Browser-CAD),
> **Vectorworks** (Resource/Navigation-Modell), **Figma** (Canvas-Interaktion,
> Inspector). Querschnitt: Snapping/Inferencing, Grip-Editing, perceived
> performance, Command-Palette, Onboarding.
>
> Jeder externe Claim ist mit Quelle verlinkt. Am Ende:
> **„Leitplanken für unsere UI"** — priorisierte Empfehlungen.
---
## 0. Kurzfazit (TL;DR)
Die ganze Klasse moderner Browser-CAD/BIM-Tools konvergiert auf ein **gemeinsames
Set von Mustern**, das wir fast 1:1 übernehmen sollten:
1. **Ein Modell, viele synchrone Sichten** (2D-Plan ⇄ 3D ⇄ Daten/Sheets), Änderung
in einer Sicht propagiert sofort in alle anderen. (Arcol, Snaptrude)
2. **Kontextuelle UI** statt voller Werkzeugleisten: Buttons/Felder erscheinen nur,
wenn die aktuelle Auswahl sie erlaubt. (Arcol, Onshape, Figma)
3. **Drei-Zonen-Layout**: links Navigator/Layer-Baum, Mitte Canvas + schwebende
Tool-Palette, rechts Inspector. (Figma, Vectorworks, Onshape)
4. **Aggressives Snapping/Inferencing** mit Live-Glyphen + Modifier zum
Unterdrücken. (Onshape) — für Maus-im-Browser unverzichtbar.
5. **Direkte Manipulation per Grips** statt Dialogen. (Figma, DOSSIER-Backlog)
6. **Perceived performance** über Skeletons, optimistic UI und gescopte
Ladezustände — im Browser-3D-Kontext ein Differenzierungs-Hebel.
7. **Command-Palette (Ctrl/Cmd-K)** als Discovery- und Speed-Layer.
8. **Onboarding via „learn by doing"** an einem mitgelieferten Sample-Projekt +
progressive disclosure.
Unsere bestehende Architektur (semantisches Modell als Single Source of Truth,
abgeleitete Sichten, Vectorworks-Terminologie) ist exakt der richtige Unterbau für
diese Muster — die meiste Arbeit liegt in der **UI-Schicht**, nicht im Datenmodell.
---
## 1. Gesamtlayout & Navigator-/Layer-Panels
### 1.1 Was die Tools machen
**Figma** strukturiert die Fläche in vier Zonen: eine Toolbar, **zwei Panels** und
einen scrollbaren Canvas. Links das **Navigation-Panel** mit Layern und Pages,
rechts das **Properties-Panel**; der Layer-Baum „enthält und organisiert alle
Elemente auf dem Canvas … und zeigt, wie Elemente verbunden sind"
([Figma: left sidebar](https://help.figma.com/hc/en-us/articles/360039831974-View-layers-and-pages-in-the-left-sidebar),
[Figma: Interface](https://www.inthepocket.design/course/figma-for-everyone/the-interface)).
**Vectorworks** trennt sauber zwei Konzepte, die für uns 1:1 relevant sind:
- Die **Navigation Palette** gibt Zugriff auf *Classes, Design Layers, Sheet
Layers, Viewports, Saved Views, References* — jeweils als eigener Tab mit Liste.
Sichtbarkeit wird per Klick in einer **Visibility-Spalte** gesetzt; Doppelklick
**aktiviert** einen Layer/eine Class. Die Zeichenfläche bleibt nutzbar, während
die Palette offen ist
([VW Navigation Palette](https://app-help.vectorworks.net/2022/eng/VW2022_Guide/Structure/The_Navigation_palette.htm)).
- Paletten sind **andockbar/ein-/ausblendbar pro Workspace**
([VW Palettes & Tool Sets](https://app-help.vectorworks.net/2018/eng/VW2018_Guide/Start/Palettes_and_Tool_Sets.htm)).
**Arcol** baut beim Modellieren einen **Model Tree** im Menü auf — pro
BIM-Komponente wächst der Baum mit
([AEC Magazine: Arcol BIM in browser](https://aecmag.com/bim/arcol-bim-cloud-browser/)).
**Onshape** zeigt links den **Feature-/Assembly-Baum** (parametrische Historie:
Sketches, Features, Mates) — die Bauhistorie ist die primäre Navigation
([Onshape UI Basics](https://cad.onshape.com/help/Content/ui-basics.htm)).
### 1.2 Übernahme für uns
Unser Dokumentmodell hat **zwei unabhängige Achsen** (siehe ROADMAP §2c):
**Zeichnungsebenen** (Geschosse + Schnitte/Ansichten) und **Ebenen**
(Grafik-Kategorien-Baum `00 Raster … 80 Plangrafik`). Das mappt fast wörtlich auf
das Vectorworks-Navigations-Modell:
- **Linke Sidebar, getabbt** wie die VW-Navigation-Palette:
- Tab **„Geschosse / Ansichten"** (= unsere Zeichnungsebenen): EG/1OG/…,
Schnitte, Ansichten. Mit **Visibility-Toggle**, **Lock**, und **Doppelklick =
aktiv setzen** (welches Geschoss editiert wird).
- Tab **„Ebenen"** (= Grafik-Kategorien-Baum, in *jedem* Geschoss gleich): Baum
mit Code, Name, Farb-Swatch, Linienstärke, Visibility, Hatch. Pro Ansicht
schaltbar (das ist genau VWs „Sichtbarkeit pro Viewport/Saved View").
- Tab **„BIM-Tree / Elemente"** (aus DOSSIER-Backlog §11: *Element-Übersicht
Geschoss→Kind→Element, Suche, Shift-Klick = Zoom*). Das ist unser Pendant zu
Arcols Model Tree + Onshapes Feature-Baum.
- **Visibility-Spalte als Erstklass-Interaktion** (VW-Muster): Auge-Icon je Zeile,
Klick togglet sofort, kein Dialog. (Wir haben bereits `EyeIcon.tsx` — das ist die
Keimzelle.)
- **Wichtig:** Geschoss wird **im 3D *oder* Plan** betrachtet, *keine* getrennten
Daten — der View-Umschalter (siehe §2) gehört in die Geschoss-Auswahl, nicht in
separate Dokumente.
> **Anti-Pattern vermeiden:** Vectorworks selbst leidet unter
> **Paletten-Wildwuchs** (viele frei schwebende Fenster). Für ein fokussiertes
> Wohnbau-Tool: **feste 3-Zonen-Shell** (links Navigator, rechts Inspector), nicht
> N frei schwebende Palettenfenster. Figmas Striktheit schlägt VWs Flexibilität für
> unsere Zielgruppe (Architekt:innen, die schnell ein EFH zeichnen wollen).
---
## 2. 3D ⇄ Plan-View-Umschaltung (das Herzstück)
### 2.1 Was die Tools machen
- **Snaptrude:** Nutzer arbeiten **in 2D *und* 3D gleichzeitig**; Änderung in einer
Sicht spiegelt sich automatisch in der anderen. Objekte sind **nach Geschossen
klassifiziert**, was es erlaubt, „3D-Geometrie zu zeichnen, während man in einer
2D-Grundriss-Ansicht arbeitet". Push-an-einer-Fläche „fühlt sich an wie eine
Linie ziehen", berechnet aber sofort Flächen/BIM-Daten neu
([ArchDaily: Snaptrude](https://www.archdaily.com/1009121/snaptrude-the-browser-based-bim-tool-thats-changing-the-way-architects-work),
[Snaptrude](https://www.snaptrude.com/)).
- **Arcol:** „Every view is 3D in Arcol" — und **Boards** (Präsentations-Layouts)
sind **live-synced**: ändert sich das Gebäude, aktualisieren sich die Layouts
automatisch (kein statischer PDF-Export)
([AEC Magazine: Arcol BIM 2.0](https://aecmag.com/bim/arcol-unleashed-bim-2-0/)).
- **TestFit:** explizites **Expand/Collapse von Optionen** — man klappt Varianten
auf zum Vergleichen und wieder zu, um sich aufs Detail-Editieren im Canvas zu
konzentrieren („smoother flow between setting up a site, reviewing options, and
refining a design")
([TestFit 5.19](https://www.testfit.io/blog/testfit-5-19-a-new-generative-design-workflow)).
### 2.2 Übernahme für uns
Das ist **genau unsere Kern-Architektur** (ROADMAP §2c: „Ansichtstyp = Kamera-
Projektion + optionaler Schnitt"). Konkrete UI-Muster:
- **View-Switcher als segmented control** direkt am Canvas (oben links oder
oben mittig): `3D | Grundriss | Schnitt | Ansicht`. Plan-View = orthogonale
Top-Kamera + Clipping-Ebene auf `okff + schnitthöhe` (steht bereits so im Modell).
- **Kein** Moduswechsel der *Daten*, nur der **Kamera + Schnitt** — visuell als
weicher Übergang (Kamera-Animation) kommunizieren, damit Nutzer Orientierung
behalten (Snaptrude/Arcol-Gefühl: „dieselbe Sache aus anderem Winkel").
- **Optional, stark differenzierend:** **Split-View** (3D links, Plan rechts) wie
Snaptrudes „2D + 3D simultan". Da unsere Sichten ohnehin reaktiv aus *einem*
Modell abgeleitet werden (Zustand-Store → SVG-Plan + Three-Scene), ist Split-View
technisch billig und ein Wow-Moment im Onboarding.
- **Kamera-Presets** (aus DOSSIER-Backlog): Kardinal N/O/S/W, Iso-Oktanten,
**Norden-Rotation** (CH/Swisstopo-Georeferenz) — als kleine Würfel-/Kompass-Gizmo
oben rechts im 3D (ViewCube-Muster, bekannt aus Onshape/CAD allgemein
([Onshape UI Basics](https://cad.onshape.com/help/Content/ui-basics.htm))).
- **Drawing Layers (Schnitte/Ansichten) sind „Saved Views"**: Auswahl in der linken
Sidebar = Kamera + Schnitt + Maßstab + Layer-Kombination springt an (VW „Saved
Views" / DOSSIER „Ausschnitte"). Das ersetzt Ordner-Wildwuchs bei 50+ Ansichten.
---
## 3. Zeichnen & Editieren: Snapping, Inferencing, Grips, Tool-Paletten
### 3.1 Snapping / Inferencing — das wichtigste Detail im Browser
**Onshape** ist hier die Referenz (sehr konkret dokumentiert,
[Onshape Automatic Inferencing](https://cad.onshape.com/help/Content/Sketch/automatic_inferencing.htm)):
- **Inference-Typen:** horizontal, vertikal, **midpoint**, parallel, coincident,
Ausrichtung zum Origin/zu anderen Entities, Tangente, Perpendikular.
- **Visuelles Feedback:**
- **gelbe Highlights** auf Vertices/Mittelpunkten beim Hovern,
- **orange gestrichelte Linie** zeigt eine vorgeschlagene H/V-Ausrichtung,
- **orange Highlight** verwandter Geometrie beim Ziehen (relationales Feedback).
- **Steuerung:** Linksklick **akzeptiert** die vorgeschlagene Bedingung; **Shift
gedrückt halten unterdrückt** Inferencing temporär (loslassen = wieder an).
- **„Wake-up"-Inferences:** kurzes Verweilen über einer Geometrie „weckt" deren
Bezugslinien (z. B. erst Mittelpunkt antippen, dann woanders zeichnen → bekommt
Ausrichtung zu diesem Mittelpunkt).
- **Post-hoc:** vorhandene Geometrie ziehen triggert erneut Inferencing (Center
eines Kreises vertikal zum Origin ziehen → fügt automatisch vertikale Constraint).
**Constraint-Sichtbarkeit:** Constraint-Icons sind farbcodiert (blau =
externe/Referenz, weiß = intern) und ein-/ausblendbar
([Onshape Working with Constraints](https://cad.onshape.com/help/Content/Sketch/working_with_constraints.htm)).
### 3.2 Übernahme für uns (Snapping)
Für ein Maus-bedientes Browser-Tool ist **gutes Snapping der Unterschied zwischen
„Spielzeug" und „Werkzeug".** Konkret:
- **Snap-Targets** (Wohnbau-relevant): Wand-Endpunkte/Achsen, Wand-Mittelpunkte,
Rechtwinklig/Parallel zu bestehender Wand, **Raster** (Achsraster `00 Raster`),
Öffnungs-Achsen, vorhandene 2D-Linien-Endpunkte, Schnittpunkte.
- **Feedback exakt wie Onshape übernehmen:** Snap-Glyph am Cursor (●
Endpunkt, △ Mitte, ⟂ rechtwinklig), **gestrichelte Hilfslinie** für
Achsen-Alignment, Hover-Highlight des Snap-Ziels.
- **Modifier:** **Shift unterdrückt Snapping** (Onshape-Konvention) — Nutzer
erwarten das bereits aus anderen Tools. Zusätzlich **Ortho-Modus** (z. B. Shift
für 0/45/90° beim Linienziehen — Figma-Konvention) sauber davon trennen oder per
Toggle.
- **Live-Maßeingabe beim Zeichnen** (CAD-Standard, auch Onshape): während des
Ziehens Länge/Winkel tippbar (Tab zwischen Feldern). Das ersetzt nachträgliches
Dimensionieren und ist für Architekt:innen Pflicht.
- Wir brauchen **kein** volles Constraint-Solver-System wie Onshape (mechanisches
parametrisches CAD). BIM-Wände sind achs-basiert; **Inferencing beim Setzen**
genügt, persistente geometrische Constraints sind Overkill für Wohnbau.
### 3.3 Grip-Editing / direkte Manipulation
- **Figma:** Auswahl zeigt Bounding-Box mit **Resize-Handles**; ziehen
manipuliert direkt; Smart-Guides/Maße erscheinen relativ zu Nachbarn beim Bewegen
([Figma right sidebar](https://help.figma.com/hc/en-us/articles/360039832014-Design-prototype-and-explore-layer-properties-in-the-right-sidebar)).
- **Snaptrude:** Push/Pull an Flächen als primäre 3D-Edit-Geste
([ArchDaily](https://www.archdaily.com/1009121/snaptrude-the-browser-based-bim-tool-thats-changing-the-way-architects-work)).
- **DOSSIER-Backlog (§11)** listet **Grip-Editing** (Wand-Endpunkte,
Schnitt-Symbole im Plan) explizit als Aufwand L, Phase 34 — und das **9-Punkt-
Objekt-Info** (lesen + verschieben/skalieren/rotieren direkt).
**Übernahme:** Grips sind der wichtigste „pro feel"-Hebel.
- **Wand-Endpunkt-Grips** im Plan *und* 3D, mit Snapping (s. o.) und Live-Maß.
- **Öffnungs-Grips** (Position entlang Wand, Breite) — Host-Beziehung bleibt erhalten.
- **Schnittlinien-Grips im Plan** (Schnittlinie ziehen → Schnitt-Ansicht
re-deriviert) — das ist Grip-Editing über die Sicht-Grenze hinweg, ein starkes
Differenzierungsmerkmal.
- Selektion → **bounding handles** (Figma-Muster) für 2D-Plangrafik (Linien,
Rechtecke, Text).
### 3.4 Tool-Palette & kontextuelle Werkzeuge
**Kontextuelle UI ist das durchgehende Muster:**
- **Arcol:** „buttons appear only when they can be used" — Loft/Sweep erscheinen bei
Auswahl zweier Sketches, Boolean bei zwei Extrusions
([AEC: Arcol sneak peek](https://aecmag.com/bim/arcol-a-sneak-peek/)).
- **Onshape:** Sketch-Toolbar erscheint beim Betreten des Sketch-Modus; Tools in
Gruppen (vertikale Trennlinien), Dropdown-Pfeile für Varianten; Dialoge mit
**blau hinterlegtem Feld**, das eine Auswahl im Graphics-Bereich verlangt
([Onshape sketch toolbar](https://cad.onshape.com/help/Content/Sketch/sketch_basics.htm),
[Onshape Constraints](https://cad.onshape.com/help/Content/Sketch/working_with_constraints.htm)).
- **Figma:** schmale Bottom-/Top-Toolbar mit den Kern-Tools; alles Weitere
kontextuell rechts.
**Übernahme:**
- **Schlanke Tool-Palette** (Figma-artig), gruppiert nach unserer Domäne:
*Wand · Tür/Fenster · Decke · Treppe · Dach · Raum* (BIM) und *Linie · Polylinie
· Rechteck · Kreis · Bogen · Text · Bemaßung* (2D auf `80 Plangrafik`).
- **Modus-bewusste Tools:** im Grundriss andere Defaults als im 3D; im
Schnitt/Ansicht nur Annotation/2D-Tools.
- **Contextual action bar bei Auswahl** (Arcol-Muster): selektiere eine Wand →
schwebende Mini-Toolbar „Tür einsetzen / Fenster / Wandtyp / verschneiden".
Selektiere zwei Wände → „verschneiden / verlängern".
- **Aktives Tool sticky + ESC bricht ab**, Leertaste = Pan, Scroll = Zoom
(Figma/CAD-Konventionen — Nutzer bringen Muskelgedächtnis mit).
- **LoD-bewusste Tool-/Stil-UI** (DOSSIER-Backlog: *zeigt nur passende Controls je
Geometrie-Typ*) — keine Füll-Optionen bei 3D-Auswahl. Deckt sich mit Figmas
„controls appear based on layer type".
---
## 4. Property-/Inspector-Panel
### 4.1 Was die Tools machen
**Figma — rechte Sidebar** (für uns das Vorbild,
[Figma right sidebar](https://help.figma.com/hc/en-us/articles/360039832014-Design-prototype-and-explore-layer-properties-in-the-right-sidebar)):
- Tabs **Design / Prototype** (bei Edit), **Inspect / Properties** (bei View-only).
- Kategorien: **Alignment/Rotation/Position → Dimensions → Constraints/Layout →
Appearance (Fill, Stroke, Effects) → Export**.
- **Controls erscheinen je Layer-Typ** (kontextuell).
- **Dev-Mode/Inspect** liefert konkrete Werte + Abstände zwischen Objekten + Code.
**Arcol — rechtes Panel** zeigt **Gebäude-Metriken** kontextuell: Geschossfläche,
Anzahl Geschosse, GFZ/FAR, Unit-Count, Standortfläche, Kostenschätzung
([Arcol BIM 2.0](https://aecmag.com/bim/arcol-unleashed-bim-2-0/)).
**TestFit — ein zentrales Parameter-Panel:** „alle Schlüsselparameter an einem
Ort" (Unit-Counts, Parkplatz-Ziele, Gebäudegrößen-Limits) → sofortige Wirkung auf
generierte Optionen
([TestFit 5.19](https://www.testfit.io/blog/testfit-5-19-a-new-generative-design-workflow)).
**Onshape — Feature-Dialoge:** Erstellen/Editieren über Dialoge mit Pflicht-
Selektionsfeldern (blau)
([Onshape UI Basics](https://cad.onshape.com/help/Content/ui-basics.htm)).
### 4.2 Übernahme für uns
- **Rechter Inspector, kontextuell nach Element-Typ** (Figma-Muster):
- **Wand** → Wandtyp (→ WallType-Bibliothek), Referenzlage mid/left/right
(DOSSIER-Backlog), Höhe, Achs-Endpunkte (9-Punkt/Maße), Stil-Overrides.
- **Tür/Fenster** → Breite/Höhe, Brüstung, Schwenkbogen/Anschlag, Detailgrad,
Symbol.
- **Decke/Slab** → SlabType, UK/OK-Override, Aussparungen.
- **Raum** → SIA-416-Kategorie (HNF/NNF/VF/FF/GF/AGF), Fläche (read-only,
berechnet), Stempel-Felder.
- **2D-Element** → Linienstil (→ Line Manager), Hatch (→ Hatch Manager), Farbe.
- **Sektionen kollabierbar** (Figma) — Wohnbau-Inspector kann lang werden;
Default-Sektionen offen, Fortgeschrittenes (Overrides) zugeklappt
(= progressive disclosure, s. §7).
- **Mixed-value-Handling bei Mehrfachauswahl** (Figma): bei Mehrfachauswahl
abweichende Werte als „Mixed/—" zeigen, gemeinsames Editieren erlauben. Wichtig
z. B. „alle EG-Wände auf Wandtyp X".
- **Live-Metriken-Block** (Arcol-Muster) — selbst im Wohnbau wertvoll:
Bruttogeschossfläche, **SIA-416-Bilanz**, Raumzahl, Volumen. Im Inspector wenn
nichts selektiert ist = „Projekt-Übersicht" (vgl. Figmas Canvas-Level-Optionen
bei leerer Auswahl).
- **Read-only-Felder klar markieren** (berechnete Flächen/Volumen) vs. editierbar.
---
## 5. Resource-Manager (Bibliotheken)
### 5.1 Was Vectorworks macht — unser direktes Vorbild
Der **Resource Manager** ist „ein zentraler Ort für Assets" (Symbole, Linientypen,
Texturen, Materialien …)
([VW Resource Manager](https://app-help.vectorworks.net/2026/eng/VW2026_Guide/ResourceManager/Resource%20Manager.htm)):
- **Zwei-/Drei-Pane-Modell:** **File-Browser** (offene Dateien, Favoriten,
VW-Libraries, User-/Workgroup-Libraries) → **Resource-Viewer** (Ressourcen der
gewählten Datei) → optional **Preview/Metadaten**
([VW File browser pane](https://app-help.vectorworks.net/2023/eng/VW2023_Guide/ResourceManager/Resource_Manager_File_browser_pane.htm),
[VW Resource viewer pane](https://app-help.vectorworks.net/2026/eng/VW2026_Guide/ResourceManager/Resource_Manager_Resource_viewer_pane.htm)).
- **Organisation mehrdimensional:** nach Quelle, **nach Typ** (Dropdown-Filter),
nach Ordnerstruktur.
- **Ansichten:** Thumbnails / List / Thumbnails-List; **Suchfeld** mit Filtern.
- **Resource Selector**: dieselbe Bibliothek erscheint **in Dialogen** und zeigt
dort nur **kontextuell passende** Ressourcen.
### 5.2 Übernahme für uns
Unsere ROADMAP §2d definiert bereits **Line Manager / Hatch Manager / Component
Manager**, mit Verweis-per-id-Architektur (Components → Hatches → LineStyles). Das
Vectorworks-Modell passt perfekt:
- **Ein gemeinsames Resource-Browser-Pattern** für alle Bibliotheken (Linienstile,
Schraffuren, Components/Baustoffe, später Wand-/Öffnungs-Stil-Kataloge,
Material-PBR, Raumstempel-Layouts). Eine wiederverwendbare React-Komponente,
parametrisiert nach Ressourcentyp.
- **Zwei Erscheinungsformen** (wie VW):
1. **Manager-Ansicht** (großes Panel/Modal) zum Anlegen/Editieren/Duplizieren.
2. **Inline-Resource-Selector** im Inspector — beim Setzen eines Wandtyps/Hatch
öffnet sich ein kompakter Picker mit Thumbnails, gefiltert auf den passenden
Typ. (Figma macht das analog mit „Styles/Variables".)
- **Thumbnails sind im CAD-Kontext kritisch**: Hatch-Vorschau, Component-
Schichtaufbau, Linienstil-Strich als gerenderte Mini-Previews.
- **Zentrale Änderung propagiert** (unsere id-Referenz-Architektur): Component-Farbe
ändern → alle Wände mit diesem Component aktualisieren live. Das ist Arcols
„single source of truth" auf Ressourcen-Ebene.
- **Cross-Projekt-Presets/Favoriten** (DOSSIER-Backlog, LocalStorage; VW-Favoriten):
„einmal speichern, überall nutzen".
---
## 6. Perceived Performance (gefühlte Geschwindigkeit)
Browser-3D + WASM-Geometrie (web-ifc, OpenCascade) + HLR-Projektion = **echte
Latenz** an mehreren Stellen. Gefühlte Performance ist hier ein
Differenzierungs-Hebel gegenüber schwerfälligem Revit/ArchiCAD.
### 6.1 Belegte Muster
- **Skeleton-Screens** lassen Apps **2030 % schneller** wirken als Spinner bei
identischer realer Ladezeit
([LogRocket: skeleton screens](https://blog.logrocket.com/ux-design/skeleton-loading-screen-design/),
[UI Deploy](https://ui-deploy.com/blog/skeleton-screens-vs-spinners-optimizing-perceived-performance)).
- **Indikator zur Situation passen:** Spinner für kurze Waits, Skeleton für
Content, Progress-Bar für messbare Operationen, **optimistic UI** für
„instant-feeling" Aktionen
([Onething: skeleton vs spinner](https://www.onething.design/post/skeleton-screens-vs-loading-spinners)).
- **Optimistic UI**: UI sofort aktualisieren, Server-Bestätigung abwarten, nur bei
Fehler zurückrollen — ideal für häufige, risikoarme Aktionen
([Smart Interface Design Patterns](https://smart-interface-design-patterns.com/articles/designing-better-loading-progress-ux/)).
- **Verzögerung vor Indikator (100200 ms):** schließt die Operation vorher ab,
gar kein Indikator → kein Flackern
([Onething](https://www.onething.design/post/skeleton-screens-vs-loading-spinners)).
- **Gescopte Ladezustände** (React Suspense / Next loading.tsx): nur der betroffene
Bereich lädt, der Rest bleibt interaktiv; `aria-busy`, Live-Regions,
reduced-motion respektieren
([LogRocket](https://blog.logrocket.com/ux-design/skeleton-loading-screen-design/)).
### 6.2 Übernahme für uns (konkret)
- **Optimistic Model-Edits:** Geometrie-Mutation (Wand ziehen, Tür setzen) **sofort**
im Zustand-Store + 3D anzeigen; **schwere Booleans/HLR im Web Worker** (Comlink,
bereits geplant) nachziehen. Wand erscheint sofort, die *exakte* verschnittene
Öffnung/Schnittlinie „schärft nach". UI bleibt flüssig.
- **Progressive Plan-Generierung:** SVG-Grundriss zuerst grob (Achsen/Linien),
Schraffuren/Symbole nachladen — Skeleton/„low-detail first" statt Spinner.
- **HLR-Schnitte (Risiko #4):** Worker + Caching (ROADMAP §6). UI: **Skeleton der
Schnitt-Ansicht** + „berechne verdeckte Kanten…" mit Progress, restliche App
bleibt nutzbar (gescopter Ladezustand).
- **Delay-then-show** für alle Worker-Tasks (150 ms-Schwelle), sonst Flicker beim
schnellen Editieren.
- **Three.js-Disziplin:** stabile 60 fps beim Orbit/Pan ist selbst „perceived
performance" — instanziertes Rendering, Frustum-Culling, LoD für ferne Geometrie
(deckt sich mit ROADMAP-Phase-7-Performance-Härtung). Lieber 60 fps bei grober
Geometrie als ruckelnde Präzision.
- **Auto-Save-Status klar, unaufdringlich** kommunizieren („Gespeichert"/„Speichern…"),
optimistic — nie blockierend (Figma-Muster).
---
## 7. Onboarding & Discoverability
### 7.1 Belegte Muster
- **Progressive Disclosure:** zuerst nur Essenzielles zeigen, Komplexität schrittweise
enthüllen — reduziert kognitive Last; drei Typen: step-by-step, conditional,
contextual
([IxDF: Progressive Disclosure](https://ixdf.org/literature/topics/progressive-disclosure),
[UXPin](https://www.uxpin.com/studio/blog/what-is-progressive-disclosure/)).
- **„Learn by doing" an Sample-Dokument:** Grammarly startet Nutzer mit einem
Beispiel-Dokument mit Fehlern; Hotspots/Tooltips führen durch Features
([Userpilot: onboarding examples](https://userpilot.com/blog/user-onboarding-examples/)).
- **Stufenweises Aufdecken fortgeschrittener Features** (Asana: erst Projekt
anlegen, später Dependencies/Kanban/Gantt)
([Userpilot: progressive disclosure](https://userpilot.com/blog/progressive-disclosure-examples/)).
- **Command-Palette als Discovery-Layer:** durchsuchbare Befehlsliste hilft, Features
zu entdecken — „incredible effect on exploration and feature discoverability",
besonders für neue/seltene Nutzer
([Mobbin: command palette](https://mobbin.com/glossary/command-palette),
[Untitled UI: command menus](https://www.untitledui.com/components/command-menus)).
- **Arcol** wirbt explizit mit „low barrier to entry, gentle learning curve … clean,
intuitive, requires minimal training"
([AEC: Arcol BIM 2.0](https://aecmag.com/bim/arcol-unleashed-bim-2-0/)).
### 7.2 Übernahme für uns
- **Mitgeliefertes Sample-Projekt** (wir haben bereits `sampleProject.ts`!) als
Onboarding-Bühne: ein kleines EFH, fertig modelliert. Nutzer **manipuliert echtes
Modell** statt leerem Canvas (Grammarly-Muster). Erste Geste: „zieh diese Wand"
→ sieht 3D + Plan live mitlaufen (unser Kern-Wow).
- **Progressive Disclosure im Inspector & Tool-Palette:** Default zeigt
Wohnbau-Essenz (Wand/Tür/Fenster/Decke/Raum). Fortgeschrittenes (Prioritäts-
Verschneidung, Overrides, Detailgrade, Section-Styles) **zugeklappt / hinter
„Erweitert"**. Das passt zu unserem radikalen Wohnbau-Fokus.
- **Contextual coachmarks** statt langem Tutorial: beim ersten Selektieren einer
Wand ein kleiner Tooltip „Endpunkt ziehen zum Verlängern, Doppelklick für Wandtyp".
- **Command-Palette (Ctrl/Cmd-K)** — siehe §8 — doppelt als Onboarding: alle
Werkzeuge/Befehle durchsuchbar = lebende Feature-Liste.
- **Tastatur-Kürzel sichtbar machen** (in Tooltips, in der Palette) — schult
beiläufig pro Workflows.
---
## 8. Command-Palette & Tastatur
### 8.1 Belegte Muster
- **Ctrl/Cmd-K** ist die De-facto-Konvention (Linear, Figma [Cmd-P], Notion,
Vercel, Raycast, Slack, Superhuman); VS Code nutzt Cmd-Shift-P
([Mobbin](https://mobbin.com/glossary/command-palette),
[Superhuman: command palette](https://blog.superhuman.com/how-to-build-a-remarkable-command-palette/)).
- Zwei Haupt-Use-Cases: **Navigation/Suche** und **Shortcuts/Quick Actions**
([Outdraw Academy: command palette](https://outdraw-academy.gitbook.io/ux-patterns/command-palette)).
- Trigger kann **sichtbar** (Button/Suchleiste) oder nur per Shortcut sein —
für Discovery besser **auch sichtbar**
([Mobbin](https://mobbin.com/glossary/command-palette)).
### 8.2 Übernahme für uns
- **Cmd/Ctrl-K-Palette** für: Werkzeug aktivieren („Wand", „Tür"), Ansicht
springen („Grundriss EG", „Schnitt A-A"), Ressource öffnen („Hatch Manager"),
globale Aktionen („Norden rotieren", „PDF exportieren", „SIA-Bilanz").
- **Sichtbarer Trigger** (Such-/Befehlsfeld in der Top-Bar) für Entdeckung +
Shortcut für Speed.
- **Konsistente, dokumentierte Shortcuts** (Figma-Disziplin): W=Wand, T=Tür,
L=Linie, Space=Pan, Scroll=Zoom, Shift=Snap aus, Esc=Abbrechen, G=Grundriss-Toggle.
In Tooltips + Palette anzeigen.
---
## 9. Leitplanken für unsere UI (priorisierte Empfehlungen)
> Sortiert nach **Hebel × Aufwand**. „P#" = grobe Phasen-Zuordnung zur ROADMAP.
### A. Sofort / Fundament (Phase 01) — billig, prägt alles
1. **Feste 3-Zonen-Shell.** Links **Navigator** (Tabs: *Geschosse/Ansichten · Ebenen
· BIM-Tree*, je mit Visibility-Toggle wie VW Navigation Palette). Mitte **Canvas**
mit schwebender Tool-Palette + View-Switcher. Rechts **Inspector** (kontextuell).
*Keine* frei schwebenden Palettenfenster (Anti-VW-Wildwuchs).
2. **View-Switcher als segmented control** `3D | Grundriss | Schnitt | Ansicht`
direkt am Canvas; weiche Kamera-Übergänge; *eine* Datenquelle (kein Daten-
Moduswechsel). Nutzt unsere bestehende „abgeleitete Sichten"-Architektur.
3. **Visibility/Lock pro Zeile** als Erstklass-Interaktion (1 Klick, kein Dialog) —
`EyeIcon.tsx` ausbauen.
4. **Kontextueller Inspector**: Controls nur für den selektierten Element-Typ
(Figma/Arcol); berechnete Felder read-only markiert; Sektionen kollabierbar.
5. **Tastatur-Grundlagen + Konventionen festnageln**: Space=Pan, Scroll=Zoom,
Esc=Abbrechen, Shift=Snap aus. Früh festlegen → Muskelgedächtnis.
### B. Kern-„Pro-Feel" (Phase 12) — der eigentliche Wert
6. **Snapping/Inferencing nach Onshape-Vorbild**: Snap-Glyphen am Cursor,
gestrichelte Achsen-Hilfslinien, Hover-Highlight, **Shift = unterdrücken**,
Wake-up-Inferences. Targets: Wand-Enden/Achsen/Mitten, Raster, Rechtwinklig/
Parallel, Öffnungs-Achsen. **Höchste Priorität für „Werkzeug-Gefühl".**
7. **Live-Maßeingabe beim Zeichnen** (Länge/Winkel tippbar, Tab zwischen Feldern).
8. **Kontextuelle Action-Bar bei Auswahl** (Arcol): Wand selektiert → „Tür/Fenster
einsetzen / Wandtyp / verschneiden". Buttons erscheinen nur, wenn anwendbar.
9. **Schlanke domänen-gruppierte Tool-Palette** (BIM-Bauteile + 2D-Zeichnen),
modus-bewusst je Ansicht.
10. **Optimistic Edits + Worker-Nachzug**: Mutation sofort sichtbar, schwere
Booleans/HLR im Worker (Comlink); Delay-then-show (150 ms) statt Spinner-Flicker.
### C. Differenzierung (Phase 3) — hier gewinnen wir
11. **Grip-Editing** (Wand-Endpunkte, Öffnungs-Position/-Breite, **Schnittlinie im
Plan**) mit Snapping + Live-Maß, in 2D *und* 3D. (DOSSIER-Backlog, Aufwand L —
aber Kern-Differenzierer.)
12. **Saved Views / Ausschnitte** in der linken Sidebar = Kamera + Schnitt + Maßstab
+ Layer-Kombination per Klick (VW „Saved Views" / DOSSIER). Skaliert auf 50+
Ansichten.
13. **Wiederverwendbares Resource-Browser-Pattern** für Line/Hatch/Component-Manager:
Zwei-Pane (File-Browser → Viewer mit Thumbnails) als Manager *und* als inline
Picker im Inspector (VW-Modell). Zentrale Änderung propagiert (id-Referenzen).
14. **Perceived-performance-Politik festschreiben**: Skeletons für Plan-/Schnitt-
Generierung, gescopte Ladezustände (restliche App bleibt nutzbar),
reduced-motion/`aria-busy` respektieren.
15. **Split-View 3D|Plan** (Snaptrude-Muster) — billig dank reaktiver Sichten,
starker Wow-Effekt; auch fürs Onboarding.
### D. Adoption & Politur (Phase 1 fortlaufend → 7)
16. **Onboarding via Sample-Projekt** (`sampleProject.ts` als fertiges EFH);
„learn by doing", erste Geste zeigt 3D⇄Plan-Live-Sync. Progressive Disclosure:
Wohnbau-Essenz default, Fortgeschrittenes (Prioritäts-Verschneidung, Overrides,
Detailgrade) zugeklappt.
17. **Command-Palette (Cmd/Ctrl-K)** + sichtbarer Trigger: Werkzeuge/Ansichten/
Ressourcen/Aktionen durchsuchbar; doppelt als Discovery-Layer.
18. **Live-Metriken-Block** im Inspector (Arcol): BGF, **SIA-416-Bilanz**, Räume,
Volumen — bei leerer Auswahl als Projekt-Übersicht.
19. **CH-Spezifika UI-seitig vorsehen**: **Norden-Rotation**-Gizmo (ViewCube/Kompass),
SIA-Raumkategorien im Raum-Inspector, später Swisstopo-Import-Flow mit Auto-Zoom
+ Nullpunkt-Verschiebung.
### Übergreifende Designprinzipien (gelten immer)
- **Kontextualität vor Vollständigkeit** — zeige nur, was jetzt anwendbar ist
(Arcol/Onshape/Figma). Direkt verzahnt mit unserem „LoD-bewusste Stil-UI"-Backlog.
- **Direkte Manipulation vor Dialogen** — Grips/Drag/Inline-Edit schlägt
Properties-Dialog (Figma/Snaptrude/DOSSIER).
- **Eine Wahrheit, viele Sichten** — niemals Sicht-spezifische Daten; alles aus dem
semantischen Modell ableiten (deckt sich exakt mit unserem Architektur-Prinzip).
- **Konventionen respektieren** — Pan/Zoom/Snap/Esc/Cmd-K wie die etablierten Tools;
Nutzer bringen Muskelgedächtnis aus Figma/CAD mit.
- **Gefühlte > tatsächliche Geschwindigkeit** — optimistic + Skeletons + 60 fps;
im schweren Browser-3D-Geometrie-Kontext ein echter Wettbewerbsvorteil.
---
## Quellen
**Arcol**
- [Arcol unleashed BIM 2.0 (AEC Magazine)](https://aecmag.com/bim/arcol-unleashed-bim-2-0/)
- [Arcol BIM in a browser (AEC Magazine)](https://aecmag.com/bim/arcol-bim-cloud-browser/)
- [Arcol: a sneak peek (AEC Magazine)](https://aecmag.com/bim/arcol-a-sneak-peek/)
- [The Arcol Manifesto](https://arcol.io/blog/the-arcol-manifesto)
**Snaptrude**
- [Snaptrude browser-based BIM tool (ArchDaily)](https://www.archdaily.com/1009121/snaptrude-the-browser-based-bim-tool-thats-changing-the-way-architects-work)
- [Snaptrude (offiziell)](https://www.snaptrude.com/)
**TestFit**
- [TestFit 5.19: A New Generative Design Workflow](https://www.testfit.io/blog/testfit-5-19-a-new-generative-design-workflow)
- [TestFit (offiziell)](https://www.testfit.io/)
**Onshape**
- [Onshape: User Interface Basics](https://cad.onshape.com/help/Content/ui-basics.htm)
- [Onshape: Automatic Inferencing](https://cad.onshape.com/help/Content/Sketch/automatic_inferencing.htm)
- [Onshape: Working with Constraints](https://cad.onshape.com/help/Content/Sketch/working_with_constraints.htm)
- [Onshape: Sketch Basics](https://cad.onshape.com/help/Content/Sketch/sketch_basics.htm)
**Vectorworks**
- [VW Resource Manager](https://app-help.vectorworks.net/2026/eng/VW2026_Guide/ResourceManager/Resource%20Manager.htm)
- [VW Resource Manager: File browser pane](https://app-help.vectorworks.net/2023/eng/VW2023_Guide/ResourceManager/Resource_Manager_File_browser_pane.htm)
- [VW Resource Manager: Resource viewer pane](https://app-help.vectorworks.net/2026/eng/VW2026_Guide/ResourceManager/Resource_Manager_Resource_viewer_pane.htm)
- [VW Navigation Palette](https://app-help.vectorworks.net/2022/eng/VW2022_Guide/Structure/The_Navigation_palette.htm)
- [VW Palettes and Tool Sets](https://app-help.vectorworks.net/2018/eng/VW2018_Guide/Start/Palettes_and_Tool_Sets.htm)
**Figma**
- [Figma: right sidebar / layer properties](https://help.figma.com/hc/en-us/articles/360039832014-Design-prototype-and-explore-layer-properties-in-the-right-sidebar)
- [Figma: left sidebar (layers & pages)](https://help.figma.com/hc/en-us/articles/360039831974-View-layers-and-pages-in-the-left-sidebar)
- [Figma for Everyone: The Interface](https://www.inthepocket.design/course/figma-for-everyone/the-interface)
**Perceived Performance**
- [LogRocket: Skeleton loading screen design](https://blog.logrocket.com/ux-design/skeleton-loading-screen-design/)
- [UI Deploy: Skeleton Screens vs. Spinners](https://ui-deploy.com/blog/skeleton-screens-vs-spinners-optimizing-perceived-performance)
- [Onething: Skeleton Screens vs Loading Spinners](https://www.onething.design/post/skeleton-screens-vs-loading-spinners)
- [Smart Interface Design Patterns: Loading & Progress UX](https://smart-interface-design-patterns.com/articles/designing-better-loading-progress-ux/)
**Command Palette**
- [Mobbin: Command Palette](https://mobbin.com/glossary/command-palette)
- [Untitled UI: Command menus (Cmd-K)](https://www.untitledui.com/components/command-menus)
- [Superhuman: How to build a remarkable command palette](https://blog.superhuman.com/how-to-build-a-remarkable-command-palette/)
- [Outdraw Academy: Command Palette UX pattern](https://outdraw-academy.gitbook.io/ux-patterns/command-palette)
**Onboarding / Progressive Disclosure**
- [IxDF: Progressive Disclosure](https://ixdf.org/literature/topics/progressive-disclosure)
- [UXPin: What Is Progressive Disclosure](https://www.uxpin.com/studio/blog/what-is-progressive-disclosure/)
- [Userpilot: User onboarding examples](https://userpilot.com/blog/user-onboarding-examples/)
- [Userpilot: Progressive disclosure examples](https://userpilot.com/blog/progressive-disclosure-examples/)