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 #[instrument(skip(mesh_graph))]
59 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);