# Schnitt/Ansicht-Pipeline: analytische Prismen-Projektion (`render3d::section`) > Gegenstueck zum OCCT-WASM-HLR-Spike (`docs/welle-c-hlr-spike/FEASIBILITY.md`): > statt eines generischen CAD-Kernels nutzt dieser Ansatz eine Invariante des > Modells, um Schnitt/Ansicht rein analytisch (kein Hidden-Line-Removal-Solver) > zu berechnen. Implementiert in `src-tauri/render3d/src/section.rs`. ## Ansatz Jedes Bauteil in diesem Modell ist ein **Prisma**: ein 2D-Grundriss-Fussabdruck- Polygon (Wand-Band bzw. Decken-Umriss, siehe `mesh.rs`), konstant extrudiert ueber ein Hoehenintervall `[z0, z1]`. Diese Einschraenkung — konstanter Querschnitt ueber die gesamte Hoehe — macht die Schnittgeometrie trivial im Vergleich zu generischem HLR: - **Schnitt einer vertikalen Ebene mit einem Prisma** = 2D-Geraden/Polygon- Clipping IM GRUNDRISS (die Schnittebene projiziert im Grundriss auf eine Linie) → ein oder mehrere u-Intervalle, in denen die Linie das Fussabdruck- Polygon durchquert. Jedes Intervall × `[z0, z1]` ist das Cut-Rechteck. Da die Hoehe unabhaengig von der Grundriss-Position ist, ist das Ergebnis **immer ein Rechteck**, nie ein Trapez — auch bei diagonalen Wandachsen. - **Projektion/Ansicht** (Kanten hinter der Ebene, in Blickrichtung) reduziert sich auf ein **2D-Sichtbarkeitsproblem im Grundriss** kombiniert mit einem Hoehen-Ueberlappungstest: da alle Seitenflaechen der Prismen vertikal sind, genuegt ein Sichtstrahl-Test im Grundriss (verdeckt ein naeheres Prisma- Fussabdruckpolygon die Sichtlinie?) plus Ueberlappung der Hoehenintervalle. Das ersetzt einen 66-MB-WASM-CAD-Kernel durch closed-form Arithmetik in reinem Rust, ohne zusaetzliches Laufzeitgewicht ueber `render3d` hinaus. ## `SectionOutput`-Format Modul: `render3d::section`. Alle Groessen in **Metern**. ```rust pub struct SectionPlane { pub point: [f32; 3], pub normal: [f32; 3] } pub struct SectionOutput { pub cut_polygons: Vec, // JSON: "cutPolygons" pub visible_edges: Vec, // JSON: "visibleEdges" pub hidden_edges: Vec, // JSON: "hiddenEdges" } pub struct CutPolygon { pub component: ComponentRef, pub color: Rgb, pub pts: Vec<[f32; 2]> } pub struct SectionEdge { pub component: ComponentRef, pub a: [f32; 2], pub b: [f32; 2] } pub struct ComponentRef { pub kind: ComponentKind /* Wall | Slab */, pub index: usize } ``` **Koordinatensystem der Ausgabe (u, v):** - Ursprung: `SectionPlane::point`, projiziert. - `u` (horizontal): Strecke entlang der Schnittebene, senkrecht zur Blickrichtung, berechnet als `normalize(cross(normal, world_up))` — dieselbe rechtshaendige Konvention wie `math::look_at`s `right`-Vektor. Bei den vier Standard-Konstruktoren (`looking_plus_x/minus_x/plus_y/minus_y`) ist `u` direkt die jeweils andere Grundriss-Achse. - `v` (vertikal, "Hoehe"): `v = world.y`, ABSOLUT. Diese Codebasis ist durchgaengig Y-up (`types.rs`/`mesh.rs`/`math.rs`: „world.y = Hoehe"); `v` folgt bewusst dieser etablierten Konvention statt einer wortwoertlichen „world.z"-Lesart, um modulübergreifend konsistent zu bleiben. - Nur **vertikale** Schnittebenen (Normale ohne Hoehen-Komponente) sind unterstuetzt — Grundriss-/Horizontalschnitte bleiben Sache der bestehenden 2D-Plan-Pipeline. `cut_polygons` sind bei diesem Modell immer Rechtecke (siehe oben), aber als generischer Punktering abgelegt — kompatibel zu `render2d::types::FillPolygon` (`pts: Vec`), dem vorgesehenen Zielformat fuer die spaetere 1:1- Uebersetzung in die Plan-/Schnitt-Ansicht. ## Bekannte Luecken - **Keine Wandknoten-Verschneidung (T-/X-Stoesse).** Wie in `mesh.rs` (M1-Stand) werden Waende als eigenstaendige, stumpf abgeschlossene Quader behandelt, die sich an Ecken UEBERLAPPEN statt sich zu vereinen (kein Miter-Join). Der Schnitt-Extraktor erbt das: an einem L-/T-Knoten kann eine Wand als „in die andere eingebettet" verdeckt erscheinen (im Testmodul `section::tests` bewusst als reales, erwartetes Verhalten dokumentiert und geprueft — kein Bug dieses Moduls, sondern ein Artefakt der fehlenden Verschneidungslogik weiter oben in der Pipeline). - **Keine Oeffnungs-Aussparungen.** `WallInput`/`SlabInput` kennen (noch) keine Tueren/Fenster; der Schnitt schneidet daher immer die volle Wandflaeche. Sobald Oeffnungen im Modell ankommen, muss `wall_prism`/die Cut-Polygon- Bildung sie als Aussparungen (Lochpolygone bzw. mehrere Teil-Rechtecke pro Hoehenband) beruecksichtigen. - **Keine echte Component-/Material-Id.** `WallInput`/`SlabInput` haben aktuell keine eigene Id; `ComponentRef` referenziert daher nur `(Art, Index im Eingabe-Array)` + die rohe Albedo-Farbe als Material-Platzhalter. Sobald ein echtes Ressourcen-/Material-System existiert, sollte `ComponentRef` auf eine stabile Id umgestellt werden (Indizes sind nicht stabil ueber Modell-Edits). - **Verdeckungstest nutzt Bounding-Boxen, nicht die exakte Fussabdruckform.** Fuer Wand-Baender und (i. d. R. konvexe) Deckenumrisse ist das exakt; bei stark konkaven oder diagonalen Grundrissen kann es zu Ueberverdeckung fuehren (ein Prisma blockiert dann auch Bereiche seiner eigenen „Nischen"). - **Kein generisches HLR.** Der Ansatz funktioniert NUR, weil alle Bauteile Prismen mit konstantem Querschnitt sind. Fuer echte gekrümmte oder nicht- prismatische Geometrie (Bogenwaende, Freiformdaecher, …) waere er nicht anwendbar — dafuer bliebe der OCCT-Weg (oder eine eigene, generischere HLR-Implementierung) die Referenz. - **Keine robuste Sonderfallbehandlung fuer Vertices exakt auf der Schnittlinie** (Toleranz-basiert, kein Tie-Breaking/Pertubation) — die Testszenarien vermeiden diesen Fall bewusst. ## Vergleich zum OCCT-WASM-Spike | | OCCT-WASM (`docs/welle-c-hlr-spike`) | Dieser Ansatz (`render3d::section`) | |---|---|---| | Verfahren | Generisches HLR (`HLRAppli_ReflectLines`) | Analytische Prismen-Projektion | | Anwendbarkeit | Beliebige BREP-Geometrie | Nur Prismen (konstanter Querschnitt über Höhe) | | Zusaetzliches Gewicht | ~62,8 MB WASM (~19,6 MB gzip), separater Lazy-Chunk | Keins — reines Rust in `render3d`, kein weiteres WASM-Asset | | Modul-Init | ~450 ms (Browser) / ~680 ms (Node) | Kein Initialisierungsschritt (kein Fremd-Modul zu laden) | | Rechenzeit (L-Wand + Platte) | ~21 ms (reiner HLR-Lauf, gemessen im Browser) | Nicht separat gemessen (kein Millisekunden-Timer im Test); die Operationen sind reine Vektor-/Intervall-Arithmetik über wenige Kanten (O(Anzahl-Prismen × Kanten-pro-Prisma) mit kleinen Konstanten) und liegen der Groessenordnung nach klar unter 1 ms fuer Szenen dieser Groesse — eine belastbare Messung steht noch aus | | Sichtbarkeit (verdeckte Kanten) | Exakt (echter HLR-Solver) | Naeherung über Bounding-Boxen im Grundriss + Hoehenintervall-Ueberlappung; exakt fuer achsparallele/konvexe Fussabdruecke | | Reifegrad | Isolierter Spike, nicht verdrahtet | Isolierter Spike (dieses Modul), nicht in `render2d`/die Plan-Ansicht verdrahtet | **Fazit:** Fuer den ueberwiegenden Regelfall dieses Projekts (Waende, Decken — alles Prismen) ist die analytische Loesung der pragmatischere Weg: kein zusaetzliches WASM-Gewicht, keine Fremd-Bibliothek, headless testbar wie der Rest von `render3d`. Der OCCT-Weg bleibt die Referenz, falls/sobald echte generische Volumenkoerper (Booleans, gekrümmte Flaechen) ins Modell kommen.