1use hashbrown::HashSet;
2use tracing::error;
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 }
58
59pub trait SelectionOps<T> {
60 fn insert(&mut self, item: T);
61 fn remove(&mut self, item: T);
62}
63
64impl SelectionOps<VertexId> for Selection {
65 fn insert(&mut self, item: VertexId) {
66 self.vertices.insert(item);
67 }
68
69 fn remove(&mut self, item: VertexId) {
70 self.vertices.remove(&item);
71 }
72}
73
74impl SelectionOps<HalfedgeId> for Selection {
75 fn insert(&mut self, item: HalfedgeId) {
76 self.halfedges.insert(item);
77 }
78
79 fn remove(&mut self, item: HalfedgeId) {
80 self.halfedges.remove(&item);
81 }
82}
83
84impl SelectionOps<FaceId> for Selection {
85 fn insert(&mut self, item: FaceId) {
86 self.faces.insert(item);
87 }
88
89 fn remove(&mut self, item: FaceId) {
90 self.faces.remove(&item);
91 }
92}
93
94impl From<VertexId> for Selection {
95 fn from(value: VertexId) -> Self {
96 Self::from_iter(vec![value])
97 }
98}
99
100impl From<HalfedgeId> for Selection {
101 fn from(value: HalfedgeId) -> Self {
102 Self::from_iter(vec![value])
103 }
104}
105
106impl From<FaceId> for Selection {
107 fn from(value: FaceId) -> Self {
108 Self::from_iter(vec![value])
109 }
110}
111
112impl FromIterator<VertexId> for Selection {
113 fn from_iter<T: IntoIterator<Item = VertexId>>(iter: T) -> Self {
114 Selection {
115 vertices: HashSet::from_iter(iter),
116 ..Default::default()
117 }
118 }
119}
120
121impl FromIterator<HalfedgeId> for Selection {
122 fn from_iter<T: IntoIterator<Item = HalfedgeId>>(iter: T) -> Self {
123 Selection {
124 halfedges: HashSet::from_iter(iter),
125 ..Default::default()
126 }
127 }
128}
129
130impl FromIterator<FaceId> for Selection {
131 fn from_iter<T: IntoIterator<Item = FaceId>>(iter: T) -> Self {
132 Selection {
133 faces: HashSet::from_iter(iter),
134 ..Default::default()
135 }
136 }
137}
138
139macro_rules! impl_from_for_selection {
140 ($type:ident) => {
141 impl From<$type<VertexId>> for Selection {
142 fn from(value: $type<VertexId>) -> Self {
143 Self::from_iter(value)
144 }
145 }
146 impl From<$type<HalfedgeId>> for Selection {
147 fn from(value: $type<HalfedgeId>) -> Self {
148 Self::from_iter(value)
149 }
150 }
151 impl From<$type<FaceId>> for Selection {
152 fn from(value: $type<FaceId>) -> Self {
153 Self::from_iter(value)
154 }
155 }
156 };
157}
158
159impl_from_for_selection!(Vec);
160impl_from_for_selection!(HashSet);