1use crate::*;
26
27use std::marker::PhantomData;
28
29#[derive(Clone)]
33pub struct SearchableMesh<M, T, IC>
34where
35 M: IsMesh<T, Face3>,
36 IC: IsIndexContainer,
37{
38 mesh: M,
39 he: HalfEdge<IC>,
40 phantomt: PhantomData<T>,
41}
42
43impl<M, T, IC> SearchableMesh<M, T, IC>
44where
45 M: IsMesh<T, Face3>,
46 IC: IsIndexContainer,
47{
48 pub fn new(mesh: M) -> Self {
52 let he = HalfEdge::new(&mesh);
53
54 SearchableMesh {
55 mesh,
56 he,
57 phantomt: PhantomData,
58 }
59 }
60
61 pub fn ensure_face_id(&self, id: FId) -> Result<()> {
63 if id.val >= self.mesh.num_faces() {
64 return Err(ErrorKind::IncorrectFaceID);
65 }
66 Ok(())
67 }
68
69 pub fn mesh(&self) -> &M {
71 &self.mesh
72 }
73}
74
75impl<M, T, IC> IsMesh<T, Face3> for SearchableMesh<M, T, IC>
76where
77 M: IsMesh<T, Face3>,
78 IC: IsIndexContainer,
79{
80 fn num_faces(&self) -> usize {
81 self.mesh.num_faces()
82 }
83
84 fn num_vertices(&self) -> usize {
85 self.mesh.num_vertices()
86 }
87
88 fn face_vertex_ids(&self, faceid: FId) -> Result<Face3> {
89 self.mesh.face_vertex_ids(faceid)
90 }
91
92 fn face_vertices(&self, faceid: FId) -> Result<[T; 3]> {
93 self.mesh.face_vertices(faceid)
94 }
95
96 fn vertex(&self, vertexid: VId) -> Result<T> {
97 self.mesh.vertex(vertexid)
98 }
99}
100
101impl<M, T, IC> IsVertexEditableMesh<T, Face3> for SearchableMesh<M, T, IC>
102where
103 M: IsMesh<T, Face3> + IsVertexEditableMesh<T, Face3>,
104 T: IsEditable3D + IsBuildable3D + Clone,
105 IC: IsIndexContainer,
106{
107 fn add_vertex(&mut self, vertex: T) -> VId {
108 self.mesh.add_vertex(vertex)
109 }
110
111 fn change_vertex(&mut self, vid: VId, vertex: T) -> Result<()> {
112 self.mesh.change_vertex(vid, vertex)
113 }
114
115 fn reserve_vertices(&mut self, n: usize) {
116 self.mesh.reserve_vertices(n)
117 }
118}
119
120impl<M, T, IC> IsSearchableMesh<T, Face3> for SearchableMesh<M, T, IC>
121where
122 M: IsMesh<T, Face3>,
123 IC: IsIndexContainer,
124{
125 fn num_edges(&self) -> usize {
126 self.mesh.num_faces() * 3
127 }
128
129 fn edges_of_face(&self, faceid: FId) -> Result<(EId, EId, EId)> {
130 self.ensure_face_id(faceid)?;
131 Ok((
132 EId {
133 val: faceid.val * 3 + 0,
134 },
135 EId {
136 val: faceid.val * 3 + 1,
137 },
138 EId {
139 val: faceid.val * 3 + 2,
140 },
141 ))
142 }
143
144 fn edges_originating_from_vertex(&self, vertexid: VId, result: &mut Vec<EId>) -> Result<()> {
145 self.he.edges_originating(vertexid, result)
146 }
147
148 fn edges_ending_at_vertex(
149 &self,
150 vertexid: VId,
151 cache: &mut Vec<EId>,
152 result: &mut Vec<EId>,
153 ) -> Result<()> {
154 self.he.edges_ending(vertexid, cache, result)
155 }
156
157 fn edges_of_vertex(
158 &self,
159 vertexid: VId,
160 cache: &mut Vec<EId>,
161 result: &mut Vec<EId>,
162 ) -> Result<()> {
163 self.he.edges_all(vertexid, cache, result)
164 }
165
166 fn edge_tail(&self, edgeid: EId) -> Result<VId> {
167 self.he.tail(edgeid)
168 }
169
170 fn edge_head(&self, edgeid: EId) -> Result<VId> {
171 self.he.next(edgeid).and_then(|next| self.he.tail(next))
172 }
173
174 fn edge_next(&self, edgeid: EId) -> Result<EId> {
175 self.he.next(edgeid)
176 }
177
178 fn edge_prev(&self, edgeid: EId) -> Result<EId> {
179 self.he.prev(edgeid)
180 }
181
182 fn edge_twin(&self, edgeid: EId) -> Result<Option<EId>> {
183 self.he.twin(edgeid)
184 }
185
186 fn edge_face(&self, edgeid: EId) -> Result<FId> {
187 self.he.face(edgeid)
188 }
189}
190
191impl<M, T, IC> HasBoundingBox3DMaybe for SearchableMesh<M, T, IC>
192where
193 M: IsMesh<T, Face3> + HasBoundingBox3DMaybe,
194 IC: IsIndexContainer,
195{
196 fn bounding_box_maybe(&self) -> Result<BoundingBox3D> {
197 self.mesh.bounding_box_maybe()
198 }
199}
200
201impl<M, T, IC> HasCenterOfGravity3D for SearchableMesh<M, T, IC>
202where
203 M: IsMesh<T, Face3> + HasCenterOfGravity3D,
204 IC: IsIndexContainer,
205{
206 fn center_of_gravity(&self) -> Result<Point3D> {
207 self.mesh.center_of_gravity()
208 }
209}
210
211impl<M, T, IC> IsScalable for SearchableMesh<M, T, IC>
212where
213 M: IsMesh<T, Face3> + IsScalable,
214 IC: IsIndexContainer,
215{
216 fn scale(&mut self, factor: Positive) {
217 self.mesh.scale(factor);
218 }
219}
220
221impl<M, T, IC> AsRef<M> for SearchableMesh<M, T, IC>
222where
223 M: IsMesh<T, Face3>,
224 IC: IsIndexContainer,
225{
226 fn as_ref(&self) -> &M {
227 &self.mesh
228 }
229}
230
231impl<M, T, IC> Into<(M, HalfEdge<IC>)> for SearchableMesh<M, T, IC>
232where
233 M: IsMesh<T, Face3>,
234 IC: IsIndexContainer,
235{
236 fn into(self) -> (M, HalfEdge<IC>) {
237 (self.mesh, self.he)
238 }
239}
240
241impl<M, T, IC> From<(M, HalfEdge<IC>)> for SearchableMesh<M, T, IC>
242where
243 M: IsMesh<T, Face3>,
244 IC: IsIndexContainer,
245{
246 fn from(me: (M, HalfEdge<IC>)) -> Self {
247 Self {
248 mesh: me.0,
249 he: me.1,
250 phantomt: PhantomData::default(),
251 }
252 }
253}