Deckenstile: solide oder mehrschichtige Decke

Analog zu den Wandstilen erhalten Decken jetzt einen eigenen
Deckentyp mit Schichtaufbau (CeilingType, ceilingTypeId). Der
Schichtaufbau erscheint nur im Schnitt als gestapelte Bänder von OK
bis UK; der Grundriss bleibt eine flächige Poché wie bisher, da die
Schichtung von oben ohnehin nicht sichtbar ist. Auswahl solide/
mehrschichtig im Objektinfo-Panel wie bei Wänden, neuer
"Deckenstile"-Tab im Ressourcen-Manager mit Fugenlinien je Schicht.
This commit is contained in:
2026-07-03 22:09:02 +02:00
parent d65d84183a
commit fae4f6fcb6
13 changed files with 341 additions and 45 deletions
+23 -3
View File
@@ -122,6 +122,8 @@ export const sampleProject: Project = {
{ id: "render-int", name: "Innenputz", color: "#efece6", hatchId: "none", joinPriority: 10 },
// Für spätere T-Stöße: Beton als durchlaufender Backbone (höchste Priorität).
{ id: "concrete", name: "Beton", color: "#9aa0a6", hatchId: "sia-concrete", joinPriority: 100 },
// Zementestrich — oberste Schicht des mehrschichtigen Deckenaufbaus (Decken-Stile).
{ id: "screed", name: "Zementestrich", color: "#c9c2b3", hatchId: "diagonal", joinPriority: 30 },
],
wallTypes: [
{
@@ -137,6 +139,22 @@ export const sampleProject: Project = {
],
},
],
// Deckenstile (Decken-Aufbau-Typen) — das liegende Gegenstück der Wandstile.
// Schichten oben (OK) → unten (UK), analog zur Wand außen → innen.
ceilingTypes: [
{
id: "dg-massiv",
name: "Geschossdecke mehrschichtig",
layers: [
// Estrich (schwimmend) → Trittschalldämmung.
{ componentId: "screed", thickness: 0.06 },
// Innere Fuge der Dämmung trifft auf die Betondecke (massiv) → 0.13 mm.
{ componentId: "insulation", thickness: 0.04, jointLineStyleId: "joint-massive" },
// Betondecke (Rohdecke, tragend) — innerste/unterste Schicht.
{ componentId: "concrete", thickness: 0.2 },
],
},
],
// Oberste Schnitte: Geschosse + Schnitt/Ansicht + freie Zeichnung.
// baseElevation wird über recomputeFloorElevations gestapelt: EG=0, OG=2.6.
drawingLevels: recomputeFloorElevations([
@@ -246,8 +264,10 @@ export const sampleProject: Project = {
},
],
// Decken (Slabs) — Geschossdecke über dem EG (= Boden des OG). Umriss = EG-
// Grundriss (5 × 4 m). Kategorie „30 Decken", 25 cm dick, OK bündig mit dem
// EG-Wandkopf (baseElevation + floorHeight = 2.6 m).
// Grundriss (5 × 4 m). Kategorie „30 Decken", mehrschichtiger Deckenstil
// „dg-massiv" (Estrich + Trittschalldämmung + Betondecke, 30 cm), OK bündig
// mit dem EG-Wandkopf (baseElevation + floorHeight = 2.6 m). `wallTypeId`
// bleibt als LEGACY-Rückfall gesetzt (siehe `getCeilingType`).
ceilings: [
{
id: "C1",
@@ -261,7 +281,7 @@ export const sampleProject: Project = {
{ x: 0, y: 4 },
],
wallTypeId: "aw",
thickness: 0.25,
ceilingTypeId: "dg-massiv",
},
],
// Treppen — eine gerade Beispieltreppe im EG entlang der Ostwand, steigt ins OG
+51 -7
View File
@@ -144,6 +144,19 @@ export interface WallType {
layers: Layer[];
}
/**
* Ein Deckentyp (Deckenstil) = geordneter Schichtaufbau EINER Decke, liegend
* gestapelt (oben → unten) — das horizontale Gegenstück zum `WallType`. Nutzt
* denselben `Layer`-Typ (Bauteil + Dicke + optionaler Schichtfugen-Linienstil),
* damit Fuge/Schraffur-Auflösung identisch zur Wand bleiben. Eine „einschichtige"
* Decke (SOLID) ist einfach ein Deckentyp mit genau einer Schicht.
*/
export interface CeilingType {
id: string;
name: string;
layers: Layer[];
}
// ── Parametrische Wände (Parametric Walls) ────────────────────────────────
// Parametrische Wand-Regeln generieren automatisch Wall[]-Arrays — analog zu
// FreeCAD BIM. Sie leben in Project.resources.parametricWalls[] und werden
@@ -462,8 +475,18 @@ export interface Ceiling {
* dupliziert (die letzte Kante läuft von outline[n-1] zu outline[0]).
*/
outline: Vec2[];
/** Verweis auf den (mehrschichtigen) Aufbau-Typ (wie WallType). */
/**
* LEGACY-Verweis auf einen Aufbau-Typ aus `wallTypes` (Rückwärtskompatibilität
* für Projekte von vor den dedizierten Deckenstilen). Nur wirksam, wenn
* `ceilingTypeId` fehlt.
*/
wallTypeId: string;
/**
* Verweis auf einen dedizierten Deckentyp (Deckenstil) aus `ceilingTypes` —
* der reguläre Weg für SOLID (1 Schicht) und MEHRSCHICHTIG (>1 Schicht). Hat
* Vorrang vor `wallTypeId`, falls gesetzt und im Projekt auflösbar.
*/
ceilingTypeId?: string;
/** Optionale Übersteuerung der Gesamtdicke in Metern (sonst Typ-Dicke). */
thickness?: number;
/**
@@ -845,6 +868,13 @@ export interface Project {
/** Bauteil-Material-Bibliothek (Component Manager). */
components: Component[];
wallTypes: WallType[];
/**
* Deckentypen (Deckenstile) — dediziert für Decken, analog `wallTypes`.
* Optional, damit bestehende Projekte/Tests ohne `ceilingTypes` gültig
* bleiben; Decken ohne `ceilingTypeId` lösen weiterhin über das LEGACY-Feld
* `Ceiling.wallTypeId` gegen `wallTypes` auf (siehe `getCeilingType`).
*/
ceilingTypes?: CeilingType[];
/** Oberste Schnitte: Geschosse + Schnitte/Ansichten. */
drawingLevels: DrawingLevel[];
/** Grafik-Kategorie-Baum (geschossübergreifend). */
@@ -898,21 +928,35 @@ export const getWallType = (project: Project, wall: Wall): WallType => {
return wt;
};
/** Liefert den Aufbau-Typ (WallType) einer Decke oder wirft. */
export const getCeilingType = (project: Project, ceiling: Ceiling): WallType => {
/**
* Liefert den Aufbau-Typ einer Decke oder wirft. Bevorzugt den dedizierten
* Deckentyp (`ceilingTypeId` → `ceilingTypes`); fehlt er, fällt die Auflösung
* auf das LEGACY-Feld `wallTypeId` → `wallTypes` zurück (Rückwärtskompatibilität
* mit Projekten von vor den Deckenstilen — dort trug die Decke ihren Aufbau
* direkt über einen WallType).
*/
export const getCeilingType = (project: Project, ceiling: Ceiling): CeilingType | WallType => {
if (ceiling.ceilingTypeId) {
const ct = (project.ceilingTypes ?? []).find((t) => t.id === ceiling.ceilingTypeId);
if (ct) return ct;
}
const wt = project.wallTypes.find((t) => t.id === ceiling.wallTypeId);
if (!wt) throw new Error(`Unbekannter Deckentyp: ${ceiling.wallTypeId}`);
if (!wt) throw new Error(`Unbekannter Deckentyp: ${ceiling.ceilingTypeId ?? ceiling.wallTypeId}`);
return wt;
};
/**
* Gesamtdicke einer Decke (Meter): eine explizite `thickness`-Übersteuerung hat
* Vorrang, sonst die Summe der Schichtdicken ihres Aufbau-Typs.
* Vorrang, sonst die Summe der Schichtdicken ihres Aufbau-Typs (siehe
* `getCeilingType`).
*/
export const ceilingThickness = (project: Project, ceiling: Ceiling): number => {
if (ceiling.thickness != null && ceiling.thickness > 0) return ceiling.thickness;
const wt = project.wallTypes.find((t) => t.id === ceiling.wallTypeId);
return wt ? wallTypeThickness(wt) : 0.2;
try {
return wallTypeThickness(getCeilingType(project, ceiling));
} catch {
return 0.2;
}
};
/** Alle Öffnungen einer Wand (leere Liste, wenn keine oder `openings` fehlt). */