Schnitt/Ansicht: SectionOutput aus render3d an die Zeichenebenen anbinden
- render3d/web.rs: GPU-freies WASM-Binding cut_section_json(model_json, p, n)
→ JSON {cutPolygons, visibleEdges, hiddenEdges} in (u,v)-Metern.
- src/plan/toSection.ts (neu): SectionOutput-Typen, sectionPlaneFromLevel()
leitet die Schnittebene aus linePoints/directionSign ab, computeSection()
flacht über projectToModel3d ab und ruft das Binding.
- src/engine/engine3d.ts (neu): geteilter memoisierter pkg3d-Loader, damit
3D-Viewport und Schnittpfad EINE mod.default()-Init teilen.
- generatePlan.ts: generateSectionPlan() übersetzt SectionOutput in
bestehende Primitive (Cut = polygon mit Poché-Schraffur, sichtbare Kante =
line solid, verdeckte Kante = line dashed) — keine neue Primitive-Art nötig.
- App.tsx: SectionPlanView ersetzt den Stub für Ebenen vom Typ Schnitt/Ansicht;
rendert dasselbe PlanView, mit lokalisierten Hinweisen (lädt/keine Linie/Fehler).
- i18n de/en: section.*-Schlüssel.
- Öffnungen erscheinen korrekt (Brüstung/Sturz-Teilrechtecke) über die
projectToModel3d-Teilkörper-Zerlegung.
Gates: tsc -b 0, build grün (WASM = eigener Lazy-Chunk), render3d cargo test 29/29,
wasm32 --features web check grün.
This commit is contained in:
@@ -19,6 +19,7 @@
|
||||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import type { Project } from "../model/types";
|
||||
import { projectToModel3d } from "../plan/toWalls3d";
|
||||
import { loadEngine3d } from "../engine/engine3d";
|
||||
|
||||
/** Fertige Kamera für einen Frame (world-Meter, Y-up — wie render3d::types::Camera). */
|
||||
export interface Camera3d {
|
||||
@@ -54,23 +55,6 @@ interface WebModelRendererLike {
|
||||
render(): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* WASM-Modul EINMAL laden + initialisieren (memoisiert). `mod.default()` darf
|
||||
* nur einmal laufen — ein zweiter Init (React-StrictMode-Doppelmount) verwirft
|
||||
* die Closures des ersten („closure invoked recursively or after being dropped").
|
||||
*/
|
||||
let enginePromise: Promise<any> | null = null;
|
||||
function loadEngine(): Promise<any> {
|
||||
if (!enginePromise) {
|
||||
enginePromise = (async () => {
|
||||
const mod: any = await import("../engine/pkg3d/render3d.js");
|
||||
await mod.default(); // lädt render3d_bg.wasm
|
||||
return mod;
|
||||
})();
|
||||
}
|
||||
return enginePromise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renderer je Canvas EINMAL erzeugen (memoisiert). Ein Canvas kann nur EINEN
|
||||
* WebGPU-Kontext tragen; ein zweiter `WebModelRenderer.new` auf demselben
|
||||
@@ -82,7 +66,7 @@ function getRenderer(canvas: HTMLCanvasElement): Promise<WebModelRendererLike> {
|
||||
let p = rendererCache.get(canvas);
|
||||
if (!p) {
|
||||
p = (async () => {
|
||||
const mod = await loadEngine();
|
||||
const mod = await loadEngine3d();
|
||||
// Canvas VOR dem Surface-Erzeugen auf die Zielpixel (DPR) bringen.
|
||||
const rect = canvas.getBoundingClientRect();
|
||||
const dpr = window.devicePixelRatio || 1;
|
||||
|
||||
Reference in New Issue
Block a user