fj_core/operations/split/
half_edge.rs

1use fj_math::Point;
2
3use crate::{
4    geometry::HalfEdgeGeometry,
5    objects::{HalfEdge, Vertex},
6    operations::insert::Insert,
7    storage::Handle,
8    Core,
9};
10
11/// Split a [`HalfEdge`] into two
12///
13/// This is a low-level operation that, by itself, leaves the containing shell
14/// in an invalid state. You probably want to use [`SplitEdge`] instead.
15///
16/// [`SplitEdge`]: super::SplitEdge
17pub trait SplitHalfEdge {
18    /// Split the half-edge into two
19    ///
20    /// # Validity
21    ///
22    /// Within a valid shell, a [`HalfEdge`] must have an equal but opposite
23    /// sibling. This operation only splits a single half-edge, which in itself
24    /// will make a valid shell invalid.
25    ///
26    /// The caller is responsible for also split this half-edge's sibling, if
27    /// appropriate, to preserve validity.
28    #[must_use]
29    fn split_half_edge(
30        &self,
31        point: impl Into<Point<1>>,
32        core: &mut Core,
33    ) -> [Handle<HalfEdge>; 2];
34}
35
36impl SplitHalfEdge for Handle<HalfEdge> {
37    fn split_half_edge(
38        &self,
39        point: impl Into<Point<1>>,
40        core: &mut Core,
41    ) -> [Handle<HalfEdge>; 2] {
42        let point = point.into();
43
44        let [start, end] = self.boundary().inner;
45
46        let a = HalfEdge::new(
47            core.layers.geometry.of_half_edge(self).path,
48            [start, point],
49            self.curve().clone(),
50            self.start_vertex().clone(),
51        )
52        .insert(core);
53        let b = HalfEdge::new(
54            core.layers.geometry.of_half_edge(self).path,
55            [point, end],
56            self.curve().clone(),
57            Vertex::new().insert(core),
58        )
59        .insert(core);
60
61        core.layers.geometry.define_half_edge(
62            a.clone(),
63            HalfEdgeGeometry {
64                path: core.layers.geometry.of_half_edge(self).path,
65            },
66        );
67        core.layers.geometry.define_half_edge(
68            b.clone(),
69            HalfEdgeGeometry {
70                path: core.layers.geometry.of_half_edge(self).path,
71            },
72        );
73
74        [a, b]
75    }
76}