1use glam::Vec3;
2use tracing::{error, instrument};
3
4use crate::{Face, FaceId, HalfedgeId, MeshGraph, VertexId, error_none};
5
6impl MeshGraph {
7 #[instrument(skip(self))]
8 pub fn add_face_from_positions(&mut self, a: Vec3, b: Vec3, c: Vec3) -> AddFace {
9 let a_id = self.add_vertex(a);
10 let b_id = self.add_vertex(b);
11 let c_id = self.add_vertex(c);
12
13 let inserted_a = self.add_or_get_edge(a_id, b_id);
14 let inserted_b = self.add_or_get_edge(b_id, c_id);
15 let inserted_c = self.add_or_get_edge(c_id, a_id);
16
17 let face_id = self.add_face(
18 inserted_a.start_to_end_he_id,
19 inserted_b.start_to_end_he_id,
20 inserted_c.start_to_end_he_id,
21 );
22
23 let mut halfedge_ids = inserted_a.created_he_ids();
24 halfedge_ids.extend(inserted_b.created_he_ids());
25 halfedge_ids.extend(inserted_c.created_he_ids());
26
27 AddFace {
28 face_id,
29 halfedge_ids,
30 vertex_ids: vec![a_id, b_id, c_id],
31 }
32 }
33
34 #[instrument(skip(self))]
36 pub fn add_face_from_halfedge_and_position(
37 &mut self,
38 he_id: HalfedgeId,
39 opposite_vertex_pos: Vec3,
40 ) -> Option<AddFace> {
41 let vertex_id = self.add_vertex(opposite_vertex_pos);
42 self.add_face_from_halfedge_and_vertex(he_id, vertex_id)
43 }
44
45 #[instrument(skip(self))]
47 pub fn add_face_from_halfedge_and_vertex(
48 &mut self,
49 he_id: HalfedgeId,
50 vertex_id: VertexId,
51 ) -> Option<AddFace> {
52 let he_a_id = self.boundary_he(he_id)?;
53
54 let he_a = self.halfedges[he_a_id];
55 let start_vertex_id_he_a = he_a.start_vertex(self)?;
56 let end_vertex_id_he_a = he_a.end_vertex;
57
58 let inserted_b = self.add_or_get_edge(end_vertex_id_he_a, vertex_id);
59 let inserted_c = self.add_or_get_edge(vertex_id, start_vertex_id_he_a);
60
61 let face_id = self.add_face(
62 he_a_id,
63 inserted_b.start_to_end_he_id,
64 inserted_c.start_to_end_he_id,
65 );
66
67 let mut halfedge_ids = inserted_b.created_he_ids();
68 halfedge_ids.extend(inserted_c.created_he_ids());
69
70 Some(AddFace {
71 face_id,
72 halfedge_ids,
73 vertex_ids: vec![],
74 })
75 }
76
77 #[instrument(skip(self))]
79 pub fn add_face_from_vertices(
80 &mut self,
81 v_id1: VertexId,
82 v_id2: VertexId,
83 v_id3: VertexId,
84 ) -> AddFace {
85 let inserted_a = self.add_or_get_edge(v_id1, v_id2);
86 let inserted_b = self.add_or_get_edge(v_id2, v_id3);
87 let inserted_c = self.add_or_get_edge(v_id3, v_id1);
88
89 let face_id = self.add_face(
90 inserted_a.start_to_end_he_id,
91 inserted_b.start_to_end_he_id,
92 inserted_c.start_to_end_he_id,
93 );
94
95 let mut halfedge_ids = inserted_a.created_he_ids();
96 halfedge_ids.extend(inserted_b.created_he_ids());
97 halfedge_ids.extend(inserted_c.created_he_ids());
98
99 AddFace {
100 face_id,
101 halfedge_ids,
102 vertex_ids: vec![],
103 }
104 }
105
106 #[instrument(skip(self))]
108 pub fn add_face_from_halfedges(
109 &mut self,
110 he_id1: HalfedgeId,
111 he_id2: HalfedgeId,
112 ) -> Option<AddFace> {
113 let he_id1 = self.boundary_he(he_id1)?;
114 let he_id2 = self.boundary_he(he_id2)?;
115
116 let he1 = *self
117 .halfedges
118 .get(he_id1)
119 .or_else(error_none!("Halfedge 1 not found"))?;
120 let he2 = *self
121 .halfedges
122 .get(he_id2)
123 .or_else(error_none!("Halfedge 2 not found"))?;
124
125 let he1_start_vertex = he1
126 .start_vertex(self)
127 .or_else(error_none!("Start vertex should be available"))?;
128
129 let he2_start_vertex = he2
130 .start_vertex(self)
131 .or_else(error_none!("Start vertex should be available"))?;
132
133 if he1_start_vertex == he2.end_vertex {
134 let inserted = self.add_or_get_edge(he1.end_vertex, he2_start_vertex);
135
136 let face_id = self.add_face(inserted.start_to_end_he_id, he_id2, he_id1);
137
138 Some(AddFace {
139 face_id,
140 halfedge_ids: inserted.created_he_ids(),
141 vertex_ids: vec![],
142 })
143 } else if he1_start_vertex == he2_start_vertex {
144 let inserted = self.add_or_get_edge(he1.end_vertex, he2.end_vertex);
145
146 let face_id = self.add_face(
147 inserted.start_to_end_he_id,
148 he2.twin.or_else(error_none!("Twin not set"))?,
149 he_id1,
150 );
151
152 Some(AddFace {
153 face_id,
154 halfedge_ids: inserted.created_he_ids(),
155 vertex_ids: vec![],
156 })
157 } else if he1.end_vertex == he2.end_vertex {
158 let inserted = self.add_or_get_edge(he2_start_vertex, he1_start_vertex);
159
160 let face_id = self.add_face(
161 inserted.start_to_end_he_id,
162 he_id1,
163 he2.twin.or_else(error_none!("Twin not set"))?,
164 );
165
166 Some(AddFace {
167 face_id,
168 halfedge_ids: inserted.created_he_ids(),
169 vertex_ids: vec![],
170 })
171 } else {
172 let inserted = self.add_or_get_edge(he2.end_vertex, he1_start_vertex);
173
174 let face_id = self.add_face(inserted.start_to_end_he_id, he_id1, he_id2);
175
176 Some(AddFace {
177 face_id,
178 halfedge_ids: inserted.created_he_ids(),
179 vertex_ids: vec![],
180 })
181 }
182 }
183
184 #[instrument(skip(self))]
187 pub fn add_face(
188 &mut self,
189 he1_id: HalfedgeId,
190 he2_id: HalfedgeId,
191 he3_id: HalfedgeId,
192 ) -> FaceId {
193 let face_id = self.faces.insert_with_key(|id| Face {
194 halfedge: he1_id,
195 index: self.next_index,
196 id,
197 });
198
199 self.index_to_face_id.insert(self.next_index, face_id);
200
201 self.next_index += 1;
202
203 for (he_id, next_he_id) in [(he1_id, he2_id), (he2_id, he3_id), (he3_id, he1_id)] {
204 if let Some(halfedge) = self.halfedges.get_mut(he_id) {
205 halfedge.face = Some(face_id);
206 halfedge.next = Some(next_he_id);
207 } else {
208 error!("Halfedge not found");
209 }
210 }
211
212 let face = self.faces[face_id]; self.bvh
214 .insert_or_update_partially(face.aabb(self), face.index, 0.0);
215
216 face_id
217 }
218}
219
220pub struct AddFace {
222 pub face_id: FaceId,
224 pub halfedge_ids: Vec<HalfedgeId>,
226 pub vertex_ids: Vec<VertexId>,
228}
229
230#[cfg(test)]
231mod test {
232 use super::*;
233
234 fn add_face(mesh_graph: &mut MeshGraph) -> FaceId {
235 mesh_graph
236 .add_face_from_positions(
237 Vec3::new(0.0, 0.0, 0.0),
238 Vec3::new(1.0, 0.0, 0.0),
239 Vec3::new(0.0, 1.0, 0.0),
240 )
241 .face_id
242 }
243
244 fn add_face_to_edge(
245 mesh_graph: &mut MeshGraph,
246 face_id: FaceId,
247 pos: Vec3,
248 use_twin: bool,
249 ) -> Option<FaceId> {
250 let mut associated_he_id = mesh_graph.faces[face_id]
251 .halfedges(mesh_graph)
252 .nth(1)
253 .unwrap();
254
255 if use_twin {
256 associated_he_id = mesh_graph.halfedges[associated_he_id].twin.unwrap();
257 }
258
259 mesh_graph
260 .add_face_from_halfedge_and_position(associated_he_id, pos)
261 .map(|f| f.face_id)
262 }
263
264 fn fill_face(
265 mesh_graph: &mut MeshGraph,
266 face_id_1: FaceId,
267 face_id_2: FaceId,
268 use_twin: bool,
269 ) -> Option<FaceId> {
270 let mut he_id_1 = mesh_graph.faces[face_id_1]
271 .halfedges(mesh_graph)
272 .next()
273 .unwrap();
274
275 let mut he_id_2 = mesh_graph.faces[face_id_2]
276 .halfedges(mesh_graph)
277 .nth(1)
278 .unwrap();
279
280 if use_twin {
281 he_id_1 = mesh_graph.halfedges[he_id_1].twin.unwrap();
282 he_id_2 = mesh_graph.halfedges[he_id_2].twin.unwrap();
283 }
284
285 mesh_graph
286 .add_face_from_halfedges(he_id_1, he_id_2)
287 .map(|f| f.face_id)
288 }
289
290 macro_rules! init_fill_face {
291 ($f1:ident, $f2:ident, $f3:ident, $mg:ident) => {
292 let $f1 = add_face(&mut $mg);
293
294 let $f2 = add_face_to_edge(&mut $mg, $f1, Vec3::new(1.0, 1.0, 0.0), false);
295 let $f3 = add_face_to_edge(&mut $mg, $f2.unwrap(), Vec3::new(0.5, 0.5, 1.0), false);
296 };
297 }
298
299 macro_rules! log_faces_rerun {
300 ($mg:ident, $($face:expr),*) => {
301 #[cfg(feature = "rerun")]
302 {
303 $(
304 $mg.log_face_rerun(&format!("{:?}", $face), $face);
305 )*
306 }
307 };
308 }
309
310 fn test_vertices(mesh_graph: &MeshGraph, face: FaceId) {
311 let mut vertices = mesh_graph.faces[face].vertices(mesh_graph);
312
313 let vertex = vertices.next();
314 assert!(vertex.is_some());
315 assert!(
316 mesh_graph.vertices[vertex.unwrap()]
317 .outgoing_halfedge
318 .is_some()
319 );
320
321 let vertex = vertices.next();
322 assert!(vertex.is_some());
323 assert!(
324 mesh_graph.vertices[vertex.unwrap()]
325 .outgoing_halfedge
326 .is_some()
327 );
328
329 let vertex = vertices.next();
330 assert!(vertex.is_some());
331 assert!(
332 mesh_graph.vertices[vertex.unwrap()]
333 .outgoing_halfedge
334 .is_some()
335 );
336
337 assert!(vertices.next().is_none());
338 }
339
340 fn test_halfedges(mesh_graph: &MeshGraph, face: FaceId) {
341 let mut halfedges = mesh_graph.faces[face].halfedges(mesh_graph);
342
343 assert!(halfedges.next().is_some());
344 assert!(halfedges.next().is_some());
345 assert!(halfedges.next().is_some());
346 assert!(halfedges.next().is_none());
347 }
348
349 #[test]
350 fn test_create_face() {
351 let mut mesh_graph = MeshGraph::new();
352 let face1 = add_face(&mut mesh_graph);
353
354 assert_eq!(mesh_graph.vertices.len(), 3);
355 assert_eq!(mesh_graph.positions.len(), 3);
356 assert_eq!(mesh_graph.halfedges.len(), 6);
357 assert_eq!(mesh_graph.faces.len(), 1);
358
359 test_vertices(&mesh_graph, face1);
360 test_halfedges(&mesh_graph, face1);
361
362 log_faces_rerun!(mesh_graph, face1);
363 }
364
365 #[test]
366 fn test_add_face_to_edge() {
367 let mut mesh_graph = MeshGraph::new();
368 let face1 = add_face(&mut mesh_graph);
369
370 let face2 = add_face_to_edge(&mut mesh_graph, face1, Vec3::new(1.0, 1.0, 0.0), false);
371
372 assert!(face2.is_some());
373 assert_eq!(mesh_graph.vertices.len(), 4);
374 assert_eq!(mesh_graph.positions.len(), 4);
375 assert_eq!(mesh_graph.halfedges.len(), 10);
376 assert_eq!(mesh_graph.faces.len(), 2);
377
378 test_vertices(&mesh_graph, face2.unwrap());
379 test_halfedges(&mesh_graph, face2.unwrap());
380
381 log_faces_rerun!(mesh_graph, face1, face2.unwrap());
382 }
383
384 #[test]
385 fn test_add_face_to_twin_edge() {
386 let mut mesh_graph = MeshGraph::new();
387 let face1 = add_face(&mut mesh_graph);
388
389 let face2 = add_face_to_edge(&mut mesh_graph, face1, Vec3::new(1.0, 1.0, 0.0), true);
390
391 assert!(face2.is_some());
392 assert_eq!(mesh_graph.vertices.len(), 4);
393 assert_eq!(mesh_graph.positions.len(), 4);
394 assert_eq!(mesh_graph.halfedges.len(), 10);
395 assert_eq!(mesh_graph.faces.len(), 2);
396
397 test_vertices(&mesh_graph, face2.unwrap());
398 test_halfedges(&mesh_graph, face2.unwrap());
399
400 log_faces_rerun!(mesh_graph, face1, face2.unwrap());
401 }
402
403 #[test]
404 fn test_fill_face() {
405 let mut mesh_graph = MeshGraph::new();
406 init_fill_face!(face1, face2, face3, mesh_graph);
407
408 let face4 = fill_face(&mut mesh_graph, face1, face3.unwrap(), false);
409
410 assert!(face4.is_some());
411 assert_eq!(mesh_graph.vertices.len(), 5);
412 assert_eq!(mesh_graph.positions.len(), 5);
413 assert_eq!(mesh_graph.halfedges.len(), 16);
414 assert_eq!(mesh_graph.faces.len(), 4);
415
416 test_vertices(&mesh_graph, face4.unwrap());
417 test_halfedges(&mesh_graph, face4.unwrap());
418
419 log_faces_rerun!(
420 mesh_graph,
421 face1,
422 face2.unwrap(),
423 face3.unwrap(),
424 face4.unwrap()
425 );
426 }
427
428 #[test]
429 fn test_fill_face_from_twin_edges() {
430 let mut mesh_graph = MeshGraph::new();
431 init_fill_face!(face1, face2, face3, mesh_graph);
432
433 let face4 = fill_face(&mut mesh_graph, face1, face3.unwrap(), true);
434
435 assert!(face4.is_some());
436 assert_eq!(mesh_graph.vertices.len(), 5);
437 assert_eq!(mesh_graph.positions.len(), 5);
438 assert_eq!(mesh_graph.halfedges.len(), 16);
439 assert_eq!(mesh_graph.faces.len(), 4);
440
441 test_vertices(&mesh_graph, face4.unwrap());
442 test_halfedges(&mesh_graph, face4.unwrap());
443
444 log_faces_rerun!(
445 mesh_graph,
446 face1,
447 face2.unwrap(),
448 face3.unwrap(),
449 face4.unwrap()
450 );
451 }
452}