geop_core_topology/edit/
merge_vertex.rs1use crate::{CoedgeGeometry, Model, VertexId, boundary::BoundaryType};
2use geop_core_math::geop_error::{GeopError, GeopResult};
3
4impl Model {
5 pub fn merge_vertex(
10 &mut self,
11 vertex_into_id: VertexId,
12 vertex_deleted_id: VertexId,
13 ) -> GeopResult<()> {
14 if vertex_into_id == vertex_deleted_id {
20 return Err(GeopError::new(format!(
21 "Model::merge_vertex: vertex_into_id and vertex_deleted_id are both {vertex_into_id} — refusing to merge a vertex into itself"
22 )));
23 }
24
25 let deleted_point = self.get_vertex(vertex_deleted_id)?.point;
27 let vertex_into = self.get_vertex_mut(vertex_into_id)?;
28 vertex_into.point = vertex_into.point.union(&deleted_point);
29
30 let edges: Vec<_> = (self.edges.iter())
34 .filter(|(_, e)| [e.start_vertex, e.end_vertex].contains(&vertex_deleted_id))
35 .map(|(&id, _)| id)
36 .collect();
37 for id in edges {
38 let edge = self.get_edge_mut(id)?;
39 if edge.start_vertex == vertex_deleted_id {
40 edge.start_vertex = vertex_into_id;
41 }
42 if edge.end_vertex == vertex_deleted_id {
43 edge.end_vertex = vertex_into_id;
44 }
45 }
46
47 let coedges: Vec<_> = (self.coedges.iter())
48 .filter(|(_, c)| c.geometry == CoedgeGeometry::Vertex(vertex_deleted_id))
49 .map(|(&id, _)| id)
50 .collect();
51 for id in coedges {
52 self.get_coedge_mut(id)?.geometry = CoedgeGeometry::Vertex(vertex_into_id);
53 }
54
55 let faces: Vec<_> = (self.faces.iter())
56 .filter(|(_, f)| {
57 f.boundaries()
58 .any(|b| b == BoundaryType::Vertex(vertex_deleted_id))
59 })
60 .map(|(&id, _)| id)
61 .collect();
62 for id in faces {
63 for boundary in self.get_face_mut(id)?.boundaries_mut() {
64 if *boundary == BoundaryType::Vertex(vertex_deleted_id) {
65 *boundary = BoundaryType::Vertex(vertex_into_id);
66 }
67 }
68 }
69
70 self.vertices.remove(&vertex_deleted_id);
71
72 Ok(())
73 }
74}