geop_core_geometry/intersection/mod.rs
1pub mod branch;
2mod coincidence;
3pub mod curve_curve;
4pub mod curve_surface;
5pub mod surface_surface;
6
7pub use coincidence::{Hit, Overlap};
8pub use curve_curve::refine_crossing as refine_curve_curve_crossing;
9pub use curve_curve::{curve_curve_intersect, curve_curve_overlaps_and_crossings};
10pub use curve_surface::{
11 crossing_points, curve_surface_crossings, curve_surface_intersect, curve_surface_overlaps,
12 refine_crossing,
13};
14
15/// Result of a subdivision-based intersection search: either the finite set
16/// of distinct solutions, or a signal that the two shapes coincide/overlap
17/// over a shared region rather than meeting at finitely many isolated
18/// points.
19///
20/// Overlaps are found directly (see [`curve_curve::curve_curve_intersect`]
21/// and [`curve_surface::curve_surface_intersect`]), not inferred from a
22/// search reaching `max_solutions`.
23///
24/// [`Intersections::Coincident`] carries, up to `max_solutions`, the
25/// overlaps' ends, the isolated crossings and points spread evenly over the
26/// overlaps — some callers detect coincidence some other way and just want
27/// every point regardless (see
28/// `geop-lib-booleans`'s `remesh_edges_x_edges`); others want to reuse
29/// them for a follow-up geometric test instead of re-deriving them (see
30/// `remesh_edges_x_faces::find_coincident_pair`). Use [`Intersections::into_vec`]
31/// to get the solutions either way, or match to tell the two cases apart.
32#[derive(Debug, Clone)]
33pub enum Intersections<T> {
34 /// The distinct isolated solutions: the shapes overlap nowhere.
35 Found(Vec<T>),
36 /// The shapes overlap along a shared region: points of it, and the
37 /// isolated solutions besides.
38 Coincident(Vec<T>),
39}
40
41impl<T> Intersections<T> {
42 /// `true` for [`Intersections::Coincident`].
43 pub fn is_coincident(&self) -> bool {
44 matches!(self, Intersections::Coincident(_))
45 }
46
47 /// The solutions found, regardless of variant.
48 pub fn into_vec(self) -> Vec<T> {
49 match self {
50 Intersections::Found(v) | Intersections::Coincident(v) => v,
51 }
52 }
53
54 /// The solutions found, regardless of variant.
55 pub fn as_slice(&self) -> &[T] {
56 match self {
57 Intersections::Found(v) | Intersections::Coincident(v) => v,
58 }
59 }
60
61 pub fn len(&self) -> usize {
62 self.as_slice().len()
63 }
64
65 pub fn is_empty(&self) -> bool {
66 self.as_slice().is_empty()
67 }
68}