Skip to main content

geop_core_topology/euler/
kill_vertex_coedge.rs

1use crate::{CoedgeGeometry, CoedgeId, Model, boundary::BoundaryType};
2use geop_core_math::{
3    geop_error::{GeopError, GeopResult},
4    scalars::Scalar,
5};
6
7impl<S: Scalar> Model<S> {
8    /// Undo [`Model::add_vertex_coedge`]: splice `coedge` back out of its
9    /// loop. `coedge` must be `Vertex`-backed (i.e. one `add_vertex_coedge`
10    /// itself returned) — nothing is removed from `V`, `E`, or `F` here
11    /// either, matching `add_vertex_coedge`'s own no-op effect on them.
12    pub fn kill_vertex_coedge(self: &mut Model<S>, coedge: CoedgeId) -> GeopResult<()> {
13        let ctx =
14            |e: GeopError| e.with_context(format!("Model::kill_vertex_coedge(coedge={coedge})"));
15
16        let ce = self.get_coedge(coedge)?.clone();
17        if !matches!(ce.geometry, CoedgeGeometry::Vertex(_)) {
18            return Err(ctx(GeopError::new(
19                "coedge is edge-backed, not vertex-backed — use kve instead",
20            )));
21        }
22
23        self.coedges.get_mut(&ce.prev).unwrap().next = ce.next;
24        self.coedges.get_mut(&ce.next).unwrap().prev = ce.prev;
25        self.coedges.remove(&coedge);
26
27        let face = self.faces.get_mut(&ce.face).unwrap();
28        for b in face.boundaries_mut() {
29            if *b == BoundaryType::Loop(coedge) {
30                *b = BoundaryType::Loop(ce.next);
31            }
32        }
33
34        Ok(())
35    }
36}