use std::collections::HashMap;
use ptr::{Ptr, EdgeRc};
use mesh::HalfEdgeMesh;
fn merge_tuple_opt<A, B>(o: (Option<A>, Option<B>)) -> Option<(A, B)> {
match o {
(Some(a), Some(b)) => Some((a, b)),
_ => None
}
}
fn vert_ab_key(e: & EdgeRc) -> Option<(u32, u32)> {
let id_origin = e.borrow().origin.upgrade().map(|o| o.borrow().id);
let id_next_origin = e.borrow().next.upgrade().and_then(|n| n.borrow().origin.upgrade()).map(|o| o.borrow().id);
merge_tuple_opt((id_origin, id_next_origin))
}
fn vert_ba_key(e: & EdgeRc) -> Option<(u32, u32)> { vert_ab_key(e).map(|tuple| (tuple.1, tuple.0)) }
pub fn connect_pairs(mesh: &mut HalfEdgeMesh) -> Result<(), &'static str> {
let mut edge_hash: HashMap<(u32, u32), & EdgeRc> = HashMap::new();
for ref edge in mesh.edges.values() {
match vert_ab_key(edge) {
Some(key) => { edge_hash.insert(key, edge); },
None => { return Err("Could not hash all mesh edges"); }
}
}
for ref edge in mesh.edges.values() {
if !edge.borrow().pair.is_valid() {
if let Some(key) = vert_ba_key(edge) {
match edge_hash.get(& key) {
Some(pair_edge) => {
edge.borrow_mut().take_pair(Ptr::new(pair_edge));
pair_edge.borrow_mut().take_pair(Ptr::new(edge));
},
None => {
return Err("Could not find pair edge");
}
}
} else {
return Err("Could not find reverse hash for mesh edge");
}
}
}
Ok(())
}
pub fn report_connect_err(res: Result<(), &str>) {
if let Err(e) = res {
println!("Error connecting mesh pairs! Mesh is not valid! {}", e);
}
}
pub fn are_edge_pairs_valid(mesh: & HalfEdgeMesh) -> Result<(), &'static str> {
let mut edge_hash: HashMap<(u32, u32), & EdgeRc> = HashMap::new();
for ref edge in mesh.edges.values() {
match vert_ab_key(edge) {
Some(key) => { edge_hash.insert(key, edge); },
None => { return Err("Could not hash all mesh edges"); }
}
}
for ref edge in mesh.edges.values() {
match vert_ba_key(edge) {
Some(key) => {
match edge_hash.get(& key) {
Some(ref pair) => {
if (edge.borrow().pair.upgrade().as_ref() != Some(pair)) ||
(pair.borrow().pair.upgrade().as_ref() != Some(edge)) {
return Err("Pairs don't match");
}
},
None => { return Err("Could not find a pair edge"); }
}
},
None => { return Err("Could not find reverse hash for mesh edge"); }
}
}
Ok(())
}