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).
This commit is contained in:
2026-07-03 21:45:01 +02:00
parent 5fd0161bc7
commit 1f6da09b2b
7 changed files with 681 additions and 73 deletions
@@ -31,6 +31,7 @@ fn l_wall_scene() -> (Vec<WallInput>, Vec<SlabInput>) {
sill: 0.8,
height: 1.0,
}],
layers: None,
},
WallInput {
start: [0.0, 3.0],
@@ -40,6 +41,7 @@ fn l_wall_scene() -> (Vec<WallInput>, Vec<SlabInput>) {
base_elevation: 0.0,
color,
openings: vec![],
layers: None,
},
// "Spaeh"-Wand: kurzer Stummel HINTER Schenkel A (groesseres Modell-X,
// also groessere Tiefe von der Betrachter-Ebene aus), genau im
@@ -54,6 +56,7 @@ fn l_wall_scene() -> (Vec<WallInput>, Vec<SlabInput>) {
base_elevation: 0.0,
color,
openings: vec![],
layers: None,
},
];
let slabs = vec![SlabInput {