fbxcel_dom/v7400/data/mesh/
triangle_vertex_index.rs

1//! Triangle vertex index.
2
3use mint::Point3;
4
5use crate::v7400::data::mesh::{
6    ControlPointIndex, PolygonIndex, PolygonVertex, PolygonVertexIndex, PolygonVertices,
7};
8
9/// Triange vertex index.
10#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
11pub struct TriangleVertexIndex(usize);
12
13impl TriangleVertexIndex {
14    /// Creates a new `TriangleVertexIndex`.
15    pub(crate) fn new(i: usize) -> Self {
16        Self(i)
17    }
18
19    /// Returns the triange vertex index.
20    pub fn to_usize(self) -> usize {
21        self.0
22    }
23
24    /// Returns the triange vertex index.
25    #[deprecated(since = "0.0.3", note = "Renamed to `to_usize`")]
26    pub fn get(self) -> usize {
27        self.to_usize()
28    }
29
30    /// Returns triangle index.
31    pub fn triangle_index(self) -> TriangleIndex {
32        TriangleIndex::new(self.0 / 3)
33    }
34}
35
36/// Triangle vertices (this is arary of control point indices).
37///
38/// "Triangle vertex" means "index of control point".
39#[derive(Debug, Clone)]
40pub struct TriangleVertices<'a> {
41    /// Source polygon vertices which can contain non-triangles.
42    polygon_vertices: PolygonVertices<'a>,
43    /// A map from triangle vertex to polygon vertex index.
44    tri_pv_indices: Vec<PolygonVertexIndex>,
45    /// A map from triangle index to polygon index.
46    tri_poly_indices: Vec<PolygonIndex>,
47}
48
49impl<'a> TriangleVertices<'a> {
50    /// Creates a new `TriangleVertices`.
51    pub(crate) fn new(
52        polygon_vertices: PolygonVertices<'a>,
53        tri_pv_indices: Vec<PolygonVertexIndex>,
54        tri_poly_indices: Vec<PolygonIndex>,
55    ) -> Self {
56        Self {
57            polygon_vertices,
58            tri_pv_indices,
59            tri_poly_indices,
60        }
61    }
62
63    /// Returns underlying polygon vertices.
64    pub fn polygon_vertices(&self) -> PolygonVertices<'a> {
65        self.polygon_vertices
66    }
67
68    /// Returns polygon vertex index corresponding to the given triangle vertex.
69    pub fn polygon_vertex_index(&self, tri_vi: TriangleVertexIndex) -> Option<PolygonVertexIndex> {
70        self.tri_pv_indices.get(tri_vi.to_usize()).cloned()
71    }
72
73    /// Returns polygon vertex corresponding to the given triangle vertex.
74    pub fn polygon_vertex(&self, i: impl Into<IntoPvWithTriVerts>) -> Option<PolygonVertex> {
75        i.into().polygon_vertex(self)
76    }
77
78    /// Returns control point index corresponding to the given triangle vertex.
79    pub fn control_point_index(
80        &self,
81        i: impl Into<IntoCpiWithTriVerts>,
82    ) -> Option<ControlPointIndex> {
83        i.into().control_point_index(self)
84    }
85
86    /// Returns control point corresponding to the given triangle vertex.
87    pub fn control_point(&self, i: impl Into<IntoCpiWithTriVerts>) -> Option<Point3<f64>> {
88        self.control_point_index(i.into())
89            .and_then(|cpi| self.polygon_vertices.control_point(cpi))
90    }
91
92    /// Returns the number of triangle vertices.
93    pub fn len(&self) -> usize {
94        self.tri_pv_indices.len()
95    }
96
97    /// Returns whether or not there are no triangle vertices.
98    pub fn is_empty(&self) -> bool {
99        self.tri_pv_indices.is_empty()
100    }
101
102    /// Returns an iterator of control point indices.
103    pub fn iter_control_point_indices(
104        &self,
105    ) -> impl Iterator<Item = Option<ControlPointIndex>> + '_ {
106        (0..self.len())
107            .map(TriangleVertexIndex::new)
108            .map(move |tri_vi| self.control_point_index(tri_vi))
109    }
110
111    /// Returns polygon index for the given triangle index.
112    pub fn polygon_index(&self, tri_i: TriangleIndex) -> Option<PolygonIndex> {
113        self.tri_poly_indices.get(tri_i.to_usize()).cloned()
114    }
115
116    /// Returns an iterator of triangle vertex indices.
117    pub fn triangle_vertex_indices(&self) -> impl Iterator<Item = TriangleVertexIndex> {
118        (0..self.len()).map(TriangleVertexIndex::new)
119    }
120}
121
122/// Triangle index.
123#[derive(Debug, Clone, Copy)]
124pub struct TriangleIndex(usize);
125
126impl TriangleIndex {
127    /// Creates a new `TriangleIndex`.
128    fn new(v: usize) -> Self {
129        Self(v)
130    }
131
132    /// Returns the index.
133    pub fn to_usize(self) -> usize {
134        self.0
135    }
136
137    /// Returns the index.
138    #[deprecated(since = "0.0.3", note = "Renamed to `to_usize`")]
139    pub fn get(self) -> usize {
140        self.to_usize()
141    }
142}
143
144/// A type to contain a value convertible into polygon vertex.
145///
146/// This is used for [`TriangleVertices::polygon_vertex`], but not intended to
147/// be used directly by users.
148///
149/// [`TriangleVertices::polygon_vertex`]:
150/// struct.TriangleVertices.html#method.polygon_vertex
151#[derive(Debug, Clone, Copy)]
152#[non_exhaustive]
153pub enum IntoPvWithTriVerts {
154    /// Polygon vertex.
155    PolygonVertex(PolygonVertex),
156    /// Polygon vertex index.
157    PolygonVertexIndex(PolygonVertexIndex),
158    /// Triangle vertex index.
159    TriangleVertexIndex(TriangleVertexIndex),
160}
161
162impl IntoPvWithTriVerts {
163    /// Returns polygon vertex.
164    fn polygon_vertex(&self, triangle_vertices: &TriangleVertices<'_>) -> Option<PolygonVertex> {
165        match *self {
166            IntoPvWithTriVerts::PolygonVertex(pv) => Some(pv),
167            IntoPvWithTriVerts::PolygonVertexIndex(pvi) => {
168                triangle_vertices.polygon_vertices.polygon_vertex(pvi)
169            }
170            IntoPvWithTriVerts::TriangleVertexIndex(tri_vi) => triangle_vertices
171                .polygon_vertex_index(tri_vi)
172                .and_then(|pvi| triangle_vertices.polygon_vertices.polygon_vertex(pvi)),
173        }
174    }
175}
176
177impl From<PolygonVertex> for IntoPvWithTriVerts {
178    fn from(i: PolygonVertex) -> Self {
179        IntoPvWithTriVerts::PolygonVertex(i)
180    }
181}
182
183impl From<&PolygonVertex> for IntoPvWithTriVerts {
184    fn from(i: &PolygonVertex) -> Self {
185        IntoPvWithTriVerts::PolygonVertex(*i)
186    }
187}
188
189impl From<PolygonVertexIndex> for IntoPvWithTriVerts {
190    fn from(i: PolygonVertexIndex) -> Self {
191        IntoPvWithTriVerts::PolygonVertexIndex(i)
192    }
193}
194
195impl From<&PolygonVertexIndex> for IntoPvWithTriVerts {
196    fn from(i: &PolygonVertexIndex) -> Self {
197        IntoPvWithTriVerts::PolygonVertexIndex(*i)
198    }
199}
200
201impl From<TriangleVertexIndex> for IntoPvWithTriVerts {
202    fn from(i: TriangleVertexIndex) -> Self {
203        IntoPvWithTriVerts::TriangleVertexIndex(i)
204    }
205}
206
207impl From<&TriangleVertexIndex> for IntoPvWithTriVerts {
208    fn from(i: &TriangleVertexIndex) -> Self {
209        IntoPvWithTriVerts::TriangleVertexIndex(*i)
210    }
211}
212
213/// A type to contain a value convertible into control point index.
214///
215/// This is used for [`TriangleVertices::control_point_index`] and
216/// [`TriangleVertices::control_point`], but not intended to be used directly by
217/// users.
218///
219/// [`TriangleVertices::control_point_index`]:
220/// struct.TriangleVertices.html#method.control_point_index
221/// [`TriangleVertices::control_point`]:
222/// struct.TriangleVertices.html#method.control_point
223#[derive(Debug, Clone, Copy)]
224#[non_exhaustive]
225pub enum IntoCpiWithTriVerts {
226    /// Control point index.
227    ControlPointIndex(ControlPointIndex),
228    /// A value which is convertible into polygon vertex.
229    IntoPolygonVertex(IntoPvWithTriVerts),
230}
231
232impl IntoCpiWithTriVerts {
233    /// Returns control point index.
234    fn control_point_index(
235        &self,
236        triangle_vertices: &TriangleVertices<'_>,
237    ) -> Option<ControlPointIndex> {
238        match *self {
239            IntoCpiWithTriVerts::ControlPointIndex(cpi) => Some(cpi),
240            IntoCpiWithTriVerts::IntoPolygonVertex(into_pv) => {
241                into_pv.polygon_vertex(triangle_vertices).map(Into::into)
242            }
243        }
244    }
245}
246
247impl<T: Into<IntoPvWithTriVerts>> From<T> for IntoCpiWithTriVerts {
248    fn from(i: T) -> Self {
249        IntoCpiWithTriVerts::IntoPolygonVertex(i.into())
250    }
251}
252
253impl From<ControlPointIndex> for IntoCpiWithTriVerts {
254    fn from(i: ControlPointIndex) -> Self {
255        IntoCpiWithTriVerts::ControlPointIndex(i)
256    }
257}
258
259impl From<&ControlPointIndex> for IntoCpiWithTriVerts {
260    fn from(i: &ControlPointIndex) -> Self {
261        IntoCpiWithTriVerts::ControlPointIndex(*i)
262    }
263}