Skip to main content

geop_core_topology/edit/
merge_edge.rs

1use crate::{CoedgeGeometry, EdgeId, Model};
2use geop_core_math::{
3    geop_error::{GeopError, GeopResult},
4    scalars::Scalar,
5};
6
7impl<S: Scalar> Model<S> {
8    /// Merges `edge_deleted_id` into `edge_into_id`: repoints every coedge
9    /// tracing the deleted edge to the surviving one, then drops the
10    /// now-unreferenced edge. `reversed` says whether the deleted edge ran
11    /// start<->end the *other* way round relative to the surviving one — if
12    /// so, every repointed coedge's `sense` is flipped so it keeps tracing
13    /// the same physical direction it always did.
14    ///
15    /// TODO: `edge_into_id`'s own curve currently stays exactly as it was —
16    /// it should instead be widened (unioned) to certainly contain the
17    /// deleted edge's curve too, so the kept edge's geometry honestly
18    /// reflects both original edges' combined tolerance instead of silently
19    /// favoring whichever one happened to survive.
20    pub fn merge_edge(
21        &mut self,
22        edge_into_id: EdgeId,
23        edge_deleted_id: EdgeId,
24        reversed: bool,
25    ) -> GeopResult<()> {
26        // Same self-merge hazard as `merge_vertex` — always a caller bug
27        // (typically: acting on a stale edge snapshot), rejected rather than
28        // silently absorbed.
29        if edge_into_id == edge_deleted_id {
30            return Err(GeopError::new(format!(
31                "Model::merge_edge: edge_into_id and edge_deleted_id are both {edge_into_id} — refusing to merge an edge into itself"
32            )));
33        }
34
35        for coedge in self.coedges.values_mut() {
36            if coedge.geometry == CoedgeGeometry::Edge(edge_deleted_id) {
37                coedge.geometry = CoedgeGeometry::Edge(edge_into_id);
38                if reversed {
39                    coedge.sense = coedge.sense.opposite();
40                }
41            }
42        }
43
44        self.edges.remove(&edge_deleted_id);
45
46        Ok(())
47    }
48}