fbxcel_dom/v7400/data/mesh/
polygon_vertex_index.rs1use anyhow::{bail, Error};
4use mint::Point3;
5
6use crate::v7400::data::mesh::{ControlPointIndex, ControlPoints, TriangleVertices};
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
12pub struct PolygonVertexIndex(usize);
13
14impl PolygonVertexIndex {
15 pub(crate) fn new(v: usize) -> Self {
17 Self(v)
18 }
19
20 pub(crate) fn to_usize(self) -> usize {
22 self.0
23 }
24}
25
26#[derive(Debug, Clone, Copy)]
28pub struct RawPolygonVertices<'a> {
29 data: &'a [i32],
31}
32
33impl<'a> RawPolygonVertices<'a> {
34 pub(crate) fn new(data: &'a [i32]) -> Self {
36 Self { data }
37 }
38
39 pub(crate) fn get(&self, pvi: PolygonVertexIndex) -> Option<PolygonVertex> {
41 self.data
42 .get(pvi.to_usize())
43 .cloned()
44 .map(PolygonVertex::new)
45 }
46}
47
48#[derive(Debug, Clone, Copy)]
50pub struct PolygonVertices<'a> {
51 control_points: ControlPoints<'a>,
53 polygon_vertices: RawPolygonVertices<'a>,
55}
56
57impl<'a> PolygonVertices<'a> {
58 pub(crate) fn new(
60 control_points: ControlPoints<'a>,
61 polygon_vertices: RawPolygonVertices<'a>,
62 ) -> Self {
63 Self {
64 control_points,
65 polygon_vertices,
66 }
67 }
68
69 pub fn raw_control_points(&self) -> anyhow::Result<impl Iterator<Item = Point3<f64>> + 'a> {
71 self.control_points.iter()
72 }
73
74 pub fn raw_polygon_vertices(&self) -> &[i32] {
76 self.polygon_vertices.data
77 }
78
79 pub fn polygon_vertex(&self, pvi: PolygonVertexIndex) -> Option<PolygonVertex> {
81 self.polygon_vertices.get(pvi)
82 }
83
84 pub fn control_point(&self, i: impl Into<IntoCpiWithPolyVerts>) -> Option<Point3<f64>> {
86 i.into()
87 .control_point_index(self)
88 .and_then(|cpi| self.control_points.get(cpi))
89 }
90
91 pub fn triangulate_each<F>(&self, mut triangulator: F) -> Result<TriangleVertices<'a>, Error>
93 where
94 F: FnMut(
95 &Self,
96 &[PolygonVertexIndex],
97 &mut Vec<[PolygonVertexIndex; 3]>,
98 ) -> Result<(), Error>
99 + Copy,
100 {
101 let len = self.polygon_vertices.data.len();
102 let mut tri_pv_indices = Vec::new();
103 let mut tri_poly_indices = Vec::new();
104
105 let mut current_poly_index = 0;
106 let mut current_poly_pvis = Vec::new();
107 let mut pv_index_start = 0;
108 let mut tri_results = Vec::new();
109 while pv_index_start < len {
110 current_poly_pvis.clear();
111 tri_results.clear();
112
113 let pv_index_next_start = match self.polygon_vertices.data[pv_index_start..]
114 .iter()
115 .cloned()
116 .map(PolygonVertex::new)
117 .position(PolygonVertex::is_end)
118 {
119 Some(v) => pv_index_start + v + 1,
120 None => bail!(
121 "Incomplete polygon found: pv_index_start={:?}, len={}",
122 pv_index_start,
123 len
124 ),
125 };
126 current_poly_pvis
127 .extend((pv_index_start..pv_index_next_start).map(PolygonVertexIndex::new));
128 triangulator(self, ¤t_poly_pvis, &mut tri_results)?;
129 tri_pv_indices.extend(tri_results.iter().flatten());
130 tri_poly_indices
131 .extend((0..tri_results.len()).map(|_| PolygonIndex::new(current_poly_index)));
132
133 pv_index_start = pv_index_next_start;
134 current_poly_index += 1;
135 }
136
137 Ok(TriangleVertices::new(
138 *self,
139 tri_pv_indices,
140 tri_poly_indices,
141 ))
142 }
143}
144
145#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
149pub struct PolygonVertex(i32);
150
151impl PolygonVertex {
152 pub fn new(i: i32) -> Self {
154 Self(i)
155 }
156
157 pub fn is_end(self) -> bool {
159 self.0 < 0
160 }
161
162 pub fn to_u32(self) -> u32 {
164 if self.0 < 0 {
165 !self.0 as u32
166 } else {
167 self.0 as u32
168 }
169 }
170
171 #[deprecated(since = "0.0.3", note = "Renamed to `to_u32`")]
173 pub fn get_u32(self) -> u32 {
174 self.to_u32()
175 }
176}
177
178impl From<PolygonVertex> for ControlPointIndex {
179 fn from(pv: PolygonVertex) -> Self {
180 Self::new(pv.to_u32())
181 }
182}
183
184impl From<&PolygonVertex> for ControlPointIndex {
185 fn from(pv: &PolygonVertex) -> Self {
186 Self::new(pv.to_u32())
187 }
188}
189
190#[derive(Debug, Clone, Copy)]
192pub struct PolygonIndex(usize);
193
194impl PolygonIndex {
195 fn new(v: usize) -> Self {
197 Self(v)
198 }
199
200 pub fn to_usize(self) -> usize {
202 self.0
203 }
204
205 #[deprecated(since = "0.0.3", note = "Renamed to `to_usize`")]
207 pub fn get(self) -> usize {
208 self.to_usize()
209 }
210}
211
212#[derive(Debug, Clone, Copy)]
220#[non_exhaustive]
221pub enum IntoCpiWithPolyVerts {
222 ControlPointIndex(ControlPointIndex),
224 PolygonVertex(PolygonVertex),
226 PolygonVertexIndex(PolygonVertexIndex),
228}
229
230impl IntoCpiWithPolyVerts {
231 fn control_point_index(
233 &self,
234 polygon_vertices: &PolygonVertices<'_>,
235 ) -> Option<ControlPointIndex> {
236 match *self {
237 IntoCpiWithPolyVerts::ControlPointIndex(cpi) => Some(cpi),
238 IntoCpiWithPolyVerts::PolygonVertex(pv) => Some(pv.into()),
239 IntoCpiWithPolyVerts::PolygonVertexIndex(pvi) => {
240 polygon_vertices.polygon_vertex(pvi).map(Into::into)
241 }
242 }
243 }
244}
245
246impl From<ControlPointIndex> for IntoCpiWithPolyVerts {
247 fn from(i: ControlPointIndex) -> Self {
248 IntoCpiWithPolyVerts::ControlPointIndex(i)
249 }
250}
251
252impl From<&ControlPointIndex> for IntoCpiWithPolyVerts {
253 fn from(i: &ControlPointIndex) -> Self {
254 IntoCpiWithPolyVerts::ControlPointIndex(*i)
255 }
256}
257
258impl From<PolygonVertex> for IntoCpiWithPolyVerts {
259 fn from(i: PolygonVertex) -> Self {
260 IntoCpiWithPolyVerts::PolygonVertex(i)
261 }
262}
263
264impl From<&PolygonVertex> for IntoCpiWithPolyVerts {
265 fn from(i: &PolygonVertex) -> Self {
266 IntoCpiWithPolyVerts::PolygonVertex(*i)
267 }
268}
269
270impl From<PolygonVertexIndex> for IntoCpiWithPolyVerts {
271 fn from(i: PolygonVertexIndex) -> Self {
272 IntoCpiWithPolyVerts::PolygonVertexIndex(i)
273 }
274}
275
276impl From<&PolygonVertexIndex> for IntoCpiWithPolyVerts {
277 fn from(i: &PolygonVertexIndex) -> Self {
278 IntoCpiWithPolyVerts::PolygonVertexIndex(*i)
279 }
280}