honeycomb_kernels/utils/
routines.rs

1use honeycomb_core::{
2    cmap::{CMap2, DartIdType, OrbitPolicy, VertexIdType},
3    geometry::{CoordsFloat, Vertex2},
4    stm::{StmClosureResult, Transaction, retry},
5};
6use smallvec::SmallVec;
7
8/// Check if all faces incident to the vertex have the same orientation.
9///
10/// Note that this function expects the incident faces to be triangles.
11///
12/// # Errors
13///
14/// This method is meant to be called in a context where the returned `Result` is used to
15/// validate the transaction passed as argument. Errors should not be processed manually,
16/// only processed via the `?` operator.
17pub fn is_orbit_orientation_consistent<T: CoordsFloat>(
18    t: &mut Transaction,
19    map: &CMap2<T>,
20    vid: VertexIdType,
21) -> StmClosureResult<bool> {
22    if let Some(new_v) = map.read_vertex(t, vid)? {
23        let mut tmp: SmallVec<DartIdType, 10> = SmallVec::new();
24        for d in map.orbit_transac(t, OrbitPolicy::Vertex, vid) {
25            tmp.push(d?);
26        }
27
28        let ref_crossp = {
29            let d = tmp[0];
30            let b1d = map.beta_transac::<1>(t, d)?;
31            let b1b1d = map.beta_transac::<1>(t, b1d)?;
32            let vid1 = map.vertex_id_transac(t, b1d)?;
33            let vid2 = map.vertex_id_transac(t, b1b1d)?;
34            let v1 = if let Some(v) = map.read_vertex(t, vid1)? {
35                v
36            } else {
37                retry()?
38            };
39            let v2 = if let Some(v) = map.read_vertex(t, vid2)? {
40                v
41            } else {
42                retry()?
43            };
44
45            Vertex2::cross_product_from_vertices(&new_v, &v1, &v2)
46        };
47        if ref_crossp.is_zero() {
48            return Ok(false);
49        }
50
51        let ref_sign = ref_crossp.signum();
52        for &d in &tmp[1..] {
53            let b1d = map.beta_transac::<1>(t, d)?;
54            let b1b1d = map.beta_transac::<1>(t, b1d)?;
55            let vid1 = map.vertex_id_transac(t, b1d)?;
56            let vid2 = map.vertex_id_transac(t, b1b1d)?;
57            let v1 = if let Some(v) = map.read_vertex(t, vid1)? {
58                v
59            } else {
60                retry()?
61            };
62            let v2 = if let Some(v) = map.read_vertex(t, vid2)? {
63                v
64            } else {
65                retry()?
66            };
67
68            let crossp = Vertex2::cross_product_from_vertices(&new_v, &v1, &v2);
69
70            if ref_sign != crossp.signum() || crossp.is_zero() {
71                return Ok(false);
72            }
73        }
74    } else {
75        retry()?;
76    }
77
78    Ok(true)
79}