Commit Graph

236 Commits

Author SHA1 Message Date
karim 4ef73c9198 Pendenzen: HATCH-Ellipse/Spline-Kanten + TEXT/MTEXT-Import erledigt 2026-07-05 14:29:55 +02:00
karim 4b93ac9cbb DXF-Import: TEXT/MTEXT -> editierbarer Plan-Text (Drawing2D text-Primitiv, SVG-Render) 2026-07-05 14:29:05 +02:00
karim 05bc5aa6e1 DXF-HATCH: Ellipsen- + Spline-Randkanten tesselliert (B-Spline-Sampling extrahiert) 2026-07-05 14:18:49 +02:00
karim d36c84689f Doku: Sprache in Planungs- und Konventionsdokumenten vereinheitlicht 2026-07-05 14:14:40 +02:00
karim 8f9123ce0d Pendenzen: HATCH-Import erledigt vermerkt 2026-07-05 14:13:24 +02:00
karim a44572bf7b DXF-Import: HATCH via Custom-Handler -> gefuellte geschlossene Drawing2D-Flaeche 2026-07-05 14:12:59 +02:00
karim 79ea6b0b3b Pendenzen: SPLINE/INSERT-Import erledigt vermerkt 2026-07-05 13:59:41 +02:00
karim 83da278ed2 DXF-Import: SPLINE (De-Boor-B-Spline) + INSERT (Block-Expansion mit Transform/Array/Verschachtelung) 2026-07-05 13:59:15 +02:00
karim 33c2c6c22e Pendenzen: DXF-Kurven-Import erledigt, Import-Ist-Stand klargestellt 2026-07-05 13:51:37 +02:00
karim b7551d4930 DXF-Import: ARC/CIRCLE/ELLIPSE als tessellierte Konturen (Abdeckungsluecke geschlossen) 2026-07-05 13:51:08 +02:00
karim 25daec6be9 Pendenzen: Join-WASM-Durchstich verworfen (gemessen: TS schneller <100 Waende) 2026-07-05 13:40:58 +02:00
karim 5229174551 Treppe: Vorkonfiguration vor Erstellung (Breite/Referenz/Trittmass)
- Referenz (links/mitte/rechts) + Trittmass-Modus (mit/ohne) als togglebare
  Optionen, Breite als Tab-Feld — bereits in der Idle-Phase (vor dem 1. Punkt).
- Trittmass-Modus 'mit': stepsFromTread(auftritt, runLength) leitet Stufenzahl
  aus Ziel-Auftritt ab (Default IDEAL_TREAD); Feld Auftritt statt Stufen.
- appendStair schreibt Stair.referenz; Geometrie/Outline versetzt entsprechend.
- stairDefaults (modulweit) merkt zuletzt gewaehlte Werte fuer die naechste
  Treppe (Session-RAM; localStorage/projectSlice waere Folgeschritt).
- 10 Tests (stair.tread.test.ts), i18n de/en. vitest 302/302, tsc sauber.
2026-07-05 13:14:06 +02:00
karim df0e5e432a Pendenzen: DWG/DXF-Import-Spike (acadrust wasm32) vermerkt + Folgeschritte 2026-07-05 03:13:04 +02:00
karim 715e950d7c DWG/DXF-Import-Spike: acadrust baut zu wasm32 (Crate dwgimport)
- src-tauri/dwgimport: eigenstaendiges Crate (cdylib+rlib, eigener [workspace]),
  dep acadrust 0.4 (MPL-2.0, pure Rust). parse_dxf_summary(bytes) via
  DxfReader::from_reader + Cursor<Vec<u8>> -> JSON (version/entityCount/
  entityTypeCounts/layerNames). wasm-Fassade parse_dxf_summary_json.
- getrandom wasm_js-Feature noetig (transitiv via ahash) -> als Dep gesetzt.
- Kernbeweis: acadrust kompiliert nach wasm32 (839 KB), DXF-Parse headless
  getestet (5 Entities korrekt). Beweist den DWG/DXF-Import-Weg im Rust/WASM-Kern.
- build:dwgimport-Script, src-tauri/Cargo.toml exclude erweitert.
2026-07-05 03:12:32 +02:00
karim dbf78a9d75 UI: Gruppe-A-Felder in Objekt-Info-Panel verdrahtet
- Treppe: Dropdown Referenz (Links/Mitte/Rechts) vor Laufrichtung.
- Fenster: Feld Fluegel (1-4) nach Bruestung.
- Tuer: Dropdowns Typ (Normal/Wandoeffnung) + Sturzlinien (Keine/Innen/Aussen/
  Beide) vor Anschlag.
- host.ts/selectionInfo.ts Durchreichung, App.tsx-Handler (kind-guard +
  updateOpening/updateStair), i18n de/en. Rueckwaertskompatibel.
  tsc sauber, vitest 292/292.
2026-07-05 03:01:35 +02:00
karim 26fbd11b73 Bauteile Gruppe A (4-6): Treppe-Referenz, Fenster-Fluegel, Tuer-wandoeffnung
- Treppe referenz links/mitte/rechts (Stair.referenz, Default mitte): Perp-Versatz
  referenzMidShift auf start/center, Lauflinie/Pfeil bleiben visuell zentriert.
- Fenster Fluegel-Mittelpfosten (Opening.wingCount 1-4, Default 1): wingCount-1
  Querlinien im Rahmen (window-mullion), nur mittel/fein.
- Tuer-Typ wandoeffnung (Opening.doorType, Default normal): ueberspringt
  Tuerblatt + Schwenkbogen, Laibung/Sturz bleiben.
- Alle Modellfelder optional/rueckwaertskompatibel. 17 neue Tests.
  vitest 292/292, tsc sauber.
2026-07-05 02:33:48 +02:00
karim 6e5998ce72 Bauteile Gruppe A: Treppe-Aussenlinie, Fenster-Bruestung, Tuer-Sturz (Rhino-Vorbild)
- Treppe Aussenlinie/Outline (stair.ts stairOutline): gerade=4-Punkt-Rechteck,
  L=6-Punkt-Polygon via lineIntersect2d, Wendel=2 Boegen+2 Radiallinien; in
  addStairSymbol als durchgezogene Umrisslinie. (Rhino _aussen_gerade/_l/_wendel)
- Fenster Bruestungslinie: bei sillHeight>0 gepunktete Linie auf der Wandachse
  zwischen den Pfosten (Klasse window-sill).
- Tuer Sturzlinien (SIA): gestrichelte Linien an Wand-Innen/-Aussenkante, neues
  optionales Opening-Feld lintelLines (keine/innen/aussen/beide, Default beide),
  rueckwaertskompatibel.
- 12 neue Tests (stairOutline.test.ts). vitest 275/275, tsc sauber.
2026-07-05 01:56:07 +02:00
karim b65c676643 Research: Bauteile Treppe/Fenster/Tuer — Rhino-Plugin als Vorbild
RESEARCH_BAUTEILE_RHINO.md: Gap-Vergleich Rhino (treppe.py 1784Z + fenster/tuer)
vs. TS-Ist, priorisierte Anhebungs-Ansaetze (Gruppe A 2D-sofort / B 2D-mittel /
C 3D). Kern-Gaps: Treppe-Aussenlinie, Fenster-Bruestungslinie, Tuer-Sturzlinien
(SIA, gestrichelt) — fallen mit Schnitt/Ansichts-Darstellung zusammen.
PENDENZEN: Bauteil-Item im Backlog + Phase 5 abgehakt (a608a59).
2026-07-05 01:33:35 +02:00
karim ae18766b01 kernel2d-Port Phase 5: roomArea/ceiling/roomBoundary/stair
- roomArea: polygonArea/perimeter/centroid.
- ceiling: normalizeOutline/isValidOutline/ceilingArea/outlineBBox/
  outlineCentroid/pointInOutline (+ BBox-Struct, serde camelCase).
- stair: defaultStepCount/stairGeometry (gerade/L/Wendel)/stairCut/stairBBox/
  pointHitsStair (StairParams-Struct, strukturgleich; Nullguard ||1e-9 wie TS).
- roomBoundary: detectRooms/roomFromPointInside(Faces)/pointInPolygon
  (planarer Graph, Half-Edge-Faces, Miter-Offset; WallSegment/WallFace).
- Batch-Fassaden + Harness-Slices je Modul (Struktur exakt + Werte).

Verifiziert: vitest 263/263 (33 Parity), tsc sauber, build:kernel2d sauber.
Bekannte Teil-Deckung: detectRooms nur mit Rechtecken (1 Face) getestet —
komplexe Topologie-Reihenfolge nicht mit Zufallsgraphen abgesichert.
2026-07-05 01:30:11 +02:00
karim c7128fe669 Pendenzen: Modellnamen-Referenz in Erledigt-Zeile neutralisiert (Trace-Konvention) 2026-07-05 01:09:39 +02:00
karim b37c9f467b Research: CAD-Ansaetze aus OpenCADStudio/truck/acadrust (am Code studiert)
RESEARCH_CAD_APPROACHES.md: konkrete, priorisierte Ansaetze fuer 'von BIM-Tool
zu echtem CAD' — direkt an geklonten Repos gelernt.
- OpenCADStudio (GPL-3.0, Referenz): generisches Entity-Trait-Modell,
  modeless StepInput-Command-System, 70KB Snap-Engine, universelle Grips,
  CadDocument=DWG/DXF-Objektmodell.
- truck (Apache-2.0): Rust-B-Rep/NURBS-Kernel, Geometrie-Crates WASM-faehig
  und vom wgpu-Rendering trennbar; Booleans/Fillets noch instabil.
- acadrust (MPL-2.0!): pure-Rust DWG/DXF R13-R2018 read+write, alle Deps
  pure Rust -> WASM-tauglich; Kandidat fuers DWG/DXF-Rueckgrat.
- Web-Import-Landkarte (web-ifc/occt-wasm/shpjs/loaders.gl/...) fuer GEO-BLOCK.
PENDENZEN: Strategie-Item im Backlog verlinkt.
2026-07-05 01:08:08 +02:00
karim 08b0b23a68 Pendenzen: kernel2d-Port Phase 4 erledigt (28471c1) 2026-07-05 01:02:00 +02:00
karim 4a26c34db1 kernel2d-Port Phase 4: Trim/Split/Join (Loewenanteil)
Portiert (1:1, reihenfolge-/strukturtreu):
- splitSegmentByCutters, trimSegment, trimPolyline (+ span/nearestParamOnChain),
  extendSegment.
- splitPolylineAtParam, splitClosedByChord (+ dedupeRing), removeSegment.
- splitAtIntersections (+ polylineEdgesAuto, splitOpenByEdgeHits/AtHits, EdgeHit).
- joinChains: greedy i<j-erster-Treffer-dann-Neustart, exakt wie TS
  (splice-Semantik via remove(j)+open[i]=combined).
- Polyline-Struct {pts,closed}; stabile (edge,t)-Sortierung, 1e-6-Dedup.
- 9 Batch-Fassaden + 4 native Unit-Tests.

Harness: 5 neue Paritaets-Bloecke (Struktur EXAKT + Werte), Cutter-/Polylinien-
Generatoren, joinChains mit re-mergebaren Ketten. cargo test 18/18, vitest 247
(5 neu, davon 17 Parity) gruen, tsc sauber, build:kernel2d sauber.
2026-07-05 01:01:03 +02:00
karim 903dc19cec kernel2d-Port Phase 3: Offset (Miter+1e-9-Fallback) + Fillet
- offsetSegment / offsetPolyline: Gehrung via line_intersect, Fallback auf
  verschobenen Endpunkt an EXAKT 1e-9 (nicht EPS) — Selbstschnitte ungeheilt
  wie TS. Dedup der Eingabe innerhalb EPS.
- filletCorner + Fillet-Struct (serde camelCase): acos/tan/sin/atan2-Kette,
  Klemmung cos∈[-1,1], None bei kollinear (<1e-4 / π-θ<1e-4) oder zu kurzem
  Schenkel. Winkel im Diff-Test abs 1e-7 rad (libm-ULP-Drift), Struktur exakt.
- 3 Batch-Fassaden (offset_segment/offset_polyline/fillet_corner) + 4 Unit-Tests.
- Harness: Offset (rel 1e-9) + Fillet (halb kontrolliert/halb Zufall, Winkel
  1e-7) + Golden (L-Ecke, rechter Winkel, kollinear/zu-gross → null).

cargo test 14/14, vitest 242 (3 neu, davon 12 Parity) gruen, tsc sauber.
2026-07-05 00:50:38 +02:00
karim 09c5178c85 Pendenzen: kernel2d-Port als In-Arbeit-Item mit Phasen-Fortschritt (1+2 erledigt) 2026-07-05 00:43:29 +02:00
karim 8750c8f547 kernel2d-Port Phase 2: Primitive/Schnitt/Flaeche/Kreis + Differential-Harness
Rust-Port (1:1 aus kernel2d.ts, exakte Term-Reihenfolge/EPS-Politik):
- Primitive: dist, vecEqual, projectParam, closestPointOnSegment,
  pointSegmentDistance.
- Schnitt: Hit, segmentIntersect, lineSegmentIntersect, polylineEdges,
  segmentPolylineHits (stabile Sortierung, 1e-6-Dedup).
- Kreis: lineCircleIntersect (Disc B*B-4*A*C + Klemmung), segmentCircleIntersect,
  circleCircleIntersect.
- Flaeche: signedArea (Shoelace, identische Vertex-Reihenfolge), isCCW.
- 11 Batch-WASM-Fassaden (JSON rein/raus) + 10 native Unit-Tests.

Differential-Harness (src/geometry/kernel2d.parity.test.ts):
- Rust-WASM (initSync, readFileSync) gegen TS-Referenz kernel2d.ts, seed-basierte
  Zufallseingaben (Cluster nahe 0 / an Schwellen) + Golden-Grenzfaelle
  (parallel/kollinear/Null-Laenge, Tangente, konzentrisch/getrennt/innen-tangential,
  Null-Flaeche). Struktur exakt, dann Werte mit op-Epsilon (coord/param abs-rel 1e-9,
  Flaeche rel 1e-9).
- Skippt sauber ohne gebautes pkgKernel2d (git-ignoriert), bricht die Suite nicht.

cargo test 10/10, vitest 239 (9 neu) gruen, tsc sauber, build:kernel2d sauber.
2026-07-05 00:43:03 +02:00
karim 028a3637b4 Pendenzen: Textur-Spike visuelle Abnahme bestanden 2026-07-05 00:33:39 +02:00
karim 74eecf7a73 Pendenzen: Textur-Spike render3d erledigt (8556037), aus Queue in Verlauf 2026-07-05 00:30:58 +02:00
karim 0ca3b1dd57 render3d Textur-Spike: RenderStyle::Textured real (Bild-Textur auf Waenden)
- Zweiter Vertex-Pfad [pos,normal,uv] via build_walls_mesh_textured, ABGELEITET
  aus dem fertigen Mesh (Positionen/Normalen/Indizes 1:1) -> Alt-Pfad
  [pos,normal,color] bitgleich; per Regressionstest belegt.
- Prozedurale 256x256-Schachbrett-Textur (kein Asset, kein image-Crate),
  Sampler Linear/Repeat, Textur-Bind-Group group 1 (Globals bleibt group 0).
- MESH_TEXTURED_WGSL: gleiche Beleuchtung wie MESH_WGSL, Albedo aus textureSample.
  Pipeline in Depth/MSAA/Color-Target bitidentisch zur Haupt-Pipeline.
- UV planar in Metern: Mantel u=entlang Achse/v=Hoehe, Deckel u=x/v=z;
  weltraumstabil, keine Verzerrung an Gehrungen. 1 Kachel = 1 m.
- spike3d: Taste T schaltet Shaded <-> Textured zur Laufzeit (kein Re-Meshing).
- Feature-gegatet, Default-Build/-Darstellung unveraendert. cargo test 58 (default)
  / 59 (--features render, inkl. naga-Test MESH_TEXTURED_WGSL) gruen.
2026-07-05 00:30:34 +02:00
karim ecefe61611 Pendenzen: Textur-Spike render3d in Queue (Als Naechstes)
- SPIKE_TEXTUR_render3d.md: Auftrag/Uebergabe fuer den kleinsten ehrlichen
  Durchstich (RenderStyle::Textured real: UVs, prozedurales Schachbrett,
  Textur-Bind-Group, MESH_TEXTURED_WGSL, spike3d umschaltbar).
- PENDENZEN: Spike als konkretes Item unter 'Als Naechstes', verlinkt am
  bestehenden Textur-/PBR-Backlog-Eintrag als dessen erster Durchstich.
2026-07-05 00:12:06 +02:00
karim 2d96a864da kernel2d-Port Phase 1: Crate-Skelett + WASM-Fassade + build:kernel2d
- src-tauri/kernel2d: eigenstaendiges Crate (cdylib+rlib, eigener leerer
  [workspace]), Feature web (wasm-bindgen) und additives robust-predicates.
- Vektor-Helfer 1:1 aus src/model/geometry.ts portiert (hypot-len,
  normalize-Nullguard, hartkodiertes 1e-9 in line_intersect) + Unit-Tests.
- Leere Batch-Fassade kernel2d_normalize_json als WASM-Grenzen-Ping.
- package.json: build:kernel2d; src-tauri/Cargo.toml: workspace-exclude.
- PORT_PLAN.md: Portierungsplan (Scope, Crate-vs-Port, Diff-Harness, Phasen).
2026-07-05 00:09:12 +02:00
karim dec431579e geometry-Crate zu WASM baubar (Feature web, compute_joins_json); aus cad-tauri-Workspace ausgeschlossen
Erster Schritt der Rust-Kern-Migration: die Join-Geometrie wird per wasm-pack zu
WASM gebaut (build:geometry) und exportiert compute_joins_json (JSON rein/raus).
Damit kann das TS-Frontend kuenftig die EINE Rust-Implementierung aufrufen statt
des TS-Duplikats. Crate wie render2d/render3d aus dem Workspace excludet, bleibt
per Pfad-Dep fuer den nativen Host nutzbar. Verhalten unveraendert (noch nicht
verdrahtet). geometry cargo test 8/8, cad-tauri cargo check ok.
2026-07-04 23:44:18 +02:00
karim 9520191bde Pendenzen: Darstellungs-Slots cut/Aufsicht/Untersicht ergaenzt (Deckenspiegel-Fall) 2026-07-04 23:29:02 +02:00
karim 9136cad0ee Pendenzen: Bug-Fixes verbucht; Backlog-Item Schnitt- vs. Ansichtslinie nach Schnitthoehe 2026-07-04 23:27:24 +02:00
karim c7e080f639 Grundriss: Decken-Umriss an Wand-Footprints clippen (Decke liegt darunter)
Die Decke ist ein Slab ueber der Schnittebene; ihre Umrisslinie soll dort, wo
eine Wand darueber steht, NICHT durch die Wand-Poche schlagen (glPlan zeichnet
alle Fuellungen, dann alle Linien -> Kontur landete sonst ueber den Waenden).
Die Fuellflaeche wird jetzt strokelos gezeichnet, der Umriss nur ueber die
Teilstuecke, die KEIN Wand-Footprint (OBB) verdeckt. Deckungsgleiche Decke
(Umriss = Wand-Mittellinien) -> Umriss entfaellt ganz; nur Ueberstaende bleiben.
2026-07-04 23:26:00 +02:00
karim aa4205bf0b T-Stoss: materialgleicher Nah-Putz verschmilzt ohne L-Trennnaht (TS+Rust)
Die L-Seitenlinie am T-Stoss wird nur noch gezeichnet, wenn der getrimmte
Abzweig-Putz materialFREMD zum durchgehenden Nah-Putz der Durchgangswand ist.
Bei materialgleichem Putz (z. B. iw-Innenputz auf iw-Innenputz) fuellt der
Nah-Putz die Putzflanken durchgehend (spanCutout schneidet nur die Kernbreite)
-> durchgehendes Putz-L ohne Naht. Tests entsprechend gezogen.
2026-07-04 23:17:18 +02:00
karim 9a80d9cf42 Snap-Farbe Sora #5FA1C9 als Default festgeschrieben; Pendenzen-Queue auf verifizierten Stand 2026-07-04 22:46:21 +02:00
karim ea86cf7456 Doku: Recovery-Stand 2026-07-04 (alle drei 3b-Slices gelandet)
PENDENZEN: Oeffnungen als Boolean-Loecher (1407c68) nach Erledigt. HANDOVER:
Slice 3 committet, Environment-Behebung + Push-Blocker dokumentiert.
2026-07-04 22:19:19 +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 87a30b7061 Pendenzen: zentrale Aufgaben-Queue (PENDENZEN.md), HANDOVER auf Kontext geschlankt
PENDENZEN.md als Single Source of Truth fuer Aufgaben eingefuehrt
(priorisierte Checkliste + Arbeitsprotokoll: Worker liest zuerst,
arbeitet top-down, Rueckfrage-Recht). Backlog/Rueckfragen/IN-FLIGHT
vollstaendig aus HANDOVER migriert; HANDOVER enthaelt nur noch
Kontext/Konventionen/Environment/Zielmodelle. Stand-Korrektur:
Locked-Iso (cb8fae5) und Joins Phase 1c (c5a344d) sind gelandet,
nur Oeffnungen-als-Boolean-Loecher noch offen.
2026-07-04 20:00:48 +02:00
karim 23dddf893e Joins Phase 1c: Durchgangswand am T-Stoss echt aufbrechen (spanCutouts)
Am materialbewussten T-Stoss wurde die Durchgangswand bisher nur uebermalt
(Zeichenreihenfolge), nicht geometrisch ausgeschnitten: ihr Nah-Putz-Band, die
Schichtfugen- und die Nahflaechenlinie liefen weiter ueber die Durchstoss-Breite
des Abzweig-Backsteins. Neu liefert computeJoins erstmals auch Cuts fuer die
DURCHGANGSWAND: WallCuts.spanCutouts (Achsen-Intervall = Projektion der Abzweig-
Kernbreite, Quer-Offsetzone = Nahflaeche bis Rueckgrat-Nahflaeche = Nah-Putz-
Tiefe aus Phase 1b). addWallPoche splittet betroffene Schicht-Baender entlang der
Achse in Teil-Baender vor/nach dem Intervall, unterbricht die Schichtfugen im
Merge-Bereich und macht die Nahflaechen-Umrisskante ueber dem Durchstoss
strokelos (separate Segmente davor/danach) — keine Trennlinie an der
Verschmelzungsflaeche, der T-Stoss liest als EIN Join. Rust-Paritaet additiv
(span_cutouts), Aggregat-startCut/endCut unveraendert -> parity gruen.

vitest 227 (+5), cargo 8 (+1), tsc sauber.
2026-07-04 19:22:32 +02:00
karim 45ded83294 Nordstern-3D: Locked-Iso — freie Kamera bleibt nach Ortho-Preset orthografisch
Iso/Front/Top/Side kippten bei der ersten Kamerabewegung sofort in Perspektive,
weil orbitCamera() Projektion und Ortho-Halbhoehe hartkodiert hatte
(perspective:true / dist*0.5). OrbitState fuehrt jetzt ortho:boolean +
orthoHalfHeight:number: der Preset-Effekt setzt ortho = view3d!=='perspective'
und seedet orthoHalfHeight auf dist*tan(FOV_Y/2) (perspektiv-aequivalente
Bildhoehe an der eingepassten Distanz -> kein Sprung beim ersten Move). Pan
rechnet worldPerPx in Ortho aus der Halbhoehe statt aus dist; Zoom skaliert im
Ortho-Modus orthoHalfHeight multiplikativ (0.05-500) und laesst dist/eye
unangetastet. Perspektive-Preset unveraendert.
2026-07-04 18:51:35 +02:00
karim 77f32f14ce Nordstern-3D: Live-Schnittebene mit schraffierten Schnittflaechen
Der 3D-Viewport kann das Modell jetzt live an einer vertikalen Ebene
aufschneiden (Overlay-Button 'Schnittebene', MVP: Ebene durch die
Modellmitte, Blick +Y):
- Globals um section_plane vec4 erweitert (xyz=Normale, w=-n*p; Enable
  in mode.y); MESH_/GRID_WGSL discarden Fragmente vor der Ebene
  (world_pos als neuer Varying) - Flaechen, Kanten, Grid, Highlight.
- section_fill.rs (neu): build_cut_caps ruft cut_section und trianguliert
  jedes (u,v)-Rechteck zurueck in Weltkoordinaten ([x,y,z,u,v]).
- CAP_WGSL: prozedurale 45-Grad-Diagonalschraffur aus (u,v) in Modell-
  Metern (fwidth-AA), Tinte auf Papier wie die 2D-Konvention; eigene
  cap_pipeline (CullMode::None, Depth-Bias Richtung Kamera gegen
  Z-Fighting), gezeichnet nach den Flaechen, nicht geclippt.
- web.rs cached walls/slabs; set_section_plane(active, p, n) aktualisiert
  Uniform + Caps; set_model baut Caps bei aktivem Schnitt neu.
- useWasm3dRenderer.setSectionPlane + Toggle in Wasm3DViewport.

Bekannte Luecken (dokumentiert): Oeffnungen im 3D-Solid nicht ausgespart
(cut_section spart aus -> Mismatch bei Schnitt durchs Fenster; wird mit
dem Boolean-Loecher-Slice geloest), nur vertikale Ebenen, ein globales
Muster (per-Bauteil = Stufe 2). cargo 56 Tests + naga-WGSL-Validierung,
222 vitest gruen, WASM neu gebaut (pkg3d gitignored).
2026-07-04 15:08:41 +02:00
karim 07042ebc75 Joins Phase 2: Merge-Regel im Schnitt (gleiche Komponente verschmilzt)
Die Schnitt-Dominanz kannte nur 'strikt hoeher schneidet schwaecher'.
Neu: Baender GLEICHER joinPriority UND GLEICHER Komponente, die sich
beruehren/ueberlappen, verschmelzen zu EINEM Rechteck (rectUnionIfRect:
Union nur, wenn das Ergebnis exakt ein Rechteck ist; iterativ bis zum
Fixpunkt) - keine innere Trennlinie mehr durch gleichartiges Material,
analog resolveJoinPriority 'merge' im Grundriss. SectionCutPolygon
traegt dafuer componentId (Schicht-Split + repraesentatives Bauteil bei
einschichtiger Poche). Verschiedene Komponenten gleicher Prioritaet
koexistieren unveraendert; Subtraktion bit-identisch. +6 Tests (222).
2026-07-04 15:06:19 +02:00
karim ecf262ef07 HANDOVER: Stand 2026-07-04 (Prioritaets-Joins, Schnitt-Sanierung) 2026-07-04 15:00:55 +02:00
karim 9acce9d7cd Joins Phase 1b: T-Stoss-Kern sticht nur durch den Nah-Putz (keine Achs-Ueberlappung)
Der verschmelzende Abzweig-Kern (Backstein) lief seit Phase 1 bis zur
ACHSE der Durchgangswand und ueberlappte deren Koerper. Jetzt stoppt er
an der Nahflaeche des Durchgangs-Rueckgrats: mergeCut bei
offT + sign*(tT/2 - nearPlaster), wobei nearPlaster die Summe der
Durchgangs-Schichten zwischen Nahseite und Rueckgrat-Kern ist. Die
L-Seitenlinien der Putzschichten liegen ebenfalls auf dieser Tiefe.
Naht zwischen den beiden Kernen entfaellt ueber die bestehenden
Mechanismen (stroke:none am Fuellband, noStrokeEdges an den Stirnkanten,
Zeichenreihenfolge bricht die Nahflaechenlinie auf) - kein
generatePlan-Umbau noetig. Rust-Paritaet in geometry/lib.rs analog
(Aggregat-Cuts unveraendert, parity.test gruen). 216 Tests + cargo 7/7.
2026-07-04 14:55:51 +02:00
karim cf8b638f33 Schnitt: wandrelative Schraffuren drehen mit der geschnittenen Wand
splitWallLayers uebergab resolveHatch keinen Wandachsen-Winkel, wodurch
wandrelative Muster (relativeToWall: Daemmung, Backstein) im Schnitt
absolut blieben — die Daemmung lief vertikal statt quer zur Wanddicke.
Die geschnittene Wand steht im Schnitt vertikal (Bandachse entlang v,
Modellwinkel 90 Grad); dieser Winkel wird jetzt wie im Grundriss
(addWallPoche) mitgegeben -> Daemmung horizontal, wie an den Waenden
im Grundriss. 216 Tests gruen.
2026-07-04 14:54:10 +02:00
karim 20cf870c4c Schnitt: materialspezifische SIA-Schraffuren wiederhergestellt
de7a26b lieferte projectToModel3d pro SCHICHT eine eigene Voll-Box; der
Schnitt bekam damit segments*layers Cut-Polygone, waehrend
wallSegmentOwners weiter nur oeffnungsbasiert segmentiert -> Index-
Versatz, falscher Owner, splitWallLayers zerteilte bereits einschichtige
Baender erneut -> einheitliches Diagonal-Muster statt SIA-Muster.

Fix: Model3dOptions { layeredWalls } an projectToModel3d (Default true,
3D-Viewer unveraendert); computeSection ruft mit layeredWalls:false ->
eine Voll-Box pro Wand, Owner-Mapping wieder 1:1, splitWallLayers
erzeugt die per-Material-Baender (Daemmung-Haarlinien, Backstein-
Diagonale, Beton-Kreuz) wie im Grundriss. 216 Tests gruen.
2026-07-04 14:44:36 +02:00
karim e095b51d15 Schraffuren monochrom: Vordergrund #0f0f0f, Hintergrund #f0f0f0
Alle Schraffuren (Schnitt- UND Oberflaechen-/Ansichtsschraffur) rendern
jetzt einheitlich in Tinte #0f0f0f auf Papier #f0f0f0 statt in der
Materialfarbe des Bauteils (Backstein braun, Beton grau). HATCH_INK/
HATCH_PAPER ersetzen POCHE_FILL_BLACK/WHITE; resolveHatch liefert immer
HATCH_INK als Linienfarbe. Der generische Schnitt-Fallback nutzte bisher
die rohe 3D-Albedo (Ursache des Backstein-Brauns bei nicht aufloesbarer
Schicht) -> jetzt HATCH_PAPER. Print-Mono-Modus unberuehrt. 216 Tests gruen.
2026-07-04 14:33:35 +02:00
karim 65d6e843fb Fix Regression: 3D-Wandschichten auf linke Normale (Schnitt = Grundriss)
de7a26b versetzte die per-Schicht-Boxen entlang (uy,-ux) = RECHTE Normale,
waehrend Grundriss/clippedBand die LINKE Normale leftNormal(u)=(-uy,ux)
nutzt -> Schichten im 3D UND im davon abgeleiteten 2D-Schnitt gespiegelt
(Backstein aussen statt innen). pushSegment nutzt jetzt die linke Normale.
Wandlage unveraendert (Stack bleibt symmetrisch um die Achse), nur die
Schichtseiten stimmen wieder mit dem Grundriss. raycast3d unberuehrt
(symmetrische Box). 216 Tests gruen, kein WASM-Rebuild.
2026-07-04 14:22:12 +02:00