mesh_graph/elements/
face.rs1use glam::Vec3;
2use parry3d::{bounding_volume::Aabb, na::Point3};
3use tracing::{error, instrument};
4
5use crate::{CircularHalfedgesIterator, MeshGraph, error_none};
6
7use super::{FaceId, HalfedgeId, VertexId};
8
9#[derive(Default, Debug, Clone, Copy)]
10#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
11pub struct Face {
12 pub halfedge: HalfedgeId,
15
16 pub index: u32,
18
19 pub id: FaceId,
21}
22
23impl Face {
24 #[instrument(skip(mesh_graph))]
26 pub fn halfedges<'a>(&self, mesh_graph: &'a MeshGraph) -> CircularHalfedgesIterator<'a> {
27 CircularHalfedgesIterator::new(Some(self.halfedge), mesh_graph, |he, mesh_graph| {
28 mesh_graph
29 .halfedges
30 .get(he)
31 .or_else(error_none!("Halfedge not found"))?
32 .next
33 })
34 }
35
36 #[instrument(skip(mesh_graph))]
38 pub fn vertices(&self, mesh_graph: &MeshGraph) -> impl Iterator<Item = VertexId> {
39 self.halfedges(mesh_graph).filter_map(|he| {
40 mesh_graph
41 .halfedges
42 .get(he)
43 .or_else(error_none!("Halfedge not found"))
44 .map(|he| he.end_vertex)
45 })
46 }
47
48 #[instrument(skip(mesh_graph))]
50 pub fn center(&self, mesh_graph: &MeshGraph) -> Vec3 {
51 let mut sum = Vec3::ZERO;
52
53 for vertex in self.vertices(mesh_graph) {
54 if let Some(position) = mesh_graph.positions.get(vertex) {
55 sum += position;
56 } else {
57 error!("Vertex position not found");
58 }
59 }
60
61 sum / 3.0
62 }
63
64 #[instrument(skip(mesh_graph))]
66 pub fn aabb(&self, mesh_graph: &MeshGraph) -> Aabb {
67 Aabb::from_points(self.vertices(mesh_graph).filter_map(|v| {
68 mesh_graph
69 .positions
70 .get(v)
71 .or_else(error_none!("Position not found"))
72 .map(|p| Point3::new(p.x, p.y, p.z))
73 }))
74 }
75}