Commit Graph

52 Commits

Author SHA1 Message Date
karim 4f48b73267 2D: Multiline-Werkzeug (Basislinie + N-1 parallele Kopien in einer Geste)
Neuer Befehl multiline.ts, baut auf derselben Offset-Geometrie auf wie der
bestehende offset-Befehl (offsetSegment) — erzeugt aber alle Kopien auf
einmal statt einzeln nacheinander offsetten zu müssen. Deckt gerade
Basislinien ab (häufigster Fall: Grenzlinie+Abstand, Leitungspaar,
Randlinien), keine mehrsegmentige Variante.

Ablauf: Start-/Endpunkt (Tab-Felder Länge/Winkel wie line.ts), dann Abstand
per Maus-Klick (Seite bestimmt Vorzeichen, wie bei offset.ts) oder getippt;
die Anzahl (Default 3, Bereich 2-6) zyklt über eine Inline-Option und bleibt
wie Abstand/Seite über Aufrufe hinweg persistent.

In Registry/Aliase (ml/parallel), ToolsPanel (COMMANDS_EDIT neben Offset),
CommandIcon, i18n de/en aufgenommen.

2 neue Tests. tsc -b / vitest run (916/916) / npm run build grün.
2026-08-20 21:07:21 +02:00
karim 245b7d7fe1 2D: Chamfer (Eckpunkt-Fasung) neu gebaut und verdrahtet
Anders als Fillet/Extend existierte hierfür noch gar keine Geometrie —
chamferCorner (src/geometry/kernel2d.ts) ist neu: gleicher Abstand vom Eck
auf beiden Schenkeln, gerade verbunden (klassischer Gleichabstands-Chamfer,
analog zu filletCorner, nur ohne Bogen — daher exakt statt tesselliert).

commands/cmds/chamfer.ts wortwörtlich nach dem fillet.ts-Muster: Ecke wählen,
Distanz per Maus oder getippt (Tab-Feld). In Registry/Aliase
(ch/fasen), ToolsPanel (COMMANDS_EDIT neben Fillet), CommandIcon, i18n
de/en aufgenommen.

3 neue Tests (Fasung, Fehltreffer, Distanz-zu-gross-No-op). tsc -b /
vitest run (914/914) / npm run build grün.
2026-08-20 21:01:15 +02:00
karim 51e594ee90 2D: Fillet und Extend als Befehle verdrahtet (Geometrie existierte bereits)
filletCorner (Eckpunkt-Verrundung) und extendSegment (Gegenstück zu Trim)
existierten fertig implementiert und getestet im Kernel (kernel2d.ts), hatten
aber keinen einzigen Aufrufer — kein Command, kein Werkzeug-Knopf, für den
Nutzer nicht erreichbar. Reine Verdrahtungsarbeit, kein neues Geometrie-
Problem:

- fillet.ts: Ecke einer polyline/rect wählen (nächstgelegener Eckpunkt mit
  zwei Nachbarn), Radius per Maus oder getippt (Tab-Feld wie bei circle.ts).
  Da Polylinien im Modell keine Bogen-Segmente kennen (kein "Bulge" —
  bekannte, separate Lücke), wird die Verrundung als kurze Punktfolge
  tessselliert statt als echtes Arc-Objekt gespeichert; ein rect wird beim
  ersten Fillet zu einer polyline. Ehrlich im Kopfkommentar dokumentiert.
- extend.ts: offene Kurve (line/offene polyline) nahe einem Ende anklicken,
  dieses Ende wird bis zur nächsten anderen Kurve verlängert (implizite
  Cutter wie bei Trim). Kein Treffer → No-op, Befehl bleibt aktiv.

Beide in COMMANDS/ALIASES registriert (fi/verrunden, ext/verlaengern),
i18n de/en ergänzt, in ToolsPanel COMMANDS_EDIT neben Trim/Join aufgenommen,
eigene Icons in CommandIcon.tsx (bisher: unbekannter Name → kein Icon).

Rotate NICHT angefasst: der ursprüngliche Befund „Rotate ist keine getippte
Kommandozeilen-Aktion, nur ein UI-Button" war unvollständig — App.tsx routet
sowohl den Ribbon-Button als auch das getippte Wort „rotate"/„drehen" ganz
bewusst an startTransformOp() (den reicheren U/I/O/P-Move/Copy/Array/
Verteilen-Fluss), nicht an die generische Befehls-Engine (Kommentar dort
erklärt das explizit). Ein zuerst geschriebener, einfacher rotateCommand
(nur „move"-Modus) wäre über diese Sonderfälle nie erreicht worden UND hätte
über neue Aliase wie „ro" einen inkonsistenten Zweit-Pfad geöffnet (voller
Funktionsumfang bei „rotate", abgespeckter bei „ro") — verworfen, bevor
committet.

6 neue Tests (fillet: Verrundung + Fehltreffer; extend: Verlängerung +
Kein-Cutter-No-op). tsc -b / vitest run (911/911) / npm run build grün.
2026-08-20 20:53:31 +02:00
karim bdbd87bf85 Zweite Leichen-Runde: weitere tote Exporte + orphaned ribbonItems.ts entfernt
ts-prune nach dem ersten Durchgang erneut laufen lassen. compute/index.ts
(101 Z., PoC-Brücke zu einem nie gebauten Rust-Command, im eigenen
Kopfkommentar schon als ungenutzt markiert) komplett gelöscht. ribbonItems.ts
war nur noch für das bereits gelöschte RibbonBar.tsx da (kein anderer
Importeur mehr) — ebenfalls komplett weg.

Einzelne tote Typen/Konstanten: SiaLabel (roomArea.ts), GeoImportResult
(geoContext.ts, plus den dadurch verwaisten GeoOrigin-Import), die drei
MATERIAL_LIBRARY_*-Konstanten (library.ts), ResolveContext-Re-Export
(parametricWalls.ts), roofTotalThickness (types.ts — Duplikat, die echte
Rechnung läuft in toWalls3d/bands.ts inline), DropTarget (panelDrag.tsx).

resolveBackground (generatePlan/shared.ts) bewusst NICHT gelöscht: anders als
das analoge resolveForeground wird es nirgends aufgerufen, obwohl
backgroundSource für Wand/Decke im Modell und im Attribut-Panel existiert —
sieht nach einer echten Lücke aus (By-Layer-Hintergrundfarbe kommt nie im
Renderer an), nicht nach totem Code.

tsc -b / vitest run (891/891) / npm run build grün.
2026-08-20 20:01:26 +02:00
karim 003fde4320 Leichen-Suche: tote Dateien/Funktionen entfernt, revokeMaterial-Bug behoben
ts-prune + cargo check über alle Crates durchsucht, jeder Fund per grep
gegengeprüft. Gelöscht: ResourcesPanel.tsx (abgelöstes Alt-Panel),
RibbonBar.tsx (Ribbon-Phase-1-Überbleibsel), sowie diverse Funktionen ohne
jeden Aufrufer (sampleTerrainColors, docToSvgText/tspanToSvg,
isEmpty/deserialize/fromJson, findAccentSwatch, unregisterPanel,
removeFromDockLayout, TOOL_ORDER).

revokeMaterial (materials/ambientcg.ts) existierte, wurde aber nie
aufgerufen — jeder Material-Wechsel/-Upload liess Blob-URLs leaken. Jetzt
über revokeMaterialUrls() in ComponentsTab.tsx beim Ersetzen/Löschen/
Bauteil-Löschen verdrahtet.

tsc -b / vitest run (891/891) / npm run build grün.
2026-08-20 19:51:52 +02:00
karim 1507c2bf00 God-Files aufgeteilt (ResourceManager/generatePlan/toWalls3d/App.tsx-Handler), Totcode entfernt (geometry-Crate, OCCT/HLR-Spike), PDF/Bild-Import ergänzt.
ResourceManager.tsx, generatePlan.ts und toWalls3d.ts sind nach Bauteil-
Domäne in src/ui/resourceManager/, src/plan/generatePlan/ und
src/plan/toWalls3d/ aufgeteilt (reine Verschiebung, keine Verhaltens-
änderung). App.tsx verliert weitere Handler-Gruppen an eigene Hooks
(useExportHandlers, useImportHandling, useKeyboardShortcuts) sowie
Hit-Testing an src/viewport/planHitTest.ts.

Unbenutzte Rust-geometry-Crate (durch WASM-Joins abgelöst) sowie der alte
OCCT/HLR-Schnitt-Spike (hlr.ts/occt.ts, vite occt-Aliases) entfernt.

Neu: PDF-Import als Rasterbild (src/io/pdfImport.ts) + gemeinsamer
Bild-Asset-Helfer (src/io/imageAsset.ts) für Plan- und Layout-Bilder.

tsc -b sauber, vitest 891/891 grün.
2026-08-19 22:45:41 +02:00
karim 3b8d48eaf5 Zahnrad-Icons in Zeichnungsebenen/Ebenen öffnen jetzt die passenden Fenster
Bisher öffneten beide Panel-Kopfzeilen die allgemeinen Einstellungen statt
ihrer eigenen: Zeichnungsebenen jetzt den Zeichnungsebenen-Fenster-Manager,
Ebenen die Ebeneneinstellungen der aktiven Kategorie.
2026-07-21 19:51:03 +02:00
karim b9e330ecb7 Schnittebenen 2D↔3D Phase 1+2, native Fenster, Hell/Dunkel-Theme, SWISSIMAGE-Import
- Schnittebenen: 3D-Live-Schnitt folgt der gewählten Grundriss-Schnittlinie
  (section3dCutId/sectionPlaneFromLevel), Schalter "Im 3D schneiden" im
  Objekt-Info, Doppelklick auf Schnittlinie springt in 2D-Schnittansicht,
  unsichtbare Ebenen blenden ihre Führungslinie aus
- Eigene native Tauri-Fenster für Kontext-Import/Zeichnungsebenen/
  Ebenen-Einstellungen/Ressourcen/Einstellungen + klassische Menüleiste
  (AppMenuBar) neben der Wortmarke
- Hell/Dunkel-Umschalter (Einstellungen → Darstellung), persistiert,
  flackerfrei vor erstem Render gesetzt
- SWISSIMAGE-Luftbild-Import (swisstopo WMS) als Kontext-Hintergrundebene
- UI-Politur: Werkzeug-Panel Symbole/Liste umschaltbar, Topbar-Quick-Access-
  Icons entfernt, Zahnrad→Einstellungen in Panel-Köpfen, Footerbar/
  Snap-Marker/Maß-HUD auf helle Pillen-Sprache umgestellt
- Neues Dachziegel-Material (RoofingTiles013A)
2026-07-20 10:51:37 +02:00
karim da0f066e49 Fenster: Rahmen-Kontur in Aufsicht separat von den geschnittenen Laibungsblöcken stylebar
Bisher teilten sich die geschnittenen Laibungs-/Stulp-Blöcke (O-Blöcke,
Schnittfläche des Rahmenmaterials) und die durchlaufende Rahmen-Kontur
zwischen ihnen (Aufsicht, nicht geschnitten) dieselbe frameLine-Farbe. Neues
Opening.frameViewLine übersteuert nur noch die Kontur; ohne Angabe fällt sie
weiterhin auf frameLine zurück (bisheriges Verhalten unverändert). frameLine
im UI zu "Rahmen (Schnitt)" umbenannt, um die beiden Kategorien zu unterscheiden.
2026-07-12 20:19:20 +02:00
karim 5be49c5557 Neuer Bezugspunkt: Projekt nach Kataster-/3D-Import auf praktischen Ursprung verschieben
Nach einem Standort-Import landet die Kontext-Geometrie dort, wo der gesuchte
Ort war — das kann weit vom bisherigen Modell-Ursprung liegen. Neuer Befehl
"georef" (Button in SitePanel) verschiebt das GESAMTE Projekt per Klick so,
dass der gewählte Punkt zum neuen Ursprung wird; geoAnchor wandert automatisch
mit, der reale LV95-Bezug bleibt exakt erhalten (rekonstruierbar, auch beim
späteren Export). Bewusst nur Translation, keine Rotation — mehrere Felder
(Roof.ridgeAxis, Column.rotation, Text-/Bild-Rotation) sind achsen-/winkel-
gebunden und bräuchten bei einer Drehung eigene Sorgfalt.
2026-07-12 20:13:22 +02:00
karim 0ab3f70277 Kontext-Objekte im 3D-Viewport anwählbar (Klick, Bounding-Box-Highlight, Löschen)
Importierte Gebäude/Terrain-Meshes waren bisher nur ein Eintrag im Geo-Panel,
nicht direkt im 3D anwählbar. Raycast/Pick-Geometrie um Kontext-Meshes
erweitert, Auswahl-Kanal (selectedContextObjectIds) ergänzt, Highlight als
Bounding-Box-Umriss (volles Dreiecks-Wireframe wäre bei grossen Importen zu
dicht), Entf-Taste löscht die Auswahl, SitePanel hebt sie in der Liste hervor.
2026-07-12 19:54:00 +02:00
karim 02c36bd35b Georeferenzierung: persistenter Standort-Bezug statt Neuberechnung je Import
Neues Project.geoAnchor: verbindet EINEN Modell-Punkt mit seiner realen
LV95-Koordinate. Bisher berechnete jeder Standort-Import (Gebäude/Terrain/
OSM) unabhängig einen neuen Bezug aus der jeweils gesuchten Adresse — bei
mehreren Importen mit leicht unterschiedlichen Suchbegriffen landete
importierter Kontext lagefalsch zueinander.

Der erste Import in einem Projekt setzt den Bezug automatisch (Modell-(0,0)
= gesuchter Ort) und speichert ihn; alle weiteren Importe verwenden densel-
ben Bezug, unabhängig vom neu gesuchten Ort (der bestimmt nur noch WOVON
Daten geladen werden, nicht mehr WOHIN sie im Modell platziert werden).
UI: Anzeige des aktiven Bezugs im Import-Dialog mit Zurücksetzen-Option.

Löst das strukturelle Problem noch nicht vollständig (der Bezug sitzt immer
bei Modell-(0,0) — passt nur, wenn das eigene Gebäude dort gezeichnet ist),
aber behebt die akute Inkonsistenz zwischen mehreren Importen.
2026-07-12 19:33:16 +02:00
karim 269aef80e2 Fenster: Farbe/Strichstärke je Linien-Kategorie im Attribute-Panel einstellbar
Neue per-Öffnung-Übersteuerung (Opening.frameLine/sashLine/sillLineStyle,
je {color?, weight?}) für Blendrahmen+Stulp-/Laibungsblöcke, Flügelrahmen/
Sprossen und die Auf-/Untersicht-Sims-Andeutung separat. Fehlt eine
Übersteuerung, gilt weiterhin der bisherige Default (Opening.color/Haarlinie).
UI: drei neue Zeilen (Farbfeld + Strichstärke) im Objekt-Info-Panel bei
selektiertem Fenster.
2026-07-12 18:45:28 +02:00
karim b9a7451eb2 Schnitt/Ansicht-Feinschliff: Kantenfilter, Print-Toggle, echte Fenster in der Ansicht
Vier Nutzer-Punkte:
1. Editieren im Schnitt funktioniert (Klick auf die Poché wählt das Bauteil,
   headless verifiziert) — die Störung waren die Kanten GESCHNITTENER
   Bauteile: der Extraktor projizierte auch deren Restkörper (Deckel-/
   Bodenkanten quer durch die eigene Poché). computeSection filtert sie jetzt;
   Ansichtskanten ungeschnittener Bauteile (Rückwand-Fenster etc.) bleiben.
2. Verdeckte Kanten (gestrichelt) sind Standard AUS — zuschaltbar je Ebene
   (DrawingLevel.hiddenLines, Checkbox in der Schnittlinien-Sektion).
3. Display/Print-Umschalter wirkt jetzt in ALLEN 2D-Darstellungen (Grundriss,
   Schnitt, Ansicht, Zeichnung) — war fälschlich auf den Grundriss begrenzt.
4. Fenster/Türen in der Ansicht als echtes Bauteil: Blendrahmen-Fläche →
   Flügelfelder (aus der Flügeltabelle, ungleiche Breiten/Pfosten) → Glas,
   Kämpfer/Oberlicht-Teilung, DIN-Öffnungssymbol (dezent gestrichelt,
   Dreh/Kipp/Drehkipp je Anschlag); Türen mit Rahmen + Blatt-Fläche.
737/737 grün; headless verifiziert (Schnitt A + Ansicht Süd).
2026-07-11 02:18:09 +02:00
karim 522727a003 Schnittlinie editierbar: Objektinfo-Sektion + Entf-Taste
Gewaehlte Schnitt-/Ansichtslinie erscheint als SectionLineSection im Attribut-
Panel (ueber host.sectionLine, da eine Linie kein Projekt-Bauteil ist): Name,
Blickrichtung umkehren (directionSign-Flip), Endpunkt-Koordinaten und Schnitt-
Tiefe editierbar; Loeschen/Entf setzt linePoints zurueck (Ebene bleibt). Host-
Kontrakt um sectionLine/onSetSectionLinePatch/onDeleteSectionLine erweitert,
verdrahtet ueber patchLevel. i18n de/en.
2026-07-11 00:26:49 +02:00
karim 1df58a3c47 Decken-Panel: Aussparungen anzeigen + einzeln entfernen
Die Decken-Sektion listet die Aussparungen (BBox-Masse je Loch) mit
Entfernen-Knopf; Anlegen über den Befehl 'Deckenloch'. CeilingInfo.openings,
host.onRemoveCeilingOpening + App-Routing. 684/684 grün.
2026-07-10 18:44:13 +02:00
karim 1bba149f72 Ressourcen: Dachtypen-Tab (Schicht-Editor wie Wand/Decke)
Dachaufbauten sind jetzt im Ressourcen-Manager anleg-/editier-/löschbar
(RoofStylesTab auf dem LayeredStylesTab-Rumpf, Ressource roofTypes):
Schichtliste mit Bauteil/Dicke/Fugen-Linienstil, Löschen geschützt solange
ein Dach den Typ referenziert. Host-/App-Handler (patch/add/deleteRoofType)
+ i18n de/en. Vervollständigt die Dach-Schichtlogik (e28b7fd) um die UI.
2026-07-10 18:35:34 +02:00
karim 5e10024385 Objektinfo: Klasse (Kategorie) + Zeichnungsebene editierbar im Kopf
VW-Muster ('Klasse'/'Ebene'): der Objektinfo-Kopf zeigt statt des read-only
Kategorie-Codes zwei Dropdowns — Grafik-Kategorie und Zeichnungsebene
(Geschoss), beide direkt änderbar. Wirkt auf Wand/Decke/Dach/Treppe/Raum/
2D-Zeichnung/Stütze/Extrusion; Öffnungen ohne Ebenen-Dropdown (Ebene kommt
aus der Wirts-Wand), Extrusionen ohne Kategorie (kein categoryCode am Element).

- Selection.floorId (alle Builder), host.onSetSelectionCategory/-Level,
  App-Routing je Elementart (Store-Actions bzw. setProject für Stütze/Extrusion)
- 2D-Zeichnungen auf Nicht-Geschoss-Ebenen behalten ihre Ebene in der Liste
673/673 grün.
2026-07-10 18:31:11 +02:00
karim cc398b7e7a Dach: getrennter Überstand Traufe/Ortgang (statt ringsum)
Bisher ein einziger overhang ringsum (Designdoc-Prio #2). Neu Roof.overhangGable
für den Ortgang (Giebelseite, entlang First); overhang gilt für die Traufe
(senkrecht zum First). Fehlt overhangGable, gilt ringsum overhang (rückwärts-
kompatibel). Geometrie mappt die Überstände je nach ridgeAxis auf die Outline-
Achsen. Panel: zweites Feld 'Überstand Ortgang' (ausser flach/zelt). +3 Tests.
672/672 grün.
2026-07-10 02:10:03 +02:00
karim e28b7fd980 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 c6a2924e98 Dach: Mansarden-Untertypen (Giebel/Walm/Zelt) + parametrierbarer Knick
Bisher gab es nur die Giebel-Mansarde (2-seitig). Neu über Roof.mansardType:
- 'giebel' (Default): Mansard-Satteldach, Giebel an den Enden (wie bisher)
- 'walm': allseitige Mansarde (Sockel + oberer Walm, kein Giebel) — 8 Flächen
- 'zelt': allseitige Mansarde zur flachen Spitze — 8 Flächen, kein First
Knicklage jetzt parametrierbar (Roof.mansardKneeRatio, Default 0.4 der halben
Spannweite). Dach-Panel: Mansard-Art-Dropdown + Knicklage-Feld (nur bei Mansarde).
+4 Geometrie-Tests (Ratio, Walm-/Zelt-Flächen/Grate).

Nebenbei: Fenster-Dialog-Labels klarer als 'Einbaulage ab / Abstand von Kante'
(Nutzer: wo sitzt das Fenster in der Aussparung, ab Innen-/Aussenkante + wieviel).
666/666 grün.
2026-07-10 01:53:55 +02:00
karim 01e5ffee48 Fenster-/Tür-Einstellungsdialog: reicher Editor mit Live-Ansicht + Stil speichern
Das ⚙ der Öffnungs-Sektion öffnet neu einen dedizierten Dialog (VW-Studie §3)
statt in den Ressourcen-Tab zu springen. Drei Zonen: Kategorie-Sidebar,
Parameter-Panel, Live-2D-Frontalansicht (aus den aktuellen Werten gezeichnet:
Rahmen/Flügel/Öffnungslinien/Verglasung/Rollladenkasten).

- OpeningEditorDialog.tsx: Kategorien Basis/Grösse/Rahmen/Flügel/Sonnenschutz
  (Fenster) bzw. Türblatt (Tür); Flügeltabelle (Flügel/Pfosten + Öffnungsart +
  Anschlag je Zeile); Stil-Leiste mit Stilwahl + 'Als Stil speichern …'
- App: openingEditorId-State, Dialog-Render, saveOpeningStyle (klont aktuellen
  Typ als neuen benannten WindowType/DoorType und weist ihn zu)
- host.onOpenOpeningEditor + OpeningInfo.id für den ⚙-Sprung
- Studie docs/design/window-editor-vectorworks-study.md
- Dialog-CSS (.oed-*) + i18n (de/en)

Renderer-Konsum der neuen Felder (sashes/glazingPanes/shading in 2D/3D) folgt separat.
2026-07-10 01:13:15 +02:00
karim 8c08299e6b Dach: Grundriss-Masse (Breite/Tiefe) im Panel editierbar
Bisher liess sich der Dach-Grundriss nach dem Platzieren nicht mehr in der
Grösse ändern. RoofSection bekommt Breite/Tiefe-Felder, die das Umriss-
Rechteck neu bilden (untere/linke Ecke bleibt fix). RoofInfo trägt
width/depth/minX/minY. tsc + vitest grün.
2026-07-10 00:37:32 +02:00
karim ce154ec249 Dach: Traufhöhe editierbar + Abwählen an allen Reset-Stellen
- RoofSection bekommt ein Traufhöhe-Feld (Roof.baseElevation, absolutes Z) —
  z. B. um das Dach für einen Kniestock über die Geschoss-Oberkante zu heben.
  RoofInfo.baseElevation trägt den aufgelösten Wert (Override oder Default).
- Dach-Auswahl wird jetzt an ALLEN Selektions-Reset-Stellen mitgeleert
  (Kontextmenü-/Ebenen-Operationen), nicht nur bei Klick/Geschosswechsel/
  Marquee/Delete — kein Geister-Dach mehr in der Auswahl.
tsc + vitest grün.
2026-07-10 00:30:21 +02:00
karim db1d9916ed Dächer anwählbar + editierbar + löschbar
Platzierte Dächer sind jetzt vollwertige Auswahl-Elemente (analog Decke):
- 2D-Auswahl per Klick: unsichtbares Traufe-Pick-Polygon (roofId) +
  pickRoof (Punkt-in-Polygon, niedrigste Priorität) in PlanView.
- Auswahl-Kanal selectedRoofIds (selectionSlice), updateRoof (projectSlice),
  RoofInfo + roofSelection + deriveSelection-Dispatch (selectionInfo).
- Attribut-Panel „Dach": Form (Sattel/Walm/Pult/Mansarde/Zelt/Flach),
  Firstrichtung X/Y, Neigung(en), Überstand, Dachdicke — live editierbar über
  host.onSetRoofPatch; dazu abgeleitete Firsthöhe + Grundfläche (read-only).
- Löschen (Delete) + Abwählen bei Geschosswechsel/Marquee/anderer Auswahl.
+2 Tests (Roof-Selection). tsc + vitest 642 + vite build grün.
2026-07-09 22:18:59 +02:00
karim 62c8a39a8e 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 8f63952cc0 Öffnung: ⚙-Knopf springt in den Tür-/Fenstertyp-Editor
Discoverability für die vertieften Bauteil-Typen: neben dem Typ-Dropdown
einer gewählten Öffnung öffnet ein ⚙-Knopf das Ressourcen-Fenster direkt
beim passenden Typeditor-Tab (Tür→doorStyles, Fenster→windowStyles).
- ResourceManager: initialTab-Prop (springt auch bei bereits offenem
  Fenster auf den angeforderten Tab).
- host.onEditOpeningType(kind) + App-Wiring (resourcesTab-State).
tsc + vitest 620 grün.
2026-07-09 01:44:13 +02:00
karim 98e38ee1e3 Schichttrennlinie als Wand-Referenzlinie (mehrschichtige Wände)
Bei mehrschichtigen Wänden lässt sich neben Aussen/Mitte/Innen jetzt auch
eine SCHICHTTRENNLINIE (Fuge zwischen zwei Schichten) als Referenzlinie
wählen — z. B. die Achse auf die Innenkante der Aussenschale legen.
- Neues Feld Wall.referenceOffset (freier Achsversatz entlang +n); wenn
  gesetzt, übersteuert es referenceLine. wallReferenceOffset bleibt die
  EINE Quelle → Grundriss, Schnitt und 3D erben das Verhalten automatisch.
- Object-Info-Panel: das Referenzlinien-Dropdown listet zusätzlich je
  interne Fuge einen Eintrag (Kürzel der angrenzenden Schichten); Auswahl
  setzt den Versatz, Aussen/Mitte/Innen löscht ihn wieder.
- selectionInfo berechnet die Fugen-Versätze (kumulierte Schichtdicken).
+3 Tests. tsc + vitest grün.
2026-07-09 01:21:28 +02:00
karim 6b9c243431 Mess-Werkzeug: Polygonzug mit Fläche + Live-Werte im Objekt-Info-Panel
Das Mess-Werkzeug wird von der reinen Strecke zum Polygonzug:
- Jeder Klick setzt einen weiteren Stützpunkt; angezeigt werden letztes
  Segment (Länge · Winkel), aufsummierte Pfadlänge und — ab 3 Ecken —
  die umschlossene Fläche (Gauss).
- Die Messwerte erscheinen dauerhaft im Objekt-Info-Panel (neuer
  Abschnitt „Messung"), nicht nur flüchtig am Cursor-HUD. Kanal:
  ToolDraft.measure → PanelHost.measurement → ObjectInfoPanel.
- Rechtsklick/Enter beendet den aktuellen Pfad und armiert sofort einen
  neuen (mehrere Messungen nacheinander); Rechtsklick auf leerem Pfad
  bzw. Esc beendet das Werkzeug.

+4 Tests (Segment/Winkel, Summe/Fläche, Ketten-Verhalten). tsc sauber.
2026-07-09 01:13:15 +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 9b33a89318 Wandtyp-Kürzel: Component.abbrev + wallTypeLabel() + Kürzel-Feld im ResourceManager; Geschoss-Dropdown schmal 2026-07-05 23:16:38 +02:00
karim ed27509881 ObjectInfo→Attribute: element-spezifische Abschnitte (Wand/Decke/Öffnung/Treppe/Raum) ins Attribute-Panel; ObjectInfo nur noch Bezugspunkt + Masse 2026-07-05 21:50:03 +02:00
karim da127f03a5 Ribbon Phase 3: Werkzeug-Sidebar aus Default-Layout, Wandtyp-Picker ins Attribute-Panel, Attribute volle Höhe (LAYOUT_VERSION 8) 2026-07-05 20:50:05 +02:00
karim 10a27e2eb7 Ribbon-UI Phase 1: datengetriebene Tab-Leiste (2D/3D/BIM/Ansichten), additiv unter TopBar 2026-07-05 17:00:09 +02:00
karim 64766ed1fe Attribute-Panel: ein durchgehendes Grid, volle Breite, doppelten Titel raus 2026-07-05 16:54:04 +02:00
karim 0d756db68f Werkzeuge: Bogen-Werkzeug (arcCommand, 3-Klick CCW) + Toolbar/Icon/i18n verdrahtet 2026-07-05 15:44:05 +02:00
karim 17f435010c Werkzeuge: Kreis-Toolbar verdrahtet (circleCommand gekoppelt, Icon, i18n) 2026-07-05 15:24:45 +02:00
karim 0e93c31e5a 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 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 3e9491cddf Farbfelder: Hex-Code separat editierbar, Swatch öffnet die Palette
ColorHexField (neu, geteilt) trennt die zwei Klickziele: Swatch/
natives Farb-Input öffnet weiter den Picker, der Hex-Text daneben ist
jetzt ein eigenes Eingabefeld (Enter übernimmt, Esc verwirft, ungültige
Eingabe fällt auf den letzten gültigen Wert zurück). Ersetzt die
bisherige reine Text-Anzeige in SettingsDialog + AttributesPanel.
2026-07-04 05:15:42 +02:00
karim a35a4fcdff Native Selects auf einheitliche Dropdown-Komponente umgestellt
Mehrere Stellen (ResourceManager SelectField + Material-Browser,
ImportDialog, AttributesPanel, SitePanel, ToolsPanel,
DisplayModeSelect, RichTextEditor) nutzten noch native <select>, deren
Optionsliste vom Betriebssystem gerendert wird und optisch nicht zur
eigenen Dropdown-Komponente (dunkles Kontextmenü-Popover) passt. Jetzt
durchgaengig dieselbe Optik.
2026-07-04 05:01:03 +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 ce235d6bc2 ResourceManager: Wandstile + Deckenstile im Master-Detail-Layout
Wand- und Deckenstile bekommen dasselbe Master-Detail wie Schraffuren/Linien:
Liste links mit Querschnitt-Thumbnail + Name, Detail rechts mit grossem
Querschnitt und Aufbau-Editor (Schichten: Bauteil/Dicke/Fugenlinie,
hinzufuegen/entfernen/umordnen), Inline-Rename, Trash-Delete, Neu anlegen.
Neuer WallTypeSwatch (hatchPreview) zeichnet die geschichtete Wand/Decke als
proportionale Baender mit den Bauteil-Schnittschraffuren. Add/Delete-Handler
(addWallType/deleteWallType/addCeilingType/deleteCeilingType, In-Use-Schutz)
in App.tsx + host ergaenzt.
2026-07-04 01:53:52 +02:00
karim da48b5fa13 Attribut-Panel: Vordergrund/Hintergrund mit 'Nach System'
Die Attribut-Sektion 'Fuellung' zeigt statt der einen Fuellfarbe jetzt zwei
Felder: Vordergrund (Muster-/Schraffurfarbe) und Hintergrund (Fuellung),
jeweils per Element ueberschreibbar. Leerer Override = 'Nach System' (erbt);
Farbe waehlen setzt den Override, x loescht ihn wieder. Schreibt
Wall/Ceiling/Drawing2D.foreground/background ueber neue Store-Mutationen
(setElementForeground/Background), gespiegelt zum bestehenden Fuellfarbe-Pfad.
Die Resolve-Schicht (generatePlan) liest diese Overrides bereits, wirkt also
sofort im Plan.
2026-07-04 00:26:32 +02:00
karim 6ea15f56ca Dockbare Panel-Tabs nur als Symbol
Die Tab-Leiste zeigt je Panel nur noch ein Inline-SVG-Icon; der Titel
wandert in Tooltip (title) und aria-label. PanelDef bekommt ein optionales
icon-Feld, die sieben eingebauten Panels je ein schlichtes stroke-Icon
(currentColor, erbt die Tab-Farbe). Fehlt ein Icon (Plugin), fällt der Tab
auf den Titeltext zurück. Tabs sind jetzt kompakt und quadratisch; Klick-,
Drag- und Dock-Logik unverändert.
2026-07-03 23:42:39 +02:00
karim 5dd9fb4308 Zeichnungsebenen-Panel: vier einklappbare Kategorien
Die flache Ebenenliste ist in vier einklappbare Kategorien gegliedert —
Geschosse/Schnitte/Ansichten/2D-Zeichnungen nach drawingLevel.kind. Jeder
Kopf trägt ein Chevron und rechtsbündig ein blankes +-Glyph (kein
Button-Chrome), das je Kategorie eine neue Ebene der passenden Art anlegt;
leere Kategorien bleiben mit Kopf und + sichtbar. Für Schnitt und Ansicht
sind dafür neue Platzhalter-Aktionen addSection/addElevation ergänzt
(analog addFloor/addDrawing, noch ohne Schnittlinie).
2026-07-03 23:31:39 +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 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 fa10687739 Wandstile: Schichtfuge pro Fuge als LineStyle waehlbar + ResourceManager-Abteilung
Mehrschichtige Waende zeichnen die Trennlinie an jeder Materialfuge jetzt mit
einem pro Fuge waehlbaren LineStyle statt einer festen Haarlinie.

- Layer.jointLineStyleId (optional): LineStyle der Fuge an der Innenkante
  dieser Schicht; fehlt er, gilt die Default-Haarlinie (0.02) in Wandfarbe.
- generatePlan: Schicht-Baender tragen nur noch Fuellung + Schraffur (kein
  Band-Umriss); jede innere Fuge wird als eigene Linie mit ihrem LineStyle
  (Gewicht/Farbe/Dash, x Detailfaktor) gezeichnet. Wand-Umriss (0.35) und
  grob-Pfad unveraendert.
- ResourceManager: neue Abteilung "Wandstile" - je Wandtyp die Schichten
  mit Fugen-LineStyle-Dropdown.
- Sample: LineStyle "Schichtfuge 0.13"; der Daemmung-Backstein-Fuge (massiv/
  massiv) zugewiesen, Putzfugen bleiben Haarlinie.
- 2 Joint-Tests ergaenzt.
2026-07-03 20:55:07 +02:00
karim 5fe7221f6c Fang-Optionen und Display/Print-Umschalter in die Footerbar
Der Linien-Modus (Display/Print) wandert aus der Oberleiste und die
Fang-Optionen aus der Werkzeug-Palette in die Statusleiste unten:

- StatusBar: segmentierter Display/Print-Umschalter (Stil wie der
  Renderer-Umschalter) plus Fang-Pill mit nach oben öffnendem Popover
  (Master-Schalter + Endpunkt/Mittelpunkt/Schnittpunkt/Kante/Raster/
  Ortho + Rastermass).
- TopBar: Linien-Modus-Gruppe entfernt.
- ToolsPanel: Fang-Abschnitt entfernt.
- App reicht lineMode/snap an die StatusBar durch.
2026-07-03 20:08:03 +02:00