Skip to main content

geop_core_part/
edit.rs

1//! Forwarding wrappers for every `Model` edit operator, exactly like
2//! `euler.rs`: each registers what it creates under the caller's name and
3//! forgets what it deletes.
4
5use geop_core_math::{geop_error::GeopResult, scalars::Scalar, vector::Vector3};
6use geop_core_topology::{Edge, EdgeId, FaceId, SolidId, Vertex, VertexId};
7
8use crate::part::Part;
9
10impl<S: Scalar> Part<S> {
11    /// Forwards to [`geop_core_topology::Model::insert_vertex`]: a vertex on
12    /// nothing yet, about to be split into an edge (see
13    /// [`Part::split_edge_at_vertex`]).
14    pub fn insert_vertex(
15        &mut self,
16        point: Vector3<S>,
17        name: impl Into<String>,
18    ) -> GeopResult<VertexId> {
19        let vertex = self.topology.insert_vertex(Vertex { point });
20        self.names.insert(vertex, name)?;
21        Ok(vertex)
22    }
23
24    /// Forwards to [`geop_core_topology::Model::insert_edge`]: an edge on no
25    /// face yet, about to be spliced into its faces (see
26    /// [`Part::splice_edge_into_face`]).
27    pub fn insert_edge(&mut self, edge: Edge<S>, name: impl Into<String>) -> GeopResult<EdgeId> {
28        let edge = self.topology.insert_edge(edge);
29        self.names.insert(edge, name)?;
30        Ok(edge)
31    }
32
33    /// Forwards to [`geop_core_topology::Model::merge_vertex`], forgetting
34    /// the name of the vertex it deletes. The survivor keeps its own name.
35    pub fn merge_vertex(
36        &mut self,
37        vertex_into_id: VertexId,
38        vertex_deleted_id: VertexId,
39    ) -> GeopResult<()> {
40        self.topology
41            .merge_vertex(vertex_into_id, vertex_deleted_id)?;
42        self.names.remove(vertex_deleted_id);
43        Ok(())
44    }
45
46    /// Forwards to [`geop_core_topology::Model::merge_edge`], forgetting the
47    /// name of the edge it deletes. The survivor keeps its own name.
48    pub fn merge_edge(
49        &mut self,
50        edge_into_id: EdgeId,
51        edge_deleted_id: EdgeId,
52        reversed: bool,
53    ) -> GeopResult<()> {
54        self.topology
55            .merge_edge(edge_into_id, edge_deleted_id, reversed)?;
56        self.names.remove(edge_deleted_id);
57        Ok(())
58    }
59
60    /// Forwards to [`geop_core_topology::Model::reverse_face`]. Creates and
61    /// deletes nothing.
62    pub fn reverse_face(&mut self, face_id: FaceId) -> GeopResult<()> {
63        self.topology.reverse_face(face_id)
64    }
65
66    /// Forwards to [`geop_core_topology::Model::splice_edge_into_face`].
67    ///
68    /// Whether that creates a face depends on how the edge's ends sit on the
69    /// face's boundary, which a caller imprinting a traced curve cannot know
70    /// beforehand — so `new_face_name` is the name for the face *if* one is
71    /// created, and unused otherwise.
72    pub fn splice_edge_into_face(
73        &mut self,
74        edge_id: EdgeId,
75        face_id: FaceId,
76        max_nodes: usize,
77        min_subdivision_size: S,
78        new_face_name: impl Into<String>,
79    ) -> GeopResult<Option<FaceId>> {
80        let new_face = self.topology.splice_edge_into_face(
81            edge_id,
82            face_id,
83            max_nodes,
84            min_subdivision_size,
85        )?;
86        if let Some(face) = new_face {
87            self.names.insert(face, new_face_name)?;
88        }
89        Ok(new_face)
90    }
91
92    /// Forwards to [`geop_core_topology::Model::split_edge_at_vertex`],
93    /// naming the new edge it creates: the (vertex -> end) segment, while
94    /// `edge_id` keeps the (start -> vertex) one and its name.
95    pub fn split_edge_at_vertex(
96        &mut self,
97        edge_id: EdgeId,
98        edge_t: S,
99        vertex_id: VertexId,
100        max_nodes: usize,
101        min_subdivision_size: S,
102        new_edge_name: impl Into<String>,
103    ) -> GeopResult<EdgeId> {
104        let new_edge = self.topology.split_edge_at_vertex(
105            edge_id,
106            edge_t,
107            vertex_id,
108            max_nodes,
109            min_subdivision_size,
110        )?;
111        self.names.insert(new_edge, new_edge_name)?;
112        Ok(new_edge)
113    }
114
115    /// Forwards to [`geop_core_topology::Model::assemble_solid`], naming the
116    /// solid it creates (if any) and forgetting the names of everything it
117    /// deletes.
118    pub fn assemble_solid(
119        &mut self,
120        consumed: &[SolidId],
121        keep: &[FaceId],
122        solid_name: impl Into<String>,
123    ) -> GeopResult<Option<SolidId>> {
124        let solid = self.topology.assemble_solid(consumed, keep)?;
125        self.forget_dead_names();
126        if let Some(solid) = solid {
127            self.names.insert(solid, solid_name)?;
128        }
129        Ok(solid)
130    }
131
132    /// Forwards to [`geop_core_topology::Model::merge_solids`], forgetting
133    /// the name of the solid it deletes.
134    pub fn merge_solids(&mut self, into: SolidId, from: SolidId) -> GeopResult<()> {
135        self.topology.merge_solids(into, from)?;
136        self.names.remove(from);
137        Ok(())
138    }
139}