Commit Graph

82 Commits

Author SHA1 Message Date
karim 43130ff018 Text-Styling-Leiste wirkt auf selektierten Freitext/Textspalte
Die Text-Formatier-Gruppe der Oberleiste formatierte bisher nur den
Raum-Stempel. Jetzt ist auch ein selektierter Freitext/Textspalten-Element
(Drawing2D shape "text") ein Formatier-Ziel:
- Neues optionales Feld Drawing2D-Text.marks (Marks) für einheitliche
  Formatierung (Schriftfamilie, fett/kursiv/unterstrichen, Farbe).
- App.textTarget adaptiert den Text über docFromText/plainText an die
  Rich-Text-Leiste; die GRÖSSE bleibt bewusst über die Modell-Höhe (Meter),
  nicht über pt (massstabslos wäre falsch) — sizePt wird verworfen.
- generatePlan/PlanView rendern die Marks (fontFamily/-weight/-style/
  textDecoration); marks.color hat Vorrang vor der Kategorie-Farbe.
+3 Tests. tsc + vitest grün.
2026-07-09 01:28:37 +02:00
karim d11cda5b87 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 060b851e5c Tür/Fenster 2D: Rahmenband, Blockrahmen, Schichteinzug, Oberlicht-Linie
Setzt die vertieften Tür-/Fensterparameter im Grundriss-Schnitt um:
- opening-frame: Rahmenprofil als Band der Breite frameWidth in der
  Laibung; Blockrahmen (Tür) als kräftigeres, vor die Laibung gesetztes
  Profil, Zarge als schmales Laibungsband.
- Schichteinzug: die gewählte Fläche (aussen/innen) wird um insetFromFace
  nach innen versetzt (Nahkante wandert, Fernkante bleibt).
- opening-transom: gestrichelte Überkopf-Linie über der Öffnung, wenn
  transomHeight > 0.
Typlose Öffnungen zeichnen unverändert (Rückwärtskompatibilität getestet).
+5 Tests. tsc sauber, vitest grün.
2026-07-09 01:14:16 +02:00
karim 1d939a939a 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 1c33232139 Bauteile: Fenster-Anschlag-Striche (Laibung, fein) analog zur Tür, mit Tests 2026-07-05 21:42:40 +02:00
karim a92b583df8 Schnitt/Ansicht Phase 2: Decken-Überkopf-Umriss als gestrichelte Haarlinie (über Schnittebene), mit Test 2026-07-05 21:31:48 +02:00
karim 804c23628a Schnitt/Ansicht Phase 1: Wand unter Schnittebene als Ansichts-Umriss (viewOnly, keine Poché), mit Tests 2026-07-05 21:22:51 +02:00
karim 1c03e35e84 Fix: Kreise/Bögen im WebGL-Renderer sichtbar (drawingCircle/drawingArc tesselliert; Regression aus 21d76bd) 2026-07-05 20:31:04 +02:00
karim 2c563a2000 DXF-Import: Platzierungsoption (relativ zu 0 ODER in Ansichtsmitte) 2026-07-05 15:17:09 +02:00
karim 21d76bd71d DXF-Import: CIRCLE/ARC als echte glatte Kreis-/Bogen-Formen (statt tesselliertem Vieleck) 2026-07-05 15:06:25 +02:00
karim 1fcd1d5a06 DXF-Import: TEXT/MTEXT -> editierbarer Plan-Text (Drawing2D text-Primitiv, SVG-Render) 2026-07-05 14:29:05 +02:00
karim 7b9ea8bd07 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 4544b6be0d 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 585e9ce9d1 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 965b29e1fa 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 51d43a51b1 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, d1244a1) 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 64c1d058d6 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 6c2e9a4282 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 106f4716a7 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 74ec476c44 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 d4d9721c3d Schnitt: materialspezifische SIA-Schraffuren wiederhergestellt
32f921b 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 9ec38ec947 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 ac3de56e1f Fix Regression: 3D-Wandschichten auf linke Normale (Schnitt = Grundriss)
32f921b 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
karim 00b5035541 Joins Phase 1: materialbewusster T-Stoss (Backstein verschmilzt, Putz-L)
Am T-Stoss wird der Abzweig nicht mehr naiv ueber die volle Dicke an der
Durchgangswand-Flaeche gekappt. Neu (joinPriority-basiert):
- resolveJoinPriority(a,b): merge/coexist/trim je nach Prioritaet+Komponente.
- WallCuts.layerCuts (additiv): pro Schicht eine Cut-Linie + optionale L-Seiten-
  linie. Gleiche/hoehere Prioritaet wie der Durchgangs-Backbone -> kein Cut
  (Schicht laeuft durch = Merge); schwaechere Schicht -> Nahflaechen-Cut + L.
- addWallPoche nutzt layerCuts pro Schicht (Fallback: alte Aggregat-Cuts);
  neue 'layer-joint-l'-Linie als L-Rueckschnitt.
- Rust-Paritaet in geometry/lib.rs additiv gespiegelt (LayerInput serde default,
  Aggregat-Cuts bit-identisch -> parity.test gruen).

Einschichtige/nicht-passende T-Stoesse pixel-identisch. +8 Tests (216 gesamt),
cargo 7/7.
2026-07-04 14:13:55 +02:00
karim d1244a147a 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 bf1e5236f1 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 32f921b7af 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 0fa3d0e691 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 aabfa3db53 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
karim ca60b5a9a4 Nordstern-3D: Klick-Auswahl von Bauteilen (Raycast)
Links-Klick auf eine Wand/Decke im 3D-Viewport selektiert das Bauteil
(TS-Raycast gegen OBB der Wände + extrudierte Deckenprismen), setzt die
Store-Selektion (setSelectedWallIds/setSelectedCeilingIds, Shift/Ctrl =
additiv) → Attribute- und Objekt-Info-Panel zeigen das Bauteil. Erster
Schritt zur 3D-Editierbarkeit.

- raycast3d.ts: reine Kamera-Strahl-/Schnitt-Mathematik (10 Unit-Tests).
- toWalls3d.ts: wallId/ceilingId in die 3D-Records + pickGeometry();
  Serde-Pfad unberührt (keine deny_unknown_fields, Extrafelder werden
  Rust-seitig ignoriert).
- Klick-vs-Drag-Schwelle (4px) trennt Auswahl von Orbit; Leertreffer
  leert die Auswahl.
2026-07-04 06:17:45 +02:00
karim d69d6f5f24 Zeilenhöhe-Regler statt "+ Text"; Linienstil editierbar; DOSSIER-Audit gesichert
- "+ Text"-Knopf entfernt (war ohnehin immer deaktiviert, kein Werkzeug
  dahinter — Text wird ein eigenständiges Zeichenwerkzeug, AUDIT B1).
  An seiner Stelle ein Zeilenhöhe-Regler (Stepper, Vielfaches der
  Schriftgrösse) — neues Paragraph.lineHeight, durchgereicht bis in
  HTML-Vorschau (line-height) und SVG-Render (kumulierte Zeilen-
  Vorschübe statt festem lineGap).
- Linienstil im Attribute-Panel war rein informativ (kein Setter im
  Host-Kontrakt). onSetSelectionLineStyle ergänzt (nur Drawing2D),
  jetzt echtes Dropdown statt "—"-Anzeige.
- docs/design/dossier-feature-audit.md: der ausführliche A1-A6/B1-B4/
  C1-C3/D1-D3/E-Auditbericht aus einer alten Session gesichert (lag
  bisher nur im Transkript, nicht im Repo) — Quelle der HANDOVER.md-
  AUDIT-Kürzel.
2026-07-04 05:36:18 +02:00
karim 59b9d3f7bb TopBar-Redesign: Marke, Zoom-Cluster, Datei-Menü, Fenstersteuerung, Dark-Theme fest
- Marke (DOSSIER-Wortmarke) + Ressourcen-Icon ganz links, wie im
  Rhino-Plugin; Settings-Icon folgt über den neuen Einstellungs-Dialog.
- Massstab/Zoom-Cluster bereinigt: doppelte Massstab-Dropdown entfernt,
  Zoom-Aktionen unter dem Massstab-Dropdown gestapelt (gleiche Breite),
  Ring bei "am Massstab" statt Flächen-Aufhellung.
- PDF/DXF-Export aus der Leiste raus, zusammen mit Speichern/Öffnen/
  Import in einem neuen Datei-Burger-Menü ganz rechts. Speichern/Öffnen
  sind echte JSON-Download/-Upload-Handler fürs ganze Projekt.
- Einstellungs-Fenster (neu): Accent-Palette, Auswahlrahmen-/Snap-Farbe
  editierbar (freier Picker + Presets), Projekt-Referenzhöhe (m ü. M.)
  als Feld.
- LayoutMenu auf die eigene Dropdown-Komponente umgestellt (war noch
  natives <select>).
- Custom Fenstersteuerung (_/□/X) für die randlose Electron-Shell via
  Preload+IPC, eigener Look statt OS-Chrome; Oberleiste als Drag-Region.
- Dark-Theme ist jetzt fester Standard (vorher an OS-Präferenz
  gekoppelt, zeigte je nach Umgebung fälschlich Light) — Light bleibt
  als Opt-in (`[data-theme="light"]`) für einen künftigen Umschalter.
  Alle Oberleisten-Pillen (Dropdown-Trigger, Segmente, Icon-Knöpfe,
  Ansichts-Icons) auf dieselbe dunkle Fläche wie das Kontextmenü
  vereinheitlicht. Panel-Köpfe nicht mehr separat aufgehellt, feste
  Höhe (40px) unabhängig von optionalem Darstellungsmodus-Dropdown.
- 2D-Zoom-Grenzen deutlich erweitert (20000x/0.005x statt 50x/0.2x).
2026-07-04 05:10:44 +02:00
karim 761119a39c Nordstern: Geo-Kontext-Meshes (Terrain/Import) rendern
Bisher zeigte nur three.js importierte Gebaeude/DXF-Meshes und das
Terrain-TIN (Project.context). Neuer MeshInput-Typ + Kontext-Mesh-Pfad
in render3d (Flat-Normalen, doppelseitig gegen unbekanntes Winding),
projectToModel3d speist project.context jetzt in beide Renderer
(nativ + WASM) ein. Nebenbei: fehlendes layers-Feld in demo_walls()
behoben, das den native3d-Feature-Build zuvor schon brach.
2026-07-04 04:38:00 +02:00
karim 3fe207ce0f Attribute: By-Layer/By-Object-Quelle fuer Farbe, Strichstaerke, Schraffur
Vordergrund, Hintergrund, Strichstaerke und Schraffur je Element (Wand/Decke/
Drawing2D) haben jetzt einen 3-Wege-Quellen-Dropdown: Nach Ebene / Nach
Bauteil / eigener Wert. Aufloesungsreihenfolge: expliziter Wert > (Quelle
'layer' => LayerCategory-Wert color/lw/hatch) > Bauteil/LineStyle-Default.
Neue *Source-Felder + strokeWeight/hatchId-Overrides am Modell (additiv,
optional), getLayerCategory-Accessor, resolveHatchId/resolveStrokeWeight;
resolveForeground/Background um category+source erweitert. Sample rendert
identisch (kein Override/Source gesetzt => Default 'object' = altes Verhalten).
Offen: LayerCategory-Schraffur noch nicht im Kategorie-Dialog editierbar.
2026-07-04 02:19:38 +02:00
karim 3f048e4068 Schnitt: Boolean-Dominanz der Schichten nach joinPriority
Wo sich Schicht-Baender verschiedener Elemente im Schnitt ueberlappen, gewinnt
die staerkere Schicht (hoehere joinPriority) und schneidet die schwaechere per
Rechteck-Subtraktion weg (elementuebergreifend: die Betondecke schneidet den
Wand-Putz). Gleiche Prioritaet koexistiert (durchgehende Betonflaeche Wand+
Decke). attachCutStyles sammelt jetzt alle Baender mit joinPriority und laesst
subtractDominantBands global gegen alle staerkeren Cutter subtrahieren; die
ueberlappungsfreie Zerlegung liefert exakt die Material-/Fugenlinien zwischen
den Schichten. Neuer subtractRect-Helfer, 11 neue Tests, 152 gruen.
2026-07-04 01:46:01 +02:00
karim 72c79e0090 Schnitt: Wandschichten nach echter Aussen/Innen-Richtung orientieren
splitWallLayers legte die Schichtbaender bisher fix layers[0]->uMin, ohne die
tatsaechliche Wandorientierung — gegenueberliegende Waende sahen identisch aus
statt gespiegelt. Jetzt wird die Aufbaurichtung aus der Grundriss-Konvention
gespiegelt (Schichten stapeln entlang leftNormal der Wandachse), gegen die
Schnitt-u-Weltachse (aus der SectionPlane) projiziert; ist das Skalarprodukt
negativ, wird die Bandreihenfolge umgekehrt (layers[0]->uMax). Damit liegt die
Daemmung aussen, der Backstein innen, und gegenueberliegende Waende sind
spiegelbildlich. Neue Helfer sectionUAxisModel/wallLayersReversedInU, additiv
durch attachCutStyles durchgereicht. 6 neue Tests, 141 gruen.
2026-07-04 01:39:26 +02:00
karim 3ad1549f45 Linien: modulares Segment-System (Strich/Punkt/Luecke) + Loop-Vorschau
Der Linien-Editor ist modular: eine Linie ist eine geordnete, loopende Folge
aus Segmenten Strich (Laenge), Punkt (Dot) und Luecke (Laenge) — beliebige
Sequenzen (Volllinie/Strichlinie/Punktlinie/Strich-Punkt als Presets, plus
frei), die Schluss-Luecke ist die letzte Luecke. Datenbasis bleibt
LineStyle.dash (mm, alternierend); ein Punkt ist ein 0-Laengen-AN-Segment.
Enthaelt dash eine 0, wird die Linie mit runder Kappe gezeichnet, damit
Punkte als Dots erscheinen (Live + Print; GL/DXF Folgearbeit). Neue reine
Segment-Logik in ui/lineSegments.ts. LineSwatch zeigt den ersten Loop dunkel
und 2 weitere grau (Loop-Kontext). 14 neue Tests, 127 gruen.
2026-07-04 01:21:04 +02:00
karim 867acd4382 Random-Schraffur modellraum-verankert + Motiv-Editor fuer Custom-Linien
Random-Verankerung (Bugfix): die Streu-Striche haengen nicht mehr an der
Polygon-Bounding-Box, sondern an einem absoluten Modellraum-Gitter
(hashCell aus absoluten Zell-Indizes + hatch.seed). Beim Vergroessern der
Flaeche bleiben bestehende Striche stehen, am Rand kommen neue dazu, die
Dichte bleibt konstant, Verschieben wandert nicht; 'Neu wuerfeln' (neuer
Seed) verschiebt das ganze Feld. Alle Renderpfade ziehen aus derselben
Funktion. Verankerungs- und Verschiebe-Dichte-Test ergaenzt.

Motiv-Editor: neuer wiederverwendbarer MotifEditor (Punkte setzen/ziehen in
einer Einheitszelle, Live-Loop-Vorschau). LineStyle.kind 'custom' + motif
(points/length), additiv durchgereicht (analog zigzag) und in allen
Renderpfaden gekachelt (motifPoints, Verallgemeinerung von zigzagPoints).
ResourceManager-Umschalter Vollinie/Strich/Zickzack/Motiv, LineSwatch-
Vorschau. Insgesamt 5 neue Tests, 113 gruen.
2026-07-04 01:09:00 +02:00
karim 0fbdc62c21 Linien-/Random-Editor: Strich-Segmente, Vollinie, Random-Kontrollen; Weight raus
Linien-Editor: Umschalter Vollinie (dash null) / Strich mit editierbarer
Segment-Liste (mm, alternierend Strich/Luecke, hinzufuegen/entfernen), Live-
Vorschau. Das Strichstaerken-Feld ist aus dem Linien-Editor entfernt —
LineStyle.weight ist @deprecated (bleibt Render-Fallback), die echte
per-Element-Aufloesung (Attribut->Ebene->Default) folgt separat.

Random-Schraffur: additive HatchStyle-Parameter seed/density/lengthMin/Max +
Neu-wuerfeln-Button (neuer Seed nur zur Editzeit). buildRandomHatchRuns mischt
den expliziten Seed in den Hash und nutzt Dichte/Laenge — Determinismus
gewahrt (gleicher Seed+Flaeche => gleiche Streuung), ueber alle Renderpfade
konsistent, da alle aus derselben Funktion ziehen. resolveHatch/HatchRender
reichen die Parameter rein additiv durch. 2 neue Tests.
2026-07-04 00:53:19 +02:00
karim c56f668354 Schraffur/Linien: Rendering der neuen Typen (Bild, Random, Zickzack)
Bild-Schraffur als getiltes <pattern>/<image> (scaleX/scaleY/rotation) im
Live-SVG- und Print-Pfad; GL/WASM/DXF vorerst neutraler Fallback (Folgearbeit,
im Code vermerkt). Random-Vektor-Schraffur als deterministische Streu-Striche
(mulberry32-Seed aus Flaechen-Bounding-Box, kein Math.random) in allen Pfaden.
Zickzack-Linie als getilteter Pfad; LineStyle.kind/zigzag additiv durch die
Linien-Emission (generatePlan) bis zu den Renderern durchgereicht. Geteilte
Geometrie in glPlanHatch (scatterStrokes/buildRandomHatchRuns/zigzagPoints) —
eine Wahrheit fuer Live/Print/GL/DXF. 8 neue Tests.
2026-07-04 00:41:09 +02:00
karim b3b361eaf3 Schraffur/Linien: Typmodell-Fundament (additiv, backward-kompatibel)
Vorbereitung fuer Vektor-/Bild-Schraffuren, Strich-/Zickzack-Linien und
Vordergrund/Hintergrund-Farben ohne Verhaltensaenderung. Alle neuen Felder
optional, Sample rendert identisch:
- HatchStyle: kind (vector/image), lines (parallel/random), image
  (src/scaleX/scaleY/rotation); color deprecated, bleibt Resolve-Fallback.
- LineStyle: kind (dash/zigzag), zigzag (amplitude/wavelength).
- Component: foreground (Muster) + background (Fuellung); color bleibt
  Fallback und 3D-Albedo.
- Wall/Ceiling/Drawing2D: foreground/background-Overrides (undefined = Nach
  System).
- generatePlan: HatchRender um kind/lines/image erweitert; resolveForeground/
  resolveBackground mit dokumentierter Reihenfolge (Override -> Component ->
  Alt-Farbe); toSection reicht Vordergrund je Schicht durch.
2026-07-04 00:17:28 +02:00
karim 981b2264ac Verschiebe-Dreieck flacher (Apex ~124 statt ~60 Grad) 2026-07-04 00:07:41 +02:00
karim af99c62faf Zoom-Prozent relativ zum angewandten Massstab statt zur Einpassung
Die Zoom-Anzeige band 100% bisher an die eingepasste Default-Ansicht, nicht
an den angewandten Papier-Massstab — der Wert driftete willkürlich. Er wird
jetzt in App.tsx aus angewandtem Nenner und Live-Nenner abgeleitet
(scaleDenominator / liveScale * 100): im angewandten Massstab exakt 100%,
hineinzoomen >100%, herauszoomen <100%. Die fit-basierte onZoom-Meldekette
aus PlanView entfällt (Single Source).
2026-07-04 00:02:50 +02:00
karim 88e38f8d6b Mehrschichtige Wände im Schnitt als Schicht-Bänder
Analog zur Decke (splitSlabLayers) wird ein mehrschichtiger Wandtyp im
Schnitt nicht mehr mit einer repräsentativen Schraffur über die ganze
Dicke gefüllt, sondern in Schicht-Bänder zerlegt — quer zur Dicke entlang
u (volle Höhe je Band), jedes Band mit der Schnittschraffur seines
Bauteils. Einschicht-Wände laufen unverändert über resolveWallSectionStyle.
Seitenorientierung (aussen/innen) vorerst deterministisch layers[0]→uMin;
korrekte Orientierung via Wandnormale bleibt Folge-Iteration.
2026-07-03 23:36:06 +02:00
karim 698b3c8d9b Bauteil: Ansichtsschraffur neben Schnittschraffur
Bauteil trägt jetzt zwei Schraffuren: die bestehende hatchId als
Schnittschraffur (nur wo tatsächlich aufgeschnitten) und ein neues
optionales Feld viewHatchId als Ansichtsschraffur für die frontale,
ungeschnittene Sicht. Die Deckenpoché im Grundriss — die Decke liegt
über der horizontalen Schnittebene, wird also frontal gesehen — nutzt
nun die Ansichtsschraffur (Default weiss/leer) statt pauschal keiner.
Schnitt-Pfade und die echt geschnittene Wand-Grundriss-Poché bleiben
auf der Schnittschraffur. Editierbar im Ressourcen-Manager.
2026-07-03 23:30:48 +02:00
karim 6085b46f21 Deckenpoché im Grundriss ohne Schraffur
Die Decke wird in der Aufsicht frontal gesehen, nicht aufgeschnitten
— Bauteil-Schraffuren gehoeren nur auf Schnittflaechen. Die neue
3-schichtige Betondecke zeigte sonst ihre dichte Schraffur ueber dem
ganzen Raum im Grundriss.
2026-07-03 23:11:42 +02:00
karim a96f619a16 Deckenstile: solide oder mehrschichtige Decke
Analog zu den Wandstilen erhalten Decken jetzt einen eigenen
Deckentyp mit Schichtaufbau (CeilingType, ceilingTypeId). Der
Schichtaufbau erscheint nur im Schnitt als gestapelte Bänder von OK
bis UK; der Grundriss bleibt eine flächige Poché wie bisher, da die
Schichtung von oben ohnehin nicht sichtbar ist. Auswahl solide/
mehrschichtig im Objektinfo-Panel wie bei Wänden, neuer
"Deckenstile"-Tab im Ressourcen-Manager mit Fugenlinien je Schicht.
2026-07-03 22:09:02 +02:00
karim a5976e3394 render3d: Wandverschneidung an Ecken + sichtbare Schichten
mesh.rs berechnet die Ecken-Verschneidung jetzt selbst (portiert aus dem
Web-Kern computeJoins/clippedBand): Wandenden werden per Rundungs-Key
gruppiert, ueber Hoehen-Ueberlappung geclustert (gestapelte Geschosse mit
gleichem Grundriss verschneiden sich NICHT), und Zweier-Cluster ueber die
gemeinsame Gehrungslinie geschnitten. T-/X-Stoesse und freie Enden bleiben
stumpf, wie im Web-Kern. Endkappen-Normalen geometrisch aus dem Kreuzprodukt.

WallInput bekommt optional layers (WallLayer{thickness,color}, serde-default,
rueckwaertskompatibel): jede Schicht wird als eigenes Band ueber dieselbe
gehrte Grundflaeche extrudiert und materialgefaerbt. toWalls3d.ts loest die
WallType-Schichten je Wand auf (hexToRgb) und reicht sie durch.

39/39 Rust-Tests (7 neue: Gehrung, T-Stoss, freies Ende, Schichten, Kombi).
2026-07-03 21:45:01 +02:00
karim 8c91118cab Raumstempel: Ausrichtung pro Zeile + Anker als Snappunkt
Jede Stempelzeile (Name, Name-2, Bodenflaeche, Nutzung) hat jetzt eine
eigene Ausrichtung links/mitte/rechts, im Stempel-Editor pro Zeile
waehlbar und in SVG- wie nativer Darstellung honoriert (text-anchor bzw.
align). Bodenflaeche/Nutzung fallen auf mitte zurueck (bisheriges Bild).

Der Stempel-Anker (stampAnchor bzw. Schwerpunkt) meldet sich zusaetzlich
als Endpunkt-Snapkandidat an — gefiltert nach Geschoss und sichtbarer
Kategorie; der ziehbare Griff war bereits verdrahtet.
2026-07-03 21:29:13 +02:00
karim f9f8162bb2 Raeume: Umriss auf die Wand-Innenflaeche + neutral statt farbig
- Sample-Raum R1: boundary auf die echte Innenkante der Aussenwaende
  (Achse +/- halbe Wanddicke 0.1725 bei Wandtyp aw 0.345 m) statt 0.1-Inset -
  der Umriss lag bisher ~7 cm im Wandkoerper.
- Raumfarbe #5a7a9a -> neutrales Grau #6b7280 (Umriss + Stempel).
- ROOM_FILL_ALPHA 33 -> 00: keine transluzente Farbfuellung mehr
  (Plandarstellung schwarz/grau); das Polygon bleibt fuer die Auswahl
  erhalten (Hit-Test laeuft ueber pointInPolygon, nicht ueber die Fuellung).

Offen: automatische Ableitung der Raum-Boundary aus den Wand-Innenflaechen
fuer spaeter gezeichnete Raeume.
2026-07-03 21:07:11 +02:00