use honeycomb_core::{
cmap::{CMap2, DartIdType, OrbitPolicy, VertexIdType},
geometry::{CoordsFloat, Vertex2},
stm::{StmClosureResult, Transaction, unwrap_or_retry},
};
use smallvec::SmallVec;
pub fn is_orbit_orientation_consistent<T: CoordsFloat>(
t: &mut Transaction,
map: &CMap2<T>,
vid: VertexIdType,
) -> StmClosureResult<bool> {
let mut tmp: SmallVec<DartIdType, 10> = SmallVec::new();
for d in map.orbit_tx(t, OrbitPolicy::Vertex, vid) {
tmp.push(d?);
}
let new_v = unwrap_or_retry(map.read_vertex_tx(t, vid)?)?;
let ref_crossp = {
let d = tmp[0];
let b1d = map.beta_tx::<1>(t, d)?;
let b1b1d = map.beta_tx::<1>(t, b1d)?;
let vid1 = map.vertex_id_tx(t, b1d)?;
let vid2 = map.vertex_id_tx(t, b1b1d)?;
let v1 = unwrap_or_retry(map.read_vertex_tx(t, vid1)?)?;
let v2 = unwrap_or_retry(map.read_vertex_tx(t, vid2)?)?;
Vertex2::cross_product_from_vertices(&new_v, &v1, &v2)
};
if ref_crossp.is_zero() {
return Ok(false);
}
let ref_sign = ref_crossp.signum();
for &d in &tmp[1..] {
let b1d = map.beta_tx::<1>(t, d)?;
let b1b1d = map.beta_tx::<1>(t, b1d)?;
let vid1 = map.vertex_id_tx(t, b1d)?;
let vid2 = map.vertex_id_tx(t, b1b1d)?;
let v1 = unwrap_or_retry(map.read_vertex_tx(t, vid1)?)?;
let v2 = unwrap_or_retry(map.read_vertex_tx(t, vid2)?)?;
let crossp = Vertex2::cross_product_from_vertices(&new_v, &v1, &v2);
if ref_sign != crossp.signum() || crossp.is_zero() {
return Ok(false);
}
}
Ok(true)
}