1pub(crate) mod mesh_builder;
3
4use cgmath::Matrix4;
6use ndarray::Array1;
7use num::ToPrimitive;
8
9use crate::{
11 simulation::drawable::binder::{Binder, Bindable, Drawable},
12 Error,
13};
14use mesh_builder::MeshBuilder;
15
16#[allow(dead_code)]
29#[derive(Debug)]
30pub(crate) struct Mesh {
31 pub(crate) max_length: f64,
32 pub(crate) model_matrix: Matrix4<f32>,
33 pub(crate) boundary_indices: Option<Vec<u32>>,
34 binder: Binder,
35 pub(crate) indices: Array1<u32>,
36 pub(crate) vertices: Array1<f64>,
37}
38
39impl Mesh {
40 pub fn get_model_matrix(&self) -> &Matrix4<f32> {
42 &self.model_matrix
43 }
44
45 pub fn builder<B>(location: B) -> MeshBuilder
47 where
48 B: AsRef<str>,
49 {
50 MeshBuilder::new(location)
51 }
52
53 pub(crate) fn filter_for_solving_1d(&self) -> Array1<f64> {
55 let vertices_len = self.vertices.len() / 12;
57 self.vertices
58 .iter()
59 .enumerate()
60 .filter_map(|(idx, x)| {
61 if idx % 6 == 0 && idx < vertices_len * 6 {
62 Some(*x)
63 } else {
64 None
65 }
66 })
67 .collect()
68 }
69
70 pub(crate) fn update_gradient_1d(&mut self, velocity_norm: Vec<f64>) {
74 let sol_max = velocity_norm
75 .iter()
76 .copied()
77 .fold(f64::NEG_INFINITY, f64::max);
78
79 let sol_min = velocity_norm.iter().copied().fold(f64::INFINITY, f64::min);
80 let vertices_len = self.vertices.len();
81
82 for i in 0..(vertices_len / 12) {
83 let norm_sol =
84 (velocity_norm[i] - sol_min) / (sol_max - sol_min) * (std::f64::consts::PI / 2.);
85 self.vertices[6 * i + 3] = norm_sol.sin();
86 self.vertices[6 * i + 5] = norm_sol.cos();
87 self.vertices[6 * i + 3 + vertices_len / 2] = norm_sol.sin();
88 self.vertices[6 * i + 5 + vertices_len / 2] = norm_sol.cos();
89 }
90 }
91}
92
93impl Bindable for Mesh {
94 fn get_binder(&self) -> Result<&Binder, Error> {
95 Ok(&self.binder)
96 }
97
98 fn get_mut_binder(&mut self) -> Result<&mut Binder, Error> {
99 Ok(&mut self.binder)
100 }
101}
102
103impl Drawable for Mesh {
104 fn get_indices(&self) -> Result<&Array1<u32>, Error> {
105 Ok(&self.indices)
106 }
107
108 fn get_vertices(&self) -> Result<Array1<f32>, Error> {
109 Ok(Array1::from_vec(
110 self.vertices.iter().map(|x| -> Result<f32,Error> { x.to_f32().ok_or(Error::FloatConversion) })
111 .collect::<Result<Vec<f32>,_>>()?
112 ))
113 }
114
115 fn get_max_length(&self) -> Result<f32, Error> {
116 let max_len = self.max_length.to_f32();
117
118 match max_len {
119 Some(f) => {
120 if f.is_finite() {
121 Ok(f)
122 } else {
123 Err(Error::Overflow)
124 }
125 }
126 None => Err(Error::Unimplemented),
127 }
128 }
129}
130
131#[cfg(test)]
132mod test {
133 use super::Mesh;
134 use ndarray::Array1;
135
136 #[test]
137 fn parse_coordinates() {
138 let new_mesh = Mesh::builder("/home/Arthur/Tesis/Dzahui/assets/test.obj")
139 .build_mesh_3d()
140 .unwrap();
141 assert!(
142 new_mesh.vertices
143 == Array1::from_vec(vec![
144 -1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0,
145 0.0, 0.0, 1.0
146 ])
147 );
148 assert!(new_mesh.indices == Array1::from_vec(vec![0, 1, 2]));
149 }
150
151 #[test]
152 fn is_max_distance() {
153 let new_mesh = Mesh::builder("/home/Arthur/Tesis/Dzahui/assets/test.obj")
154 .build_mesh_2d()
155 .unwrap();
156 assert!(new_mesh.max_length >= 1.90);
157 assert!(new_mesh.max_length <= 2.10);
158 }
159}