truck_polymesh/
polygon_mesh.rs1use crate::errors::Error;
2use crate::*;
3use std::fmt::Debug;
4
5impl<V: Copy + Debug, A: Attributes<V>> PolygonMesh<V, A> {
6 pub fn new(attributes: A, faces: Faces<V>) -> Self {
12 Self::try_new(attributes, faces).unwrap_or_else(|e| panic!("{e:?}"))
13 }
14
15 pub fn try_new(attributes: A, faces: Faces<V>) -> Result<Self, Error<V>> {
24 faces
25 .is_compatible(&attributes)
26 .map(|_| Self::new_unchecked(attributes, faces))
27 }
28
29 #[inline(always)]
31 pub const fn new_unchecked(attributes: A, faces: Faces<V>) -> Self {
32 Self { attributes, faces }
33 }
34
35 #[inline(always)]
37 pub fn debug_new(attributes: A, faces: Faces<V>) -> Self {
38 match cfg!(debug_assertions) {
39 true => Self::new(attributes, faces),
40 false => Self::new_unchecked(attributes, faces),
41 }
42 }
43
44 #[inline(always)]
46 pub const fn attributes(&self) -> &A { &self.attributes }
47
48 #[inline(always)]
50 pub const fn faces(&self) -> &Faces<V> { &self.faces }
51
52 #[inline(always)]
54 pub const fn tri_faces(&self) -> &Vec<[V; 3]> { &self.faces.tri_faces }
55
56 #[inline(always)]
58 pub const fn quad_faces(&self) -> &Vec<[V; 4]> { &self.faces.quad_faces }
59
60 #[inline(always)]
62 pub const fn other_faces(&self) -> &Vec<Vec<V>> { &self.faces.other_faces }
63
64 #[inline(always)]
70 pub fn face_iter(&self) -> impl Iterator<Item = &[V]> { self.faces.face_iter() }
71
72 #[inline(always)]
78 pub fn face_iter_mut(&mut self) -> impl Iterator<Item = &mut [V]> { self.faces.face_iter_mut() }
79 #[inline(always)]
81 pub fn editor(&mut self) -> PolygonMeshEditor<'_, V, A> {
82 PolygonMeshEditor {
83 attributes: &mut self.attributes,
84 faces: &mut self.faces,
85 bound_check: true,
86 }
87 }
88 #[inline(always)]
90 pub fn uncheck_editor(&mut self) -> PolygonMeshEditor<'_, V, A> {
91 PolygonMeshEditor {
92 attributes: &mut self.attributes,
93 faces: &mut self.faces,
94 bound_check: false,
95 }
96 }
97 #[inline(always)]
99 pub fn debug_editor(&mut self) -> PolygonMeshEditor<'_, V, A> {
100 PolygonMeshEditor {
101 attributes: &mut self.attributes,
102 faces: &mut self.faces,
103 bound_check: cfg!(debug_assertions),
104 }
105 }
106}
107
108impl PolygonMesh {
109 pub fn merge(&mut self, mut mesh: PolygonMesh) {
111 let n_pos = self.positions().len();
112 let n_uv = self.uv_coords().len();
113 let n_nor = self.normals().len();
114 mesh.faces.face_iter_mut().for_each(move |face| {
115 face.iter_mut().for_each(|v| {
116 v.pos += n_pos;
117 v.uv = v.uv.map(|uv| uv + n_uv);
118 v.nor = v.nor.map(|nor| nor + n_nor);
119 })
120 });
121 self.attributes.positions.extend(mesh.attributes.positions);
122 self.attributes.uv_coords.extend(mesh.attributes.uv_coords);
123 self.attributes.normals.extend(mesh.attributes.normals);
124 self.faces.naive_concat(mesh.faces);
125 }
126 #[inline(always)]
128 pub fn bounding_box(&self) -> BoundingBox<Point3> { self.positions().iter().collect() }
129 #[inline(always)]
131 pub fn to_positions_mesh(&self) -> PolygonMesh<usize, Vec<Point3>> {
132 let faces = self.faces();
133 let tri_faces = faces
134 .tri_faces()
135 .iter()
136 .map(|face| [face[0].pos, face[1].pos, face[2].pos])
137 .collect::<Vec<_>>();
138 let quad_faces = faces
139 .quad_faces()
140 .iter()
141 .map(|face| [face[0].pos, face[1].pos, face[2].pos, face[3].pos])
142 .collect::<Vec<_>>();
143 let other_faces = faces
144 .other_faces()
145 .iter()
146 .map(|face| face.iter().map(|x| x.pos).collect::<Vec<_>>())
147 .collect::<Vec<_>>();
148 PolygonMesh {
149 attributes: self.positions().clone(),
150 faces: Faces {
151 tri_faces,
152 quad_faces,
153 other_faces,
154 },
155 }
156 }
157}
158
159impl Invertible for PolygonMesh {
160 #[inline(always)]
161 fn invert(&mut self) {
162 self.attributes.normals.iter_mut().for_each(|n| *n = -*n);
163 self.faces.invert();
164 }
165 #[inline(always)]
166 fn inverse(&self) -> Self {
167 Self {
168 attributes: StandardAttributes {
169 positions: self.attributes.positions.clone(),
170 uv_coords: self.attributes.uv_coords.clone(),
171 normals: self.attributes.normals.iter().map(|n| -*n).collect(),
172 },
173 faces: self.faces.inverse(),
174 }
175 }
176}
177
178impl PolygonMesh {
179 #[inline(always)]
181 pub const fn positions(&self) -> &Vec<Point3> { &self.attributes.positions }
182
183 #[inline(always)]
185 pub fn positions_mut(&mut self) -> &mut [Point3] { &mut self.attributes.positions }
186
187 #[inline(always)]
189 pub fn push_position(&mut self, position: Point3) { self.attributes.positions.push(position) }
190
191 #[inline(always)]
193 pub fn extend_positions<I: IntoIterator<Item = Point3>>(&mut self, iter: I) {
194 self.attributes.positions.extend(iter)
195 }
196
197 #[inline(always)]
199 pub const fn uv_coords(&self) -> &Vec<Vector2> { &self.attributes.uv_coords }
200
201 #[inline(always)]
203 pub fn uv_coords_mut(&mut self) -> &mut [Vector2] { &mut self.attributes.uv_coords }
204
205 #[inline(always)]
207 pub fn push_uv_coord(&mut self, uv_coord: Vector2) { self.attributes.uv_coords.push(uv_coord) }
208
209 #[inline(always)]
211 pub fn extend_uv_coords<I: IntoIterator<Item = Vector2>>(&mut self, iter: I) {
212 self.attributes.uv_coords.extend(iter)
213 }
214
215 #[inline(always)]
217 pub const fn normals(&self) -> &Vec<Vector3> { &self.attributes.normals }
218
219 #[inline(always)]
221 pub fn normals_mut(&mut self) -> &mut [Vector3] { &mut self.attributes.normals }
222
223 #[inline(always)]
225 pub fn extend_normals<I: IntoIterator<Item = Vector3>>(&mut self, iter: I) {
226 self.attributes.normals.extend(iter)
227 }
228}
229
230impl<V, A: Default> Default for PolygonMesh<V, A> {
231 fn default() -> Self {
232 Self {
233 attributes: A::default(),
234 faces: Faces::default(),
235 }
236 }
237}
238
239impl<'de, V, A> Deserialize<'de> for PolygonMesh<V, A>
240where
241 V: Copy + Debug + Deserialize<'de>,
242 A: Attributes<V> + Deserialize<'de>,
243{
244 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
245 where D: serde::Deserializer<'de> {
246 #[derive(Deserialize)]
247 struct PolygonMesh_<V, A> {
248 attributes: A,
249 faces: Faces<V>,
250 }
251 let PolygonMesh_ { attributes, faces } = PolygonMesh_::<V, A>::deserialize(deserializer)?;
252 Self::try_new(attributes, faces).map_err(serde::de::Error::custom)
253 }
254}
255
256#[derive(Debug)]
314pub struct PolygonMeshEditor<'a, V: Copy + Debug, A: Attributes<V>> {
315 pub attributes: &'a mut A,
317 pub faces: &'a mut Faces<V>,
319 bound_check: bool,
320}
321
322impl<'a, V: Copy + Debug, A: Attributes<V>> PolygonMeshEditor<'a, V, A> {
323 #[inline(always)]
324 fn is_compatible(&self) -> Result<(), Error<V>> { self.faces.is_compatible(&*self.attributes) }
325
326 #[inline(always)]
328 pub fn try_drop(mut self) -> Result<(), Error<V>> {
329 self.bound_check = false;
330 self.is_compatible()
331 }
332}
333
334impl<'a, V: Copy + Debug, A: Attributes<V>> Drop for PolygonMeshEditor<'a, V, A> {
335 #[inline(always)]
336 fn drop(&mut self) {
337 if self.bound_check {
338 self.is_compatible().unwrap_or_else(|e| panic!("{e:?}"));
339 }
340 }
341}