From bdbd87bf85ba319567de3b374238d31b7c9b5281 Mon Sep 17 00:00:00 2001 From: Karim Date: Thu, 20 Aug 2026 20:01:26 +0200 Subject: [PATCH] Zweite Leichen-Runde: weitere tote Exporte + orphaned ribbonItems.ts entfernt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ts-prune nach dem ersten Durchgang erneut laufen lassen. compute/index.ts (101 Z., PoC-Brücke zu einem nie gebauten Rust-Command, im eigenen Kopfkommentar schon als ungenutzt markiert) komplett gelöscht. ribbonItems.ts war nur noch für das bereits gelöschte RibbonBar.tsx da (kein anderer Importeur mehr) — ebenfalls komplett weg. Einzelne tote Typen/Konstanten: SiaLabel (roomArea.ts), GeoImportResult (geoContext.ts, plus den dadurch verwaisten GeoOrigin-Import), die drei MATERIAL_LIBRARY_*-Konstanten (library.ts), ResolveContext-Re-Export (parametricWalls.ts), roofTotalThickness (types.ts — Duplikat, die echte Rechnung läuft in toWalls3d/bands.ts inline), DropTarget (panelDrag.tsx). resolveBackground (generatePlan/shared.ts) bewusst NICHT gelöscht: anders als das analoge resolveForeground wird es nirgends aufgerufen, obwohl backgroundSource für Wand/Decke im Modell und im Attribut-Panel existiert — sieht nach einer echten Lücke aus (By-Layer-Hintergrundfarbe kommt nie im Renderer an), nicht nach totem Code. tsc -b / vitest run (891/891) / npm run build grün. --- src/compute/index.ts | 101 ----------------------------- src/geometry/roomArea.ts | 8 --- src/io/geoContext.ts | 7 -- src/io/projectFile.ts | 4 +- src/materials/library.ts | 4 -- src/model/parametricWalls.ts | 4 -- src/model/types.ts | 4 -- src/panels/ToolsPanel.tsx | 5 +- src/panels/panelDrag.tsx | 6 -- src/ui/ribbon/ribbonItems.ts | 121 ----------------------------------- 10 files changed, 4 insertions(+), 260 deletions(-) delete mode 100644 src/compute/index.ts delete mode 100644 src/ui/ribbon/ribbonItems.ts diff --git a/src/compute/index.ts b/src/compute/index.ts deleted file mode 100644 index eb60c80..0000000 --- a/src/compute/index.ts +++ /dev/null @@ -1,101 +0,0 @@ -// Compute-Grenze: der EINE Einstiegspunkt für rechenintensive Operationen. -// War als Brücke zu einem Rust-`#[tauri::command]` gedacht (PoC), aber -// ungenutzt: kein Aufrufer im Frontend, und die Rust-Seite (`compute_joins` + -// das `geometry`-Crate) wurde entfernt (ungenutzter Totcode, s. PENDENZEN.md). -// `computeJoins` läuft daher immer über den TS-Fallback; die übrigen -// Funktionen waren schon vorher reine TS-Pass-throughs. - -import type { Project, Wall } from "../model/types"; -import { getWallType, wallTypeThickness } from "../model/types"; -import { wallReferenceOffset } from "../model/wall"; -import { computeJoins as computeJoinsTS } from "../model/joins"; -import type { WallCuts } from "../model/joins"; -import type { Line } from "../model/geometry"; -import { detectRooms as detectRoomsTS } from "../geometry/roomBoundary"; -import type { WallSegment, DetectRoomsOptions } from "../geometry/roomBoundary"; -import { parseDwg as parseDwgTS } from "../io/dwgParser"; -import type { DxfImportResult } from "../io/dxfParser"; -import type { Vec2 } from "../model/types"; - -// Tauri-invoke, wenn vorhanden — sonst null (Browser/kein Tauri). Dynamischer, -// GEGUARDETER Import, damit der Build ohne @tauri-apps/api grün bleibt. -async function tauriInvoke(cmd: string, args: Record): Promise { - try { - // @ts-ignore optionales Paket - const mod = await import(/* @vite-ignore */ "@tauri-apps/api/core").catch(() => null); - if (!mod || typeof (mod as any).invoke !== "function") return null; - return await (mod as any).invoke(cmd, args) as T; - } catch { - return null; - } -} - -/** Serialisierbare Wand-Repräsentation für den Rust-Kern. */ -interface FlatWall { - id: string; - start: Vec2; - end: Vec2; - thickness: number; - referenceOffset: number; -} - -/** Rohantwort des Rust-Befehls `compute_joins`. */ -interface RustWallCut { - wallId: string; - startCut: Line | null; - endCut: Line | null; -} - -/** - * Gehrungs-Schnittlinien pro Wand. Unter Tauri via Rust-Kern, sonst TS-Fallback. - * Die Signatur ist synchron-kompatibel zur TS-Impl, aber async (Rust-Aufruf). - */ -export async function computeJoins( - project: Project, - walls: Wall[], -): Promise> { - try { - const flattened: FlatWall[] = walls.map((w) => { - const thickness = wallTypeThickness(getWallType(project, w)); - return { - id: w.id, - start: w.start, - end: w.end, - thickness, - referenceOffset: wallReferenceOffset(w, thickness), - }; - }); - - const res = await tauriInvoke("compute_joins", { - input: { walls: flattened }, - }); - if (res != null) { - const map = new Map(); - for (const c of res) { - map.set(c.wallId, { startCut: c.startCut, endCut: c.endCut }); - } - return map; - } - } catch { - // fällt unten in den TS-Pfad - } - console.warn("Rust compute_joins nicht verfügbar, TS-Fallback"); - return computeJoinsTS(project, walls); -} - -// ── Pass-throughs (noch reines TS; bereit für spätere Rust-Migration) ───────── - -/** Raumerkennung aus Wandsegmenten. Aktuell TS; Grenze für spätere Migration. */ -export async function detectRooms( - walls: WallSegment[], - options: DetectRoomsOptions = {}, -): Promise { - return detectRoomsTS(walls, options); -} - -/** DWG-Import (LibreDWG-WASM). Aktuell TS; Grenze für spätere Migration. */ -export async function parseShapeFromDwg( - data: ArrayBuffer, -): Promise { - return parseDwgTS(data); -} diff --git a/src/geometry/roomArea.ts b/src/geometry/roomArea.ts index c083081..382348e 100644 --- a/src/geometry/roomArea.ts +++ b/src/geometry/roomArea.ts @@ -124,14 +124,6 @@ export const SIA_CATEGORIES: readonly SiaCategory[] = [ "AGF", ] as const; -/** Deutsche Bezeichnungen (Kurz + Lang) je SIA-416-Schlüssel. */ -export interface SiaLabel { - /** Kürzel, z. B. „HNF". */ - code: SiaKey; - /** Ausgeschriebene deutsche Bezeichnung. */ - name: string; -} - const SIA_LABELS: Record = { HNF: "Hauptnutzfläche", NNF: "Nebennutzfläche", diff --git a/src/io/geoContext.ts b/src/io/geoContext.ts index f687eac..318e5c4 100644 --- a/src/io/geoContext.ts +++ b/src/io/geoContext.ts @@ -8,7 +8,6 @@ // Bezeichner englisch, Kommentare deutsch (CONVENTIONS.md). import Delaunator from "delaunator"; -import type { GeoOrigin } from "./lv95"; import type { ContextObject, Contour, ImportedMesh } from "../model/types"; /** Fachliche Kategorie einer importierten Kontext-Linie. */ @@ -39,12 +38,6 @@ export interface GeoFeature { /** Default-Gebäudehöhe (m), wenn keine Höhe aus der Quelle vorliegt. */ export const DEFAULT_BUILDING_HEIGHT = 9; -/** Ergebnis eines Import-Laufs: Features + verwendete Origin. */ -export interface GeoImportResult { - origin: GeoOrigin; - features: GeoFeature[]; -} - /** Menschlicher Layer-/Objektname je Kategorie (deutsch, für die Kontext-Liste). */ const CATEGORY_LABEL: Record = { building: "Gebäude", diff --git a/src/io/projectFile.ts b/src/io/projectFile.ts index 8830530..bbf4fef 100644 --- a/src/io/projectFile.ts +++ b/src/io/projectFile.ts @@ -107,8 +107,8 @@ export type LockResult = { ok: true } | { ok: false; info: LockInfo | null }; /** * Holt (ungeguardet) die Tauri-`invoke`-Funktion, oder `null` ohne Tauri-Core. - * Anders als das Muster in compute/index.ts bzw. plan/nativeSync.ts schluckt - * dieser Helfer KEINE Fehler aus dem eigentlichen Aufruf — ein `Err(...)` vom + * Anders als das Muster in plan/nativeSync.ts schluckt dieser Helfer KEINE + * Fehler aus dem eigentlichen Aufruf — ein `Err(...)` vom * Rust-Command (hier: „schon gelockt", inkl. {@link LockInfo}-Payload) muss bis * zum Aufrufer durchgereicht werden. */ diff --git a/src/materials/library.ts b/src/materials/library.ts index ef7219b..573f6c1 100644 --- a/src/materials/library.ts +++ b/src/materials/library.ts @@ -24,10 +24,6 @@ export interface MaterialAsset { maps: Partial>; } -export const MATERIAL_LIBRARY_SOURCE = "ambientCG (ambientcg.com)"; -export const MATERIAL_LIBRARY_LICENSE = "CC0 1.0 Universal (Public Domain)"; -export const MATERIAL_LIBRARY_RESOLUTION = "2K"; - export const MATERIAL_LIBRARY: MaterialAsset[] = [ { id: "Concrete048", diff --git a/src/model/parametricWalls.ts b/src/model/parametricWalls.ts index f89e5b4..0d566da 100644 --- a/src/model/parametricWalls.ts +++ b/src/model/parametricWalls.ts @@ -561,9 +561,5 @@ function isExteriorWall(wall: Wall, ctx: RuleCtx): boolean { return isOnEdge(wall.start) && isOnEdge(wall.end); } -// ── Re-Export der Kontexttypen für Unit-Tests / Integration ────────────── -// (ermöglicht Import ohne Direktverweis auf interne RuleCtx) -export type { ParametricContext as ResolveContext }; - // DrawingLevel-Re-Export für Konsumenten, die keinen eigenen types-Import wollen. export type { DrawingLevel }; diff --git a/src/model/types.ts b/src/model/types.ts index 3d1be01..d125033 100644 --- a/src/model/types.ts +++ b/src/model/types.ts @@ -2353,10 +2353,6 @@ export const roofLayers = (project: Project, roof: Roof): Layer[] => { return [{ componentId: "", thickness: Math.max(0, roof.thickness) }]; }; -/** Gesamtdicke eines Daches (Meter, senkrecht zur Fläche) = Summe der Schichten. */ -export const roofTotalThickness = (project: Project, roof: Roof): number => - roofLayers(project, roof).reduce((s, l) => s + Math.max(0, l.thickness), 0); - /** * Löst den {@link DoorType} einer Tür-Öffnung auf, oder `undefined` (keine * `typeId` bzw. unbekannt ⇒ Inline-Verhalten). Bewusst NICHT werfend — der diff --git a/src/panels/ToolsPanel.tsx b/src/panels/ToolsPanel.tsx index b38fab6..da8af38 100644 --- a/src/panels/ToolsPanel.tsx +++ b/src/panels/ToolsPanel.tsx @@ -172,9 +172,8 @@ export function ToolIcon({ id }: { id: ToolId }) { // ── Kategorien ─────────────────────────────────────────────────────────────── // Werkzeuge/Befehle in drei Rubriken sortiert (Nutzerwunsch: „sortiere nach 2D -// und 3D und Bearbeiten"). Befehlsnamen spiegeln die Ribbon-Registry -// (ui/ribbon/ribbonItems.ts) — dort liegt die kanonische Liste; hier nur die -// Panel-Gruppierung (2D-Zeichnen · 3D/BIM-Bauteile · Bearbeiten-Aktionen). +// und 3D und Bearbeiten"): reine Panel-Gruppierung (2D-Zeichnen · 3D/BIM- +// Bauteile · Bearbeiten-Aktionen). const TOOLS_2D: ToolId[] = ["line", "polyline", "rect", "circle", "arc", "text", "textbox", "image"]; const TOOLS_3D: ToolId[] = ["wall", "ceiling", "window", "door", "stair", "room"]; const COMMANDS_3D = ["column", "ceilingopening", "roof", "extrude", "sectionline", "viewline"]; diff --git a/src/panels/panelDrag.tsx b/src/panels/panelDrag.tsx index 48abec4..f238a28 100644 --- a/src/panels/panelDrag.tsx +++ b/src/panels/panelDrag.tsx @@ -36,12 +36,6 @@ const DRAG_THRESHOLD = 5; export const DEFAULT_FLOAT_W = 300; export const DEFAULT_FLOAT_H = 360; -/** Ein aufgelöstes Ablageziel beim Loslassen. */ -export type DropTarget = - | { kind: "join"; dock: DockId; group: number; index?: number } - | { kind: "newgroup"; dock: DockId; at: number } - | { kind: "float"; x: number; y: number }; - /** Laufender Drag-Zustand (für Geist + Hervorhebung). */ interface DragState { panelId: string; diff --git a/src/ui/ribbon/ribbonItems.ts b/src/ui/ribbon/ribbonItems.ts deleted file mode 100644 index 39b2a38..0000000 --- a/src/ui/ribbon/ribbonItems.ts +++ /dev/null @@ -1,121 +0,0 @@ -// Ribbon-Registry (docs/design/ribbon-ui-plan.md §Architektur) — EINE -// datengetriebene Beschreibung aller Ribbon-Elemente. Die Ribbon-Tabs UND eine -// spätere modulare Custom-Bar (Phase 4) sind bloß zwei Ansichten über dieselbe -// Registry, ohne Sonderweg pro Element. -// -// Ein `RibbonItem` ist entweder ein Werkzeug (`tool` → onSelectTool, wie die -// Werkzeug-Sidebar) oder ein Engine-Befehl (`command` → engine.start). Beide -// münden in exakt DENSELBEN Pfad wie Klick in der alten Sidebar bzw. das Tippen -// des Befehlsnamens — keine Duplikate. -// -// Bezeichner englisch, UI-Text/Kommentare deutsch (CONVENTIONS.md). Sichtbare -// Texte kommen als i18n-Schlüssel und werden erst in der Komponente über t(...) -// aufgelöst. - -import type { ToolId } from "../../tools/types"; - -/** Ein aktivierbares Ribbon-Element. Bei `command` wird die Beschriftung aus der - * Befehls-Registry (`getCommand(name).labelKey`) abgeleitet — kein doppeltes - * Pflegen von Labels. */ -export type RibbonItem = - | { kind: "tool"; id: ToolId } - | { kind: "command"; name: string }; - -/** Eine benannte Gruppe von Elementen innerhalb eines Tabs. */ -export interface RibbonGroup { - titleKey: string; - items: RibbonItem[]; -} - -/** Kennung eines Ribbon-Tabs (fest, für Tab-State + i18n). */ -export type RibbonTabId = "2d" | "bim" | "custom"; - -/** Ein Ribbon-Tab: Beschriftung + gruppierte Elemente. */ -export interface RibbonTab { - id: RibbonTabId; - labelKey: string; - groups: RibbonGroup[]; -} - -const c = (name: string): RibbonItem => ({ kind: "command", name }); - -/** - * Die Ribbon-Tabs (2D·BIM·Eigene) — keine Tab-Reiter mehr in der UI (v12, - * siehe layout.ts): App rendert alle drei permanent nebeneinander (kein - * Umschalter). Reine Werkzeug-Elemente (`t(...)`, persistentes Werkzeug wie - * Wand/Linie/Fenster) leben AUSSCHLIESSLICH im ToolsPanel (kein Doppel- - * Auftritt). Reine Befehls-Elemente (`c(...)`, Einmal-Aktionen wie - * Verschieben/Kopieren/Säule setzen ohne eigenen Werkzeug-Modus) bleiben hier, - * da sie im Panel keine Entsprechung haben. Ansichts-/Zoom-/Darstellungs- - * Steuerung + Text-Formatierung sitzen direkt in App (ViewRibbonTab), nicht - * in dieser Registry. - */ -export const RIBBON_TABS: RibbonTab[] = [ - { - id: "2d", - labelKey: "ribbon.tab.2d", - groups: [ - { - titleKey: "ribbon.group.modify", - items: [ - c("move"), - c("copy"), - c("rotate"), - c("mirror"), - c("offset"), - c("trim"), - c("join"), - c("measure"), - ], - }, - ], - }, - { - id: "bim", - labelKey: "ribbon.tab.bim", - groups: [ - { - // "extrude" war vormals im (jetzt entfernten) 3D-Ribbon-Tab - // (Ribbon3dTab) — einziger Zugang zum Befehl, daher hier statt - // gestrichen. - titleKey: "ribbon.group.components", - items: [c("column"), c("ceilingopening"), c("roof"), c("extrude")], - }, - { - titleKey: "ribbon.group.sections", - items: [c("sectionline"), c("viewline")], - }, - ], - }, - { - // Modulare Custom-Bar (Phase 4): der Nutzer stellt sich die Elemente selbst - // zusammen (persistiert). Gerendert aus `customItems`, nicht aus `groups`. - id: "custom", - labelKey: "ribbon.tab.custom", - groups: [], - }, -]; - -/** Stabiler Schlüssel eines Items für die Persistenz der Custom-Bar. */ -export function itemKey(item: RibbonItem): string { - return item.kind === "tool" ? `tool:${item.id}` : `command:${item.name}`; -} - -/** Parst einen Item-Schlüssel zurück (oder null bei unbekanntem Präfix). */ -export function itemFromKey(key: string): RibbonItem | null { - const i = key.indexOf(":"); - if (i < 0) return null; - const kind = key.slice(0, i); - const rest = key.slice(i + 1); - if (kind === "tool") return { kind: "tool", id: rest as ToolId }; - if (kind === "command") return { kind: "command", name: rest }; - return null; -} - -/** - * Alle datengetriebenen Items (aus den Werkzeug-/Befehls-Tabs) — die wählbare - * Menge für den Custom-Bar-Picker. „views"/„custom" tragen keine `groups`. - */ -export const ALL_RIBBON_ITEMS: RibbonItem[] = RIBBON_TABS.flatMap((tab) => - tab.groups.flatMap((g) => g.items), -);