introduce DirectedEdge

This commit is contained in:
Quaternions 2023-11-10 15:23:28 -08:00
parent 717cf2290d
commit 3cbefbab03

View File

@ -5,6 +5,22 @@ use std::borrow::Cow;
pub struct VertId(usize); pub struct VertId(usize);
#[derive(Debug,Clone,Copy,Hash,Eq,PartialEq)] #[derive(Debug,Clone,Copy,Hash,Eq,PartialEq)]
pub struct EdgeId(usize); pub struct EdgeId(usize);
impl EdgeId{
fn as_directed_edge_id(&self,parity:bool)->DirectedEdgeId{
DirectedEdgeId(self.0|((parity as usize)<<(usize::BITS-1)))
}
}
/// DirectedEdgeId refers to an EdgeId when undirected.
#[derive(Debug,Clone,Copy,Hash,Eq,PartialEq)]
pub struct DirectedEdgeId(usize);
impl DirectedEdgeId{
fn as_edge_id(&self)->EdgeId{
EdgeId(self.0&!(1<<(usize::BITS-1)))
}
fn signum(&self)->isize{
((self.0&(1<<(usize::BITS-1))!=0) as isize)*2-1
}
}
#[derive(Debug,Clone,Copy,Hash,Eq,PartialEq)] #[derive(Debug,Clone,Copy,Hash,Eq,PartialEq)]
pub struct FaceId(usize); pub struct FaceId(usize);
@ -36,7 +52,7 @@ struct EdgeRefs{
} }
struct VertRefs{ struct VertRefs{
faces:Vec<FaceId>, faces:Vec<FaceId>,
edges:Vec<EdgeId>, edges:Vec<DirectedEdgeId>,
} }
pub struct PhysicsMesh{ pub struct PhysicsMesh{
faces:Vec<Face>, faces:Vec<Face>,
@ -48,18 +64,18 @@ pub struct PhysicsMesh{
#[derive(Default,Clone)] #[derive(Default,Clone)]
struct VertRefGuy{ struct VertRefGuy{
edges:std::collections::HashSet<EdgeId>, edges:std::collections::HashSet<DirectedEdgeId>,
faces:std::collections::HashSet<FaceId>, faces:std::collections::HashSet<FaceId>,
} }
#[derive(Clone,Hash,Eq,PartialEq)] #[derive(Clone,Hash,Eq,PartialEq)]
struct EdgeIdGuy([VertId;2]); struct EdgeIdGuy([VertId;2]);
impl EdgeIdGuy{ impl EdgeIdGuy{
fn new(v0:VertId,v1:VertId)->Self{ fn new(v0:VertId,v1:VertId)->(Self,bool){
if v0.0<v1.0{ (if v0.0<v1.0{
Self([v0,v1]) Self([v0,v1])
}else{ }else{
Self([v1,v0]) Self([v1,v0])
} },v0.0<v1.0)
} }
} }
struct EdgeRefGuy([FaceId;2]); struct EdgeRefGuy([FaceId;2]);
@ -92,7 +108,7 @@ impl EdgePool{
impl From<&crate::model::IndexedModel> for PhysicsMesh{ impl From<&crate::model::IndexedModel> for PhysicsMesh{
fn from(indexed_model:&crate::model::IndexedModel)->Self{ fn from(indexed_model:&crate::model::IndexedModel)->Self{
let verts=indexed_model.unique_pos.iter().map(|v|Vert(v.clone())).collect(); let verts=indexed_model.unique_pos.iter().map(|v|Vert(v.clone())).collect();
let mut vert_edges=vec![VertRefGuy::default();indexed_model.unique_pos.len()]; let mut vert_ref_guys=vec![VertRefGuy::default();indexed_model.unique_pos.len()];
let mut edge_pool=EdgePool::default(); let mut edge_pool=EdgePool::default();
let mut face_i=0; let mut face_i=0;
let mut faces=Vec::new(); let mut faces=Vec::new();
@ -114,7 +130,7 @@ impl From<&crate::model::IndexedModel> for PhysicsMesh{
(v0.x()-v1.x())*(v0.y()+v1.y()), (v0.x()-v1.x())*(v0.y()+v1.y()),
); );
//get/create edge and push face into it //get/create edge and push face into it
let edge_id_guy=EdgeIdGuy::new(VertId(vert0_id),VertId(vert1_id)); let (edge_id_guy,is_sorted)=EdgeIdGuy::new(VertId(vert0_id),VertId(vert1_id));
let (edge_ref_guy,edge_id,exists)=edge_pool.push(edge_id_guy); let (edge_ref_guy,edge_id,exists)=edge_pool.push(edge_id_guy);
if exists{ if exists{
edge_ref_guy.push(1,face_id); edge_ref_guy.push(1,face_id);
@ -123,10 +139,10 @@ impl From<&crate::model::IndexedModel> for PhysicsMesh{
} }
//index edges & face into vertices //index edges & face into vertices
{ {
let vert_ref_guy=unsafe{vert_edges.get_unchecked_mut(vert0_id)}; let vert_ref_guy=unsafe{vert_ref_guys.get_unchecked_mut(vert0_id)};
vert_ref_guy.edges.insert(edge_id); vert_ref_guy.edges.insert(edge_id.as_directed_edge_id(!is_sorted));
vert_ref_guy.faces.insert(face_id); vert_ref_guy.faces.insert(face_id);
unsafe{vert_edges.get_unchecked_mut(vert1_id)}.edges.insert(edge_id); unsafe{vert_ref_guys.get_unchecked_mut(vert1_id)}.edges.insert(edge_id.as_directed_edge_id(is_sorted));
} }
//return edge_id //return edge_id
edge_id edge_id
@ -162,7 +178,7 @@ impl From<&crate::model::IndexedModel> for PhysicsMesh{
edge_topology:edge_pool.edge_guys.into_iter().map(|(edge_id_guy,edge_ref_guy)| edge_topology:edge_pool.edge_guys.into_iter().map(|(edge_id_guy,edge_ref_guy)|
EdgeRefs{faces:edge_ref_guy.0,verts:edge_id_guy.0} EdgeRefs{faces:edge_ref_guy.0,verts:edge_id_guy.0}
).collect(), ).collect(),
vert_topology:vert_edges.into_iter().map(|vert_ref_guy| vert_topology:vert_ref_guys.into_iter().map(|vert_ref_guy|
VertRefs{ VertRefs{
edges:vert_ref_guy.edges.into_iter().collect(), edges:vert_ref_guy.edges.into_iter().collect(),
faces:vert_ref_guy.faces.into_iter().collect(), faces:vert_ref_guy.faces.into_iter().collect(),