diff --git a/PENDENZEN.md b/PENDENZEN.md index 81a239c..4bd2ee4 100644 --- a/PENDENZEN.md +++ b/PENDENZEN.md @@ -61,6 +61,19 @@ ## ⏭️ Als Nächstes +- [ ] **BIM-Elemente „wirklich 1:1" (Tür/Fenster/Dach/Decke)** — volle Studie + Priorisierung: **[docs/design/bim-elements-depth-study.md](docs/design/bim-elements-depth-study.md)** (623 Zeilen, Referenzmatrix VW/ArchiCAD/Revit/Allplan gegen IST). ✅ **Bereits erledigt 2026-07-10:** Fenster-Schachtelung Blendrahmen→Flügelrahmen→Glas + fest/öffenbar + Einbaulage 2D (`9a38636`); Mansard-Untertypen Giebel/Walm/Zelt + Knick (`bfb80b3`); Dach-Dicke 3D (`e99bb24`) + **Dach-Schichtlogik RoofType/Layer[]** (`3a986ec`); zweiflügelige Türen leafCount 2D+3D (`4319e12`); getrennter Traufe/Ortgang-Überstand (`c9baff5`); Glas/glazingPanes 2D+3D + Rollladenkasten (`2e13ec3`/`d131683`). **Offen (nach Doc-Priorität):** + - [ ] **Decken-Aussparungen** `Ceiling.openings?: Vec2[][]` (Treppenauge/Schacht) — **P0**, grösster Praxiswert. Braucht Loch-Support im `polygon`-Primitiv (`generatePlan.ts:207`, aktuell KEINE Löcher) + SVG-/glPlan-Renderer + 3D-Slab-Loch (Vorlage `wallMeshCut.ts`). Cross-cutting, ~3 PT. + - [ ] **2D-Schnitt-Poché der Dachschichten** — `toSection.ts` behandelt Dächer heute gar nicht; Grundriss-Poché der Dachschichten (`addRoof` in generatePlan analog `addCeilingPoche`). + - [ ] **RoofType-ResourceManager-Tab** (Schicht-Editor wie Wand/Decke) — heute nur über sampleProject-Default wählbar, kein Anlegen/Editieren im UI. + - [ ] **Decken-Randschicht-Override** (`Ceiling.edgeOverride`, Ringzone anderer Aufbau, Tropfkante/Randdämmung) — P1; **Deckentrenn-Werkzeug** für thermisch getrennte Auskragung (Isokorb, UI-only) — P1. + - [ ] **Tür 1:1 Rest:** `glazingRatio` (Teilverglasung), Kassettentür-Geometrie, `frameKind` im 3D (Zarge vs. Blockrahmen), echtes Schwellenprofil; Alt-`Door[]`-Pfad in `Opening` konsolidieren (technische Schuld, zwei Datenwege). + - [ ] **Fenster 1:1 Rest:** asymmetrische Rahmenbreiten, echtes Sprossengitter, Bank/Nische, Laibungsverkleidung, Form (Rund/Spitz/Schräg). + - [ ] **Dach 1:1 Rest:** Kniestock/Drempel, Krüppelwalm, Kehlen bei L-Grundriss (Straight-Skeleton), Gauben/Dachfenster, Aufschieblinge; Dach im Vertikalschnitt (`toSection.ts`). + - [ ] **Geneigte Decke** (Rampe/Gefälle), Deckenspiegel (zweite abgehängte Fläche) — P2/P3. + - **Nicht bauen** (Doc §6): VW-Massketten-Apparat, volle Sichtbarkeitsmatrix, Eck-Fenster/-Dach generisch, Beschlags-Produktbibliothek, IFC-Void-Semantik nachrüsten. + +- [ ] **`make2D`-Befehl (Sicht → 2D-Zeichnung mit Füllungen)** (Nutzer-Wunsch 2026-07-10). Aus der AKTUELLEN Sicht — egal ob Grundriss, Schnitt oder 3D — eine flache 2D-Zeichnung aus reinen 2D-Geometrien erzeugen (Linien + Füllungen/Schraffuren, „mit allem"). Zwei Ausgaben: (a) als neue `Drawing2D`-Elemente ins Modell einfügen (auf einer Ziel-Ebene), ODER (b) in die Zwischenablage kopieren (SVG/DXF-Fragment) zum Einfügen anderswo. Vorbild: Vectorworks „2D-Darstellung erzeugen" / Rhino `Make2D`. **Bausteine vorhanden:** Grundriss/Schnitt laufen bereits über `generatePlan()`/`generateSectionPlan()` → RScene → SVG (`sceneToPrintSvg`); für 3D braucht es eine Projektion (HLR/Silhouette) der `projectToModel3d`-Meshes auf die Bildebene (neuer Teil). MVP: Grundriss/Schnitt → Drawing2D + Clipboard; 3D-Projektion als zweite Phase. Scope/Format (SVG vs. DXF vs. native Drawing2D) mit Nutzer schärfen. + - [x] ~~**Dächer: Auswahl + Attribut-Editieren + Löschen**~~ — **erledigt (`80121a3` + Folge-Commits `7cfdf59`/`eaf57e2`/`64f6179`/`826685c`):** Klick-Auswahl (Traufe-Pick-Polygon + pickRoof), `selectedRoofIds`/`updateRoof`/`RoofInfo`/`roofSelection`; RoofSection-Panel voll editierbar (Form, Firstrichtung X/Y, Neigung(en), **Breite/Tiefe**, Überstand, Dicke, **Traufhöhe**) + Firsthöhe/Fläche read-only; **Auswahl-Hervorhebung im 2D UND 3D** (Draht-Umriss); Löschen; Abwählen an ALLEN Reset-Stellen. **Optional Folge:** ~~3D-Griffe zum Ziehen (Traufe/First)~~ ✅ **erledigt `4ef40a0`** (Eckpunkt-Resize + Verschieben + First-Griff für Neigung). **Noch offen:** Dachfenster, Kehlen bei nicht-rechteckigem Grundriss (Straight-Skeleton). - [ ] **Ribbon-UI + modulare Bars** (Nutzer-Vision 2026-07-05, bestätigt: Tab-Schema **2D·3D·BIM·Ansichten**). Voller Plan + datengetriebene Architektur: **[docs/design/ribbon-ui-plan.md](docs/design/ribbon-ui-plan.md)**. Ribbon-Oberleiste mit Tabs ersetzt die Werkzeug-Sidebar; datengetriebene Registry (RibbonItem = tool|command|action) ermöglicht auch eine **modulare Custom-Bar** (gleiche Items, vom Nutzer gewählt). Attribute bekommen volle Höhe, Objektinfo darunter gemergt; XYZ-Box oben rechts bleibt. **Phasen:** ~~(1) Gerüst + 2D/BIM-Tab~~ ✅ (`9d6e86d`), ~~(2) TopBar → Ansichten-Tab mergen~~ ✅ (`85011cb`), ~~(2b) Tabs in die TopBar-Zeile~~ ✅ (`456ebc8`), ~~(2c) OCS-Chrome (kleine Wortmarke + Quick-Access-Icons statt Burger, Zeile 26px)~~ ✅ (`4e3b074`), ~~(2d) Text + Ansichten auf eine Leiste, „Ansichten" als Standard-Tab zuerst~~ ✅ (`fe22cbf`), (3) **teilweise** ✅: Werkzeug-Sidebar aus Default-Layout raus + Attribute volle linke Höhe + Wandtyp-/Deckentyp-Picker ins Attribute-Panel verschoben (Nutzer-Entscheid), `LAYOUT_VERSION`→8; ~~**offen:** Objektinfo unter Attribute mergen~~ ✅ (`3a2cef3`): element-spezifische Abschnitte (Wand/Decke/Öffnung/Treppe/Raum) + Wand-Referenzlinie ins Attribute-Panel verschoben; ObjectInfo trägt nur noch Bezugspunkt + Masse (Nutzer-Wunsch). ~~(4) modulare Custom-Bar~~ ✅ (Tab „Eigene" + +-Picker, localStorage-persistiert). **Offen:** 3D-Tab füllen (aktuell leer; ggf. 3D-spezifisch statt Doppelung mit Ansichten), Band-Höhe/Abstände + 26px-Zeile visuell im Tauri abnehmen, Dauer-Zoom-Anzeige (Statusleiste?) klären. ✅ Vorarbeit: Eigenschaften-Grid im OCS-Stil (`00733d8`), Kreis+Bogen-Werkzeuge (`e454eab`/`bd2b12b`). **Nächster Schritt: im Tauri visuell prüfen (Band-Höhe, Icons, Aktiv-Highlight), dann Phase 2/3.** diff --git a/docs/design/bim-elements-depth-study.md b/docs/design/bim-elements-depth-study.md new file mode 100644 index 0000000..41be847 --- /dev/null +++ b/docs/design/bim-elements-depth-study.md @@ -0,0 +1,623 @@ +# BIM-Elementtiefe — Tür, Fenster, Dach, Decke ("wirklich 1:1") + +## 0. Zweck und Abgrenzung + +DOSSIER modelliert Bauteile heute semantisch (kein reines Zeichenprogramm) und +hat für Wand/Decke bereits eine mehrschichtige Aufbaulogik (`Component[]` via +`WallType`/`CeilingType`). Türen und Fenster haben seit +`docs/design/window-editor-vectorworks-study.md` einen dedizierten, +phasierten Ausbauplan (Flügeltabelle, Verglasung, Sonnenschutz). Was fehlt, +ist die gleiche Tiefe für **Dach** (keine Schichtlogik, keine Mansard- +Untertypen, kein Kehl-/Gaubenmodell) und für die **Decken-Randterminierung** +(Deckenrand als reines Polygon ohne Kantendetail). + +Dieses Dokument nimmt die vier Bauteile Tür, Fenster, Dach, Decke und hält +sie gegen die reale Tiefe vollständiger BIM-Programme (Vectorworks Architektur, +ArchiCAD, Revit, Allplan). Ziel ist NICHT, jedes Feature dieser Programme zu +kopieren, sondern zu benennen, welche Lücken einen echten "1:1-Zuwachs" für +ein Einfamilienhaus-/Wohnbau-Tool wie DOSSIER bringen — und welche reiner +Ballast wären (Abschnitt 6). + +Für Fenster/Tür dupliziert dieses Dokument NICHT die Mapping-Tabelle aus +`window-editor-vectorworks-study.md` — es referenziert sie und ergänzt, was +dort fehlt (v. a. Tür-Tiefe, die die Studie nur am Rand behandelt, und die +architektonischen Grenzen des heutigen Öffnungsmodells). Für Wand-Schichtlogik +siehe `docs/design/parametric-walls.md` (Raster/Modul-Regeln, nicht +Gegenstand hier) und `docs/design/elements.md` (ältere Gesamtplanung, Stand +vor der aktuellen `Component`/`Layer`-Implementierung — dort abweichende +Typnamen wie `Slab`/`ProfileDef`, hier durchgängig der IST-Code zitiert). + +Alle IST-Aussagen sind mit Datei:Zeile belegt (verifiziert per Lesen des +Codes, Stand dieses Commits). Status-Legende der Lücken-Tabellen: **✓** +vorhanden und gerendert · **~** Feld existiert, Renderer liest es nicht oder +nur grob · **✗** fehlt vollständig. Priorität P0 (grösster 1:1-Zuwachs, bald) +… P3 (Ballast, nur auf Nachfrage). Aufwand grob in Personentagen (PT). + +--- + +## 1. Gemeinsames Fundament: das Schicht-Muster + +Der zentrale Baustein, den DOSSIER bereits hat und der sich wiederverwenden +lässt, ist `Component`/`Layer`: + +- `Component` (`src/model/types.ts:196`) — ein Bauteil-Material: Poché-Farbe + (`color`/`foreground`/`background`), Schnitt-Schraffur (`hatchId`) UND + Ansichts-Schraffur (`viewHatchId`, für unaufgeschnittene Aufsicht), + optionales PBR-Material (`material`), Kürzel (`abbrev`) und ein + Verschneidungs-Rang (`joinPriority`, `types.ts:241`) für die Boolean- + Dominanz am Stoss. +- `Layer` (`types.ts:245`) — eine Schicht: `componentId` + `thickness` + + optionaler Fugen-Linienstil (`jointLineStyleId`). +- `WallType` (`types.ts:260`) und `CeilingType` (`types.ts:273`) sind BEIDE + nur `{ id, name, layers: Layer[] }` — bewusst derselbe Typ, "das + horizontale Gegenstück zum WallType" (Kommentar `types.ts:266-271`). + +Das Muster ist also bereits zweimal (Wand, Decke) verifiziert: +`ceilingThickness()` (`types.ts:2104`) summiert die Layer-Dicken, +`emitSlabs()` (`src/plan/toWalls3d.ts:1352-1419`) stapelt sie im 3D als +einzelne `RSlab`-Scheiben proportional in `[zBottom, zTop]`, `addCeilingPoche` +(`src/plan/generatePlan.ts:2453`) zeichnet die Aufsicht mit der +Ansichts-Schraffur der ERSTEN Schicht, und `toSection.ts:633` +(`splitSlabLayers`) zerlegt die Decke im ECHTEN Schnitt in +Einzel-Bänder je Schicht (mit `resolveCeilingSectionStyle`, +`generatePlan.ts:591`, als Schraffur-/Farbquelle). + +**Der Dach-Vorschlag in Abschnitt 4 ist im Kern: dasselbe Muster ein drittes +Mal anwenden.** Das ist der günstigste Weg zu echter Dach-1:1-Tiefe, weil +Layer-Resolver, Schraffur-Ketten (`resolveHatch`/`resolveForeground` etc., +`generatePlan.ts:409-536`) und die 3D-Stapel-Logik bereits bestehen und nur +auf einen neuen Aufbau-Typ angewendet werden müssen statt neu erfunden. + +Architektonische Randbemerkung: `Project` führt bereits `wallTypes`, +`ceilingTypes?`, `doorTypes?`, `windowTypes?`, `stairTypes?` +(`types.ts:1936-1958`) als eigene Bibliotheken — aber **kein `roofTypes?`**. +`Roof` (`types.ts:1022`) trägt nur ein einzelnes `thickness: number` +(`types.ts:1044`), keinen Aufbau-Verweis. Das ist die strukturelle Lücke, +die Abschnitt 4 schliesst. + +--- + +## 2. Tür (Door) + +### 2.1 Was ein vollständiges BIM-Tool bietet + +| Bereich | Typische Parameter (VW/ArchiCAD/Revit/Allplan) | +|---|---| +| Bauart | Dreh-, Schiebe- (auf/vor Wand), Falt-, Pendel-, Karusselltür, reiner Durchbruch | +| Blattzahl/-teilung | 1-/2-flügelig, Gangflügel + Standflügel (unterschiedliche Breite), Seitenteile links/rechts | +| Blattausführung | glatt, kassettiert, Glasfüllung (Anteil/Sprossenbild), Brandschutz-/Schallschutz-Kennwert | +| Rahmen/Zarge | Zarge vs. Blockrahmen, Rahmenbreite je Kante, Zargentiefe, Bekleidung/Abdeckleiste, Falz | +| Schwelle | ohne, Alu-Flachschwelle, Anschlagdichtung, Bodenanschluss/Gefälle bei Aussentüren | +| Sturz/Oberlicht | festverglastes Oberlicht mit eigenem Rahmen, Kämpfer, Sprossenbild | +| Seitenteile | fest verglaste Seitenteile links/rechts, eigene Breite | +| Form | rechteckig, Rundbogen, Segmentbogen, Stichbogen — bei Aussen-/Haustüren verbreitet | +| Beschlag | Drücker/Knauf-Typ, Schild, Schliesszylinder, Bänder sichtbar/verdeckt | +| 2D-Darstellung | Blatt + Schwenkbogen (Grundriss), eigene Ansichtssymbolik in Schnitt/Elevation, Sturzlinien | +| Material/Schichten | Blatt-Kernaufbau (bei Brand-/Schallschutztüren mehrschichtig, analog Wand) | +| IFC-Rolle | `IfcDoor` mit `IfcDoorType` (PredefinedType), `OverallWidth/Height`, `IfcDoorPanelProperties`, Void in der Wirtswand | + +### 2.2 IST in DOSSIER + +`Opening` mit `kind: "door"` (`src/model/types.ts:1068`) referenziert +optional einen `DoorType` (`types.ts:296`). Vorhanden am Typ: `kind` +("dreh"/"schiebe"/"wandoeffnung", :303), `leafCount` (1|2, :305), `leafStyle` +("glatt"/"kassette"/"glas", :307), `glazingRatio` (:309), `frameThickness`/ +`frameDepth`/`frameKind`("zarge"/"blockrahmen")/`frameWidth` +(:311-328), `insetFromFace`/`insetFace` (:335-337), `transomHeight` (:343), +`threshold` (:349). Am Element selbst: `swing`/`hinge`/`swingAngle`/ +`openingDir` (:1104-1108), `lintelLines` (Sturzlinien, :1119) und +`doorType: "normal"|"wandoeffnung"` (:1100) — ein zweites, mit `DoorType.kind` +teilweise redundantes Feld. + +Renderer-Konsum, real geprüft: + +- **2D-Blatt ist IMMER einflügelig.** `addOpeningSymbol` (Tür-Zweig, + `src/plan/generatePlan.ts:2091-2213`) zeichnet genau EINE Blattlinie + (`sym.hinge → sym.openEnd`) und EINEN Schwenkbogen — `DoorType.leafCount` + wird an keiner Stelle in `generatePlan.ts` gelesen (kein Treffer für + `leafCount` im ganzen Plan-Renderer). Eine zweiflügelige Tür sieht im Plan + aus wie eine einflügelige. +- **3D genauso**: `resolveOpeningFrame` (`src/plan/toWalls3d.ts:1861-1886`) + setzt für Türen hart `wingCount: 1`, unabhängig von `leafCount`. +- `leafStyle` wirkt NUR binär: `"glas"` schaltet eine volle Verglasung frei + (`glazed: dt.leafStyle === "glas"`, `toWalls3d.ts:1883`) — `glazingRatio` + (Teilverglasung, z. B. 60 % Glasanteil im oberen Blattbereich) wird an + keiner Stelle gelesen. "kassette" (Kassettentür) hat keine eigene Geometrie, + fällt auf dieselbe Quader-Darstellung wie "glatt" zurück. + `frameKind: "blockrahmen"` wirkt NUR im 2D-Rahmenband + (`generatePlan.ts:1996`, `isBlock`), im 3D gibt es keinen Unterschied zur + Zarge (`frameMeshesForOpening`, `toWalls3d.ts:1936`, kennt kein + `frameKind`). +- `threshold` steuert `hasSill` im 3D-Rahmen (`toWalls3d.ts:1880`), was einen + einfachen Schwellen-Riegel zeichnet — kein eigenes Schwellenprofil, + keine Gefälle-/Dichtungsdarstellung. +- Es gibt eine ZWEITE, ältere Tür-Repräsentation: `Door` + (`types.ts:1333`, `project.doors: Door[]`) mit eigenem Symbol-Renderer + `addDoorSymbol` (`generatePlan.ts:1840-1899`) — strukturell identisch zum + `Opening`-Pfad, aber ohne jeden Typ-Bezug. Zwei parallele Datenwege für + dieselbe Bauteilart sind selbst technische Schuld, nicht nur ein + BIM-Feature-Gap. +- Form (Rundbogen etc.) existiert nicht: `Opening.width`/`height` sind ein + reines Rechteck, `wallGaps`/`buildWallFootprints` + (`generatePlan.ts:1363-1457`) schneiden nur rechteckige Bänder aus der + Wand-Poché. +- IFC-Export: `IfcDoor` wird erzeugt (`src/export/exportIfc.ts:30-31`), aber + als reine Box-Geometrie ohne `IfcDoorType`/`PredefinedType` und ohne + `IfcOpeningElement`-Void (bewusste Design-Entscheidung, siehe Kommentar + `exportIfc.ts:18-31`: das Loch steckt bereits im geschnittenen Wand-Mesh). + +### 2.3 Lücken (Tür) + +| Feature | Status | Priorität | Aufwand | +|---|---|---|---| +| Zweiflügelige Tür rendert 2 Blätter (2D+3D) | ✗ (`leafCount` ungelesen) | **P0** | 2 PT | +| Teilverglasung nach `glazingRatio` (2D-Linie + 3D-Split) | ✗ | P1 | 1.5 PT | +| Kassettentür eigene Blattgeometrie (Füllungsfelder) | ✗ | P2 | 2 PT | +| `frameKind` (Blockrahmen) auch im 3D wirksam | ~ | P1 | 1 PT | +| Seitenteile (feste Verglasung links/rechts der Tür) | ✗ | P1 | 2 PT | +| Rundbogen-/Segmentbogen-Türform | ✗ | P2 | 4 PT (braucht gekrümmten Wandausschnitt, s. §5.3) | +| Schwellenprofil (Alu-Flachschwelle, Dichtung) statt Riegel | ✗ | P2 | 1 PT | +| `Door`/`Opening`-Doppelpfad konsolidieren | technische Schuld | P1 | 3 PT (Migration) | +| Beschlag (Drücker/Knauf) als Mesh + 2D-Symbol | ✗ | P2 | 1.5 PT | +| IFC `IfcDoorType`/PredefinedType/OverallWidth-Height-Properties | ~ | P2 | 1 PT | + +### 2.4 Umsetzungsvorschlag + +**Modell**: `DoorType.leafs?: { width: number; hingeSide: "left"|"right"; +fixed?: boolean }[]` analog `WindowType.sashes` (`SashDef`, `types.ts:367`) — +bewusst dieselbe Struktur, damit `resolveSashSpans` (`toWalls3d.ts:2019`) UND +die 2D-Pfostenlinien-Logik direkt wiederverwendet werden können, statt eine +Tür-eigene Variante zu bauen. Ein `fixed: true`-Leaf ist das Seitenteil. +`glazingRatio` wandert vom Skalar zu einer klaren Geometrie: Kämpferhöhe +innerhalb des Blatts, gerendert wie das bestehende Oberlicht +(`transomHeight`), nur INNERHALB des Blattrahmens statt darüber. + +**2D**: `addOpeningSymbol` (Tür-Zweig) über die Leaf-Liste iterieren statt +einer festen Blattlinie; pro Leaf ein eigenes `hinge`/`swing` (Default: +alternierend wie bei Fenstern, `sashesOfWindowType`, `types.ts:2132`). + +**3D**: `resolveOpeningFrame` liefert `wingCount = leafs.length` statt hart 1; +`frameMeshesForOpening` (bereits generisch über `params.sashes`) übernimmt +die Mehrflügel-Darstellung ohne Änderung — das ist der Vorteil der +Struktur-Wiederverwendung. + +**UI**: Im Tür-Editor (sofern nach dem Muster von +`window-editor-vectorworks-study.md` gebaut) eine Flügeltabelle wie bei +Fenstern, nur mit Tür-Vokabular (Gangflügel/Standflügel statt Flügel 1/2). + +--- + +## 3. Fenster (Window) + +Für Fenster existiert bereits eine vollständige Referenzmatrix in +`docs/design/window-editor-vectorworks-study.md` §2 (Basiseinstellungen, +Grösse, Brüstung, Rahmen, Flügeltabelle, Laibung/Form/Ober-Unterlicht, +Sonnenschutz/Beschlag, Attribute/IFC) mit eigener P0–P3-Phasierung. Diese +Studie ist der massgebliche Bezugspunkt; hier nur die Delta-Punkte, die dort +fehlen oder seither vom IST abweichen. + +### 3.1 IST-Ergänzung (was die Studie nicht/knapp behandelt) + +- `WindowType.glazing` (einfach/zweifach/dreifach) ist bis heute NICHT + renderwirksam — bestätigt weiterhin: `glazingPanesOf()` (`types.ts:2149`) + wird von `glassPanesForOpening` in `toWalls3d.ts` konsumiert, aber die + Studie selbst vermerkt (Zeile 61-65 dort), dass der 2D-Pfad die + Scheibenzahl weiterhin allein aus `DetailLevel` ableitet, nicht aus + `glazingPanes`. Das ist über ein Jahr nach der Studie noch offen — ein + Hinweis, dass P0/P1-Posten aus Fenster-Studien real liegen bleiben, wenn + niemand sie explizit nachzieht. +- `sillBoard` (Fensterbank keine/innen/aussen/beide, `types.ts:447`) ist + weiterhin ungenutzt (kein Treffer für `sillBoard` in `toWalls3d.ts` oder + `generatePlan.ts` ausserhalb der Typ-Definition und des Editors) — + entspricht dem in der Studie als P1 markierten "Fensterbank erstellen". + +### 3.2 Architektonische Grenze: gekrümmte Öffnungen + +Sowohl die Fenster-Studie (§2.6, "Form Eckig/Schräg/Spitz/Rund", P2, 4 PT) +als auch dieser Auftrag nennen Rundbogen-/Spitzbogenfenster. Das ist teurer, +als die Aufwandschätzung suggeriert, weil das gesamte Öffnungsmodell auf +GERADEN Bändern basiert: `buildWallFootprints`/`wallGaps` +(`generatePlan.ts:1363-1457`) schneiden ein rechteckiges Intervall `[from,to]` +entlang der Wandachse aus der Poché, `openingAxisBox` +(`toWalls3d.ts:1739`) baut im 3D ebenso einen achsparallelen Quader. Eine +Bogenform braucht entweder (a) eine gekrümmte Zusatzkontur, die die +Rechteck-Aussparung oben kappt (2D: zusätzliche Polygon-Boolean gegen die +Poché; 3D: gekrümmte Deckfläche statt ebenem Sturz) oder (b) ein komplett +neues, polygonbasiertes Öffnungsmodell. Vorschlag: (a) zuerst — ein +`headShape: "eckig"|"segment"|"spitz"|"rund"` mit Zusatzparametern +(Stichhöhe/Radius), das NUR die obere Kante der bestehenden Rechteck-Öffnung +ersetzt, während Pfosten/Sohlbank rechteckig bleiben. Deckt die reale +Mehrheit der Fälle (Haustür mit Rundbogen, Dachflächenfenster-Giebel) ohne +das Kernmodell umzubauen. + +### 3.3 Lücken (Fenster, Delta zur Studie) + +| Feature | Status | Priorität | Aufwand | +|---|---|---|---| +| `glazing`/`glazingPanes` 2D-wirksam (Scheibenzahl statt nur DetailLevel) | ~ (weiter offen seit Studie) | **P0** | 1 PT | +| `sillBoard` gerendert (2D-Kontur + 3D-Box) | ✗ | P1 | 2 PT | +| Kopfform (Rundbogen/Spitzbogen/Schräge) über Zusatzkontur | ✗ | P2 | 5 PT (s. §3.2) | +| Echtes Sprossengitter (Glasteilung UNABHÄNGIG von Flügelrahmen) | ✗ | P1 | 2 PT | +| Alle übrigen Fenster-Lücken | siehe window-editor-vectorworks-study.md §2/§4 | — | — | + +--- + +## 4. Dach (Roof) + +### 4.1 Was ein vollständiges BIM-Tool bietet + +| Bereich | Typische Parameter | +|---|---| +| Grundform | Pult, Sattel, Walm, Krüppelwalm, Zeltdach, Mansarde (mit Untertyp Giebel-/Walm-/Zeltmansarde), Flach/Terrassendach, Sheddach, Tonnendach, freie Neigungsflächen je Kante | +| Grundriss | beliebiges Polygon (nicht nur Rechteck), automatische Kehlen/Grate über Straight-Skeleton bei L-/T-/U-Grundrissen | +| Neigung | je Dachfläche einzeln editierbar, unterschiedliche Neigungen je Seite | +| Schichtaufbau | Eindeckung (Ziegel/Blech/Bitumen), Lattung, Konterlattung, Unterdach/-spannbahn, Sparren/Dämmung zwischen Sparren, Dampfbremse, Innenverkleidung — analog Wandaufbau, mit Deckenanschluss | +| Überstand | Traufe und Ortgang UNABHÄNGIG editierbar (Betrag + Ausbildung), Aufschiebling (Neigungsknick am Traufende), Ortganddetail (Windbrett, Blech) | +| Kniestock/Drempel | vertikale Wandaufkantung zwischen Deckenoberkante und Dach-Traufpunkt, definiert First-/Trauf-Geometrie mit | +| Öffnungen im Dach | Dachflächenfenster (schräg, in der Dachebene), Dachgauben (Schlepp-, Sattel-, Walm-, Spitzgaube, Fledermausgaube) als eigenständige Sekundärdächer mit eigenem First | +| First/Grat/Kehl/Ortgang | eigene Linientypen in 2D-Ansicht (Dachaufsicht) UND im Schnitt sichtbar (Sparrenlage, Dämmstärke) | +| Material/Poché | Dachfläche in der Aufsicht mit Eindeckungs-Symbol/-Schraffur (Ziegel-Textur o. Ä.), im Schnitt Vollschichten wie eine geneigte Wand | +| IFC-Rolle | `IfcRoof` (aggregiert `IfcRoofType`), Dachflächen selbst oft als `IfcSlab`-artige Elemente mit `IfcMaterialLayerSetUsage`, Gauben als eigene `IfcRoof`/`IfcBuildingElementProxy`-Unterobjekte | + +### 4.2 IST in DOSSIER + +`Roof` (`src/model/types.ts:1022-1047`) rechnet ausschliesslich auf der +**Bounding-Box** des Umrisses (Kommentar `types.ts:1016-1020`: "First entlang +einer Hauptachse ... die gängige, intuitive Vereinfachung"). Geometrie kommt +aus `roofGeometry()`/`computeCanonical()` (`src/geometry/roof.ts:80-267`), +explizit **"ohne Straight-Skeleton"** (Kommentar `roof.ts:5`). Unterstützte +`RoofShape` (`types.ts:1013`): flach/pult/sattel/walm/mansarde/zelt — je EINE +feste Berechnung, keine Untertypen. Mansarde hat eine feste, nicht editierbare +Knick-Geometrie (`d1 = halfD * 0.4`, `roof.ts:181` — 40 % der Tiefe von der +Traufe, hart codiert, keine Möglichkeit den Umbruchpunkt zu verschieben). + +Konkrete, verifizierte Lücken: + +- **Kein Schichtaufbau.** `Roof.thickness` (`types.ts:1044`) ist ein + einzelner Skalar. Er wird an KEINER Stelle im Code gelesen (`grep + "roof.thickness"` über `toWalls3d.ts`/`generatePlan.ts`/`roof.ts` liefert + null Treffer) — das Feld existiert im Typ, ist aber komplett tot. Die + 3D-Dachfläche ist eine unendlich dünne, einfarbige Fläche + (`emitRoofs()`, `src/plan/toWalls3d.ts:1670-1684`: nur `plane.pts`/ + `gable`-Fans, EINE Farbe `ROOF_RGB` bzw. `roof.color`, keine Dicke, keine + Materialschichten). +- **Kein `RoofType`.** `Project` hat `wallTypes`, `ceilingTypes?`, + `doorTypes?`, `windowTypes?`, `stairTypes?` (`types.ts:1936-1958`), aber + kein `roofTypes?`. Es gibt keinen Bauteil-Bibliothekseintrag für Dächer. +- **2D-Grundriss zeigt keine Poché.** `addRoof()` + (`src/plan/generatePlan.ts:2549-2605`) zeichnet AUSSCHLIESSLICH Linien + (Traufe/First/Grat/Knick, je feste Strichstärke `ROOF_EAVES_MM`/ + `ROOF_RIDGE_MM`/`ROOF_HIP_MM`) — keine Fläche, keine Schraffur, keine + Materialkennzeichnung. Deckungsgleich mit Wand/Decke, die BEIDE eine + Poché-Füllung mit Schraffur haben (`addWallPoche`, `addCeilingPoche`), + bleibt das Dach in der Aufsicht ein reines Liniendiagramm. +- **Kein Schnitt.** `src/plan/toSection.ts` hat KEINE Roof-Behandlung (kein + Treffer für `roof`/`Roof` im gesamten Datei-Grep). Ein Vertikalschnitt + durch ein Gebäude mit Satteldach zeigt heute keine Dachlinie, keine + Sparrenlage, keine Firstprojektion — ein Kernstück der BIM-1:1-Erwartung + fehlt vollständig. +- **Kein IFC.** `exportIfc.ts` erzeugt `IfcWall`, `IfcSlab`, `IfcDoor`/ + `IfcWindow`, `IfcStair`, `IfcBuildingElementProxy` (Kommentar + `exportIfc.ts:18-36`) — `Roof`/`IfcRoof` ist in der Abbildungsliste NICHT + aufgeführt und wird beim Export komplett übersprungen. +- **Kein Straight-Skeleton, kein L-Grundriss mit Kehle.** Ein L-förmiger + Baukörper mit durchgehendem Satteldach (Kehle an der Innenecke) lässt sich + nicht abbilden — die BBox-Rechnung würde ein Rechteck über die ganze + L-Ausdehnung legen. +- **Keine Gauben, keine Dachfenster.** Kein Treffer für Gaube/Dormer im + gesamten `src`-Baum (verifiziert per Suche). +- **Kein Kniestock als Bauteilbeziehung.** `baseElevation` (`types.ts:1042`) + erlaubt zwar, die Traufhöhe manuell über die Geschoss-Oberkante zu heben + (ein Kommentar in `ObjectInfoPanel.tsx:549` erwähnt das explizit als + Nutzungsmuster), aber es gibt keine Wand-Dach-Kopplung, die einen + Drempel/Kniestock als eigenes, vermasstes Bauteil führt — der Nutzer muss + die Zahl manuell abstimmen. +- **Traufe/Ortgang nicht unabhängig.** `overhang` (`types.ts:1038`) ist EIN + Wert "ringsum" — Traufüberstand und Ortgangüberstand (oft unterschiedlich, + z. B. 0.5 m Traufe / 0.3 m Ortgang) sind nicht trennbar. +- **UI**: `ObjectInfoPanel.tsx:479-561` bietet volle Instanz-Bearbeitung + (shape/ridgeAxis/pitch/pitchUpper/width/depth/overhang/thickness/ + baseElevation), aber keine Typ-/Stil-Verwaltung (kein `ResourceManager`- + Eintrag für Dächer, anders als Wand/Decke/Tür/Fenster/Treppe). + +### 4.3 Dach-Schichtlogik — konkreter Vorschlag (Kernthema dieses Dokuments) + +Der Vorschlag überträgt exakt das `WallType`/`CeilingType`-Muster: + +``` +export interface RoofType { + id: string; + name: string; + /** Aussen (Eindeckung) → innen (Verkleidung), analog WallType.layers. */ + layers: Layer[]; +} +``` + +Kein neuer Layer-Typ nötig — `Layer` (`types.ts:245`) ist bereits +"Bauteil + Dicke + optionaler Fugen-Linienstil", unabhängig davon ob sie +horizontal (Decke), vertikal (Wand) oder GENEIGT (Dach) gestapelt wird, weil +die Stapel-Richtung beim jeweiligen Renderer entschieden wird, nicht im +Datentyp. Typische Schichtfolge eines Steildachs (Eindeckung → Konterlattung +→ Lattung → Unterdach/Unterdeckbahn → Sparren+Dämmung → Dampfbremse → +Innenverkleidung/GKB) bildet sich 1:1 auf `Layer[]` ab, jede Schicht bekommt +ein `Component` mit eigener Schraffur/Farbe/Material wie bei Wand/Decke. + +`Roof.thickness: number` wird zu `Roof.roofTypeId?: string` (Verweis, analog +`Ceiling.ceilingTypeId`) mit optionaler `thicknessOverride?: number` — exakt +das Muster aus `Ceiling.thickness?` (`types.ts:952-953`, "Optionale +Übersteuerung der Gesamtdicke ... sonst Typ-Dicke"). `Project.roofTypes?: +RoofType[]` ergänzt die Bibliothek. + +**3D-Konsum**: `emitRoofs()` (`toWalls3d.ts:1670`) baut heute EINE +Dreiecksfläche je Dachfläche+Giebel. Mit Layern wird daraus — analog +`emitSlabs()` (`toWalls3d.ts:1352-1419`, das bereits genau diese +Proportional-Stapel-Logik für Decken hat) — ein Stapel PARALLEL versetzter +Flächen entlang der Flächennormalen (nicht entlang Z wie bei der Decke, +sondern entlang der Dachflächen-Normalen `n`, siehe `RoofGeometry.planes` +in `roof.ts:19-21`). Jede Schicht wird zum eigenen `RMesh` mit eigener Farbe/ +Schraffur-Metadaten (`RCutMeta`, wie bei `emitSlabs`). Der Versatz macht +zugleich die Dachdicke sichtbar (heute unendlich dünn) — ein Nebengewinn ohne +Mehraufwand. + +**2D-Konsum (Grundriss/Aufsicht)**: `addRoof()` bekommt eine Poché-Fläche +analog `addCeilingPoche` — Füllung mit der `viewHatchId` der obersten Schicht +(Eindeckungssymbol), gerahmt von den bestehenden Traufe/First/Grat/Knick- +Linien (die bleiben unverändert, sie sind flächen-unabhängig). + +**2D-Konsum (Schnitt, der grössere Umbau)**: `toSection.ts` braucht einen +neuen Roof-Zweig. Ansatz: die Dachebene mit der Schnittebene schneiden +(Ebene-Ebene-Schnitt, da `RoofPlane` eben ist), daraus ein Liniensegment je +betroffener Dachfläche gewinnen, dann `Layer[]` senkrecht ZUR +Dachneigung als Bandsequenz auftragen (wie `resolveWallBands`, +`toWalls3d.ts:521`, aber gedreht um den Neigungswinkel `pitchDeg`) und mit +`splitSlabLayers`-Logik (`toSection.ts:633`) füllen. Das ist der aufwendigste +Einzelposten dieses Dokuments (siehe Prioritätsliste), aber ohne ihn bleibt +"Dach im Schnitt" eine reine Lücke. + +**UI**: Ein `RoofType`-Eintrag im `ResourceManager` +(`src/ui/ResourceManager.tsx`), identisch zum bestehenden Ceiling-Typ-Editor +(Schicht-Liste, Dicke, Bauteil-Zuweisung) — kein neues UI-Paradigma. + +### 4.4 Dach 1:1 — Formen, Kehlen, Gauben (konkreter Vorschlag) + +Reihenfolge nach Aufwand/Nutzen, NICHT alles auf einmal: + +1. **Traufe/Ortgang trennen**: `overhang` → `{ eaves: number; gable: number + }`. Kleine, lokale Änderung in `roof.ts` (zwei statt einer Offset-Variable + je nach Kantentyp), grosser optischer Gewinn (das ist die häufigste + Rückmeldung "sieht nicht echt aus" bei Steildächern mit gleich langem + Überstand allseitig). +2. **Mansard-Untertyp** (`mansardVariant: "walm"|"giebel"|"zelt"`, wie in der + älteren Planung `elements.md:298` bereits vorgesehen, aber nie gebaut): + steuert nur, wie die STIRNSEITE der Mansarde behandelt wird (heute IMMER + `gables` = vertikale Giebelfläche, `roof.ts:200-203`) — bei "walm" wird + daraus eine geneigte Fläche wie beim Walmdach. Mittlerer Aufwand, da die + Mansard-Berechnung (`roof.ts:176-206`) bereits alle Eckpunkte hat, nur die + Gable-Erzeugung muss konditional werden. +3. **Editierbarer Mansard-Knickpunkt** (`kinkDepthRatio?: number` statt hart + `0.4`, `roof.ts:181`) — 0.5 PT, reine Parametrisierung einer bestehenden + Konstante. +4. **Krüppelwalm** (`hipTruncation?: number`, 0 = voller Walm, 1 = voller + Giebel/Sattel): der First bleibt voll lang, nur ein kleines Walmstück am + First-Ende — technisch eine Variation der bestehenden `walm`-Berechnung + (`roof.ts:147-174`, der First-Verkürzungs-Faktor `halfD` wird + parametrisiert statt fix). +5. **Dachflächenfenster** (kein neues Bauteil — ein `Opening`-ähnliches + Element, das in eine Dachfläche statt eine Wand einschneidet): neuer + `hostRoofId`-Pfad, eigenständiger Vorschlag; lohnt sich erst NACH der + Schichtlogik, weil das Fenster sonst nicht "in die Dämmebene" passt. +6. **Gauben** (Schlepp-/Sattelgaube als eigenständiges Sekundär-`Roof` mit + eigenem `outline`/`baseElevation`, das in die Hauptdachfläche einschneidet): + grösster Einzelposten, weil er eine echte Boolean-Verschneidung zwischen + zwei Dachkörpern braucht (ähnlich der bestehenden Wand-Boolean-Dominanz + über `joinPriority`, aber räumlich in 3D). Realistisch erst nach einem + Mesh-Boolean-Werkzeug (die begonnene truck-Integration, + `src-tauri/trucksolid/`, ist ein Kandidat dafür). +7. **L-/T-Grundriss mit Kehle (Straight-Skeleton)**: bewusst NICHT vor 6, + weil es die Bounding-Box-Vereinfachung komplett ersetzt (neue + Geometrie-Engine, kein inkrementeller Ausbau von `roof.ts`) — separates, + grosses Vorhaben, siehe Prioritätsliste. + +### 4.5 Lücken (Dach) + +| Feature | Status | Priorität | Aufwand | +|---|---|---|---| +| `RoofType`/`Layer[]`-Schichtaufbau (Modell) | ✗ (`thickness` toter Skalar) | **P0** | 3 PT | +| 3D-Schichten (gestapelte Flächen entlang Normalen) | ✗ | **P0** | 3 PT | +| 2D-Aufsicht-Poché (Eindeckungssymbol) | ✗ | P1 | 1.5 PT | +| Dach im Vertikalschnitt (Ebene-Ebene-Schnitt + Bänder) | ✗ | **P0** | 5 PT | +| Traufe/Ortgang getrennter Überstand | ✗ | **P0** | 1 PT | +| Mansard-Untertyp (Walm/Giebel/Zelt-Stirn) | ✗ | P1 | 2 PT | +| Editierbarer Mansard-Knick | ✗ | P2 | 0.5 PT | +| Krüppelwalm | ✗ | P2 | 1.5 PT | +| Dachflächenfenster | ✗ | P2 | 4 PT | +| Gauben (Boolean-Einschnitt) | ✗ | P3 | 8+ PT | +| L-/T-Grundriss, Straight-Skeleton-Kehle | ✗ | P3 | 10+ PT | +| `RoofType`-Ressourcen-UI | ✗ | P1 (folgt aus RoofType) | 1 PT | +| IFC `IfcRoof`-Export | ✗ | P2 | 1.5 PT | + +--- + +## 5. Decke (Ceiling / Slab) + +### 5.1 Was ein vollständiges BIM-Tool bietet + +| Bereich | Typische Parameter | +|---|---| +| Grundfläche | beliebiges Polygon inkl. Aussparungen (Treppenauge, Schacht, Kamindurchbruch) | +| Schichtaufbau | Rohdecke, Trittschalldämmung, Estrich, Bodenbelag — analog Wand, mit Deckenspiegel/Untersicht (abgehängte Decke, Akustikplatten) als eigene Schicht(en) | +| Randausbildung | gerader Rand, auskragender Balkon-/Vordachrand mit thermischer Trennung (Isokorb/Randdämmstreifen), Randschalung/Abschalungsprofil, Attika-Anschluss, Tropfkante | +| Deckenspiegel | abgehängte Untersicht mit eigener Höhe/Raster (Akustik-/Gipskarton-Decke), UNABHÄNGIG von der tragenden Rohdecke | +| Öffnungen | Deckenaussparungen als eigene, editierbare Polygone (nicht nur Gesamtumriss) | +| Neigung | geneigte Decke (Garagenrampe, Terrasse mit Gefälle) — nicht nur horizontal | +| 2D-Darstellung | Aufsicht mit Ansichts-Poché (unaufgeschnitten), Schnitt mit Vollschichten je Lage, Deckenspiegel-Plan (reflected ceiling plan) als eigene Zeichnungsart | +| IFC-Rolle | `IfcSlab` (PredefinedType FLOOR/ROOF/BASESLAB), `IfcMaterialLayerSetUsage` für den Schichtaufbau, `IfcCovering` für abgehängte Decken | + +### 5.2 IST in DOSSIER + +`Ceiling` (`types.ts:928-1000`) hat bereits die stärkste Tiefe der vier +Bauteile in diesem Dokument: geschlossenes Umriss-Polygon (`outline`), +`ceilingTypeId` mit Legacy-Fallback auf `wallTypeId` (`getCeilingType`, +`types.ts:2089`), volle Attribut-Override-Kette (`foreground`/`background`/ +`strokeWeight`/`hatchId` + `*Source`, wie bei `Wall`) und unabhängige +vertikale Bindung von OK/UK über `VerticalAnchor` (`top?`/`bottom?`, +`types.ts:990-999` — "floor"-gebunden oder "custom"-Z, exakt wie bei +`Wall.top`/`Wall.bottom`, `types.ts:887-893`). 3D-Schichtstapel ist +implementiert (`emitSlabs`, `toWalls3d.ts:1352-1419`), Schnitt-Schichtsplit +ebenfalls (`splitSlabLayers`, `toSection.ts:633`). + +Verifizierte Lücken: + +- **Keine Aussparungen.** `Ceiling.outline: Vec2[]` ist EIN geschlossenes + Polygon (`types.ts:936-939`) — kein `openings?: Vec2[][]` für + Treppenauge/Schacht/Kamin. Ein Treppenloch in der Decke muss heute über + die Aussenkontur der Decke "herumgeschnitten" werden (Decke als + komplexes, nicht-konvexes Polygon), nicht als saubere Innenaussparung. + (`elements.md:217` sah dieses Feld in der älteren Planung explizit vor, + es wurde nie in `types.ts` übernommen.) +- **Kein Randdetail.** Die Decke ist über die gesamte `outline` exakt + `thickness` dick, EINHEITLICH. Es gibt kein Feld für eine abweichende + Randausbildung (Aufkantung, Randdämmstreifen, Tropfkante, andere Dicke am + Balkonrand). Ein auskragender Balkon lässt sich zwar über eine erweiterte + `outline` modellieren, bekommt aber zwangsläufig denselben Vollschicht- + Aufbau wie die Innendecke — eine thermisch getrennte Balkonplatte + (Isokorb) ist nicht abbildbar. +- **Kein Deckenspiegel.** Abgehängte Untersicht (Akustik-/GKB-Decke mit + eigener, tieferer Kote) existiert nicht als eigenes Konzept — nur der + tragende Aufbau über `ceilingTypeId`. + Ein "Deckenspiegel-Plan" (reflected ceiling plan) fehlt als Zeichnungsart + komplett (`DrawingLevelKind`, `types.ts:722`, kennt nur "floor"/"section"/ + "elevation"/"drawing"). + (Randbemerkung: Beleuchtungsplanung/Deckenspiegel ist ein Elektro-Thema und + damit bewusst ausserhalb des DOSSIER-Kernscopes — siehe "nicht bauen", + Abschnitt 6. Die reine Geometrie einer zweiten, tiefer liegenden Fläche + bleibt aber ein legitimer BIM-1:1-Punkt.) +- **Keine Neigung.** `top`/`bottom` sind je EIN `VerticalAnchor` (ein + Z-Wert), keine Neigungsebene — eine geneigte Garagen-/Terrassendecke ist + nicht modellierbar, nur über mehrere ebene Teildecken behelfsweise + annäherbar. +- **2D-Aufsicht nutzt nur die erste Schicht.** `addCeilingPoche` + (`generatePlan.ts:2453-2536`) liest `wt.layers[0]` (Kommentar/Code + `generatePlan.ts:2465`) für die Ansichts-Schraffur — bei einer + mehrschichtigen Decke (z. B. Beton unten, Dämmung oben) zeigt die Aufsicht + immer nur die OBERSTE (erste) Schicht, was für eine unaufgeschnittene + Draufsicht baupraktisch korrekt ist (man sieht von unten die + Untersicht/erste Lage), aber nicht konfigurierbar ist, welche Lage als + "sichtbare" gilt, falls der Deckenaufbau umgekehrt sortiert wäre. +- IFC: `IfcSlab` wird erzeugt (`exportIfc.ts:28`), aber laut Kopfkommentar + (`exportIfc.ts:38-41`) bewusst OHNE `IfcMaterialLayerSet`/-`Usage` — der + Export verliert den Schichtaufbau, den DOSSIER intern bereits hat. + +### 5.3 Deckenrand/Randterminierung — vertieft + +Der Nutzer nennt explizit "Deckenränder, Stirnabschlüsse, Anschluss an Wand/ +Aussenkante, auskragende Ränder, Randabschalung" als Schwerpunkt. IST-Bild: +keines davon existiert als eigenes Konzept — die Decke ist ein reines +Extrusions-Polygon. Konkreter Vorschlag, dreistufig nach Aufwand: + +1. **Aussparungen** (`Ceiling.openings?: Vec2[][]`) — niedrigster Aufwand, + grösster praktischer Nutzen (Treppenauge ist im Wohnbau der Regelfall, + nicht die Ausnahme). 2D: zusätzliche Ausschnitts-Polygone in + `addCeilingPoche` (Loch im Fill, zusätzliche Randlinien). 3D: `emitSlabs` + bekommt Löcher im Extrusions-Profil (analog dem bereits vorhandenen + Loch-Schnitt bei Wand-Öffnungen, `wallMeshCut.ts`, als Vorlage). +2. **Randschicht-Override** (`Ceiling.edgeOverride?: { ringOffset: number; + ceilingTypeId: string }` — ein schmaler Innenring der Decke entlang des + Randes bekommt einen ANDEREN Layer-Aufbau, z. B. mit zusätzlicher + Randdämmschicht oder reduzierter Dicke für eine Tropfkante). Technisch: + `emitSlabs` erzeugt für den Ringbereich einen zweiten Layer-Stapel mit dem + Override-Typ, geometrisch als Offset-Polygon-Differenz (`outline` minus + `outline.offset(-ringOffset)`), eine Operation, die für Wandbänder + bereits ähnlich existiert (`buildWallFootprints`). +3. **Thermisch getrennte Auskragung (Isokorb-Fall)**: ein eigenes, + sekundäres `Ceiling`-Objekt für den auskragenden Teil mit eigenem + `ceilingTypeId` (dünnerer/anderer Aufbau) UND eigener `top`/`bottom`- + Bindung, das an die Hauptdecke stösst — kein neues Feld nötig, nur eine + UI-Erleichterung ("Deckenrand abtrennen"-Werkzeug, das die Decke entlang + einer gewählten Kante in zwei `Ceiling`-Objekte teilt). Niedrigster + Modell-Aufwand, weil er das bestehende Mehrfach-Decken-Prinzip nutzt statt + ein neues Konzept einzuführen. + +### 5.4 Lücken (Decke) + +| Feature | Status | Priorität | Aufwand | +|---|---|---|---| +| Aussparungen (`openings?: Vec2[][]`) in 2D+3D | ✗ | **P0** | 3 PT | +| Randschicht-Override (Ringzone anderer Aufbau) | ✗ | P1 | 3 PT | +| Deckentrenn-Werkzeug für Isokorb-Fall (UI, kein neues Modellfeld) | ✗ | P1 | 1.5 PT | +| Geneigte Decke (Rampe/Gefälle) | ✗ | P2 | 3 PT | +| Deckenspiegel (zweite, abgehängte Fläche) | ✗ | P3 | 2 PT (reine Geometrie) | +| IFC `IfcMaterialLayerSetUsage` für Decke (UND Wand) | ~ (bewusst ausgelassen) | P2 | 2 PT | +| Konfigurierbare "oberste Schicht" für Aufsicht-Poché | ✓ implizit (Layer-Reihenfolge = Sortierung) | — | — | + +--- + +## 6. Konsolidierte Priorisierung (über alle vier Bauteile) + +Sortiert nach "1:1-Zuwachs pro Aufwand", nicht nach Aufwand allein: + +1. **Dach-Schichtaufbau (Modell + 3D-Stapel)** — schliesst die grösste + strukturelle Lücke (totes `thickness`-Feld, kein `RoofType`) und liefert + sofort sichtbaren Tiefengewinn im 3D (§4.3, ~6 PT gesamt). +2. **Traufe/Ortgang getrennter Überstand** — 1 PT, sofortiger optischer + Sprung bei jedem Steildach-Projekt (§4.4 Punkt 1). +3. **Zweiflügelige Tür rendert wirklich 2 Blätter** — das `leafCount`-Feld + existiert seit der Türtyp-Einführung, wird aber komplett ignoriert; sehr + sichtbarer Bug-artiger Gap (§2.3, 2 PT). +4. **Deckenaussparungen** — Treppenauge ist der Wohnbau-Regelfall, heute nur + über Umweg (nicht-konvexes Aussenpolygon) lösbar (§5.3 Punkt 1, 3 PT). +5. **Fenster-Glazing 2D-wirksam** — seit über einem Jahr als P0 in der + Fenster-Studie dokumentiert und weiterhin offen; niedriger Aufwand, + sollte nicht liegen bleiben (§3.1, 1 PT). +6. **Dach im Vertikalschnitt** — grösster Einzelposten (5 PT), aber ohne ihn + bleibt jeder Gebäudeschnitt mit Steildach unvollständig; das ist die + Art Lücke, die bei einer Bemusterung/Baueingabe sofort auffällt. +7. **Deckenrand-Override / Isokorb-Trennwerkzeug** — folgt danach, weil er + auf demselben Mehrfach-Decken-Prinzip aufbaut wie Punkt 4. +8. **Mansard-Untertyp + editierbarer Knick** — mittlere Priorität, weil + Mansarde in der Schweiz/Süddeutschland baupraktisch häufig ist und die + heutige starre 40 %-Konstante sichtbar unrealistisch wirkt. +9. **Tür/Fenster-Rahmentiefe** (asymmetrische Rahmenbreiten, Beschlag, + Kopfform) — bewusst NACH den strukturellen Lücken, weil sie additive + Detailverbesserungen an einem bereits funktionierenden Pfad sind, während + 1–7 fehlende oder falsch dargestellte Kernfunktionen betreffen. +10. **Gauben, L-Grundriss/Kehle, Dachflächenfenster** — grösste Einzel- + Aufwände (8–10+ PT), architektonisch am voraussetzungsreichsten (Boolean- + Werkzeug bzw. neue Geometrie-Engine); erst nach 1–9 angehen. + +### 6.1 NICHT bauen (VW/Revit-Ballast ohne Nutzen für DOSSIER) + +- **Vollständiger Massketten-/Bezugsapparat** (VW B1..B5/H1..H7, + Roh-/Fertigmass-Umschaltung) — DOSSIER arbeitet mit lichten Massen, das + genügt für ein Schweizer Wohnbau-/Kleinprojekt-Tool (bereits so in + `window-editor-vectorworks-study.md` §5 entschieden, hier bestätigt für + Dach/Decke: keine Dach-Rohmass-/Fertigmass-Unterscheidung). +- **Sichtbarkeitsmatrix 3D-Objekte × Ansichten** (Augen-Tabelle je + Kategorie×Ansicht×Detailstufe) — DOSSIERs Layer-Sichtbarkeit + + `DetailLevel` deckt den praktischen Bedarf; eine volle Matrix ist + Verwaltungsaufwand ohne Mehrwert für Einzelprojekte. +- **Eckfenster/Eckdach als generischer Sonderfall über zwei Wirtsbauteile** + — seltene Geometrie, hoher Modellierungsaufwand (zwei Hosts, ein Element); + bei Bedarf als manueller Workaround (zwei separate Öffnungen) lösbar. + Ebenso: freie Neigungsflächen je Dachkante (VW erlaubt jede Kante einzeln + zu kippen) — für die abgedeckten Standardformen (Pult/Sattel/Walm/ + Mansarde/Zelt/Krüppelwalm) nicht nötig; wer eine Freiform-Dachlandschaft + braucht, ist besser mit den `ExtrudedSolid`/truck-Werkzeugen bedient. +- **Vollständige Beschlags-/Baubeschlag-Bibliothek** (Marken-Beschlagsätze, + Schliessplan) — Beschlag als generisches Griff-Mesh (§2.4) genügt für die + visuelle 1:1-Wirkung; eine Beschlags-PRODUKTBIBLIOTHEK ist Kataloggeschäft, + kein CAD-Kernfeature. +- **Deckenspiegel als vollwertige Beleuchtungsplanung** (Leuchtenraster, + Lichtberechnung) — reine Geometrie einer zweiten Fläche ist ok (P3), die + Elektro-/Lichtplanungslogik selbst liegt ausserhalb des Tool-Zwecks. +- **IFC `IfcOpeningElement`/Void-Semantik nachrüsten** — bewusste + Design-Entscheidung im bestehenden Export (`exportIfc.ts:22-27`), NICHT + revidieren: die heutige "Loch steckt im Mesh"-Lösung liefert visuelle + Parität in jedem Viewer ohne Boolean-Pflicht beim Empfänger; der reine + IFC4-Purismus (Wand als parametrische Extrusion + Void) würde + bestehende, bewusst getroffene Trade-offs zunichtemachen. +- **Straight-Skeleton/Kehlen und Gauben SOFORT** — nicht "nicht bauen", aber + bewusst zurückgestellt (§6, Punkt 10): ohne die Schichtlogik (Punkt 1) + vorher zu bauen, würde jede Kehlen-/Gauben-Lösung auf dem unendlich dünnen, + ungeschichteten Dach aufsetzen und müsste bei Einführung der Schichten + ohnehin neu gefasst werden.