truck_polymesh/
faces.rs

1use crate::*;
2use errors::Error;
3
4type Vertex = StandardVertex;
5
6/// can be regarded as a vertex slice
7pub trait AsVertexSlice: AsRef<[Self::V]> {
8    /// items converted to vertex
9    type V: Copy + Into<Vertex>;
10}
11
12impl From<&Vertex> for Vertex {
13    fn from(v: &Vertex) -> Vertex { *v }
14}
15
16impl<'a, T: AsVertexSlice> AsVertexSlice for &'a T {
17    type V = T::V;
18}
19
20macro_rules! impl_as_vertex_slice {
21    ($vertex: ty) => {
22        impl<'a> AsVertexSlice for &'a [$vertex] {
23            type V = $vertex;
24        }
25        impl<const N: usize> AsVertexSlice for [$vertex; N] {
26            type V = $vertex;
27        }
28        impl AsVertexSlice for Vec<$vertex> {
29            type V = $vertex;
30        }
31        impl<'a> AsVertexSlice for &'a [&'a $vertex] {
32            type V = &'a $vertex;
33        }
34        impl<'a> AsVertexSlice for Vec<&'a $vertex> {
35            type V = &'a $vertex;
36        }
37    };
38}
39
40impl_as_vertex_slice!(Vertex);
41
42macro_rules! impl_as_vertex {
43    (impl From<$vertex: ty> for Vertex { $from: item }) => {
44        impl From<$vertex> for Vertex {
45            #[inline(always)]
46            $from
47        }
48        impl From<&$vertex> for Vertex {
49            #[inline(always)]
50            fn from(v: &$vertex) -> Vertex { Vertex::from(*v) }
51        }
52        impl_as_vertex_slice!($vertex);
53    };
54}
55
56impl_as_vertex! {
57    impl From<(usize, Option<usize>, Option<usize>)> for Vertex {
58        fn from(tuple: (usize, Option<usize>, Option<usize>)) -> Vertex {
59            Vertex {
60                pos: tuple.0,
61                uv: tuple.1,
62                nor: tuple.2,
63            }
64        }
65    }
66}
67
68impl_as_vertex! {
69    impl From<[usize; 3]> for Vertex {
70        fn from(arr: [usize; 3]) -> Vertex {
71            Vertex {
72                pos: arr[0],
73                uv: Some(arr[1]),
74                nor: Some(arr[2]),
75            }
76        }
77    }
78}
79
80impl_as_vertex! {
81    impl From<usize> for Vertex {
82        fn from(idx: usize) -> Vertex {
83            Vertex {
84                pos: idx,
85                uv: None,
86                nor: None,
87            }
88        }
89    }
90}
91
92impl<T: AsVertexSlice> FromIterator<T> for Faces {
93    #[inline(always)]
94    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Faces {
95        let mut faces = Faces::default();
96        faces.extend(iter);
97        faces
98    }
99}
100
101impl<S: AsRef<[usize]>> FromIterator<S> for Faces<usize> {
102    #[inline(always)]
103    fn from_iter<I: IntoIterator<Item = S>>(iter: I) -> Faces<usize> {
104        let mut faces = Faces::default();
105        faces.extend(iter);
106        faces
107    }
108}
109
110#[test]
111fn faces_from_iter() {
112    let slice: &[&[[usize; 3]]] = &[
113        &[[0, 0, 0], [1, 1, 1], [2, 2, 2]],
114        &[[0, 0, 0], [2, 2, 2], [3, 3, 3]],
115        &[[0, 0, 0], [4, 4, 4], [5, 5, 5], [1, 1, 1]],
116    ];
117    let _faces = Faces::from_iter(slice);
118}
119
120impl<V: Copy> Faces<V> {
121    /// Extends faces by an iterator.
122    #[inline(always)]
123    pub fn extend<U: Copy + Into<V>, T: AsRef<[U]>, I: IntoIterator<Item = T>>(&mut self, iter: I) {
124        iter.into_iter().for_each(|face| self.push(face))
125    }
126
127    /// Creates faces of a polygon mesh by the vectors of triangle and quadrangle.
128    /// # Examples
129    /// ```
130    /// // Creates faces consisis only triangles.
131    /// use truck_polymesh::*;
132    /// let tri_faces: Vec<[StandardVertex; 3]> = vec![
133    ///     [[0, 0, 0].into(), [1, 1, 1].into(), [2, 2, 2].into()],
134    ///     [[0, 0, 0].into(), [2, 2, 2].into(), [3, 3, 3].into()],
135    /// ];
136    /// let faces = Faces::from_tri_and_quad_faces(tri_faces, Vec::new());
137    /// ```
138    #[inline(always)]
139    pub const fn from_tri_and_quad_faces(tri_faces: Vec<[V; 3]>, quad_faces: Vec<[V; 4]>) -> Self {
140        Faces {
141            tri_faces,
142            quad_faces,
143            other_faces: Vec::new(),
144        }
145    }
146
147    /// Push a face to the faces.
148    ///
149    /// If `face.len() < 3`, the face is ignored with warning.
150    /// # Examples
151    /// ```
152    /// use truck_polymesh::*;
153    /// let mut faces = Faces::<StandardVertex>::default(); // empty faces
154    /// faces.push(&[[0, 0, 0], [1, 1, 1], [2, 2, 2]]);
155    /// faces.push(&[[3, 3, 3], [0, 0, 0], [2, 2, 2]]);
156    /// faces.push(&[[0, 0, 0], [4, 4, 4], [5, 5, 5], [1, 1, 1]]);
157    /// faces.push(&[[100, 1000, 10]]); // Wargning: ignored one vertex "face"
158    /// ```
159    #[inline(always)]
160    pub fn push<U: Copy + Into<V>, T: AsRef<[U]>>(&mut self, face: T) {
161        let face = face.as_ref();
162        match face.len() {
163            0 => {}
164            1 => {}
165            2 => {}
166            3 => self
167                .tri_faces
168                .push([face[0].into(), face[1].into(), face[2].into()]),
169            4 => self.quad_faces.push([
170                face[0].into(),
171                face[1].into(),
172                face[2].into(),
173                face[3].into(),
174            ]),
175            _ => self
176                .other_faces
177                .push(Vec::from_iter(face.iter().map(|v| (*v).into()))),
178        }
179    }
180
181    /// Returns the vector of triangles.
182    #[inline(always)]
183    pub const fn tri_faces(&self) -> &Vec<[V; 3]> { &self.tri_faces }
184
185    /// Returns the mutable slice of triangles.
186    #[inline(always)]
187    pub fn tri_faces_mut(&mut self) -> &mut [[V; 3]] { &mut self.tri_faces }
188
189    /// Returns the vector of quadrangles.
190    #[inline(always)]
191    pub const fn quad_faces(&self) -> &Vec<[V; 4]> { &self.quad_faces }
192
193    /// Returns the mutable slice of quadrangles.
194    #[inline(always)]
195    pub fn quad_faces_mut(&mut self) -> &mut [[V; 4]] { &mut self.quad_faces }
196
197    /// Returns the vector of n-gons (n > 4).
198    #[inline(always)]
199    pub const fn other_faces(&self) -> &Vec<Vec<V>> { &self.other_faces }
200
201    /// Returns the mutable iterator of n-gons (n > 4).
202    #[inline(always)]
203    pub fn other_faces_mut(&mut self) -> impl Iterator<Item = &mut [V]> {
204        self.other_faces.iter_mut().map(|face| face.as_mut())
205    }
206
207    /// Returns the iterator of the slice.
208    ///
209    /// By the internal optimization, this iterator does not runs in the simple order
210    /// in which they are registered, but runs order: triangle, square, and the others.
211    /// # Examples
212    /// ```
213    /// use truck_polymesh::*;
214    /// let slice: &[&[usize]] = &[
215    ///     &[0, 1, 2],
216    ///     &[0, 4, 5, 1],
217    ///     &[1, 2, 6, 7, 8, 9],
218    ///     &[0, 2, 3],
219    /// ];
220    /// let faces = Faces::<usize>::from_iter(slice);
221    /// let mut iter = faces.face_iter();
222    /// assert_eq!(iter.next(), Some([0, 1, 2].as_ref()));
223    /// assert_eq!(iter.next(), Some([0, 2, 3].as_ref()));
224    /// assert_eq!(iter.next(), Some([0, 4, 5, 1].as_ref()));
225    /// assert_eq!(iter.next(), Some([1, 2, 6, 7, 8, 9].as_ref()));
226    /// assert_eq!(iter.next(), None);
227    /// ```
228    #[inline(always)]
229    pub fn face_iter(&self) -> impl Iterator<Item = &[V]> {
230        self.tri_faces
231            .iter()
232            .map(|v| v.as_ref())
233            .chain(self.quad_faces.iter().map(|v| v.as_ref()))
234            .chain(self.other_faces.iter().map(|v| v.as_ref()))
235    }
236
237    /// Returns the iterator of the slice.
238    ///
239    /// By the internal optimization, this iterator does not runs in the simple order
240    /// in which they are registered, but runs order: triangle, square, and the others.
241    /// cf: [`Faces:face_iter`](./struct.Faces.html#method.face_iter)
242    #[inline(always)]
243    pub fn face_iter_mut(&mut self) -> impl Iterator<Item = &mut [V]> {
244        self.tri_faces
245            .iter_mut()
246            .map(|v| v.as_mut())
247            .chain(self.quad_faces.iter_mut().map(|v| v.as_mut()))
248            .chain(self.other_faces.iter_mut().map(|v| v.as_mut()))
249    }
250
251    /// Returns true if the faces is empty.
252    #[inline(always)]
253    pub fn is_empty(&self) -> bool { self.len() == 0 }
254
255    /// Returns the number of faces.
256    #[inline(always)]
257    pub fn len(&self) -> usize {
258        self.tri_faces.len() + self.quad_faces.len() + self.other_faces.len()
259    }
260
261    /// Merges `other` into `self`.
262    #[inline(always)]
263    pub fn naive_concat(&mut self, other: Self) {
264        self.tri_faces.extend(other.tri_faces);
265        self.quad_faces.extend(other.quad_faces);
266        self.other_faces.extend(other.other_faces);
267    }
268
269    #[inline(always)]
270    pub(super) fn is_compatible(&self, attrs: &impl Attributes<V>) -> Result<(), Error<V>>
271    where V: std::fmt::Debug {
272        self.face_iter()
273            .flatten()
274            .try_for_each(|v| match attrs.get(*v) {
275                Some(_) => Ok(()),
276                None => Err(Error::OutOfRange(*v)),
277            })
278    }
279
280    /// Returns iterator with triangulation faces
281    ///
282    /// # Examples
283    /// ```
284    /// use truck_polymesh::*;
285    /// let slice: &[&[usize]] = &[
286    ///     &[0, 1, 2],
287    ///     &[0, 4, 5, 1],
288    ///     &[1, 2, 6, 7, 8, 9],
289    ///     &[1, 2, 4, 3],
290    ///     &[0, 2, 3],
291    /// ];
292    /// let faces = Faces::<usize>::from_iter(slice);
293    /// let mut iter = faces.triangle_iter();
294    /// assert_eq!(iter.len(), 10);
295    /// assert_eq!(iter.next(), Some([0, 1, 2]));
296    /// assert_eq!(iter.next(), Some([0, 2, 3]));
297    /// assert_eq!(iter.next(), Some([0, 4, 5]));
298    /// assert_eq!(iter.next(), Some([0, 5, 1]));
299    /// assert_eq!(iter.next(), Some([1, 2, 4]));
300    /// assert_eq!(iter.next(), Some([1, 4, 3]));
301    /// assert_eq!(iter.next(), Some([1, 2, 6]));
302    /// assert_eq!(iter.next(), Some([1, 6, 7]));
303    /// assert_eq!(iter.next(), Some([1, 7, 8]));
304    /// assert_eq!(iter.next(), Some([1, 8, 9]));
305    /// assert_eq!(iter.len(), 0);
306    /// assert_eq!(iter.next(), None);
307    /// ```
308    #[inline(always)]
309    pub fn triangle_iter(&self) -> TriangleIterator<'_, V> {
310        let len = self.face_iter().fold(0, |sum, face| sum + face.len() - 2);
311        TriangleIterator {
312            tri_faces: self.tri_faces.iter(),
313            quad_faces: self.quad_faces.iter(),
314            other_faces: self.other_faces.iter(),
315            current_face: None,
316            current_vertex: 0,
317            len,
318        }
319    }
320}
321
322impl<V> Default for Faces<V> {
323    fn default() -> Self {
324        Self {
325            tri_faces: Vec::new(),
326            quad_faces: Vec::new(),
327            other_faces: Vec::new(),
328        }
329    }
330}
331
332impl<V> std::ops::Index<usize> for Faces<V> {
333    type Output = [V];
334    fn index(&self, idx: usize) -> &Self::Output {
335        if idx < self.tri_faces.len() {
336            &self.tri_faces[idx]
337        } else if idx < self.tri_faces.len() + self.quad_faces.len() {
338            &self.quad_faces[idx - self.tri_faces.len()]
339        } else {
340            &self.other_faces[idx - self.tri_faces.len() - self.quad_faces.len()]
341        }
342    }
343}
344
345impl<V: Copy> Invertible for Faces<V> {
346    #[inline(always)]
347    fn invert(&mut self) { self.face_iter_mut().for_each(|f| f.reverse()); }
348    #[inline(always)]
349    fn inverse(&self) -> Self {
350        let tri_faces: Vec<_> = self
351            .tri_faces
352            .iter()
353            .map(|face| [face[2], face[1], face[0]])
354            .collect();
355        let quad_faces: Vec<_> = self
356            .quad_faces
357            .iter()
358            .map(|face| [face[3], face[2], face[1], face[0]])
359            .collect();
360        let other_faces: Vec<_> = self
361            .other_faces
362            .iter()
363            .map(|face| face.iter().rev().map(Clone::clone).collect())
364            .collect();
365        Faces {
366            tri_faces,
367            quad_faces,
368            other_faces,
369        }
370    }
371}
372
373impl std::ops::IndexMut<usize> for Faces {
374    fn index_mut(&mut self, idx: usize) -> &mut Self::Output {
375        if idx < self.tri_faces.len() {
376            &mut self.tri_faces[idx]
377        } else if idx < self.tri_faces.len() + self.quad_faces.len() {
378            &mut self.quad_faces[idx - self.tri_faces.len()]
379        } else {
380            &mut self.other_faces[idx - self.tri_faces.len() - self.quad_faces.len()]
381        }
382    }
383}
384
385/// iterator run on faces as the set of triangle.
386#[derive(Clone, Debug)]
387pub struct TriangleIterator<'a, V> {
388    tri_faces: std::slice::Iter<'a, [V; 3]>,
389    quad_faces: std::slice::Iter<'a, [V; 4]>,
390    other_faces: std::slice::Iter<'a, Vec<V>>,
391    current_face: Option<&'a [V]>,
392    current_vertex: usize,
393    len: usize,
394}
395
396impl<'a, V: Copy> Iterator for TriangleIterator<'a, V> {
397    type Item = [V; 3];
398    fn next(&mut self) -> Option<[V; 3]> {
399        let TriangleIterator {
400            tri_faces,
401            quad_faces,
402            other_faces,
403            current_face,
404            current_vertex,
405            len,
406        } = self;
407        if *len == 0 {
408            return None;
409        }
410        *len -= 1;
411        if let Some(face) = tri_faces.next() {
412            Some(*face)
413        } else {
414            if current_face.is_none() {
415                *current_face = quad_faces
416                    .next()
417                    .map(AsRef::as_ref)
418                    .or_else(|| other_faces.next().map(AsRef::as_ref));
419            }
420            let face = current_face.unwrap();
421            let res = [
422                face[0],
423                face[*current_vertex + 1],
424                face[*current_vertex + 2],
425            ];
426            *current_vertex += 1;
427            if current_face.unwrap().len() == *current_vertex + 2 {
428                *current_face = None;
429                *current_vertex = 0;
430            }
431            Some(res)
432        }
433    }
434    #[inline(always)]
435    fn size_hint(&self) -> (usize, Option<usize>) { (self.len, Some(self.len)) }
436}
437
438impl<'a, V: Copy> ExactSizeIterator for TriangleIterator<'a, V> {}