Skip to main content

geop_core_topology/euler/
kvr.rs

1use crate::{FaceId, Model, VertexId, boundary::BoundaryType};
2use geop_core_math::{
3    geop_error::{GeopError, GeopResult, WithContext},
4    scalars::Scalar,
5};
6
7impl<S: Scalar> Model<S> {
8    // Kill the bare-vertex boundary added by mvr: vertex must be a bare-vertex
9    // boundary (no edges yet) of face_id.
10    pub fn kvr(self: &mut Model<S>, face_id: FaceId, vertex: VertexId) -> GeopResult<()> {
11        let ctx = |e: GeopError| {
12            e.with_context(format!("Model::kvr(face_id={face_id}, vertex={vertex})"))
13        };
14
15        let face = self.get_face(face_id).with_context(&ctx)?;
16        // `mvr` adds a bare vertex as a *hole*, and only a hole can be
17        // removed — killing a face's outer boundary would leave it unbounded,
18        // so a vertex sitting there is not something `kvr` can undo.
19        let hole_idx = face
20            .holes
21            .iter()
22            .position(|&b| b == BoundaryType::Vertex(vertex))
23            .ok_or_else(|| {
24                ctx(GeopError::new(
25                    "vertex is not a bare-vertex hole boundary of face_id",
26                ))
27            })?;
28
29        self.faces.get_mut(&face_id).unwrap().holes.remove(hole_idx);
30        self.vertices.remove(&vertex);
31
32        Ok(())
33    }
34}