Files
DOSSIER-STANDALONE/docs/design/bim-elements-depth-study.md
T

37 KiB
Raw Blame History

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 P0P3-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 17 fehlende oder falsch dargestellte Kernfunktionen betreffen.
  10. Gauben, L-Grundriss/Kehle, Dachflächenfenster — grösste Einzel- Aufwände (810+ PT), architektonisch am voraussetzungsreichsten (Boolean- Werkzeug bzw. neue Geometrie-Engine); erst nach 19 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.