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.
"dossier" statt "Dossier".
Prüft beim Start still gegen ein Gitea-Release-Manifest (latest.json),
bietet im Settings-/About-Dialog einen manuellen Check sowie einen
Versionsverlauf mit Rollback-Download (versions.json, eigener schlanker
Index neben dem Updater-Manifest). Dafür: tauri-plugin-updater/process/
http/shell + zugehörige Capabilities, neue App-Icons (auch für die
plattformspezifischen Bundle-Formate), sowie ein kleingeschriebener
Produktname samt erweitertem nativen Info-Fenster (macOS-About).
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.
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.
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.
Nutzer-Report „funktioniert nicht": Der Import stürzte mit einem harten
RangeError ab, sobald eine STAC-Kachel entpackt die maximale JS-String-Länge
überschritt (DXF komprimiert stark — eine Kachel unter dem 150-MB-Limit kann
trotzdem >700 MB unkomprimierten Text ergeben, real reproduziert für ein
dicht bebautes Stadtzentrum). downloadAssetText prüft jetzt zusätzlich die
JSZip-interne unkomprimierte Grössenschätzung VOR dem Entpacken und fängt
verbleibende Fehler (Netzwerk/ZIP/String-Länge) sicher ab, statt zu werfen.
Zu grosse/fehlgeschlagene Kacheln wurden bisher stumm übersprungen (0 Gebäude,
keine Erklärung — sah wie ein Bug aus). fetchBuildings3d liefert jetzt
skippedTiles mit; der Dialog zeigt „X Kachel(n) übersprungen, zu gross" statt
eines wortlosen Leer-Ergebnisses.
Neuer RenderStyle::ShadedEdges in render3d: wie "shaded" (echte Bauteilfarben,
beleuchtet), zusätzlich dunkle Modell-Kanten obenauf wie bei "hidden" — der
typische Revit/ArchiCAD-Look, der bisher fehlte (nur reines Weiss+Kanten via
"hidden" oder reine Bauteilfarben ohne Kanten via "shaded" waren möglich).
Nutzt dieselbe tiefengebiaste Flächen-Pipeline wie "hidden", damit die Kanten
sauber obenauf liegen (kein Z-Fighting). +6 Rust-Tests (--features render,
83/83 grün). Als neue Option "shaded-edges" in beiden Darstellungsart-
Dropdowns der 3D-Oberleiste; Three.js-Fallback ignoriert den Wert graceful
(fällt auf shaded zurück, bekommt bewusst keine neuen Features).
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.
Ersatz für die entfernte pauschale Brüstungslinie: wählbar aussen/innen/beide
Flächen + Blickrichtung Auf-/Untersicht (Aufsicht dünn gepunktet, Untersicht
gestrichelt wie die übrigen Überkopf-Projektionen), an der tatsächlichen
Rahmenkante statt der Wandachse. Default aus (kein Feld gesetzt = keine Linie).
UI-Feld im Fenstertyp-Editor.
Ersetzt die stark vereinfachte Box-Extrusion (vec25-Footprint + Pauschalhöhe
9m) durch echte Gebäudegeometrie aus den swissBUILDINGS3D-STAC-Kacheln (Wahl
zwischen Generation 2.0 stabil und 3.0 Beta, DXF-Kacheln über den bestehenden
dxfParser als Mesh eingelesen). Gelände kommt neu aus echten swissALTI3D-XYZ-
Rastern (0.5m/2m wählbare Punktdichte) statt der groben profile.json-Näherung.
Gemeinsames STAC-Client-Modul (stacApi.ts) für beide Quellen.
Vertikale Sprossenteilung im Glasfeld (mullionCols−1 Spalten), spiegelbildlich
zur bestehenden mullionRows-Logik: 3D-Rahmen-Riegel, Ansichts-Trennlinien +
Glasscheiben als echtes rows×cols-Raster, Eingabefeld im Fenstertyp-Editor und
im ResourceManager.
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).
Nutzer-Feedback 'Ansichten sehen noch schrecklich aus' — drei Ursachen behoben:
1. RUHIGE FLÄCHEN: Rollen-Füllung (Fassade/Decke einheitlich hell, Dach eine
Stufe dunkler) statt Tiefen-Grau-Patchworks; Wand-/Deckenflächen ohne
Kontur (kein Linienraster aus Pfeiler-/Sturz-Teilboxen und Geschossfugen
mehr — der Fassadenrand liest sich über den Kontrast zum Papier), nur das
Dach behält seine Kontur. Painter-Gleichstand: Decke vor Wand (bündige
Decken-Stirnstreifen verschwinden unter der Fassade).
2. ENTSPIEGELT: die u-Achse der Ansicht ist jetzt das Blickrichtungs-RECHTS
(cross(up, N)) statt der Kamera-Formel für Blick entlang −z — wer nach
Norden schaut, hat Osten rechts. (Die Schnitt-Pipeline behält vorerst die
Rust-Konvention; die dortige Spiegelung ist als separates Thema notiert.)
3. SCHATTEN REPARIERT: Werfer-Tiefe = nächste Kante (depthMin — bei
Dachflächen die auskragende Traufe, dadurch wirft das Dach jetzt den
klassischen Traufschatten) + Kappung MAX_SHADOW_DELTA 1.2 m (keine
raumhohen Parallelogramme von fernen Innenwänden mehr).
Fusszeile 'render3d' → 'aus dem Modell' (die Ansicht ist reine TS-Projektion).
737/737 grün; headless verifiziert (Demo-Ansicht Süd).
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.
toElevation.ts: Painter-Projektion des 3D-Modells auf die Ansichtsebene
(Fassaden-/Deckenflächen fern→nah, Rückseiten-Culling, Fenster/Türen als
Rahmen+Glas, Bodenlinie) + klassischer 45°-Schlagschatten auskragender
Bauteile (Sutherland–Hodgman auf die Empfängerfläche geclippt). Schatten-
Umschalter in der Ansichts-Leiste (DrawingLevel.shadows), App rendert
elevation-Ebenen über den neuen Generator (synchron, ohne WASM).
Beim Zeichnen erscheinen Länge + Winkel direkt am Cursor (L:/W:-Kästchen),
gängige Winkel (15°-Vielfache) rasten weich ein — mit Winkel-Badge und
gestrichelter Führungslinie. Vorrang: Objekt-Snap > Shift/Ortho > Winkelraster
> Raster. Toggle + Toleranz in der Fang-Leiste. Konflikt tools/types.ts:
erweitertes hud-Feld + measure-Feld koexistieren.
# Conflicts:
# src/tools/types.ts
Beim Zeichnen erscheint jetzt direkt am Cursor ein blau umrandetes
Massband-Kästchen mit Länge/Winkel (L: 3.118m W: 60.000°, Winkel im
Bereich (−180,180]) statt nur in der Befehlszeile. Zusätzlich rastet
der Zugwinkel weich auf gängige Winkel (15°-Vielfache, Toleranz per
Default 2.5°) ein, sobald kein Objekt-Snap greift — mit gelblichem
Winkel-Badge und einer über den Cursor hinaus verlängerten, gestrichelten
Führungslinie (Vectorworks-Vorbild).
- tools/types.ts: ToolDraft.hud um length/angleDeg erweitert (text bleibt
für Befehle ohne L/W-Paar), neuer segmentHud()-Helper.
- tools/snapping.ts: neue reine Funktion snapCommonAngle() + Einbindung in
computeSnap (Objekt-Snap > harter Ortho-Zwang > weiches Winkelraster >
Raster). Neues SnapSettings-Feld commonAngles + commonAngleTolerance,
neuer SnapKind "angle".
- ui/StatusBar.tsx: Toggle + Toleranz-Eingabe in der Fang-Popover.
- plan/PlanView.tsx: DraftHud- und AngleGuide-Overlay (screen-space,
zoomunabhängige Größe); die Winkel-Info reitet auf draft.snap mit.
- i18n: snap.commonAngles / snap.commonAngleTolerance (de/en).
- snapping.test.ts: snapCommonAngle-Fälle (exakt/Toleranz/Bereich/
15°-Raster/Projektion) + Objekt-Snap-Vorrang vor dem Winkelraster.
App: kind "elevation" nutzt generateElevationPlan (synchron, ohne WASM)
statt der Schnitt-Pipeline; Fallback-Hinweis bleibt bei fehlender Linie.
Oberleiste (ViewRibbonTab): Umschalter "Schatten", nur bei aktiver Ansicht
sichtbar, schreibt DrawingLevel.shadows. i18n-Keys in de/en.
Zwei Klicks (Start -> Ende) legen die Grundriss-Schnitt-/Ansichtslinie einer
DrawingLevel fest. Ziel: genau eine Platzhalter-Ebene ohne Linie wird belegt,
sonst neue Ebene (Schnitt B/C ...). Live-Vorschau mit Richtungspfeil, Art
(Schnitt/Ansicht) als Inline-Option umschaltbar. Registry-Aliase schnittlinie/
ansichtslinie, Ribbon-Gruppe 'Schnitte' im BIM-Tab, i18n de/en, Datenpfad-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.
Zwei Klicks (Ecke → Gegenecke, Live-Vorschau + Mass-HUD); die Aussparung wird
der Decke des aktiven Geschosses hinzugefügt, die das Rechteck vollständig
enthält (alle 4 Ecken im Umriss), sonst No-op. Aliase 'deckenloch'/
'aussparung', BIM-Ribbon-Eintrag mit eigenem Icon. Komplettiert die Decken-
Aussparungen (b290120) um den Zeichenweg. 684/684 grün.
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.
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.
Zwei vom Renderer bereits konsumierte Felder im Flügel/Sprossen-Panel
zugänglich gemacht + in der Live-Ansicht dargestellt:
- transomHeight (Oberlicht): 2D-Kämpferlinie im Grundriss + 3D-Oberlichtscheibe
waren schon da; Kämpferlinie jetzt auch in der Dialog-Vorschau
- mullionRows (Kämpfer-/Sprossenzeilen): 3D-Kämpfer bei 'fein'; waagrechte
Teiler in der Vorschau
Kein Renderer-Aufwand — reine UI-/Vorschau-Freischaltung. 659/659 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.
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.
Gewählte Decken bekommen im wgpu-3D-Viewport editierbare Griffe — analog
Wand/2D-Element:
- Eckpunkt-Griffe (Umriss-Vertices) → moveCeilingGrip.
- Je Seite ein Kanten-Mittelpunkt-Griff (rautenförmig, eigene Farbe) →
moveCeilingEdge (Nutzer-Wunsch „an allen seiten auch ein punkt").
- Verschiebe-Griff im Schwerpunkt → moveCeilingBy.
Alle drei Store-Actions existierten bereits (2D-Griffe); neu ist nur die
3D-Griffgeometrie (computeGrips), das Kanten-Drag (GripDrag „edge") und die
Prop-Verdrahtung Wasm3DViewport ← Viewport3D ← App (editCeilings/onEditEdge,
Griff-Ziel um ceilingId erweitert). Die three.js-Sicht bleibt unverändert
(Default ist wgpu). tsc + vitest 620 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.
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.