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:
@@ -734,11 +734,7 @@ export function createProjectSlice(
|
||||
setProject((p) => mapCeiling(p, id, (c) => ({ ...c, ...patch }))),
|
||||
|
||||
setCeilingThickness: (ceilingId, thickness) =>
|
||||
setProject((p) =>
|
||||
!isFinite(thickness) || thickness <= 0
|
||||
? p
|
||||
: mapCeiling(p, ceilingId, (c) => ({ ...c, thickness })),
|
||||
),
|
||||
setProject((p) => setCeilingThickness(p, ceilingId, thickness)),
|
||||
|
||||
// ── Öffnungs-Editieren ────────────────────────────────────────────────
|
||||
updateOpening: (id, patch) =>
|
||||
@@ -914,6 +910,61 @@ function setWallThickness(
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt die Gesamtdicke einer einschichtigen Decke über ihre Deckentyp-Schicht
|
||||
* — analog `setWallThickness`. Wenn der aktive Aufbau-Typ einschichtig UND ein
|
||||
* DEDIZIERTER Deckentyp (`ceilingTypeId`) ist, der nur von dieser Decke genutzt
|
||||
* wird, wird er direkt editiert. Sonst wird ein neuer, dedizierter
|
||||
* einschichtiger Deckentyp (Klon der ersten Schicht des aktuellen Aufbaus)
|
||||
* erzeugt und der Decke zugewiesen. Der geteilte LEGACY-Wandtyp
|
||||
* (`Ceiling.wallTypeId`) wird dabei NIE mutiert — er gehört den Wänden.
|
||||
*/
|
||||
function setCeilingThickness(
|
||||
project: Project,
|
||||
ceilingId: string,
|
||||
thickness: number,
|
||||
): Project {
|
||||
if (!isFinite(thickness) || thickness <= 0) return project;
|
||||
const ceiling = (project.ceilings ?? []).find((c) => c.id === ceilingId);
|
||||
if (!ceiling) return project;
|
||||
const activeId = ceiling.ceilingTypeId ?? ceiling.wallTypeId;
|
||||
const ct =
|
||||
(project.ceilingTypes ?? []).find((t) => t.id === ceiling.ceilingTypeId) ??
|
||||
project.wallTypes.find((t) => t.id === ceiling.wallTypeId);
|
||||
if (!ct || ct.layers.length === 0) return project;
|
||||
|
||||
const single = ct.layers.length === 1;
|
||||
const usedByOthers = (project.ceilings ?? []).some(
|
||||
(c) => c.id !== ceilingId && (c.ceilingTypeId ?? c.wallTypeId) === activeId,
|
||||
);
|
||||
|
||||
if (single && !usedByOthers && ceiling.ceilingTypeId) {
|
||||
// Direkt die Schichtdicke des (exklusiven, einschichtigen) Deckentyps setzen.
|
||||
return {
|
||||
...project,
|
||||
ceilingTypes: (project.ceilingTypes ?? []).map((t) =>
|
||||
t.id === ct.id ? { ...t, layers: [{ ...t.layers[0], thickness }] } : t,
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
// Dedizierten einschichtigen Deckentyp erzeugen (erste Schicht klonen) und
|
||||
// der Decke zuweisen — damit die Dicke nur diese Decke betrifft.
|
||||
const id = `ct-${Date.now()}`;
|
||||
const clone = {
|
||||
id,
|
||||
name: t("default.ceilingTypeSingle", { thickness: thickness.toFixed(2) }),
|
||||
layers: [{ ...ct.layers[0], thickness }],
|
||||
};
|
||||
return {
|
||||
...project,
|
||||
ceilingTypes: [...(project.ceilingTypes ?? []), clone],
|
||||
ceilings: (project.ceilings ?? []).map((c) =>
|
||||
c.id === ceilingId ? { ...c, ceilingTypeId: id, thickness: undefined } : c,
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
// ── Resize (Skalierung auf Zielmaß um einen Anker) ───────────────────────────
|
||||
|
||||
/**
|
||||
|
||||
@@ -94,15 +94,16 @@ export interface WallInfo {
|
||||
* einer Decke gesetzt). Anzeigefertige Werte + Listen für die Dropdowns.
|
||||
*/
|
||||
export interface CeilingInfo {
|
||||
wallTypeId: string;
|
||||
/** Effektiv aktiver Aufbau-Typ: `ceilingTypeId`, sonst LEGACY-`wallTypeId`. */
|
||||
typeId: string;
|
||||
/** Aktuelle Gesamtdicke (Meter). */
|
||||
thickness: number;
|
||||
/** Ob der aktuelle Aufbau-Typ einschichtig ist (1 Schicht). */
|
||||
singleLayer: boolean;
|
||||
/** Grundfläche der Decke (m²). */
|
||||
area: number;
|
||||
/** Verfügbare Aufbau-Typ-Presets (wie WallType). */
|
||||
wallTypes: WallTypeChoice[];
|
||||
/** Verfügbare Deckentyp-Presets (dediziert, `project.ceilingTypes`). */
|
||||
ceilingTypes: WallTypeChoice[];
|
||||
/** Geschoss, dem die Decke zugeordnet ist. */
|
||||
floorId: string;
|
||||
floorName: string;
|
||||
@@ -358,11 +359,11 @@ function ceilingSelection(project: Project, ceiling: Ceiling): Selection {
|
||||
const floor = project.drawingLevels.find((z) => z.id === ceiling.floorId);
|
||||
const { zBottom, zTop } = ceilingVerticalExtent(project, ceiling);
|
||||
const ceilingInfo: CeilingInfo = {
|
||||
wallTypeId: ceiling.wallTypeId,
|
||||
typeId: ceiling.ceilingTypeId ?? ceiling.wallTypeId,
|
||||
thickness,
|
||||
singleLayer: wt.layers.length <= 1,
|
||||
area: ceilingArea(ceiling.outline),
|
||||
wallTypes: project.wallTypes.map((t) => ({
|
||||
ceilingTypes: (project.ceilingTypes ?? []).map((t) => ({
|
||||
id: t.id,
|
||||
name: t.name,
|
||||
thickness: wallTypeThickness(t),
|
||||
|
||||
Reference in New Issue
Block a user