Native wgpu-Viewports (2D+3D) im Tauri-Prozess: echtes Modell + gehrte Ecken
- native.rs: EINE winit-EventLoop hostet 2D- und 3D-Fenster (winit erlaubt nur eine Loop pro Prozess) — loest den RecreationAttempt-Panic zweier Loops; ersetzt native2d.rs/native3d.rs. Feature-gegated (native2d/native3d, einzeln oder zusammen). - render2d/render3d laden das ECHTE Modell aus assets/native2d_scene.json bzw. native3d_walls.json (Demo-Szene als Fallback); initialer Ausschnitt/Kamera aus den Modell-Grenzen gerahmt, initialer Redraw + gesetzte Fenstergroesse. - TS-Konverter toRenderScene/toWalls3d + scripts/dump-native-scene erzeugen die JSON aus sampleProject/generatePlan (npm run dump:native). - render2d: Scene.polylines fuer zusammenhaengende Umriss-/Zeichnungslaeufe → Gehrung statt Stumpfkappen an Wandecken/2D-Geometrien; MITER_LIMIT 4→8 (deckungsgleich mit SVG stroke-miterlimit:8 und WebGL2). - native3d-Feature + render3d-Pfad-Dep in der Tauri-Crate.
This commit is contained in:
@@ -50,6 +50,7 @@ pub fn demo_scene() -> Scene {
|
||||
width_mm: 0.18,
|
||||
},
|
||||
],
|
||||
polylines: vec![],
|
||||
lines: vec![Line {
|
||||
a: [0.0, -1.0],
|
||||
b: [9.0, -1.0],
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
// Schicht, die ohne Display gruen bleiben muss.
|
||||
// - Ergebnis ist byte-fuer-byte-vergleichbar mit dem WebGL-Referenzpfad.
|
||||
|
||||
use crate::types::{FillPolygon, Line, Point, Rgba, Scene};
|
||||
use crate::types::{FillPolygon, Line, Point, Polyline, Rgba, Scene};
|
||||
|
||||
/// viewBox-Einheiten je Meter (identisch zu PlanView/toScreen im Web-Pfad).
|
||||
pub const PX_PER_M: f32 = 90.0;
|
||||
@@ -46,7 +46,7 @@ fn cross(a: Point, b: Point, c: Point) -> f32 {
|
||||
}
|
||||
|
||||
/// Maximaler Miter-Laengenfaktor; darueber wird geklemmt (kein Spike an spitzen Ecken).
|
||||
const MITER_LIMIT: f32 = 4.0;
|
||||
const MITER_LIMIT: f32 = 8.0;
|
||||
|
||||
/// Einheits-Links-Normale von `from` nach `to` (Bildschirm-Raum); None bei Nulllaenge.
|
||||
#[inline]
|
||||
@@ -380,7 +380,13 @@ pub fn compile_scene(scene: &Scene) -> GpuGeometry {
|
||||
geo.stroke_polyline(&o.pts, true, o.color, o.width_mm, &mut bounds);
|
||||
}
|
||||
}
|
||||
// 3) Freie Linien.
|
||||
// 3) Offene Polylinien (verbundene Umrisskanten / 2D-Zeichnungszuege) als EIN
|
||||
// gehrter Streifen — die inneren Ecken bekommen so eine Gehrung statt
|
||||
// Stumpfkappen (closed=false).
|
||||
for pl in &scene.polylines {
|
||||
compile_polyline(&mut geo, pl, &mut bounds);
|
||||
}
|
||||
// 4) Freie Einzel-Linien (Tuerblaetter, Bogen-Sehnen, Referenzlinien).
|
||||
for l in &scene.lines {
|
||||
compile_line(&mut geo, l, &mut bounds);
|
||||
}
|
||||
@@ -389,6 +395,12 @@ pub fn compile_scene(scene: &Scene) -> GpuGeometry {
|
||||
geo
|
||||
}
|
||||
|
||||
fn compile_polyline(geo: &mut GpuGeometry, pl: &Polyline, bounds: &mut Bounds) {
|
||||
if pl.width_mm > 0.0 && pl.pts.len() >= 2 {
|
||||
geo.stroke_polyline(&pl.pts, false, pl.color, pl.width_mm, bounds);
|
||||
}
|
||||
}
|
||||
|
||||
fn compile_fill(geo: &mut GpuGeometry, poly: &FillPolygon, bounds: &mut Bounds) {
|
||||
let tris = triangulate(&poly.pts);
|
||||
if tris.is_empty() {
|
||||
|
||||
@@ -52,9 +52,25 @@ pub struct Outline {
|
||||
pub width_mm: f32,
|
||||
}
|
||||
|
||||
/// Ein OFFENER Linienzug mit echter Papier-mm-Breite. Anders als `Outline`
|
||||
/// (geschlossener Ring) und `Line` (Einzelsegment) traegt er >=2 zusammenhaengende
|
||||
/// Punkte, deren INNERE Ecken korrekt gehrt (mitred) werden — genau das, was die
|
||||
/// nicht-unterdrueckten Umrisskanten einer Wandecke bzw. eine 2D-Zeichnungs-
|
||||
/// Polylinie brauchen (sonst Stumpfkappen statt Gehrung).
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Polyline {
|
||||
/// Zusammenhaengende Punkte in Modell-Metern (offen, nicht geschlossen).
|
||||
pub pts: Vec<Point>,
|
||||
/// Strichfarbe (RGBA 0..1).
|
||||
pub color: Rgba,
|
||||
/// Strichbreite in echten Papier-Millimetern.
|
||||
#[serde(rename = "widthMm")]
|
||||
pub width_mm: f32,
|
||||
}
|
||||
|
||||
/// Die vollstaendige Szene: alles, was ein Frame zeichnet. Reihenfolge ist
|
||||
/// signifikant (Z-/Alpha-Ueberlagerung): erst Fuellungen, dann Umrisse, dann
|
||||
/// freie Linien — analog zur Draw-Reihenfolge im WebGL-Pfad.
|
||||
/// offene Polylinien, dann freie Linien — analog zur Draw-Reihenfolge im WebGL-Pfad.
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
||||
pub struct Scene {
|
||||
#[serde(default)]
|
||||
@@ -62,6 +78,8 @@ pub struct Scene {
|
||||
#[serde(default)]
|
||||
pub outlines: Vec<Outline>,
|
||||
#[serde(default)]
|
||||
pub polylines: Vec<Polyline>,
|
||||
#[serde(default)]
|
||||
pub lines: Vec<Line>,
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user