parry3d/transformation/convex_hull3/
validation.rs1#[cfg(feature = "std")]
2use super::ConvexHullError;
3use super::TriangleFacet;
4#[cfg(feature = "std")]
5use crate::math::Real;
6#[cfg(feature = "std")]
7use na::Point3;
8
9pub fn check_facet_links(ifacet: usize, facets: &[TriangleFacet]) {
10 let facet = &facets[ifacet];
11
12 for i in 0..3 {
13 assert!(facets[facet.adj[i]].valid);
14 }
15
16 for i in 0..3 {
17 let adj_facet = &facets[facet.adj[i]];
18
19 assert_eq!(adj_facet.adj[facet.indirect_adj_id[i]], ifacet);
20 assert_eq!(adj_facet.indirect_adj_id[facet.indirect_adj_id[i]], i);
21 assert_eq!(
22 adj_facet.first_point_from_edge(facet.indirect_adj_id[i]),
23 facet.second_point_from_edge(i)
24 );
25 assert_eq!(
26 adj_facet.second_point_from_edge(facet.indirect_adj_id[i]),
27 facet.first_point_from_edge(i)
28 );
29 }
30}
31
32#[cfg(feature = "std")]
34pub fn check_convex_hull(
35 points: &[Point3<Real>],
36 triangles: &[[u32; 3]],
37) -> Result<(), ConvexHullError> {
38 use crate::utils::hashmap::{Entry, HashMap};
39 use crate::utils::SortedPair;
40 let mut edges = HashMap::default();
41
42 struct EdgeData {
43 adjacent_triangles: [usize; 2],
44 }
45
46 for i in 0..points.len() {
55 for j in i + 1..points.len() {
56 if points[i] == points[j] {
57 return Err(ConvexHullError::DuplicatePoints(i, j));
58 }
59 }
60 }
61
62 for (itri, tri) in triangles.iter().enumerate() {
63 assert!(tri[0] != tri[1]);
64 assert!(tri[0] != tri[2]);
65 assert!(tri[2] != tri[1]);
66
67 for i in 0..3 {
68 let ivtx1 = tri[i as usize];
69 let ivtx2 = tri[(i as usize + 1) % 3];
70 let edge_key = SortedPair::new(ivtx1, ivtx2);
71
72 match edges.entry(edge_key) {
73 Entry::Vacant(e) => {
74 let _ = e.insert(EdgeData {
75 adjacent_triangles: [itri, usize::MAX],
76 });
77 }
78 Entry::Occupied(mut e) => {
79 if e.get().adjacent_triangles[1] != usize::MAX {
80 return Err(ConvexHullError::TJunction(itri, ivtx1, ivtx2));
81 }
82
83 e.get_mut().adjacent_triangles[1] = itri;
84 }
85 }
86 }
87 }
88
89 for edge in &edges {
90 if edge.1.adjacent_triangles[1] == usize::MAX {
91 return Err(ConvexHullError::UnfinishedTriangle);
92 }
93 }
94
95 assert_eq!(points.len() + triangles.len() - edges.len(), 2);
97
98 Ok(())
99}
100
101