Beide GEO-BLOCK-Design-Punkte (persistenter Standort-Anker, Kontext-Meshes im 3D anwählbar) sind umgesetzt; offene Teilaspekte (frei wählbarer Referenzpunkt, Ebenen-Zuordnung) bleiben dokumentiert.
125 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
-
GEO-BLOCK Folgepunkte (2026-07-12, nach dem swissBUILDINGS3D-DXF-Fix) — Nutzer-Report, noch NICHT umgesetzt:
- ✅ Georeferenzierung (Teil-Fix,
ae47b4f):Project.geoAnchor(persistenter Modell↔LV95-Referenzpunkt) ergänzt — der ERSTE Import in einem Projekt setzt ihn, ALLE folgenden Importe verwenden denselben Anker statt je eigenständigmakeOrigin(center)neu zu berechnen (behebt die Lage-Inkonsistenz zwischen mehreren Importen). Bewusst nur Teil-Fix: der Anker sitzt immer bei Modell-(0,0) — es gibt noch KEIN Werkzeug, um ihn auf einen beliebigen, vom Nutzer gewählten Modellpunkt zu legen. Wenn das eigene Gebäude nicht nahe (0,0) gezeichnet ist, bleibt die Lage weiterhin ungenau. Frei wählbarer Referenzpunkt bleibt offen. - ✅ Importierte Gebäude/Terrain sind jetzt anwählbare Meshes im 3D-Viewport (
e6a7738): Klick im WASM-3D-Viewport pickt Kontext-Meshes per Raycast (raycast3d.ts/pickGeometryintoWalls3d.ts), Auswahl bekommt einen eigenen Kanal (selectedContextObjectIds), Bounding-Box-Umriss als Highlight (volles Dreiecks-Wireframe wäre bei grossen Importen zu dicht), Entf-Taste löscht,SitePanel-Liste hebt die Auswahl hervor. Bewusst NICHT umgesetzt: die „auf einer Ebene"-Zuordnung (keincategoryCode/Layer-Feld anImportedMesh/TerrainMesh, keine Sichtbarkeits-Kopplung an die Ebenen-Verwaltung) und keine volle Attribut-Bearbeitung (nur Name-Anzeige/Löschen, keinederiveSelection()-Integration ins Attribute-Panel — als zu gross für diesen Schritt eingeschätzt). Ebenen-Zuordnung bleibt offen, ggf. eigener Design-Entscheid nötig (eine feste „Import"-Ebene vs. frei zuweisbar). - ✅ Zwei echte Bugs im swissBUILDINGS3D-Pfad behoben (
35a6834+9705890): (1) Absturz bei riesigen Kacheln (JSZip „Invalid string length" — DXF komprimiert stark, eine Kachel unter dem 150-MB-Limit kann entpackt trotzdem >700 MB Text ergeben; nurasset.sizeaus der STAC-API zu prüfen reichte nicht, jetzt zusätzlich die JSZip-interne Grössenschätzung + genereller Try/Catch, übersprungene Kacheln landen sichtbar inskippedTiles/UI-Meldung statt stumm 0 Gebäude). (2) Der eigentliche „Import funktioniert nicht"-Bug: die installiertedxf-parser-Version liefert Polyface-Mesh-Face-Indizes als vier einzelne Felder (faceA/faceB/faceC/faceD, Gruppencodes 71–74) statt alsfaces-Array — unser Code prüfte auf das Array, das nie existierte, jede swissBUILDINGS3D-DXF-Kachel ergab dadurch 0 Dreiecke. Live gegen echte Kacheln verifiziert: jetzt tausende Dreiecke mit realistischen Höhenwerten. Damit ist der Gebäude-Import technisch lauffähig — die beiden Design-Punkte oben (Georeferenzierung, Ebenen-Zuordnung) bleiben offen.
- ✅ Georeferenzierung (Teil-Fix,
-
3D-Kanten-Folgepunkte ("Schattiert mit Kanten", 2026-07-12) — nach dem Fix der falschen Flächendiagonalen (
7dc8f0d) zeigte der Nutzer drei weitere Beobachtungen, NOCH NICHT behoben:- Fenster-Rahmenecken überlappen statt sauber zu stossen (Screenshot: doppelte/kreuzende Linien an den Blendrahmen-Ecken bei „fein"). Vermutlich KEIN Kanten-Rendering-Bug, sondern echte überlappende Geometrie — die Rahmen-/Sprossen-Riegel (
openingAxisBoxintoWalls3d.ts) sind separate Boxen ohne Gehrung/Union an den Stössen. Nutzer-Folgewunsch dazu: bei „fein" einstellbar machen, ob die Ecke vertikal-dominant, horizontal-dominant oder auf Gehrung gelöst wird. - Dach ebenfalls kein sauberer Verschnitt am First/Grat (Screenshot: kleines Störtriangle exakt am First-Apex). Gleiche Kategorie — mehrere Dachflächen (
emitRoofs) sind separate, nicht verschnittene Meshes. - Im OG viele vertikale Striche auf den Wandflächen — noch NICHT diagnostiziert (nicht als Textur-Pipeline-Artefakt bestätigt, evtl. eine mehrschichtige Wandtyp-Verkleidung mit vielen dünnen Einzelelementen). Braucht weitere Untersuchung, idealerweise mit Angabe welcher Wandtyp/welche Schicht im betroffenen Projekt verwendet wird.
- Alle drei sind vermutlich Fälle für eine echte Boolean-Verschneidung (Kandidat:
csgrs/boolean_mesh, bereits als WASM-Export vorhanden aus der truck-Integration, s. u.) statt nur Kanten-Heuristik — grösserer, eigener Task.
- Fenster-Rahmenecken überlappen statt sauber zu stossen (Screenshot: doppelte/kreuzende Linien an den Blendrahmen-Ecken bei „fein"). Vermutlich KEIN Kanten-Rendering-Bug, sondern echte überlappende Geometrie — die Rahmen-/Sprossen-Riegel (
-
Warteschlange „für danach" (Nutzer 2026-07-12, noch nicht begonnen):
- Luftbild/SWISSIMAGE wahlweise als Drapierung auf das Terrain-Mesh ODER als eigenständiges „Dokument" einfügbar (Bild/PDF generell als einfügbares Dokument-Objekt — noch keine Anforderungen präzisiert).
- Import-Mesh (swissBUILDINGS3D u. Ä.) wahlweise geglättet („gerundet") oder kantig/eckig belassen, wählbar beim Import oder am Objekt.
-
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, Bank/Nische, Laibungsverkleidung, Form (Rund/Spitz/Schräg).
echtes Sprossengitter✅ erledigt 2026-07-12 (00bff27):mullionCols(vertikale Sprossen-Spalten) spiegelbildlich zumullionRows— 3D-Rahmen-Riegel, Ansichts-Trennlinien + Glasscheiben als echtes rows×cols-Raster, Eingabefelder inOpeningEditorDialog/ResourceManager. - 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):
- ✅ swissBUILDINGS3D 1:1 + swissALTI3D-Terrain erledigt 2026-07-12 (
ed724be): Root Cause warswissTopo.ts::fetchBuildings(generalisierter 1:25'000-Kartografie-Layer, nur Grundriss,DEFAULT_BUILDING_HEIGHT=9-Pauschalkiste) + grobeprofile.json-Terrain-Näherung. Fix: neuesstacApi.ts(gemeinsamer STAC-Client) +swissBuildings3d.ts(echte Wände/Dach-Meshes aus swissBUILDINGS3D-DXF-Kacheln, Generation 2.0 (stabil) UND 3.0 (Beta) wählbar, über den bestehendendxfParser.tseingelesen — kein neuer Parser nötig) +swissAlti3d.ts(echtes swissALTI3D-Höhenraster, 0.5 m/2 m wählbare Punktdichte statt Näherung).ContextImportDialog.tsxentsprechend erweitert (Gebäude-Modus aus/vereinfacht/2.0/3.0, Terrain-Auflösung). Referenz war das Rhino-Vorgänger-Plugin (git.kgva.ch/karim/DOSSIER,rhino/swisstopo.py). Pipeline nutzt render3d (nicht Three.js, Nutzer-Entscheid 2026-07-12 „scheiss auf three.js darstellung render3d ist fokus"). Nordstern-Geo-Rendering— war bereits erledigt (35299307d, 2026-07-09, stand hier fälschlich noch als offen):emitMeshesintoWalls3d.tsliestproject.context(importedMesh/terrainMesh) bereits und speist sie inprojectToModel3dein — keine weitere Verdrahtung nötig, war Voraussetzung für den swissBUILDINGS3D-Fix oben und stand schon.- 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. - 3D-Mesh-DXF/DWG-Import (heute DXF nur 2D bei manuellem Import — der Mesh-Pfad selbst ist über
dxfParser.tsschon 3D-fähig, s. o.); Building-Draping; höhere DTM-Auflösung.
- ✅ swissBUILDINGS3D 1:1 + swissALTI3D-Terrain erledigt 2026-07-12 (
-
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-12 Georeferenzierung: persistenter Standort-Bezug statt Neuberechnung je Import (Teil-Fix) (
ae47b4f) — erster Design-Punkt aus dem GEO-BLOCK-Report umgesetzt. NeuesProject.geoAnchor({lv95, model, label?}) verbindet einmalig „dieser LV95-Punkt = dieser Modellpunkt"; der ERSTE Import in einem Projekt setzt ihn automatisch, alle folgenden Importe (ContextImportDialog) verwenden denselben Anker statt je unabhängigmakeOrigin(center)neu zu berechnen — behebt die Lage-Inkonsistenz zwischen mehreren Importen in einem Projekt.tscsauber, Suite 794 grün. Bewusst Teil-Fix: Anker sitzt immer bei Modell-(0,0), es gibt noch kein Werkzeug, um ihn auf einen beliebigen, vom Nutzer gewählten Modellpunkt zu legen — bleibt offen. -
2026-07-12 Kontext-Meshes (importierte Gebäude/Terrain) im 3D-Viewport anwählbar (
e6a7738) — zweiter Design-Punkt aus dem GEO-BLOCK-Report umgesetzt. Raycast/pickGeometry(raycast3d.ts/toWalls3d.ts) um Kontext-Meshes erweitert (rohe Dreiecke ausproject.context, kaputte Indizes robust übersprungen), neuer Auswahl-KanalselectedContextObjectIds(Store-Slice +onViewport3dPick-Zweig, konsistent in ALLE bestehenden Auswahl-Reset-Stellen eingehängt), Highlight als achsenparallele Bounding-Box (volles Dreiecks-Wireframe wäre bei importierten Gebäuden mit tausenden Dreiecken unbrauchbar dicht), Entf-Taste löscht die Auswahl (reusedproject.context-Filter im bestehenden Lösch-Handler),SitePanel-Liste hebt die im 3D gewählte Zeile hervor (host.selectedContextObjectIds). +9 Tests (raycast3d.test.ts,toWalls3d.test.ts), Suite 803 grün,tscsauber. Bewusst nicht umgesetzt: Ebenen-/Layer-Zuordnung (categoryCodeanImportedMesh/TerrainMesh), volle Attribut-Panel-Integration (deriveSelection()) — als eigener, grösserer Schritt eingeschätzt, s. „🔧 In Arbeit" oben. -
2026-07-12 3D-Ansicht: „Schattiert mit Kanten" (BIM-Look) + Fix falscher Flächendiagonalen (
a84dc7a+7dc8f0d) — neuerRenderStyle::ShadedEdges(render3d): Bauteilfarben + dunkle Modell-Kanten obenauf, wie Revit/ArchiCAD. Direkt danach Nutzer-Report: sichtbare Dreiecks-Diagonalen auf Dach/Fensterglas im neuen Modus. Root Cause: Kontext-Meshes (Dach/Glas/Rahmen, auch swissBUILDINGS3D-Import) werden wegen aktivem Backface-Culling IMMER doppelseitig aufgebaut (mesh.rs::push_ctx_tri, Dreieck + gespiegelte Rückseite) — jede Kante bekam dadurch ein exakt entgegengesetztes Normalen-Paar, das die Knick-Erkennung fälschlich als Kante wertete. Fix inedges.rs::should_draw: Rückseiten-Duplikate (dot≈-1) werden vor der Rand-/Knick-Entscheidung zusammengeführt. +11 Rust-Tests, 88/88 grün (--features render). Drei Folgepunkte dabei entdeckt, noch offen (s. „🔧 In Arbeit" oben): Fenster-Rahmenecken/Dach-First ohne sauberen Verschnitt (vermutlich fehlende Boolean-Union, kein Kanten-Bug), OG-Wandflächen mit vielen vertikalen Strichen (nicht diagnostiziert). -
2026-07-12 swissBUILDINGS3D-Import repariert: Absturz + eigentlicher „funktioniert nicht"-Bug (
35a6834+9705890) — zwei getrennte, echte Bugs gefunden und behoben. (1) Harter Absturz (JSZip „Invalid string length") bei Kacheln, deren ENTPACKTE Grösse (DXF komprimiert stark) die max. JS-String-Länge sprengt, obwohl die ZIP-Grösse selbst unter dem Limit lag —downloadAssetTextprüft jetzt zusätzlich die JSZip-interne Grössenschätzung und fängt alle Fehler sicher ab; übersprungene Kacheln landen sichtbar inskippedTiles/einer UI-Meldung statt eines stummen Leer-Ergebnisses. (2) Der eigentliche Grund, warum der Import nie Gebäude lieferte: die installiertedxf-parser-Version liefert Polyface-Mesh-Face-Indizes als vier einzelne Felder (faceA..faceD, Gruppencodes 71–74) statt als erwartetesfaces-Array —addPolyfaceMeshprüfte auf ein Array, das nie existierte, jede swissBUILDINGS3D-DXF-Kachel (exakt dieses Format) ergab dadurch 0 Dreiecke. Live gegen echte Kacheln verifiziert (vorher 0 Meshes, jetzt tausende Dreiecke mit realistischen Höhenwerten). +3 Tests mit rohem DXF-Text (deckt auch die zugrundeliegende Bibliothek ab), Suite 794 grün. Georeferenzierung und „anwählbares Mesh auf Ebene statt Geo-Panel-Eintrag" bleiben als eigene, ungelöste Design-Fragen offen (s. „🔧 In Arbeit" oben). -
2026-07-12 Fenster-Grundriss komplett überarbeitet (
e65a6b7..d2758ef, iterativ über mehrere Live-Prüfungsrunden in Tauri) — Nutzer-Report mit SIA-Referenzbildern deckte mehrere übereinanderliegende Probleme auf, alle einzeln gefixt + verifiziert:- Sims/Anschlag-Kerben nutzten pauschal die volle Wandfläche statt der tatsächlichen (ggf. per
insetFromFaceeingezogenen) Rahmen-Aussenkante. - Stulp-Marken waren kleine, von der Rahmentiefe unabhängige Quadrate statt Profilquerschnitte über die GANZE Rahmentiefe; die Blendrahmen-Querschnittsblöcke an den Laibungs-Enden fehlten komplett — beide jetzt als
meetingMarksinwindowSymbolberechnet (inkl. Laibungs-Enden),generatePlan.tsnutzt sie direkt statt einer zweiten, abweichenden Neuberechnung. - Zusätzliche
window-mullion-Trennlinie lag redundant NEBEN dem neuen Rahmenblock (entfernt, für typisierte Fenster reicht der Block; Alt-Pfad ohne Typ behält die Linie). - Glaslinie(n) im Feld (mittel: 1, fein: Doppellinie) komplett entfernt — Nutzer wollte dort keine Haarlinie, unabhängig von Detailgrad/Position.
- Pauschale Brüstungslinie (Wandachse, unabhängig von Rahmenposition) UND die „Oberlicht-Andeutung" (gestrichelt bei
transomHeight>0, ebenfalls immer auf der Wandachse unabhängig davon ob die Schnittebene den Kämpfer trifft) beide entfernt — architektonisch nicht aussagekräftig für einen horizontalen Grundriss-Schnitt. - Ersatz:
WindowType.sillLine— konfigurierbare Auf-/Untersicht-Andeutung (Fläche aussen/innen/beide, Blickrichtung Auf-/Untersicht), an der echten Rahmenkante statt der Wandachse. - Neu:
Opening.frameLine/sashLine/sillLineStyle— Farbe/Strichstärke je Linien-Kategorie (Blendrahmen+Stulp / Flügelrahmen+Sprossen / Sims) im Objekt-Info-Panel einstellbar, Default = bisheriges Verhalten. - +~30 Tests über mehrere Dateien, Suite 790 grün.
- Sims/Anschlag-Kerben nutzten pauschal die volle Wandfläche statt der tatsächlichen (ggf. per
-
2026-07-12 Dach-Wand-Verschneidung (Z-Fighting im 3D behoben) (
a584911) — Nutzer-Report mit Screenshot (flackerndes Rausch-Muster wo Wand-Oberkante die Dachschräge kreuzt). Root Cause: Wände bekamen ihre Höhe unabhängig vom Dach,collectCeilingCutterskappte nur gegenproject.ceilings, nie gegenproject.roofs— wo die geneigte Dachfläche den flachen Wand-Top kreuzte, überlappten sich beide Volumen. Fix:roofUndersideAt(geometry/roof.ts, Ebenengleichung je Dachfläche + Punkt-in-Polygon) liefert die Dach-Unterkante an einem Grundriss-Punkt;clipPieceToRoofs(toWalls3d.ts) zerlegt betroffene Wand-Achsenstücke in feine ~15-cm-Schritte und klemmt jeden auf die dort gemessene Unterkante — Treppenstufen-Annäherung an eine echte geneigte Giebelwand-Stirnfläche (render3d-Wandkörper haben nur einen flachen Top; eine echte Schrägfläche bräuchte einen neuen Mesh-Pfad, bewusst nicht gebaut). Ohne Dach im selben Geschoss unverändertes Verhalten. +9 Tests (5roofUndersideAt, 3 Integration inkl. Regressionsfund einer legitim gekappten Putz-Gehrungsspitze im Sample-Projekt), Suite 781 grün. Verwandt: design-schicht-verschneidung-3d-schnitt (gleiche Kategorie wie „Wand endet an Decke", hier für geneigte statt horizontale Cutter). -
2026-07-12 Fenster-Grundriss grob/mittel/fein nach SIA 400 klar unterschieden (
13cc6a0) — Nutzer-Report „mittel und fein sind genau gleich, grob ist viel zu grob" behoben:windowSymbol(geometry/opening.ts) staffelt jetzt nach SIA 400 Anhang B.9.1 Fig. 36–38 statt DIN — grob (1:100) nur eine Glaslinie, mittel (1:50) Blendrahmen + Flügel-Trennlinien + 1 Stulp-Quadrat je Flügelstoss, fein (1:20) zusätzlich verschachtelte Flügelrahmen + Glas-Doppellinie (Isolierverglasung) + 2 Stulp-Quadrate.generatePlan.tsreichtdetaildurch, rendert die neuen Stulp-Marken (window-stulp) nur im typisierten Pfad (kein Fake-Stoss bei reinemwingCount-Altfall). Referenzdokudocs/research/sia400-fenster-tueren.md(Fig.-Transkription aus der SIA-400-PDF, lokal excluded). +9 Tests, Suite 753 grün. Visuell per Puppeteer verifiziert. ✅ Folge-Fixe309e54: Öffnungssymbol-Kommentare intoElevation.ts/toWalls3d.tswaren fälschlich „DIN" benannt (Grundlage ist SIA 400 B.9.1.3) — reine Doku-Korrektur, Symbol-Geometrie selbst war bereits korrekt (SIA-PDF zeigt nur Sinnbild-Namen, keine Pfeilgrafiken, daher keine Geometrieänderung). ✅ Wand-Poché bei „grob" jetzt immer vollschwarz (0240a23, 2026-07-12) — war zuvor nur schwarz, wenn das dominante Bauteil selbstpattern:"solid"hatte (bei mehrschichtigen Wandtypen mit Backstein/Dämmung/Verputz blieb es weiss). Fix (unconditionalHATCH_INKbei grob) von Hermes/Qwen3 geliefert (zweiter Versuch, erster war die o. g. Fehleinschätzung), von mir verifiziert + um fehlenden Regressionstest + Aufräumen der totenbackbonePocheFill-Hilfsfunktion ergänzt. +2 Tests, Suite 755 grün. -
2026-07-11 Schnitt/Ansicht auf VW-Niveau (grosser Block) — Schnitt ENTSPIEGELT (
983d061, u-Achse = Betrachter-Rechts, Rust+TS koordiniert, Engine neu gebaut); Kanten geschnittener Bauteile gefiltert + verdeckte Kanten opt-in (4c4c990); Wand-Terminierung wirkt im Schnitt auch bei Decken-ANSCHLUSS ±5 cm (a612ae5); Dämmschraffur-Orientierung Wand/Decke korrekt (Sprossen quer zur Schicht, empirisch verifiziert,a612ae5+38a4d8c). Ansicht als LINIENZEICHNUNG (c02a02c): weisse Flächen + XOR-Silhouette (xorOutlineEdges — Teilbox-Innenkanten heben sich auf), Fenster mit Blendrahmen→Flügelprofil→Glas, Sims mit Tropfkante, DIN-Symbole exakt auf den Glasfeld-Ecken (ee9aeda). 3D-Öffnungen VW-fein (Merge31d7aef): vorstehende Flügelrahmen, DIN-Symbole auf dem Glas (openingPlaneBox-Prismen), 3D-Fensterbank + Tropfkante, Zargen-Umgriff; Staffelung grob/mittel/fein. Display/Print-Umschalter in allen 2D-Darstellungen. Offen: Tauri-Visualabnahme 3D; Schnitt-Auswahl-UX (Treffer nur auf der Poché). -
2026-07-11 Lineale + VW-Zeichen-Feedback komplett (
1945fec,8f85e13,7898a0d,242b850) — Lineale oben/links in allen 2D-Ansichten (Meter-Ticks, Cursor-Marker); Cursor-HUD im Programm-Look mit Live-Echo getippter Werte (oben+unten synchron), Tab-Feldwechsel, Direkt-Tippen; Δx/Δy beim Rechteck; lange Führungslinien + Winkelbogen mit 0°-Referenz. -
2026-07-11 Schnitt ausgebaut (
b86fca2) — Befehlsectionline/viewline(Aliase schnittlinie/ansichtslinie, BIM-Ribbon „Schnitte"): zwei Klicks setzen die Schnitt-/Ansichtslinie (neue Ebene bei Bedarf). Schnittführungs-Symbol im Grundriss (Strichpunkt, Endmarken, Richtungspfeile, Label) + Pick-Band; Schnittlinie selektierbar mit Attribut-Sektion (Name, Blickrichtung umkehren, Endpunkte, Tiefe, Löschen/Entf). Editieren IM Schnitt: Cut-Polygone tragen die Quell-Element-Id (sourceId, durch Schicht-Zerlegung/Terminierung/Dominanz propagiert) → Klick im Schnitt wählt das Bauteil, Panels editieren, Schnitt rechnet neu. Schnitt-TiefeDrawingLevel.depth(Owner-Distanz-Näherung, TODO exakte Kanten-Tiefe bräuchte section.rs). Offen: Endpunkt-Drag-Griffe der Schnittlinie im Grundriss. -
2026-07-11 Ansicht (Elevation) als echte 2D-Darstellung (
456ecc5+a6db682) —toElevation.ts: Painter-Projektion (Fassaden/Decken fern→nah, Rückseiten-Culling, Tiefen-Graustaffelung), Fenster/Türen als Rahmen+Glas, Bodenlinie, Dächer (Flächen + Giebel aus roofGeometry) und Schatten ein/aus (45°-Schlagschatten auskragender Decken UND Dachflächen, Sutherland–Hodgman-geclippt; Toggle in der Ansichts-Leiste,DrawingLevel.shadows). Rein TS/synchron ohne WASM. Offen: exakter Hidden-Line statt Painter (dokumentierte Näherung), Material-/viewHatch-Füllungen je Fassade. -
2026-07-11 VW-Zeichengefühl: Cursor-HUD + Winkelraster (
975ce3f) — beim Zeichnen L/W-Kästchen am Cursor (L: 3.118m W: 60.000°, VW-Stil), weiches Einrasten auf 15°-Vielfache (±2.5°, konfigurierbar) mit Winkel-Badge + gestrichelter Führungslinie; Vorrang Objekt-Snap > Shift/Ortho > Winkelraster > Raster; Toggle in der Fang-Leiste. Das bis dahin nie gerenderteToolDraft.hudlebt jetzt (line/polyline/wall/rect/circle/arc). -
2026-07-11 Dach im 3D anwählbar (
355c1d4) + 2D-Schnitt = 3D Wand-Terminierung (0e02c2b) — Ray-Dreieck-Pick über Dachflächen/Giebel; applyWallTermination spiegelt terminateOrSubtractSpans im (u,v)-Schnittraum (below/above kappen an der Decken-UK/OK). -
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