mesh_graph/
selection.rs

1use hashbrown::HashSet;
2use tracing::{error, instrument};
3
4use super::{FaceId, HalfedgeId, MeshGraph, VertexId};
5
6#[derive(Debug, Clone, Default)]
7#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8pub struct Selection {
9    pub vertices: HashSet<VertexId>,
10    pub halfedges: HashSet<HalfedgeId>,
11    pub faces: HashSet<FaceId>,
12}
13
14impl Selection {
15    pub fn select_all(mesh_graph: &MeshGraph) -> Self {
16        Self {
17            faces: mesh_graph.faces.keys().collect(),
18            ..Default::default()
19        }
20    }
21
22    pub fn resolve_to_halfedges(&self, mesh_graph: &MeshGraph) -> HashSet<HalfedgeId> {
23        let mut halfedges = self.halfedges.clone();
24
25        for face in &self.faces {
26            halfedges.extend(mesh_graph.faces[*face].halfedges(mesh_graph));
27        }
28
29        for vertex in &self.vertices {
30            halfedges.extend(mesh_graph.vertices[*vertex].outgoing_halfedges(mesh_graph));
31        }
32
33        halfedges
34    }
35
36    pub fn resolve_to_vertices(&self, mesh_graph: &MeshGraph) -> HashSet<VertexId> {
37        let mut vertices = self.vertices.clone();
38
39        for halfedge in &self.halfedges {
40            let he = mesh_graph.halfedges[*halfedge];
41            if let Some(start_vertex) = he.start_vertex(mesh_graph) {
42                vertices.insert(start_vertex);
43            } else {
44                error!("Start vertex not found");
45            }
46            vertices.insert(he.end_vertex);
47        }
48
49        for face in &self.faces {
50            vertices.extend(mesh_graph.faces[*face].vertices(mesh_graph));
51        }
52
53        vertices
54    }
55
56    // TODO : also resolve to faces
57
58    #[instrument(skip(mesh_graph))]
59    /// Grows the selection by neighboring vertices. It returns the new vertices.
60    pub fn grow(&mut self, mesh_graph: &MeshGraph) -> HashSet<VertexId> {
61        let existing_verts = self.resolve_to_vertices(mesh_graph);
62
63        let mut new_verts = HashSet::new();
64
65        for vert_id in &existing_verts {
66            if let Some(vert) = mesh_graph.vertices.get(*vert_id) {
67                for neighbor in vert.neighbours(mesh_graph) {
68                    if !existing_verts.contains(&neighbor) {
69                        new_verts.insert(neighbor);
70                        self.insert(neighbor);
71                    }
72                }
73            } else {
74                error!("Vertex not found");
75            }
76        }
77
78        new_verts
79    }
80}
81
82pub trait SelectionOps<T> {
83    fn insert(&mut self, item: T);
84    fn remove(&mut self, item: T);
85}
86
87impl SelectionOps<VertexId> for Selection {
88    fn insert(&mut self, item: VertexId) {
89        self.vertices.insert(item);
90    }
91
92    fn remove(&mut self, item: VertexId) {
93        self.vertices.remove(&item);
94    }
95}
96
97impl SelectionOps<HalfedgeId> for Selection {
98    fn insert(&mut self, item: HalfedgeId) {
99        self.halfedges.insert(item);
100    }
101
102    fn remove(&mut self, item: HalfedgeId) {
103        self.halfedges.remove(&item);
104    }
105}
106
107impl SelectionOps<FaceId> for Selection {
108    fn insert(&mut self, item: FaceId) {
109        self.faces.insert(item);
110    }
111
112    fn remove(&mut self, item: FaceId) {
113        self.faces.remove(&item);
114    }
115}
116
117impl From<VertexId> for Selection {
118    fn from(value: VertexId) -> Self {
119        Self::from_iter(vec![value])
120    }
121}
122
123impl From<HalfedgeId> for Selection {
124    fn from(value: HalfedgeId) -> Self {
125        Self::from_iter(vec![value])
126    }
127}
128
129impl From<FaceId> for Selection {
130    fn from(value: FaceId) -> Self {
131        Self::from_iter(vec![value])
132    }
133}
134
135impl FromIterator<VertexId> for Selection {
136    fn from_iter<T: IntoIterator<Item = VertexId>>(iter: T) -> Self {
137        Selection {
138            vertices: HashSet::from_iter(iter),
139            ..Default::default()
140        }
141    }
142}
143
144impl FromIterator<HalfedgeId> for Selection {
145    fn from_iter<T: IntoIterator<Item = HalfedgeId>>(iter: T) -> Self {
146        Selection {
147            halfedges: HashSet::from_iter(iter),
148            ..Default::default()
149        }
150    }
151}
152
153impl FromIterator<FaceId> for Selection {
154    fn from_iter<T: IntoIterator<Item = FaceId>>(iter: T) -> Self {
155        Selection {
156            faces: HashSet::from_iter(iter),
157            ..Default::default()
158        }
159    }
160}
161
162macro_rules! impl_from_for_selection {
163    ($type:ident) => {
164        impl From<$type<VertexId>> for Selection {
165            fn from(value: $type<VertexId>) -> Self {
166                Self::from_iter(value)
167            }
168        }
169        impl From<$type<HalfedgeId>> for Selection {
170            fn from(value: $type<HalfedgeId>) -> Self {
171                Self::from_iter(value)
172            }
173        }
174        impl From<$type<FaceId>> for Selection {
175            fn from(value: $type<FaceId>) -> Self {
176                Self::from_iter(value)
177            }
178        }
179    };
180}
181
182impl_from_for_selection!(Vec);
183impl_from_for_selection!(HashSet);