monstertruck_mesh/
meshing_shape.rs1use crate::*;
2
3#[cfg(not(target_arch = "wasm32"))]
4use rayon::prelude::*;
5
6#[cfg(not(target_arch = "wasm32"))]
8const PAR_THRESHOLD: usize = 8;
9
10impl<P> PolylineCurve<P> {
11 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 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 #[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}