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