Skip to main content

monstertruck_mesh/
meshing_shape.rs

1use crate::*;
2
3#[cfg(not(target_arch = "wasm32"))]
4use rayon::prelude::*;
5
6/// Minimum U-row count to enable parallel surface evaluation.
7#[cfg(not(target_arch = "wasm32"))]
8const PAR_THRESHOLD: usize = 8;
9
10impl<P> PolylineCurve<P> {
11    /// Meshes the curve.
12    pub fn from_curve<C>(curve: C, range: (f64, f64), tol: f64) -> Self
13    where C: ParameterDivision1D<Point = P> {
14        PolylineCurve(curve.parameter_division(range, tol).1)
15    }
16}
17
18fn eval_row(
19    surface: &impl ParametricSurface3D,
20    u: f64,
21    div1: &[f64],
22) -> (Vec<Point3>, Vec<Vector3>) {
23    let positions = div1.iter().map(|v| surface.evaluate(u, *v)).collect();
24    let normals = div1.iter().map(|v| surface.normal(u, *v)).collect();
25    (positions, normals)
26}
27
28impl StructuredMesh {
29    /// Meshes the surface.
30    /// # Arguments
31    /// * `surface` - surface to be meshed.
32    /// * `range` - parameter range.
33    /// * `tol` - standard tolerance for meshing.
34    pub fn from_surface<S>(
35        surface: &S,
36        range: ((f64, f64), (f64, f64)),
37        tol: f64,
38    ) -> StructuredMesh
39    where
40        S: ParametricSurface3D + ParameterDivision2D,
41    {
42        let (div0, div1) = surface.parameter_division(range, tol);
43        let (positions, normals): (Vec<_>, Vec<_>) =
44            div0.iter().map(|u| eval_row(surface, *u, &div1)).unzip();
45        StructuredMesh {
46            positions,
47            uv_division: Some((div0, div1)),
48            normals: Some(normals),
49        }
50    }
51
52    /// Meshes the surface with parallel U-row evaluation on non-WASM.
53    #[cfg(not(target_arch = "wasm32"))]
54    pub fn from_surface_par<S>(
55        surface: &S,
56        range: ((f64, f64), (f64, f64)),
57        tol: f64,
58    ) -> StructuredMesh
59    where
60        S: ParametricSurface3D + ParameterDivision2D + Sync,
61    {
62        let (div0, div1) = surface.parameter_division(range, tol);
63        let (positions, normals): (Vec<_>, Vec<_>) = if div0.len() >= PAR_THRESHOLD {
64            div0.par_iter()
65                .map(|u| eval_row(surface, *u, &div1))
66                .unzip()
67        } else {
68            div0.iter().map(|u| eval_row(surface, *u, &div1)).unzip()
69        };
70        StructuredMesh {
71            positions,
72            uv_division: Some((div0, div1)),
73            normals: Some(normals),
74        }
75    }
76}