From 83dcdd0501669008e584878b83faeffe6a364a50 Mon Sep 17 00:00:00 2001 From: Karim Date: Fri, 10 Jul 2026 18:44:13 +0200 Subject: [PATCH] Decken-Panel: Aussparungen anzeigen + einzeln entfernen MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Die Decken-Sektion listet die Aussparungen (BBox-Masse je Loch) mit Entfernen-Knopf; Anlegen über den Befehl 'Deckenloch'. CeilingInfo.openings, host.onRemoveCeilingOpening + App-Routing. 684/684 grün. --- src/App.tsx | 8 ++++++++ src/i18n/de.ts | 2 ++ src/i18n/en.ts | 2 ++ src/panels/ObjectInfoPanel.tsx | 27 +++++++++++++++++++++++++++ src/panels/host.ts | 2 ++ src/state/selectionInfo.ts | 7 +++++++ 6 files changed, 48 insertions(+) diff --git a/src/App.tsx b/src/App.tsx index 89709b7..977fc6a 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -3238,6 +3238,14 @@ export default function App() { if (selection?.kind === "ceiling") setCeilingThickness(selection.id, thickness); }, + onRemoveCeilingOpening: (index) => { + if (selection?.kind !== "ceiling") return; + const c = (project.ceilings ?? []).find((x) => x.id === selection.id); + if (!c?.openings || index < 0 || index >= c.openings.length) return; + updateCeiling(selection.id, { + openings: c.openings.filter((_, i) => i !== index), + }); + }, onSetCeilingTop: (anchor) => { if (selection?.kind === "ceiling") updateCeiling(selection.id, { top: anchor ?? undefined }); diff --git a/src/i18n/de.ts b/src/i18n/de.ts index 18394c6..438c61b 100644 --- a/src/i18n/de.ts +++ b/src/i18n/de.ts @@ -366,6 +366,8 @@ export const de = { "objinfo.ceiling.top": "Oberkante (OK)", "objinfo.ceiling.bottom": "Unterkante (UK)", "objinfo.ceiling.height": "Dicke (OK−UK)", + "objinfo.ceiling.openings": "Aussparungen", + "objinfo.ceiling.removeOpening": "Aussparung entfernen", "objinfo.ceiling.area": "Fläche", "objinfo.ceiling.anchorFloor": "Gebunden", "objinfo.ceiling.anchorCustom": "Eigene", diff --git a/src/i18n/en.ts b/src/i18n/en.ts index 002de2a..c0b65c3 100644 --- a/src/i18n/en.ts +++ b/src/i18n/en.ts @@ -366,6 +366,8 @@ export const en: Record = { "objinfo.ceiling.top": "Top (OK)", "objinfo.ceiling.bottom": "Bottom (UK)", "objinfo.ceiling.height": "Thickness (OK−UK)", + "objinfo.ceiling.openings": "Openings", + "objinfo.ceiling.removeOpening": "Remove opening", "objinfo.ceiling.area": "Area", "objinfo.ceiling.anchorFloor": "Bound", "objinfo.ceiling.anchorCustom": "Custom", diff --git a/src/panels/ObjectInfoPanel.tsx b/src/panels/ObjectInfoPanel.tsx index f6cdf09..5ffacd0 100644 --- a/src/panels/ObjectInfoPanel.tsx +++ b/src/panels/ObjectInfoPanel.tsx @@ -1050,6 +1050,33 @@ export function CeilingSection({ {ceiling.volume.toFixed(2)} m³ + {/* Aussparungen (Treppenauge/Schacht) — Liste mit Entfernen je Loch. + Anlegen über den Befehl „Deckenloch" (BIM-Ribbon). */} + {ceiling.openings.length > 0 && ( + <> +
+ {t("objinfo.ceiling.openings")} + {ceiling.openings.length} +
+ {ceiling.openings.map((o, i) => ( +
+ + {`${i + 1}: ${o.width.toFixed(2)} × ${o.depth.toFixed(2)} m`} + + +
+ ))} + + )} +
{/* OK der Decke: an Geschoss gebunden ODER eigene Höhe. */} diff --git a/src/panels/host.ts b/src/panels/host.ts index fd7423a..e5b046b 100644 --- a/src/panels/host.ts +++ b/src/panels/host.ts @@ -275,6 +275,8 @@ export interface PanelHostValue { onSetCeilingType: (ceilingTypeId: string) => void; /** Setzt die Gesamtdicke der Decke (Meter, thickness-Übersteuerung). */ onSetCeilingThickness: (thickness: number) => void; + /** Entfernt die Aussparung mit Index `index` der selektierten Decke. */ + onRemoveCeilingOpening: (index: number) => void; /** Setzt/entfernt die OK-Bindung der Decke (`null` = Geschoss-Oberkante). */ onSetCeilingTop: (anchor: VerticalAnchor | null) => void; /** diff --git a/src/state/selectionInfo.ts b/src/state/selectionInfo.ts index b59fde9..0b0b325 100644 --- a/src/state/selectionInfo.ts +++ b/src/state/selectionInfo.ts @@ -196,6 +196,8 @@ export interface CeilingInfo { /** Aufgelöste absolute UK/OK (Meter). */ zBottom: number; zTop: number; + /** Aussparungen (Treppenauge/Schacht) als BBox-Masse, Reihenfolge = Modell. */ + openings: { width: number; depth: number }[]; } /** @@ -606,6 +608,11 @@ function ceilingSelection(project: Project, ceiling: Ceiling): Selection { bottom: ceiling.bottom, zBottom, zTop, + // Aussparungen als anzeigefertige BBox-Masse (Breite × Tiefe je Loch). + openings: (ceiling.openings ?? []).map((hole) => { + const bb = outlineBBox(hole); + return { width: bb.maxX - bb.minX, depth: bb.maxY - bb.minY }; + }), }; return { kind: "ceiling",