Skip to main content

geop_core_topology/euler/
kvfs.rs

1use crate::{Model, SolidId, boundary::BoundaryType};
2use geop_core_math::{
3    geop_error::{GeopError, GeopResult},
4    scalars::Scalar,
5};
6
7impl<S: Scalar> Model<S> {
8    // Kill the vertex, face and solid created by mvfs. solid must still be in its
9    // freshly-made-vfs shape: a single void-free shell with a single face whose only
10    // boundary is a bare vertex (no edges yet).
11    pub fn kvfs(self: &mut Model<S>, solid: SolidId) -> GeopResult<()> {
12        let ctx = |e: GeopError| e.with_context(format!("Model::kvfs(solid={solid})"));
13
14        let s = self.get_solid(solid)?.clone();
15        if s.shells.len() != 1 {
16            return Err(ctx(GeopError::new("solid must have exactly one shell")));
17        }
18        let shell_id = s.shells[0];
19        let shell = self.get_shell(shell_id)?.clone();
20        if shell.faces.len() != 1 {
21            return Err(ctx(GeopError::new("shell must have exactly one face")));
22        }
23        let face_id = shell.faces[0];
24        let face = self.get_face(face_id)?.clone();
25        if !face.holes.is_empty() {
26            return Err(ctx(GeopError::new("face must have no holes")));
27        }
28        let vertex_id = match face.outer {
29            BoundaryType::Vertex(v) => v,
30            BoundaryType::Loop(_) => {
31                return Err(ctx(GeopError::new("face boundary must be a bare vertex")));
32            }
33        };
34
35        self.vertices.remove(&vertex_id);
36        self.faces.remove(&face_id);
37        self.shells.remove(&shell_id);
38        self.solids.remove(&solid);
39
40        Ok(())
41    }
42}