mesh_graph/
selection.rs

1use hashbrown::HashSet;
2
3use super::{FaceId, HalfedgeId, MeshGraph, VertexId};
4
5#[derive(Debug, Clone, Default)]
6pub struct Selection {
7    pub vertices: HashSet<VertexId>,
8    pub halfedges: HashSet<HalfedgeId>,
9    pub faces: HashSet<FaceId>,
10}
11
12impl Selection {
13    pub fn select_all(mesh_graph: &MeshGraph) -> Self {
14        Self {
15            faces: mesh_graph.faces.keys().collect(),
16            ..Default::default()
17        }
18    }
19
20    pub fn resolve_to_halfedges(&self, mesh_graph: &MeshGraph) -> HashSet<HalfedgeId> {
21        let mut halfedges = self.halfedges.clone();
22
23        for face in &self.faces {
24            halfedges.extend(mesh_graph.faces[*face].halfedges(mesh_graph));
25        }
26
27        for vertex in &self.vertices {
28            halfedges.extend(mesh_graph.vertices[*vertex].outgoing_halfedges(mesh_graph));
29        }
30
31        halfedges
32    }
33
34    pub fn resolve_to_vertices(&self, mesh_graph: &MeshGraph) -> HashSet<VertexId> {
35        let mut vertices = self.vertices.clone();
36
37        for halfedge in &self.halfedges {
38            let he = mesh_graph.halfedges[*halfedge];
39            vertices.insert(he.start_vertex(mesh_graph));
40            vertices.insert(he.end_vertex);
41        }
42
43        for face in &self.faces {
44            vertices.extend(mesh_graph.faces[*face].vertices(mesh_graph));
45        }
46
47        vertices
48    }
49
50    // TODO : also resolve to faces
51}
52
53pub trait SelectionOps<T> {
54    fn insert(&mut self, item: T);
55    fn remove(&mut self, item: T);
56}
57
58impl SelectionOps<VertexId> for Selection {
59    fn insert(&mut self, item: VertexId) {
60        self.vertices.insert(item);
61    }
62
63    fn remove(&mut self, item: VertexId) {
64        self.vertices.remove(&item);
65    }
66}
67
68impl SelectionOps<HalfedgeId> for Selection {
69    fn insert(&mut self, item: HalfedgeId) {
70        self.halfedges.insert(item);
71    }
72
73    fn remove(&mut self, item: HalfedgeId) {
74        self.halfedges.remove(&item);
75    }
76}
77
78impl SelectionOps<FaceId> for Selection {
79    fn insert(&mut self, item: FaceId) {
80        self.faces.insert(item);
81    }
82
83    fn remove(&mut self, item: FaceId) {
84        self.faces.remove(&item);
85    }
86}
87
88impl From<VertexId> for Selection {
89    fn from(value: VertexId) -> Self {
90        Self::from_iter(vec![value])
91    }
92}
93
94impl From<HalfedgeId> for Selection {
95    fn from(value: HalfedgeId) -> Self {
96        Self::from_iter(vec![value])
97    }
98}
99
100impl From<FaceId> for Selection {
101    fn from(value: FaceId) -> Self {
102        Self::from_iter(vec![value])
103    }
104}
105
106impl FromIterator<VertexId> for Selection {
107    fn from_iter<T: IntoIterator<Item = VertexId>>(iter: T) -> Self {
108        Selection {
109            vertices: HashSet::from_iter(iter),
110            ..Default::default()
111        }
112    }
113}
114
115impl FromIterator<HalfedgeId> for Selection {
116    fn from_iter<T: IntoIterator<Item = HalfedgeId>>(iter: T) -> Self {
117        Selection {
118            halfedges: HashSet::from_iter(iter),
119            ..Default::default()
120        }
121    }
122}
123
124impl FromIterator<FaceId> for Selection {
125    fn from_iter<T: IntoIterator<Item = FaceId>>(iter: T) -> Self {
126        Selection {
127            faces: HashSet::from_iter(iter),
128            ..Default::default()
129        }
130    }
131}
132
133macro_rules! impl_from_for_selection {
134    ($type:ident) => {
135        impl From<$type<VertexId>> for Selection {
136            fn from(value: $type<VertexId>) -> Self {
137                Self::from_iter(value)
138            }
139        }
140        impl From<$type<HalfedgeId>> for Selection {
141            fn from(value: $type<HalfedgeId>) -> Self {
142                Self::from_iter(value)
143            }
144        }
145        impl From<$type<FaceId>> for Selection {
146            fn from(value: $type<FaceId>) -> Self {
147                Self::from_iter(value)
148            }
149        }
150    };
151}
152
153impl_from_for_selection!(Vec);
154impl_from_for_selection!(HashSet);