37 KiB
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) undCeilingType(types.ts:273) sind BEIDE nur{ id, name, layers: Layer[] }— bewusst derselbe Typ, "das horizontale Gegenstück zum WallType" (Kommentartypes.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.leafCountwird an keiner Stelle ingeneratePlan.tsgelesen (kein Treffer fürleafCountim 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 hartwingCount: 1, unabhängig vonleafCount. leafStylewirkt 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 keinframeKind).thresholdsteuerthasSillim 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-RendereraddDoorSymbol(generatePlan.ts:1840-1899) — strukturell identisch zumOpening-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/heightsind ein reines Rechteck,wallGaps/buildWallFootprints(generatePlan.ts:1363-1457) schneiden nur rechteckige Bänder aus der Wand-Poché. - IFC-Export:
IfcDoorwird erzeugt (src/export/exportIfc.ts:30-31), aber als reine Box-Geometrie ohneIfcDoorType/PredefinedTypeund ohneIfcOpeningElement-Void (bewusste Design-Entscheidung, siehe KommentarexportIfc.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 vonglassPanesForOpeningintoWalls3d.tskonsumiert, aber die Studie selbst vermerkt (Zeile 61-65 dort), dass der 2D-Pfad die Scheibenzahl weiterhin allein ausDetailLevelableitet, nicht ausglazingPanes. 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ürsillBoardintoWalls3d.tsodergeneratePlan.tsausserhalb 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"übertoWalls3d.ts/generatePlan.ts/roof.tsliefert 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: nurplane.pts/gable-Fans, EINE FarbeROOF_RGBbzw.roof.color, keine Dicke, keine Materialschichten). - Kein
RoofType.ProjecthatwallTypes,ceilingTypes?,doorTypes?,windowTypes?,stairTypes?(types.ts:1936-1958), aber keinroofTypes?. 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ärkeROOF_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.tshat KEINE Roof-Behandlung (kein Treffer fürroof/Roofim 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.tserzeugtIfcWall,IfcSlab,IfcDoor/IfcWindow,IfcStair,IfcBuildingElementProxy(KommentarexportIfc.ts:18-36) —Roof/IfcRoofist 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 inObjectInfoPanel.tsx:549erwä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-561bietet volle Instanz-Bearbeitung (shape/ridgeAxis/pitch/pitchUpper/width/depth/overhang/thickness/ baseElevation), aber keine Typ-/Stil-Verwaltung (keinResourceManager- 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:
- Traufe/Ortgang trennen:
overhang→{ eaves: number; gable: number }. Kleine, lokale Änderung inroof.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). - Mansard-Untertyp (
mansardVariant: "walm"|"giebel"|"zelt", wie in der älteren Planungelements.md:298bereits vorgesehen, aber nie gebaut): steuert nur, wie die STIRNSEITE der Mansarde behandelt wird (heute IMMERgables= 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. - Editierbarer Mansard-Knickpunkt (
kinkDepthRatio?: numberstatt hart0.4,roof.ts:181) — 0.5 PT, reine Parametrisierung einer bestehenden Konstante. - 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 bestehendenwalm-Berechnung (roof.ts:147-174, der First-Verkürzungs-FaktorhalfDwird parametrisiert statt fix). - Dachflächenfenster (kein neues Bauteil — ein
Opening-ähnliches Element, das in eine Dachfläche statt eine Wand einschneidet): neuerhostRoofId-Pfad, eigenständiger Vorschlag; lohnt sich erst NACH der Schichtlogik, weil das Fenster sonst nicht "in die Dämmebene" passt. - Gauben (Schlepp-/Sattelgaube als eigenständiges Sekundär-
Roofmit eigenemoutline/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 überjoinPriority, aber räumlich in 3D). Realistisch erst nach einem Mesh-Boolean-Werkzeug (die begonnene truck-Integration,src-tauri/trucksolid/, ist ein Kandidat dafür). - 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) — keinopenings?: 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:217sah dieses Feld in der älteren Planung explizit vor, es wurde nie intypes.tsübernommen.) - Kein Randdetail. Die Decke ist über die gesamte
outlineexaktthicknessdick, 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 erweiterteoutlinemodellieren, 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/bottomsind je EINVerticalAnchor(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) liestwt.layers[0](Kommentar/CodegeneratePlan.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:
IfcSlabwird erzeugt (exportIfc.ts:28), aber laut Kopfkommentar (exportIfc.ts:38-41) bewusst OHNEIfcMaterialLayerSet/-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:
- Aussparungen (
Ceiling.openings?: Vec2[][]) — niedrigster Aufwand, grösster praktischer Nutzen (Treppenauge ist im Wohnbau der Regelfall, nicht die Ausnahme). 2D: zusätzliche Ausschnitts-Polygone inaddCeilingPoche(Loch im Fill, zusätzliche Randlinien). 3D:emitSlabsbekommt Löcher im Extrusions-Profil (analog dem bereits vorhandenen Loch-Schnitt bei Wand-Öffnungen,wallMeshCut.ts, als Vorlage). - 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:emitSlabserzeugt für den Ringbereich einen zweiten Layer-Stapel mit dem Override-Typ, geometrisch als Offset-Polygon-Differenz (outlineminusoutline.offset(-ringOffset)), eine Operation, die für Wandbänder bereits ähnlich existiert (buildWallFootprints). - Thermisch getrennte Auskragung (Isokorb-Fall): ein eigenes,
sekundäres
Ceiling-Objekt für den auskragenden Teil mit eigenemceilingTypeId(dünnerer/anderer Aufbau) UND eigenertop/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 zweiCeiling-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:
- Dach-Schichtaufbau (Modell + 3D-Stapel) — schliesst die grösste
strukturelle Lücke (totes
thickness-Feld, keinRoofType) und liefert sofort sichtbaren Tiefengewinn im 3D (§4.3, ~6 PT gesamt). - Traufe/Ortgang getrennter Überstand — 1 PT, sofortiger optischer Sprung bei jedem Steildach-Projekt (§4.4 Punkt 1).
- 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). - Deckenaussparungen — Treppenauge ist der Wohnbau-Regelfall, heute nur über Umweg (nicht-konvexes Aussenpolygon) lösbar (§5.3 Punkt 1, 3 PT).
- 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).
- 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.
- Deckenrand-Override / Isokorb-Trennwerkzeug — folgt danach, weil er auf demselben Mehrfach-Decken-Prinzip aufbaut wie Punkt 4.
- 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.
- 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.
- 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 +
DetailLeveldeckt 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.