Nutzer-Report: Textfelder waren nicht mehrzeilig. Ursache: die Text-/
Textspalte-Werkzeuge holten ihre Eingabe über die Befehlszeile
(CommandLine.tsx) — ein einzeiliges <input>, Enter committet sofort, kein
Zeilenumbruch möglich. Das betraf auch "Textspalte", obwohl die explizit für
mehrzeiligen Wortumbruch gedacht ist.
Lösung (Nutzer-Vorgabe: kein Dialog, direktes Editieren auf der Fläche wie
im Layout-System): text.ts/textbox.ts committen nach dem Platzieren (Anker
bzw. Anker+Breite) sofort ein LEERES Text-Element und melden
`focusDrawingId` — dafür CommandResult/EngineHost um einen Passthrough
erweitert (engine.ts applyResult ruft host.focusDrawing(id)). App.tsx setzt
darauf Auswahl + editTextId (dieselbe State-Variable wie beim bisherigen
Doppelklick-Editieren). PlanView rendert bei gesetztem editTextId jetzt
einen RichTextEditor-Overlay direkt über dem Element (position:fixed via
vbToClient/toScreen, eigene Mini-Toolbar erscheint darüber) statt des
bisherigen TextEditorDialog-Modals — Prinzip 1:1 vom Layout-Blatt-Inline-
Editor (LayoutSheet.tsx) übernommen. Die neuen Props (editTextId/
onCommitTextEdit/onCloseTextEdit) laufen durch Content/LevelPlanView/
SectionPlanView (viewportContent.tsx) bis zu PlanView durch.
Verhalten der beiden Werkzeuge (Nutzer-Vorgabe): "text" bleibt ohne
Wortumbruch (kein `width`) — Enter erzeugt weitere Zeilen, aber keine
automatische Breite. "textbox" setzt `width` und verhält sich damit wie ein
InDesign-Textrahmen (echter Wortumbruch live beim Tippen, kein reines
Render-Detail mehr).
commitTextEdit (useMouseSelectionHandlers.ts) schreibt jetzt bei JEDEM
Tastendruck (kein Guard mehr gegen leeren Text — nötig, damit Löschen bis
auf null Zeichen sich sofort spiegelt); neues closeTextEdit räumt ein beim
Schliessen noch leeres Element auf (verhindert Leichen bei abgebrochener
Neuerstellung).
4 neue Tests (text/textbox: sofortiger Commit + focusDrawingId). tsc -b /
vitest run (918/918) / npm run build grün. Rendering/Positionierung des
Overlays selbst nicht automatisiert testbar — Nutzer prüft visuell in der
Tauri-App.
Seit der Umstellung auf echte SVG-Kreis-/Bogen-Primitive (drawingCircle/
drawingArc statt 64-Ecken-Polygon-Annäherung) wurde die Interaktionsschicht
nie nachgezogen — betraf drei unabhängige Stellen mit derselben Ursache:
- Einzelklick: pickDrawing() testete nur kind==="line", fiel sonst auf
Text-/Bild-Bbox zurück. Neuer distToDrawingRing()-Zweig: Ring-Abstand in
Bildschirm-Pixeln (zoom-unabhängig wie die Linien-Toleranz), bei gefüllten
Kreisen zählt auch innerhalb als Treffer; Bögen zusätzlich auf ihre
Winkel-Spanne begrenzt. grabbedBody() (Körper-Verschieben) profitiert
automatisch mit, da es denselben Picker nutzt.
- Marquee (Rahmenauswahl): marqueeHitDrawings() sammelte nur line/polygon —
drawingCircle/drawingArc UND drawingText/drawingImage fehlten komplett
(Text/Bild waren nie per Rahmen erfassbar, unabhängig von der Kreis-Frage).
Kreis/Bogen werden für den Punkt-Test auf Ring-Stützpunkte abgetastet
(Bogen nur innerhalb seiner Winkel-Spanne, nicht als Vollkreis), Text/Bild
über ihre Bounding-Box.
- Griffe: drawingVertices() hatte keinen Fall für circle/arc → leeres Array,
selbst nach Fix von Klick+Marquee also unverschiebbar/nicht editierbar.
Kreis bekommt einen Radius-Griff (Ost), Bogen Start-/End-Winkel-Griffe plus
einen Radius-Griff auf halbem Bogen — moveGrip() entsprechend erweitert.
10 neue Tests (drawingVertices/moveGripOf für Kreis/Bogen, marqueeHitDrawings
für alle vier zuvor fehlenden Primitive-Arten). tsc -b / vitest run
(901/901) / npm run build grün. Der Einzelklick-Pfad selbst (PlanView.tsx-
Closures) ist nicht automatisiert testbar — visuell in der Tauri-App prüfen.
Übersetzt rohe Pick-/Marquee-/Kontextmenü-Events aus PlanView/Viewport3D in
Selektions-Mutationen (onPlanSelect/onPlanMarquee/onPlanContextMenu/
onViewportSelect{Wall,Stair,Ceiling,Opening}/onViewport3dPick/
onViewportContextMenu) + zwei eng verwandte Doppelklick-Trigger
(onOpenStampEditor, onEditDrawingText) + commitTextEdit. Reine Verschiebung,
keine Verhaltensänderung. Der useImageImportHandling()-Aufruf, der bisher
mitten in diesem Abschnitt sass (unabhängig vom Rest), ist dabei direkt hinter
den neuen Hook-Aufruf gerutscht statt mit extrahiert zu werden.
App.tsx: 3655 → 3278 Zeilen.
tsc -b sauber, vitest 891/891 grün, vite build ok.
Der ~990-zeilige Panel-Host-Vertrag (baseHost-useMemo: Projekt/Selektion/
Snap-/View-State + sämtliche Attribut-Setter/Ausschnitte/Layouts-CRUD, den
PanelHostContext für Docks/Floating-Panels konsumiert) war ein einzelner
riesiger useMemo-Objektliteral direkt in App.tsx. Wortgetreu verschoben (keine
Logik neu geschrieben), damit kein Verhalten unterwegs verändert wird — nur
die Objekt-Konstruktion selbst wandert in eine eigene Funktion.
Der Hook-Aufruf sitzt jetzt spät im Funktionskörper (nach useProjectActions/
useSelectionState/useDialogState/useContextMenuState, kurz vor den frühen
Boot-Returns), weil einige referenzierte Handler (openResources, activeLayout,
patchOpenLayout, openSettings, openLayerSettings, onOpenStampEditor) erst dort
definiert sind — dieselbe Art Vorwärtsreferenz-Falle wie beim vorigen
useGripEditing-Schritt, diesmal mit deutlich mehr betroffenen Namen.
Parameter-Vertrag bündelt wo möglich ganze Hook-Rückgabewerte (projectActions/
selectionState/toolState/topBarState/dialogState/contextMenuState als Pick<>
der jeweiligen Hook-Signatur) statt ~150 Einzelfelder aufzulisten — erhält
volle Typsicherheit ohne manuelles Retippen jedes Handler-Signatur.
App.tsx: 4594 → 3690 Zeilen.
tsc -b sauber, vitest 891/891 grün, vite build ok.
Eckpunkt-/Kanten-Griffe der aktuellen Auswahl (Wand/2D-Element/Decke/Raum/
Öffnung/Treppe), deren Zieh-Handler (Ortho/Snap/koinzidente Nachbar-Ecken)
sowie der Tab-Feld-Controller für präzise Länge/Winkel-Eingabe während eines
Vertex-Drags waren als drei separat benannte, aber tatsächlich zusammen-
hängende Abschnitte in App.tsx verstreut. Jetzt ein Hook mit explizitem
Parameter-Vertrag (Selektion/Projekt/Snap-Settings/Projekt-Mutationen rein,
grips/edgeGrips/gripHandlers/Feld-Controller raus) statt anonymer Closures
über den gesamten Komponenten-Scope.
Reine Verschiebung, keine Verhaltensänderung — einzige Korrektur beim
Verschieben: der Öffnungs-/Wand-Snap in onGripMove nutzte computeSnap direkt
(gegen ein um das gezogene Element bereinigtes Projekt), das im ersten Entwurf
versehentlich mit dem allgemeinen snapFor-Helper vertauscht worden wäre —
beim Nachvollziehen der Original-Logik korrigiert, bevor es committet wurde.
App.tsx: 5096 → 4594 Zeilen.
tsc -b sauber, vitest 891/891 grün, vite build ok.
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.
Zuletzt-geöffnet-Liste (state/recentProjects.ts) trägt sich beim Öffnen und
beim Speichern automatisch ein, inkl. Öffnen über einen bekannten Pfad ohne
Dialog (verwaiste Einträge fliegen raus, wenn die Datei fehlt). Der Splash
wartet bewusst nicht auf den Update-Check — der läuft unabhängig im
Hintergrund weiter, damit ein langsames Netz den Start nie verzögert.
Bündelt Projekt-Mutationen (Store-Actions), Wand-/Decken-/Dach-/Tür-/
Fenster-/Treppentyp-CRUD sowie diverse Element-Mutationsaktionen (Teil
der laufenden App.tsx-Verkleinerung).
Bündelt die Auswahl-Mengen aller Bauteil-/Zeichnungs-Arten (Wand, 2D-
Zeichnung, Decke, Dach, Öffnung, Treppe, Raum, Extrusion, Stütze,
Kontext-Objekt) plus abgeleitete Einzel-Ids, die 2D-Zwischenablage und
den 3D-Live-Schnitt-Treiber (Teil der laufenden App.tsx-Verkleinerung).
Bündelt aktives Werkzeug, Wandtyp/Linienstil, Snap-Einstellungen,
Werkzeug-Zustand-Ref, Draft-Vorschau, aktive Transformation
(Bewegen/Spiegeln/Drehen) und die Kopienanzahl für Array/Distribute
(Teil der laufenden App.tsx-Verkleinerung).
Reiner Umzug von neun useState-Deklarationen (Ressourcen-Fenster, Layout-
Ansicht, Import-/Export-/Einstellungs-Dialoge, Drop-Feedback) in einen
eigenen Hook — bewusst KEIN Store-Slice (dieser State ist laut den
Original-Kommentaren explizit lokal/transient, keine Undo/Redo- oder
Cross-Component-Relevanz). Verhaltensgleich.
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.
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.
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.
generatePlan zeichnet fuer jede Schnitt-/Ansichtsebene mit linePoints das
klassische Symbol: Strichpunkt-Linie, Endmarken + Richtungspfeile (directionSign),
Kurz-Label an beiden Enden und ein unsichtbares Pick-Band (Polygon mit
sectionLineId). PlanView pickt die Linie (hoechste Prioritaet) und hebt die
Auswahl hervor. Neuer Selektionskanal selectedSectionLineId (Einzel-DrawingLevel-
Id) in selectionSlice; onPlanSelect + alle Reset-Stellen in App gepflegt.
Primitive.sectionLineId, PlanSelection.sectionLineId, Tests.
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.
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.
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.
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.
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.
Gewählte Dächer bekommen im wgpu-Viewport Ziehgriffe wie Wände/Decken:
Eckpunkte (achsparalleles Resize, Gegenecke fix), Verschiebe-Griff im
Schwerpunkt und ein First-Griff am höchsten Dachpunkt — vertikales Ziehen
rechnet aus der neuen First-Höhe die Dachneigung (behält die Firstlage).
- projectSlice: moveRoofGrip/moveRoofBy (coalescing pro Dach)
- Wasm3DViewport: roofpitch-Griff (Render + vertikaler Drag auf Apex-Achse)
- App: edit3dRoofs + roofId-Routing in onEdit3dVertex/Body + onEdit3dRoofPitch
- Viewport3D: editRoofs/onEditRoofPitch durchgereicht
- Tests: roofGrips.test.ts (Resize/Verschieben/Coalescing)
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.
- 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.
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.
Selektierte 2D-Zeichnungselemente lassen sich jetzt in der Zeichen-
reihenfolge umsortieren — Kontextmenü „Ganz nach vorn / Nach vorn /
Nach hinten / Ganz nach hinten". Reine Array-Umsortierung in
project.drawings2d (spätere Position = optisch oben), Undo-fähig über
setProject. reorderDrawings(ids, front|forward|backward|back).
- Boden-Grid-Fläche auf y = baseElevation des aktiven Geschosses,
ein-/ausschaltbar (Overlay-Button im Viewport, State in viewSlice
grid3dVisible). Eigene LineList-Pipeline in der Engine (grid.rs,
GRID_WGSL, geteilte View-Projection/Depth mit der Mesh-Pipeline),
neue set_ground_grid(visible, elevation, extent, spacing)-Methode.
Minor-Linien dezent, jede 5. als Major betont.
- Kamera-Steuerung überarbeitet (vorher nur Mitte=Orbit, Pan auf
Shift+Mitte versteckt): Links=Orbit, Mitte/Rechts=Pan (bewegen),
Rad=Zoom zum Cursor. Laptop-freundlich, konsistent mit der
2D-Plan-Navigation (dort Mitte=Pan).
- 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).
setProject wird jetzt von einer History gewrappt (undoStack/redoStack,
Limit 100). Echte Aenderungen (Referenzvergleich) landen auf dem
Undo-Stack, eine neue Aktion leert den Redo-Stack. Hochfrequente
Drag-Mutatoren (Griffe/Body-Move) bekommen einen coalesceKey, damit
ein Drag nicht hunderte Einzelschritte erzeugt. Tastatur-Bindung
(Ctrl+Z/Ctrl+Shift+Z/Ctrl+Y) folgt im TopBar-Commit (App.tsx).
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.
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.
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).
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.
Bisher war viewType (Grundriss/Perspektive) ein einziger globaler
Wert. Beim Tab-Wechsel blieb er unverändert stehen, was wirkte, als
würde die Ansicht "durchsickern". Jede Ebene merkt sich jetzt ihren
zuletzt gewählten Ansichtstyp und stellt ihn beim Zurückwechseln
wieder her.
Neuer GPU-Renderer fuer den Grundriss (src/plan/glPlan/): Earcut-Tessellierung
(konkav-faehig), gehrte Linienzuege (Miter), echte Papier-mm-Strichbreiten im
Massstab (repliziert den SVG-printStrokeVb-Pfad), Hybrid mit scharfem SVG-Text-
Overlay. GPU ist der Standardpfad; der SVG-Renderer bleibt automatischer Fallback,
falls WebGL2/Shader nicht verfuegbar sind. Imperativer Pan (rAF + CSS-transform)
fuer fluessige Interaktion ohne React-Re-Render je Frame.
Enthaelt zudem den bisher nicht committeten Arbeitsstand des Browser-BIM
(Oeffnungen, Treppen, Raeume, Decken, DXF-Export, Materialbibliothek, Kontext-
Import, Tauri-Compute-Boundary-PoC).
Standalone-Browser-Port von DOSSIER. Enthaelt das semantische Modell mit
Plan-/3D-Ableitung, Zeichen- und Editierwerkzeuge, Rhino-artiges Befehlssystem,
dockbares Panel-System, Resource-Manager, DXF/.lin/.pat-Import, i18n (de/en)
sowie Projektdokumentation und Probe-Harness.