Skip to main content

curve_surface_intersect

Function curve_surface_intersect 

Source
pub fn curve_surface_intersect<S: Scalar>(
    curve: &NurbCurve<S, 4>,
    surface: &NurbSurface<S, 4>,
    max_solutions: usize,
    max_nodes: usize,
    min_subdivision_size: S,
) -> GeopResult<Intersections<(S, Vector2<S>)>>
Expand description

Points where curve crosses (or, in the coplanar case, lies within) surface.

A DFS-with-priority-queue search (restored, against the current [DisjointSet]-based solution representation, from an earlier implementation removed by commit d75bff5): the outer loop always dives from the shallowest still-unexplored (curve segment, surface patch) pair (a level-ordered BinaryHeap, so the search spreads laterally across the whole domain before going deep anywhere), each dive following [dfs]’s own leftmost-branch-first policy and stashing every sibling subtree it skips along the way back onto the queue at its own depth. For an isolated, genuine crossing this behaves essentially like a plain stack-based DFS (hull-overlap pruning quickly discards everything but the local neighborhood of the crossing, regardless of traversal order). But for a coincident or coplanar pair — where hull-overlap pruning can’t narrow anything down, since the curve overlaps the surface almost everywhere along the shared region — a plain LIFO stack tends to exhaustively refine one small neighborhood (feeding [DisjointSet] a long run of adjacent, could_be_equal candidates that all merge into one ever-widening solution) before ever reaching a genuinely different part of the domain. The breadth-first-by-level ordering here instead guarantees an evenly-spread set of solutions across the whole shared region — which is what actually lets a caller reliably treat “found max_solutions distinct solutions” as a coincidence signal in the first place; see e.g. booleans::remesh::remesh_edges_x_faces.

The search stops once max_solutions distinct solutions have been found, or the queue empties (every subtree explored, genuinely fewer solutions than max_solutions) — either way, Ok. If it instead exhausts max_nodes mid-dive without reaching either of those, that’s a genuinely unknown result: this returns an error rather than silently reporting a possibly-incomplete solution set as if it were final. A caller checking len() >= max_solutions to detect coincidence has no way to tell “genuinely converged short of the budget” apart from “ran out of nodes early” otherwise — and the latter is, if anything, itself evidence of extended overlap (an isolated crossing converges in a handful of nodes; only a broad shared region burns through a real budget), so callers relying on that heuristic should treat this error the same way they’d treat hitting max_solutions.