use crate::mesh::*;
impl Mesh {
pub fn is_closed(&self) -> bool {
for halfedge_id in self.edge_iter() {
if self.is_edge_on_boundary(halfedge_id) {
return false;
}
}
true
}
pub fn connecting_edge(
&self,
vertex_id1: VertexID,
vertex_id2: VertexID,
) -> Option<HalfEdgeID> {
for halfedge_id in self.vertex_halfedge_iter(vertex_id1) {
if self.walker_from_halfedge(halfedge_id).vertex_id().unwrap() == vertex_id2 {
return Some(halfedge_id);
}
}
None
}
pub fn is_vertex_on_boundary(&self, vertex_id: VertexID) -> bool {
for halfedge_id in self.vertex_halfedge_iter(vertex_id) {
let mut walker = self.walker_from_halfedge(halfedge_id);
if walker.face_id().is_none() || walker.as_twin().face_id().is_none() {
return true;
}
}
false
}
pub fn is_edge_on_boundary(&self, halfedge_id: HalfEdgeID) -> bool {
let mut walker = self.walker_from_halfedge(halfedge_id);
walker.face_id().is_none() || walker.as_twin().face_id().is_none()
}
pub fn edge_vertices(&self, halfedge_id: HalfEdgeID) -> (VertexID, VertexID) {
let mut walker = self.walker_from_halfedge(halfedge_id);
let v1 = walker.vertex_id().unwrap();
let v2 = walker.as_twin().vertex_id().unwrap();
(v1, v2)
}
pub fn ordered_edge_vertices(&self, halfedge_id: HalfEdgeID) -> (VertexID, VertexID) {
let mut walker = self.walker_from_halfedge(halfedge_id);
let v1 = walker.vertex_id().unwrap();
let v2 = walker.as_twin().vertex_id().unwrap();
if v1 < v2 {
(v1, v2)
} else {
(v2, v1)
}
}
pub fn face_vertices(&self, face_id: FaceID) -> (VertexID, VertexID, VertexID) {
let mut walker = self.walker_from_face(face_id);
let v1 = walker.vertex_id().unwrap();
walker.as_next();
let v2 = walker.vertex_id().unwrap();
walker.as_next();
let v3 = walker.vertex_id().unwrap();
(v1, v2, v3)
}
pub fn ordered_face_vertices(&self, face_id: FaceID) -> (VertexID, VertexID, VertexID) {
let mut walker = self.walker_from_face(face_id);
let v1 = walker.vertex_id().unwrap();
walker.as_next();
let v2 = walker.vertex_id().unwrap();
walker.as_next();
let v3 = walker.vertex_id().unwrap();
if v1 < v2 {
if v2 < v3 {
(v1, v2, v3)
} else {
if v1 < v3 {
(v1, v3, v2)
} else {
(v3, v1, v2)
}
}
} else {
if v1 < v3 {
(v2, v1, v3)
} else {
if v2 < v3 {
(v2, v3, v1)
} else {
(v3, v2, v1)
}
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use three_d_asset::TriMesh;
#[test]
fn test_is_closed_when_not_closed() {
let mesh = crate::test_utility::subdivided_triangle();
assert!(!mesh.is_closed());
}
#[test]
fn test_is_closed_when_closed() {
let mesh: Mesh = TriMesh::sphere(4).into();
assert!(mesh.is_closed());
}
}