pub fn build_pcurve_on_surface_marched(
surface: &NurbsSurface,
curve: &NurbsCurve,
) -> Result<NurbsCurve, String>Expand description
SECTION-PCURVE SEEDED MARCH (t222: cone × ABC 00000327, non-integral genus).
build_pcurve_on_surface inverts every sample by GLOBAL closest point. Where
the carrier surface is COMPRESSED / self-overlapping along the row the
section rides, the global search aliases interior samples onto a DISTANT
preimage sheet, folding the pcurve out past the trim boundary and re-crossing
it. The arrangement then splits the shared section at that phantom crossing,
while the mate face (whose carrier is not folded there) keeps the section
whole — so the two operands’ fragments disagree and the section strands
one-use (non-integral genus). Ground truth for t222: 00000327 face 496’s
v≈0.7875 row maps u∈[0.55,0.81] into a ~0.18mm neighbourhood of the section
endpoint A; the global pcurve for piece 9 folded out to u=0.806 and back,
re-crossing trim edge 349 at v≈0.784, 0.003 below the corner vertex A.
This marches the interior inversions with each seeded from the PREVIOUS
accepted parameters (project_point_to_surface_seeded), so a marched sample
adopts the nearby branch instead of the momentarily-closest distant sheet.
The two ENDPOINT samples keep the deterministic global inversion (they are
the piece’s shared junction vertices — same reasoning as
repair_branch_jumps). Additive + fail-soft: the marched chain is used ONLY
when it CLOSES onto the global far endpoint (its last interior sample is
parameter-adjacent to it, measured against the chain’s own median step);
otherwise the plain global build is returned byte-for-byte. A single-preimage
carrier (the cone side of the same section) marches to the same samples the
global search already had, so it is unchanged there — this only ever alters a
carrier that actually presents multiple preimages within tolerance.
Escape hatch: BREP_SECTION_PCURVE_MARCH=0.