107 KiB
PENDENZEN — Aufgaben-Queue (Single Source of Truth)
Diese Datei ist die einzige verbindliche Aufgabenliste. HANDOVER.md enthält nur noch Kontext/Konventionen/Environment/Zielmodelle — keinen Backlog mehr.
Arbeitsprotokoll (ZWINGEND)
Bearbeiter:
- Zuerst diese Datei lesen, dann
CONVENTIONS.md+ verlinkte Detailquellen des Items. - Oberstes nicht-blockiertes Item aus 🔧 In Arbeit bzw. sonst ⏭️ Als Nächstes nehmen, fertig machen, verifizieren (
npx tsc --noEmit+npx vitest run+ trace-scan), abhaken, eine Ergebniszeile nach ✅ Erledigt schreiben (mit Commit-Hash, sobald committet). - Rückfrage-Recht: Bei Unklarheit/Design-Entscheid NICHT raten — Item mit
❓markieren, kurze Frage darunter notieren, nächstes freies Item nehmen. Fragen sammeln sich unter ❓ Offene Rückfragen. - Kein Arbeitsschritt endet ohne aktualisierte Liste. Status hier ist immer aktuell, sonst driftet es wieder.
- Bearbeiter committet nicht selbst und delegiert Unteraufgaben nicht weiter.
Planer (mit dem Nutzer, kuratiert):
- Nimmt Nutzer-Feedback, pflegt daraus die Liste (rein/umpriorisieren/aufspalten). Führt selbst keine Queue-Items aus.
- Prüft ❓-Zeilen mit dem Nutzer, wandelt sie in konkrete Items.
⛔ Blocker (zuerst klären)
Toolchain prüfen— ERLEDIGT 2026-07-04 (macOS-Gerät):node/npm/cargo(1.96.0)/wasm-pack(0.15.0) alle vorhanden.npm install+npm approve-scripts esbuild wasm-pack …(npm gated Install-Scripts →allowScripts-Block inpackage.json, ungetrackt gelassen),rustup target add wasm32-unknown-unknown, beide WASM-Engines gebaut, Frontend gebaut,npm run tauri:build→ Mac-App (cad.app+cad_0.1.0_aarch64.dmg, arm64) läuft. Verifikations-Baseline grün:tsc --noEmitsauber,vitest run230/230,cargo test render3d56/56. Kein Blocker mehr für Engine-Slices auf diesem Gerät.
🔧 In Arbeit
-
truck-Integration (Profil-Extrusion / B-Rep) (Plan: docs/design/truck-plan.md). Ziel: Nutzer zeichnet 2D-Querschnitt → truck-Extrusion → 3D-Körper + später Boolean gegen Wand/Decke. Umfang gesamt: ~4–6 Wochen. Fortschritt:
-
Phase 1: Geometrie-Schicht — Crate
src-tauri/trucksolid(extrude_polygon_core/extrude_circle_core,truck_modelingnur zur B-Rep-Validierung/try_attach_plane/tsweep, Tessellierung manuell aus den Ring-Koordinaten — truck-rendimesh-Tessellierung für Solids in 0.3 nicht verfügbar, daher Abweichung vom Übergabe-Dokument), WASM-Bindings (Featureweb) +build:truck-Script +exclude-Eintrag, TS-Wrappersrc/engine/truckSolid.ts(extrudePolygon/extrudeCircle),RMeshKindum"extrusion"erweitert (toWalls3d.ts). Verifiziert:cargo test5/5 grün,npm run build:trucksauber,tsc --noEmit0 Fehler,vitest run339/339 grün. -
Phase 2 (MVP, Nutzer-Entscheid 2026-07-06: "Nur Viewer-Wiring", kein Werkzeug/Store) — Ende-zu-Ende-Beweis, dass die Pipeline bis ins Bild funktioniert: ein fest verdrahtetes L-Profil (
emitTruckFixtureintoWalls3d.ts, 2 m abseits vom Ursprung) wird bei Bedarf pertrucksolid-WASM extrudiert und erscheint im 3D-Viewport. Zwei echte Lücken dabei gefunden und geschlossen: (1)render3d::types::MeshKindkannte nurTerrain/Imported— einkind:"extrusion"ohne passende Rust-Variante hätte die serde-Deserialisierung des GESAMTEN Modell-Pushes zum Absturz gebracht (nicht nur die Fixture);Extrusion-Variante + warmes Orange als Default-Farbe ergänzt (cargo testrender3d 58/58 weiterhin grün). (2)updateModel(project)läuft nur bei Projektänderung (useEffect-Depproject) — die asynchron ladende Fixture hätte trotz Erfolg NIE einen Re-Push ausgelöst; Fix via Browser-EventTRUCK_FIXTURE_READY_EVENT(toWalls3d.tsdispatcht,Wasm3DViewport.tsxhört + stösstupdateModelerneut an). Visuell verifiziert (Playwright,?engine=wasm, Chromium mit--use-angle=metalfür echten WebGPU-Adapter headed): orangene Extrusion sichtbar neben dem Demo-Haus im Viewport.tsc --noEmit+vitest run339/339 +cargo testrender3d 58/58 grün. Noch uncommittet (Bearbeiter committet nicht selbst). -
Phase 3: UI-Werkzeug + Store-Integration — erledigt 2026-07-06:
extrude-Befehl (src/commands/cmds/extrude.ts, Alias „ex") nimmt Polylinie/Rechteck/Kreis als Profil (vorselektiert ODER Klick), Höhe tippen oder Enter für Default; Quell-Zeichnung wird beim Commit ENTFERNT (nicht dupliziert) — der Grundriss zeigt die Extrusions-Footprint-Kontur (generatePlan.ts, warmes Orange#d98c40) statt der alten Linie.project.extrudedSolids-Array statt Fixture. Volle Auswahl-Parität mit Wand/Decke/Raum (Nutzer-Entscheid „Voll: wie Wand/Decke/Raum"): eigener Selektionskanal, Klick-Priorität inPlanView.tsx, Attribute-Panel-Sektion (Höhe editierbar → löst Re-Extrusion aus, Grundfläche, Geschoss), Löschen, Ctrl+A,move-Befehl (src/tools/transform.ts). Kreis-Profil nutzt die echteextrudeCircle-WASM-Rundextrusion (kein N-Eck-Fallback) über eine 48-Eck-Tessellierung für 2D/Auswahl. Verifiziert:tsc/vitest339/339 grün, Playwright-Durchlauf (zeichnen→extrudieren→auswählen→Höhe ändern→löschen) ohne Konsolenfehler. Bewusst NICHT gebaut (Konsistenz mit Raum/Decke/Treppe/Öffnung, die das auch nicht haben): Marquee-Auswahl, Klick-Drag-Verschieben. Noch uncommittet. -
Phase 4: Boolean gegen Wand/Decke — Mesh-CSG statt B-Rep-Boolean. Spike 1, 2026-07-06 (Monstertruck-Fork getestet, nicht nur Recherche): eigenes Rust-Testprogramm gegen
monstertruck-solid0.3.2 (Fork vonricosjp/truck, wirbt mit gehärteten Booleans) — der Crate-eigene Smoke-Test (echter Überlapp, versetzt in allen 3 Achsen) läuft sauber (or/andliefern exakte Volumina). Aber: jede Konstellation mit deckungsgleichen/berührenden Seitenflächen schlägt fehl — exakt der Praxisfall „Extrusion flächenbündig an Wand" oder „Extrusion mit gleichem Wandquerschnitt eingebunden" (gleiche y/z-Ausdehnung wie die Wand, nur in x versetzt): 0 Überlapp →Internal{operation:"or"/"and"}-Fehler; 1e-4 UND sogar 0.1 m sichtbarer Überlapp bei deckungsgleichen Seitenflächen → derselbe interne Fehler; 1e-9 Gleitkomma-Rauschen (winziger Spalt statt exakt 0) → kein Fehler, aber STILL FALSCHES Ergebnis (2 unverschmolzene Shells, Volumen = Summe statt Vereinigung). Sobald y/z zusätzlich leicht versetzt sind (keine deckungsgleichen Seiten mehr), funktioniert derselbe x-Überlapp einwandfrei. Schluss: B-Rep-Booleans (truck/monstertruck) sind für diesen Projekt-Praxisfall (Extrusion mit Wandbreite/-höhe eingebunden) grundsätzlich ungeeignet — teils Absturz, teils stiller Falsch-Wert.Spike 2, 2026-07-06 (
csgrs, Mesh-Ebenen-CSG/BSP-Baum statt B-Rep): strukturell anderer Ansatz — rechnet auf Dreiecks-Ebene statt über analytische Kurven/Flächen-Schnitte, damit unempfindlich gegen genau die koinzidenten-Flächen-Fälle, an denen truck/monstertruck scheiterten. Gegen dieselben Testfälle geprüft: generischer Überlapp exakt korrekt (or/and); flächenbündig (0 Überlapp) →orexakt 2.0 (korrekt verschmolzen, kein doppeltes Volumen),andliefert korrekt LEER (als Trimesh-Fehler statt sauberemNone— muss beim Aufrufer als "leer" interpretiert werden); 1e-9-Rauschen → weiterhin exakt korrekt (kein falsches Doppel-Volumen wie bei monstertruck); 1e-4 winziger Überlapp → exakt korrekt; der kritische Praxisfall (0.1 m Einbindetiefe, deckungsgleicher Wandquerschnitt) →or/differencebeide exakt korrekt. Jedes Ergebnis analytisch exakt (nicht nur "nah dran").- Packungs-Caveat: alle crates.io-Releases (0.16.0–0.20.1) sind wegen einer harten, zurückgezogenen
core2-Abhängigkeit nicht installierbar — auf dem unveröffentlichtenmain-Branch bereits behoben. Nutzerautorisiert ("Git-Fetch für den Spike erlauben", danach "alles klar mach das" zur Umsetzung als echte Abhängigkeit):trucksolid/Cargo.tomlpinntcsgrsauf Commit5e7a37a8803d4e56617734687edc9b98f4ebeed7(Git-Dependency, kein crates.io-Release — Risiko: kein durchnummeriertes/geprüftes Release, sollte bei Gelegenheit auf ein echtes0.21.0-Release umgestellt werden, sobald verfügbar). - Umgesetzt:
src-tauri/trucksolid/src/boolean.rs—boolean_mesh_core(a, b, op)baut aus flachen Positions-/Indices-Arrayscsgrs::mesh::Mesh-Polygone (Polygon::new/Vertex::new, Normale je Dreieck aus dem Kreuzprodukt, NICHT aus den Eingabe-Normalen — die Ebenen-Orientierung fürs BSP kommt aus der Vertex-REIHENFOLGE/Winding, nicht aus einem mitgelieferten Normalenfeld), ruftunion/difference/intersection(Traitcsgrs::csg::CSG) auf, tesselliert das Ergebnis zurück überTriangulated3D::visit_triangles.empty: boolim Output normalisiert den "Trimesh-Fehler bei leerem Schnitt"-Fall. WASM-Exportboolean_mesh(Featureweb, JSON-Schnittstelle wieextrude_polygon) + TS-WrapperbooleanMesh()insrc/engine/truckSolid.ts. Wichtige Voraussetzung für Aufrufer: beide Eingabe-Meshes müssen konsistent nach AUSSEN gewundene Dreiecke haben (Rechte-Hand-Regel) — falsches Winding liefert ein falsches Ergebnis, OHNE Fehler zu werfen (im eigenen Test zunächst selbst hineingetappt: alle 6 Quader-Seiten der Test-Fixture waren invertiert, dadurch schlugen 3 von 4 Boolean-Tests fehl, bis das Winding korrigiert wurde — reiner Test-Fixture-Bug, nicht im Produktivcode). - Verifiziert:
cargo testintrucksolid11/11 grün (inkl.wall_minus_embedded_extrusion_matching_cross_section,flush_touching_union_is_exact),cargo build --target wasm32-unknown-unknown --features websauber (csgrs + truck-modeling gemeinsam im selben WASM-Modul, keine Konflikte),npm run build:truck(echterwasm-pack-Build) sauber —boolean_meshist reell im generierten.d.tsexportiert. - Noch offen (bewusst NICHT gebaut, eigene Scope-Entscheidung nötig): die eigentliche Verdrahtung in die Live-3D-Szene (WANN soll eine Wand automatisch um eine eingebundene Extrusion gekürzt werden? Bei jeder geometrischen Überlappung? Nur bei explizit markierten Fällen?) ist eine UX/Scope-Frage, keine technische — analog zum Feld-Controller-Rückstand unten nicht blind entschieden, sondern auf Nutzer-Entscheid wartend. Aktuell bleibt eine Extrusion weiterhin ein unabhängiges, nicht mit der Wand verschmolzenes Solid im 3D (wie seit Phase 2/3).
- Packungs-Caveat: alle crates.io-Releases (0.16.0–0.20.1) sind wegen einer harten, zurückgezogenen
-
Phase 5: Verjüngung (Taper) —
taper0 (Prisma) … 1 (Spitze/Kegel-Pyramide), linear zum Profil-Schwerpunkt skaliert. Rust-Kern (extrude_polygon_core/extrude_circle_coreinlib.rs), WASM/TS-Wrapper, dritte Befehls-Phase inextrude.ts(Höhe → Verjüngung, Enter für persistenten Default),ExtrudedSolid.taper?, Attribute-Panel-Feld (editierbar → Re-Extrusion). Tests: Kegel-Volumen (Divergenzsatz gg. analytisch), Pyramidenstumpf-Schwerpunkt-Skalierung, Range-Check. -
Deep-Review + Fixes (2026-07-07, nach Geräte-Absturz der vorherigen Session): 8-Winkel-Review (Korrektheit/Reuse/Simplify/Efficiency/Altitude/Conventions) über den gesamten uncommitteten Stand ergab mehrere echte Bugs, alle gefixt:
- Konkave Profile falsch trianguliert (
trucksolid/src/lib.rs): Deckel/Boden nutzten eine Fächer-Triangulierung ab Vertex 0 — korrekt nur für konvexe/von Vertex 0 aus sternförmige Polygone. Bei einem T-Träger (genau das im Plan genannte Zielprofil) erzeugte das nachweislich Phantom-Dreiecke quer durch die konkave Kerbe (nachgerechnet: 2 von 6 Deckel-Dreiecken lagen mit Schwerpunkt ausserhalb). Fix: Ohr-Clipping-Triangulierung (portiert von der bereits vorhandenen, robustenrender3d::mesh::triangulate) ersetzt den Fächer; Schwerpunkt-Berechnung für die Verjüngung ebenfalls auf die korrekte flächen-gewichtete Formel umgestellt (vorher reiner Vertex-Mittelwert, bei asymmetrischen Profilen verzerrt). Neuer Regressionstestt_beam_caps_stay_inside_polygon(prüft, dass jeder Deckel-/Boden-Dreieck-Schwerpunkt im wahren Polygon liegt).cargo testtrucksolid 15/15 grün. - Auswahl-Zustand (
selectedExtrudedSolidIds) an 6 Stellen inApp.tsxnicht zurückgesetzt, wo alle anderen Auswahl-Arten es bereits werden: Geschosswechsel-Effekt,onOpenStampEditor, die vier alten three.js-Viewport-Pick-Handler (Wand/Treppe/Decke/Öffnung),onViewport3dPick. Ohne Fix: Extrusion bleibt nach Geschosswechsel/anderer Auswahl "geisterhaft" mit-selektiert (falsches Panel, Löschen träfe das falsche Objekt). - Mirror/Copy ignorierten eine reine Extrusions-Auswahl (
hasSelection/toTransformSelinmirror.ts/copy.tskanntenextrudedSolidIdnicht, obwohltransform.ts/move.tses längst unterstützen) → stiller No-op statt Spiegeln/Kopieren. - DXF-Export verlor den Layer von Extrusions-Footprints: da
extrudedie Quell-Zeichnung (mitcategoryCode) entfernt, fiellayerFor()inexportDxf.tsaufLAYER_DEFAULTzurück. Fix: eigenerEXTRUSION-Layer (gleiches Orange wie 2D/3D-Darstellung). truckMeshCache(toWalls3d.ts) ohne Eviction — wuchs unbegrenzt über eine Session (Extrudieren→Kopieren→Löschen in Serie liess Mesh-Daten toter Körper im Speicher). Fix: gelöschte Ids werden bei jedememitExtrudedSolids-Lauf aus dem Cache entfernt. Gleichzeitig behoben: sichtbares Flackern beim Tippen von Höhe/Verjüngung im Attribute-Panel (jeder Tastendruck = neue Signatur = Cache-Eintrag wurde sofort aufmesh:nullgesetzt, bevor die neue Extrusion geladen war) — die alte Mesh bleibt jetzt sichtbar, bis die neue fertig ist.fitTargetDistim 3D-Viewport (Wasm3DViewport.tsx) rief bei JEDER Projekt-Änderung (auch während eines laufenden Griff-Drags) unnötig die komplette Wand-/Öffnungs-/Decken-Flatten-Pipeline auf, nur um eine Bounding-Box für die Schnittebene zu ziehen — die aber nur bei aktiver Schnittebene gebraucht wird. Fix: Aufruf hintersectionActivegegated.- Nutzer-Report währenddessen: Schnittebene-Umschalter (Wasm3DViewport.tsx) hatte
title/aria-labelhart auf Deutsch verdrahtet statt übert()— einzige Stelle im 3D-Viewport, die das i18n-System umging. Fix + Audit der ganzen App auf dasselbe Muster (title/aria-label/placeholder ausserhalbt()): genau eine weitere Stelle gefunden (ColorHexField.tsxSwatch-Tooltip „Farbe wählen"), beide jetzt über neue i18n-Keys (viewport3d.section.*,attr.pickColor). - Verifiziert nach jedem Schritt:
tsc --noEmitsauber,cargo testtrucksolid grün.vitest run/cargo test render3dam Ende der ganzen Fix-Reihe erneut komplett gegengeprüft (339/339, 58/58, 15/15).
- Konkave Profile falsch trianguliert (
-
-
kernel2d-Port nach Rust/WASM (Plan: PORT_PLAN.md, Crate
src-tauri/kernel2d, TS-Referenz bleibtkernel2d.ts, Differential-Harnesssrc/geometry/kernel2d.parity.test.ts). Fortschritt:- Phase 1: Crate-Skelett + WASM-Fassade +
build:kernel2d—a78e7c7 - Phase 2: Primitive/Schnitt/Fläche/Kreis + Batch-Fassaden + Diff-Harness (Zufall+Golden) —
9e2c521 - Phase 3: Offset (Miter + 1e-9-Fallback) + Fillet —
c8ea2bf - Phase 4: Trim/Split/Join (
trimPolyline,splitAtIntersections,joinChains— Löwenanteil) —28471c1 - Phase 5:
roomArea-Flächen/ceiling/stair/roomBoundaryportiert (vitest 263, 33 Parity) —a608a59. ✅ Phase 5 komplett (2026-07-07):openingportiert (wall_axis_length/opening_interval/wall_axis_frame/opening_jambs/opening_gap_quad/opening_center/door_symbol/window_symbol+along-Helper, geflachte Signaturen nach PORT_PLAN;openingVerticalExtentbleibt bewusst TS — echte Modell-Kopplung an drawingLevels). +7 Parity-Tests (Suite 40 Parity).cargo testkernel2d 18/18,build:kernel2dsauber, vitest 348/348. Produktive Aufrufer unverändert (Phase 6 weiter offen/Nutzer-Entscheid). Noch uncommittet. - Phase 6: TS-Fassade umstellen (alt →
kernel2d.legacy.ts), Suite grün,npm run build+ WASM sauber. Achtung Laufzeit-Entscheid: macht die Live-App synchron WASM-abhängig (Init + Per-Call-Marshalling) — heute nutzt die App KEINE WASM-Geometrie zur Laufzeit; vor Umstellung mit Nutzer klären.- Join-Durchstich verworfen (2026-07-05, gemessen):
computeJoinslive auf WASM zu legen lohnt NICHT. Benchmark TS vs. WASM inkl. JSON-Marshalling (Median ms/Aufruf, 200 Iter): 6 W → TS 0.018/WASM 0.022 · 20 → 0.027/0.043 · 50 → 0.082/0.102 · 120 → 0.331/0.246 · 300 → 1.68/0.67. Crossover erst ~100+ Wände; realistische Plan-/Geschossmengen liegen darunter → TS schneller, und selbst 300 Wände sind mit TS 1,7 ms (nicht wahrnehmbar). Marshalling frisst den Rust-Vorteil, plus dauerhafte Rust↔TS-Paritätspflicht. Fazit: reines TS behalten; WASM für Joins nicht weiterverfolgen. WASM lohnt erst bei echten Rechen-Hotspots (Booleans/Tessellierung).
- Join-Durchstich verworfen (2026-07-05, gemessen):
- Phase 1: Crate-Skelett + WASM-Fassade +
⚠️ Zu prüfen (evtl. schon erledigt / Status unklar)
Snap an Wand-Schichttrennlinien— gelandet339202b(wallLayerBoundarySegmentsinsrc/tools/snapping.ts), verifiziert vorhanden.
⏭️ Als Nächstes
-
BIM-Elemente „wirklich 1:1" (Tür/Fenster/Dach/Decke) — volle Studie + Priorisierung: docs/design/bim-elements-depth-study.md (623 Zeilen, Referenzmatrix VW/ArchiCAD/Revit/Allplan gegen IST). ✅ Bereits erledigt 2026-07-10: Fenster-Schachtelung Blendrahmen→Flügelrahmen→Glas + fest/öffenbar + Einbaulage 2D (
9a38636); Mansard-Untertypen Giebel/Walm/Zelt + Knick (bfb80b3); Dach-Dicke 3D (e99bb24) + Dach-Schichtlogik RoofType/Layer[] (3a986ec); zweiflügelige Türen leafCount 2D+3D (4319e12); getrennter Traufe/Ortgang-Überstand (c9baff5); Glas/glazingPanes 2D+3D + Rollladenkasten (2e13ec3/d131683). Offen (nach Doc-Priorität):Decken-Aussparungen— erledigt 2026-07-10 (37f4fe8+cdbef99+aee8846+83dcdd0):Ceiling.openings?: Vec2[][]+ Brücken-Trick (mergeHolesinsrc/geometry/polygonHoles.ts: Löcher über schmale Brücken in den Aussenring → EIN einfacher Ring, paritätskorrekt für SVG/Hatch/Ear-Clipping/Pick — KEIN Loch-Support in den Primitiven nötig, kein Rust-Change). 2D-Poché-Loch (Brückenkanten via noStrokeEdges) + 3D-Slab-Loch; Befehl „Deckenloch" (Aliase deckenloch/aussparung, BIM-Ribbon); Panel listet Aussparungen mit Entfernen. +11 Tests.Dach in 2D-Aufsicht + Vertikalschnitt— erledigt 2026-07-10 (9a00c8e+f248e2a): Grundriss-Aufsicht trägt die Ansichts-Schraffur (viewHatchId) der Eindeckungs-Schicht; Vertikalschnitt viaappendRoofSections(analytischer TS-Schnitt: Cyrus–Beck gegen die Aufsichts-Polygone, lineare Oberkante, Dicke/cos(Neigung), Schicht-Bänder aussen→innen mit Bauteil-Schraffur). Offen: Ansichts-/Silhouettenkanten des Dachs in Elevationen (nur Schnitt-Polygone bisher).RoofType-ResourceManager-Tab— erledigt83abc1d(RoofStylesTab auf LayeredStylesTab-Rumpf; anlegen/editieren/löschen, Löschen geschützt bei Verwendung).- Decken-Randschicht-Override (
Ceiling.edgeOverride, Ringzone anderer Aufbau, Tropfkante/Randdämmung) — P1; Deckentrenn-Werkzeug für thermisch getrennte Auskragung (Isokorb, UI-only) — P1. - Tür 1:1 Rest:
glazingRatio(Teilverglasung), Kassettentür-Geometrie,frameKindim 3D (Zarge vs. Blockrahmen), echtes Schwellenprofil; Alt-Door[]-Pfad inOpeningkonsolidieren (technische Schuld, zwei Datenwege). - Fenster 1:1 Rest: asymmetrische Rahmenbreiten, echtes Sprossengitter, Bank/Nische, Laibungsverkleidung, Form (Rund/Spitz/Schräg).
- Dach 1:1 Rest: Kniestock/Drempel, Krüppelwalm, Kehlen bei L-Grundriss (Straight-Skeleton), Gauben/Dachfenster, Aufschieblinge.
Dach im Vertikalschnitt✅f248e2a. - Geneigte Decke (Rampe/Gefälle), Deckenspiegel (zweite abgehängte Fläche) — P2/P3.
- Nicht bauen (Doc §6): VW-Massketten-Apparat, volle Sichtbarkeitsmatrix, Eck-Fenster/-Dach generisch, Beschlags-Produktbibliothek, IFC-Void-Semantik nachrüsten.
-
make2D-Befehl (Sicht → 2D-Zeichnung mit Füllungen) (Nutzer-Wunsch 2026-07-10). Aus der AKTUELLEN Sicht — egal ob Grundriss, Schnitt oder 3D — eine flache 2D-Zeichnung aus reinen 2D-Geometrien erzeugen (Linien + Füllungen/Schraffuren, „mit allem"). Zwei Ausgaben: (a) als neueDrawing2D-Elemente ins Modell einfügen (auf einer Ziel-Ebene), ODER (b) in die Zwischenablage kopieren (SVG/DXF-Fragment) zum Einfügen anderswo. Vorbild: Vectorworks „2D-Darstellung erzeugen" / RhinoMake2D. Bausteine vorhanden: Grundriss/Schnitt laufen bereits übergeneratePlan()/generateSectionPlan()→ RScene → SVG (sceneToPrintSvg); für 3D braucht es eine Projektion (HLR/Silhouette) derprojectToModel3d-Meshes auf die Bildebene (neuer Teil). MVP: Grundriss/Schnitt → Drawing2D + Clipboard; 3D-Projektion als zweite Phase. Scope/Format (SVG vs. DXF vs. native Drawing2D) mit Nutzer schärfen. -
Dächer: Auswahl + Attribut-Editieren + Löschen— erledigt (80121a3+ Folge-Commits7cfdf59/eaf57e2/64f6179/826685c): Klick-Auswahl (Traufe-Pick-Polygon + pickRoof),selectedRoofIds/updateRoof/RoofInfo/roofSelection; RoofSection-Panel voll editierbar (Form, Firstrichtung X/Y, Neigung(en), Breite/Tiefe, Überstand, Dicke, Traufhöhe) + Firsthöhe/Fläche read-only; Auswahl-Hervorhebung im 2D UND 3D (Draht-Umriss); Löschen; Abwählen an ALLEN Reset-Stellen. Optional Folge:3D-Griffe zum Ziehen (Traufe/First)✅ erledigt4ef40a0(Eckpunkt-Resize + Verschieben + First-Griff für Neigung). Noch offen: Dachfenster, Kehlen bei nicht-rechteckigem Grundriss (Straight-Skeleton). -
Ribbon-UI + modulare Bars (Nutzer-Vision 2026-07-05, bestätigt: Tab-Schema 2D·3D·BIM·Ansichten). Voller Plan + datengetriebene Architektur: docs/design/ribbon-ui-plan.md. Ribbon-Oberleiste mit Tabs ersetzt die Werkzeug-Sidebar; datengetriebene Registry (RibbonItem = tool|command|action) ermöglicht auch eine modulare Custom-Bar (gleiche Items, vom Nutzer gewählt). Attribute bekommen volle Höhe, Objektinfo darunter gemergt; XYZ-Box oben rechts bleibt. Phasen:
(1) Gerüst + 2D/BIM-Tab✅ (9d6e86d),(2) TopBar → Ansichten-Tab mergen✅ (85011cb),(2b) Tabs in die TopBar-Zeile✅ (456ebc8),(2c) OCS-Chrome (kleine Wortmarke + Quick-Access-Icons statt Burger, Zeile 26px)✅ (4e3b074),(2d) Text + Ansichten auf eine Leiste, „Ansichten" als Standard-Tab zuerst✅ (fe22cbf), (3) teilweise ✅: Werkzeug-Sidebar aus Default-Layout raus + Attribute volle linke Höhe + Wandtyp-/Deckentyp-Picker ins Attribute-Panel verschoben (Nutzer-Entscheid),LAYOUT_VERSION→8;offen: Objektinfo unter Attribute mergen✅ (3a2cef3): element-spezifische Abschnitte (Wand/Decke/Öffnung/Treppe/Raum) + Wand-Referenzlinie ins Attribute-Panel verschoben; ObjectInfo trägt nur noch Bezugspunkt + Masse (Nutzer-Wunsch).(4) modulare Custom-Bar✅ (Tab „Eigene" + +-Picker, localStorage-persistiert). Offen: 3D-Tab füllen (aktuell leer; ggf. 3D-spezifisch statt Doppelung mit Ansichten), Band-Höhe/Abstände + 26px-Zeile visuell im Tauri abnehmen, Dauer-Zoom-Anzeige (Statusleiste?) klären. ✅ Vorarbeit: Eigenschaften-Grid im OCS-Stil (00733d8), Kreis+Bogen-Werkzeuge (e454eab/bd2b12b). Nächster Schritt: im Tauri visuell prüfen (Band-Höhe, Icons, Aktiv-Highlight), dann Phase 2/3. -
SPIKE — Bild-Texturen in— erledigtrender3d0ca3b1d(verifiziert 2026-07-05):RenderStyle::Texturedreal, prozedurales 256×256-Schachbrett (kein Asset/image-Crate), UVs planar in Metern, Textur-Bind-Group group 1,MESH_TEXTURED_WGSL(gleiche Beleuchtung, Albedo austextureSample),spike3dperTumschaltbar. Alt-Vertexpfad[pos,normal,color]bitgleich (Regressionstest).cargo test58 grün (59 mit--features render, inkl. naga-Test);spike3d-Build sauber; keine neuen Deps, Default-Build unverändert. Auftrag: SPIKE_TEXTUR_render3d.md. Lücken bis „richtig gutes" Texturing → siehe 3D-REST unten.
📋 Backlog (Priorität grob absteigend)
-
Shift-Ortho beim Körper-Verschieben (2D) fehlte— erledigt 2026-07-06: Nutzer-Report — Shift zum H/V-Einrasten wirkte beim Ziehen eines Vertex-Griffs (onGripMove) und beim freien Kanten-Zug (onEdgeMove), aber NICHT beim Verschieben eines ganzen Elements per Körper-Griff (onMoveBody— Wand/2D-Element/Decke/Treppe/Raum als Ganzes):PlanView.tsxreichtemodsan dieser einen Stelle schlicht nicht durch. Fix:GripHandlers.onMoveBodybekommt optionales drittes Argumentmods: ToolMods,App.tsxzwingt beimods.shiftdas Delta auf die dominante Achse (H/V) — dieselbe Regel wie beim freien Kanten-Zug.tsc/vitest339/339 grün. -
Feld-Controller (getippte Länge/Winkel relativ zum Ausgangspunkt) fehlt beim Körper-Verschieben + im 3D. Nutzer-Wunsch 2026-07-06: „allgemein brauchen wir ein System bei 2D- und 3D-Elementen, dass wenn man einen Punkt anwählt, man ihn verschiebt — mit der Option, Länge und Winkel relativ zur alten Position zu wählen." Bestandsaufnahme: existiert bereits für den 2D-Vertex-Griff-Drag (
gripEditRef/„Feld-Controller", Tab öffnet/zykelt Länge↔Winkel-Sperre,gripEditPointinApp.tsx) — fehlt aber (a) beim 2D-Körper-Verschieben (onMoveBody, ganzes Element ziehen) und (b) komplett im neuen 3D-Griffsystem (Wasm3DViewport.tsx, s. „3D-Griffe/Editieren" oben — weder Vertex- noch Verschiebe-Griff haben dort eine Locks/HUD-Eingabe). Für (b) zusätzlich zu klären: wie eine getippte Zahl im 3D-Viewport erfasst wird, ohne mit der freien Maus-Navigation (Orbit/Pan) zu kollidieren — eigenes UI-Element (z. B. ein kleines Eingabefeld neben dem gezogenen Griff-Button) naheliegend, aber nicht mit dem 2D-HUD-Muster identisch übertragbar. Mit Nutzer Scope/Reihenfolge klären (2D-Körper zuerst, da mechanische Erweiterung des bestehenden Feld-Controllers; 3D danach als grössere UI-Frage). -
Zeichenwerkzeuge ergänzen: Kreis + Bogen.— komplett erledigt (2026-07-05): beide Werkzeuge + Center-/Quadrant-Snaps + WebGL-Sichtbarkeitsfix (2c8ad8f). Details in den Unterpunkten:Kreis-Toolbar (trivial)— erledigte454eab(2026-07-05):ToolId+"circle", PlatzhaltercircleTool(nicht floorOnly),TOOL_COMMAND+TOOL_ORDER, Kreis-Icon inToolsPanel, i18ntool.circle/tool.circle.hint. tsc + Suite 331 grün. (Kreise rendern seit4ac99d3glatt als<circle>.)Bogen-Werkzeug (mittel)— erledigt (2026-07-05):arcCommandinsrc/commands/cmds/arc.ts(3-Klick: Mittelpunkt → Start/Radius → Endwinkel, CCW; Vorschau viaarcPts/circlePts), registriert inregistry.ts(Aliasa/bogen),"arc"als ToolId + Toolbar-Eintrag (Bogen-Icon) + i18n. tsc + Suite 331 grün. ✅ Center-/Quadrant-Snaps ergänzt (2026-07-05):collectCircles+ Snap-Block insnapping.ts— Mittelpunkt + Quadranten (Kreis: alle 4; Bogen: nur im Spannbereich) unter dercenter-Einstellung, Bogen-Endpunkte unterendpoint; +3 Tests (Suite 334).
-
BAUTEILE aufs Rhino-Niveau heben (Treppe/Fenster/Tür). Vergleich Rhino-Plugin ↔ TS + priorisierte Ansätze: RESEARCH_BAUTEILE_RHINO.md. ✅ Gruppe A (2D, Items 1–6) komplett — verifiziert 2026-07-05: (1) Treppe-Outline (
stairOutline, gerade/L/Wendel,generatePlan.ts:2186), (2) Fenster-Brüstungslinie (window-sill, gepunktet,sillHeight>0,:1810), (3) Tür-Sturzlinien (door-lintel+lintelLineskeine/innen/aussen/beide, gestrichelt,:1711), (4) Treppe-Referenz links/mitte/rechts, (5) Fenster-Flügel-Mittelpfosten, (6) Türwandoeffnung. Offen: Gruppe B (2D mittel: Tür-Schwung am Rahmen, Treppen-Pfeil-Stylefilled, Fenster/Tür-Presets,swing_invert) — Feinpolish. ✅ Fenster-Anschlag-Striche erledigt (8d688b9, Laibungsstriche quer zur Wand bei „fein", analog Tür; +2 Tests). Gruppe C (3D: Rahmen/Blatt/Glas/Sims als Mesh — wartet auf Mesh-/B-Rep-Pipeline). Der große Rest ist „Schnitt- vs. Ansichts-Darstellung" (eigenes Item unten). -
DWG/DXF-Import via
acadrust(weiterbauen). ✅ Spike763a558:acadrust0.4 (MPL-2.0, pure Rust) baut zu wasm32 (Cratesrc-tauri/dwgimport, 839 KB), parst DXF aus Byte-Buffer (DxfReader::from_reader+Cursor), headless getestet. Offen: (1) Entity→DOSSIER-Modell-Mapping (LINE/ARC/… → Wand/Öffnung — die eigentliche Domainarbeit, Wochen), (2) Datei-Upload-Glue im Browser (<input type=file>→Uint8Array→parse_dxf_summary_json, trivial), (3) DWG-binär (DwgReader::from_readeranalog, aber R13–R2018-Korrektheit unverifiziert), (4) WASM-Größe (nalgebra Haupttreiber). Klarstellung: der TS-DXF/DWG-Import (parseDxf/parseDwg/dxfToDrawings) + Upload-UI (App.tsx,ImportDialog.tsx) existieren längst und funktionieren — der acadrust-Weg wäre eine Rust-Neuimplementierung des Lesens (nur DWG-Schreiben ist eine echte Lücke). ✅ 2887794 (2026-07-05): Kurven-Abdeckungslücke geschlossen —parseDxfdeckt jetzt ARC/CIRCLE/ELLIPSE (tesselliert zu Konturen, Winkel Radiant, voller Umlauf geschlossen) zusätzlich zu LINE/LWPOLYLINE/POLYLINE/MESH ab; 5 Tests, volle Suite 307 grün. ✅ c481373 (2026-07-05): SPLINE + INSERT ergänzt —parseDxfwertet SPLINE als echte B-Spline (De Boor, Grad/Knoten; Fallback fitPoints/Kontrollpolygon) aus und expandiert INSERT-Block-Referenzen (2D-Transform Scale/Rotation/Basispunkt + MINSERT-Array + verschachtelte Blöcke, Tiefe ≤8) zu transformierten Konturen; Kontur-Dispatch in gemeinsamencollectContoursrefaktoriert; +7 Tests, volle Suite 314 grün. Bekannte Grenzen: rationale SPLINE-Gewichte ignoriert (dxf-parser liefert sie nicht); Block-interne MESH/3DFACE-Entities werden im 2D-Import nicht expandiert. ✅ c29f27e (2026-07-05): HATCH ergänzt — dxf-parser hat KEINEN HATCH-Handler (verwarf HATCH stumm); Lösung viaregisterEntityHandler+ eigenemHatchHandler(sammelt rohe Gruppencodes) + testbarerhatchContours-Auswertung: Randpfade (Polyline-Pfade + Linien-/Bogen-Kanten, Bögen über vorhandene Tessellierung) → geschlossene Konturen mitContour.filled;contoursToDrawingsmacht daraus gefülltepolyline-Drawing2D (fillColor-Default, restylebar). +6 Tests, Suite 320 grün. ✅05bc5aa(2026-07-05): HATCH-Ellipse/Spline-Kanten ergänzt (Kantentyp 3/4 tesselliert; B-Spline-Sampling insampleBSplineextrahiert). ✅4b93ac9(2026-07-05): TEXT/MTEXT —parseDxfliefertDxfImportResult.texts(ImportedText: Position/Höhe-in-Metern/Winkel-Radiant; MTEXT-Formatcodes grob gesäubert);textsToDrawings→{shape:"text"}-Drawing2D; Darstellung neu:addDrawing2Demittiert ein schlankeskind:"drawingText"-Primitiv, PlanView rendert es rein per SVG (modellverankert, Rotation; GPU-Guard so, dass es in ALLEN Renderer-Modi im SVG bleibt);toRenderSceneüberspringt es; ImportDialog zählt/importiert Texte. +5 Tests, Suite 327 grün. Bekannte Grenzen HATCH: Bulges an Polyline-Rändern als Sehne; Insel-Loops = eigene Ringe (keine echten Löcher). Bekannte Grenzen TEXT: importierte Texte (pointerEvents:none) noch nicht per Canvas-Klick selektierbar; MTEXT-Feinformatierung flachgeklopft; Block-interne TEXT/MTEXT nicht expandiert. Text im Tauri visuell abgenommen (Nutzer 2026-07-05) — auch gedreht korrekt. ✅4ac99d3: CIRCLE/ARC als echte glatte Formen —Contour.curveträgt die wahre Kreis-/Bogen-Geometrie (pts bleiben für Kontext/3D);contoursToDrawingsbaut{shape:"circle"|"arc"}; neue PrimitivedrawingCircle(SVG<circle>) +drawingArc(SVG-Bogenpfad),toRenderScenetesselliert sie für den nativen Pfad; +4 Tests, Suite 331. Ellipse bleibt tesselliert (kein Ellipsen-Primitiv). Weiter offen: Entity→Wand-Semantik (die dicke Domainarbeit); DWG-Schreiben (einzige echte Export-Lücke). -
STRATEGIE — „von BIM-Tool zu echtem CAD". Direkt am Quellcode studierte Referenzen (OpenCADStudio/truck/acadrust) + Web-Import-Landkarte → konkrete, priorisierte Ansätze in RESEARCH_CAD_APPROACHES.md. Kern: (1) generisches Entity-Modell + Trait-Dispatch, (2) modeless Command-System (
StepInput-Funnel + Kommandozeile), (3) DWG/DXF-Round-Trip viaacadrust(MPL-2.0, pure Rust, WASM-tauglich), (4) volle Object-Snap-Schicht, (5) 3D-B-Rep später selektiv viatruck(Apache-2.0, Geometrie-Crates WASM-fähig, Booleans/Fillets noch instabil). Derkernel2d-Rust/WASM-Kurs ist damit bestätigt. Mit Nutzer priorisieren, welcher Ansatz zuerst. -
Schnitt- vs. Ansichts-Darstellung nach Schnitthöhe (BIM-Standard). ✅ Phase 1 (Wand unter Schnittebene) erledigt (2026-07-05):
generatePlan.addWallPochehat einenviewOnly-Zweig — erreicht eine Wand die Grundriss-Schnitthöhe nicht (wall.height < floor.cutHeight, z. B. 0.3-m-Brüstung bei 1 m), wird sie nur als Ansichts-Umriss (Haarlinie,fill:"none", keine Schraffur) gezeichnet statt als Schnitt-Poché; normale Wände (≥ Schnitthöhe) unberührt. Segment-/Gehrungs-/Öffnungs-Logik geteilt. +2 Tests (generatePlan.viewwall.test.ts, Suite 336). ✅ Phase 2 (Decke über Ebene = gestrichelte Überkopf-Linie) erledigt (2026-07-05,39ddd9b): der freie Decken-Umriss (Überstände/Balkone, wo keine Wand verdeckt) ist jetzt gestrichelte Haarlinie (OVERHEAD_DASH) statt kräftiger Volllinie — BIM-Konvention „Aufsicht auf Bauteil über einem". Decken-FLÄCHE war schon Ansicht (viewHatchId, weiß). +1 Test. Offen (Phase 3): per-Component View-/Cut-Weight + eigene View-Schraffur (Slot-Trennung); cut/Aufsicht/Untersicht (Deckenspiegel/Reflected Ceiling Plan); Unterzüge; Feinheiten. Kern-Idee (Nutzer): jedes Bauteil bekommt getrennt eine Schnittlinie (kräftig, z. B. 0.25–0.35 mm, + Schnitt-Poché) und eine Ansichtslinie (Haarlinie); WELCHE gilt, entscheidet die z-Ausdehnung des Bauteils vs. die Schnitthöhe des Grundrisses (Default ~1 m):- Bauteil wird von der Schnittebene GESCHNITTEN → Schnittlinie + Schnitt-Poché (heutiges Wandverhalten).
- Bauteil liegt ganz UNTER der Ebene (z. B. 30-cm-Wand bei 1 m Schnitthöhe, Brüstung, Podest) → nur „von oben gesehen" = Ansichtslinie/Haarlinie, KEINE Schnitt-Poché. ← genau der vom Nutzer genannte Fall.
- Bauteil liegt ganz ÜBER der Ebene (Decke/Slab, Unterzug) → Ansicht, üblicherweise gestrichelte Überkopf-Haarlinie.
- Passt konsistent zum bereits existierenden
viewHatchId(Ansichts-Schraffur) vs. Schnitt-Schraffur — die Linienstärke-Dualität (View-/Cut-Weight je Component) ist die natürliche Erweiterung derselben Logik. - Nicht nur cut/view, sondern cut / AUFSICHT / UNTERSICHT (Nutzer): ein Bauteil sieht von oben anders aus als von unten. Der Grundriss (Blick nach unten) zeigt Bauteile UNTER der Ebene in Aufsicht (Oberseite); ein Deckenspiegel/Reflected Ceiling Plan (Blick nach oben) zeigt Bauteile ÜBER der Ebene in Untersicht (Unterseite — z. B. Kassettendecke, Leuchten). Also je Component potenziell drei Darstellungs-Slots (Schnitt / Aufsicht / Untersicht) × {Schraffur + Linienstärke}. Das heutige
viewHatchIdist faktisch EIN View-Slot und vermischt Auf-/Untersicht; sauber wäre die Trennung. WELCHER Slot gilt, entscheidet die Blickrichtung der Sicht (Grundriss ↓ / Deckenspiegel ↑) UND die z-Lage relativ zur Schnittebene. - Verallgemeinert den Decken-Footprint-Clip (
a2f6923): „Decke unter Wand verdeckt" ist ein Spezialfall von „Ansichtsbauteil vs. schneidende/überdeckende Bauteile". - Aufwand: mittel–groß, phasenweise machbar (1: z-Extent-vs-Schnitthöhe-Klassifikation cut/above/below; 2: Ansichtslinie-Weight je Component + Haarlinie/gestrichelt; 3: 30-cm-Wände & Slabs verdrahten). Nicht zu komplex im Konzept — es ist der reguläre CAD/BIM-Weg (ArchiCAD/Vectorworks/Revit). Mit Nutzer Detailgrade/Defaults festlegen.
-
Ebene-Schraffur editierbar— gelandetdcb6ed5: Kategorie-Dialog (App.tsx,editor.hatch-Feld) hat<select>aufcat.hatch+HatchSwatch-Vorschau. Verifiziert vorhanden. -
GEO-BLOCK (gemeinsame Dateien io/geoContext/swissTopo/terrain/ContextImportDialog/Viewport3D/siteSlice):
- Reale Höhen + Projekt-MüM (EG-Referenzhöhe): Terrain georeferenziert bei realem z relativ dazu, Gebäude auf Terrain drapiert (heute alles z=0).
- Luftbild/SWISSIMAGE-Orthofoto als Textur aufs Terrain-Mesh.
- Importierte Geo-Elemente auf aktives Geschoss (
viewSlice.activeLevelId) + Gelände-Ebene. - Nordstern-Geo-Rendering: importierte Meshes (heute nur three.js
importedMesh/terrainMesh) auch inprojectToModel3deinspeisen. - 3D-Mesh-DXF/DWG-Import (heute DXF nur 2D); Building-Draping; höhere DTM-Auflösung.
-
ResourceManager Bauteile-Tab auf Master-Detail— bereits Master-Detail (ComponentsTab/ComponentDetailinsrc/ui/ResourceManager.tsx, Liste linksres-md-list/ Detail rechts). Verifiziert vorhanden. -
Einstellungs-Fenster (Rest)— erledigt: Verdrahtung war schon da (viewSlice.snapColor/marqueeColor→ PlanViewSnapMarker/Marquee, Defaults austheme/accents.ts, Projekt-MüM-FeldreferenceElevationMasl); der einzig offene Punkt (Snap/Endpunkt-Default „aki") ist längst entschieden (2026-07-04: Sora #5FA1C9, s. „❓ Offene Rückfragen"). Zeile war stehen geblieben, obwohl die Frage schon geschlossen war. -
Bildschraffur: ambientCG/CGI-Colorfiles als Quelle (Material-Lib WIP — erst nach Freigabe); Bild-Filter Sättigung/Helligkeit/Kontrast/SW (
image.filters). -
Tragwerk-Start: Stützen (Column) — MVP end-to-end(DOSSIER-Audit A4) — erledigt 2026-07-07:Column/ColumnProfile(rect/round) als platzierte Profil-Extrusion,Project.columns,columnFootprint()(gemeinsame Geometrie 2D/3D/Selektion/Transform),columnVerticalExtent(UK/OK-Anker wie Wand). Platzieren via BIM-Ribbon-Befehl (column, Alias stütze; Default Rect 0.3×0.3, Höhe=Geschosshöhe, Rechteck/Rund-Toggle + Live-Vorschau), 2D-Poché auf Kat. 50 (addColumnPoche, Component/Hatch-Auflösung), 3D-Prisma (emitColumns, synchron, Rust unberührt), eigener Selektionskanal (ALLE Reset-Stellen gespiegelt),ColumnSection(Profil/Masse/Höhe/Drehung editierbar), Löschen/move/copy/mirror, DXF-Layer, i18n. +8 Tests (2D-Position/Rotation, 3D-Box/Prisma, vertikale Lage). tsc/vitest 422. Bewusst ausgelassen: 3D-Pick (wie ExtrudedSolid), Marquee, Schedule-Zeile, eigene ToolId (Extrude-Muster gefolgt). Noch uncommittet. Nutzer prüft 3D/2D visuell. -
Schnellexport-Dialog (Format + Dateiname) für Topbar-Export(Nutzer-Wunsch) — erledigt 2026-07-07: Klick auf CSV/IFC/OBJ/STL im Topbar-Export-Menü öffnet jetztExportSaveDialog(Format-Dropdown + Dateiname-Feld, Endung folgt dem Format, Enter/Speichern), statt sofort mit Default-Namen zu laden. PDF/DXF behalten ihre eigenen Options-Dialoge.runExport(format, filename)in App.tsx erzeugt+lädt. +i18nexportSave.*. tsc/vitest 434. Offen (bewusst, Nutzer nannte es selbst als Folge): echter Speicherort-Picker („wo") braucht den nativen Tauri-Save-Dialog (plugin-dialog/fs, Rust) — aktuell Download-Ordner + frei wählbarer Dateiname; die späteren „Ausschnitte" bekommen vordefinierten Namen+Ort. Noch uncommittet. -
Nativer Tauri-Speichern-Dialog für Exporte(Nutzer „ausnahmsweise JA") — erledigt 2026-07-07:@tauri-apps/plugin-dialog+plugin-fseingebunden (Cargo/lib.rs/capabilitiesdialog:allow-save+fs:allow-write-text-file,cargo checkgrün), Utilsrc/io/saveFile.ts(saveTextFile: unter Tauri nativer „Speichern unter"-Dialogsave()+writeTextFile, sonst Blob-Fallback mit octet-stream + verzögertem revoke; +2 Tests). App.tsx-downloadTextFileruft jetztsaveTextFile(Import ergänzt). Nutzer testet den nativen Dialog in Tauri. Scope-Hinweis: falls fs-Scope-Fehler,fs:scope$HOME/**nachrüsten. Noch uncommittet. -
Ausschnitte liessen sich nicht speichern (Tauri)— erledigt 2026-07-08: Ursachewindow.promptist im Tauri-WKWebView DEAKTIVIERT (→ null, kein Name, nichts gespeichert).ViewSnapshotsPanelnutzt jetzt In-App-Inline-Eingaben statt prompt/confirm (Speichern + Umbenennen inline, Löschen ohne confirm). tsc/vitest 465. -
Layouts als Ordner-/Baumstruktur— erledigt 2026-07-08: Modell additivLayoutFolder{id,name,parentId?}+Layout.folderId?+Project.layoutFolders?; freie GrössecustomWidthMm?/customHeightMm?an Layout UND MasterLayout (übersteuert paper/orientation), zentraler HelfereffectiveSheetSizeMm(). Pure LogiklayoutModel.ts:buildLayoutTree,collectFolderLayouts,deleteFolder(Kinder reparent auf Elternebene),folderPdfPages.LayoutsPanel.tsxals Baum (auf/zuklappbare Ordner, Master als eigener Vorlagen-Abschnitt), EIN „+"-Dropdown {Ordner·Layout·Masterlayout}, neues Element landet SOFORT im Inline-Rename (ViewSnapshotsPanel-Muster, kein window.prompt). Zwei Erstell-Dialoge (LayoutCreateDialogs.tsx): Layout mit Master-Vorlage-Dropdown ODER freie Grösse (A4/A3/Custom-mm); Masterlayout mit Format/freie Grösse+Ausrichtung. Ordner→Mehrseiten-PDF funktioniert:src/export/layoutPdf.ts(buildFolderPdf/saveFolderPdf, jsPDF,addPageje Layout mit eigener Grösse, Viewports via generatePlan→planToPrintSvg, Master-Titelblock als Vektor), neuersaveBinaryFileinsaveFile.ts(nativer Speichern-Dialog für PDF-Bytes). +14 Tests (Custom-Grösse, Ordner-CRUD, Baumaufbau inkl. verwaister Refs, Reparenting, PDF-Seitenplan). Nachtrag (Orchestrator):LayoutSheet.tsx(In-Viewport-Editor, vom Agent bewusst nicht angefasst) nutzte nochsheetSizeMm(layout.paper,...)ohne Custom-Grösse zu respektieren — aufeffectiveSheetSizeMm(master ?? layout)umgestellt (identische Regel wie der PDF-Export), damit Blätter mit freier Grösse auch im Viewport korrekt dargestellt werden. tsc/vitest 505. Noch uncommittet. Nutzer prüft visuell in Tauri (+-Menü, Ordner-Zuordnung, Dialoge, Mehrseiten-PDF-Reihenfolge/Grössen). -
Icons/A0-A6+B0-B6/aktiver Ordner/Drag&Drop im Layouts-Baum— erledigt 2026-07-08: eigene inline-SVG-Icons (FolderIconauf/zu,LayoutSheetIcon,MasterSheetIconmit Stern-Akzent), Muster wie die bestehenden Tab-Icons.LayoutPaperFormatvolle ISO-216-Reihe A0–A6+B0–B6 (PAGE_MM/PAPER_FORMATS/PAPER_FORMAT_GROUPS), Dropdowns gruppiert A-/B-Reihe. „Aktiver Ordner" war schon korrekt (verifiziert, keine Änderung nötig). HTML5-Drag&Drop (Layout/Ordner zwischen Ordnern, Root-Drop, Ziel-Highlight) mit Zyklus-Schutz (isDescendant,moveFolderToFolderverwirft Selbst-Verschachtelung als No-op).layoutPdf.ts/LayoutSheet.tsxbekommen die neuen Formate automatisch (laufen übereffectiveSheetSizeMm/PAGE_MM, kein Hardcoding). +14 Tests. tsc/vitest 519. Noch uncommittet. Nutzer prüft visuell. -
Ausschnitte-Panel: Footer-Bar + Anwahl-Persistenz— erledigt 2026-07-08 (Agent starb erst beim Schluss-Testlauf, aber vollständig verdrahtet + grün): Footer im ViewSnapshotsPanel zeigt bei angewähltem Ausschnitt Massstab, passende Ebenen-/Zeichnungskombi (Deep-EqualboolMapEqual/matchingComboNamegegen gespeicherte Combos), aktive Override-Namen, + Inline-Rename in der Footer-Bar. Anwahl bleibt markiert bis Abweichung:selectedViewSnapshotId-State +snapshotMatchesLiveState-Vergleich in App.tsx (bei Änderung eines erfassten Feldes → Auswahl weg). host.ts umselectedViewSnapshotId/listLayerCombos/loadLayerCombo/listDrawingCombos/loadDrawingComboerweitert. tsc sauber, vitest 532 (+13). Noch uncommittet. Nutzer prüft visuell. -
Ausschnitte-Panel: Ordner wie bei Layouts— erledigt 2026-07-08: echte Ordner-/Baumstruktur (spiegelbildlich zu Layouts). Modell additivViewSnapshotFolder{id,name,parentId?}+ViewSnapshot.folderId?(altesfolder?-Namensfeld bleibt LEGACY-kompatibel),Project.viewSnapshotFolders?. Pure Baum-Logiksrc/state/viewSnapshotFolders.ts(buildViewSnapshotTree/moveSnapshotToFolder/moveFoldermit Zyklus-Schutz/deleteFolder-Reparent, +20 Tests). Panel: auf/zuklappbare Ordner, zwei Header-Buttons (FolderPlus/Plus), aktiver-Ordner-State, Inline-Rename, Löschen, Drag&Drop. Footer-Bar + Anwahl-Persistenz UNVERÄNDERT erhalten (unter dem Baum). +i18n. tsc/vitest 558. Noch uncommittet. Nutzer prüft visuell. -
2D-Zeichnen auf „Zeichnung"-Ebenen UND auf Layout-Blättern freigeben; 3D/BIM dort sperren (Nutzer-Wunsch 2026-07-08): ✅ ALLE drei Teile erledigt 2026-07-08. TEIL B erledigt 2026-07-08: 2D-Annotationen (Linie/Rechteck/Text in mm-Papier) direkt auf Layout-Blättern —
LayoutAnnotationanLayout(additiv) + CRUD (layoutModel.ts: create/add/remove/patchAnnotation) + Editor inLayoutSheet.tsx(Tool-Buttons, zeichnen/Vorschau/commit,pickAnnotation/translateAnnotationinlayoutSheetMath.ts, Selektion+Verschieben+Löschen, HUD mit Farbe/Stärke,PromptDialogfür Text — kein window.prompt) + Handler in App.tsx. Tests:layoutModel.test.ts+layoutSheetMath.test.ts, Suite 588 grün. Bewusst ohne: Resize-Griffe, Text-Rotation, Snapping, Sheet-Clamping beim Verschieben. TEIL A erledigt 2026-07-08 — die 2D-Zeichenwerkzeuge (select/line/polyline/rect/circle/arc/text) sind bereits nichtfloorOnly, die zugehörigen Commands (line/rect/polyline/circle/arc/text) auch nicht → die Command-Engine erlaubt das Zeichnen auf jeder Ebene, und eine"drawing"-Ebene rendert schon die volle interaktiveLevelPlanView(App.tsx:5515). Der einzige echte Blocker war das UI-Gating: die ToolsPanel-Sidebar sperrte ALLE Werkzeuge ausser „select", sobald!toolsEnabled(App.tsxactiveLevel.kind === "floor"). Fix:ToolsPanel.tsxgatet jetzt pertool.floorOnly && !toolsEnabled— Parität mit dem Ribbon (RibbonBar.tsx, das schon so gatete). Damit sind auf „drawing"-Ebenen die 2D-Tools nutzbar, BIM/3D-Tools (wall/ceiling/window/door/stair/room/column, allefloorOnly) bleiben grau.AttributesPanel.tsx:78bleibt unverändert (gatet nur den Wandtyp/Deckentyp-Picker, der ohnehin nur bei floorOnly-Tools erscheint). Verifiziert:tscsauber,vitest558/558. TEIL B (grösser, OFFEN): auf Layout-Blättern 2D zeichnen — derLayoutSheet-Viewport-Editor kann bisher nur Viewports platzieren; für Annotationen (Linien/Text/Rechtecke direkt aufs Blatt) fehlt ein Annotations-Datenmodell amLayout+ das Zeichnen/Rendern auf dem Blatt (mm-Koordinaten). Scope Teil B mit Nutzer/als eigene Phase. TEIL C erledigt 2026-07-08 („endlich"): Text-Platzierungswerkzeug als 2D-Element. Das{shape:"text"}-Drawing2D-Modell + Rendering (generatePlan→drawingText) + Transform (transform.tsat) existierten schon (DXF-Import-Weg); es fehlte nur das PLATZIER-Werkzeug. Umgesetzt: neuestext-Command (src/commands/cmds/text.ts: Ankerpunkt klicken → Freitext in der Command-Line eingeben → commitDrawing2D {shape:"text", height:0.25m, angle:0}), Placeholder-Tooltext(nicht floorOnly) gekoppelt viaTOOL_COMMAND, in Registry + Aliase (tx/txt/beschriftung) +ToolId+TOOL_ORDER+ Ribbon-2D-Gruppe + ToolIcon (Serifen-A) + i18n (de/en). Neu: die Command-Engine routet jetzt Freitext-Eingabe (AcceptKindum"text"erweitert,engine.tsrouteTypedInputreicht beiaccepts:["text"]die getippte Zeile 1:1 durch — vor der numerischen Auflösung, damit auch Zahlen/Kommas als Label ankommen). Nutzer-Test: Text-Tool wählen → in den Plan klicken → Label tippen → Enter. Noch uncommittet, WASM-unabhängig (rein TS). -
Masterlayout im Viewport ansehen + Elemente darauf platzieren (Nutzer-Wunsch 2026-07-08) — NACH Rollback+Footer-Agenten (gleiche Dateien LayoutsPanel/LayoutSheet): ein Masterlayout soll wie ein Layout im
LayoutSheet-In-Viewport-Editor geöffnet werden können, um Plankopf-Elemente/Rahmen VISUELL darauf zu platzieren (statt nur über ein Formular mit festen Titelblock-Textfeldern).LayoutSheet.tsxarbeitet aktuell nur mitLayout(hatviewports: LayoutViewport[]); für Master fehlt sowohl das Öffnen im Viewport als auch ein Datenmodell für frei platzierbare Grafik-/Text-Elemente (Plankopf-Felder, Rahmen-Linien) auf dem Master. Scope/Umfang mit Nutzer klären, bevor gebaut wird: welche Elementarten (Text-Feld mit Platzhalter-Variable wie {ProjectName}/{Scale}/{Date}, Linie/Rechteck als Rahmen, Logo/Bild?), wie sie sich von den normalenLayoutViewports unterscheiden (kein Ausschnitt-Bezug, rein grafisch), Doppelklick-Navigation vomLayoutsPanelaus zum Öffnen eines Masters im Viewport (analogonOpenLayout). -
LayoutsPanel: Doppel-Name + zwei Buttons je Abschnitt + Master in Ordnern— erledigt 2026-07-08: Doppel-„LAYOUTS" behoben durch Umbenennung des ÄUSSEREN Panel-Titels auf „Mappe" (DE) / „Portfolio" (EN, neuer Keylayouts.panelTitle); innere Abschnitte bleiben „Layouts"/„Masterlayouts". Kombiniertes „+"-Dropdown ersetzt durch zwei Icon-Buttons je Abschnitt:FolderPlusIcon(Ordner) +PlusIcon(Layout bzw. Masterlayout). Masterlayouts jetzt in eigenen Ordnern:MasterLayout.folderId?+LayoutFolder.kind?:"layout"|"master"(fehlt=layout, rückwärtskompatibel), getrennte Bäume (buildMasterTree, kind-Filter), eigeneractiveMasterFolderId. Bug gefixt:deleteFolder/moveFolderToFolderverlorenkindbeim Reparent →stripParentId. +6 Tests. PanelFrame unangetastet. tsc/vitest 538. Bewusst offen: Drag&Drop im Master-Baum (bestehende Master nur beim Anlegen in Ordner). Noch uncommittet. Nutzer prüft visuell. -
Fixer, unlöschbarer „Masterlayout"-Ordner— VERWORFEN 2026-07-08 (Nutzer-Kurskorrektur): gebaut, dann sofort zurückgebaut — Nutzer sah die bestehende Lösung (Masterlayouts als separate Kategorie/Abschnitt ausserhalb der Ordnerstruktur, aus dem vorherigen Layouts-Agenten) live und wollte sie explizit BEHALTEN, keinen Ordner. Vollständig zurückgerollt (layoutModel.ts/LayoutsPanel.tsx/App.tsx/i18n), verifiziert tsc sauber + vitest exakt Baseline 519 (keine Regression). Masterlayouts bleiben separater Abschnitt. -
— erledigt 2026-07-08: neue generischewindow.prompt/confirmüberall ersetzen (Tauri-WKWebView deaktiviert sie) — SWEEPsrc/ui/PromptDialog.tsx(Muster ExportSaveDialog: Overlay+Dialog, Enter bestätigt, Esc schliesst) ersetzt ALLE verbliebenenwindow.prompt-Aufrufe:ComboMenu(TopBar, Ebenen-/Zeichnungskombination speichern),LayoutMenu(Arbeitsumgebung speichern), Text-Grösse „frei" (TextGroup), Massstab „frei" (ViewRibbonTab), sowie die Tastatur-Flows O/P (Array-Kopien/Verteilen-Anzahl,App.tsx:promptCount()entfernt, ersetzt durchpendingCopyMode-State + Dialog).window.confirmwar bereits an allen Fundstellen vorher entfernt (ViewSnapshots/LayoutsPanel). Verifiziert:grep -rn 'window\.prompt(\|window\.confirm('über src/ liefert NICHTS mehr. tsc sauber, vitest 491/491. Noch uncommittet. -
Layout im Viewport editierbar (wie ArchiCAD/VW/OpenCADStudio) — Phase 2b— erledigt 2026-07-08 (Agent-verifiziert, NICHT visuell abgenommen): Blatt jetzt erstklassiger Ansichtsmodus im Haupt-Viewport (activeLayoutIdin App.tsx →LayoutSheetViewstatt Content), schwebendesLayoutEditor-Fenster ENTFERNT. Maus-Editing (LayoutSheet.tsx): Viewport aufziehen→Ausschnitt-Bindung (Inline-Dropdown, kein prompt), auswählen/verschieben/8-Griff-Resize (Commit bei Pointer-Up, Live-Ghost), löschen (Entf), Massstab-HUD; Pan (Mitte/Space)/Zoom-to-Cursor/Einpassen. Pure Transform+Hit-TestlayoutSheetMath.ts(+26 Tests).LayoutsPanelwindow.prompt/confirm ebenfalls auf Inline umgestellt. +i18nlayouts.*, CSS.layout-sheet-*. tsc/vitest 491, vite build OK. NOCH VISUELL IN TAURI ZU PRÜFEN. Offen: Einrasten an Kanten/Nachbarn, Ribbon-Massstab wirkt im Layout-Modus nicht (nicht deaktiviert). Noch uncommittet. -
Layout-Blätter mit Masterlayout — Phase 2a(A3, setzt auf Ausschnitte auf) — erledigt 2026-07-08: ModellLayout/LayoutViewport/MasterLayout+Project.layouts/masterLayouts(im Dokument).LayoutsPanel(Layouts+Master anlegen/umbenennen/löschen, im Rechts-Dock,LAYOUT_VERSION10→11).LayoutEditor(schwebendes Fenster wie ResourceManager): Blatt im mm-Seitenverhältnis (Zoom/Einpassen), Titelblock (Master-Vererbung viaresolveTitleBlock, leere Felder → Defaults Projektname/Blattname/Massstab/Datum), und jeder Viewport rendert ECHT den Plan seines gebundenen Ausschnitts viageneratePlan→planToPrintSvg(viewBox-mm = Viewport-mm, 100%-Einpassung + Clipping). Viewport hinzufügen (Ausschnitt-Picker)/entfernen, Position/Grösse/Massstab numerisch; Papier/Ausrichtung/Master pro Blatt. +16 Tests (Blatt-Geometrie, immutables CRUD, Master-Vererbung, mm-Geometrie). +i18nlayouts.*. Ehrliche Grenzen: Live-Viewport-Render nur per Code korrekt, NICHT im Browser abgenommen (Nutzer prüft); Ausschnitte auf Schnitt/Ansicht (activeLevelId≠Geschoss) → leerer Plan (nur Grundriss-Ausschnitte füllen den Viewport); Titelblock-Font ≠ PDF-Helvetica (Phase-2b-PDF baut es separat). Bewusst Phase 2b: Multi-Page-PDF-Export, Maus-Drag/Resize der Viewports, „Alle aktualisieren", erweiterte Kamera-POV (Augen-/Zielhöhe). tsc/vitest 465. Noch uncommittet. -
Ausschnitte / View-Snapshots — Phase 1(A2, Fundament) — erledigt 2026-07-07:ViewSnapshot(name/folder + viewType/view3d/fov/scaleDenominator/detail/activeLevelId + Ebenen-/Zeichnungs-Sichtbarkeit + aktive Override-Ids) amProject.viewSnapshots(im Dokument). Pure Capture/Apply-Logiksrc/state/viewSnapshots.ts(+8 Tests: Roundtrip, defensives Auffüllen, Override-Menge). App.tsx: Capture sammelt View-State +snapshotLayer/DrawingVisibility+ aktive Overrides; Apply Reihenfolge Geschoss→View→Sichtbarkeit→Overrides, Massstab-Zoom per 1 rAF. NeuesViewSnapshotsPanel(Liste/Ordner, Speichern/Umbenennen/Löschen), registriert im Default-Rechts-Dock (LAYOUT_VERSION9→10). +i18nviewsnap.*. Bewusst offen Phase 2: Layout-Blätter+Masterlayout (A3), Viewport-Platzierung + Ausschnitt-Bindung, „Alle aktualisieren", Multi-Page-PDF, erweiterte Kamera-POV (Augen-/Zielhöhe getrennt), Ordner-Drag&Drop; Apply erzeugt mehrere Undo-Schritte (bekannt). Noch uncommittet. -
IFC-Wände nicht solid (oben/unten offen)— erledigt 2026-07-07: ECHTE Ursache war eine invertierte Wicklung, NICHT eine fehlende Fläche — der Y-up→Z-up-Achsen-Swap im IFC-Export ((mx,my,mz)→(mx,mz,my−base)) ist eine Reflexion (Determinante −1) und kehrte jedes Dreieck um → Normalen nach innen → Viewer cullt Vorderseiten → hohl. Fix: beim Swap Dreieck umdrehen (i0,i2,i1).Closed=.T.gesetzt, verifiziert überisWatertight(wallMeshCut.ts): NICHT der naive „jede Kante von 2 Dreiecken"-Test (der meldet die legitimen T-Stösse aus vollen Deckel/Boden-Streifen fälschlich als offen), sondern das T-Stoss-robuste Gauss-/Divergenz-Kriterium∮n dA=0+ signiertes Volumen >0. STL/OBJ waren korrekt (kein Swap). +15 Tests (Wasserdicht/Winding, inkl. IFC-Face-Set-Volumen aus dem geparsten SPF). tsc/vitest 449, cargo check grün. Noch uncommittet. Nutzer prüft im Viewer. -
Exporte an 3D angleichen: Öffnungen ausschneiden + Joins (STL/OBJ/IFC)(Nutzer: „es sollte so raus wie es im 3d ist") — erledigt 2026-07-07: neuer TS-Helfersrc/plan/wallMeshCut.tsportiertrender3d/mesh.rs::extrude_layer_segment_with_holes1:1 (Koordinaten-KompressionsolidSubrects, Langseiten/Deckel/Boden/Stirnkappen minus Loch-Intervalle, bis zu 4 Laibungsquads pro Loch, konsistentes Winding). STL/OBJ: Wände mitholes→ ausgeschnittenes Mesh (sonst klassische Box); Joins kommen auspickGeometry. IFC: Wände alsIfcTriangulatedFaceSet(IFC4, gespeist aus demselben Loch-Mesh) → sichtbar wie 3D in JEDEM Viewer (behebt „Void nicht subtrahiert"); Tür/Fenster bleiben eigeneIfcDoor/IfcWindow-Objekte, die das Loch füllen; IfcOpeningElement/Void/Fill entfallen (Loch steckt im Mesh). +12 Geometrie-Tests (Loch-Region hat keine Voll-Wand-Dreiecke, Laibungen vorhanden, dangling-refs grün). tsc/vitest 434. Ehrliche Rest-Lücken: echte Miter-Gehrungsflächen (Export nutzt die achsparallele pickGeometry-Näherung), Schicht-Farben (IFC-FaceSet ohne per-Vertex-Farbe/IfcStyledItem), Fensterglas/Rahmendetail. Noch uncommittet. Nutzer prüft im Viewer. -
Layout-Auswahl in die Einstellungen, umbenannt „Arbeitsumgebung"— erledigt 2026-07-07:LayoutMenu(Fenster-/Dock-Layouts) aus der TopBar-Zeile inSettingsDialogverschoben (neue erste Sektion),layoutMenu-Prop von TopBar → SettingsDialog umgehängt (ReactNode-Import in TopBar entfernt, da sonst ungenutzt). i18nlayout.*umbenannt (DE „Arbeitsumgebung", EN „Workspace") + neuesettings.section.workspace. tsc/vitest 423. Noch uncommittet. -
Export-Sammelmenü + Über-Dialog + Petrol-Punkt (TopBar-Feinschliff)— erledigt 2026-07-07: (1) Die 6 einzeln aufgereihten Export-Icons (PDF/DXF/CSV/IFC/OBJ/STL) zu EINEM „Export"-Knopf (ExportMenu,ios_share) mit Dropdown-Popover zusammengefasst — entschlackt die Chrome-Zeile; Import bleibt separat. (2) Klick auf die Wortmarke „dossier" öffnet einen In-App-„Über"-Dialog (AboutDialog: Marke, Version 0.1.0, Kurzbeschreibung, OSS-Lizenzen; Esc/Klick-ausserhalb schliesst). Wortmarke ist jetzt<button>(Chrome zurückgesetzt, Optik identisch). +i18nfile.export/about.*, CSS (tb-menu/about-*). tsc/vitest 422. Fix (Nutzer-Report „IFC nicht anwählbar"): Popover percreatePortalnach body (entkommt dem Topbar-Stacking-Context, der die unteren Einträge unter dem Ribbon verdeckte) + zweiterpopRefim Outside-Click-Handler (sonst schloss der mousedown das Menü vor dem Klick) — Muster wieContextMenu/Dropdown. Hinweis: In-App-Dialog statt nativem macOS-About-Panel (das bräuchte ein Rust-Command in src-tauri) — falls der native Panel gewünscht ist, Folge-Item. Noch uncommittet. -
Brand-Punkt petrolgrün— erledigt 2026-07-07:.brand-dotfix#0f766e(petrolgrün wie DOSSIER-Rhino-Plugin) stattvar(--accent). Feinton per Nutzer justierbar. -
OSM-Import auf 7 Kategorien— erledigt 2026-07-07: 3 neue Kontext-Kategorien im Overpass-Import —parking(amenity=parking, Fläche),railway(railway~rail|tram, Linie),forest(landuse=forest + natural=wood, ausgreenherausgelöst;greenjetzt nur Parks/Wiesen).OsmSelection/buildQuery/categorize/isClosedCategory(osm.ts),GeoCategory/Labels/Layer (geoContext.ts), 3 Checkboxen (ContextImportDialog.tsx), i18nctxImport.src.*. tsc/vitest 414. Noch uncommittet. -
IndexedDB-Persistenz-Kern— erledigt 2026-07-07:src/state/projectStore.ts— async CRUDsaveProject/loadProject/listProjects/deleteProjectüber IndexedDB (DB „dossier"/Store „projects", keyPath name,{name,savedAt,project}), guard-sicher (fehltindexedDB→ degradiert: load→null/list→[]/save+delete no-op, 1× warn) — läuft daher auch in vitest/node. +7 Guard-Tests (414). UI-Wiring (Speichern/Öffnen-Menü, Recent-Liste, Auto-Save) NOCH OFFEN — Folge-Item. Noch uncommittet. -
ObjectInfo Wand: UK/OK-Reihenfolge vertauscht— erledigt 2026-07-07: im Wand-Abschnitt steht jetzt OK (Oberkante) oben, UK (Unterkante) darunter — räumlich passend (Nutzer-Report „stimmt visuell nicht überein"); Decken-Abschnitt hatte die Reihenfolge schon → jetzt konsistent. Reiner JSX-Reorder. tsc/vitest 414. Noch uncommittet. -
STL- + OBJ-Export (3D-Mesh, Interop)— erledigt 2026-07-07: pures Modulsrc/export/exportMesh.ts(exportObj/exportStl, ASCII-STL) auspickGeometry(project)(echte 3D-Geometrie inkl. Joins/Decken-Dominanz): Wand-Bänder als 12-Dreieck-Boxen, Decken/Extrusionen als triangulierte Prismen (bestehendertriangulate()aus glPlanCompile, kein WASM), y-up rechtshändig. Voll verdrahtet: Quick-Access-Buttons (view_in_ar/landscape) +onExportObj/onExportStlin App.tsx (Blob-Download) + i18nfile.exportObj/file.exportStl. 8 Kern-Tests (Index-Bounds, facet/vertex-Konsistenz, Tri-Zahl-Plausibilität). tsc/vitest 407. Bewusste v1-Limitation: Öffnungslöcher NICHT ausgeschnitten (Wände volle Boxen) — ladbar in Blender/MeshLab, aber nicht öffnungsgenau; öffnungsgenaue Variante = Folge-Item. Extrusionen nutzen Prisma-Triangulierung statt async truckSolid-WASM (bewusst, wegen synchronem pure-Kern). Noch uncommittet. (IFC-Import + DWG-Schreiben bleiben offen.) -
Raumstempel: Personenzahl + Flächen-Rundung— erledigt 2026-07-07:RoomStamp.occupancy?/roundingStep?(additiv, optional).formatStampArea(area, step?)inroomStamp.tsrundet auf Vielfache vonstep(0.01/0.1/0.5/1 m²), sonst 2 Nachkommastellen wie bisher; Personenzahl als „{n} Pers."-Zeile im Stempel. Editor-Zeilen (Dropdown Rundung + Zahlfeld Personen). Drag&Drop-Builder bleibt out of scope. +6 Tests, +i18n. tsc/vitest 399. Noch uncommittet. -
Auto-Zoom nach Geo-Import— erledigt 2026-07-07: nach swisstopo/OSM/Terrain-Import (onAddContextObjects) passt die Plan-Ansicht automatisch auf die neuen Objekte ein.PlanViewHandle.fitBounds(pts)(dünner Wrapper umfitBoxFor),contextObjectsBounds()bildet die Gesamt-BBox über alle neuen ContextObjects (contourSet-Punkte + Mesh-/Terrain-Positions, Z ignoriert),addContextObjectsAndFitin App.tsx verdrahtet. DXF-Import-Pfad (eigene viewCenter-Logik) bewusst unberührt. Kein i18n, host.ts unverändert. tsc/vitest 393. Noch uncommittet. -
Rich-Text Hoch-/Tiefstellung (super/sub)— erledigt 2026-07-07: zwei Toolbar-Buttons inRichTextEditor.tsx(Muster der bestehenden B/I/U/S-Buttons; super/sub-Exklusivität war im ModellrichText.ts::applyMarkschon gelöst); +i18nrt.super/rt.sub. Teil des ROADMAP-Items „Rich-Text-Annotationen" (Maskierung/Rahmen bleiben offen/blockiert). tsc/vitest 393. Noch uncommittet. -
B2 — Objekt-Info numerisch erweitern— erledigt 2026-07-07: im ObjectInfo-Panel sind X/Y jetzt editierbar (Commit verschiebt die Selektion so, dass der gewählte Bezugspunkt auf die Koordinate wandert, via neuem Host-CallbackonMoveSelectionBy), dazu ein Dreh-Feld (RotateField, Delta-Grad um den Anker,onRotateSelectionAround) und für einzelne Drawing2D-line/circleein Längen- bzw. Radius-Feld (onSetDrawingLineLength/onSetDrawingCircleRadius). Move/Rotate nutzen die bestehendecommitTransform-Maschinerie (transform.ts unverändert), wirken für wall/drawing2d/extrudedSolid; für ceiling/opening/stair/room ist der Aufruf No-op (Feld rendert, revertiert — gleiches Muster wie das bestehende Breite/Höhe-Resize). +i18n. tsc/vitest 393. Noch uncommittet. -
Komponenten-Thumbnail: PBR-Kugel-Vorschau (D3-Rest)— erledigt 2026-07-07: ComponentsTab-Listeneintrag + Detail-Preview inResourceManager.tsxzeigen jetzt bei gesetztemcomponent.materialdie live gerenderte PBR-Kugel (ComponentMaterialSphere, lazy via IntersectionObserver +requestMaterialPreview, Muster vonMaterialLibraryTile);materialAssetOflöstlibraryIdgegenMATERIAL_LIBRARYauf, sonst Ad-hoc-Asset aus den eigenen Map-URLs. Fallback-Kette Material→Hatch→Color unverändert. NurResourceManager.tsx, kein i18n. tsc/vitest 393. Noch uncommittet. -
E2b Schraffur-Kachel-Motiv (MotifEditor für HatchStyle-Tile wiederverwenden).
-
Linienstile aufräumen— erledigt (2026-07-05): die drei funktional identischen 0.13-Volllinien (thin/hatch-line/joint-massive— alle weight 0.13,dash:null, gleiche Farbe) auf EINE kanonische „Volllinie 0.13" (thin) zusammengeführt; alle weight-only-Stile klar als „Volllinie X.XX" benannt; Schraffur-Referenzen (hatch-line→thin, inkl.ResourceManager.patToHatches) + Schichtfugen (joint-massive→thin) remappt;hatch-dash(einzige gestrichelte) bleibt. Ids stabil gelassen (geladene Projekte + interne Refs bleiben heil; Rendering-Gewichte unverändert). 7→5 Stile. tsc + Suite 331 grün. -
2D-Plan z-Anordnen (Kombo-Schraffuren); Bild-Schraffur GL/DXF (heute Fallback).
-
AUSSCHNITTE- + LAYOUT-SYSTEM (Nutzer-Vision 2026-07-07, grosser Hebel). Zwei zusammenhängende Systeme (DOSSIER A2→A3, ROADMAP §7 Phase 3 + §11 Pläne):
- Ausschnitte / View-Snapshots (A2): benannte, gespeicherte Ansichten, die einen kompletten Darstellungszustand einfangen und wiederherstellen. Kern-Einsicht des Nutzers: das muss NICHT neu erfunden werden — die Bausteine existieren schon und werden nur KOMPONIERT: ein Ausschnitt = Referenz/Snapshot auf {Ebenenkombination (
src/state/visibilitySets.tsLayerCombo) + Zeichnungsebenen-Kombination/-Einstellungen (DrawingComboebd.) + aktive Overrides-Regelmenge (Project.overrideRules, A1) + Kamera/Ansichtstyp/View3d + Massstab + Detailgrad}. Also im Wesentlichen ein Container, der diese bereits vorhandenen Zustände bündelt, benennt (Ordner/Presets) und per Klick wiederherstellt. Speicherort: Projekt (nicht localStorage — Ausschnitte gehören zum Dokument). Voraussetzung für die halbe Pläne-Tabelle (Layouts, Multi-Page-PDF, Detail-Bindung, Massstab-pro-Viewport). - Layout-System mit Masterlayout + Layouts (A3): Druck-/Plan-Blätter (A4/A3-Papierformate), auf denen mehrere Details/Viewports platziert werden, jedes an einen Ausschnitt-Snapshot gebunden (bei „Alle aktualisieren" ziehen sie nach). Ein Masterlayout (gemeinsame Elemente: Titelblock/Planrahmen/Logo/Plankopf, wie Vorlagen-Master in InDesign/ArchiCAD) wird von den einzelnen Layouts geerbt/überlagert — Änderung am Master schlägt auf alle Layouts durch. Pro Layout eigener Massstab pro Viewport (Auto-DPI, Plotweight-/Schraffur-Skalierung,
sceneToPrintSvg.tsals Basis), PDF-Export pro Blatt bzw. Multi-Page. - Erweiterte Kamera-Settings als Teil des Ausschnitts (Nutzer 2026-07-07): mehr einstellbare Kamera-Parameter, die der Ausschnitt MIT speichert — u. a. Zielhöhe und Augenhöhe (Eye/Target-Z getrennt), FOV, Blickrichtung/Distanz; die Parameter dürfen pro Projektionsart unterschiedlich sein (Perspektive vs. Isometrie/Ortho haben je eigene sinnvolle Sets — Iso braucht z. B. orthoHalfHeight statt FOV/Augenhöhe). Heutiger Zustand: nur FOV global (
fovin App-State, CameraMenu) + Orbit-State intern imWasm3DViewport(OrbitStateyaw/pitch/dist/target,orthoHalfHeight) — nicht als benannte, persistierbare Kamera-Definition nach aussen geführt. Schritt dazu: Kamera-Zustand als serialisierbares Objekt exponieren (get/set am Viewport), UI-Felder (Augenhöhe/Zielhöhe/Distanz) im Kamera-Popover, dann im Ausschnitt-Modell mitführen. - Phasen-Vorschlag: (1) Ausschnitt-Datenmodell + Speichern/Wiederherstellen (komponiert die bestehenden Combos/Overrides/View-State) + Ausschnitte-Panel (Liste/Ordner, wie
visibilitySets-Muster). (2) Masterlayout + Layout-Blatt-Modell + Viewport-Platzierung, Viewport→Ausschnitt-Bindung. (3) Master-Vererbung + „Alle aktualisieren" + Multi-Page-PDF@DPI. Mit Nutzer Detailgrade/Papier-Defaults/Ordnerstruktur festlegen.
- Ausschnitte / View-Snapshots (A2): benannte, gespeicherte Ansichten, die einen kompletten Darstellungszustand einfangen und wiederherstellen. Kern-Einsicht des Nutzers: das muss NICHT neu erfunden werden — die Bausteine existieren schon und werden nur KOMPONIERT: ein Ausschnitt = Referenz/Snapshot auf {Ebenenkombination (
-
SCHNITTEBENEN als editierbare, gekoppelte Objekte (2D↔3D) — Nutzer-Vision 2026-07-07 „ein richtig ausgereiftes Tool". Schnittebenen sollen sichtbare, im Grundriss platzier- und editierbare Objekte sein, die 2D-Schnitt und 3D-Live-Schnitt verbinden. Bausteine der Vision (verbindlich festhalten):
- Eigene Zeichnungs-/Grafik-Ebene „Schnittebenen": die Schnittlinie des 2D-Schnitts liegt auf einer eigenen Ebene (ein-/ausblendbar wie andere Layer). Auch die 3D-Schnittebene wird im GRUNDRISS als Objekt dargestellt (Linie/Symbol) — vor allem, um die 3D-Schnittebene dort PRÄZISE zu setzen (im 2D positionieren statt im 3D fummeln).
- 3D-Schnittebene über Topbar ein/aus (existiert teilweise: Viewport-Toggle) + Farbe; alles HINTER der Ebene (die weggeschnittene Seite) wird mit einer Misch-/Andeutungsschraffur umhüllt, damit visuell klar ist, dass dieser Teil abgeschnitten wird — sowohl im 3D als auch als Vorschau im 2D.
- Doppelklick auf eine Schnittebene → springt in die zugehörige Schnitt-Ansicht: 2D-Schnittebene-Symbol → 2D-Schnittfenster; 3D-Schnittebene-Symbol → 3D-Schnittfenster (Perspektive/Ansicht mit gesetzter Clip-Ebene). Zwei Objektarten, zwei Zielansichten, gleiche Interaktion.
- 3D-Schnitt-POV-Parameter: die 3D-Schnittebene definiert zusätzlich Blickpunkt (POV), Augenhöhe + Zielhöhe (getrennt) und Blickwinkel — dieselben erweiterten Kamera-Settings wie im [Ausschnitte-System oben] (dort pro Projektionsart mitgespeichert). Ein Schnitt ist damit ein Ausschnitt mit Clip-Ebene + Kamera-Definition.
- Verknüpfung: baut auf dem bestehenden 2D-Schnitt (
DrawingLevel kind:"section",linePoints/directionSign) + der 3D-Live-Schnittebene (03f0c40, Clip-Uniform) auf; koppelt eng mit dem Ausschnitte-/Layout-System (View-Snapshots) und den erweiterten Kamera-Settings. Grosses, phasenweises Feature — mit Nutzer Reihenfolge/Scope festlegen (zuerst: 3D-Schnittebene als 2D-Grundriss-Objekt platzier-/editierbar + Doppelklick-Navigation).
-
AUDIT (DOSSIER-Studie):
A1 Override-Regel-Engine✅ (2026-07-07, s. Erledigt); A2→A3 View-Snapshots → Print-Layout-Blätter (PDF pro Blatt); A5 reichere Öffnungen; B1 Text-Werkzeug (+ Kreis-Tool → Shortcuts 1&3); A4 Tragwerk; B2 Object-Info numerisch. (A6 Bauteil-Schedule-CSV erledigt; D2 volles Element-Set erledigt 2026-07-07.) Belege in/tmp/dossier-ref/rhino/*.py. -
Elemente im Schnitt anwählbar; render3d 2D-Schraffur auf 3D-Flächen.
-
TEAMWORK — kollaboratives Bearbeiten (Supabase self-hosted). Projekte auf einem self-hosted Supabase-Stack speichern; mehrere Nutzer bearbeiten dasselbe Projekt gleichzeitig. Kernkonzept: pessimistisches Object-Locking (wie Revit Worksharing / ArchiCAD Teamwork) — alle Objekte sind zunächst gesperrt; ein Nutzer reserviert die Elemente, die er bearbeiten möchte (exklusiver Schreibzugriff), und gibt sie frei, sobald er fertig ist. Freigabe → sofort für alle anderen sichtbar via Supabase Realtime (WebSocket-Kanal). Kein Merge-Konflikt nötig, weil niemals zwei Nutzer dasselbe Objekt gleichzeitig schreiben. Grobe Schichten:
- Auth + Projekt-Liste: Supabase Auth (Email/Magic-Link), Projektübersicht, Öffnen/Schliessen.
- Lock-Service: Tabelle
object_locks (project_id, object_id, user_id, locked_at)mit Row-Level Security;reserveObjects(ids[])/releaseObjects(ids[])als Supabase-RPC; Optimistisches Check-in via DB-Constraint (doppelte Reserve → Fehler → UI-Feedback). - Realtime-Sync: Supabase Realtime-Channel pro Projekt; bei Freigabe werden die veränderten Objekte (JSON-Patch oder ganzes Objekt-Payload, TBD) gepusht; lokaler Store merged incoming changes sofort.
- Presence: Wer ist online, wer hat welche Objekte reserviert (farbige User-Badges an reservierten Elementen im Plan).
- Offline-Guard: Beim Verbindungsabbruch Locks automatisch nach Timeout freigeben (DB-seitig:
locked_at + intervalprüfen). - Umfang/Granularität TBD mit Nutzer: Object = Wand/Raum/Drawing2D-Element? Geschoss? Layer? Feinere Granularität = mehr Parallelarbeit, aber komplexeres UI.
- Aufwand: gross (2–4 Wochen echte Arbeit). Erst sinnvoll, wenn Kern-CAD-Features stabil. Mit Nutzer Granularität + Hosting-Setup klären bevor Implementierung startet.
-
2D-Zeichnungen (— erledigt 2026-07-06: Nutzer-Report — früher wurden 2D-Plan-Elemente auch im 3D als flache Referenz bei z=0 gezeigt, das gab es nur noch im alten three.js-Fallback (drawings2d) fehlen im nativen render3d/WASM-Pfad bei z=0.addDrawing2DLines), nicht im nativenrender3d/wgpu-Pfad (heute Standard-Renderer). Fix OHNE Rust-Änderungen: neuer EmitteremitDrawingLines(src/plan/toWalls3d.ts) baut je 2D-Zeichnung (line/polyline/rect — Parität zudrawing2DSegmentsim three.js-Fallback, Kreis/Bogen/Text bewusst aussen vor) ein dünnes Ribbon-Mesh (2 Dreiecke je Segment,DRAWING_LINE_HALF_WIDTH0.008 m) knapp über der Geschossebene (DRAWING_LINE_ELEVATION_EPS0.01 m), Farbe viadrawingColor3d(color→LineStyle→Kategorie, wiedrawing2DColor) → hexToRgb. Läuft über den bereits bestehenden generischenRMesh/MeshInput-Kanal (kind:"imported",append_context_meshrendert ohnehin doppelseitig) — kein neuer Rust-Typ nötig.tsc/vitest339/339 grün. Nutzer-bestätigt (2026-07-06, Tauri-Dev-App selbst getestet): Linien aus dem 2D-Grundriss sichtbar in der Perspektive. Noch uncommittet.
3D-REST (engine-schwer, bewusst NICHT blind — mit Nutzer angehen)
Wand-Joins in 3D— erledigt 2026-07-07:toWalls3d.tswendet jetzt die per-Schicht-Cuts auscomputeJoins(pro Geschoss,computeJoinsByFloor) auf den layered-3D-Pfad an — dieselben Zahlen wie generatePlan im 2D: End-Cuts/Merge an L-/T-Stössen (Band-Mittellinie geschnitten, Kern läuft bis zur Rückgrat-Nahfläche durch, Putz trimmt), Durchgangswand-Span-Cutouts (Band zerfällt in Achsen-Teilstücke). Decken-Dominanz per Schicht (Scope-Erweiterung):trimWallTopForCeilings(kappte die ganze Wand) ersetzt durch per-Schicht-z-Subtraktion analogsubtractDominantBands— Wand behält volle Höhe, nur Bänder mit strikt niedrigerer joinPriority verlieren das Decken-z-Intervall (Kern läuft durch; dominiertes Band spaltet vertikal in unter/über). Öffnungs-Löcher je Teilstück korrekt rebased. Rust unverändert (Boxen parametrisch). Pick/Highlight jetzt konsistent verschnitten. vitest 383 (25 in toWalls3d.test). Auslassung ehrlich: Achsenbox bildet gekippte Miter-Stirnfläche nicht exakt ab (Band-Länge = Mittellinien-Schnitt) — passgenau bei rechten/stumpfen Winkeln, kleine Rest-Approximation an sehr spitzen. Noch uncommittet. Nutzer prüft visuell in der Tauri-App.Decken-Schnitt in 3D schneidet zu viele Schichten („Kranz durch die Dämmung")— erledigt 2026-07-07:collectCeilingCutters/emitWallintoWalls3d.tsprüft jetzt PER BAND, ob die Decken-Outline die Band-Mittellinie (wall.start + u·t + n·offset) im Grundriss überdeckt — via vorhandenempointInOutline(geometry/ceiling.ts), Achse in ~5-cm-Schritten gerastert + Bisektion an den Überdeckungsgrenzen (neue HelferbandCoverageIntervals/bisectBoundary); nur überdeckte Achs-Teilstücke bekommen den Decken-z-Schnitt, unbedeckte behalten volle Höhe. RepliziertsubtractDominantBands(echter geometrischer Überlapp statt wandweiter BBox). Am Sample: Backstein/Innenputz (innen) geschnitten, Dämmung/Aussenputz (aussen) laufen voll durch — kein Kranz. Die 3 falschen Alt-Tests des Vorgängers korrigiert (kodierten „alle Schichten geschnitten"), +2 neue (Voll-Überdeckung schneidet weiterhin alle; Teil-Längen-Überdeckung splittet entlang der Achse). Schnitt-Pfad/L-T-Joins/holes/Rust unberührt. tsc sauber, vitest 393. Noch uncommittet. Nutzer prüft visuell.- [~] 3D-Live-Schnitt: echte Bauteil-Schraffuren statt prozeduralem 45°-Muster (Nutzer-Wunsch 2026-07-07). — implementiert 2026-07-08 (wartet auf visuelle Nutzer-Verifikation nach WASM-Rebuild). Der ganze Weg von der 2D-Hatch-Definition bis in den wgpu-Cap-Pass ist gelegt:
toWalls3d.tsbildet je Materiallage/Decke via neuemhatchPatternId()/resolveComponentHatch()(ausgetHatch(comp.hatchId)) einHatch{pattern,angle,scale}→WallInput.hatch/SlabInput.hatch(additiv,#[serde(default)]) →section.rsreicht es überPrism→CutPolygon.hatch→section_fill.rsschreibt es je Cap-Vertex (CAP_FLOATS_PER_VERTEX5→8:[pos,u,v,pattern,angle_rad,scale]) →gpu.rsCap-Pipeline-Vertexlayout erweitert →shaders.rsCAP_WGSLwählt prozedural das Muster:0 none→weiss,1 solid→Vollton (Beton-Poché),2 diagonal→45° (bitgleich zum alten Muster bei angle=0/scale=1 → rückwärtskompatibel),3 crosshatch→Kreuz,4 insulation→Zickzack. Monochrom (Tinte auf Papier, nur MUSTER variiert — bewusst keine Farbe). Da der 3D-Viewer je Schicht EINE Box emittiert (layeredWalls:true), trägt jede geschnittene Schicht ihr eigenes Muster; ohne aufgelöste Schraffur → Fallback-Diagonale.cargo test -p render3d --features render63 grün (+2 section_fill-Tests, WGSL-Validierung inkl. Cap-Shader). WASM (npm run build:engine3d) noch NICHT gebaut (brauchte Netz) — Nutzer muss rebuilden + Tauri-Dev neu starten, sonst greift nichts.cargo check --target wasm32 --features webgrün. Noch uncommittet. - 3D-Snapping beim Ziehen (Nutzer-Wunsch 2026-07-07): alle Elemente sollen im 3D auf andere Punkte einrasten. Heute rastet das 3D-Griff-Ziehen NICHT ein — es projiziert die Maus nur frei auf eine Ebene (
rayPlaneY/rayPlaneinsrc/viewport/Wasm3DViewport.tsx:576-582); Snap wurde beim 3D-Griffsystem bewusst weggelassen (three.js-Snap blieb 2D-exklusiv). Nutzer nennt konkret: Wände beim Verschieben auf andere Punkte snappen, Decken ebenso, „eigentlich alle Elemente". Gewünscht ist also eine gemeinsame 3D-Snap-Schicht (Kandidatenpunkte: Wand-Endpunkte/Ecken, Decken-Eckpunkte, Extrusions-/Öffnungs-Anker, evtl. Rasterpunkte), gegen die der gezogene Griff/Körper im Weltraum einrastet — analog zur 2D-Snap-Infrastruktur (computeSnapinsrc/tools/snapping.ts). Zu klären mit Nutzer/Scope: welche Snap-Ziele in 3D (nur Endpunkte oder auch Kanten/Flächen/Raster?), Snap-Radius im Bildschirm- vs. Weltraum, visuelles Feedback (3D-Snap-Marker), und ob die 2D-computeSnap-Kandidatenlogik wiederverwendbar ist oder eine eigene 3D-Variante braucht. BetrifftWasm3DViewport.tsx(Drag-Pfad) + neue 3D-Snap-Hilfsschicht; die Store-Callbacks (onEdit3dVertex/onEdit3dBody/onEdit3dWallTop) bleiben. - [~] Textur-/PBR-Pipeline (Sampler/Bindings/UV in wgpu; dann
textured-Style +Component.texture3d/Material echt rendern). ✅ Erster Durchstich (0ca3b1d, Schachbrett). ✅ Farb-Textur-Array implementiert 2026-07-08 (wartet auf visuelle Nutzer-Verifikation nach WASM-Rebuild): Statt Schachbrett zeigt eine Wand mit zugewiesenem Material jetzt dessen Farb-Map. Voller Weg:WallInput.materialIndex: Option<u32>(1-basiert; 0 = Schachbrett-Fallback) →mesh.rsbuild_scene_mesh_textured()füllt je Vertex die Material-Ebene (dieselben Extrusionsfns → Geometrie-Parität) →gpu.rs: Schachbrett-Textur zutexture_2d_arrayerweitert,set_material_textures()baut[Schachbrett, Mat0, Mat1, …], zweiter Vertex-Buffer für die Ebene →shaders.rsMESH_TEXTURED_WGSLsamplt die Array-Ebene je Band (layer<0→Schachbrett) →web.rsWASM-Exportset_material_textures(rgba, layer_count)→ TS:wallMaterialColorMaps()/resolveComponentMaterialLayer()(deterministische Array-Ordnung), neuersrc/viewport/materialTextures.tsdekodiert die Farb-Maps im Browser (ImageBitmap→Canvas→getImageData 256²),useWasm3dRenderer.updateModellädt sie asynchron hoch (Signatur-Cache, Fallback auf Schachbrett bis geladen). Ehrlich als Rest: nur Farb-Map (keine Normal-/Roughness-/Metalness → Beleuchtung wie Shaded); der native Tauri-Push (nativeSync.ts) lädt keine Texturen → dort Schachbrett-Fallback (das WASM/Nordstern-Viewport im „Texturiert"-Modus hat den vollen Weg).cargo check --target wasm32 --features webgrün,cargo test63 grün. WASM noch NICHT gebaut (Netz) — Nutzer:npm run build:engine3d+ Tauri-Neustart. Verbleibende PBR-Lücken (~15–25 PT): Normal-/Roughness-/Metallic-Maps + Cook-Torrance-BRDF + Tangentenraum ~5–8 · Mipmaps (Blit-Pass) + anisotropes Filtern ~1–2 · Bild-Datei-Laden serverseitig statt Browser-Dekodierung ~1–2 · nativer Tauri-Textur-Push ~2–3 · UI/Persistenz-Feinschliff ~5–8. Noch uncommittet. Wand-Schicht-Bänder in 3D Option B— bereits umgesetzt inresolveWallBands(layered=true)(src/plan/toWalls3d.ts:236-241): 3D-Viewer-Pfad liefert je Materiallage ein eigenesWallBand(Dicke + Component-Albedo + Normalen-Versatz),pushSegmentemittiert jede Lage als eigene Voll-Box.dominantLayerColorist nur noch Fallback für den Schnitt-Einkörper-Pfad (layered=false). Verifiziert per Code-Lesung.Ortho-Ray-Picking— erledigt 2026-07-07:cameraRay(src/viewport/raycast3d.ts) war IMMER ein perspektivischer Pinhole-Strahl (ein Ursprungeye, Richtung variiert je Pixel) — für Front/Top/Side/Iso-Presets (die render3d orthografisch zeichnet) nur eine Näherung. Fix:cameraRaynimmt jetzt optionalperspective/orthoHalfHeight(neue optionale Felder aufRayCamera, rückwärtskompatibel — fehltperspective, bleibt das Verhalten exakt wie vorher) und baut beiperspective:falseechte PARALLELE Strahlen (Ursprung wandert lateral mit dem Pixel, Richtung immerf— exakte Umkehrung vonworldToScreens bereits vorhandenem Ortho-Zweig). Beide Aufrufer inWasm3DViewport.tsx(Klick-Pick + Griff-Drag) reichten schon das volleorbitCamera(o)-Objekt (inkl.perspective/orthoHalfHeight) durch — der Bug sass rein incameraRay, keine Änderung an den Aufrufstellen nötig. +2 Tests (raycast3d.test.ts: parallele Strahlen, Rückwärtskompatibilität ohneperspective-Feld).tsc/vitest341/341 grün.3D-Griffe/Editieren im nativen render3d/wasm-Pfad— erledigt 2026-07-06: existierte bereits vollständig im three.js-Fallback (Viewport3D.tsx/drawGrips), fehlte aber im nativen wasm-Pfad (Wasm3DViewport.tsx, seitWASM_ENGINE_ACTIVEder Standard-Renderer) — genau wie beim drawings2d-z0-Fund oben eine „existiert, aber auf dem falschen Pfad"-Lücke. Feasibility-Spike (Nutzer-Entscheid „Spike jetzt starten") zuerst nur Wand-Endpunkte, dann auf volle Parität ausgebaut: Wand-Endpunkt-/Höhen-/Verschiebe-Griff + 2D-Zeichnungs-Vertex-/Verschiebe-Griff, dieselben App.tsx-Callbacks (onEdit3dVertex/onEdit3dBody/onEdit3dWallTop) wie die three.js-Sicht. Wichtige Design-Korrektur unterwegs: erster Versuch zeichnete Griff-Marker als In-Szene-Geometrie (3-Achsen-Kreuz, dann Drahtgitter-Kugel) über den bestehendensetHighlightLines-Kanal — Nutzer-Feedback zweimal"immernoch kein GUI button sondern geometrie": nicht klar genug als klickbarer Punkt erkennbar UND farblich identisch mit dem Auswahl-Umriss auf derselben Ecke. Gelöst durch Umstieg auf ECHTE DOM-Buttons (position:absolute-Kreise über dem Canvas, Farben wie drei.js: Vertex orange/Höhe blau/Verschieben grün), deren Bildschirmposition einrequestAnimationFrame-Loop aus der aktuellen Kamera nachführt (worldToScreen, neue Umkehrfunktion zucameraRayinraycast3d.ts) — kein WASM/GPU-Push nötig, nur 2D-Projektionsmathe. Ziehen läuft überrayPlaneY/rayPlane(neu inraycast3d.ts) + dieselben Store-Callbacks.drawingGripVertices/drawingMoveAnchornachsrc/viewport/drawingGrips.tsausgelagert (gemeinsam von beiden Renderern genutzt, sonst zyklischer Import). Bewusst NICHT gebaut: Snap/Koinzidenz-Mitführen beim 3D-Ziehen (bleibt three.js-exklusiv).tsc/vitest339/339 grün. Nutzer-bestätigt (Wand-Endpunkt-Drag funktional in der Tauri-App getestet, dann Marker-Sichtbarkeit korrigiert). Noch uncommittet.
❓ Offene Rückfragen (an den Nutzer)
„aki" Snap/Endpunkt-Farbe— entschieden 2026-07-04: Sora #5FA1C9 als endgültiger Default festgeschrieben (src/theme/accents.tsDEFAULT_SNAP_COLOR, Doc aktualisiert). Frage geschlossen.- Floating-ResourceManager „headless" = ganz ohne Titelleiste? (aktuell MIT)
- Geo-Block: Projekt-MüM zuerst oder Nordstern-Geo-Rendering?
- Verifizieren/klären: Isometrie „echte" orthographische Iso (teilw. durch Locked-Iso
cb8fae5adressiert)? · TopBar-Detailgrad (zoom% ganz aus Footer)? · DOSSIER-Audit welche Features konkret übernommen?
✅ Erledigt (Verlauf, neueste oben)
Nur jüngste Session; ältere Historie siehe git log und HANDOVER-Narrative.
-
2026-07-10 Fenster-/Tür-Einstellungsdialog + reiche Öffnungs-Parameter (
1bbe814+c734802+2e13ec3, Studie docs/design/window-editor-vectorworks-study.md) — Nutzer-Feedback „Fenster/Türen mega mager". Das ⚙ der Öffnungs-Sektion öffnet neu einen dedizierten Dialog (OpeningEditorDialog.tsx): Kategorie-Sidebar (Basis/Grösse/Rahmen/Flügel/Sonnenschutz bzw. Türblatt), Flügeltabelle (Flügel/Pfosten + Öffnungsart + Anschlag je Flügel), Live-2D-Frontalansicht, Stil-Leiste mit „Als Stil speichern" (klont Typ → neuer benannter WindowType/DoorType). Modell additiv:SashDef[]/shading/glazingPanes+ HelfersashesOfWindowType/glazingPanesOf. Renderer konsumiert sie: 2D-Flügeltrennlinien aus Flügelbreiten + Öffnungsandeutung, glazingPanes-Glaslinien, gestrichelte Rollladenkasten-Kontur; 3D mehrscheibige Verglasung. +26 Tests, 659/659 grün. Offen (P1+, Studie §4): asymmetrische Rahmenbreiten, Oberlicht/Unterlicht als eigene Felder, Sprossengitter, Bank/Nische, Form (Rund/Spitz), echte wgpu-3D-Vorschau im Dialog, 3D-Rollladenkasten-Box. -
2026-07-10 Dach-3D-Ziehgriffe (
4ef40a0) — gewählte Dächer haben im wgpu-Viewport Eckpunkt-Griffe (achsparalleles Resize, Gegenecke fix), einen Verschiebe-Griff und einen First-Griff (vertikal ziehen → Dachneigung, Firstlage bleibt). StoremoveRoofGrip/moveRoofBy(coalescing) +onEdit3dRoofPitch(Höhe→Neigung). +3 Tests. Schliesst die „optionale Folge" des Dach-Features (s. u.). Tauri-Visualabnahme offen. -
2026-07-10 Messwert im Objekt-Info (
9b6dd80) — Live-Messwerte erschienen nicht im Panel; Ursache war ein eingefrorenes Memo (baseHost-Deps ohnedraft). Fix:measurementpro Render live inhostWithModeinjiziert. -
2026-07-09 Dächer (Grundfeature) (
1195d2a+31f2d63) — Roof-Element +geometry/roof.ts(Flach/Pult/Sattel/Walm/Mansarde/Zelt, BBox-basiert, First X/Y). Befehl „Dach" (BIM-Ribbon, Rechteck aufziehen, Form als Inline-Option), 2D-Plan (Traufe/First/Grat/Knick), 3D (emitRoofs, terrakotta), Demo-Dach RF1. +19 Tests. Offen: Auswahl/Attribut-Editieren/Löschen (s. „Als Nächstes"). -
2026-07-09 Fenster/Tür-Feedback (
4beae72+89e737b) — Fenster im 3D tiefer (Rahmen füllt Wanddicke, dünne Scheibe mittig); Detailgrad grob/mittel/fein wirkt im 3D; Fenster↔Tür-Umschalter entfernt; platzierte Öffnungen bekommen Standard-Typ (sonst kein Rahmen). Kernursache „sieht im 3D nicht so aus" = fehlender typeId behoben. -
2026-07-09 Decken-Griffe im 3D (
973ac6d) — gewählte Decken haben im wgpu-Viewport Eckpunkt- + Kanten-Mittelpunkt-Griffe (rautenförmig, eigene Farbe) + Verschiebe-Griff → moveCeilingGrip/moveCeilingEdge/moveCeilingBy (Store-Actions existierten schon fürs 2D). Neu: 3D-Griffgeometrie (computeGrips), Kanten-Drag (GripDrag „edge"), Prop-Kette Wasm3DViewport←Viewport3D←App (editCeilings/onEditEdge, Ziel um ceilingId). three.js-Sicht unverändert. Tauri-Visualabnahme offen. -
2026-07-09 Text-Styling-Leiste wirkt auf Freitext (
d0b9d22) — selektierter Freitext/Textspalte (Drawing2D shape „text") ist Formatier-Ziel der Oberleiste: Drawing2D-Text.marks (Schrift/fett/kursiv/Farbe); Grösse bleibt über Modell-Höhe (Meter, nicht pt). App.textTarget adaptiert via docFromText/plainText; generatePlan/PlanView rendern die Marks. +3 Tests. -
2026-07-09 Schichttrennlinie als Wand-Referenzlinie (
938d642) — Wall.referenceOffset (freier Achsversatz) übersteuert left/center/right; Object-Info-Dropdown listet je interne Fuge einen Eintrag (kumulierte Schichtdicken in selectionInfo). wallReferenceOffset bleibt EINE Quelle → 2D/Schnitt/3D erben es. +3 Tests. -
2026-07-09 Mess-Werkzeug: Polygonzug + Fläche + Objekt-Info (
492e1f8) — Länge je Segment + aufsummiert + FLÄCHE (ab 3 Ecken, Gauss); Live-Werte dauerhaft im Objekt-Info-Panel (ToolDraft.measure→PanelHost.measurement→ObjectInfoPanel); Rechtsklick beendet Pfad + armiert neuen (mehrere nacheinander). +4 Tests. -
2026-07-09 Tür/Fenster tief ausgearbeitet (
fa40429/142ba7e/9a65900) — DoorType/WindowType um frameKind (Zarge/Blockrahmen), frameWidth, insetFromFace/insetFace (Schichteinzug), transomHeight (Oberlicht), mullionRows (Kämpfer). ResourceManager-Typeditor + Seeds (Haustür Blockrahmen/Oberlicht, Fenster 2-flügl.+Oberlicht). 2D: opening-frame/-transom-Primitive. 3D: emitOpeningFrames (Rahmen/Sprossen/Kämpfer) + einzugs-/oberlicht-bewusste Scheiben. +13 Tests. 3D-Visualabnahme offen. -
2026-07-09 LICENSE (
dbe7d37) — offizieller AGPL-3.0-Text (gnu.org). -
2026-07-07 IFC4-Export (erste Scheibe) — reiner Kern
src/export/exportIfc.ts(exportIfcSpf(project)→string, kein WASM/Dependency, direkt IFC-SPF-Text, Muster wie exportDxf). Räumliche Hierarchie IfcProject→IfcSite→IfcBuilding→IfcBuildingStorey (jekind:"floor"), Elemente via IfcRelContainedInSpatialStructure. Geometrie durchgängig IfcExtrudedAreaSolid: Wand→IfcWall, Decke→IfcSlab, Öffnung→IfcOpeningElement+IfcRelVoidsElement + Tür/Fenster-Füllung+IfcRelFillsElement, Extrusion→IfcBuildingElementProxy, Treppe→IfcStair (vereinfachter Hüllkörper, keine Stufengeometrie). IFC-22-Zeichen-GUIDs deterministisch aus Element-id (FNV→128bit→IFC-Base64, gegen IfcOpenShell-Referenz verifiziert). SI-Einheiten, OwnerHistory. Quick-Access-Button (deployed_code) +onExportIfcin App.tsx (Blobmodel/ifc,<name>.ifc) + i18nfile.exportIfc. 8 Tests (wichtigster: KEINE dangling refs — jede#N-Referenz definiert + eindeutig). vitest 391. Bewusst offen/vereinfacht: IfcMaterialLayerSet (DirectionSense/Offset-Semantik ohne Viewer zu riskant — Folge-Item), Treppen-Stufengeometrie, Tür/Fenster nutzt dieselbe Box wie die Öffnung (kein Rahmen/Blatt).host.tsbewusst NICHT angefasst (Export-Callbacks leben in TopBarProps, nicht PanelHostValue — konsistent mit DXF/Schedule). ⚠️ Unit-Tests beweisen nur STRUKTURELLE STEP-Validität — Nutzer muss die .ifc in echtem Viewer (BIMcollab Zoom / IFC.js / Revit) gegenprüfen. Noch uncommittet. (STL/OBJ-Export + IFC-Import + DWG-Schreiben bleiben offen — s. Interop-Befund.) -
2026-07-07 ObjectInfo: Volumen/Länge bei Wand + Volumen bei Decke (Nutzer-Wunsch) —
selectionInfo.ts: WallInfo umlength/grossVolume/openingVolume/netVolume(Netto = Länge×Dicke×Höhe − Σ Öffnungen[Breite×Höhe×Dicke]), CeilingInfo umvolume(Fläche×Dicke). Panel zeigt bei Wand Länge + Netto-Volumen (Tooltip Brutto−Öffnungen), bei Decke Fläche + Volumen. +i18nobjinfo.volume/objinfo.wall.length/objinfo.wall.volumeGross. tsc/vitest 391. Noch uncommittet. -
2026-07-07 UI-Feinschliff-Runde (Nutzer-Session, Tauri live abgenommen): (1) Kamera-Settings (FOV-Popover) ZUSÄTZLICH oben in der TopBar-Chrome neben CSV, dafür UNTEN aus beiden Ribbon-Tabs entfernt → unten saubere 2×4 View-Icons (Nutzer-Korrektur: erst waren fälschlich alle Presets mit oben). (2) ObjectInfo: Bezugspunkt-Würfel fix quadratisch (64px, skaliert nicht mehr mit Panelbreite), X/Y/Z als Spalte rechts daneben (
objinfo-refrow/objinfo-xyzcol). (3) Wand/Decken-UK/OK-Unterzeile in normale Label/Wert-Struktur: „Referenzgeschoss" + Dropdown in der Wertspalte, bei Eigene „Eigene Höhe" linksbündig (+2 i18n-Keysobjinfo.anchor.*). (4) Ansichten-Ribbon: Detailgrad + Darstellung übereinander gestapelt (einetb-stack-Gruppe), alte separate Darstellungs-Gruppe entfernt. tsc sauber, vitest 377/377. Noch uncommittet. -
2026-07-07 Basis-Materialien mit Default-Textur (Nutzer-Wunsch „nicht dass ich sie zuweisen muss und jeder Reset zerstört es") — Seed-Components in
src/model/sampleProject.tstragen ab Werkmaterial(viamaterialFromAsset, exakt der ResourceManager-Zuweisungsweg): Aussen-/Innenputz→Plaster001, Backstein→Bricks104, Beton→Concrete048. Bewusst OHNE: Dämmung + Estrich (kein passendes Asset in der 12er-Bibliothek — nicht geraten). Alt-Projekte unberührt (Feld optional). three.js-Viewport rendert automatisch texturiert; nativer Renderer weiterhin ohne Texturen (bekannter 3D-REST). tsc sauber, vitest 377/377. Noch uncommittet. -
2026-07-07 Element-Übersicht / BIM-Tree-Panel (ROADMAP §11, Phase-1) — neues
src/panels/ElementTreePanel.tsx: dreistufiger Baum Geschoss→Bauteilklasse→Element ausscheduleRows()(Textfilter mit Auto-Aufklappen; Klick = selektieren, Shift/Doppelklick = selektieren+zoomen).ScheduleRow.floorIdadditiv (CSV unverändert), Host-CallbackonSelectScheduleRow(App.tsx setzt korrekten Selektionskanal, wechselt bei Bedarf Geschoss + defert 1 rAF gegen den Geschosswechsel-Reset). Registriert inbuiltinPanels.tsx+ Default-Rechts-Dock (LAYOUT_VERSION8→9). Legacyproject.doorsbewusst ausgefiltert (tot; echte Türen sindOpening kind=door). +i18nelements.*. vitest 377/377, tsc sauber. Bekannte Grobheit: Zoom nutztfit()(ganzer Plan) stattfitSelection(), weil letzteres nur lokal geklickte Indizes kennt undPlanView.tsxgesperrt war — Element wird per Auswahl-Outline sichtbar. Nebenbei: NUL-Byte inexportSchedule.ts(Kollision paralleler Schreibzugriffe) repariert. Noch uncommittet. -
2026-07-07 Decken-UK-Verdrahtung nachgezogen (Orchestrator) —
onSetCeilingBottom-Handler in App.tsx ergänzt (MusteronSetCeilingTop); das UI-Feld aus dem Decken-UK/OK-Item ist damit funktional statt inert. tsc sauber, vitest 377/377. -
2026-07-07 Kamera-Presets: Kardinal + Iso-Oktanten (Milestone B3-Teil, OHNE Nord-Rotation — die bleibt Nutzer-Entscheid) —
View3djetzt front/back/side(=Rechts)/left/top/iso + 3 weitere obere Iso-Oktanten (vorne-links/hinten-rechts/hinten-links; untere 4 bewusst weggelassen) + perspective. RustCameraPreset/preset_camera/web.rssynchron erweitert (+2 Tests, cargo render3d 60/60), three.js-Pfad (Viewport3D.tsx) in Parität,VIEW3D_ORBIT-Seeds analytisch. UI: 4 Kardinal-Buttons + Iso-Split-Button mit Oktanten-Popover (ViewRibbonTab + Ribbon3dTab). WASM-Rebuild sauber, tsc sauber, vitest 372/372. Visuelle Abnahme im Tauri offen. Noch uncommittet. -
2026-07-07 Decken UK/OK-Override (ROADMAP §11, Phase-1-Item) —
Ceiling.bottom?: VerticalAnchor(additiv),ceilingVerticalExtentlöst bottom-Anchor vorzTop−thicknessauf (exakt das Wand-Muster); wirkt automatisch in 3D (toWalls3d) UND Schnitt (toSection), da beide denselben Resolver konsumieren. ObjectInfo: UK-Zeile jetzt editierbareVerticalAnchorRow(i18n-Key existierte). Neue Testsmodel/wall.test.ts(5). vitest 377/377, tsc sauber. ⚠️ Folge-Zeile:onSetCeilingBottom-Handler in App.tsx (~5 Zeilen, Muster onSetCeilingTop) war ausserhalb der Agent-Lane — wird vom Orchestrator nachverdrahtet, bis dahin ist das UI-Feld inert. Noch uncommittet. -
2026-07-07 A1 Override-Regel-Engine (Top-Item des DOSSIER-Audits) —
OverrideRule(condition: layer_name|object_name × equals|contains|starts_with|not_equals → actions: color/lineweight/linetypeId) additiv anProject.overrideRules; pure Enginesrc/overrides/engine.ts(effectiveOverrides: additiv, oberste aktive Regel gewinnt pro Feld, case-insensitiv, layer_name matcht Name ODER Code); Einhängung als Render-Dekoration ingeneratePlan.tsNACH der By-Layer/By-Object-Kette (Wände/Decken/Räume/Öffnungen/Treppen/Drawing2D; Projektdaten unverändert, jederzeit reversibel); ResourceManager-Tab „Overrides" (Master-Detail, Prioritätsliste ▲/▼, Aktiv-Checkbox). +18 Tests (engine 12, generatePlan-Integration 6). vitest 372/372, tsc sauber. Bewusst offen: user_string-Bedingung (kein Tag-Feld am Element), 3D-/Schnitt-Pfad, Presets/Templates (C2), Drag-Reorder; Overrides-Tab im ANGEDOCKTEN ResourcesPanel-Adapter vorerst nur lesend (Handler optional gehalten — Mini-Folge-Item). Noch uncommittet. -
2026-07-07 SIA-416: AGF-Kategorie ergänzt (Lücken-Schluss aus dem Milestone-Abgleich) —
SiaCategory+AGFingeometry/roomArea.ts, Rollup NUR in GF (nicht NF/NGF): Bilanz-Reihenfolge HNF·NNF·NF(Σ)·VF·FF·NGF(Σ)·KGF·AGF·GF(Σ), GF = NGF+KGF+AGF. Dropdown/Bilanz-Panel/CSV übernehmen generisch ohne Änderung. Neue TestdateiroomArea.test.ts(8 Tests). vitest 366/366 grün. Noch uncommittet. -
2026-07-07 D2 Bauteil-CSV volles Element-Set —
exportSchedule.tsdeckt jetzt Tür/Fenster/Öffnung/Treppe/Extrusion zusätzlich zu Wand/Decke ab, exakt nach dem in HANDOVER.md hinterlegten Scope (Tür/Öffnung: Breite/Höhe/Fläche, Geschoss via Wirtswand; Treppe: Lauflänge + totalRise, Fläche bewusst leer; Extrusion: Höhe + polygonArea, Geschoss via levelId; Räume weiterhin im eigenen Raum-CSV). Aggregat-Zeile generalisiert (totalLength/totalArea> 0 ? Wert : leer — kein irreführendes 0.00 bei Treppe). Tests erweitert (Fixture + Zeilen-Asserts je neuem Element).tscsauber,vitest341/341 grün. Noch uncommittet. -
2026-07-06
extrude-Befehl im 3D-Ribbon-Tab —Ribbon3dTab(src/ui/TopBar.tsx) kannte nur Kamera/Darstellungsart, nicht den seit Phase 3 existierendenextrude-Befehl; neue Gruppe mit Befehls-Button (gleiches Muster wieRibbonButtons Befehls-Zweig:CommandIcon+ Label aus der Registry, deaktiviert ohne aktives Geschoss, aktiv-Highlight bei laufendem Befehl).onRunCommand/activeCommandneu durchgereicht (App.tsx). tsc sauber. -
2026-07-06 truck-Integration Phase 4 (Boolean) — Mesh-CSG via
csgrsumgesetzt, technisch bewiesen (Details s. oben bei „Phase 4"): zweiter Spike (csgrs, Mesh-Ebenen-BSP statt B-Rep) löst exakt den Fall, an demmonstertruck-solidscheiterte; nutzerautorisiert als echte (Git-gepinnte) Abhängigkeit intrucksolideingebaut (boolean.rs, WASM-Exportboolean_mesh, TS-WrapperbooleanMesh()).cargo test11/11,wasm32-unknown-unknown-Build + echterwasm-pack-Build sauber. UI-Verdrahtung (wann automatisch subtrahieren) bewusst offen gelassen — Scope-Entscheidung, kein Technik-Risiko mehr. -
2026-07-05 Schnitt/Ansicht Phase 2: Decke über Schnittebene = gestrichelte Überkopf-Linie (
39ddd9b) — freier Decken-Umriss (Balkon-/Vordach-Überstände) jetzt gestrichelte Haarlinie (OVERHEAD_DASHingeneratePlan.ts,addCeilingPoche) statt Volllinie; Decken-Fläche war schon Ansicht (viewHatchId).lwMm-Param entfernt (feste Haarlinie). +1 Test, Suite 337. -
2026-07-05 Schnitt/Ansicht Phase 1: Wand unter Schnittebene = Ansichtslinie —
addWallPoche(viewOnly)ingeneratePlan.ts:wall.height < floor.cutHeight(Brüstung/Podestrand) → Umriss-Haarlinie (fill:"none", NO_HATCH) statt Schnitt-Poché; normale Wände unberührt (Segment-/Gehrungs-/Öffnungslogik geteilt). +2 Tests (generatePlan.viewwall.test.ts), Suite 336. Erster Baustein des BIM-Standard-Items „Schnitt vs. Ansicht nach Schnitthöhe". -
2026-07-05 Ribbon Phase 4: modulare Custom-Bar (Tab „Eigene") — datengetrieben auf der bestehenden Registry: neuer
custom-Tab,CustomBarinRibbonBar.tsxrendert die vom Nutzer gewählten Items + einen „+ Hinzufügen"-Picker (Dropdown mit Häkchen, listet ALLE Werkzeuge/Befehle ausALL_RIBBON_ITEMS, Klick = an/abwählen).itemKey/itemFromKeyfür stabile Persistenz; State in App (customItems) via localStorage (dossier.ribbon.customItems). GleicheRibbonButton-Aktivierung wie normale Tabs (kein Sonderweg). tsc + Suite 334 grün. -
2026-07-05 Ribbon Phase 3 (Teil): Werkzeug-Sidebar raus —
DEFAULT_LEFT_GROUPSnur nochattributes(volle linke Höhe),LAYOUT_VERSION7→8 (gespeicherte Layouts fallen auf neuen Default zurück → sichtbar). Wandtyp-/Deckentyp-Picker vonToolsPanelinsAttributesPanelverschoben (Nutzer-Entscheid „ins Attribute-Panel") — erscheint bei aktivem Wand-/Decken-Werkzeug (Sektion „Neues Bauteil", auch ohne Auswahl), Host-State unverändert.ToolsPanelbleibt registriert (per Fenster-Menü andockbar),Dropdown-Import dort entfernt. tsc + Suite 334 grün. Offen: Objektinfo unter Attribute mergen. -
2026-07-05 Fix: gezeichnete/importierte Kreise+Bögen im WebGL unsichtbar — der WebGL-Compiler (
glPlan/glPlanCompile.ts, Default-Renderer) dispatchtepolygon/line/arc, aber NICHTdrawingCircle/drawingArc→ seit4ac99d3(Kreise als echtesdrawingCircle-Primitiv statt 64-Eck-Polygon) fielen sie im GL still raus (SVG-/WASM-Pfad hatten sie, GL nicht). Zweig ergänzt: bildschirm-adaptive Tessellierung wie beimarc-Primitiv (Kreis geschlossen + optionale Vollton-Füllung, Bogen a0..a1 offen). tsc + Suite 334 grün. Nutzer-Report („zeichne Kreis, bleibt nicht sichtbar"). -
2026-07-05 Textur-Spike verifiziert erledigt (
0ca3b1d) — bei der Backlog-Abarbeitung festgestellt, dass die render3d-Textur-Spike (RenderStyle::Textured, Schachbrett, planare Meter-UVs,MESH_TEXTURED_WGSLgroup 1,spike3d-T-Toggle) bereits vollständig umgesetzt + committet war;cargo test58/59 grün, keine neuen Deps, Alt-Pfad bitgleich. „Als Nächstes"-Eintrag war veraltet → abgehakt; PBR-Restlückenliste (~18–29 PT) in 3D-REST übernommen. -
2026-07-05 Ribbon-Feinschliff (OCS-Zeile) — Tabs in die TopBar-Zeile verlegt (
456ebc8, eine Leiste Chrome+Tabs, Inhalt darunter; Tab-State in App); OCS-Chrome: kleine Wortmarke „dossier." + Quick-Access-Icons für ALLE Datei-/Export-Aktionen statt Burger-Menü, Zeile auf 26px (4e3b074); Text-/Font-Formatierung mit der Ansichts-/Zoom-Steuerung auf EINE Leiste gelegt, „Ansichten" als Standard-Tab zuerst + initial aktiv (fe22cbf). Alle tsc + 331 Tests grün. Visuelle Abnahme (26px, Icon-Sitz) noch offen. -
2026-07-05 Ribbon Phase 2: TopBar → „Ansichten"-Tab gemergt (
85011cb, Nutzer-Entscheid „voll mergen") — die Ansichts-/Zoom-/Darstellungs-Cluster der TopBar (View-Grid+Kamera, Ebenen-/Zeichnungs-Kombis, Detailgrad, Massstab/Zoom, Darstellungsart) alsViewRibbonTab(inTopBar.tsx) in den Ansichten-Tab verschoben; App reicht sie alsviewsContent-Node anRibbonBar(analog Layout-Menü). TopBar ist jetzt schmale globale Leiste (Marke/Ressourcen · Text · Datei/Export/Einstellungen · Fensterknöpfe).TopBarPropsentsprechend verschlankt. Visuelle Feinabstimmung offen. -
2026-07-05 Ribbon-UI Phase 1 (
9d6e86d) — datengetriebene Tab-Leiste (src/ui/ribbon/:ribbonItems.tsRegistry,RibbonBar.tsx,CommandIcon.tsx) unter der TopBar, additiv (Sidebar bleibt). Tabs 2D·3D·BIM·Ansichten; 2D=Zeichnen(select/line/polyline/rect/circle/arc)+Ändern(move/copy/mirror/offset/trim/join), BIM=Bauteile(wall/window/door/stair/ceiling/room); 3D/Ansichten noch leer. Ein Aktivierungs-Pfad: tool→onSelectTool, command→onRunCommand(engine.start); Aktiv-Highlight überactiveTool/engineView.commandName.ToolIconaus ToolsPanel exportiert (wiederverwendet). -
2026-07-05 Attribut-Panel: ein Grid, volle Breite (
ace0dc6) — drei getrennte Grids zu EINEM durchgehenden Zwei-Spalten-Grid gemerged (Wertspalte über alle Sektionen bündig), Dropdown-Pills füllen die Wertspalte (fixe Breiten raus), doppeltes Eigen-Padding + zweiter „Attribute"-Titel entfernt. Nutzer-Report. -
2026-07-05 Eigenschaften-Grid OCS-Stil (
00733d8) —.attr-*als klares Grid: Sektion-Balken, Zeilentrenner, füllende linksbündige Wertfelder (Texte/Zahlen/Dropdowns einheitlich). Erste Stufe der Ribbon-UI-Vision. -
2026-07-05 Zoom-Scroll-Fix (
077e774) — Dokument-Overscroll/Rubberband gesperrt (html,body,#root { overflow:hidden; overscroll-behavior:none }); Viewport-Zoom zieht die UI nicht mehr mit (macOS). Nutzer-Report. -
2026-07-05 Kreis- + Bogen-Werkzeug (
e454eab,bd2b12b) — Kreis-Toolbar (circleCommand gekoppelt) + neuesarcCommand(3-Klick CCW), beide mit Toolbar-Icon/i18n; rendern glatt viadrawingCircle/drawingArc. -
2026-07-05 DXF-Import: Platzierungsoption (
dd76ec8) — ImportDialog fragt „relativ zum Nullpunkt" ODER „in die Mitte der aktuellen Ansicht";PlanViewHandle.viewCenterModel()neu;runImportverschiebt den Gesamt-Umriss (bbox-Mitte → Ansichtsmitte). tsc + Suite 331 grün. -
2026-07-05 Zeichnungen Copy/Paste über Geschosse (
376aa67) — Ctrl/Cmd+C kopiert gewählte Drawing2D tief; Ctrl/Cmd+V fügt Klone (neue IDs) auf dem AKTIVEN Geschoss ein und wählt sie. Für z. B. importiertes Mobiliar. Textfeld-Fokus bleibt natives Copy/Paste. -
2026-07-05 Tauri Drag&Drop + Import-Dialog-Fix (
c5b5ca6,45e19b7) —import-Befehl alsautoRun(Datei-Dialog öffnet synchron in der Geste, HMR-Falle via Config-Relaunch behoben);dragDropEnabled:false(Tauris natives Drag-Drop fing HTML-Drops ab). Nutzer-bestätigt: Dialog + Text gehen. -
2026-07-05 Layout: Befehlszeile in Mitte-Spalte (
c794fee) — nur Viewport-breit, Docks gewinnen Höhe. Nutzer-bestätigt „sieht clean aus". -
2026-07-05 Textur-Spike render3d (
RenderStyle::Texturedreal) — zweiter Vertex-Pfad[pos,normal,uv]aus dem Mesh abgeleitet (Alt-Pfad bitgleich, per Test belegt), prozedurales 256×256-Schachbrett (kein Asset/image-Crate), Textur-Bind-Group group 1,MESH_TEXTURED_WGSL(gleiche Beleuchtung, Albedo aus Sampler), Pipeline bitidentisch zur Haupt-Pipeline,spike3dperTumschaltbar. Verifiziert: cargo test 58/59 (inkl. naga-Test) grün, alle 4 Builds sauber. Visuelle Fenster-Abnahme durch Nutzer bestanden 2026-07-05 (Schachbrett korrekt,T-Umschaltung ok). Erster Durchstich der Textur-/PBR-Pipeline; ehrliche Lückenliste im Bericht —8556037 -
2026-07-04 Grundriss: Decke drückt nicht mehr durch die Wände — Decken-Umriss an Wand-Footprints (OBB) geclippt; Füllfläche strokelos, Umriss nur über unverdeckte Teilstücke (Überstände). Deckungsgleiche Decke ⇒ Umriss entfällt. vitest 230, tsc sauber —
a2f6923 -
2026-07-04 T-Stoss-Putznaht entfernt — L-Seitenlinie nur noch bei materialFREMDEM Nah-Putz; materialgleicher Putz verschmilzt nahtlos (Nutzer-Direktive „Naht entfernen"). TS+Rust synchron, 3 Tests gezogen, cargo 8/8 —
a5ebfa7 -
2026-07-04 Snap-Farbe entschieden: Sora #5FA1C9 als endgültiger Default festgeschrieben (
DEFAULT_SNAP_COLOR, Doc), „aki"-❓ geschlossen. -
2026-07-04 Mac-Build via Tauri + Queue-Abgleich — Toolchain auf macOS-Gerät verifiziert,
cad.app/cad_0.1.0_aarch64.dmggebaut & gestartet. Verifikations-Baseline grün (tsc/vitest 230/cargo 56). Queue-Reconciliation: Toolchain-Blocker, Snap-Slice (339202b), Ebene-Schraffur (dcb6ed5), Bauteile-Tab-Master-Detail, Einstellungs-Verdrahtung UND Wand-Schicht-Bänder 3D (Option B,toWalls3d.ts) waren allesamt bereits gelandet, aber in PENDENZEN noch als offen gelistet → abgehakt. (kein Code-Commit) -
2026-07-04 Öffnungen als echte Boolean-Löcher (+ Deckentrim-nur-3D) — Fenster/Türen = 1 Wandkörper mit rechteckigen
holes(Rechteck-Gitter-Zerlegung + Laibungsquads), Segment-Boxen weg; Deckentrim nur noch im 3D-Pfad, Schnitt volle Höhe. Pflicht-Testfall versetzt-überlappende Fenster grün. cargo test 56, vitest 230, build:engine3d + tsc sauber —1407c68 -
2026-07-04 Joins Phase 1c Durchgangswand am T-Stoss echt aufbrechen (spanCutouts) —
c5a344d -
2026-07-04 Locked-Iso-Fix freie Kamera bleibt nach Ortho-Preset orthografisch —
cb8fae5 -
2026-07-04 3D-Live-Schnittebene mit schraffierten Schnittflächen —
03f0c40 -
2026-07-04 Joins Phase 2 Merge-Regel im Schnitt (gleiche Komponente verschmilzt) —
82d354f