Commit Graph

20 Commits

Author SHA1 Message Date
karim d34e1cb1c1 3D-Öffnungen: Flügel-/Türblatt-Regression fixen; Ansicht: Eck-Joins, Durchsicht, Farbig-Modus
3D: Flügelrahmen sass fälschlich vor der Fassade (Rahmen-Glas-Rahmen-Sandwich)
und Türen hatten kein Blatt — beides aus dem letzten 'fein'-Merge. Flügelband
jetzt hinter die Blendrahmen-Vorderkante zurückgesetzt, Türblatt (Voll- und
Teilverglasung) ergänzt.

Ansicht: Wandboxen liefen achsenzu-achse ohne Eckverlängerung (dreieckige
Kerbe an jeder Gebäudeecke, sichtbar v.a. im Schlagschatten) — Wände mit
gemeinsamem Endpunkt verlängern sich jetzt um die halbe Nachbardicke. Die
Linien-Pipeline zeichnet alle Konturen in einem eigenen Durchgang über allen
Füllungen, wodurch Öffnungs-/Fugenlinien hinterer Fassaden durch nähere Wände
schienen — verdeckte Flächen/Öffnungen werden jetzt gar nicht mehr emittiert.
Farbig-Modus zeigte bisher nur Weiss statt Bauteilfarben; Wand/Dach/Fenster/
Tür tragen jetzt echte Farben, Mono bleibt die reine Linienzeichnung.
2026-07-11 12:38:13 +02:00
karim 06803206e5 3D-Öffnungen im VW-Detail 'fein': verschachtelte Flügelrahmen, DIN-Symbole, Sims, Zargen-Umgriff
- Flügelrahmen sitzen in eigenem, ~12 mm nach aussen vorstehenden und flacheren
  Quer-Band (abgesetzte, plastische Schachtelung Blendrahmen -> Flügelrahmen ->
  Glas) statt flach mit dem Blendrahmen verschmolzen; jetzt bei mittel + fein.
- DIN-Öffnungssymbole (Dreh/Kipp/Dreh-Kipp) als sehr dünne, in der Öffnungsebene
  gedrehte dunkle Prismen knapp vor der Glasebene (neuer Helfer openingPlaneBox);
  nur bei fein, nur je nicht-festem Flügel, exakt wie in der 2D-Ansicht.
- Fensterbank (Sims) unter der Öffnung: Bank-Quader + dünnere Tropfkanten-Stufe,
  seitlich ueberstehend, nach aussen auskragend; Gating sillBoard (keine/innen aus,
  Default zeichnen) und DetailLevel (mittel + fein).
- Tuer-Zarge mit Umgriff: schmale Bekleidungs-Platte vor beiden Wandflaechen als
  Ring um die Oeffnung (nur frameKind 'zarge'; Blockrahmen bleibt buendig).
- Mesh-Tests je Feature: Anzahl/Farbe/BBox, sillBoard- und frameKind-Gating,
  Symbole nur fein/nicht-fest, Flügelrahmen-Vorstand.
2026-07-11 02:58:50 +02:00
karim 355c1d4dd1 Dach im 3D anwählbar: Ray-Dreieck-Pick über die Dachflächen
Der 3D-Pick kannte nur Wand/Decke/Öffnung/Treppe — Dächer waren im
wgpu-Viewport nicht anwählbar (Nutzer-Report). Neu: pickGeometry liefert je
Dach die Dachflächen + Giebel als World-Dreiecke (fan-trianguliert wie
emitRoofs); pickNearest testet sie über das bestehende doppelseitige
rayTriangle (präzise geneigte Flächen statt Bounding-Prisma — kein Klick-
Diebstahl vor der Fassade dahinter). App-Routing: kind 'roof' →
setSelectedRoofIds (exklusiv, wie Treppe/Öffnung); damit greifen Highlight
und die Dach-3D-Griffe (4ef40a0) jetzt auch per 3D-Klick. +1 Test. 690/690.
2026-07-10 23:56:12 +02:00
karim 897a2dcd43 Tür: Teilverglasung (glazingRatio) im 3D wirksam
DoorType.glazingRatio wurde bisher von keinem Renderer gelesen (Designdoc).
Bei Glasblatt (leafStyle 'glas') füllt das Glas jetzt nur den oberen
glazingRatio-Anteil des Hauptfelds; darunter bleibt ein blindes Blattfeld
(z. B. Tür mit Oberglas). Fenster unberührt (glazedFraction = 1). +1 Test
(Halbglas: Unterkante angehoben, Oberkante am Sturz). 673/673 grün.
2026-07-10 02:14:33 +02:00
karim 3a986ecd2f Dach-Schichtlogik: RoofType/Layer[] wie Decken (3D mehrschichtig)
Kernthema der BIM-Tiefe (Designdoc docs/design/bim-elements-depth-study.md, P0):
Dächer bekommen einen mehrschichtigen Aufbau analog WallType/CeilingType.

- Modell: RoofType { layers: Layer[] }, Project.roofTypes, Roof.roofTypeId
  (Roof.thickness bleibt einschichtiger Fallback). Resolver roofLayers()/
  roofTotalThickness() — wiederverwendet den bestehenden Layer-Typ.
- 3D (emitRoofs): je Schicht ein eigenes Mesh mit Bauteilfarbe, entlang der
  Flächennormalen unter die vorige gestapelt (Eindeckung aussen → Verkleidung
  innen). Ohne roofTypeId einschichtiger thickness-Slab (Default-Dachfarbe).
- UI: Dachtyp-Dropdown im Dach-Panel (leer = einschichtig). Default-Dachtyp
  'Steildach gedämmt' in sampleProject.
- +2 Tests (Schicht-Meshes/Stapelung; einschichtig = Slab+Giebel).

Offen (Designdoc): 2D-Schnitt-Poché der Dachschichten, RoofType-ResourceManager-
Tab, Traufe/Ortgang getrennt. 668/668 grün; 3D-Optik vom Nutzer in Tauri prüfen.
2026-07-10 02:03:55 +02:00
karim e99bb2413f Dach 3D: echte Materialdicke (solide Slabs) statt papierdünner Flächen
roof.thickness war im 3D bislang ein totes Feld — Dächer waren einseitige
Flächen. emitRoofs baut jede Dachfläche jetzt als soliden Slab: Oberseite +
um thickness entlang der Flächennormalen (Newell) nach unten versetzte
Unterseite + umlaufende Seitenwände. Giebel bleiben dünne Endfüllung.
Basis für die kommende Dach-Schichtlogik. +1 Test (Unterseite unter der
Oberfläche); Walm-Zähltest auf Slab-Dreiecke aktualisiert. 667/667 grün.
Visuelle 3D-Abnahme in der Tauri-App durch den Nutzer.
2026-07-10 01:58:15 +02:00
karim 9a38636bf2 Fenster: echte Schachtelung Blendrahmen → Flügelrahmen → Glas (2D+3D)
Öffenbare vs. feste Flügel sind jetzt unterscheidbar, und die Einbaulage
(Schichteinzug) wirkt auch im 2D-Grundriss.

2D (windowSymbol/generatePlan):
- Der reiche Pfad (typisiertes Fenster) zeichnet den Blendrahmen an der REALEN
  Einbaulage (insetFace/insetFromFace, vorher ignoriert), je Flügel einen
  Flügelrahmen (window-sash) nur wenn ÖFFENBAR, und das Glas darin. Feste
  Flügel: Glas direkt im Blendrahmen.
- Die alte Diagonale quer über die Box (sah aus wie durchgestrichen) entfernt —
  Öffenbarkeit wird jetzt über den Flügelrahmen ausgedrückt.
- Alt-Pfad (kein Typ) byte-identisch → kernel2d-Parität unberührt.

3D (frameMeshesForOpening/resolveOpeningFrame):
- Je öffenbarem Flügel ein Flügelrahmen-Ring (4 Riegel) im Blendrahmen (fein).
- Flügeltabelle konsistent aus explizitem sashes bzw. effektivem wingCount
  (Instanz-Override wirkt jetzt auch auf Flügelrahmen); wingCount daraus abgeleitet.

Tests angepasst/ergänzt (fest vs. öffenbar, Zählungen). 663/663 grün.
2026-07-10 01:47:27 +02:00
karim d131683304 Sonnenschutz 3D: Rollladenkasten als Box über der Öffnung
emitOpeningShading zeichnet für Fenster mit shading.create eine helle 3D-Box
über der Öffnungs-OK, an der Aussenfläche ansetzend und um box.depth hinaus,
box.height hoch, box.width breit (0 ⇒ Öffnungsbreite). Nur mittel/fein.
Vervollständigt das Sonnenschutz-Feature (2D-Kontur war da, 3D-Box war in der
Studie 'später'). +3 Tests (Box-Primitive/Position, Leerfälle, grob).
3D visuell vom Nutzer in der Tauri-App zu prüfen. 662/662 grün.
2026-07-10 01:23:39 +02:00
karim 2e13ec3097 Fenster-Renderer: Flügeleinteilung, Öffnungslinien, Verglasung, Rollladenkasten
Der 2D/3D-Renderer konsumiert die neuen Fenster-Modellfelder (VW-Studie §6):

- opening.ts: windowSymbol nimmt die Flügeltabelle (sashes); Trennlinien aus
  Flügel-/Pfostenbreiten statt gleichmässiger wingCount-Teilung + Öffnungs-
  andeutung (Diagonale zur Bandseite) je nicht-festem Flügel. Ohne sashes
  exakt das bisherige Verhalten (Regressionssicherheit).
- generatePlan: glazingPanesOf steuert die Glaslinien-Anzahl (mittel/fein),
  grob bleibt bei einer; gestrichelte Rollladenkasten-Kontur über der Öffnung.
- toWalls3d: glassPanesForOpening zeichnet glazingPanes dünne, in Wandrichtung
  versetzte Scheiben mit Luftraum (Ein-/Zwei-/Dreifachverglasung); panes=1 =
  exakt die alte Einzelscheibe.

Verhaltensänderung: window-standard (zweifach) zeigt 3D nun 2 Scheiben statt
einer — 2 Bestandstests entsprechend angepasst (+ Nicht-Überlappungs-Check).
+13 Primitiv-Tests (generatePlan.windowFields, toWalls3d). 659/659 grün.
2026-07-10 01:17:35 +02:00
karim 64f61797d8 Dach: Auswahl-Hervorhebung auch im 3D (Draht-Umriss der Dachflächen)
selectionHighlightLines bekommt roofIds und emittiert die Kanten aller
Dachflächen + Giebel (roofGeometry, Modell→World) als Akzent-Draht — ein
selektiertes Dach leuchtet jetzt im wgpu-Viewport wie Wand/Decke. App reicht
selectedRoofIds durch. +1 Test. tsc + vitest grün.
2026-07-10 00:35:26 +02:00
karim 31f2d63362 Dächer: Platzier-Werkzeug + 2D-Plan + 3D-Flächen + Demo-Dach
Dach-Feature end-to-end nutzbar:
- Befehl „Dach" (Alias dach/rf, BIM-Ribbon, Satteldach-Icon): Grundriss als
  Rechteck aufziehen; die Dachform (Sattel/Walm/Pult/Mansarde/Zelt/Flach)
  wählt man als Inline-Option der Befehlszeile vor/während des Aufziehens.
  First entlang der längeren Seite (Standard).
- 2D-Grundriss (generatePlan): Traufe/First/Grat (Walm/Zelt) + gestrichelte
  Knicklinien (Mansarde), Farbe aus roof.color/Kategorie „31 Dächer".
- 3D (toWalls3d emitRoofs): Dachflächen + Giebel als terrakottafarbene
  Meshes (Fan-Triangulierung, Mansarde-Fünfeck sauber).
- Seed: Demo-Satteldach RF1 über dem Baukörper (OG, 5×4, Überstand 0.4).
- i18n de/en für Befehl + Formen.

+10 Tests (2D 7, 3D 3). tsc + vitest 640 grün. Auswahl/Attribut-Editieren
placierter Dächer folgt separat.
2026-07-09 21:13:11 +02:00
karim 4beae72eea Fenster/Tür 3D: tiefer, Detailgrad im 3D, kein Fenster→Tür-Umschalten
Nutzer-Feedback:
- Fenster wirkten im 3D flach: die Rahmen-Einbautiefe wurde fälschlich aus
  frameThickness (Profil-Breite, ~6 cm) statt aus der Wanddicke bestimmt.
  Jetzt füllt der Rahmen die VOLLE Wanddicke (tiefe Laibung), die Scheibe
  ist eine dünne Tafel mittig darin → plastische Fenster mit sichtbarer
  Laibung. frameDepth übersteuert weiterhin.
- Detailgrad grob/mittel/fein wirkt jetzt auch im 3D: grob = nur Loch +
  Scheibe, mittel = Rahmen (+Oberlicht-Kämpfer), fein = zusätzlich
  Flügel-Mittelpfosten/Kämpfer-Sprossen. Durchgereicht App → Viewport3D →
  Wasm3DViewport → useWasm3dRenderer → projectToModel3d({detail}).
- Fenster↔Tür-Umschalter im Objekt-Info entfernt (nur noch Anzeige): die
  Gattung wird beim Platzieren festgelegt, nicht nachträglich getauscht.

+1 Test (Detailgrad-Gating grob/mittel/fein). tsc + vitest grün.
2026-07-09 20:59:21 +02:00
karim 9a65900377 Tür/Fenster 3D: Rahmen, Sprossen/Kämpfer, Oberlicht, Schichteinzug als Mesh
Emittiert die vertieften Tür-/Fensterparameter als wgpu-Geometrie:
- emitOpeningFrames: Rahmenriegel (Laibung + Sturz + Sohlbank),
  wingCount−1 senkrechte + mullionRows−1 waagrechte Sprossen, Kämpferbalken
  bei transomHeight>0. Rahmenfarbe hell-warmgrau [0.85,0.85,0.83].
- emitOpeningGlass erweitert: typisierte Öffnungen bekommen einzugs-/
  oberlicht-bewusste Scheiben (Haupt- + Oberlichtscheibe), typlose behalten
  die alte zentrierte Scheibe (Rückwärtskompatibilität).
- Schichteinzug: Rahmen/Glas entlang der Wandnormale ab der gewählten
  Fläche (aussen/innen) um insetFromFace versetzt, auf Wanddicke geklemmt.
+5 Tests. tsc sauber, vitest 614/614 grün.
2026-07-09 01:15:59 +02:00
karim 35299307d6 Akkumulierten grünen Arbeitsstand landen (Basis für Weiterarbeit)
Bündelt den über mehrere Sessions gewachsenen, uncommitteten Stand in
einem Basis-Commit, damit Folge-Features isoliert darauf aufsetzen.
Verifikation: tsc --noEmit sauber, vitest 600/600 grün.

Enthalten (Details in PENDENZEN.md -Liste / HANDOVER.md):
- truck-Integration: Profil-Extrusion + Verjüngung + Boolean-CSG (csgrs),
  Crate src-tauri/trucksolid, Werkzeug `extrude`, ExtrudedSolid-Modell.
- kernel2d-Port nach Rust/WASM (Phasen 1–5, Diff-Harness).
- render3d 3D-Live-Schnitt = 2D-Schnitt: geschichteter Bodenaufbau,
  Prioritäts-Verschneidung (section_boolean.rs), einstellbare
  Schichttrennlinien, per-Hatch-Strichstärke, relativeToWall-Orientierung.
- Interop-Export IFC4/STL/OBJ (Loch-Ausschnitt wallMeshCut), Schnellexport.
- Projektdatei .obp + OS-Lock (lock.rs, LockConflictDialog).
- Layout-Blätter (Modell/Editor/Panel/PDF), Ausschnitte, Override-Engine,
  Tragwerk-Stützen (Column), BIM-Tree-Panel.
- Bauteil-Typsystem (Tür/Fenster/Treppe-Typen), Betontreppe mit schräger
  Laufplatte, Text-/Textbox-Werkzeug, Mess-Werkzeug, 2D/3D-Griffe für
  Öffnungen/Treppen, Snap-Symbol-Restyle.
2026-07-09 00:57:29 +02:00
karim 05cfade483 Nordstern-3D: Fenster/Tueren als echte Boolean-Loecher in EINEM Wandkoerper
Bisher zerlegte emitWall eine Wand um jede Oeffnung in Pfeiler/Bruestung/Sturz-
Teilquader -> sichtbare Segment-Naehte im 3D, Oeffnung war semantisch kein Loch,
und versetzt uebereinanderliegende Fenster liessen sich gar nicht abbilden. Neu:
im 3D-Pfad (layered=true) EIN RWall pro Schicht-Band ueber die volle Achse mit
allen Oeffnungen als rechteckige holes; render3d stanzt sie per achsparalleler
Rechteck-Gitter-Zerlegung der Langseiten aus und setzt 4 Laibungsquads je Loch.
holes und openings schliessen sich im Emitter gegenseitig aus. Tuer = Loch bis
zum Wand-zBottom. Schnitt-Pfad (layered=false) segmentiert unveraendert weiter
(wallSegmentOwners bleibt synchron, toSection.ts unangetastet).

Zusatz: trimWallTopForCeilings (Deckentrim, e4b8df6) gilt jetzt NUR im 3D-Pfad
(layered=true, Z-Fighting-Vermeidung) und wird im Schnitt-Pfad uebersprungen -
der Schnitt braucht die volle Wandhoehe fuer seine schichtweise Prioritaets-
Subtraktion (Kontrolle von Schichteinzug/Bodenaufbau am Wand-Decken-Anschluss).

RWall.holes / WallInput.holes additiv (#[serde(default)]). Pflicht-Testfaelle:
zwei ueberlappende, hoehenversetzte Fenster in einem Koerper; Tuer-Loch bis Boden
ohne untere Laibung. cargo test 56 gruen, vitest 230 (+3), build:engine3d + tsc
sauber.
2026-07-04 22:17:21 +02:00
karim 6035b8a8c2 3D: Wand an Deckenunterkante trimmen (Prioritaets-Trim, kein Z-Fighting)
Wo eine Decke (hoehere joinPriority, z.B. Beton 100) buendig auf der
Wandoberkante sitzt, durchdrangen sich Wand- und Deckenvolumen exakt
ueber die Deckendicke -> Z-Fighting im 3D-Viewport. emitWall trimmt jetzt
zTop der Wand auf die Deckenunterkante, wenn eine Decke gleichen
Geschosses mit Footprint-Ueberlapp hoehere Prioritaet hat. Footprint-Test
ist eine Bounding-Box-Naeherung (dokumentiert). Rein TS-seitig vor dem
RWall-Export -> kein WASM-Rebuild. +3 Tests (208 gesamt).
2026-07-04 14:02:22 +02:00
karim c54a2f916c 3D: Glasscheiben in Fenstern (AUDIT A5-Teilschritt)
Jede Fensteröffnung bekommt im 3D eine dünne, leicht bläuliche
Glasscheibe (RMesh, mittig in der Wanddicke, UK=baseElevation+sillHeight
bis OK), damit Fenster als Fenster lesbar sind statt als Löcher. Türen
bleiben offen. Nur meshes-Ebene → pickGeometry/Highlight unberührt.
2026-07-04 12:53:01 +02:00
karim 00c90857ad 3D: mehrschichtige Wände zeigen ihren Schichtaufbau
Statt eines Vollkörpers in der repräsentativen Farbe wird jede
Materiallage der Wand als eigener extrudierter Teilquader in ihrer
Component-Farbe emittiert (quer zur Wanddicke gestapelt, zentriert um
die Achse). Gilt auch für die Öffnungs-Teilquader (Pfeiler/Brüstung/
Sturz). Jede Schicht-Box trägt die wallId der Ursprungswand → Klick-
Auswahl + Highlight umfassen weiter die ganze Wand.
2026-07-04 12:40:25 +02:00
karim 6ea562ceda 3D: Bauteil-/Materialfarbe statt Einheitsgrau für Wände & Decken
projectToModel3d trug bisher für alle Wände WALL_RGB und alle Decken
SLAB_RGB (konstant grau), obwohl die Component-Materialfarbe verfügbar
ist. Jetzt: repräsentative Farbe der dicksten Schicht (tragende/
dominante Lage) je Wandtyp bzw. Deckentyp, Fallback auf die Konstanten.
Reine Albedo-Änderung — Geometrie, Picking und Highlight unberührt.
Schicht-Teilquader je Materiallage (echter 3D-Wandaufbau) bleibt als
Folgeschritt vermerkt.
2026-07-04 06:31:48 +02:00
karim e137353b95 Nordstern-3D: Auswahl-Highlight (orange Outline, immer sichtbar)
Ein selektiertes Bauteil wird jetzt im 3D-Viewport mit einer orangen
Umrisslinie markiert, die dank No-Depth-Pipeline auch hinter Wänden
durchscheint (klare Selektions-Rückmeldung). Zusammen mit Objekt-Info
(numerisch) und Attribute-Panel ist die 3D-Auswahl damit vollständig.

- Engine: set_highlight_lines(vertices) + highlight_pipeline
  (LineList, depth_compare Always, kein Depth-Write), als letzter
  Draw-Call obenauf. Reuse der Grid-Linien-Infrastruktur.
- TS: selectionHighlightLines() baut die Quader-/Prisma-Kanten der
  Auswahl in Akzentfarbe; App berechnet sie per useMemo aus der
  Store-Auswahl und reicht sie durch.
2026-07-04 06:26:29 +02:00