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