Skip to main content

brep_kernel/csg/imprint/
driver.rs

1use crate::{KernelRefusal, KernelStage, OrRefuse, RefusalClass, MAX_FIT_STATIONS};
2
3// Fit-split instrumentation (2026-11-02): where the section
4// fit's time goes, read only under BREP_PROFILE and printed once per
5// `build_imprints` as `imprint.fit_split`. Zero behaviour: timers only.
6#[derive(Clone, Copy)]
7pub(super) enum FitSplitLane { InitialFit, EvenSliverTotal, RefineTotal, Consistency, Midspan, MidspanRefine, CarrierUpper, Representatives, Seeded, FullRefit, CarrierReadings }
8const FIT_SPLIT_LANES: usize = 11;
9const FIT_SPLIT_NAMES: [&str; FIT_SPLIT_LANES] = ["initial_fit", "even_sliver_total", "refine_total", "consistency", "midspan", "midspan_refine", "carrier_upper", "representatives", "seeded", "full_refit", "carrier_readings"];
10thread_local! {
11    static FIT_SPLIT: std::cell::RefCell<([f64; FIT_SPLIT_LANES], [u64; FIT_SPLIT_LANES])> = const { std::cell::RefCell::new(([0.0; FIT_SPLIT_LANES], [0; FIT_SPLIT_LANES])) };
12}
13pub(super) fn fit_split_started() -> Option<Instant> { crate::profile::profile_enabled().then(Instant::now) }
14pub(super) fn fit_split_add(lane: FitSplitLane, started: Option<Instant>, calls: u64) {
15    if let Some(started) = started {
16        FIT_SPLIT.with(|cell| { let mut cell = cell.borrow_mut(); cell.0[lane as usize] += started.elapsed().as_secs_f64() * 1e3; cell.1[lane as usize] += calls; });
17    }
18}
19pub(super) fn fit_split_timed<T>(lane: FitSplitLane, run: impl FnOnce() -> T) -> T {
20    let started = fit_split_started();
21    let out = run();
22    fit_split_add(lane, started, 1);
23    out
24}
25pub(super) fn fit_split_report() {
26    let (ms, calls) = FIT_SPLIT.with(|cell| std::mem::take(&mut *cell.borrow_mut()));
27    let line = FIT_SPLIT_NAMES.iter().enumerate().map(|(i, name)| format!("{name}={:.2}/{}", ms[i], calls[i])).collect::<Vec<_>>().join(" ");
28    profile_line!("imprint.fit_split {line}");
29    let (calls, stations, points, params_ms, interpolate_ms, measure_ms) = crate::fit::station_set_split_take();
30    profile_line!("imprint.station_set calls={calls} stations={stations} points={points} params_ms={params_ms:.2} interpolate_ms={interpolate_ms:.2} measure_ms={measure_ms:.2}");
31}
32
33/// The degree a marched section is interpolated at (2026-09-27). The march
34/// puts every station on both carriers; the fit decides how far the curve
35/// strays BETWEEN them, and a cubic's O(h^4) there left `BadBoolean`'s
36/// sphere×bore rim 2.5e-7 off the bore with a mean bias of −1.2e-8 that both
37/// trims inherited (+1.14e-6 on the solid). A quintic through the same
38/// stations reads 8.5e-9 and +6e-11 with the same knots and control-point
39/// count. More stations bought the same accuracy on 2026-09-26 and were
40/// reverted for their cost: the watertight tessellator samples every interior
41/// knot, so every scan downstream scales with station count, and a degree does
42/// not add knots. `BREP_SECTION_FIT_DEGREE=3` restores the cubic. The gate on
43/// the mid-span refinement, as a multiple of the fit tolerance (2026-09-27): a
44/// marched section whose unrefined fit misses a carrier between stations by
45/// more than this is UNDERSAMPLED — the 20° cylinder crossing of
46/// `fillet-skew-cylinder-seam-split-20deg` sits 4e-5..8e-5 off, 470 times the
47/// tolerance, at any degree — and only such a section is given true
48/// intersection points until its mid-spans hold. Refining every section cost
49/// more downstream than it returned (the tessellator samples every knot).
50/// `BREP_SECTION_REFINE_GATE` sets the multiple (`on` for
51/// [`SECTION_REFINE_GATE`]). OFF BY DEFAULT: at k = 100 the sequential
52/// blend/direct_edit/imprint/boolean lib set costs +64 % and
53/// `oblique_multi_rim_cone_cap_tearing_push_refuses` goes red; k = 1000 costs
54/// +32 % and leaves the skew union +5.3e-4 off. This global switch stays off.
55/// Independently, a pair of grazing crossings on one trim edge requests a
56/// fit-floor check for that face pair below: those two nearby junctions and
57/// the intervening cap must survive the fit.
58fn section_refine_gate() -> Option<f64> {
59    static GATE: std::sync::OnceLock<Option<f64>> = std::sync::OnceLock::new();
60    *GATE.get_or_init(|| match std::env::var("BREP_SECTION_REFINE_GATE") {
61        Ok(value) if value == "on" => Some(SECTION_REFINE_GATE),
62        Ok(value) => value.parse::<f64>().ok().filter(|gate| *gate >= 0.0),
63        Err(_) => None,
64    })
65}
66
67/// Why a section goes to [`refine_section_against_carriers`].
68#[derive(Clone, Copy, Debug, PartialEq)]
69pub(super) enum SectionRefineRoute {
70    /// `BREP_SECTION_REFINE_GATE`: every section, at the variable's multiple.
71    Global,
72    /// A recovered fit reproduces its march points; check it between them.
73    Recovered,
74    /// A pair of grazing crossings on one trim edge.
75    Grazing,
76    /// The standing fit missed the tolerance it was asked for. The polyline
77    /// deviation can overstate the carrier miss (a band-raised floor reads the
78    /// input's noise), so the refiner's own carrier measure decides: a section
79    /// whose mid-spans already hold the gate leaves at round 0 as `BelowGate`,
80    /// unchanged. Measured 2026-10-04: the StationCeiling fits it reaches ship
81    /// 4.7e-5 to 2.1e-4 off the true section; the refiner brings them to
82    /// 1e-8..3e-8.
83    UnmetRequest,
84    /// A standing fit that MET its request on no other route, whose kept
85    /// stations all lie on both carriers within the fit tolerance, but whose
86    /// curve stands further off the carriers BETWEEN them than the local gate
87    /// ([`carrier_miss_route`]). The polyline it met is the march's chords; an
88    /// interpolant through consistent stations can still ring between them.
89    /// Measured 2026-10-04 (08356963b, 94 cases): 23 of 285 fast-path sections,
90    /// 13 distinct pairs, read their mid-spans up to 6.03e-6 off while every
91    /// kept station read within 1e-7; fixture 28 t217 pair 118x474 read 1.59e-6
92    /// between stations 1.8e-9 off.
93    CarrierMiss,
94}
95
96/// The carrier-miss route for a fit that met its request on no other route:
97/// refine at the local gate when its mid-spans miss the carriers by more than
98/// the fit tolerance WHILE every kept station is within it. Stations off a
99/// carrier are the input's (moving them is the reserved relocation ruling),
100/// so such a section keeps the fast path and is not reported as refined. An
101/// unreadable reading (NaN) never routes.
102pub(super) fn carrier_miss_route(station_upper: f64, midspan_upper: f64, fit_tolerance: f64) -> Option<(f64, SectionRefineRoute)> {
103    (station_upper.is_finite() && midspan_upper.is_finite() && station_upper <= fit_tolerance && midspan_upper > fit_tolerance)
104        .then_some((1.0, SectionRefineRoute::CarrierMiss))
105}
106
107/// The carrier readings [`carrier_miss_route`] decides on: the worst of both
108/// carriers over EVERY point of the section's run (the march's original
109/// stations, kept or dropped by the fit, so a fit through consistent kept
110/// stations cannot hide an inconsistent dropped one), and at the fit's
111/// mid-spans. Projector distances, so upper readings; NaN as soon as any is
112/// unreadable. The mid-span read is the route's TRIGGER, not a bound on the
113/// curve's maximum; [`knot_interior_carrier_upper`] is the finer read.
114pub(super) fn fast_path_carrier_readings(fit: &PolylineFit, run: &[Vec3], first: &NurbsSurface, second: &NurbsSurface) -> (f64, f64) {
115    let read = |surface: &NurbsSurface, point: Vec3| project_point_to_surface(surface, point).map_or(f64::NAN, |projection| projection.distance);
116    let mut station = 0.0f64;
117    for point in run {
118        let (a, b) = (read(first, *point), read(second, *point));
119        station = if a.is_nan() || b.is_nan() || station.is_nan() { f64::NAN } else { station.max(a).max(b) };
120    }
121    (station, midspan_carrier_upper(fit, first, second))
122}
123
124/// SECTION-REFINE READ MEMO (`BREP_SECTION_REFINE_READ_MEMO`, default on, =0 restores;
125/// 2026-11-03). One section refine reads the carrier distance of
126/// the SAME points several times: a representative round reads every mid-span
127/// in [`midspan_misses`], again in [`midspan_carrier_upper`], and, once a
128/// representative has run, the mid-spans and knot interiors a second time on
129/// the unchanged fit. In wasm the planter's carrier upper reads were 103 ms of
130/// its 395 ms section fit. This keeps each `(carrier, point bits)` reading for
131/// one `refine_section_against_carriers_inner` call, error included, so every
132/// caller sees exactly the value (or error) the first read returned. Off, it
133/// is the projector itself.
134pub(super) struct CarrierReads {
135    memo: Option<HashMap<(usize, [u64; 3]), Result<f64, String>>>,
136}
137impl CarrierReads {
138    pub(super) fn off() -> Self {
139        Self { memo: None }
140    }
141    pub(super) fn open() -> Self {
142        Self { memo: switch!(live "BREP_SECTION_REFINE_READ_MEMO", true).then(HashMap::default) }
143    }
144    /// The carrier distance at `point` on carrier `side` (0 first, 1 second).
145    pub(super) fn distance(&mut self, side: usize, surface: &NurbsSurface, point: Vec3) -> Result<f64, String> {
146        let Some(memo) = self.memo.as_mut() else {
147            return project_point_to_surface(surface, point).map(|projection| projection.distance);
148        };
149        memo.entry((side, [point.x.to_bits(), point.y.to_bits(), point.z.to_bits()]))
150            .or_insert_with(|| project_point_to_surface(surface, point).map(|projection| projection.distance))
151            .clone()
152    }
153}
154
155/// The worst of BOTH carriers at the fit's mid-spans, each carrier read on its
156/// own and checked finite BEFORE any max (`f64::max` would drop a NaN from one
157/// carrier and pass the other's reading): NaN as soon as either is unreadable.
158pub(super) fn midspan_carrier_upper(fit: &PolylineFit, first: &NurbsSurface, second: &NurbsSurface) -> f64 {
159    midspan_carrier_upper_read(fit, first, second, &mut CarrierReads::off())
160}
161
162/// [`midspan_carrier_upper`] through a section-refine round's [`CarrierReads`].
163fn midspan_carrier_upper_read(fit: &PolylineFit, first: &NurbsSurface, second: &NurbsSurface, reads: &mut CarrierReads) -> f64 {
164    let mut read = |side: usize, surface: &NurbsSurface, point: Vec3| reads.distance(side, surface, point).unwrap_or(f64::NAN);
165    let mut worst = 0.0f64;
166    for span in 0..fit.parameters.len().saturating_sub(1) {
167        let mid = 0.5 * (fit.parameters[span] + fit.parameters[span + 1]);
168        let (a, b) = match fit.curve.evaluate(mid) {
169            Ok(point) => (read(0, first, point), read(1, second, point)),
170            Err(_) => (f64::NAN, f64::NAN),
171        };
172        if !(a.is_finite() && b.is_finite()) || worst.is_nan() {
173            return f64::NAN;
174        }
175        worst = worst.max(a).max(b);
176    }
177    worst
178}
179
180/// The curve's worst distance from both carriers at the quarter points of
181/// every one of its own knot spans (its native pieces, where an interpolant
182/// is extremal between knots), NaN as soon as any read is unreadable. Sampled
183/// and projector-based: an upper reading at its points, not a certified
184/// maximum of the curve.
185pub(super) fn knot_interior_carrier_upper(curve: &NurbsCurve, first: &NurbsSurface, second: &NurbsSurface) -> f64 {
186    knot_interior_carrier_upper_read(curve, first, second, &mut CarrierReads::off())
187}
188
189/// [`knot_interior_carrier_upper`] through a section-refine round's [`CarrierReads`].
190fn knot_interior_carrier_upper_read(curve: &NurbsCurve, first: &NurbsSurface, second: &NurbsSurface, reads: &mut CarrierReads) -> f64 {
191    let mut read = |side: usize, surface: &NurbsSurface, point: Vec3| reads.distance(side, surface, point).unwrap_or(f64::NAN);
192    let Ok([t0, t1]) = curve.domain() else { return f64::NAN };
193    let mut knots: Vec<f64> = curve.knots.iter().copied().filter(|knot| *knot >= t0 && *knot <= t1).collect();
194    knots.dedup();
195    let mut worst = 0.0f64;
196    for pair in knots.windows(2) {
197        if pair[1] <= pair[0] {
198            continue;
199        }
200        for fraction in [0.25, 0.5, 0.75] {
201            let value = match curve.evaluate(pair[0] + (pair[1] - pair[0]) * fraction) {
202                Ok(point) => {
203                    let (a, b) = (read(0, first, point), read(1, second, point));
204                    if a.is_finite() && b.is_finite() { a.max(b) } else { f64::NAN }
205                }
206                Err(_) => f64::NAN,
207            };
208            worst = if worst.is_nan() || !value.is_finite() { f64::NAN } else { worst.max(value) };
209        }
210    }
211    worst
212}
213
214/// The refine route and its gate (a multiple of the fit tolerance) for one
215/// section, or `None` for the fast path.
216///
217/// A standing fit that MET its request takes exactly the routes that existed
218/// before: the global gate alone when set, else a recovered fit, else a grazing
219/// pair (read lazily, only when the first two do not apply), else nothing — it
220/// goes straight to `process_curve`, untouched.
221///
222/// A fit that MISSED its request is always refined, at the local gate 1, or at
223/// a tighter global gate. A looser global gate does not mask the miss: seam 60
224/// was a recovered fit missing its 1e-7 request, and `BREP_SECTION_REFINE_GATE`
225/// above 1 used to let it through. Its route stays `UnmetRequest` under any
226/// global gate, so its cost reads apart from the global gate's.
227pub(super) fn section_refine_route(
228    global: Option<f64>,
229    recovered: bool,
230    grazing: impl FnOnce() -> bool,
231    met_requested: bool,
232) -> Option<(f64, SectionRefineRoute)> {
233    if !met_requested {
234        return Some((global.map_or(1.0, |gate| gate.min(1.0)), SectionRefineRoute::UnmetRequest));
235    }
236    global
237        .map(|gate| (gate, SectionRefineRoute::Global))
238        .or_else(|| recovered.then_some((1.0, SectionRefineRoute::Recovered)))
239        .or_else(|| grazing().then_some((1.0, SectionRefineRoute::Grazing)))
240}
241
242/// The multiple `BREP_SECTION_REFINE_GATE=on` uses: the smallest measured
243/// that trips the skew union's undersampled sections and leaves fixture 22 as
244/// it was (k = 10 flips it).
245const SECTION_REFINE_GATE: f64 = 100.0;
246
247/// The axis-aligned box of a curve's control points (rational ones read at
248/// their Cartesian position), grown by `margin` on every side: a box the
249/// curve cannot leave, since a NURBS curve with positive weights lies in its
250/// control hull.
251pub(super) fn control_hull_box(curve: &NurbsCurve, margin: f64) -> [Vec3; 2] {
252    let mut low = Vec3::new(f64::INFINITY, f64::INFINITY, f64::INFINITY);
253    let mut high = Vec3::new(f64::NEG_INFINITY, f64::NEG_INFINITY, f64::NEG_INFINITY);
254    for control in &curve.control_points {
255        let w = if control.w.abs() > 1e-300 { control.w } else { 1.0 };
256        let point = Vec3::new(control.x / w, control.y / w, control.z / w);
257        low = Vec3::new(low.x.min(point.x), low.y.min(point.y), low.z.min(point.z));
258        high = Vec3::new(high.x.max(point.x), high.y.max(point.y), high.z.max(point.z));
259    }
260    [
261        Vec3::new(low.x - margin, low.y - margin, low.z - margin),
262        Vec3::new(high.x + margin, high.y + margin, high.z + margin),
263    ]
264}
265
266/// Whether two closed boxes share a point.
267pub(super) fn boxes_overlap(a: &[Vec3; 2], b: &[Vec3; 2]) -> bool {
268    a[0].x <= b[1].x && b[0].x <= a[1].x && a[0].y <= b[1].y && b[0].y <= a[1].y && a[0].z <= b[1].z && b[0].z <= a[1].z
269}
270
271/// A clipped run's END span can be a sliver: the clip endpoint lands beside a
272/// march station, a spacing ratio to the run's median of 0.011 on
273/// `anotherBooleanFail`, and a global interpolant rings next to such a jump —
274/// the mid-spans near the ends miss their carriers by 1e-3, and bisecting them
275/// only makes the spacing more uneven (2026-09-27). The reduced witness
276/// (`imprint/tests.rs` `sliver_end_evening`) says what makes the jump ring: a
277/// sliver end ON both carriers fits to 3e-8, while the same end 2.7e-4 off
278/// the torus — the vendor's edge curves sit that far off the tori they
279/// bound, and the run's end is solved on such an edge — rings at 2e-3 with
280/// the interior at 3e-13 (2026-09-30). Below
281/// `SLIVER_END_FRACTION` of the median spacing the station beside the
282/// endpoint is RE-SOLVED at the middle of the merged gap as a fresh
283/// intersection point (the default, `BREP_SECTION_SLIVER_END=resolve`) or
284/// dropped (`drop`); `off` restores the unevened fit for a before/after
285/// reading. Returns how many ends were evened.
286///
287/// ON BY DEFAULT since 2026-09-30 (lane K6), behind the measurement in
288/// [`even_sliver_ends_measured`]: only a section whose fit shows the ringing signature
289/// ([`ringing_signature`]) is evened, and the evened fit stands only where it reads closer to
290/// the carriers by [`SLIVER_END_GAIN`]. The ringing is what a marched section carries into the
291/// result: on `anotherBooleanFail` the sphere sections leave the analytic vendor torus by
292/// 3.1e-3 within 1% of their span (measured against the STEP file's own `TOROIDAL_SURFACE`,
293/// not the projector), the cut torus faces depart from their edges by 2.6e-4 and the result
294/// shell's vector-area closure reads 1.88e-4 against a 3.83e-5 bar. Evened, the sections sit
295/// 5e-8 off, the shell closes at 1.7e-6 and the boolean takes 2.3 s instead of 9.1 s. The
296/// 2026-09-27 shelving reason was three fixture-25 exact-value pins moving under a blanket
297/// `resolve`; a blanket default also refused fixture 28's reversed subtract and broke fixture
298/// 26's idempotence, which is why the signature gates it. Fixture 25's sections do not show
299/// the signature at the shipped contrast and its pins stand.
300fn even_sliver_ends(
301    section: &mut Vec<Vec3>,
302    first: &NurbsSurface,
303    second: &NurbsSurface,
304    tolerance: f64,
305) -> Result<usize, String> {
306    static MODE: std::sync::OnceLock<String> = std::sync::OnceLock::new();
307    let mode = MODE.get_or_init(|| {
308        std::env::var("BREP_SECTION_SLIVER_END").unwrap_or_else(|_| "resolve".to_string())
309    });
310    if !(mode == "drop" || mode == "resolve") {
311        return Ok(0);
312    }
313    let mut evened = 0;
314    // One sliver at a time: each removal changes the spans it sits between.
315    for _ in 0..SLIVER_END_ROUNDS {
316        let count = section.len();
317        if count < 6 {
318            break;
319        }
320        let mut chords: Vec<f64> = section.windows(2).map(|pair| pair[1].sub(pair[0]).length()).collect();
321        let lengths = chords.clone();
322        chords.sort_by(f64::total_cmp);
323        let median = chords[chords.len() / 2];
324        let spans = lengths.len();
325        let near_ends = [0, 1, 2, spans - 3, spans - 2, spans - 1];
326        let Some(&sliver) = near_ends
327            .iter()
328            .filter(|&&span| lengths[span] < sliver_end_fraction() * median)
329            .min_by(|a, b| lengths[**a].total_cmp(&lengths[**b]))
330        else {
331            break;
332        };
333        // The sliver's bounding stations are `sliver` and `sliver + 1`; a run
334        // endpoint is never moved. Of the interior ones, remove the one whose
335        // removal leaves the shorter merged span.
336        let mut candidates = Vec::new();
337        for station in [sliver, sliver + 1] {
338            if station == 0 || station == count - 1 {
339                continue;
340            }
341            let merged = section[station + 1].sub(section[station - 1]).length();
342            candidates.push((station, merged));
343        }
344        let Some(&(station, _)) = candidates.iter().min_by(|a, b| a.1.total_cmp(&b.1)) else {
345            break;
346        };
347        if mode == "resolve" {
348            let (before, after) = (section[station - 1], section[station + 1]);
349            let seed = before.add(after).scale(0.5);
350            let reach = 0.5 * after.sub(before).length();
351            match crate::surface_surface_intersection::refine_to_intersection(first, second, seed, tolerance, reach)? {
352                Some(point) => section[station] = point,
353                None => {
354                    section.remove(station);
355                }
356            }
357        } else {
358            section.remove(station);
359        }
360        evened += 1;
361    }
362    Ok(evened)
363}
364
365/// At 0.25 six of `anotherBooleanFail`'s eight sections stay NoProgress
366/// (worst miss 2.7e-4); at 0.5 all eight are evened and fall below the
367/// refinement gate (worst miss 2.8e-3 -> 5.4e-8).
368const SLIVER_END_FRACTION: f64 = 0.5;
369
370/// How many sliver spans one section may lose, at most, over both ends. Every
371/// `anotherBooleanFail` section reaches this cap (the march lands several
372/// closely spaced stations beside each clip end), and the evened fits read
373/// 2.2e-8..5.4e-8 against the carriers under it; whether a higher cap would
374/// read differently was not measured (lane K6, 2026-09-30).
375const SLIVER_END_ROUNDS: usize = 4;
376
377/// `BREP_SECTION_SLIVER_FRACTION` overrides [`SLIVER_END_FRACTION`] for the
378/// measurement that picks it.
379fn sliver_end_fraction() -> f64 {
380    static FRACTION: std::sync::OnceLock<f64> = std::sync::OnceLock::new();
381    *FRACTION.get_or_init(|| {
382        std::env::var("BREP_SECTION_SLIVER_FRACTION")
383            .ok()
384            .and_then(|value| value.parse::<f64>().ok())
385            .filter(|fraction| *fraction > 0.0 && *fraction < 1.0)
386            .unwrap_or(SLIVER_END_FRACTION)
387    })
388}
389
390fn section_fit_degree() -> usize {
391    static DEGREE: std::sync::OnceLock<usize> = std::sync::OnceLock::new();
392    *DEGREE.get_or_init(|| {
393        std::env::var("BREP_SECTION_FIT_DEGREE")
394            .ok()
395            .and_then(|value| value.parse::<usize>().ok())
396            .filter(|degree| (1..=7).contains(degree))
397            .unwrap_or(5)
398    })
399}
400
401/// `BREP_SPAN_BUDGET`, read once: unset leaves [`ImprintOptions::span_budget`]
402/// in charge; `off` forces none; `fit` is the pair's `intersection_fit` at the
403/// operands' scale; a number is an absolute budget.
404#[derive(Clone, Copy, Debug, PartialEq)]
405enum SpanBudgetSwitch {
406    Unset,
407    Off,
408    Fit,
409    Absolute(f64),
410}
411
412fn span_budget_switch() -> SpanBudgetSwitch {
413    static SWITCH: std::sync::OnceLock<SpanBudgetSwitch> = std::sync::OnceLock::new();
414    *SWITCH.get_or_init(|| match std::env::var("BREP_SPAN_BUDGET") {
415        Ok(value) if value == "fit" => SpanBudgetSwitch::Fit,
416        Ok(value) if value == "off" || value == "0" => SpanBudgetSwitch::Off,
417        Ok(value) => value
418            .parse::<f64>()
419            .ok()
420            .filter(|budget| *budget > 0.0)
421            .map_or(SpanBudgetSwitch::Unset, SpanBudgetSwitch::Absolute),
422        Err(_) => SpanBudgetSwitch::Unset,
423    })
424}
425
426/// The span budget every march of this imprint carries: the option under
427/// its environment override. `fit` is what the catalogue names as the
428/// budget a lane may carry, the imprint's `intersection_fit`
429/// (`KernelTolerances::for_scale`), never the corrector's `tolerance`.
430pub(super) fn span_budget(options: &ImprintOptions, scale: f64) -> Option<f64> {
431    match span_budget_switch() {
432        SpanBudgetSwitch::Unset => options.span_budget,
433        SpanBudgetSwitch::Off => None,
434        SpanBudgetSwitch::Fit => Some(crate::KernelTolerances::for_scale(scale, options.tolerance).intersection_fit),
435        SpanBudgetSwitch::Absolute(budget) => Some(budget),
436    }
437}
438
439/// [`ImprintOptions::hermite_sections`] under its environment override.
440fn hermite_sections(options: &ImprintOptions) -> bool {
441    match std::env::var("BREP_HERMITE_SECTIONS").as_deref() {
442        Ok("0") => false,
443        Ok(_) => true,
444        Err(_) => options.hermite_sections,
445    }
446}
447
448/// [`ImprintOptions::exact_iso_pcurves`] under its environment override
449/// (`BREP_EXACT_ISO_PCURVES`: `0`/`off`, `check`, anything else on).
450#[derive(Clone, Copy, Debug, PartialEq, Eq)]
451pub(super) enum ExactIsoPcurves {
452    Off,
453    On,
454    /// The fit lane runs; the exact pcurve is built beside it and compared
455    /// (`ImprintBuilder::exact_pcurve_check`).
456    Check,
457}
458
459fn exact_iso_pcurves(options: &ImprintOptions) -> ExactIsoPcurves {
460    match mode_switch!(live "BREP_EXACT_ISO_PCURVES", options.exact_iso_pcurves) {
461        crate::env_read::Mode::Off => ExactIsoPcurves::Off,
462        crate::env_read::Mode::Check => ExactIsoPcurves::Check,
463        crate::env_read::Mode::On => ExactIsoPcurves::On,
464    }
465}
466
467thread_local! {
468    /// Set by `build_imprints_impl` as it returns, read by the boolean
469    /// right after ([`take_rescue_firings`]) into
470    /// `intersect.march_swap_rescue` and `intersect.clip_swap_rescue`; a
471    /// thread-local rather than a field so the shared record's eight
472    /// literals stay as they are.
473    static RESCUE_FIRINGS: std::cell::Cell<(u64, u64)> = const { std::cell::Cell::new((0, 0)) };
474}
475
476/// `(march-order swap rescues, clip-order swap rescues)` of the last imprint
477/// built on this thread, cleared by the read.
478pub(crate) fn take_rescue_firings() -> (u64, u64) {
479    RESCUE_FIRINGS.with(|cell| cell.replace((0, 0)))
480}
481
482/// [`ImprintOptions::march_starts`] under its environment override, as
483/// `(ordered_starts, consume_starts, tree_seeds)` for every march this
484/// imprint runs. `BREP_MARCH_STARTS`: `0`/`off`; `order` (A3's ordering
485/// alone); `snap` (the ordering with run-through starts consumed); `tree`
486/// (A4 alone); `order+tree`; anything else all three.
487fn march_starts(options: &ImprintOptions, carrier_tree_seeds: bool) -> (bool, bool, bool) {
488    match std::env::var("BREP_MARCH_STARTS").as_deref() {
489        Ok("0") | Ok("off") => (false, false, false),
490        Ok("order") => (true, false, false),
491        Ok("snap") => (true, true, false),
492        Ok("tree") => (false, false, true),
493        Ok("order+tree") => (true, false, true),
494        Ok(_) => (true, true, true),
495        Err(_) => (options.march_starts, options.march_starts, options.march_starts || carrier_tree_seeds),
496    }
497}
498
499/// `BREP_SPAN_CENSUS=<file>`: one line per clipped section, appended, so a
500/// corpus replay can be read for station growth and refine-route firings
501/// under a budget. `BREP_CENSUS_LABEL` names the run on every line.
502fn span_census(line: impl FnOnce() -> String) {
503    if let Ok(path) = std::env::var("BREP_SPAN_CENSUS") {
504        use std::io::Write;
505        if let Ok(mut file) = std::fs::OpenOptions::new().create(true).append(true).open(path) {
506            let label = std::env::var("BREP_CENSUS_LABEL").unwrap_or_default();
507            let _ = writeln!(file, "span-budget census: label {label} {}", line());
508        }
509    }
510}
511
512/// A marched section is held to the fit tolerance against the CARRIERS, not
513/// only against the polyline it was fitted through (2026-09-26). The march
514/// refines every station onto both surfaces to `tolerance * 0.01`, but the
515/// cubic interpolant between stations is measured by `fit_polyline` against the
516/// polyline's own chords, which are further from the true curve than the
517/// interpolant is — so a systematic bias of the interpolant (2.8e-8 mean,
518/// 4.7e-7 worst, inside the bore on `BadBoolean`'s sphere/bore rim at 135
519/// stations) passed every check the fit could make, and both trims inherited it
520/// (+1.14e-6 on the solid's volume, against two independent readings agreeing
521/// to 1e-8). The check below evaluates the fitted curve at every mid-span,
522/// measures it against both carriers, and where it misses `fit tolerance *
523/// SECTION_MIDSPAN_FRACTION` inserts a TRUE intersection point there and
524/// refits. The interpolant's bias falls as h^4, so one round usually suffices.
525/// A round that neither halves the worst miss nor lowers the count of spans
526/// missing is not in that regime — a carrier's C0 crease puts a corner in the
527/// section (fixture 25's pierce solid), where every round only doubles the
528/// stations — so that round is discarded and the loop stops. It is also capped
529/// in rounds and stations, and names how it left.
530/// `BREP_SECTION_REFINE_GATE=off` switches it off, for the before/after reading
531/// and nothing else.
532pub(super) const SECTION_MIDSPAN_FRACTION: f64 = 0.1;
533const SECTION_MIDSPAN_ROUNDS: usize = 4;
534/// A round earns another if it cuts the worst mid-span miss by this factor
535/// (h^4 promises 16 for a halved spacing) OR lowers the count of spans
536/// missing: near the floor a few isolated spans hold the worst while the count
537/// falls, and on a corner the count GROWS round on round.
538const SECTION_MIDSPAN_PROGRESS: f64 = 0.5;
539
540/// Squared distance from `point` to the segment `from`-`to`.
541fn distance_to_segment_sq(point: Vec3, from: Vec3, to: Vec3) -> f64 {
542    point.distance_to_segment_squared(from, to)
543}
544
545/// The carrier miss, in fit tolerances, past which a section the mid-span
546/// refiner left unconverged goes to the 3-D Hermite lane
547/// (`BREP_SECTION_HERMITE_3D`). Measured on the lane's cases: a section that
548/// stalls near its floor (crossing cylinders, a tangent cone: 1.2e-8 to
549/// 1.3e-7 at a 1e-7 tolerance) keeps its fit; the swept rim walls' hairpin
550/// sections miss by 0.1 to 4.4e2.
551const HERMITE_3D_GROSS_MISS: f64 = 1e3;
552
553/// How a mid-span refinement left (`SECTION_MIDSPAN_*`), for the pair trace.
554#[derive(Clone, Copy, Debug, PartialEq)]
555pub(super) enum MidspanExit {
556    /// Every mid-span within the floor of both carriers.
557    Converged,
558    /// The unrefined fit's worst mid-span is within the gate: the section is
559    /// sampled well enough that its degree carries it, and stations would
560    /// cost more downstream than they return.
561    BelowGate,
562    /// Some mid-span still misses and no inserted point could improve it
563    /// (the Newton failed, wandered off the span, or landed on a station
564    /// already present).
565    Stalled,
566    /// A round neither halved the worst miss nor lowered the count of spans
567    /// missing: not the h^4 regime, so the section has a corner the
568    /// interpolant cannot follow. That round's fit is discarded.
569    NoProgress,
570    RoundBudget,
571    StationCeiling,
572}
573
574/// Measure `fit` at every mid-span against both carriers; return the worst
575/// distance, the count of spans that miss `floor` and, for each of them the
576/// Newton could place, the refined intersection point to insert (with the
577/// span's index).
578fn midspan_misses(
579    fit: &PolylineFit,
580    first: &NurbsSurface,
581    second: &NurbsSurface,
582    floor: f64,
583    tolerance: f64,
584    reads: &mut CarrierReads,
585) -> Result<(f64, usize, Vec<(usize, Vec3)>), String> {
586    let mut worst = 0.0f64;
587    let mut missing = 0usize;
588    let mut inserts = Vec::new();
589    for span in 0..fit.parameters.len().saturating_sub(1) {
590        let mid = 0.5 * (fit.parameters[span] + fit.parameters[span + 1]);
591        let point = fit.curve.evaluate(mid)?;
592        let off = reads.distance(0, first, point)?.max(reads.distance(1, second, point)?);
593        worst = worst.max(off);
594        if off <= floor {
595            continue;
596        }
597        missing += 1;
598        // The refined point must stay on THIS span: half its chord is the reach.
599        let reach = 0.5 * fit.kept[span + 1].sub(fit.kept[span]).length();
600        if let Some(refined) = fit_split_timed(FitSplitLane::MidspanRefine, || crate::surface_surface_intersection::refine_to_intersection(
601            first, second, point, tolerance, reach,
602        ))? {
603            inserts.push((span, refined));
604        }
605    }
606    Ok((worst, missing, inserts))
607}
608
609/// Every mid-span miss of `fit` against both carriers, measured and nothing
610/// else: what [`even_sliver_ends_measured`] reads before and after evening.
611/// It refines nothing, so a section without a sliver end pays only the
612/// projections.
613fn midspan_misses_only(fit: &PolylineFit, first: &NurbsSurface, second: &NurbsSurface) -> Result<Vec<f64>, String> {
614    let mut misses = Vec::with_capacity(fit.parameters.len());
615    for span in 0..fit.parameters.len().saturating_sub(1) {
616        let mid = 0.5 * (fit.parameters[span] + fit.parameters[span + 1]);
617        let point = fit.curve.evaluate(mid)?;
618        let off = project_point_to_surface(first, point)?
619            .distance
620            .max(project_point_to_surface(second, point)?.distance);
621        misses.push(off);
622    }
623    Ok(misses)
624}
625
626/// The signature of a global interpolant ringing on a sliver end span: the
627/// worst mid-span miss sits in one of the [`SLIVER_END_SPANS`] spans at either
628/// end, is over the fit `floor`, AND stands [`SLIVER_RING_CONTRAST`] times
629/// above the median of the interior spans. A section sampled too coarsely for the carriers misses
630/// everywhere at once and does not show this; a section with fewer than two
631/// interior spans offers no evidence either way. Returns the end-span worst
632/// and the interior median when the signature is present.
633fn ringing_signature(misses: &[f64], floor: f64) -> Option<(f64, f64)> {
634    let spans = misses.len();
635    if spans < 2 * SLIVER_END_SPANS + 2 {
636        return None;
637    }
638    let ends = misses[..SLIVER_END_SPANS]
639        .iter()
640        .chain(&misses[spans - SLIVER_END_SPANS..])
641        .copied()
642        .fold(0.0f64, f64::max);
643    let mut interior: Vec<f64> = misses[SLIVER_END_SPANS..spans - SLIVER_END_SPANS].to_vec();
644    interior.sort_by(f64::total_cmp);
645    let median = interior[interior.len() / 2];
646    let worst = misses.iter().copied().fold(0.0f64, f64::max);
647    // Below the fit floor there is nothing to even: a 1e-8 miss on a planar
648    // section passed the contrast on fixture 26 and flipped its idempotence
649    // reading while changing nothing a bar could see.
650    (ends > floor.max(sliver_min_miss()) && ends >= worst && ends > sliver_ring_contrast() * median.max(f64::MIN_POSITIVE))
651        .then_some((ends, median))
652}
653
654/// How many spans at each end of a section [`even_sliver_ends`] may even —
655/// the same three it inspects — and where [`ringing_signature`] looks.
656const SLIVER_END_SPANS: usize = 3;
657
658/// The ringing signature's contrast: the end spans' worst mid-span miss over
659/// the interior spans' median. A converged march leaves its interior at
660/// 1e-9 and a sliver end rings at 1e-4..1e-3, so the ratio is 1e5 and up:
661/// `anotherBooleanFail`'s eight sections read 1.3e5..2.2e6 (interior
662/// 6e-10..2.6e-9, ends 1.6e-4..2.8e-3). A section whose interior itself
663/// misses is under-sampled rather than ringing, and evening its end moves a
664/// junction the assembler then cannot repair: fixture 28's pair 822×118
665/// (interior 1.5e-6, ends 1.4e-3, contrast 930) refused the reversed
666/// subtract whenever it was evened, while its pairs 474×118 (1.7e4) and
667/// 842×118 (1.4e5) are evened and build. Fixture 25's two sections read
668/// 2.2e3 and 5.9e3 (interior 2e-8) and keep their stations and their pins.
669/// 3e4 sits at least 4× from the nearest reading on either side
670/// (2026-09-30).
671const SLIVER_RING_CONTRAST: f64 = 3.0e4;
672
673/// `BREP_SECTION_SLIVER_CONTRAST` overrides [`SLIVER_RING_CONTRAST`] for the
674/// measurement that picks it.
675fn sliver_ring_contrast() -> f64 {
676    static CONTRAST: std::sync::OnceLock<f64> = std::sync::OnceLock::new();
677    *CONTRAST.get_or_init(|| {
678        std::env::var("BREP_SECTION_SLIVER_CONTRAST")
679            .ok()
680            .and_then(|value| value.parse::<f64>().ok())
681            .filter(|contrast| *contrast >= 1.0)
682            .unwrap_or(SLIVER_RING_CONTRAST)
683    })
684}
685
686/// `BREP_SECTION_SLIVER_MIN_MISS` raises the absolute floor under the end
687/// spans' worst miss, for measurement only (the shipped floor is the fit
688/// tolerance).
689fn sliver_min_miss() -> f64 {
690    static MIN: std::sync::OnceLock<f64> = std::sync::OnceLock::new();
691    *MIN.get_or_init(|| {
692        std::env::var("BREP_SECTION_SLIVER_MIN_MISS")
693            .ok()
694            .and_then(|value| value.parse::<f64>().ok())
695            .filter(|miss| *miss >= 0.0)
696            .unwrap_or(0.0)
697    })
698}
699
700/// How a sliver-end evening left, for the census line.
701#[derive(Clone, Copy, Debug, PartialEq)]
702pub(super) enum SliverEvening {
703    /// No end span was shorter than the fraction, or the hatch is `off`.
704    NoSliver,
705    /// A sliver end exists but the unevened fit does not show the ringing
706    /// signature ([`ringing_signature`]): its stations stand.
707    NotRinging { slivers: usize, worst: f64 },
708    /// The evened section's fit reads at least [`SLIVER_END_GAIN`] times
709    /// closer to the carriers at its worst mid-span: the evened fit stands.
710    Accepted { slivers: usize, before: f64, after: f64, interior: f64 },
711    /// Evening did not earn its keep: the unevened fit stands, the stations
712    /// untouched.
713    Rejected { slivers: usize, before: f64, after: f64, interior: f64 },
714}
715
716/// A sliver-end evening must earn its keep: the evened fit stands only when
717/// its worst mid-span miss against both carriers falls by at least this
718/// factor. Measured on 2026-09-30 against the blanket default: `resolve` on
719/// every section that HAS a sliver end refused the reversed subtract of
720/// fixture 28 (`march_swap_rescue_recovers_reversed_subtract_t217`, an open
721/// loop) and made fixture 26's union read differently before and after
722/// operand splitting, while on `anotherBooleanFail` (2.8e-3 → 5e-8) and
723/// fixture 25 (2.0e-5 / 3.4e-5 → 9.2e-7) it cut the miss by 20× to 5e4×. A
724/// section whose evened fit is not clearly better keeps its stations.
725const SLIVER_END_GAIN: f64 = 2.0;
726
727/// [`even_sliver_ends`] with the measurement that decides whether it stands:
728/// fit the section as marched; if its mid-spans show the ringing signature
729/// ([`ringing_signature`]), even its sliver ends, fit again, and keep the
730/// evened fit only when its worst mid-span wins by [`SLIVER_END_GAIN`].
731/// Returns the section, its fit, the recovery flag of the fit that stands and
732/// the outcome.
733pub(super) fn even_sliver_ends_measured(
734    section: Vec<Vec3>,
735    first: &NurbsSurface,
736    second: &NurbsSurface,
737    tolerance: f64,
738    fit_tolerance: f64,
739    maximum_fit_points: usize,
740    local_fit: bool,
741) -> Result<(Vec<Vec3>, PolylineFit, bool, SliverEvening), String> {
742    fit_split_timed(FitSplitLane::EvenSliverTotal, || even_sliver_ends_measured_inner(section, first, second, tolerance, fit_tolerance, maximum_fit_points, local_fit))
743}
744
745fn even_sliver_ends_measured_inner(
746    section: Vec<Vec3>,
747    first: &NurbsSurface,
748    second: &NurbsSurface,
749    tolerance: f64,
750    fit_tolerance: f64,
751    maximum_fit_points: usize,
752    local_fit: bool,
753) -> Result<(Vec<Vec3>, PolylineFit, bool, SliverEvening), String> {
754    let (fit, recovered) = fit_split_timed(FitSplitLane::InitialFit, || crate::fit::fit_polyline_of_degree_with_recovery(
755        &section,
756        fit_tolerance,
757        maximum_fit_points,
758        local_fit,
759        section_fit_degree(),
760    ))?;
761    let mut evened = section.clone();
762    let slivers = even_sliver_ends(&mut evened, first, second, tolerance)?;
763    if slivers == 0 {
764        return Ok((section, fit, recovered, SliverEvening::NoSliver));
765    }
766    let misses = midspan_misses_only(&fit, first, second)?;
767    let Some((before, interior)) = ringing_signature(&misses, fit_tolerance) else {
768        let worst = misses.iter().copied().fold(0.0f64, f64::max);
769        return Ok((section, fit, recovered, SliverEvening::NotRinging { slivers, worst }));
770    };
771    let (evened_fit, evened_recovered) = crate::fit::fit_polyline_of_degree_with_recovery(
772        &evened,
773        fit_tolerance,
774        maximum_fit_points,
775        local_fit,
776        section_fit_degree(),
777    )?;
778    let after_misses = midspan_misses_only(&evened_fit, first, second)?;
779    let after = after_misses.iter().copied().fold(0.0f64, f64::max);
780    if let Ok(path) = std::env::var("BREP_SECTION_SLIVER_CENSUS") {
781        use std::io::Write;
782        if let Ok(mut file) = std::fs::OpenOptions::new().create(true).append(true).open(path) {
783            let chords = |points: &[Vec3]| points.windows(2).map(|pair| format!("{:.4e}", pair[1].sub(pair[0]).length())).collect::<Vec<_>>().join(" ");
784            let fmt = |values: &[f64]| values.iter().map(|value| format!("{value:.2e}")).collect::<Vec<_>>().join(" ");
785            let _ = writeln!(file, "sliver-end detail: stations {} -> {} kept {} -> {}", section.len(), evened.len(), fit.kept.len(), evened_fit.kept.len());
786            let _ = writeln!(file, "sliver-end detail: chords before: {}", chords(&section));
787            let _ = writeln!(file, "sliver-end detail: chords after:  {}", chords(&evened));
788            let _ = writeln!(file, "sliver-end detail: misses before: {}", fmt(&misses));
789            let _ = writeln!(file, "sliver-end detail: misses after:  {}", fmt(&after_misses));
790            let _ = writeln!(file, "sliver-end detail: ends before: {:?} {:?}", section[0], section[section.len() - 1]);
791            let _ = writeln!(file, "sliver-end detail: ends after:  {:?} {:?}", evened[0], evened[evened.len() - 1]);
792        }
793    }
794    if after * SLIVER_END_GAIN <= before {
795        Ok((evened, evened_fit, evened_recovered, SliverEvening::Accepted { slivers, before, after, interior }))
796    } else {
797        Ok((section, fit, recovered, SliverEvening::Rejected { slivers, before, after, interior }))
798    }
799}
800
801/// Refit `section` until its mid-spans sit within `floor` of both carriers,
802/// inserting true intersection points where they do not. Returns the fit that
803/// stands, the worst mid-span miss it still carries, the unrefined fit's worst
804/// (what the gate read), the rounds spent and the exit.
805/// Keep the single best measured refiner state (root grant 2026-10-04,
806/// accepted-representative sections only): replaced when `worst` is finite and
807/// no larger than the kept one (ties go to the later state). An unreadable
808/// reading is never kept. At most one snapshot is held.
809pub(super) fn keep_best_state<S>(best: &mut Option<(S, f64)>, state: impl FnOnce() -> S, worst: f64) {
810    if worst.is_finite() && best.as_ref().is_none_or(|(_, kept)| worst <= *kept) {
811        *best = Some((state(), worst));
812    }
813}
814
815/// The rollback a budget-type exit (RoundBudget, StationCeiling, Stalled)
816/// takes: on a section where an ACCEPTED representative round ran, the kept
817/// best state when its COMMON reading is strictly lower than the current
818/// state's common reading on the same instrument (both carriers, finite, at the
819/// fit's mid-spans and its own knot-span quarter points). Otherwise `None`:
820/// the exit returns the current state exactly as before, with nothing cloned.
821/// An unreadable current reading never rolls back (it is not hidden).
822pub(super) fn take_rollback<S>(best: &mut Option<(S, f64)>, current_common: f64, representative_ran: bool) -> Option<(S, f64)> {
823    let lower = matches!(best, Some((_, kept)) if representative_ran && current_common.is_finite() && *kept < current_common);
824    if lower { best.take() } else { None }
825}
826
827/// Which fit a refinement RETURNED: a receipt for controls, deciding nothing.
828#[derive(Clone, Copy, Debug, PartialEq)]
829pub(super) enum RefinedFitSource {
830    /// The standing fit the caller passed in.
831    Standing,
832    /// The original full refit of the run, made directly (`full-unmatched`,
833    /// or the retry after an unreadable representative or a seeded stall).
834    FullRefit,
835    /// The seeded (forced-station) call and its own path: a `Fallback` path
836    /// IS the original full refit.
837    Seeded(crate::fit::SeededPath),
838    /// The representative candidate call and its own path: a `Fallback` path
839    /// IS the original full refit.
840    Representatives(crate::fit::SeededPath),
841    /// The best measured state the budget-exit rollback restored.
842    Rollback,
843}
844
845/// The refiner's receipt: whether the run took the representative route at
846/// all, and which fit it returned (None on an error return). Production
847/// callers discard it; only controls read it.
848#[allow(dead_code)]
849#[derive(Clone, Copy, Debug, Default, PartialEq)]
850pub(super) struct RefineReceipt {
851    pub original_consistent: bool,
852    pub returned: Option<RefinedFitSource>,
853}
854
855pub(super) fn refine_section_against_carriers(
856    section: &mut Vec<Vec3>,
857    fit: PolylineFit,
858    first: &NurbsSurface,
859    second: &NurbsSurface,
860    fit_tolerance: f64,
861    tolerance: f64,
862    local_fit: bool,
863    gate: f64,
864) -> Result<(PolylineFit, f64, f64, usize, MidspanExit), String> {
865    // `BREP_SECTION_REPRESENTATIVES=0` restores the seeded path everywhere for
866    // an attribution A/B only; read here, once per call, as before.
867    let representatives = std::env::var("BREP_SECTION_REPRESENTATIVES").as_deref() != Ok("0");
868    refine_section_against_carriers_with(section, fit, first, second, fit_tolerance, tolerance, local_fit, gate, representatives, &mut RefineReceipt::default())
869}
870
871/// [`refine_section_against_carriers`] with the representative switch passed
872/// in (the env hatch's value, so a control can take the seeded route without
873/// touching the process environment) and a receipt of the fit returned.
874#[allow(clippy::too_many_arguments)]
875pub(super) fn refine_section_against_carriers_with(
876    section: &mut Vec<Vec3>,
877    fit: PolylineFit,
878    first: &NurbsSurface,
879    second: &NurbsSurface,
880    fit_tolerance: f64,
881    tolerance: f64,
882    local_fit: bool,
883    gate: f64,
884    representatives: bool,
885    receipt: &mut RefineReceipt,
886) -> Result<(PolylineFit, f64, f64, usize, MidspanExit), String> {
887    let started = fit_split_started();
888    let out = refine_section_against_carriers_inner(section, fit, first, second, fit_tolerance, tolerance, local_fit, gate, representatives, receipt);
889    fit_split_add(FitSplitLane::RefineTotal, started, 1);
890    out
891}
892
893#[allow(clippy::too_many_arguments)]
894fn refine_section_against_carriers_inner(
895    section: &mut Vec<Vec3>,
896    fit: PolylineFit,
897    first: &NurbsSurface,
898    second: &NurbsSurface,
899    fit_tolerance: f64,
900    tolerance: f64,
901    local_fit: bool,
902    gate: f64,
903    representatives: bool,
904    receipt: &mut RefineReceipt,
905) -> Result<(PolylineFit, f64, f64, usize, MidspanExit), String> {
906    // A reused receipt starts clean, so an error return leaves `returned`
907    // None as documented, never a previous call's value.
908    *receipt = RefineReceipt::default();
909    // Which fit `fit` currently is, and which fit `previous` holds.
910    let mut fit_source = RefinedFitSource::Standing;
911    let mut previous_source = RefinedFitSource::Standing;
912    let floor = fit_tolerance * SECTION_MIDSPAN_FRACTION;
913    let mut unrefined = f64::NAN;
914    let mut fit = fit;
915    let mut rounds = 0usize;
916    let mut previous: Option<(PolylineFit, f64, usize)> = None;
917    // Every true intersection point inserted so far: the residual-driven bend
918    // witnesses, which the refit must keep as stations.
919    let mut inserted_points: Vec<Vec3> = Vec::new();
920    // `BREP_SECTION_REFINE_CENSUS`: one `section-refine round:` line per round,
921    // bound to its section by the run's head and tail, so a stall can be read
922    // round by round (debug only; nothing below reads it).
923    let round_census = std::env::var("BREP_SECTION_REFINE_CENSUS").ok();
924    let (head, tail) = (section[0], section[section.len() - 1]);
925    // Whether EVERY original point of the run lies on both carriers within the
926    // fit tolerance (projector upper readings, NaN = no): only such a run takes
927    // the refiner-specific representative candidate below. A run with any
928    // point off a carrier keeps the existing seeded path exactly (moving or
929    // discounting input points is the reserved relocation ruling).
930    // `representatives` false (the `BREP_SECTION_REPRESENTATIVES=0` hatch)
931    // restores the seeded path everywhere for an attribution A/B only.
932    let consistency_started = fit_split_started();
933    let original_consistent = representatives
934        && section.iter().all(|point| {
935            let a = project_point_to_surface(first, *point).map_or(f64::NAN, |projection| projection.distance);
936            let b = project_point_to_surface(second, *point).map_or(f64::NAN, |projection| projection.distance);
937            a.is_finite() && b.is_finite() && a <= fit_tolerance && b <= fit_tolerance
938        });
939    receipt.original_consistent = original_consistent;
940    fit_split_add(FitSplitLane::Consistency, consistency_started, 1);
941    let mut refit_path = String::from("standing");
942    let mut refit_seeds = 0usize;
943    let mut refit_seeds_kept = 0usize;
944    let mut refit_seeds_outside_pool = 0usize;
945    let mut refit_pool = 0usize;
946    let mut refit_pool_discarded = 0usize;
947    let mut refit_pool_floor = f64::NAN;
948    let mut refit_seed_min_chord = f64::NAN;
949    // Trace only: what the closest seed pair is made of (kept station or
950    // refiner insert at each end), to place the near pair upstream.
951    let mut refit_seed_min_pair = "n/a";
952    // Trace only: every seed the full refit's pool rejects, by ORIGIN (a march
953    // station of the run, or a refiner insert) and by REASON (dropped by
954    // `station_pool`'s simplification, or kept by it and then conditioned
955    // away as a near-duplicate): [march simplified, march conditioned,
956    // insert simplified, insert conditioned].
957    let mut refit_rejected = [0usize; 4];
958    // Fits made for the round being judged (2 when its seeded fit stalled and
959    // the full refit was tried as well), and that retry's own cost.
960    let mut refit_trials = 1usize;
961    let mut retry_ms = 0.0f64;
962    // Whether the fit judged this round is an ACCEPTED seeded fit (not merely
963    // a seeded call: a seeded call that fell back already IS the full refit).
964    let mut seeded_refit = false;
965    // Whether the fit judged this round is an ACCEPTED representative
966    // candidate, and what that candidate call spent (its own interpolations
967    // and whether it ended on the full refit), kept apart from the fit's
968    // report, which on a fallback must stay the full refit's to the bit.
969    let mut representative_fit = false;
970    let mut refit_cost = crate::fit::RepresentativeCost::default();
971    // Whether an ACCEPTED representative round ran on this section, and the one
972    // best measured (fit, section) state kept for its budget exits.
973    let mut representative_ran = false;
974    let mut best_state: Option<((PolylineFit, Vec<Vec3>), f64)> = None;
975    let mut reads = CarrierReads::open();
976    loop {
977        // On an accepted representative candidate a read or refinement ERROR is
978        // not a refusal: the section takes the original full refit of the same
979        // run instead, as an unreadable read does below.
980        let (mut worst, missing, inserts) = match fit_split_timed(FitSplitLane::Midspan, || midspan_misses(&fit, first, second, floor, tolerance, &mut reads)) {
981            Ok(reading) => reading,
982            Err(_) if representative_fit => {
983                representative_fit = false;
984                seeded_refit = false;
985                let maximum_points = section.len().min(MAX_FIT_STATIONS);
986                fit = fit_split_timed(FitSplitLane::FullRefit, || fit_polyline_of_degree(section, fit_tolerance, maximum_points, local_fit, section_fit_degree()))?;
987                fit_source = RefinedFitSource::FullRefit;
988                refit_path = String::from("full-after-unreadable-representative");
989                refit_trials += 1;
990                refit_cost.full_refit = true;
991                continue;
992            }
993            Err(error) => return Err(error),
994        };
995        // An ACCEPTED representative candidate is judged on more than its
996        // mid-spans: both carriers must read finite at every mid-span and at
997        // the quarter points of the curve's own knot spans, and its worst is
998        // the worse of the two reads (sampled, projector upper readings; the
999        // carrier target is unchanged). An unreadable read never passes: the
1000        // section takes the original full refit of the same run instead.
1001        if representative_fit {
1002            let interior = fit_split_timed(FitSplitLane::CarrierUpper, || knot_interior_carrier_upper_read(&fit.curve, first, second, &mut reads));
1003            let midspans = fit_split_timed(FitSplitLane::CarrierUpper, || midspan_carrier_upper_read(&fit, first, second, &mut reads));
1004            if interior.is_finite() && midspans.is_finite() {
1005                worst = worst.max(interior).max(midspans);
1006            } else {
1007                representative_fit = false;
1008                seeded_refit = false;
1009                let maximum_points = section.len().min(MAX_FIT_STATIONS);
1010                fit = fit_split_timed(FitSplitLane::FullRefit, || fit_polyline_of_degree(section, fit_tolerance, maximum_points, local_fit, section_fit_degree()))?;
1011                fit_source = RefinedFitSource::FullRefit;
1012                refit_path = String::from("full-after-unreadable-representative");
1013                refit_trials += 1;
1014                refit_cost.full_refit = true;
1015                continue;
1016            }
1017        }
1018        if let Some(path) = &round_census {
1019            use std::io::Write;
1020            if let Ok(mut file) = std::fs::OpenOptions::new().create(true).append(true).open(path) {
1021                let _ = writeln!(
1022                    file,
1023                    "section-refine round: head ({:.9}, {:.9}, {:.9}) tail ({:.9}, {:.9}, {:.9}) round {rounds} fit {refit_path} trials {refit_trials} retry_ms {retry_ms:.3} kept {} seeds {refit_seeds} seeds_kept {refit_seeds_kept} seeds_outside_pool {refit_seeds_outside_pool} seed_min_chord {refit_seed_min_chord:.3e} seed_min_pair {refit_seed_min_pair} rejected_march_simplified {} rejected_march_conditioned {} rejected_insert_simplified {} rejected_insert_conditioned {} pool {refit_pool} pool_discarded {refit_pool_discarded} pool_floor {refit_pool_floor:.3e} exit {:?} deviation {:.3e} floor {:.3e} run {} worst {:.3e} missing {} inserts_offered {} representatives {} witnesses {} candidate_fits {} candidate_full_refit {} candidate_end_offsets {:.3e}/{:.3e} seed_role {}",
1024                    head.x, head.y, head.z, tail.x, tail.y, tail.z,
1025                    fit.kept.len(),
1026                    refit_rejected[0], refit_rejected[1], refit_rejected[2], refit_rejected[3], fit.report.exit, fit.report.deviation, fit.report.floor, section.len(), worst, missing, inserts.len(),
1027                    refit_cost.representatives, refit_cost.witnesses, refit_cost.candidate_fits, refit_cost.full_refit,
1028                    refit_cost.start_offset, refit_cost.end_offset,
1029                    // On the representative path the seeds counted above are
1030                    // WITNESSES (not forced); on the seeded path they are forced.
1031                    if original_consistent { "witness" } else { "forced" }
1032                );
1033                // Trace only: where the full refit's band-raised floor comes
1034                // from on THIS run, and whether the run's own points are on
1035                // the carriers (input-consistent) or not. The band is
1036                // `dropped_band`'s reading (largest distance of a point the
1037                // pool drops from the segment between its surviving
1038                // neighbours); its point is classified as simplified away or
1039                // conditioned away, with its carrier distance and its gap to
1040                // the nearest run neighbour. Projector distances are upper
1041                // readings.
1042                let pool = crate::fit::polyline_station_pool(section, fit_tolerance);
1043                let simplified = crate::fit::simplify_polyline_indices(section, fit_tolerance);
1044                let mut band = (0.0f64, usize::MAX);
1045                for pair in pool.windows(2) {
1046                    for index in pair[0] + 1..pair[1] {
1047                        let off = distance_to_segment_sq(section[index], section[pair[0]], section[pair[1]]).sqrt();
1048                        if off > band.0 {
1049                            band = (off, index);
1050                        }
1051                    }
1052                }
1053                let carrier = |point: Vec3| -> f64 {
1054                    let a = project_point_to_surface(first, point).map_or(f64::NAN, |projection| projection.distance);
1055                    let b = project_point_to_surface(second, point).map_or(f64::NAN, |projection| projection.distance);
1056                    if a.is_nan() || b.is_nan() { f64::NAN } else { a.max(b) }
1057                };
1058                let mut run_carrier = 0.0f64;
1059                for point in section.iter() {
1060                    let off = carrier(*point);
1061                    run_carrier = if off.is_nan() || run_carrier.is_nan() { f64::NAN } else { run_carrier.max(off) };
1062                }
1063                let (kind, band_carrier, gap) = if band.1 == usize::MAX {
1064                    ("none", f64::NAN, f64::NAN)
1065                } else {
1066                    let index = band.1;
1067                    let kind = if simplified.binary_search(&index).is_ok() { "conditioned" } else { "simplified" };
1068                    let mut gap = f64::INFINITY;
1069                    if index > 0 {
1070                        gap = gap.min(section[index].sub(section[index - 1]).length());
1071                    }
1072                    if index + 1 < section.len() {
1073                        gap = gap.min(section[index + 1].sub(section[index]).length());
1074                    }
1075                    (kind, carrier(section[index]), gap)
1076                };
1077                let _ = writeln!(
1078                    file,
1079                    "section-refine band: head ({:.9}, {:.9}, {:.9}) tail ({:.9}, {:.9}, {:.9}) round {rounds} run {} pool {} tolerance {:.3e} band {:.3e} band_index {} of {} band_kind {kind} band_point_carrier_upper {band_carrier:.3e} band_point_gap {gap:.3e} run_carrier_upper {run_carrier:.3e}",
1080                    head.x, head.y, head.z, tail.x, tail.y, tail.z,
1081                    section.len(), pool.len(), fit_tolerance, band.0,
1082                    if band.1 == usize::MAX { -1 } else { band.1 as i64 }, section.len()
1083                );
1084            }
1085        }
1086        if rounds == 0 {
1087            unrefined = worst;
1088        }
1089        // The rollback path's COMMON reading, only once an accepted
1090        // representative round has run and only on a run the refit can hold
1091        // (<= MAX_FIT_STATIONS): both carriers, finite, at the fit's mid-spans
1092        // and its own knot-span quarter points, for EVERY state compared
1093        // (representative, standing or full alike). One snapshot, the fit and
1094        // the run it was measured on as one coherent pair: its payload is one
1095        // PolylineFit and at most MAX_FIT_STATIONS points. Off this path
1096        // nothing is read or cloned.
1097        let mut current_common = f64::NAN;
1098        if representative_ran && section.len() <= MAX_FIT_STATIONS {
1099            let interior = fit_split_timed(FitSplitLane::CarrierUpper, || knot_interior_carrier_upper_read(&fit.curve, first, second, &mut reads));
1100            let midspans = fit_split_timed(FitSplitLane::CarrierUpper, || midspan_carrier_upper_read(&fit, first, second, &mut reads));
1101            current_common = if interior.is_finite() && midspans.is_finite() { interior.max(midspans) } else { f64::NAN };
1102            keep_best_state(&mut best_state, || (fit.clone(), section.clone()), current_common);
1103        }
1104        if worst <= floor {
1105            receipt.returned = Some(fit_source);
1106            return Ok((fit, worst, unrefined, rounds, MidspanExit::Converged));
1107        }
1108        if rounds == 0 && worst <= gate {
1109            receipt.returned = Some(fit_source);
1110            return Ok((fit, worst, unrefined, rounds, MidspanExit::BelowGate));
1111        }
1112        if let Some((earlier, earlier_worst, earlier_missing)) = previous.take() {
1113            // A round that did not earn its keep is discarded whole: the fit
1114            // of the last round that did stands (on a corner, the unrefined
1115            // fit), not whichever of the two happens to read a smaller max.
1116            if worst > earlier_worst * SECTION_MIDSPAN_PROGRESS && missing >= earlier_missing {
1117                // A SEEDED round that did not earn its keep is refitted once
1118                // with the original full refit of the same denser run, and
1119                // that is judged against the same earlier round before the
1120                // section stops. The seeded fit keeps fewer stations; on the
1121                // helmet's 2036x3009 section that gave back the whole of the
1122                // full refit's gain (6.335e-6 stood where 5.596e-7 was
1123                // reached). The full refit is the round the refiner made
1124                // before the seeded entry existed; only a round that fails
1125                // both ends the section, exactly as before.
1126                if seeded_refit {
1127                    seeded_refit = false;
1128                    let maximum_points = section.len().min(MAX_FIT_STATIONS);
1129                    let retry_started = round_census.is_some().then(Instant::now);
1130                    fit = fit_split_timed(FitSplitLane::FullRefit, || fit_polyline_of_degree(section, fit_tolerance, maximum_points, local_fit, section_fit_degree()))?;
1131                    fit_source = RefinedFitSource::FullRefit;
1132                    // Trace: one more fit for the SAME round, its cost, and no
1133                    // seed counters carried over from the rejected seeded fit.
1134                    refit_path = String::from("full-after-seeded-stall");
1135                    // Every fit this round made: the candidate's (or the seeded
1136                    // call's one) plus this retry.
1137                    refit_trials += 1;
1138                    retry_ms = retry_started.map_or(0.0, |started| started.elapsed().as_secs_f64() * 1e3);
1139                    refit_seeds = 0;
1140                    refit_seeds_kept = 0;
1141                    refit_seeds_outside_pool = 0;
1142                    refit_seed_min_chord = f64::NAN;
1143                    refit_seed_min_pair = "n/a";
1144                    refit_rejected = [0; 4];
1145                    representative_fit = false;
1146                    // Keep the candidate's own counts; the retry is the full refit.
1147                    refit_cost.full_refit = true;
1148                    previous = Some((earlier, earlier_worst, earlier_missing));
1149                    continue;
1150                }
1151                receipt.returned = Some(previous_source);
1152                return Ok((earlier, earlier_worst, unrefined, rounds, MidspanExit::NoProgress));
1153            }
1154        }
1155        if inserts.is_empty() {
1156            if let Some(((kept_fit, kept_run), kept_common)) = take_rollback(&mut best_state, current_common, representative_ran) {
1157                *section = kept_run;
1158                receipt.returned = Some(RefinedFitSource::Rollback);
1159                return Ok((kept_fit, kept_common, unrefined, rounds, MidspanExit::Stalled));
1160            }
1161            receipt.returned = Some(fit_source);
1162            return Ok((fit, worst, unrefined, rounds, MidspanExit::Stalled));
1163        }
1164        if rounds >= SECTION_MIDSPAN_ROUNDS {
1165            if let Some(((kept_fit, kept_run), kept_common)) = take_rollback(&mut best_state, current_common, representative_ran) {
1166                *section = kept_run;
1167                receipt.returned = Some(RefinedFitSource::Rollback);
1168                return Ok((kept_fit, kept_common, unrefined, rounds, MidspanExit::RoundBudget));
1169            }
1170            receipt.returned = Some(fit_source);
1171            return Ok((fit, worst, unrefined, rounds, MidspanExit::RoundBudget));
1172        }
1173        if section.len() + inserts.len() > MAX_FIT_STATIONS {
1174            if let Some(((kept_fit, kept_run), kept_common)) = take_rollback(&mut best_state, current_common, representative_ran) {
1175                *section = kept_run;
1176                receipt.returned = Some(RefinedFitSource::Rollback);
1177                return Ok((kept_fit, kept_common, unrefined, rounds, MidspanExit::StationCeiling));
1178            }
1179            receipt.returned = Some(fit_source);
1180            return Ok((fit, worst, unrefined, rounds, MidspanExit::StationCeiling));
1181        }
1182        // Insert each refined point into the run between its span's stations,
1183        // on the nearest segment of the run there. Positions are located
1184        // against the run BEFORE any insertion of this round, then applied
1185        // from the back so earlier indices stay valid. The kept stations are
1186        // found by a FORWARD search from the previous one: a closed section
1187        // ends on its first station, and a search from the start would put
1188        // the last span's far end at index 0 and skip that span forever.
1189        let station_index = |point: Vec3, from: usize| -> Option<usize> {
1190            section[from..]
1191                .iter()
1192                .position(|p| p.sub(point).length() <= 1e-15 * (1.0 + point.length()))
1193                .map(|offset| from + offset)
1194        };
1195        let mut placed: Vec<(usize, Vec3)> = Vec::new();
1196        for (span, point) in inserts {
1197            let Some(lo) = station_index(fit.kept[span], 0) else {
1198                continue;
1199            };
1200            let Some(hi) = station_index(fit.kept[span + 1], lo + 1) else {
1201                continue;
1202            };
1203            if hi <= lo {
1204                continue;
1205            }
1206            if section[lo..=hi].iter().any(|p| p.sub(point).length() <= floor) {
1207                continue; // already a station: inserting it again refines nothing
1208            }
1209            let mut best = (lo, f64::INFINITY);
1210            for index in lo..hi {
1211                let d2 = distance_to_segment_sq(point, section[index], section[index + 1]);
1212                if d2 < best.1 {
1213                    best = (index, d2);
1214                }
1215            }
1216            placed.push((best.0 + 1, point));
1217        }
1218        if placed.is_empty() {
1219            if let Some(((kept_fit, kept_run), kept_common)) = take_rollback(&mut best_state, current_common, representative_ran) {
1220                *section = kept_run;
1221                receipt.returned = Some(RefinedFitSource::Rollback);
1222                return Ok((kept_fit, kept_common, unrefined, rounds, MidspanExit::Stalled));
1223            }
1224            receipt.returned = Some(fit_source);
1225            return Ok((fit, worst, unrefined, rounds, MidspanExit::Stalled));
1226        }
1227        placed.sort_by(|a, b| b.0.cmp(&a.0));
1228        for (at, point) in placed {
1229            section.insert(at, point);
1230            inserted_points.push(point);
1231        }
1232        // The refit keeps the stations the current fit kept and every point
1233        // inserted so far as SEEDS, and grows only where it is measured to
1234        // miss (`fit_polyline_seeded_with_path`). It is no longer the whole denser run
1235        // from the run's own count: that interpolated every march station the
1236        // standing fit had dropped as well, 3x the controls on the skew-cylinder
1237        // loop for the same carrier floor. The ceiling is the one the full refit
1238        // derives from the same `maximum_points`, and a seeded fit that cannot
1239        // meet the floor, or cannot be read, IS the full refit. The carrier
1240        // measure above still decides every round.
1241        let same = |a: &Vec3, b: &Vec3| a.x.to_bits() == b.x.to_bits() && a.y.to_bits() == b.y.to_bits() && a.z.to_bits() == b.z.to_bits();
1242        let mut seeds = Vec::with_capacity(fit.kept.len() + inserted_points.len());
1243        // The previous fit's kept stations alone: the representative candidate's
1244        // starting set (inserts are its witnesses, not forced stations).
1245        let mut kept_seeds = Vec::with_capacity(fit.kept.len());
1246        // The refiner's own inserted true-carrier points: the representative
1247        // candidate's TIGHT witnesses, held to this refiner's carrier floor.
1248        let mut insert_indices = Vec::with_capacity(inserted_points.len());
1249        let mut next_kept = 0usize;
1250        for (index, point) in section.iter().enumerate() {
1251            // The kept stations are a subsequence of the run, in run order
1252            // (insertion only adds points), so a closed run's two equal ends
1253            // each match their own station.
1254            // An inserted point is a tight witness whether or not the previous
1255            // fit also kept it as a station (membership is independent).
1256            let inserted = inserted_points.iter().any(|candidate| same(point, candidate));
1257            if inserted {
1258                insert_indices.push(index);
1259            }
1260            if next_kept < fit.kept.len() && same(point, &fit.kept[next_kept]) {
1261                seeds.push(index);
1262                kept_seeds.push(index);
1263                next_kept += 1;
1264            } else if inserted {
1265                seeds.push(index);
1266            }
1267        }
1268        let maximum_points = section.len().min(MAX_FIT_STATIONS);
1269        // Every standing station must be found as a seed; if the pass missed
1270        // one, the seeded refit would silently lose it, so the section takes the
1271        // original full refit instead.
1272        refit_trials = 1;
1273        retry_ms = 0.0;
1274        let refit_source;
1275        let refit = if next_kept == fit.kept.len() {
1276            let (refit, path) = if original_consistent {
1277                let (refit, path, cost) = fit_split_timed(FitSplitLane::Representatives, || crate::fit::fit_polyline_representatives_with_witnesses(
1278                    section,
1279                    &kept_seeds,
1280                    &insert_indices,
1281                    floor,
1282                    fit_tolerance,
1283                    maximum_points,
1284                    local_fit,
1285                    section_fit_degree(),
1286                ))?;
1287                // MIXED UNITS, named as such: the candidate's own
1288                // `fit_station_set` interpolations plus one per call of the
1289                // full refit `fit_polyline_of_degree`, which may itself run
1290                // several ladder and recovery interpolations that are NOT
1291                // counted here. Whole-job cost is the matched timing.
1292                refit_cost = cost;
1293                refit_trials = cost.candidate_fits + usize::from(cost.full_refit);
1294                (refit, path)
1295            } else {
1296                refit_cost = crate::fit::RepresentativeCost::default();
1297                fit_split_timed(FitSplitLane::Seeded, || crate::fit::fit_polyline_seeded_with_path(
1298                    section,
1299                    &seeds,
1300                    fit_tolerance,
1301                    maximum_points,
1302                    local_fit,
1303                    section_fit_degree(),
1304                ))?
1305            };
1306            // Only an ACCEPTED seeded fit can be retried in full: a fallback
1307            // already is the full refit, and retrying it would repeat it.
1308            seeded_refit = matches!(path, crate::fit::SeededPath::Accepted { .. });
1309            representative_fit = original_consistent && seeded_refit;
1310            refit_source = if original_consistent { RefinedFitSource::Representatives(path) } else { RefinedFitSource::Seeded(path) };
1311            representative_ran |= representative_fit;
1312            if round_census.is_some() {
1313                refit_path = if original_consistent { format!("representatives-call:{path:?}") } else { format!("seeded-call:{path:?}") };
1314            }
1315            refit
1316        } else {
1317            seeded_refit = false;
1318            representative_fit = false;
1319            refit_cost = crate::fit::RepresentativeCost::default();
1320            refit_path = String::from("full-unmatched");
1321            refit_source = RefinedFitSource::FullRefit;
1322            fit_split_timed(FitSplitLane::FullRefit, || fit_polyline_of_degree(section, fit_tolerance, maximum_points, local_fit, section_fit_degree()))?
1323        };
1324        if round_census.is_some() {
1325            // Trace only: how many seeds the refit kept. This does NOT tell an
1326            // accepted seeded fit from the fallback (a full refit can keep
1327            // every seed too); the returned `SeededPath`, traced as `fit`, does.
1328            refit_seeds = seeds.len();
1329            refit_seeds_kept = seeds.iter().filter(|&&index| refit.kept.iter().any(|kept| same(kept, &section[index]))).count();
1330            // Seeds the full refit's pool would NOT interpolate (simplified
1331            // or conditioned away): forced stations only the seeded fit keeps.
1332            let pool = crate::fit::polyline_station_pool(section, fit_tolerance);
1333            refit_pool = pool.len();
1334            refit_pool_discarded = section.len() - pool.len();
1335            refit_pool_floor = crate::fit::polyline_station_pool_floor(section, fit_tolerance);
1336            refit_seeds_outside_pool = seeds.iter().filter(|index| !pool.contains(index)).count();
1337            // Seeds are in run order; the closest consecutive pair is what a
1338            // near-duplicate conditioning floor would act on.
1339            refit_seed_min_chord = seeds
1340                .windows(2)
1341                .map(|pair| section[pair[1]].sub(section[pair[0]]).length())
1342                .fold(f64::INFINITY, f64::min);
1343            let is_insert = |index: usize| inserted_points.iter().any(|inserted| same(inserted, &section[index]));
1344            refit_seed_min_pair = seeds
1345                .windows(2)
1346                .min_by(|a, b| {
1347                    section[a[1]].sub(section[a[0]]).length().total_cmp(&section[b[1]].sub(section[b[0]]).length())
1348                })
1349                .map_or("n/a", |pair| match (is_insert(pair[0]), is_insert(pair[1])) {
1350                    (false, false) => "station-station",
1351                    (false, true) => "station-insert",
1352                    (true, false) => "insert-station",
1353                    (true, true) => "insert-insert",
1354                });
1355            // Every rejected seed, classified. `station_pool` starts from this
1356            // same simplification, so a non-member that is not in it was
1357            // simplified away, and one that is in it was conditioned away.
1358            let simplified = crate::fit::simplify_polyline_indices(section, fit_tolerance);
1359            refit_rejected = [0; 4];
1360            for &index in seeds.iter().filter(|index| !pool.contains(index)) {
1361                let conditioned = simplified.binary_search(&index).is_ok();
1362                refit_rejected[2 * usize::from(is_insert(index)) + usize::from(conditioned)] += 1;
1363            }
1364        }
1365        previous = Some((std::mem::replace(&mut fit, refit), worst, missing));
1366        previous_source = std::mem::replace(&mut fit_source, refit_source);
1367        rounds += 1;
1368    }
1369}
1370use super::*;
1371use super::gate_census::{census_pair, fit_census_enabled};
1372
1373pub fn build_imprints(
1374    solid_a: &BrepSolid,
1375    solid_b: &BrepSolid,
1376    options: &ImprintOptions,
1377) -> Result<ImprintResultRecord, KernelRefusal> {
1378    build_imprints_impl(solid_a, solid_b, options, false, super::pcurve_cache::enabled())
1379}
1380
1381/// Imprint temporary open offset sheets. A section riding one sheet's trim
1382/// still cuts the other sheet when no boundary copy supplied that section.
1383pub(crate) fn build_carrier_imprints(
1384    solid_a: &BrepSolid,
1385    solid_b: &BrepSolid,
1386    options: &ImprintOptions,
1387    tree_seeds: bool,
1388) -> Result<ImprintResultRecord, KernelRefusal> {
1389    build_imprints_with_carrier_seeds(
1390        solid_a, solid_b, options, true, super::pcurve_cache::enabled(), tree_seeds, None,
1391    )
1392}
1393
1394/// Lane P3b row 6 (2026-10-26): imprint the faces of ONE open sheet solid
1395/// against each other in a single call. `solid` is both operands (operand 0
1396/// and 1 tag the same faces); a face pair is processed once, as
1397/// (first index, second index) in the solid's face order with first < second,
1398/// and only when `admit(first, second)` says so. Every post-pass then runs
1399/// once over the whole piece set instead of once per pair.
1400pub(crate) fn build_carrier_imprints_within(
1401    solid: &BrepSolid,
1402    admit: &dyn Fn(usize, usize) -> bool,
1403    options: &ImprintOptions,
1404    tree_seeds: bool,
1405) -> Result<ImprintResultRecord, KernelRefusal> {
1406    build_imprints_with_carrier_seeds(
1407        solid, solid, options, true, super::pcurve_cache::enabled(), tree_seeds, Some(admit),
1408    )
1409}
1410
1411/// `BREP_IMPRINT_PLANE_POINT_SKIP` (lane X row 5): skip the march for two
1412/// exact parallelogram faces whose contact is one point
1413/// ([`super::support::planar_point_contact`]) once their seeds are accepted.
1414/// On by default; `0`/`off` disables it.
1415pub(super) fn plane_point_skip_enabled() -> bool {
1416    switch!(live "BREP_IMPRINT_PLANE_POINT_SKIP", true)
1417}
1418
1419thread_local! {
1420    static PLANE_POINT_SKIPS: std::cell::Cell<u64> = const { std::cell::Cell::new(0) };
1421}
1422
1423/// Pairs skipped by [`plane_point_skip_enabled`] on this thread since the last call.
1424pub(super) fn take_plane_point_skips() -> u64 {
1425    PLANE_POINT_SKIPS.with(|count| count.replace(0))
1426}
1427
1428
1429pub(super) fn build_imprints_impl(
1430    solid_a: &BrepSolid,
1431    solid_b: &BrepSolid,
1432    options: &ImprintOptions,
1433    open_carriers: bool,
1434    pcurve_cache: bool,
1435) -> Result<ImprintResultRecord, KernelRefusal> {
1436    build_imprints_with_carrier_seeds(solid_a, solid_b, options, open_carriers, pcurve_cache, false, None)
1437}
1438
1439// A carved offset can have a narrow transverse section beside its fold.
1440// Seed its knot spans without enabling ordered/consumed starts on other paths.
1441fn build_imprints_with_carrier_seeds(
1442    solid_a: &BrepSolid,
1443    solid_b: &BrepSolid,
1444    options: &ImprintOptions,
1445    open_carriers: bool,
1446    pcurve_cache: bool,
1447    carrier_tree_seeds: bool,
1448    // `Some`: `solid_a` IS `solid_b` and only face pairs (first < second) the
1449    // predicate admits are processed ([`build_carrier_imprints_within`]).
1450    self_pairs: Option<&dyn Fn(usize, usize) -> bool>,
1451) -> Result<ImprintResultRecord, KernelRefusal> {
1452    let _wall = crate::wall_profile::Stage::open("imprint");
1453    let _profile_sink = ProfileSink::open();
1454    let _work = super::work_profile::Scope::open("imprint");
1455    let classify_before = crate::pair_classification::classify_reads();
1456    let setup_started = profile_enabled().then(Instant::now);
1457    let windows_before = window_reads();
1458    let _pcurve_cache = super::pcurve_cache::FitCacheScope::open(pcurve_cache);
1459    let _edge_hulls = super::support::EdgeHullScope::open(super::support::edge_hull_memo_enabled());
1460    let _intersection_cache = super::intersection_cache::Scope::open();
1461    let reuse_whole_miss = open_carriers &&
1462        std::env::var("BREP_OFFSET_IMPRINT_READINGS").map_or(true, |v| v != "0" && v != "off");
1463    let mut section_evidence = false;
1464    let edges = edge_map(solid_a, solid_b);
1465    // FEATURE SCALE (`BREP_FEATURE_SCALE_IMPRINT`, default on, `=0` off):
1466    // the slivers between almost parallel plane faces of the two operands,
1467    // measured before any section is processed so that every band the
1468    // imprint applies sees them. A sliver a quarter of which is under the
1469    // tolerance cannot be resolved by any band, so the boolean refuses
1470    // rather than merge it away.
1471    let feature_scale = if crate::feature_scale::imprint_enabled() {
1472        let scale = crate::feature_scale::FeatureScale::between(solid_a, solid_b, options.tolerance)
1473            .or_refuse(KernelStage::Intersect, "feature_scale")?;
1474        if let Some(thinnest) = scale.thinnest() {
1475            if crate::feature_scale::FRACTION * thinnest < options.tolerance {
1476                return Err(KernelRefusal::new(
1477                    RefusalClass::IllPosed { what: "feature size".into() },
1478                    KernelStage::Intersect,
1479                    format!(
1480                        "boolean: a sliver {thinnest:.3e} thick between almost parallel faces is smaller than the \
1481                         section's resolution (tolerance {:.1e})",
1482                        options.tolerance
1483                    ),
1484                ));
1485            }
1486        }
1487        scale
1488    } else {
1489        Default::default()
1490    };
1491    // The tail passes (coincident-piece merge, junction canonicalisation)
1492    // run after the builder is consumed; they read the same scale.
1493    let tail_feature_scale = feature_scale.clone();
1494    let mut builder = ImprintBuilder {
1495        feature_scale,
1496        open_carriers,
1497        edges,
1498        tolerance: options.tolerance,
1499        barrier_edges: HashSet::default(),
1500        overlap_ridden_edges: HashSet::default(),
1501        scale: solid_scale(solid_a).max(solid_scale(solid_b)),
1502        vertices: Vec::new(),
1503        vertex_radii: HashMap::default(),
1504        vertex_sources: HashMap::default(),
1505        pieces: Vec::new(),
1506        by_face: HashMap::default(),
1507        edge_splits: HashMap::default(),
1508        marched_pieces: HashSet::default(),
1509        exact_section: false,
1510        emitted_pcurves: HashSet::default(),
1511        exact_pcurve_check: false,
1512        next_id: 1,
1513    };
1514    let requested_hermite_lane = hermite_sections(options);
1515    let hermite_lane = requested_hermite_lane || super::hermite::carried_uv_enabled();
1516    let hermite_min_stations = if hermite_lane { super::hermite::carried_uv_min_stations() } else { 2 };
1517    let exact_iso = exact_iso_pcurves(options);
1518    let (ordered_starts, consume_starts, tree_seeds) = march_starts(options, carrier_tree_seeds);
1519    builder.exact_pcurve_check = exact_iso == ExactIsoPcurves::Check;
1520    // The Hermite lane needs the march's span test; with no budget asked for
1521    // it carries the one the catalogue names, the pair's `intersection_fit`.
1522    let march_span_budget = span_budget(options, builder.scale)
1523        .or_else(|| requested_hermite_lane.then(|| crate::KernelTolerances::for_scale(builder.scale, options.tolerance).intersection_fit));
1524    // UV reuse must never request a different trace. Its stricter emission
1525    // check is applied after clipping; an unqualified run keeps the fit route.
1526    let emission_budget = super::hermite::carried_uv_emission_budget(march_span_budget,
1527        crate::KernelTolerances::for_scale(builder.scale, options.tolerance).intersection_fit);
1528    let mut first_faces = faces(solid_a, 0);
1529    let mut second_faces = faces(solid_b, 1);
1530    // Per-face trim-window carriers, computed once: tighter BVH bounds, and
1531    // the seed/march stages walk the window instead of the full carrier
1532    // (identical geometry and parameterization inside the window).
1533    //
1534    // A window LIFTED across a closed direction's seam (`restricted_carrier`)
1535    // is the exception to "same parameterization": it is the trim's frame, a
1536    // period off the carrier's on one side. Its face carries it as its
1537    // `chart`, and every uv the imprint reads for that face — the clip's
1538    // containment, the sections' pcurves, a seed's normal — is read there.
1539    let first_restricted: Vec<Option<MarchWindow>> = first_faces
1540        .iter()
1541        .map(|tagged| restricted_carrier_memoized(tagged.face))
1542        .collect();
1543    let second_restricted: Vec<Option<MarchWindow>> = second_faces
1544        .iter()
1545        .map(|tagged| restricted_carrier_memoized(tagged.face))
1546        .collect();
1547    for (tagged, window) in first_faces.iter_mut().zip(&first_restricted) {
1548        tagged.lifted = window.as_ref().filter(|window| window.lifted).map(|window| &window.surface);
1549    }
1550    for (tagged, window) in second_faces.iter_mut().zip(&second_restricted) {
1551        tagged.lifted = window.as_ref().filter(|window| window.lifted).map(|window| &window.surface);
1552    }
1553    let first_faces = first_faces;
1554    let second_faces = second_faces;
1555    // The lifted charts, by key, for the post-passes that rebuild a pcurve
1556    // after the mint (junction canonicalization, the origin dissolve, the
1557    // truncation bridge). A face absent here is read on its own carrier.
1558    let charts: FaceCharts<'_> = first_faces
1559        .iter()
1560        .chain(second_faces.iter())
1561        .filter_map(|tagged| tagged.lifted.map(|surface| (tagged.key(), surface)))
1562        .collect();
1563    let first_bounds = first_faces
1564        .iter()
1565        .zip(&first_restricted)
1566        .map(|(tagged, restricted)| {
1567            face_bounds(
1568                tagged.face,
1569                restricted.as_ref().map(|window| &window.surface),
1570                &builder.edges,
1571                tagged.operand,
1572                options.tolerance,
1573            )
1574        })
1575        .collect::<Result<Vec<_>, _>>()?;
1576    let second_bounds = second_faces
1577        .iter()
1578        .zip(&second_restricted)
1579        .map(|(tagged, restricted)| {
1580            face_bounds(
1581                tagged.face,
1582                restricted.as_ref().map(|window| &window.surface),
1583                &builder.edges,
1584                tagged.operand,
1585                options.tolerance,
1586            )
1587        })
1588        .collect::<Result<Vec<_>, _>>()?;
1589    let second_bvh = Bvh::build(&second_bounds);
1590    // Per-face classifier data and edge lists/subcurves, computed once and
1591    // reused across every pair the face participates in.
1592    let first_classify = first_faces
1593        .iter()
1594        .map(|tagged| SurfaceClassifyData::memoized(&tagged.face.surface, options.tolerance))
1595        .collect::<Result<Vec<_>, _>>().or_refuse(KernelStage::Intersect, "csg.imprint.driver")?;
1596    let second_classify = second_faces
1597        .iter()
1598        .map(|tagged| SurfaceClassifyData::memoized(&tagged.face.surface, options.tolerance))
1599        .collect::<Result<Vec<_>, _>>().or_refuse(KernelStage::Intersect, "csg.imprint.driver")?;
1600    let mut face_edge_lists: HashMap<FaceKey, Vec<&EdgeRecord>> = HashMap::default();
1601    for tagged in first_faces.iter().chain(second_faces.iter()) {
1602        face_edge_lists.insert(tagged.key(), face_edges(*tagged, &builder.edges)?);
1603    }
1604    let mut subcurves: HashMap<(u8, u64), NurbsCurve> = HashMap::default();
1605    for (&key, edge) in &builder.edges {
1606        if !edge.degenerate {
1607            // Failures fall through: the use sites recompute and surface the
1608            // original error exactly where the uncached code did.
1609            if let Ok(curve) = edge_subcurve(edge) {
1610                subcurves.insert(key, curve);
1611            }
1612        }
1613    }
1614    let cached_subcurve = |operand: u8, edge: &EdgeRecord| -> Result<NurbsCurve, KernelRefusal> {
1615        match subcurves.get(&(operand, edge.id)) {
1616            Some(curve) => Ok(curve.clone()),
1617            None => edge_subcurve(edge),
1618        }
1619    };
1620    if let Some(started) = setup_started { profile_line!("imprint.setup ms={:.3} faces={} classify_reads={} windows_built={}", started.elapsed().as_secs_f64()*1000.0, first_faces.len()+second_faces.len(), crate::pair_classification::classify_reads()-classify_before, window_reads()-windows_before); }
1621    let mut profile = ImprintProfile::new();
1622    let mut march_swap_rescues = 0_u64;
1623    let mut clip_swap_rescues = 0_u64;
1624    // `imprint.fits`: the pcurve fits the pairs record, read through a nested
1625    // scope that folds into the operation's own ledger on close.
1626    let pairs_fits = profile.enabled.then(crate::PcurveFitScope::open);
1627    let mut tangent_nodes: Vec<Vec3> = Vec::new();
1628    let mut tangent_sections: Vec<TangentSectionRecord> = Vec::new();
1629    // Planar tangent runs to IMPRINT once every pair has minted its pieces
1630    // (`ImprintOptions::tangent_curve_imprint`): (section index, run, pair).
1631    let mut tangent_imprint_candidates: Vec<(usize, Vec<Vec3>, TaggedFace<'_>, TaggedFace<'_>)> = Vec::new();
1632    let mut cosurface_pairs: Vec<(FaceKey, FaceKey)> = Vec::new();
1633    let mut deferred_boundary_spans = Vec::new();
1634    let mut work_pairs = super::work_profile::Pairs::new(first_faces.len() * second_faces.len());
1635    let mut paired = Vec::new();
1636    for (first_index, first) in first_faces.iter().enumerate() {
1637        let first = *first;
1638        paired.clear();
1639        second_bvh.overlapping(
1640            first_bounds[first_index],
1641            options.tolerance * 100.0,
1642            &mut paired,
1643        );
1644        paired.sort_unstable();
1645        let debug_pairs = std::env::var("BREP_DEBUG_PAIRS").is_ok();
1646        if debug_pairs {
1647            eprintln!(
1648                "bvh first_face={} -> {} candidate pairs {:?}",
1649                first.face.id,
1650                paired.len(),
1651                paired
1652                    .iter()
1653                    .map(|&index| second_faces[index].face.id)
1654                    .collect::<Vec<_>>()
1655            );
1656        }
1657        for &second_index in &paired {
1658            if let Some(admit) = self_pairs {
1659                if second_index <= first_index || !admit(first_index, second_index) {
1660                    continue;
1661                }
1662            }
1663            let second = second_faces[second_index];
1664            profile.pairs += 1;
1665            let _work_pair = super::work_profile::Pair::open(&mut work_pairs, first.face, second.face);
1666            // Set when this pair's section passes through an isolated TANGENT
1667            // NODE inside both trims (see the classification below). The march
1668            // is attempted anyway — that is the whole point — but a marcher
1669            // that cannot get through a node must refuse in the tangent-node
1670            // class naming the node, not leak its own step-budget message.
1671            let mut tangent_node: Option<Vec3> = None;
1672            // The pair's branches came from the sub-gate re-march below: a
1673            // run end that stalls in the tangency band then lands on a trim
1674            // edge the carriers share exactly as a tangent-node pair's does.
1675            let mut grazing_march = false;
1676            let mut lap_start = None;
1677            profile.lap(&mut lap_start);
1678            let pair_classification = classify_surface_pair_cached(
1679                &first.face.surface,
1680                &first_classify[first_index],
1681                &second.face.surface,
1682                &second_classify[second_index],
1683                options.tolerance,
1684                PAIR_ANGULAR_TOLERANCE,
1685            ).or_refuse(KernelStage::Intersect, "csg.imprint.driver")?;
1686            profile.classify += profile.lap(&mut lap_start);
1687            if pair_classification.relation == SurfacePairRelation::Disjoint {
1688                if debug_pairs {
1689                    eprintln!(
1690                        "pair {}x{}: DISJOINT-cull sep={:.4e}",
1691                        first.face.id, second.face.id, pair_classification.minimum_separation
1692                    );
1693                }
1694                continue;
1695            }
1696            // Coincident carriers are never marched: their true intersection
1697            // is a 2D region, not a curve, so anything the marcher traces on
1698            // them is noise ("similar faces we do not intersect" — Golovanov
1699            // §6.2).  The sampled classification catches coincident pairs
1700            // the strict reconstruction test misses (partial overlaps,
1701            // differing parameterizations); both route to the boundary-curve
1702            // exchange below.
1703            let is_cosurface = pair_classification.relation == SurfacePairRelation::Cosurface
1704                || cosurface_pair(&first.face.surface, &second.face.surface, options.tolerance)?;
1705            profile.cosurface += profile.lap(&mut lap_start);
1706            if is_cosurface {
1707                if debug_pairs {
1708                    eprintln!("pair {}x{}: cosurface", first.face.id, second.face.id);
1709                }
1710                cosurface_pairs.push((first.key(), second.key()));
1711                for edge in &face_edge_lists[&second.key()] {
1712                    if !edge.degenerate {
1713                        builder.process_curve(
1714                            cached_subcurve(second.operand, edge)?,
1715                            first,
1716                            second,
1717                            &[first],
1718                            &[first],
1719                            false,
1720                            None,
1721                        )?;
1722                    }
1723                }
1724                for edge in &face_edge_lists[&first.key()] {
1725                    if !edge.degenerate {
1726                        builder.process_curve(
1727                            cached_subcurve(first.operand, edge)?,
1728                            first,
1729                            second,
1730                            &[second],
1731                            &[second],
1732                            false,
1733                            None,
1734                        )?;
1735                    }
1736                }
1737                profile.process_curve += profile.lap(&mut lap_start);
1738                continue;
1739            }
1740
1741            // Exact lanes discard sections riding an ordinary trim boundary:
1742            // that face already owns the edge, but the other face still needs
1743            // the overlapping span as a cut. Keep the existing whole-edge
1744            // exchange order, and append missing partial spans after all pairs
1745            // have run so duplicate sections retain their established IDs and
1746            // fragment names. Seams are retained by the exact lane itself.
1747            let planar_iso = planar_iso_section(
1748                &first.face.surface,
1749                &second.face.surface,
1750                options.tolerance,
1751            )?;
1752            profile.planar_iso += profile.lap(&mut lap_start);
1753            let analytic = crate::intersect_analytic_pair(
1754                &first.face.surface,
1755                &second.face.surface,
1756                options.tolerance,
1757            );
1758            profile.analytic += profile.lap(&mut lap_start);
1759            let exact_section = planar_iso.is_some() || analytic.is_some();
1760
1761            for (source, target) in [(first, second), (second, first)] {
1762                for edge in &face_edge_lists[&source.key()] {
1763                    if edge.degenerate {
1764                        continue;
1765                    }
1766                    let curve = cached_subcurve(source.operand, edge)?;
1767                    let spans = curve_spans_on_face(
1768                        curve.clone(), target.face, &face_edge_lists[&target.key()],
1769                        options.tolerance, exact_section,
1770                    )?;
1771                    let seam = source.face.loops.iter().flat_map(|loop_record| &loop_record.coedges)
1772                        .filter(|coedge| coedge.edge_id == edge.id).count() >= 2;
1773                    if spans.is_empty() && exact_section && !seam {
1774                        // The whole-only call above returned empty: its exact
1775                        // curve/carrier reading was false. Nothing has mutated.
1776                        let partial = if reuse_whole_miss {
1777                            profile.whole_reading_reuses += 1;
1778                            curve_spans_after_whole_miss(
1779                                curve, target.face, &face_edge_lists[&target.key()], options.tolerance,
1780                            )?
1781                        } else {
1782                            curve_spans_on_face(
1783                                curve, target.face, &face_edge_lists[&target.key()], options.tolerance, false,
1784                            )?
1785                        };
1786                        for span in partial {
1787                            deferred_boundary_spans.push((span, first, second, target));
1788                        }
1789                    }
1790                    for span in spans {
1791                        builder.process_curve(span, first, second, &[target], &[target], false, None)?;
1792                    }
1793                }
1794            }
1795            profile.lies_on += profile.lap(&mut lap_start);
1796            // CENSUS ONLY (`BREP_FIT_CENSUS=1`): the lane this pair takes under
1797            // the count-keyed and the geometry-keyed gates, and — when it is
1798            // marched here and answered exactly there — the point-set comparison
1799            // of the two, printed when `pair_census` is dropped. `imprint/gate_census.rs`.
1800            let mut pair_census = if fit_census_enabled() {
1801                census_pair(first, second, options.tolerance)?
1802            } else {
1803                None
1804            };
1805            if let Some(IsoSection { curve, pcurves }) = planar_iso {
1806                if debug_pairs {
1807                    eprintln!("pair {}x{}: planar_iso", first.face.id, second.face.id);
1808                }
1809                // Slice 1: the exact pcurves ride along with the curve when
1810                // the lane is on (or checked). A face read in a lifted chart
1811                // declines: the iso line is in the carrier's own frame, and
1812                // the lifted chart's period is not the carrier's.
1813                let exact_pcurves = match (exact_iso, pcurves) {
1814                    (ExactIsoPcurves::Off, _) => None,
1815                    (_, Some(pcurves)) if first.lifted.is_none() && second.lifted.is_none() => {
1816                        profile.exact_iso_sections += 1;
1817                        Some(pcurves)
1818                    }
1819                    _ => {
1820                        profile.exact_iso_declined += 1;
1821                        None
1822                    }
1823                };
1824                let lane_fits = profile.enabled.then(crate::PcurveFitScope::open);
1825                builder.process_curve(
1826                    curve,
1827                    first,
1828                    second,
1829                    &[first, second],
1830                    &[first, second],
1831                    true,
1832                    exact_pcurves,
1833                )?;
1834                if let Some(scope) = lane_fits {
1835                    profile.exact_lane_fits += scope.close().fits;
1836                }
1837                profile.process_curve += profile.lap(&mut lap_start);
1838                continue;
1839            }
1840
1841            // Recognized analytic pairs produce their exact intersection
1842            // curves (lines, circles, ellipses) directly — no marching, no
1843            // polyline fitting, no chord-sag drift. An empty result is a
1844            // proof of non-intersection and also skips the marcher. (Read
1845            // above, with the planar-iso curve.)
1846            if let Some(curves) = analytic {
1847                if debug_pairs {
1848                    eprintln!(
1849                        "pair {}x{}: analytic x{}",
1850                        first.face.id,
1851                        second.face.id,
1852                        curves.len()
1853                    );
1854                }
1855                // TANGENT-CURVE LANE. An exact lane's "provably empty" is a
1856                // proof about TRANSVERSE curves: a plane at exactly the
1857                // cylinder's radius from its axis has no generatrix pair, and
1858                // the pair would be dropped here without a word while the
1859                // carriers touch along a whole line. Where the classification
1860                // read the pair as near-tangent, the lane looks for the
1861                // extended contact and records it typed.
1862                if curves.is_empty()
1863                    && options.tangent_curve_lane
1864                    && pair_classification.relation == SurfacePairRelation::NearTangent
1865                {
1866                    if let Some((mut section, run)) = tangent_curve_section(
1867                        first, second, options, &first_faces, &second_faces, &face_edge_lists, debug_pairs,
1868                    )? {
1869                        if options.tangent_curve_imprint && section.planar && run.len() >= 2 {
1870                            tangent_imprint_candidates.push((tangent_sections.len(), run, first, second));
1871                        }
1872                        tangent_sections.push(section);
1873                    }
1874                }
1875                let lane_fits = profile.enabled.then(crate::PcurveFitScope::open);
1876                builder.exact_section = true;
1877                for curve in curves {
1878                    let processed = builder.process_curve(
1879                        curve,
1880                        first,
1881                        second,
1882                        &[first, second],
1883                        &[first, second],
1884                        true,
1885                        None,
1886                    );
1887                    if processed.is_err() {
1888                        builder.exact_section = false;
1889                    }
1890                    processed?;
1891                }
1892                builder.exact_section = false;
1893                if let Some(scope) = lane_fits {
1894                    profile.exact_lane_fits += scope.close().fits;
1895                }
1896                profile.process_curve += profile.lap(&mut lap_start);
1897                continue;
1898            }
1899
1900            // A pair whose every touching sample is TANGENTIAL cannot
1901            // contain a transverse intersection curve: the marcher would
1902            // walk the tangency band's noise, which neither closes nor
1903            // reaches a boundary (the distance-0 glue-extrude runaway).
1904            // Shared topology at a tangential contact comes from the
1905            // boundary-curve exchange above ("similar faces we do not
1906            // intersect" extended to tangential contacts — Golovanov §6.2;
1907            // where surfaces CROSS through a tangency, off-line samples
1908            // have non-parallel normals and the pair still marches).
1909            if pair_classification.relation == SurfacePairRelation::NearTangent
1910                && pair_classification.tangential_only
1911            {
1912                // The coarse 5×5 classifier can flag `tangential_only` off an
1913                // incidental tangential KISS between two curved carriers and
1914                // miss the transverse loop where they actually cross (two
1915                // overlapping tori: their tubes cross while their inner walls
1916                // just touch). Before honouring the skip, a GATED supplemental
1917                // detector (denser two-sided seeding, tangency-band seeds
1918                // rejected, trace-exhaustion swallowed, transverse-only
1919                // branches) checks whether a genuine transverse curve of
1920                // meaningful length lies inside BOTH trims.
1921                //
1922                // Such a pair's intersection is SINGULAR where a tangency
1923                // sits on it, and what the imprint can do about that depends
1924                // entirely on the SHAPE of the tangency — see
1925                // `imprint/tangent_contact.rs`. An isolated NODE (two branches
1926                // crossing, as every equal-radius pair produces) is already
1927                // assembled correctly by the ordinary march plus the 2D
1928                // arrangement's pinch carving; an EXTENDED contact along a
1929                // whole curve has no section to imprint at all and tears the
1930                // shell. Both are classified below and only the second is
1931                // refused. Skipping either silently would DROP the
1932                // intersection (torus∪torus double-counts; torus−torus removes
1933                // nothing — the two structural bugs the semantic oracle
1934                // found), so nothing here ever falls through quietly.
1935                let first_march = first_restricted[first_index]
1936                    .as_ref()
1937                    .map(|window| &window.surface)
1938                    .unwrap_or(&first.face.surface);
1939                let second_march = second_restricted[second_index]
1940                    .as_ref()
1941                    .map(|window| &window.surface)
1942                    .unwrap_or(&second.face.surface);
1943                let supplemental = super::work_profile::supplemental(
1944                    first_march,
1945                    second_march,
1946                    &SurfaceIntersectionOptions {
1947                        tolerance: options.tolerance,
1948                        maximum_step: options.maximum_ssi_step,
1949                        span_budget: march_span_budget,
1950                        ..Default::default()
1951                    },
1952                ).or_refuse(KernelStage::Intersect, "csg.imprint.driver")?;
1953                let mut dropped_length = 0.0f64;
1954                let mut clipped: Vec<Vec<Vec3>> = Vec::new();
1955                for branch in &supplemental {
1956                    for run in clip_branch_to_trims(&branch.points, first, second)? {
1957                        if run.len() < 2 {
1958                            continue;
1959                        }
1960                        let length: f64 = run
1961                            .windows(2)
1962                            .map(|pair| pair[1].sub(pair[0]).length())
1963                            .sum();
1964                        dropped_length = dropped_length.max(length);
1965                        clipped.push(run);
1966                    }
1967                }
1968                if dropped_length <= options.tolerance * 100.0 {
1969                    if debug_pairs {
1970                        eprintln!(
1971                            "pair {}x{}: tangential-only contact, march skipped",
1972                            first.face.id, second.face.id
1973                        );
1974                    }
1975                    // TANGENT-CURVE LANE: the skip is right for a transverse
1976                    // march, which has nothing to walk here, but the contact
1977                    // may still be a CURVE inside both trims (the same
1978                    // generatrix on a carrier no exact lane recognises).
1979                    // Recognise and record it, typed, rather than lose it.
1980                    if options.tangent_curve_lane {
1981                        if let Some((mut section, run)) = tangent_curve_section(
1982                            first, second, options, &first_faces, &second_faces, &face_edge_lists, debug_pairs,
1983                        )? {
1984                            if options.tangent_curve_imprint && section.planar && run.len() >= 2 {
1985                                tangent_imprint_candidates.push((tangent_sections.len(), run, first, second));
1986                            }
1987                            tangent_sections.push(section);
1988                        }
1989                    }
1990                    // RIM BRIDGE (`BREP_RIM_BRIDGE`, default on, `=0` off). A pair
1991                    // tangent along one stretch (two swept walls along the
1992                    // join of the sweeps) can still cross elsewhere along a
1993                    // section shorter than the march can see: where a rim of
1994                    // each operand passes the other at a grazing angle, each
1995                    // rim pierces the other operand's face a few
1996                    // `tol / |tan·n|` from the other's pierce, and the section
1997                    // between the two pierces lies on both faces of this pair.
1998                    // Its neighbours end at the two pierces; without it the
1999                    // shell tears there. The bridge is the straight segment
2000                    // between a crossing pierce of each operand inside both
2001                    // trims, mutual nearest and within the grazing reach.
2002                    if rim_bridge_enabled() {
2003                        rim_bridge(&mut builder, first, second, first_march, second_march, &face_edge_lists, options, debug_pairs)?;
2004                    }
2005                    continue;
2006                }
2007                // A transverse curve EXISTS. What would make it unimprintable is
2008                // a tangent NODE on it — and the node need not lie inside the
2009                // trims. Two equal-radius pipe arms are tangent to each other
2010                // where their axes' common perpendicular leaves the junction,
2011                // and a joint ball wider than the arms trims that crotch off
2012                // both faces; what is left inside the trims is an ordinary
2013                // crossing. So the question is not "does a transverse curve
2014                // exist" but "does the curve INSIDE BOTH TRIMS reach a
2015                // tangency". Only the latter is the checkerboard case.
2016                let mut tangency_inside_trims = false;
2017                let mut tangency_witness = Vec3::default();
2018                'clipped: for run in &clipped {
2019                    for (index, &point) in run.iter().enumerate() {
2020                        if pair_normals_parallel_at(first, second, point)? {
2021                            tangency_inside_trims = true;
2022                            tangency_witness = point;
2023                            if debug_pairs {
2024                                eprintln!(
2025                                    "pair {}x{}: TANGENCY at run index {}/{} ({:.6},{:.6},{:.6}) dropped_len={:.4e}",
2026                                    first.face.id, second.face.id, index, run.len(),
2027                                    point.x, point.y, point.z, dropped_length
2028                                );
2029                            }
2030                            break 'clipped;
2031                        }
2032                    }
2033                }
2034                if tangency_inside_trims {
2035                    // WHAT SHAPE is the tangency? The witness is only a marched
2036                    // sample within the transverse-seed angular gate, so it is
2037                    // REFINED onto the contact before being classified — at the
2038                    // raw witness a G1 cylinder/torus join and a genuine
2039                    // equal-radius node are eighteen-fold apart, which would be
2040                    // a band; at the refined contact they are thirty orders
2041                    // apart, which is a rank question. See
2042                    // `imprint/tangent_contact.rs`.
2043                    let contact = classify_tangent_contact(
2044                        &first.face.surface,
2045                        &second.face.surface,
2046                        tangency_witness,
2047                        options.tolerance,
2048                    )?;
2049                    if debug_pairs {
2050                        eprintln!(
2051                            "pair {}x{}: contact classification {:?}",
2052                            first.face.id, second.face.id, contact
2053                        );
2054                    }
2055                    match contact {
2056                        // An isolated node: the section is a curve everywhere
2057                        // but that one point, so the ordinary march below runs
2058                        // and the 2D arrangement carves the pinch on both
2059                        // faces. `tangent_node` records it so a march that
2060                        // cannot get through still refuses in THIS class rather
2061                        // than leaking the marcher's own message.
2062                        Some(contact) if contact.is_isolated_node() => {
2063                            tangent_node = Some(contact.point);
2064                            tangent_nodes.push(contact.point);
2065                        }
2066                        // An extended contact (rank-deficient) or a witness we
2067                        // could not refine onto any contact at all (None — so
2068                        // nothing is proven and the pre-classification refusal
2069                        // stands). Neither has a section curve the imprint can
2070                        // represent.
2071                        other => {
2072                            let shape = match other {
2073                                Some(contact) => contact.describe(),
2074                                None => format!(
2075                                    "the tangency near ({:.6},{:.6},{:.6}) could not be refined \
2076                                     onto a contact, so its shape is unproven",
2077                                    tangency_witness.x, tangency_witness.y, tangency_witness.z
2078                                ),
2079                            };
2080                            return Err(KernelRefusal::new(
2081                                RefusalClass::TangentNodeSingularity,
2082                                KernelStage::Intersect,
2083                                format!(
2084                                    "boolean: unsupported singular/tangent-node surface intersection \
2085                                     between faces {} and {}: {shape}",
2086                                    first.face.id, second.face.id
2087                                ),
2088                            ));
2089                        }
2090                    }
2091                }
2092                if debug_pairs && tangent_node.is_none() {
2093                    // Transverse the whole way inside both trims: the coarse
2094                    // 5x5 classifier only saw the tangency the trims cut away.
2095                    eprintln!(
2096                        "pair {}x{}: classified tangential-only, but the curve inside both \
2097                         trims is transverse ({dropped_length:.4}) — marching",
2098                        first.face.id, second.face.id
2099                    );
2100                }
2101            }
2102
2103            // The trim-window carriers: same surface and parameterization
2104            // over the window, so hit (u, v) values remain valid on the
2105            // originals; out-of-window intersections could never survive
2106            // clip_branch_to_trims and are not walked at all.
2107            let first_march = first_restricted[first_index]
2108                .as_ref()
2109                .map(|window| &window.surface)
2110                .unwrap_or(&first.face.surface);
2111            let second_march = second_restricted[second_index]
2112                .as_ref()
2113                .map(|window| &window.surface)
2114                .unwrap_or(&second.face.surface);
2115            let pair_hermite_lane = hermite_lane && super::hermite::refinement_carriers_eligible(
2116                &first.face.surface, &second.face.surface,
2117            );
2118            let mut seed_points = Vec::new();
2119            // Smallest |edge_tangent · surface_normal| over accepted seeds — the
2120            // local grazing measure at the trim crossings (near 0 = the edge
2121            // pierces the other surface tangentially). Gates the near-tangent
2122            // clip-order rescue below to genuinely grazing pairs.
2123            let mut min_seed_tangency = f64::INFINITY;
2124            // Two grazing crossings of one trim edge bound a real, narrow
2125            // interval. It cannot tolerate a section fit that misses either
2126            // crossing, even when a coarse whole-model distance looks small.
2127            let mut paired_grazing_crossings = false;
2128            // Every hit the seed gate rejected, for the whole pair: the
2129            // point, its `|tan·n|`, the edge (its operand, its id) and the
2130            // parameter on it, and whether that edge belongs to `first`.
2131            // Read only when the march comes back empty, below, where the
2132            // genuine crossings among them are told from lies-on samples.
2133            let mut grazing_hits: Vec<(Vec3, f64, u8, u64, f64, bool)> = Vec::new();
2134            for (face, other_march, other) in
2135                [(first, second_march, second), (second, first_march, first)]
2136            {
2137                for edge in &face_edge_lists[&face.key()] {
2138                    if edge.degenerate {
2139                        continue;
2140                    }
2141                    let mut grazing_crossings: Vec<Vec3> = Vec::new();
2142                    // LIES-ON SKIP (2026-10-17, the shelled-box report's
2143                    // offset bore against the offset blend walls): an edge
2144                    // that LIES ON the other carrier — the test the exchange
2145                    // stage above already trusted to hand the whole edge over
2146                    // as a shared span — returns a hit per sample from
2147                    // `intersect_curve_surface`, every one grazing (|tan.n| = 0
2148                    // on a curve in the surface) and every one rejected: three
2149                    // such edges answered 8 580 of that pair's 8 586 seed hits
2150                    // at 0.36 s. Such an edge contributes no seed, no tangency
2151                    // minimum and no section evidence; its one effect is the
2152                    // paired-grazing flag, set when two of its grazing points
2153                    // sit more than the weld apart, which is reproduced here
2154                    // from the edge's own extent. `BREP_IMPRINT_LIES_ON_SEED_SKIP=0`
2155                    // runs the solve as before.
2156                    if lies_on_seed_skip_enabled() {
2157                        let subcurve = cached_subcurve(face.operand, edge)?;
2158                        if super::support::curve_lies_on_surface(&subcurve, other_march, options.tolerance)? {
2159                            let [start, end] = subcurve.domain().or_refuse(KernelStage::Intersect, "domain")?;
2160                            let mut probes = Vec::with_capacity(5);
2161                            for fraction in [0.0, 0.25, 0.5, 0.75, 1.0] {
2162                                probes.push(subcurve.evaluate(start + (end - start) * fraction).or_refuse(KernelStage::Intersect, "evaluate")?);
2163                            }
2164                            let weld = assembler_weld(options.tolerance);
2165                            if probes.iter().any(|a| probes.iter().any(|b| a.sub(*b).length() > weld)) {
2166                                paired_grazing_crossings = true;
2167                            }
2168                            if debug_pairs {
2169                                eprintln!(
2170                                    "pair {}x{}: seed edge {} lies on the other carrier — seed solve skipped",
2171                                    first.face.id, second.face.id, edge.id
2172                                );
2173                            }
2174                            continue;
2175                        }
2176                    }
2177                    for hit in intersect_curve_surface(&edge.curve, other_march, options.tolerance).or_refuse(KernelStage::Intersect, "intersect_curve_surface")?
2178                    {
2179                        if hit.t < edge.t0 - 1e-9 || hit.t > edge.t1 + 1e-9 {
2180                            continue;
2181                        }
2182                        let derivative = edge.curve.derivatives(hit.t, 1).or_refuse(KernelStage::Intersect, "derivatives")?[1];
2183                        // A STATIONARY POINT on the edge curve is not a reason
2184                        // to refuse the boolean. An involute flank starts at
2185                        // the base circle with an exactly zero tangent, so a
2186                        // gear tooth's profile carries one cusp per flank, and
2187                        // a hit landing on that parameter used to propagate
2188                        // "Vec3.normalized: zero-length vector" out of the
2189                        // whole union (the 2026-09-14 herringbone report: the
2190                        // second tooth band's z=0 cap edge meets the first
2191                        // band's flank exactly at the cusp). The direction is
2192                        // still defined as the one-sided limit, so read it from
2193                        // just inside the edge's own range; an edge with no
2194                        // direction at all simply contributes no seed, exactly
2195                        // as a hit whose face normal is unavailable already
2196                        // does two lines below. Seeds are marcher hints, so a
2197                        // dropped one costs a hint, never an answer.
2198                        // Escape hatch for tamper-verification:
2199                        // BREP_CUSP_TANGENT_RESCUE=0 restores the refusal.
2200                        let tangent = match derivative.normalized() {
2201                            Ok(tangent) => tangent,
2202                            Err(error) => {
2203                                if std::env::var("BREP_CUSP_TANGENT_RESCUE").as_deref() == Ok("0") {
2204                                    return Err(error)
2205                                        .or_refuse(KernelStage::Intersect, "normalized");
2206                                }
2207                                match edge.curve.stationary_tangent_rescue(hit.t, edge.t0, edge.t1)
2208                                {
2209                                    Some(tangent) => tangent,
2210                                    None => continue,
2211                                }
2212                            }
2213                        };
2214                        // `hit` was solved on the other face's MARCH WINDOW, so
2215                        // its uv is in that face's chart — a period off the
2216                        // carrier's where the window is lifted, and `normal`
2217                        // clamps a parameter past its domain.
2218                        let normal = match other.chart().normal(hit.u, hit.v) {
2219                            Ok(normal) => normal,
2220                            Err(_) => continue,
2221                        };
2222                        if debug_pairs {
2223                            eprintln!(
2224                                "pair {}x{}: seed edge {} t={:.6} p=({:.5},{:.5},{:.5}) |tan.n|={:.4} {}",
2225                                first.face.id,
2226                                second.face.id,
2227                                edge.id,
2228                                hit.t,
2229                                hit.point.x,
2230                                hit.point.y,
2231                                hit.point.z,
2232                                tangent.dot(normal).abs(),
2233                                if tangent.dot(normal).abs() >= 0.1 { "ACCEPT" } else { "reject" }
2234                            );
2235                        }
2236                        if tangent.dot(normal).abs() >= 0.1 {
2237                            seed_points.push(hit.point);
2238                            min_seed_tangency = min_seed_tangency.min(tangent.dot(normal).abs());
2239                            section_evidence = true;
2240                        } else {
2241                            if grazing_crossings.iter().any(|point| {
2242                                point.sub(hit.point).length() > assembler_weld(options.tolerance)
2243                            }) {
2244                                paired_grazing_crossings = true;
2245                            }
2246                            grazing_crossings.push(hit.point);
2247                            grazing_hits.push((
2248                                hit.point,
2249                                tangent.dot(normal).abs(),
2250                                face.operand,
2251                                edge.id,
2252                                hit.t,
2253                                face.operand == first.operand && face.face.id == first.face.id,
2254                            ));
2255                        }
2256                    }
2257                }
2258            }
2259            profile.seeds += profile.lap(&mut lap_start);
2260            // POINT CONTACT (`BREP_IMPRINT_PLANE_POINT_SKIP`, lane X row 5):
2261            // two exact parallelograms meeting at one point have no section
2262            // curve. Once a seed is accepted the pair's contact evidence is
2263            // already recorded and the march could only trace that point, so
2264            // it is skipped; an unseeded pair still marches.
2265            if !seed_points.is_empty()
2266                && plane_point_skip_enabled()
2267                && super::support::planar_point_contact(&first.face.surface, &second.face.surface, options.tolerance) == Some(true)
2268            {
2269                PLANE_POINT_SKIPS.with(|count| count.set(count.get() + 1));
2270                if debug_pairs {
2271                    eprintln!("pair {}x{}: planar point contact, march skipped", first.face.id, second.face.id);
2272                }
2273                continue;
2274            }
2275            profile.marched_pairs += 1;
2276            if debug_pairs {
2277                eprintln!(
2278                    "pair {}x{}: marching (relation {:?})...",
2279                    first.face.id, second.face.id, pair_classification.relation
2280                );
2281            }
2282            let marched = super::work_profile::trace(
2283                first_march,
2284                second_march,
2285                &SurfaceIntersectionOptions {
2286                    tolerance: options.tolerance,
2287                    maximum_step: march_maximum_step(
2288                        &pair_classification,
2289                        options.maximum_ssi_step,
2290                        builder.scale,
2291                    ),
2292                    seed_points: seed_points.clone(),
2293                    span_budget: march_span_budget,
2294                    ordered_starts,
2295                    consume_starts,
2296                    tree_seeds,
2297                    ..Default::default()
2298                },
2299            );
2300            // A pair carrying a tangent node keeps its OWN refusal class when
2301            // the march fails: the node is why the trace cannot close, and the
2302            // equal-radius torus pair depends on being told so rather than on
2303            // reading a step-budget message it cannot act on.
2304            let marched = match (marched, tangent_node) {
2305                (Err(error), Some(node)) => {
2306                    return Err(KernelRefusal::new(
2307                        RefusalClass::TangentNodeSingularity,
2308                        KernelStage::Intersect,
2309                        format!(
2310                            "boolean: unsupported singular/tangent-node surface intersection \
2311                             between faces {} and {}: the section through the tangent node at \
2312                             ({:.6},{:.6},{:.6}) could not be marched ({error})",
2313                            first.face.id, second.face.id, node.x, node.y, node.z
2314                        ),
2315                    ));
2316                }
2317                (marched, _) => marched,
2318            };
2319            let mut branches = marched
2320            .map_err(|error| {
2321                format!(
2322                    "{error} (marching faces {} and {})",
2323                    first.face.id, second.face.id
2324                )
2325            }).or_refuse(KernelStage::Intersect, "csg.imprint.driver")?;
2326            profile.march += profile.lap(&mut lap_start);
2327            let rescue_started = profile.enabled.then(Instant::now);
2328            // MARCH-ORDER SWAP RESCUE (hatch BREP_MARCH_SWAP_RESCUE=0).
2329            // `intersect_surfaces` is not order-symmetric: the coupled Newton
2330            // trace can fail to start/continue from a valid seed when the two
2331            // surfaces are presented in one operand order yet succeed in the
2332            // other. This is the sole reason t217's `subtract(sphere, step)`
2333            // fails while every other op passes — pair 118x842 (sphere-first)
2334            // marches ZERO branches, while 842x118 (step-first, the working
2335            // a\b order) marches the section from the IDENTICAL accepted pierce
2336            // seeds. When the forward order returns no branch AND an accepted
2337            // transverse pierce seed exists (so a real section provably crosses
2338            // both trims), retry the march with the surfaces swapped — i.e.
2339            // reproduce the exact call the working operand order makes for this
2340            // pair (measured: seed_only alone does NOT recover it — the section
2341            // is found from an auto-grid start, not from the near-tangent pierce
2342            // seeds, which the seed normal-cross gate rejects). The returned
2343            // branch points are 3D and therefore order-independent, so no
2344            // parameter remap is needed; they flow through the identical clip /
2345            // process_curve gates below, which drop any out-of-trim or
2346            // sub-length run exactly as today. The rescue only ever runs when
2347            // the forward order found NOTHING, so it cannot alter a pair that
2348            // already marched.
2349            if branches.is_empty()
2350                && !seed_points.is_empty()
2351                && pair_classification.relation == SurfacePairRelation::Candidate
2352                && std::env::var("BREP_MARCH_SWAP_RESCUE").as_deref() != Ok("0")
2353            {
2354                // FAIL-SOFT: the forward order already returned Ok(empty); a
2355                // swapped-march error (trace-exhaustion is a real error class —
2356                // `intersect_surfaces_supplemental` swallows it for exactly this
2357                // reason) must NOT convert that graceful empty into a hard error.
2358                // On Err, keep the (empty) forward result and carry on.
2359                let swapped = super::work_profile::trace(
2360                    second_march,
2361                    first_march,
2362                    &SurfaceIntersectionOptions {
2363                        tolerance: options.tolerance,
2364                        maximum_step: march_maximum_step(
2365                            &pair_classification,
2366                            options.maximum_ssi_step,
2367                            builder.scale,
2368                        ),
2369                        seed_points: seed_points.clone(),
2370                        span_budget: march_span_budget,
2371                        ordered_starts,
2372                        consume_starts,
2373                        tree_seeds,
2374                        ..Default::default()
2375                    },
2376                )
2377                .unwrap_or_default();
2378                if debug_pairs {
2379                    eprintln!(
2380                        "pair {}x{}: MARCH-SWAP RESCUE attempt -> {} branches, pts {:?}",
2381                        first.face.id,
2382                        second.face.id,
2383                        swapped.len(),
2384                        swapped.iter().map(|b| b.points.len()).collect::<Vec<_>>()
2385                    );
2386                }
2387                if !swapped.is_empty() {
2388                    branches = swapped;
2389                    march_swap_rescues += 1;
2390                }
2391            }
2392            // NEAR-TANGENT CLIP-ORDER RESCUE (hatch BREP_MARCH_SWAP_CLIP_RESCUE=0).
2393            // Companion to the empty-branch MARCH-SWAP RESCUE above:
2394            // `intersect_surfaces` is order-asymmetric not only in WHETHER it
2395            // marches, but in the exact sample positions of the section
2396            // polyline. On a NEAR-TANGENT graze, `clip_branch_to_trims`
2397            // classifies those samples against the mutual trims, and a sample
2398            // landing just past the near-tangent boundary is dropped as a
2399            // false-Outside that TRUNCATES the clipped section. The two operand
2400            // orders drop DIFFERENT near-tangent tail samples, so one order
2401            // yields a section ~0.1-0.2mm shorter at ONE endpoint (t660: b\a's
2402            // step-first order clips pairs 223x105/399x105 ~0.22/0.14mm short of
2403            // the section a\b's cyl-first order keeps, stranding edge 173
2404            // one-use). Near-tangent clip errors are almost exclusively
2405            // false-Outside (a point truly outside a trim rarely projects to an
2406            // in-trim uv), so the order with the LONGER clipped section suffered
2407            // fewer drops and is the more complete one. When the swapped order
2408            // marches the SAME branch structure with a meaningfully longer
2409            // clipped total, adopt its branches (3D points, so they flow through
2410            // the identical clip/process_curve gates below). Gated to Candidate
2411            // pairs (the near-tangent/ambiguous class; clean Transverse
2412            // crossings clip identically in both orders and never differ) with
2413            // an accepted GRAZING pierce seed (min |tan·n| < 0.5 — a real
2414            // section provably crosses, and does so near-tangentially, the only
2415            // regime where the clip wobbles; this also bounds the extra march to
2416            // grazing pairs), and requires a >0.1%-of-length margin so
2417            // raw-sampling jitter (t660: 0.02%) cannot flip a clean pair.
2418            // Fail-soft: any swapped-march or comparison-clip error keeps the
2419            // forward result.
2420            if !branches.is_empty()
2421                && !seed_points.is_empty()
2422                && min_seed_tangency < 0.5
2423                && pair_classification.relation == SurfacePairRelation::Candidate
2424                && std::env::var("BREP_MARCH_SWAP_CLIP_RESCUE").as_deref() != Ok("0")
2425            {
2426                let swapped = super::work_profile::trace(
2427                    second_march,
2428                    first_march,
2429                    &SurfaceIntersectionOptions {
2430                        tolerance: options.tolerance,
2431                        maximum_step: march_maximum_step(
2432                            &pair_classification,
2433                            options.maximum_ssi_step,
2434                            builder.scale,
2435                        ),
2436                        seed_points: seed_points.clone(),
2437                        span_budget: march_span_budget,
2438                        ordered_starts,
2439                        consume_starts,
2440                        tree_seeds,
2441                        ..Default::default()
2442                    },
2443                )
2444                .unwrap_or_default();
2445                // Only a swap that reproduces the SAME branch count — a
2446                // refined-endpoint variant of the same section, not a different
2447                // branch decomposition (guards against adopting a spurious
2448                // extra branch as "longer").
2449                if !swapped.is_empty() && swapped.len() == branches.len() {
2450                    let totals = (|| -> Result<(f64, f64), KernelRefusal> {
2451                        let mut fwd = 0.0;
2452                        for b in &branches {
2453                            let refined = insert_seed_points_into_branch(
2454                                &b.points,
2455                                &seed_points,
2456                                options.tolerance,
2457                            );
2458                            for run in clip_branch_to_trims(&refined, first, second)? {
2459                                fwd += run
2460                                    .windows(2)
2461                                    .map(|p| p[1].sub(p[0]).length())
2462                                    .sum::<f64>();
2463                            }
2464                        }
2465                        let mut swp = 0.0;
2466                        for b in &swapped {
2467                            let refined = insert_seed_points_into_branch(
2468                                &b.points,
2469                                &seed_points,
2470                                options.tolerance,
2471                            );
2472                            for run in clip_branch_to_trims(&refined, first, second)? {
2473                                swp += run
2474                                    .windows(2)
2475                                    .map(|p| p[1].sub(p[0]).length())
2476                                    .sum::<f64>();
2477                            }
2478                        }
2479                        Ok((fwd, swp))
2480                    })();
2481                    if let Ok((fwd_clip, swp_clip)) = totals {
2482                        let margin = fwd_clip.max(swp_clip) * 1.0e-3;
2483                        let adopt = swp_clip > fwd_clip + margin;
2484                        if debug_pairs {
2485                            eprintln!(
2486                                "pair {}x{}: CLIP-SWAP RESCUE fwd_clip={:.6} swp_clip={:.6} margin={:.6}{}",
2487                                first.face.id,
2488                                second.face.id,
2489                                fwd_clip,
2490                                swp_clip,
2491                                margin,
2492                                if adopt { " ADOPT" } else { "" }
2493                            );
2494                        }
2495                        if adopt {
2496                            branches = swapped;
2497                            clip_swap_rescues += 1;
2498                        }
2499                    }
2500                }
2501            }
2502            if let Some(started) = rescue_started {
2503                profile.rescue_march += started.elapsed();
2504            }
2505            // CROSSING-NODE SPLIT (`BREP_SSI_NODE_SPLIT`, default on, `=0` off;
2506            // `intersect/crossing_node.rs`): a branch the marcher carried
2507            // through a saddle tangent node is cut at every passage, so the
2508            // node is a vertex where the four half-branches meet.
2509            if crate::crossing_node_split_enabled() && !branches.is_empty() {
2510                let (split, nodes) = crate::split_at_crossing_nodes(
2511                    first_march,
2512                    second_march,
2513                    std::mem::take(&mut branches),
2514                    options.tolerance,
2515                )
2516                .or_refuse(KernelStage::Intersect, "csg.imprint.driver")?;
2517                branches = split;
2518                for node in nodes {
2519                    if debug_pairs {
2520                        eprintln!(
2521                            "pair {}x{}: crossing node ({:.9},{:.9},{:.9}) split the march",
2522                            first.face.id, second.face.id, node.x, node.y, node.z
2523                        );
2524                    }
2525                    tangent_node.get_or_insert(node);
2526                    if !tangent_nodes.iter().any(|known| known.sub(node).length() <= options.tolerance * 10.0) {
2527                        tangent_nodes.push(node);
2528                    }
2529                }
2530            }
2531            if branches.iter().any(|branch| branch.points.len() >= 2) {
2532                section_evidence = true;
2533            }
2534            if debug_pairs {
2535                eprintln!(
2536                    "pair {}x{}: MARCH {} branches, pts {:?}",
2537                    first.face.id,
2538                    second.face.id,
2539                    branches.len(),
2540                    branches.iter().map(|b| b.points.len()).collect::<Vec<_>>()
2541                );
2542            }
2543            // GRAZING PIERCE, NO SECTION (2026-10-17, the revolve-into-bore
2544            // report). A trim edge of one face pierces the other carrier at
2545            // an angle below the seed gate, inside BOTH trims, and the pair
2546            // marched nothing: the pierce proves a section crosses the faces
2547            // there, the empty march says the crossing is too near tangency
2548            // for the marcher's start gate to admit (the -4° revolve of a
2549            // bored box's top face about its back edge, unioned back: the
2550            // torus hole wall continues the bore tangentially along their
2551            // shared rim and crosses it again at 0.002 rad — a third-order
2552            // contact, `boolean::attribute_to_tangent_node`). Nothing is
2553            // imprinted here; the contact is RECORDED, with the faces across
2554            // the pierced edges, so a tear downstream of it is attributed to
2555            // the contact in the tangent-node class — which declines the
2556            // perturbation ladder — instead of leaking as an anonymous
2557            // open-edge arrangement and burning the ladder's rungs (12.5 s
2558            // on the report, every rung refused by its mirror). A pair whose
2559            // pierce the trims do not both contain is left alone, as is one
2560            // with an accepted seed: those pairs the march could and should
2561            // have answered. `BREP_GRAZING_PIERCE_RECORD=0` is the hatch.
2562            if branches.is_empty()
2563                && seed_points.is_empty()
2564                && !grazing_hits.is_empty()
2565                && options.tangent_curve_lane
2566                && std::env::var("BREP_GRAZING_PIERCE_RECORD").as_deref() != Ok("0")
2567            {
2568                let mut inside: Vec<(Vec3, f64, u8, u64)> = Vec::new();
2569                for &(point, tangency, operand, edge_id, t, on_first) in &grazing_hits {
2570                    // A pierce, not a lies-on sample: the edge must CROSS the
2571                    // carrier at the hit (a rim lying on the other carrier
2572                    // reads |tan·n| = 0 at every sample and never changes
2573                    // side) — and inside both trims.
2574                    let (owner, other_march) = if on_first { (first, second_march) } else { (second, first_march) };
2575                    let Some(edge) = face_edge_lists[&owner.key()].iter().find(|edge| edge.id == edge_id) else {
2576                        continue;
2577                    };
2578                    let crosses = edge_crosses_carrier(edge, &face_edge_lists[&owner.key()], t, other_march, options.tolerance)?;
2579                    // The two halves of a split edge report one pierce at
2580                    // their shared vertex: it is one section point, once.
2581                    if crosses && inside.iter().any(|(seen, ..)| seen.sub(point).length() <= options.tolerance) {
2582                        continue;
2583                    }
2584                    let contained = crosses && inside_both_trims(point, first, second)?;
2585                    if debug_pairs && crosses {
2586                        eprintln!(
2587                            "pair {}x{}: grazing pierce op={operand} edge={edge_id} ({:.6},{:.6},{:.6}) |tan.n|={tangency:.4} inside both trims: {contained}",
2588                            first.face.id, second.face.id, point.x, point.y, point.z
2589                        );
2590                    }
2591                    if contained {
2592                        inside.push((point, tangency, operand, edge_id));
2593                    }
2594                }
2595                // SUB-GATE RE-MARCH (2026-10-17, the same report, second
2596                // half). The pierces are PROVEN section points, so the march
2597                // is retried from them alone, admitted below the marcher's
2598                // start gate: the crossing is resolvable while its lateral
2599                // uncertainty `tol / α` fits inside the tangency band's
2600                // half-width `√(2 R tol)`, i.e. `α ≥ √(tol / 2R)`, and no
2601                // carrier is curved tighter than the model, so the bound is
2602                // taken at `R = scale`. Grid starts stay gated (their
2603                // tangency-band runaway is the gate's reason). A branch that
2604                // comes back is imprinted exactly as a marched one; only when
2605                // none does is the contact recorded for the attribution. The
2606                // retry is fail-soft like the swap rescue: an Err keeps the
2607                // empty forward result. Hatch: BREP_GRAZING_SEED_MARCH=0.
2608                if !inside.is_empty() && std::env::var("BREP_GRAZING_SEED_MARCH").as_deref() != Ok("0") {
2609                    let bound = (options.tolerance / (2.0 * builder.scale.max(options.tolerance))).sqrt();
2610                    let pierces: Vec<Vec3> = inside.iter().map(|(point, _, _, _)| *point).collect();
2611                    let rescued = super::work_profile::trace(
2612                        first_march,
2613                        second_march,
2614                        &SurfaceIntersectionOptions {
2615                            tolerance: options.tolerance,
2616                            maximum_step: march_maximum_step(
2617                                &pair_classification,
2618                                options.maximum_ssi_step,
2619                                builder.scale,
2620                            ),
2621                            seed_points: pierces.clone(),
2622                            seed_only: true,
2623                            seed_start_cross: Some(bound),
2624                            span_budget: march_span_budget,
2625                            ordered_starts,
2626                            consume_starts,
2627                            tree_seeds,
2628                            ..Default::default()
2629                        },
2630                    )
2631                    .unwrap_or_default();
2632                    if debug_pairs {
2633                        eprintln!(
2634                            "pair {}x{}: SUB-GATE MARCH from {} pierce(s) at bound {bound:.3e} -> {} branches, pts {:?}",
2635                            first.face.id,
2636                            second.face.id,
2637                            pierces.len(),
2638                            rescued.len(),
2639                            rescued.iter().map(|b| b.points.len()).collect::<Vec<_>>()
2640                        );
2641                    }
2642                    if !rescued.is_empty() {
2643                        branches = rescued;
2644                        grazing_march = true;
2645                        // The pierces are the branches' exact trim crossings,
2646                        // inserted below like any accepted seed.
2647                        seed_points.extend(pierces);
2648                        inside.clear();
2649                    }
2650                }
2651                if !inside.is_empty() {
2652                    if debug_pairs {
2653                        eprintln!(
2654                            "pair {}x{}: {} grazing pierce(s) inside both trims and no marched branch: {}",
2655                            first.face.id,
2656                            second.face.id,
2657                            inside.len(),
2658                            inside
2659                                .iter()
2660                                .map(|(point, tangency, operand, edge)| format!(
2661                                    "op={operand} edge={edge} ({:.6},{:.6},{:.6}) |tan.n|={tangency:.4}",
2662                                    point.x, point.y, point.z
2663                                ))
2664                                .collect::<Vec<_>>()
2665                                .join(", ")
2666                        );
2667                    }
2668                    // The extended contact the lane can name, when it finds
2669                    // one (the shared rim here); else the record stands on
2670                    // the pierces alone.
2671                    let mut section = match tangent_curve_section(
2672                        first, second, options, &first_faces, &second_faces, &face_edge_lists, debug_pairs,
2673                    )? {
2674                        Some((section, _run)) => section,
2675                        None => TangentSectionRecord {
2676                            first: first.key(),
2677                            second: second.key(),
2678                            start: inside[0].0,
2679                            end: inside[inside.len() - 1].0,
2680                            length: 0.0,
2681                            closed: false,
2682                            stations: 0,
2683                            planar: false,
2684                            faces: vec![first.key(), second.key()],
2685                            piece_ids: Vec::new(),
2686                            grazing: Vec::new(),
2687                        },
2688                    };
2689                    // The faces across each pierced edge: the pierce is where
2690                    // the missing section meets that edge, so those faces are
2691                    // the ones a tear downstream of it will name.
2692                    for (_, _, operand, edge_id) in &inside {
2693                        let siblings = if *operand == first.operand { &first_faces } else { &second_faces };
2694                        for sibling in siblings.iter() {
2695                            let shares = sibling
2696                                .face
2697                                .loops
2698                                .iter()
2699                                .flat_map(|loop_record| &loop_record.coedges)
2700                                .any(|coedge| coedge.edge_id == *edge_id);
2701                            if shares && !section.faces.contains(&sibling.key()) {
2702                                section.faces.push(sibling.key());
2703                            }
2704                        }
2705                    }
2706                    section.grazing = inside.iter().map(|(point, tangency, _, _)| (*point, *tangency)).collect();
2707                    tangent_sections.push(section);
2708                }
2709            }
2710            if profile.enabled {
2711                // Net metadata only: observing carriers must not warm their
2712                // recognition/projection caches before the section fitter.
2713                profile_line!("imprint.march_pair first={:?} second={:?} ids={}x{} degrees={}x{}/{}x{} nets={}x{}/{}x{} stations={:?}",
2714                    first.face.name, second.face.name, first.face.id, second.face.id,
2715                    first.face.surface.degree_u, first.face.surface.degree_v,
2716                    second.face.surface.degree_u, second.face.surface.degree_v,
2717                    first.face.surface.control_points.len(), first.face.surface.control_points.first().map_or(0, Vec::len),
2718                    second.face.surface.control_points.len(), second.face.surface.control_points.first().map_or(0, Vec::len),
2719                    branches.iter().map(|branch| branch.points.len()).collect::<Vec<_>>());
2720            }
2721            // GRAZING PIERCES BOUND CLIP INTERVALS TOO (hosted report
2722            // 2026-11-01, "Boolean seems to take way too long": the cage-box
2723            // union with the cylinder moved 0.165 off the cage's axis). The
2724            // seed gate rejects a pierce whose `|tan·n|` is under 0.1 as a
2725            // march START, but the point is still an exact section point on
2726            // a trim edge: the end of a trim interval. The cylinder's bottom
2727            // rim crosses the cage's flat-to-second-order side twice, 0.036
2728            // apart, at `|tan·n|` = 0.0035, so the disc keeps a 0.036-long
2729            // piece of the y = 0 section there. Marched from the accepted
2730            // seeds with ~0.9 stations, that interval held no station, the
2731            // clip dropped it, the disc's two lenses stayed unbounded and
2732            // the arrangement tore: an open-edge refusal that sent the union
2733            // up the perturbation ladder (64 imprints, ~39 s native, every
2734            // rung refused). Inserting the rejected hits — gated, like every
2735            // seed, to the ones lying on the branch — gives such an interval
2736            // its endpoints. Only a RESOLVABLE pierce is inserted: its
2737            // position along the edge is known to `tol / |tan·n|`, so the
2738            // same bound the sub-gate re-march below admits a start at,
2739            // `|tan·n| >= √(tol / 2·scale)`, keeps the lateral uncertainty
2740            // inside the tangency band. Below it the hits are lies-on
2741            // samples (an edge in the other carrier reads |tan·n| = 0 at
2742            // every sample) or near-tangent brushes whose along-edge
2743            // position is a guess: the 2026-10-25 offset-shell history
2744            // (`successive_fillet_history_shells_under_the_one_call_imprint`)
2745            // inserts 25 pairs' worth of such points at |tan·n| ≤ 1.1e-4 and
2746            // its O.S10 pcurve fit then misses its stations by 2.6e-3.
2747            // `BREP_GRAZING_CLIP_REFINE=0` restores the accepted seeds alone.
2748            let clip_points: std::borrow::Cow<'_, [Vec3]> = if grazing_hits.is_empty()
2749                || std::env::var("BREP_GRAZING_CLIP_REFINE").as_deref() == Ok("0")
2750            {
2751                std::borrow::Cow::Borrowed(&seed_points)
2752            } else {
2753                let resolvable = (options.tolerance / (2.0 * builder.scale.max(options.tolerance))).sqrt();
2754                // A crease fading to tangency along a rim brushes it at |tan.n|
2755                // around 1e-4 for its last stretch, and those hits cut the
2756                // section into micro-pieces whose ends disagree; the interval
2757                // this path exists for pierced at 3.5e-3. `BREP_GRAZING_CLIP_FLOOR=0`
2758                // restores the resolvable bound alone.
2759                let resolvable = if switch!("BREP_GRAZING_CLIP_FLOOR", true) { resolvable.max(1e-3) } else { resolvable };
2760                let mut points = seed_points.clone();
2761                points.extend(grazing_hits.iter().filter(|hit| hit.1 >= resolvable).map(|hit| hit.0));
2762                if debug_pairs && points.len() != seed_points.len() {
2763                    eprintln!(
2764                        "pair {}x{}: {} grazing pierce(s) at |tan.n| >= {resolvable:.3e} join the trim clip",
2765                        first.face.id, second.face.id, points.len() - seed_points.len()
2766                    );
2767                }
2768                std::borrow::Cow::Owned(points)
2769            };
2770            for branch in branches {
2771                // The pierce seeds are the section's exact trim-crossing
2772                // points — insert them so no trim interval shorter than the
2773                // march step is invisible to the point-classification clip.
2774                let refined_points =
2775                    insert_seed_points_into_branch(&branch.points, &clip_points, options.tolerance);
2776                let clip_started = profile.enabled.then(Instant::now);
2777                let mut runs = clip_branch_to_trims(&refined_points, first, second)?;
2778                // TANGENT-RIM LANDING: a run the march stalled short of a trim
2779                // edge the two carriers are tangent along ends ON that edge
2780                // (see `land_run_ends_on_tangent_rim`).
2781                // Reached for the pairs whose march can stall short: one
2782                // carrying an admitted node, one marched from sub-gate
2783                // pierces, or one the classifier read as near-tangent (the
2784                // −10° sibling: no node admitted, an ordinary march that
2785                // stops 4e-5 short of the rim it is tangent along).
2786                if tangent_node.is_some()
2787                    || grazing_march
2788                    || pair_classification.relation == SurfacePairRelation::NearTangent
2789                {
2790                    for run in runs.iter_mut() {
2791                        for (operand, edge_id, parameter, from, to) in land_run_ends_on_tangent_node(
2792                            run,
2793                            first,
2794                            second,
2795                            &face_edge_lists,
2796                            options.tolerance,
2797                        )? {
2798                            if debug_pairs {
2799                                eprintln!(
2800                                    "pair {}x{}: tangent-node landing: run end ({:.6},{:.6},{:.6}) -> \
2801                                     node ({:.9},{:.9},{:.9}) on operand {operand} edge {edge_id} at t={parameter:.9}",
2802                                    first.face.id, second.face.id, from.x, from.y, from.z, to.x, to.y, to.z
2803                                );
2804                            }
2805                            let edge = builder.edges[&(operand, edge_id)];
2806                            builder.add_edge_split(operand, edge, parameter)?;
2807                        }
2808                        for (operand, edge_id, parameter, from, to) in land_run_ends_on_tangent_rim(
2809                            run,
2810                            tangent_node,
2811                            first,
2812                            second,
2813                            &face_edge_lists,
2814                            options.tolerance,
2815                        )? {
2816                            if debug_pairs {
2817                                eprintln!(
2818                                    "pair {}x{}: tangent-rim landing: run end ({:.6},{:.6},{:.6}) -> \
2819                                     ({:.6},{:.6},{:.6}) on operand {operand} edge {edge_id} at t={parameter:.6}",
2820                                    first.face.id, second.face.id, from.x, from.y, from.z, to.x, to.y, to.z
2821                                );
2822                            }
2823                            let edge = builder.edges[&(operand, edge_id)];
2824                            builder.add_edge_split(operand, edge, parameter)?;
2825                        }
2826                    }
2827                }
2828                if debug_pairs {
2829                    let dups = |points: &[Vec3]| points.windows(2).enumerate().filter(|(_, pair)| pair[1].sub(pair[0]).length() <= options.tolerance).map(|(i, pair)| format!("{i}:{:.2e}", pair[1].sub(pair[0]).length())).collect::<Vec<_>>();
2830                    eprintln!(
2831                        "pair {}x{}: DUPS branch {:?} seeded {:?} runs {:?} seeds {} branch_pts {} seeded_pts {}",
2832                        first.face.id, second.face.id, dups(&branch.points), dups(&refined_points), runs.iter().map(|run| dups(run)).collect::<Vec<_>>(), seed_points.len(), branch.points.len(), refined_points.len()
2833                    );
2834                }
2835                if let Some(started) = clip_started {
2836                    profile.clip += started.elapsed();
2837                }
2838                for run in runs {
2839                    if debug_pairs {
2840                        eprintln!(
2841                            "pair {}x{}: clip run len_pts={} length={:.4e}",
2842                            first.face.id,
2843                            second.face.id,
2844                            run.len(),
2845                            run.windows(2)
2846                                .map(|pair| pair[1].sub(pair[0]).length())
2847                                .sum::<f64>()
2848                        );
2849                    }
2850                    if run.len() < 2 {
2851                        continue;
2852                    }
2853                    let length: f64 = run
2854                        .windows(2)
2855                        .map(|pair| pair[1].sub(pair[0]).length())
2856                        .sum();
2857                    if length <= options.tolerance * 100.0 {
2858                        continue;
2859                    }
2860                    let shared_started = profile.enabled.then(Instant::now);
2861                    let follows_shared = branch_follows_shared_boundary(
2862                        &run,
2863                        first,
2864                        second,
2865                        &builder.edges,
2866                        options.tolerance,
2867                        builder.scale,
2868                    )?;
2869                    if let Some(started) = shared_started {
2870                        profile.shared_boundary += started.elapsed();
2871                    }
2872                    if follows_shared {
2873                        if debug_pairs {
2874                            eprintln!(
2875                                "pair {}x{}: run dropped (follows shared boundary)",
2876                                first.face.id, second.face.id
2877                            );
2878                        }
2879                        continue;
2880                    }
2881                    if let Some(census) = pair_census.as_mut() {
2882                        census.record_stations(&run);
2883                    }
2884                    let pieces_before = builder.pieces.len();
2885                    let chunk_points = options.fit_chunk_points.unwrap_or(run.len()).max(2);
2886                    let mut start = 0;
2887                    while start + 1 < run.len() {
2888                        let end = (start + chunk_points - 1).min(run.len() - 1);
2889                        // HERMITE EMISSION (`imprint/hermite.rs`): with the lane on
2890                        // and every span of this run within the budget, the section
2891                        // is the march's own cubic Hermite with its two parameter
2892                        // Hermites, and the fit lane below is skipped.
2893                        let hermite_started = profile.enabled.then(Instant::now);
2894                        let hermite: Option<Result<super::hermite::HermiteSection, super::hermite::HermiteDecline>> = if pair_hermite_lane && end + 1 - start >= hermite_min_stations {
2895                            Some(match emission_budget {
2896                                Some(budget) => super::hermite::hermite_section(&run[start..=end], &branch, first_march, second_march, budget)
2897                                    .or_refuse(KernelStage::Intersect, "csg.imprint.driver.hermite")?,
2898                                None => Err(super::hermite::HermiteDecline::NoTangents),
2899                            })
2900                        } else {
2901                            None
2902                        };
2903                        if let Some(started) = hermite_started {
2904                            profile.hermite += started.elapsed();
2905                        }
2906                        let (section_curve, exact_pcurves) = match hermite {
2907                            Some(Ok(emitted)) => {
2908                                super::work_profile::add(|c| { c.carried_uv_curves += 2; c.carried_uv_stations += 2 * emitted.stations as u64; });
2909                                profile.hermite_runs += 1;
2910                                span_census(|| {
2911                                    format!(
2912                                        "pair {}x{} budget {} branch_stations {} run_stations {} kept {} span_deviation {:.3e} tangents true route None met_requested true lane hermite inserted {}",
2913                                        first.face.id,
2914                                        second.face.id,
2915                                        march_span_budget.map_or("none".to_string(), |budget| format!("{budget:.3e}")),
2916                                        branch.points.len(),
2917                                        emitted.stations,
2918                                        emitted.stations,
2919                                        emitted.deviation,
2920                                        emitted.inserted,
2921                                    )
2922                                });
2923                                (emitted.curve, Some([emitted.pcurve_a, emitted.pcurve_b]))
2924                            }
2925                            other => {
2926                        let hermite_decline = other.map(|lane| lane.err());
2927                        profile.fit_runs += 1;
2928                        let fit_started = profile.enabled.then(Instant::now);
2929                        let fit_tolerance = options.tolerance.max(1e-7);
2930                        let (mut section, mut fit, recovered, evening) = even_sliver_ends_measured(
2931                            run[start..=end].to_vec(),
2932                            &first.face.surface,
2933                            &second.face.surface,
2934                            options.tolerance,
2935                            fit_tolerance,
2936                            options.maximum_fit_points,
2937                            options.local_fit,
2938                        )
2939                        .or_refuse(KernelStage::Intersect, "csg.imprint.driver.sliver_end")?;
2940                        if evening != SliverEvening::NoSliver {
2941                            if let Ok(path) = std::env::var("BREP_SECTION_SLIVER_CENSUS") {
2942                                use std::io::Write;
2943                                if let Ok(mut file) = std::fs::OpenOptions::new().create(true).append(true).open(path) {
2944                                    let _ = writeln!(file, "sliver-end census: pair {}x{} {evening:?} stations {}", first.face.id, second.face.id, section.len());
2945                                }
2946                            }
2947                        }
2948                        // A recovered fit may reproduce every march point yet
2949                        // still wander off the carriers between sparse stations.
2950                        // Measure it against both supports before accepting that
2951                        // recovery, and use the existing bounded SSI refiner.
2952                        let met_requested = fit.report.met_requested_tolerance();
2953                        let refine_route = section_refine_route(
2954                            section_refine_gate(),
2955                            recovered,
2956                            || {
2957                                paired_grazing_crossings
2958                                    && std::env::var("BREP_GRAZE_SECTION_REFINE").as_deref() != Ok("0")
2959                            },
2960                            met_requested,
2961                        )
2962                        .or_else(|| {
2963                            // `BREP_SECTION_CARRIER_MISS=0` restores the fast path
2964                            // for an attribution A/B only (default on).
2965                            if std::env::var("BREP_SECTION_CARRIER_MISS").as_deref() == Ok("0") {
2966                                return None;
2967                            }
2968                            let (station_upper, midspan_upper) =
2969                                fit_split_timed(FitSplitLane::CarrierReadings, || fast_path_carrier_readings(&fit, &section, &first.face.surface, &second.face.surface));
2970                            carrier_miss_route(station_upper, midspan_upper, fit_tolerance)
2971                        });
2972                        let mut refine_unconverged = false;
2973                        let mut refine_worst = 0.0f64;
2974                        if let Some((gate, route)) = refine_route {
2975                            let stations_before = fit.kept.len();
2976                            let refine_census = std::env::var("BREP_SECTION_REFINE_CENSUS").ok();
2977                            let (census_head, census_tail) = (section[0], section[section.len() - 1]);
2978                            let refine_started = refine_census.is_some().then(Instant::now);
2979                            // The wrapper's own two lines, inlined so the receipt
2980                            // can be read (behaviour identical to
2981                            // `refine_section_against_carriers`).
2982                            let representatives = std::env::var("BREP_SECTION_REPRESENTATIVES").as_deref() != Ok("0");
2983                            let mut receipt = RefineReceipt::default();
2984                            let (refined, worst, unrefined, rounds, exit) = refine_section_against_carriers_with(
2985                                &mut section,
2986                                fit,
2987                                &first.face.surface,
2988                                &second.face.surface,
2989                                fit_tolerance,
2990                                options.tolerance,
2991                                options.local_fit,
2992                                gate * fit_tolerance,
2993                                representatives,
2994                                &mut receipt,
2995                            ).or_refuse(KernelStage::Intersect, "csg.imprint.driver.midspan")?;
2996                            let _ = &receipt;
2997                            // `BREP_SECTION_REFINE_CENSUS=<file>`: one line per section,
2998                            // appended, so a corpus replay (whose children's stderr is
2999                            // captured) can be read for trip counts and growth.
3000                            // The route, whether the standing fit met its request, and
3001                            // the refiner's own wall time close the line, so a run can
3002                            // total the UNMET-REQUEST route's cost apart from the
3003                            // global gate's (which reads every section).
3004                            if let Some(path) = refine_census {
3005                                use std::io::Write;
3006                                if let Ok(mut file) = std::fs::OpenOptions::new().create(true).append(true).open(path) {
3007                                    let _ = writeln!(
3008                                        file,
3009                                        "section-refine census: pair {}x{} exit {:?} rounds {} stations {} -> {} unrefined {:.3e} worst {:.3e} route {:?} met_requested {} ms {:.3} head ({:.9}, {:.9}, {:.9}) tail ({:.9}, {:.9}, {:.9})",
3010                                        first.face.id, second.face.id, exit, rounds, stations_before, refined.kept.len(), unrefined, worst,
3011                                        route, met_requested, refine_started.map_or(0.0, |started| started.elapsed().as_secs_f64() * 1e3),
3012                                        census_head.x, census_head.y, census_head.z, census_tail.x, census_tail.y, census_tail.z
3013                                    );
3014                                }
3015                            }
3016                            if debug_pairs && (rounds > 0 || !matches!(exit, MidspanExit::Converged | MidspanExit::BelowGate)) {
3017                                eprintln!(
3018                                    "pair {}x{}: mid-span refinement {:?} after {} round(s): {} stations, worst {:.3e}",
3019                                    first.face.id, second.face.id, exit, rounds, section.len(), worst
3020                                );
3021                            }
3022                            refine_unconverged = !matches!(exit, MidspanExit::Converged | MidspanExit::BelowGate);
3023                            refine_worst = worst;
3024                            fit = refined;
3025                        }
3026                        span_census(|| {
3027                            format!(
3028                                "pair {}x{} budget {} branch_stations {} run_stations {} kept {} span_deviation {} tangents {} route {:?} met_requested {} lane fit hermite {}",
3029                                first.face.id,
3030                                second.face.id,
3031                                march_span_budget.map_or("none".to_string(), |budget| format!("{budget:.3e}")),
3032                                branch.points.len(),
3033                                section.len(),
3034                                fit.kept.len(),
3035                                branch.span_deviation.map_or("none".to_string(), |deviation| format!("{deviation:.3e}")),
3036                                branch.tangents.is_some(),
3037                                refine_route.map(|(_, route)| route),
3038                                met_requested,
3039                                hermite_decline.map_or("off".to_string(), |decline| decline.map_or("none".to_string(), |decline| format!("{decline:?}"))),
3040                            )
3041                        });
3042                        // `BREP_SECTION_OVERSHOOT_CENSUS=<file>` (debug only; nothing
3043                        // reads it): EVERY section's final fit, on any route, is read
3044                        // against both carriers at its kept stations and at its
3045                        // mid-spans, so a fit that stands further off the carriers
3046                        // between its stations than at them (fixture 28 t217: 5.07e-4
3047                        // shipped against a 1.32e-4 worst station) is counted, not
3048                        // guessed. Projector distances are upper readings; the line
3049                        // says so by its field names.
3050                        {
3051                            if let Ok(path) = std::env::var("BREP_SECTION_OVERSHOOT_CENSUS") {
3052                                // An unreadable station makes the whole reading NaN
3053                                // (f64::max would silently drop it).
3054                                let read = |surface: &NurbsSurface, point: Vec3| {
3055                                    project_point_to_surface(surface, point).map_or(f64::NAN, |projection| projection.distance)
3056                                };
3057                                let mut station_worst = 0.0f64;
3058                                for point in &fit.kept {
3059                                    let (a, b) = (read(&first.face.surface, *point), read(&second.face.surface, *point));
3060                                    station_worst = if a.is_nan() || b.is_nan() || station_worst.is_nan() { f64::NAN } else { station_worst.max(a).max(b) };
3061                                }
3062                                let (run_worst, _) = fast_path_carrier_readings(&fit, &section, &first.face.surface, &second.face.surface);
3063                                let interior_worst = knot_interior_carrier_upper(&fit.curve, &first.face.surface, &second.face.surface);
3064                                let misses = midspan_misses_only(&fit, &first.face.surface, &second.face.surface).unwrap_or_default();
3065                                let (worst_span, midspan_worst) = misses
3066                                    .iter()
3067                                    .copied()
3068                                    .enumerate()
3069                                    .fold((usize::MAX, 0.0f64), |best, (span, miss)| if miss > best.1 { (span, miss) } else { best });
3070                                let line = format!(
3071                                    "section-overshoot census: pair {}x{} route {:?} kept {} spans_read {} station_upper {:.3e} midspan_upper {:.3e} worst_span {} fit_tolerance {:.1e} ratio {:.3} run {} run_upper {run_worst:.3e} knot_interior_upper {interior_worst:.3e} head ({:.9}, {:.9}, {:.9}) tail ({:.9}, {:.9}, {:.9})\n",
3072                                    first.face.id, second.face.id, refine_route.map(|(_, route)| route), fit.kept.len(), misses.len(), station_worst, midspan_worst,
3073                                    if worst_span == usize::MAX { -1 } else { worst_span as i64 }, fit_tolerance,
3074                                    midspan_worst / station_worst.max(fit_tolerance),
3075                                    section.len(),
3076                                    section[0].x, section[0].y, section[0].z,
3077                                    section[section.len() - 1].x, section[section.len() - 1].y, section[section.len() - 1].z
3078                                );
3079                                use std::io::Write;
3080                                if let Ok(mut file) = std::fs::OpenOptions::new().create(true).append(true).open(path) {
3081                                    let _ = file.write_all(line.as_bytes());
3082                                }
3083                            }
3084                        }
3085                        if let Some(started) = fit_started {
3086                            profile.fit += started.elapsed();
3087                        }
3088                        if let Some(census) = pair_census.as_mut() {
3089                            census.record_fit(&fit);
3090                        }
3091                        // HERMITE 3-D LANE (`BREP_SECTION_HERMITE_3D`, default on;
3092                        // `imprint/hermite.rs`): a fit the refiner left unconverged and
3093                        // still missing a carrier by more than [`HERMITE_3D_GROSS_MISS`]
3094                        // fit tolerances, or one standing further from its own polyline
3095                        // between stations than half the run's longest chord (ringing,
3096                        // not chord sag), is
3097                        // replaced by the C1 cubic through the march stations and their
3098                        // tangents, bisected onto true intersection points until every
3099                        // span holds the fit tolerance on both carriers. A run the lane
3100                        // cannot bring within that keeps the fit.
3101                        let mut lane_pcurves = None;
3102                        if super::hermite::hermite_3d_enabled() {
3103                            let longest = section.windows(2).map(|pair| pair[1].sub(pair[0]).length()).fold(0.0f64, f64::max);
3104                            let ringing = !(fit.report.between_stations <= 0.5 * longest);
3105                            let gross = refine_unconverged && !(refine_worst <= HERMITE_3D_GROSS_MISS * fit_tolerance);
3106                            if gross || ringing {
3107                                let emitted = super::hermite::hermite_section_3d(
3108                                    &run[start..=end],
3109                                    &branch,
3110                                    &first.face.surface,
3111                                    &second.face.surface,
3112                                    fit_tolerance,
3113                                )
3114                                .or_refuse(KernelStage::Intersect, "csg.imprint.driver.hermite_3d")?;
3115                                if debug_pairs {
3116                                    eprintln!(
3117                                        "pair {}x{}: hermite 3-D lane (gross {gross}, unconverged {refine_unconverged} worst {refine_worst:.3e}, ringing {ringing} between {:.3e} longest {longest:.3e}): {}",
3118                                        first.face.id,
3119                                        second.face.id,
3120                                        fit.report.between_stations,
3121                                        emitted.as_ref().map_or("declined".to_string(), |(curve, _)| format!("{} controls", curve.control_points.len()))
3122                                    );
3123                                }
3124                                // `BREP_HERMITE_3D_CENSUS=<file>`: one line per section the
3125                                // lane is asked to take, appended (debug only).
3126                                if let Ok(path) = std::env::var("BREP_HERMITE_3D_CENSUS") {
3127                                    use std::io::Write;
3128                                    if let Ok(mut file) = std::fs::OpenOptions::new().create(true).append(true).open(path) {
3129                                        let _ = writeln!(
3130                                            file,
3131                                            "hermite-3d census: label {} pair {}x{} gross {gross} ringing {ringing} worst {refine_worst:.3e} between {:.3e} -> {}",
3132                                            std::env::var("BREP_CENSUS_LABEL").unwrap_or_default(),
3133                                            first.face.id,
3134                                            second.face.id,
3135                                            fit.report.between_stations,
3136                                            emitted.as_ref().map_or("declined".to_string(), |(curve, _)| format!("{} controls", curve.control_points.len()))
3137                                        );
3138                                    }
3139                                }
3140                                if let Some((curve, pcurves)) = emitted {
3141                                    fit.curve = curve;
3142                                    lane_pcurves = Some(pcurves);
3143                                }
3144                            }
3145                        }
3146                        (fit.curve, lane_pcurves)
3147                            }
3148                        };
3149                        let process_started = profile.enabled.then(Instant::now);
3150                        builder.process_curve(
3151                            section_curve,
3152                            first,
3153                            second,
3154                            &[first, second],
3155                            &[first, second],
3156                            true,
3157                            exact_pcurves,
3158                        )?;
3159                        if let Some(started) = process_started {
3160                            profile.process += started.elapsed();
3161                        }
3162                        start = end;
3163                    }
3164                    for piece in &builder.pieces[pieces_before..] {
3165                        builder.marched_pieces.insert(piece.id);
3166                    }
3167                    if debug_pairs {
3168                        eprintln!(
3169                            "pair {}x{}: run -> {} pieces",
3170                            first.face.id,
3171                            second.face.id,
3172                            builder.pieces.len() - pieces_before
3173                        );
3174                    }
3175                }
3176            }
3177            profile.clip_and_fit += profile.lap(&mut lap_start);
3178        }
3179    }
3180    for (span, first, second, target) in deferred_boundary_spans {
3181        builder.process_curve(span, first, second, &[target], &[target], false, None)?;
3182    }
3183    if let Some(scope) = pairs_fits {
3184        profile.pairs_fits = scope.close().fits;
3185    }
3186    super::work_profile::faces(first_faces.iter().chain(&second_faces)
3187        .map(|face| (face.face, builder.by_face.contains_key(&face.key()))));
3188    profile.report();
3189    let hull_culls = super::builder::take_hull_culls();
3190    if profile.enabled && super::builder::hull_cull_enabled() {
3191        profile_line!("imprint.hull_culls edges={hull_culls}");
3192    }
3193    // The row counters are drained only when they are printed, so a test
3194    // reading them after a whole operation sees every call's count.
3195    if profile.enabled && super::builder::pierce_cull_enabled() {
3196        profile_line!("imprint.pierce_culls edges={}", super::builder::take_pierce_culls());
3197    }
3198    if profile.enabled {
3199        let overlap_hull_skips = super::sections::take_overlap_hull_skips();
3200        if overlap_hull_skips > 0 {
3201            profile_line!("imprint.overlap_hull_skips stations={overlap_hull_skips}");
3202        }
3203        let exchange_hull_skips = super::builder::take_exchange_hull_skips();
3204        if exchange_hull_skips > 0 {
3205            profile_line!("imprint.exchange_hull_skips answered={exchange_hull_skips}");
3206        }
3207    }
3208    // SELF-TOUCH SPLIT: a face whose loops touch at an edge interior (a hole
3209    // tangent to a fillet setback) gets a vertex minted at the touch on BOTH
3210    // edges, so the fragment arrangement's pinch resolution assembles — see
3211    // `imprint/self_touch.rs`. Escape hatch: BREP_SELF_TOUCH_SPLIT=0.
3212    let mut tail_lap: Option<Instant> = None;
3213    // Beside each stage's time, the pcurve fits it recorded (a nested
3214    // `PcurveFitScope` per stage, folded into the operation's ledger).
3215    let mut tail_fits: Option<crate::PcurveFitScope> = None;
3216    let mut tail_ms = Vec::<(&str, f64, u64)>::new();
3217    let mut lap = |name: &'static str,
3218                   started: &mut Option<Instant>,
3219                   fits: &mut Option<crate::PcurveFitScope>,
3220                   tail_ms: &mut Vec<(&str, f64, u64)>| {
3221        if profile.enabled {
3222            let now = Instant::now();
3223            let recorded = fits.take().map_or(0, |scope| scope.close().fits);
3224            if let Some(previous) = *started {
3225                tail_ms.push((name, (now - previous).as_secs_f64() * 1_000.0, recorded));
3226            }
3227            *started = Some(now);
3228            *fits = Some(crate::PcurveFitScope::open());
3229        }
3230    };
3231    lap("pairs", &mut tail_lap, &mut tail_fits, &mut tail_ms);
3232    if std::env::var("BREP_SELF_TOUCH_SPLIT").as_deref() != Ok("0") {
3233        let scans_before = super::self_touch::touch_scans();
3234        builder.split_self_touching_loops(&first_faces, &face_edge_lists, &cached_subcurve)?;
3235        builder.split_self_touching_loops(&second_faces, &face_edge_lists, &cached_subcurve)?;
3236        if profile.enabled {
3237            profile_line!("imprint.self_touch faces={} scanned={}", first_faces.len() + second_faces.len(), super::self_touch::touch_scans() - scans_before);
3238        }
3239    }
3240    // PIECE-ENDPOINT EXCHANGE post-pass: with every pair's process_curve
3241    // done, the piece set is final for the ridden-edge class — imprint each
3242    // open riding piece's junction endpoints onto the ridden edges (see the
3243    // method doc; hatch BREP_OVERLAP_PIECE_ENDPOINT_SPLIT=0).
3244    builder.exchange_piece_endpoint_junctions()?;
3245    // TANGENT-SECTION IMPRINT (`ImprintOptions::tangent_curve_imprint`), after
3246    // every pair: whether a run splits a face is read against the face's trim
3247    // AND the pieces the other pairs minted on it, so the runs are minted
3248    // once the piece set is complete (the through-bore's contact ends on the
3249    // bore's cap circles, which the box's top and bottom minted).
3250    for (index, run, first, second) in std::mem::take(&mut tangent_imprint_candidates) {
3251        let closed = tangent_sections[index].closed;
3252        tangent_sections[index].piece_ids = imprint_tangent_run(
3253            &mut builder,
3254            &run,
3255            closed,
3256            first,
3257            second,
3258            &face_edge_lists,
3259            options,
3260            std::env::var("BREP_DEBUG_PAIRS").is_ok(),
3261        )?;
3262    }
3263    // TANGENT-SECTION T-JUNCTIONS (`ImprintOptions::tangent_curve_imprint`):
3264    // an imprinted contact ends on operand edges, which `process_curve` split,
3265    // and on earlier SECTIONS of the same carrier, which nothing splits — the
3266    // through-bore's contact line ends on the two cap circles the box's top
3267    // and bottom minted on the bore. Split those pieces at the contact's end
3268    // vertices so both faces of each circle carry the vertex the bore's
3269    // arrangement needs there (see `split_pieces_at_tangent_ends`).
3270    if tangent_sections.iter().any(|section| !section.piece_ids.is_empty()) {
3271        split_pieces_at_tangent_ends(
3272            &mut builder,
3273            &tangent_sections,
3274            &first_faces,
3275            &second_faces,
3276            options,
3277            std::env::var("BREP_DEBUG_PAIRS").is_ok(),
3278        )?;
3279    }
3280    lap("self_touch", &mut tail_lap, &mut tail_fits, &mut tail_ms);
3281    let mut edge_splits = builder
3282        .edge_splits
3283        .into_iter()
3284        .map(|((operand, edge_id), mut parameters)| {
3285            parameters.sort_by(f64::total_cmp);
3286            EdgeSplitRecord {
3287                operand,
3288                edge_id,
3289                parameters,
3290            }
3291        })
3292        .collect::<Vec<_>>();
3293    edge_splits.sort_by_key(|record| (record.operand, record.edge_id));
3294    let mut by_face = builder
3295        .by_face
3296        .into_iter()
3297        .map(|(face, piece_ids)| FaceImprints {
3298            operand: face.operand,
3299            face_id: face.face_id,
3300            piece_ids,
3301        })
3302        .collect::<Vec<_>>();
3303    by_face.sort_by_key(|record| (record.operand, record.face_id));
3304    let section_evidence = section_evidence || !builder.pieces.is_empty();
3305    let marched_pieces = std::mem::take(&mut builder.marched_pieces);
3306    let mut emitted_pcurves = std::mem::take(&mut builder.emitted_pcurves);
3307    let junction_evidence = JunctionEvidence {
3308        radii: std::mem::take(&mut builder.vertex_radii),
3309        sources: std::mem::take(&mut builder.vertex_sources),
3310    };
3311    let mut result = ImprintResultRecord {
3312        tangent_nodes,
3313        tangent_sections,
3314        vertices: builder.vertices,
3315        pieces: builder.pieces,
3316        by_face,
3317        edge_splits,
3318        barrier_edges: builder.barrier_edges.into_iter().collect(),
3319        section_evidence,
3320        cosurface_pairs,
3321    };
3322    RESCUE_FIRINGS.with(|cell| cell.set((march_swap_rescues, clip_swap_rescues)));
3323    if profile.enabled {
3324        profile_line!("imprint.rescues march_swap={march_swap_rescues} clip_swap={clip_swap_rescues}");
3325    }
3326    // COINCIDENT-PIECE MERGE (and the generic one-circle-from-many-pairs
3327    // class): the SAME section curve can be minted by several pairs — a
3328    // cosurface boundary-edge copy (the cylinder cap ring lying ON the
3329    // inscribed sphere) AND the cap-plane's analytic section ring are one
3330    // circle minted twice, each carrying only its own pair's
3331    // supports/pcurves. Assembly then builds duplicate edges that cannot both
3332    // be two-use → one-use strands. Merge pieces whose curves coincide along
3333    // their whole span (bidirectional max deviation within the weld band):
3334    // keep the first, union the supports/pcurves/by_face registrations of the
3335    // rest into it. Escape hatch: BREP_COINCIDENT_PIECE_MERGE=0.
3336    lap("collect", &mut tail_lap, &mut tail_fits, &mut tail_ms);
3337    if std::env::var("BREP_COINCIDENT_PIECE_MERGE").as_deref() != Ok("0") {
3338        let weld = assembler_weld(options.tolerance).max(options.tolerance * 10.0);
3339        // Two pieces that coincide along their WHOLE spans (deviation within
3340        // the weld both ways) also have matching end points, up to direction
3341        // and a weld or two of overhang, so a piece whose ends are nowhere
3342        // near the other's needs no 33-station projection sweep. The sweep is
3343        // what made this pass quadratic in wall time: 630 pieces cost 3.2 s
3344        // of a 3.8 s imprint on the 2026-09-12 mesh-import report, all of it
3345        // rejecting pairs an end-point look already rules out.
3346        let mut ends: Vec<[Vec3; 2]> = Vec::with_capacity(result.pieces.len());
3347        for piece in &result.pieces {
3348            let [d0, d1] = piece.curve.domain().or_refuse(KernelStage::Intersect, "domain")?;
3349            ends.push([
3350                piece.curve.evaluate(d0).or_refuse(KernelStage::Intersect, "evaluate")?,
3351                piece.curve.evaluate(d1).or_refuse(KernelStage::Intersect, "evaluate")?,
3352            ]);
3353        }
3354        let end_band = 4.0 * weld;
3355        // CONTROL-HULL CULL (2026-10-10): the plate minus 36 cylinders mints 72
3356        // CLOSED rings, every one of which took the full sweep against every other —
3357        // 2 556 pairs, 230 of the imprint's 288 ms — although rings 16 units apart
3358        // cannot coincide. A NURBS curve lies in the convex hull of its control
3359        // points, so two curves within `weld` of each other along their whole spans
3360        // have control boxes that overlap once each is grown by `weld`; a pair whose
3361        // boxes do not is skipped before any projection. Exact, so the merged set is
3362        // the one the sweep alone found. `BREP_COINCIDENT_MERGE_BOX=0` restores the
3363        // unculled sweep for a before/after reading.
3364        let box_cull = std::env::var("BREP_COINCIDENT_MERGE_BOX").as_deref() != Ok("0");
3365        let mut boxes: Vec<[Vec3; 2]> = Vec::with_capacity(result.pieces.len());
3366        for piece in &result.pieces {
3367            boxes.push(control_hull_box(&piece.curve, weld));
3368        }
3369        // A CLOSED piece (a full ring) has no end points to speak of: two
3370        // rings of the same circle seamed at different azimuths coincide
3371        // along their whole spans while their domain ends sit anywhere on
3372        // the ring, so a closed piece always takes the full sweep.
3373        let ends_match = |a: &[Vec3; 2], b: &[Vec3; 2]| -> bool {
3374            let near = |p: Vec3, q: Vec3| p.sub(q).length() <= end_band;
3375            near(a[0], a[1])
3376                || near(b[0], b[1])
3377                || (near(a[0], b[0]) && near(a[1], b[1]))
3378                || (near(a[0], b[1]) && near(a[1], b[0]))
3379        };
3380        let mut removed: Vec<u64> = Vec::new();
3381        let mut index = 0;
3382        while index < result.pieces.len() {
3383            let mut other = index + 1;
3384            while other < result.pieces.len() {
3385                let coincide = (!box_cull || boxes_overlap(&boxes[index], &boxes[other]))
3386                    && ends_match(&ends[index], &ends[other])
3387                    && {
3388                        let a = &result.pieces[index];
3389                        let b = &result.pieces[other];
3390                        // FEATURE SCALE B2 (`BREP_FEATURE_SCALE_IMPRINT`):
3391                        // the weld (1e-6) equals the hairline slot's width,
3392                        // so the two walls' pieces read as one; beside a
3393                        // feature the weld is capped at a quarter of it.
3394                        let weld = if tail_feature_scale.is_empty() {
3395                            weld
3396                        } else {
3397                            tail_feature_scale.cap(ends[index][0], weld).min(tail_feature_scale.cap(ends[index][1], weld))
3398                        };
3399                        max_curve_deviation(&a.curve, &b.curve)? <= weld
3400                            && max_curve_deviation(&b.curve, &a.curve)? <= weld
3401                    };
3402                if coincide {
3403                    let absorbed = result.pieces.remove(other);
3404                    ends.remove(other);
3405                    boxes.remove(other);
3406                    removed.push(absorbed.id);
3407                    let keeper = &mut result.pieces[index];
3408                    for pcurve in absorbed.pcurves {
3409                        if !keeper
3410                            .pcurves
3411                            .iter()
3412                            .any(|existing| {
3413                                existing.operand == pcurve.operand
3414                                    && existing.face_id == pcurve.face_id
3415                            })
3416                        {
3417                            let key = FaceKey { operand: pcurve.operand, face_id: pcurve.face_id };
3418                            if emitted_pcurves.remove(&(absorbed.id, key)) {
3419                                emitted_pcurves.insert((keeper.id, key));
3420                            }
3421                            keeper.pcurves.push(pcurve);
3422                        }
3423                    }
3424                    let keeper_id = keeper.id;
3425                    for record in &mut result.by_face {
3426                        if let Some(position) =
3427                            record.piece_ids.iter().position(|&id| id == absorbed.id)
3428                        {
3429                            if record.piece_ids.contains(&keeper_id) {
3430                                record.piece_ids.remove(position);
3431                            } else {
3432                                record.piece_ids[position] = keeper_id;
3433                            }
3434                        }
3435                    }
3436                } else {
3437                    other += 1;
3438                }
3439            }
3440            index += 1;
3441        }
3442        if !removed.is_empty() && std::env::var("BREP_DEBUG_BOOL").is_ok() {
3443            eprintln!("coincident-piece merge: absorbed {:?}", removed);
3444        }
3445    }
3446    // Rescue near-tangent SSI truncations BEFORE canonicalization so the added
3447    // bridge pieces' endpoints (existing crossing/stub vertices) fold into the
3448    // same junction merges as every other section.
3449    lap("coincident_merge", &mut tail_lap, &mut tail_fits, &mut tail_ms);
3450    extend_truncated_sections(
3451        &mut result,
3452        &face_edge_lists,
3453        solid_a,
3454        solid_b,
3455        &charts,
3456        options.tolerance,
3457    )?;
3458    lap("extend_truncated", &mut tail_lap, &mut tail_fits, &mut tail_ms);
3459    canonicalize_imprint_junctions(
3460        &mut result,
3461        solid_a,
3462        solid_b,
3463        &charts,
3464        options.tolerance,
3465        &emitted_pcurves,
3466        &junction_evidence,
3467        junction_combine_mode(options),
3468        &tail_feature_scale,
3469        // The composite one-call carrier imprint keeps the per-pair contract:
3470        // no residual-evidence vertex merge across its admitted pairs (see
3471        // the parameter doc on `canonicalize_imprint_junctions`).
3472        self_pairs.is_none(),
3473    )?;
3474    lap("canonicalize", &mut tail_lap, &mut tail_fits, &mut tail_ms);
3475    // ONE RIM, ONE EDGE: with vertex identity final, dissolve the section
3476    // vertices that no operand edge passes through — the marcher's own
3477    // parameterization origin, which `process_curve` cannot tell from a
3478    // junction because it sees one pair at a time. See the method doc.
3479    let dissolved = dissolve_section_origin_vertices(
3480        &mut result,
3481        &marched_pieces,
3482        solid_a,
3483        solid_b,
3484        &charts,
3485        options.tolerance,
3486    )?;
3487    if dissolved > 0 && std::env::var("BREP_DEBUG_BOOL").is_ok() {
3488        eprintln!("origin-dissolve: {dissolved} parameterization vertex/vertices removed");
3489    }
3490    lap("origin_dissolve", &mut tail_lap, &mut tail_fits, &mut tail_ms);
3491    // B2: reuse an existing boundary edge as the shared section edge wherever a
3492    // section coincides with one along its whole span (vertices are final after
3493    // canonicalization; `face_edge_lists` holds each face's boundary edges on
3494    // the healed operands). Runs here so both operands reference ONE edge.
3495    reuse_boundary_section_edges(
3496        &mut result,
3497        &face_edge_lists,
3498        solid_a,
3499        solid_b,
3500        options.tolerance,
3501    )?;
3502    // Capstone step 1 — instrumentation only, zero behavior change: report
3503    // every (section piece × boundary edge) contact where the piece runs
3504    // within the scale-derived band of the edge over a real span. Measuring
3505    // the bands here first validates the graze-contact model on the
3506    // acceptance suite before step 2's common-block machinery replaces a
3507    // grazed overlap with a shared edge.
3508    lap("reuse_boundary", &mut tail_lap, &mut tail_fits, &mut tail_ms);
3509    report_graze_contacts(&result, &face_edge_lists, solid_a, solid_b, options.tolerance)?;
3510    if profile.enabled {
3511        if let Some(scope) = tail_fits.take() {
3512            scope.close();
3513        }
3514        let line = tail_ms
3515            .iter()
3516            .map(|(name, ms, _)| format!("{name}={ms:.2}"))
3517            .collect::<Vec<_>>()
3518            .join(" ");
3519        profile_line!("imprint.stages {line}");
3520        let split = imprint_split_take();
3521        let ms = |d: Duration| d.as_secs_f64() * 1_000.0;
3522        profile_line!(
3523            "imprint.split pierce={:.3} pierce_edges={} overlap={:.3} overlap_edges={} crossing={:.3} crossing_edges={} recover={:.3} recover_pierces={} lies_whole={:.3} lies_whole_calls={} lies_whole_hits={} lies_span={:.3} lies_span_calls={} reuse_edges={}",
3524            ms(split.pierce), split.pierce_edges, ms(split.overlap), split.overlap_edges, ms(split.crossing), split.crossing_edges,
3525            ms(split.recover), split.recover_pierces, ms(split.lies_whole), split.lies_whole_calls, split.lies_whole_hits,
3526            ms(split.lies_span), split.lies_span_calls, split.reuse_edges,
3527        );
3528        let fits = tail_ms
3529            .iter()
3530            .map(|(name, _, fits)| format!("{name}={fits}"))
3531            .collect::<Vec<_>>()
3532            .join(" ");
3533        profile_line!("imprint.stage_fits {fits}");
3534    }
3535    if let Ok(path) = std::env::var("BREP_IMPRINT_SECTION_CENSUS") {
3536        use std::io::Write;
3537        // A private observation of the complete imprint, including section
3538        // curves, pcurves and junctions. Canonicalize only the set-valued
3539        // barrier list on a COPY; leave every returned record untouched.
3540        let mut observed = result.clone();
3541        observed.barrier_edges.sort_unstable();
3542        let bytes = serde_json::to_vec(&observed).expect("serialize imprint census");
3543        let digest = bytes.iter().fold(0xcbf29ce484222325_u64,
3544            |hash, byte| (hash ^ u64::from(*byte)).wrapping_mul(0x100000001b3));
3545        let mut file = std::fs::OpenOptions::new().create(true).append(true).open(path)
3546            .expect("open imprint section census");
3547        writeln!(file, "imprint.sections digest={digest:016x} bytes={} pieces={} vertices={}",
3548            bytes.len(), observed.pieces.len(), observed.vertices.len()).expect("append imprint section census");
3549    }
3550    Ok(result)
3551}
3552
3553/// Debug-only graze-contact survey (`BREP_DEBUG_GRAZE=1`): for each section
3554/// piece and each boundary edge of its support faces, sample the piece and
3555/// measure distance to the edge; report contacts whose in-band span exceeds
3556/// both the weld scale and 4× the minimum deviation (span-wise proximity, not
3557/// a point touch). `band_cap` reuses the residual-merge `sep_cap` ceiling —
3558/// measured, never grown. The output is the raw material for capstone step 2
3559/// (partial-span common-block): which contacts exist, their spans, and their
3560/// measured bands.
3561fn report_graze_contacts(
3562    result: &ImprintResultRecord,
3563    face_edge_lists: &HashMap<FaceKey, Vec<&EdgeRecord>>,
3564    solid_a: &BrepSolid,
3565    solid_b: &BrepSolid,
3566    tolerance: f64,
3567) -> Result<(), KernelRefusal> {
3568    if std::env::var("BREP_DEBUG_GRAZE").as_deref() != Ok("1") {
3569        return Ok(());
3570    }
3571    let raw_extent = raw_solid_extent(solid_a).max(raw_solid_extent(solid_b));
3572    let (_, band_cap) = residual_merge_bands(raw_extent, tolerance);
3573    const SAMPLES: usize = 17;
3574    for piece in &result.pieces {
3575        let [t0, t1] = [piece.t0, piece.t1];
3576        if !(t1 > t0) {
3577            continue;
3578        }
3579        for key in piece.support_faces {
3580            let Some(edges) = face_edge_lists.get(&key) else {
3581                continue;
3582            };
3583            for edge in edges {
3584                if edge.degenerate {
3585                    continue;
3586                }
3587                let mut in_band = 0usize;
3588                let mut min_dev = f64::INFINITY;
3589                let mut max_dev_in_band = 0.0f64;
3590                let mut span = 0.0f64;
3591                let mut prev: Option<(bool, Vec3)> = None;
3592                for k in 0..SAMPLES {
3593                    let t = t0 + (t1 - t0) * k as f64 / (SAMPLES - 1) as f64;
3594                    let point = piece.curve.evaluate(t).or_refuse(KernelStage::Intersect, "evaluate")?;
3595                    let deviation = project_point_to_curve(&edge.curve, point).or_refuse(KernelStage::Intersect, "project_point_to_curve")?.distance;
3596                    min_dev = min_dev.min(deviation);
3597                    let inside = deviation <= band_cap;
3598                    if inside {
3599                        in_band += 1;
3600                        max_dev_in_band = max_dev_in_band.max(deviation);
3601                        if let Some((true, prev_point)) = prev {
3602                            span += point.sub(prev_point).length();
3603                        }
3604                    }
3605                    prev = Some((inside, point));
3606                }
3607                // Span-wise contact: several consecutive samples in band and a
3608                // span that dwarfs the closest-approach (not a transversal
3609                // crossing, which dips in and out at one sample).
3610                if in_band >= 3 && span > (4.0 * min_dev).max(assembler_weld(tolerance)) {
3611                    eprintln!(
3612                        "graze: piece {} sup=[{}:{},{}:{}] ~ edge {}:{} span={:.3e} band=[{:.3e},{:.3e}] samples_in_band={}/{}",
3613                        piece.id,
3614                        piece.support_faces[0].operand,
3615                        piece.support_faces[0].face_id,
3616                        piece.support_faces[1].operand,
3617                        piece.support_faces[1].face_id,
3618                        key.operand,
3619                        edge.id,
3620                        span,
3621                        min_dev,
3622                        max_dev_in_band,
3623                        in_band,
3624                        SAMPLES
3625                    );
3626                }
3627            }
3628        }
3629    }
3630    Ok(())
3631}
3632
3633/// `BREP_RIM_BRIDGE` (default on, `=0` off): see RIM BRIDGE in the pair loop.
3634fn rim_bridge_enabled() -> bool {
3635    crate::switch!("BREP_RIM_BRIDGE", true)
3636}
3637
3638/// The rim pierces of a tangential-only pair, bridged (see RIM BRIDGE in the
3639/// pair loop): every edge of each face that CROSSES the other carrier at a
3640/// grazing angle (`|tan·n|` under the seed gate) inside both trims, and for
3641/// each pierce of the first operand whose nearest pierce of the second is
3642/// mutually nearest, farther apart than the assembler weld and within
3643/// `4 tol / |tan·n|` (capped at 1e-3), the segment between them is imprinted.
3644#[allow(clippy::too_many_arguments)]
3645fn rim_bridge(
3646    builder: &mut ImprintBuilder<'_>,
3647    first: TaggedFace<'_>,
3648    second: TaggedFace<'_>,
3649    first_march: &NurbsSurface,
3650    second_march: &NurbsSurface,
3651    face_edge_lists: &HashMap<FaceKey, Vec<&EdgeRecord>>,
3652    options: &ImprintOptions,
3653    debug_pairs: bool,
3654) -> Result<(), KernelRefusal> {
3655    let mut pierces: [Vec<(Vec3, f64)>; 2] = [Vec::new(), Vec::new()];
3656    for (side, (face, other, other_march)) in [(first, second, second_march), (second, first, first_march)].into_iter().enumerate() {
3657        let edges = &face_edge_lists[&face.key()];
3658        for edge in edges {
3659            if edge.degenerate {
3660                continue;
3661            }
3662            // An edge lying ON the other carrier (the rims along the join the
3663            // pair is tangent across) reads a grazing hit per sample and
3664            // crosses nowhere: skip its solve, as the seed loop does.
3665            if super::support::curve_lies_on_surface(&edge_subcurve(edge)?, other_march, options.tolerance)? {
3666                continue;
3667            }
3668            for hit in intersect_curve_surface(&edge.curve, other_march, options.tolerance).or_refuse(KernelStage::Intersect, "intersect_curve_surface")? {
3669                if hit.t <= edge.t0 || hit.t >= edge.t1 {
3670                    continue;
3671                }
3672                let Ok(tangent) = edge.curve.derivatives(hit.t, 1).or_refuse(KernelStage::Intersect, "derivatives")?[1].normalized() else {
3673                    continue;
3674                };
3675                let Ok(normal) = other.chart().normal(hit.u, hit.v) else {
3676                    continue;
3677                };
3678                let tangency = tangent.dot(normal).abs();
3679                if !(tangency > 0.0 && tangency < 0.1) {
3680                    continue;
3681                }
3682                if !edge_crosses_carrier(edge, edges, hit.t, other_march, options.tolerance)? {
3683                    continue;
3684                }
3685                if !inside_both_trims(hit.point, first, second)? {
3686                    continue;
3687                }
3688                pierces[side].push((hit.point, tangency));
3689            }
3690        }
3691    }
3692    let nearest = |point: Vec3, among: &[(Vec3, f64)]| -> Option<(Vec3, f64)> {
3693        among.iter().copied().min_by(|a, b| a.0.sub(point).length().total_cmp(&b.0.sub(point).length()))
3694    };
3695    let weld = assembler_weld(options.tolerance);
3696    for &(from, from_tangency) in &pierces[0] {
3697        let Some((to, to_tangency)) = nearest(from, &pierces[1]) else {
3698            continue;
3699        };
3700        let mutual = nearest(to, &pierces[0]).is_some_and(|(back, _)| back.sub(from).length() <= options.tolerance);
3701        let gap = from.sub(to).length();
3702        let reach = (4.0 * options.tolerance / from_tangency.min(to_tangency)).min(1e-3);
3703        if debug_pairs {
3704            eprintln!(
3705                "pair {}x{}: rim bridge candidate ({:.7},{:.7},{:.7}) -> ({:.7},{:.7},{:.7}) gap {gap:.3e} reach {reach:.3e} mutual {mutual}",
3706                first.face.id, second.face.id, from.x, from.y, from.z, to.x, to.y, to.z
3707            );
3708        }
3709        if !mutual || gap <= weld || gap > reach {
3710            continue;
3711        }
3712        let segment = crate::make_line(from, to).or_refuse(KernelStage::Intersect, "make_line")?;
3713        builder.process_curve(segment, first, second, &[first, second], &[first, second], true, None)?;
3714    }
3715    Ok(())
3716}
3717
3718/// `BREP_PIERCE_NEAR_END_STEP` (default on, `=0` off): [`edge_crosses_carrier`] reads
3719/// a hit within its step of an open edge's end with the step shortened to it.
3720fn pierce_near_end_step_enabled() -> bool {
3721    crate::switch!("BREP_PIERCE_NEAR_END_STEP", true)
3722}
3723
3724/// Does `edge` CROSS `carrier` at parameter `t` — leave one side of the
3725/// surface for the other — rather than touch it or lie on it? Read from the
3726/// signed distance of the edge to the carrier a step either side of `t`
3727/// (one hundredth of the edge's live window): a crossing changes sign with
3728/// both readings clear of the tolerance; a lies-on edge reads zero on both
3729/// sides and a kiss reads one sign on both. A hit at the edge's end has no
3730/// far side and is not a crossing, UNLESS the face's boundary continues the
3731/// same curve there: `siblings` are the face's edges, and one that carries
3732/// this edge's curve bit for bit over the adjoining parameter window is the
3733/// other half of an edge a vertex was put on (`apply_edge_splits` keeps the
3734/// parent curve and narrows the window). The live window is then the whole
3735/// chain's, so the step and both readings are the ones the unsplit edge
3736/// gave. Fixture 31's union on its own split operands: pad edge 2 pierces
3737/// the model's blend at 0.0525 rad inside both trims, the imprint had put a
3738/// vertex at that very pierce, both halves then read "at the end", the
3739/// sub-gate march never started and the section it imprints on the unsplit
3740/// operands was missing (4 open edges). The signed distance is read against the
3741/// carrier itself (projection), never against the tangent plane at the hit,
3742/// where a curve lying ON a curved carrier would read a same-signed sagitta
3743/// on both sides that outweighs a grazing crossing's first-order departure.
3744/// A CLOSED edge (a cap's rim circle) has no end: a hit within a step of its
3745/// seam reads its far side across the seam (the G1 elbow's arm cap pierces
3746/// the lower torus half at t = 0.0037 of its rim circle).
3747fn edge_crosses_carrier(
3748    edge: &EdgeRecord,
3749    siblings: &[&EdgeRecord],
3750    t: f64,
3751    carrier: &NurbsSurface,
3752    tolerance: f64,
3753) -> Result<bool, KernelRefusal> {
3754    if !(edge.t1 - edge.t0 > 0.0) {
3755        return Ok(false);
3756    }
3757    let (t0, t1) = same_curve_chain_window(edge, siblings);
3758    let window = t1 - t0;
3759    let mut delta = window * 1e-2;
3760    // A hit inside the step of an open edge's end is read with the step
3761    // halved to the end (`BREP_PIERCE_NEAR_END_STEP`): the readings must still
3762    // clear the band either side, so a hit at the end vertex itself is no
3763    // crossing, while one a short real distance in from it is.
3764    if pierce_near_end_step_enabled() && t > t0 && t < t1 {
3765        let (start, end) = (
3766            edge.curve.evaluate(t0).or_refuse(KernelStage::Intersect, "evaluate")?,
3767            edge.curve.evaluate(t1).or_refuse(KernelStage::Intersect, "evaluate")?,
3768        );
3769        if start.sub(end).length() > tolerance {
3770            delta = delta.min(0.5 * (t - t0)).min(0.5 * (t1 - t));
3771        }
3772    }
3773    let (mut before, mut after) = (t - delta, t + delta);
3774    if before < t0 || after > t1 {
3775        let start = edge.curve.evaluate(t0).or_refuse(KernelStage::Intersect, "evaluate")?;
3776        let end = edge.curve.evaluate(t1).or_refuse(KernelStage::Intersect, "evaluate")?;
3777        if start.sub(end).length() > tolerance {
3778            return Ok(false);
3779        }
3780        if before < t0 {
3781            before += window;
3782        }
3783        if after > t1 {
3784            after -= window;
3785        }
3786    }
3787    let mut readings = [0.0f64; 2];
3788    for (slot, parameter) in [before, after].into_iter().enumerate() {
3789        let point = edge.curve.evaluate(parameter).or_refuse(KernelStage::Intersect, "evaluate")?;
3790        let projection = project_point_to_surface(carrier, point).or_refuse(KernelStage::Intersect, "project_point_to_surface")?;
3791        let normal = match carrier.normal(projection.u, projection.v) {
3792            Ok(normal) => normal,
3793            Err(_) => return Ok(false),
3794        };
3795        readings[slot] = point.sub(projection.point).dot(normal);
3796    }
3797    let clear = tolerance * 10.0;
3798    Ok(readings[0] * readings[1] < 0.0 && readings[0].abs() > clear && readings[1].abs() > clear)
3799}
3800
3801/// The parameter window of the chain of `siblings` that continue `edge`'s own
3802/// curve: edges with a bit-identical curve whose windows adjoin end to start.
3803/// `edge`'s own window when nothing continues it.
3804fn same_curve_chain_window(edge: &EdgeRecord, siblings: &[&EdgeRecord]) -> (f64, f64) {
3805    let same_curve = |other: &EdgeRecord| other.id != edge.id && !other.degenerate && same_curve_bits(&other.curve, &edge.curve);
3806    let halves: Vec<&&EdgeRecord> = siblings.iter().filter(|other| same_curve(other)).collect();
3807    let (mut t0, mut t1) = (edge.t0, edge.t1);
3808    for _ in 0..halves.len() {
3809        let mut grew = false;
3810        for other in &halves {
3811            if other.t1 == t0 && other.t0 < t0 {
3812                t0 = other.t0;
3813                grew = true;
3814            } else if other.t0 == t1 && other.t1 > t1 {
3815                t1 = other.t1;
3816                grew = true;
3817            }
3818        }
3819        if !grew {
3820            break;
3821        }
3822    }
3823    (t0, t1)
3824}
3825
3826/// `BREP_IMPRINT_LIES_ON_SEED_SKIP=0` runs the seed solve on an edge that lies
3827/// on the other carrier as before (see the seed loop); unset or anything else
3828/// skips it. Read once.
3829fn lies_on_seed_skip_enabled() -> bool {
3830    switch!("BREP_IMPRINT_LIES_ON_SEED_SKIP", true)
3831}
3832
3833/// TANGENT-RIM LANDING (hosted report 2026-10-17, "boolean fails": a box
3834/// with a bore, its top face revolved 25° about a top edge and subtracted).
3835///
3836/// The revolve turns the profile's hole into a torus whose start rim IS the
3837/// bore's top rim, so the bore cylinder and the torus are tangent along that
3838/// whole circle — a shared TRIM EDGE of both faces, not an interior contact —
3839/// and inside the trims they cross along two transverse branches that leave
3840/// the rim at the two points where the torus's revolution-direction curvature
3841/// vanishes against the cylinder's. The classifier admits those as isolated
3842/// nodes (`tangent_contact.rs`: a third-order cusp reads as a saddle at every
3843/// stopping rule) and the branch is marched — but the marcher's step direction
3844/// `n_a × n_b` collapses as it nears the node, so the trace STALLS a few 1e-5
3845/// short of the rim instead of running past the trim with its usual slack.
3846/// Measured: the run ends 6.95e-5 and 1.17e-4 below y = 20, which on the
3847/// cylinder's 30-tall chart is 2.3e-6 and 3.9e-6 — just over the arrangement's
3848/// 1.4e-6 band — so the cut never reaches the boundary, the cylinder face is
3849/// not split, and six edges stand one-use (the torus faces, whose pcurve is
3850/// clamped at the rim's domain wall, DID split there, which is the asymmetry
3851/// the one-use count reads). The exact `A − B` is a manifold solid (two
3852/// slivers of box material inside the torus tube pinching to a zero-dihedral
3853/// edge along the rim), so the refusal was wrong, not the model.
3854///
3855/// A transverse section cannot end strictly inside both trims; a run end that
3856/// stops within the on-boundary clearance (`polish_endpoint`'s band) of a trim
3857/// edge which lies on BOTH carriers at the foot of that stop has merely been
3858/// truncated, and the foot — on the edge, hence on both carriers exactly — is
3859/// where the exact section continues to. Land the end there and split the
3860/// edge at it, so the ordinary machinery (pcurve projection, the arrangement's
3861/// boundary split, the assembler's vertex weld) takes the junction from here.
3862/// Reach: pairs carrying an admitted tangent node (the only place the march
3863/// stalls short — elsewhere it overshoots the trim), a foot within
3864/// `1e-2·(1 + |foot|)` of that node, and an end not already on the edge. The
3865/// moved sample is the run's own last station, so the section polyline keeps
3866/// every marched point and the landing segment is at most the clearance long.
3867/// Returns the splits to register, one per edge sharing the landing point:
3868/// `(operand, edge id, parameter, from, to)`.
3869///
3870/// Without an admitted node (`node` is `None`: the pair was marched from
3871/// sub-gate pierces, or its branch simply ran into a tangency — the −10°
3872/// sibling of the revolve-into-bore report, a near-tangent pair with no node
3873/// admitted whose ordinary march stalled 4e-5 and 2.4e-4 short of its rim),
3874/// the certificate is the run end itself: it must sit where the carriers are
3875/// TANGENT (`|n_a × n_b|` under the seed gate), which is the only place a
3876/// march stalls short. With or without a node the reach is `1e-2 (1 +
3877/// |point|)`, and a gap beyond the plain clearance is earned sample by
3878/// sample: the straight landing segment must stay within the on-boundary
3879/// clearance of BOTH carriers at every sample — a section through a tangency
3880/// band is within tolerance of both carriers all the way to the rim, so a
3881/// segment that leaves either is not the missing stretch (the −20° sibling's
3882/// 7x6 end stops 3e-4 short, over the plain clearance of 2.1e-4). A gap
3883/// within the plain clearance lands exactly as before.
3884fn land_run_ends_on_tangent_rim(
3885    run: &mut [Vec3],
3886    node: Option<Vec3>,
3887    first: TaggedFace<'_>,
3888    second: TaggedFace<'_>,
3889    face_edge_lists: &HashMap<FaceKey, Vec<&EdgeRecord>>,
3890    tolerance: f64,
3891) -> Result<Vec<(u8, u64, f64, Vec3, Vec3)>, KernelRefusal> {
3892    let mut landings = Vec::new();
3893    if run.len() < 2 || std::env::var("BREP_TANGENT_RIM_LANDING").as_deref() == Ok("0") {
3894        return Ok(landings);
3895    }
3896    for index in [0, run.len() - 1] {
3897        let point = run[index];
3898        let clearance = (tolerance * 100.0).max(1e-6) * (1.0 + point.length());
3899        // No node: the end must stand in the tangency band, and the reach
3900        // beyond the plain clearance is earned sample by sample below.
3901        let stalled = match node {
3902            Some(_) => true,
3903            None => pair_normals_parallel_at(first, second, point)?,
3904        };
3905        if !stalled {
3906            continue;
3907        }
3908        let reach = 1e-2 * (1.0 + point.length());
3909        // Every qualifying foot over both faces' trim edges; the nearest is
3910        // where the end lands, and every edge whose foot coincides with it
3911        // (the two operands' copies of the shared rim) is split there, so
3912        // neither side depends on its pcurve happening to clamp at a domain
3913        // wall for its vertex.
3914        let mut feet: Vec<(f64, u8, u64, f64, Vec3)> = Vec::new();
3915        for face in [first, second] {
3916            let Some(edges) = face_edge_lists.get(&face.key()) else {
3917                continue;
3918            };
3919            for edge in edges {
3920                if edge.degenerate {
3921                    continue;
3922                }
3923                let projection = project_point_to_curve(&edge.curve, point)
3924                    .or_refuse(KernelStage::Intersect, "project_point_to_curve")?;
3925                let parameter = projection.u.clamp(edge.t0.min(edge.t1), edge.t0.max(edge.t1));
3926                let foot = edge.curve.evaluate(parameter).or_refuse(KernelStage::Intersect, "evaluate")?;
3927                let gap = foot.sub(point).length();
3928                if gap <= tolerance || gap > reach {
3929                    continue;
3930                }
3931                if let Some(node) = node {
3932                    if foot.sub(node).length() > 1e-2 * (1.0 + foot.length()) {
3933                        continue;
3934                    }
3935                }
3936                if gap > clearance
3937                    && !landing_segment_within(&first.face.surface, &second.face.surface, point, foot, clearance)
3938                {
3939                    continue;
3940                }
3941                // The edge must ride BOTH carriers at the foot: that is what
3942                // makes the foot a point of the section.
3943                let on_both = [first, second].iter().all(|face| {
3944                    project_point_to_surface(&face.face.surface, foot)
3945                        .map(|projection| projection.distance <= clearance)
3946                        .unwrap_or(false)
3947                });
3948                if !on_both {
3949                    continue;
3950                }
3951                feet.push((gap, face.operand, edge.id, parameter, foot));
3952            }
3953        }
3954        let Some(&(_, _, _, _, landing)) = feet.iter().min_by(|a, b| a.0.total_cmp(&b.0)) else {
3955            continue;
3956        };
3957        for (_, operand, edge_id, parameter, foot) in feet {
3958            if foot.sub(landing).length() <= tolerance * 10.0 {
3959                landings.push((operand, edge_id, parameter, point, landing));
3960            }
3961        }
3962        run[index] = landing;
3963    }
3964    Ok(landings)
3965}
3966/// TANGENT-NODE LANDING (hosted report 2026-11-01, "Boolean fails": a NURBS
3967/// Solid BOX cage, 10³ with 8 segments and 3 rings, unioned with a radius-5
3968/// cylinder standing on `y = 0`).
3969///
3970/// Three collinear cage points per side make the body flat to second order at
3971/// each side midpoint, and the cylinder's bottom rim passes through all four:
3972/// the two carriers touch at four isolated higher-order NODES that lie ON a
3973/// trim edge. Two section branches leave each node, mutually tangent there
3974/// (`z = ±c·y^{3/2}` on the wall). The march cannot place a station near such
3975/// a node: across the contact the carriers separate only as `δ² κ / 2`, so at
3976/// the model tolerance a station is uncertain by `√(2·tol/κ)` along the rim
3977/// (`1e-3` here). Measured: the four arcs ended ON the rim but 1.4e-5..2e-4
3978/// along it from their nodes, so each node's two arrivals split the rim twice
3979/// and left `On` slivers between, and the arcs into the node on the cylinder's
3980/// seam wobbled ACROSS the seam at `y ≈ 1.3e-3` (the true branch touches the
3981/// seam only at the node), leaving seam-hugging slivers. Six open corners and
3982/// a torn shell; [`land_run_ends_on_tangent_rim`] does not reach it because
3983/// those ends are already on the edge — they stopped at the wrong place ALONG
3984/// it, not short of it.
3985///
3986/// So: a run end where the carriers are tangent is refined onto its contact
3987/// (`classify_tangent_contact`); when that contact is an isolated node within
3988/// the landing reach that lies on a trim edge of either face, the stations
3989/// inside the node's ambiguity radius `3·√(2·tol/κ)` are dropped — they carry
3990/// no position the march could resolve — and the end is the node itself,
3991/// provided the closing chord stays on both carriers
3992/// ([`landing_segment_within`]). Every edge through the node is split exactly
3993/// there, so both branches arriving at a node share one vertex. Returns the
3994/// splits as [`land_run_ends_on_tangent_rim`] does.
3995fn land_run_ends_on_tangent_node(
3996    run: &mut Vec<Vec3>,
3997    first: TaggedFace<'_>,
3998    second: TaggedFace<'_>,
3999    face_edge_lists: &HashMap<FaceKey, Vec<&EdgeRecord>>,
4000    tolerance: f64,
4001) -> Result<Vec<(u8, u64, f64, Vec3, Vec3)>, KernelRefusal> {
4002    let mut landings = Vec::new();
4003    if run.len() < 2 || std::env::var("BREP_TANGENT_NODE_LANDING").as_deref() == Ok("0") {
4004        return Ok(landings);
4005    }
4006    for at_end in [false, true] {
4007        let end = if at_end { run[run.len() - 1] } else { run[0] };
4008        if !pair_normals_parallel_at(first, second, end)? {
4009            continue;
4010        }
4011        let reach = 1e-2 * (1.0 + end.length());
4012        let Some(contact) =
4013            classify_tangent_contact(&first.face.surface, &second.face.surface, end, tolerance)?
4014        else {
4015            continue;
4016        };
4017        let node = contact.point;
4018        if !contact.is_isolated_node() || node.sub(end).length() > reach || contact.curvature_scale <= 0.0 {
4019            continue;
4020        }
4021        let clearance = (tolerance * 100.0).max(1e-6) * (1.0 + node.length());
4022        // Every trim edge of either face the node lies on.
4023        let mut splits: Vec<(u8, u64, f64)> = Vec::new();
4024        for face in [first, second] {
4025            let Some(edges) = face_edge_lists.get(&face.key()) else {
4026                continue;
4027            };
4028            for edge in edges {
4029                if edge.degenerate {
4030                    continue;
4031                }
4032                let projection = project_point_to_curve(&edge.curve, node)
4033                    .or_refuse(KernelStage::Intersect, "project_point_to_curve")?;
4034                let parameter = projection.u.clamp(edge.t0.min(edge.t1), edge.t0.max(edge.t1));
4035                let foot = edge.curve.evaluate(parameter).or_refuse(KernelStage::Intersect, "evaluate")?;
4036                if foot.sub(node).length() <= tolerance * 10.0
4037                    && !splits.iter().any(|&(operand, id, _)| operand == face.operand && id == edge.id)
4038                {
4039                    splits.push((face.operand, edge.id, parameter));
4040                }
4041            }
4042        }
4043        if splits.is_empty() {
4044            continue;
4045        }
4046        // The ambiguity radius: the stations inside it are noise along the
4047        // contact and are dropped outright. Beyond it, keep dropping while
4048        // the closing chord to the node still rides both carriers to ten
4049        // times the tolerance: near the node the branch is TANGENT to the
4050        // contact direction (on the seam node, to the seam itself), so its
4051        // true offset from that direction grows only as `r^{3/2}` and a
4052        // station must be far enough out for that offset to dominate the
4053        // corrector's noise — or the fitted piece wobbles across the seam.
4054        let ambiguity = 3.0 * (2.0 * tolerance / contact.curvature_scale).sqrt();
4055        let tight = tolerance * 10.0;
4056        let mut kept: Vec<Vec3> = if at_end { run.clone() } else { run.iter().rev().copied().collect() };
4057        while kept.len() > 1 && kept[kept.len() - 1].sub(node).length() <= ambiguity {
4058            kept.pop();
4059        }
4060        let last = kept[kept.len() - 1];
4061        if last.sub(node).length() > reach
4062            || !landing_segment_within(&first.face.surface, &second.face.surface, last, node, clearance)
4063        {
4064            continue;
4065        }
4066        while kept.len() > 2 {
4067            let further = kept[kept.len() - 2];
4068            if further.sub(node).length() > reach
4069                || !landing_segment_within(&first.face.surface, &second.face.surface, further, node, tight)
4070            {
4071                break;
4072            }
4073            kept.pop();
4074        }
4075        kept.push(node);
4076        if !at_end {
4077            kept.reverse();
4078        }
4079        *run = kept;
4080        for (operand, edge_id, parameter) in splits {
4081            landings.push((operand, edge_id, parameter, end, node));
4082        }
4083    }
4084    Ok(landings)
4085}
4086
4087/// The widened landing's certificate: is the straight segment from the
4088/// stalled run end `from` to the foot `to` within `clearance` of BOTH
4089/// carriers at every interior sample?
4090///
4091/// Why this is a construction guarantee and not a reading: the foot is on a
4092/// trim edge that rides both carriers (checked by the caller), so it is a
4093/// point of the carriers' intersection set to within the clearance. The run
4094/// end is a marched station, on both carriers to the corrector's residual.
4095/// A segment whose every sample is within the clearance of both carriers is
4096/// a chord of the band where the two carriers are within tolerance of each
4097/// other — exactly the set a section through a tangency is confined to —
4098/// and the section polyline's last chord is held to the same deviation every
4099/// marched chord is. A segment that leaves either carrier mid-way (a chord
4100/// across a curved rim: its sagitta clears the clearance by orders) is NOT
4101/// the missing stretch, whatever its ends read, and is refused here.
4102fn landing_segment_within(
4103    first: &NurbsSurface,
4104    second: &NurbsSurface,
4105    from: Vec3,
4106    to: Vec3,
4107    clearance: f64,
4108) -> bool {
4109    const SAMPLES: usize = 8;
4110    (1..SAMPLES).all(|k| {
4111        let sample = from.add(to.sub(from).scale(k as f64 / SAMPLES as f64));
4112        [first, second].iter().all(|surface| {
4113            project_point_to_surface(surface, sample)
4114                .map(|projection| projection.distance <= clearance)
4115                .unwrap_or(false)
4116        })
4117    })
4118}
4119
4120/// Are the two carriers TANGENT (normals parallel) where they both pass through
4121/// `point`?
4122///
4123/// The test the tangential-only refusal above needs: a point on the marched
4124/// intersection is a TANGENT NODE when the two surface normals there are
4125/// parallel. The threshold is the transversality bound the supplemental
4126/// detector already accepts seeds by (`TRANSVERSE_SEED_CROSS`), not the far
4127/// tighter pair-classifier bound — a node the march merely passes CLOSE to
4128/// still poisons the assembly, so this errs toward calling a pair singular.
4129/// The tangent-curve lane's recognition of one pair: find the pair's
4130/// tangential contact without a witness, keep only an EXTENDED one (a node or
4131/// a point contact is the existing paths' business), and with one planar
4132/// carrier march it along the null direction of `II_a − II_b` and clip the
4133/// curve to both trims. `None` when there is no extended contact, or its trace
4134/// has no run inside both trims (a contact on the carriers' extensions
4135/// imprints nothing, exactly as today).
4136///
4137/// The section is RECORDED, not imprinted: a tangent edge whose two sides
4138/// both survive is a four-coedge incidence the assembler cannot represent
4139/// (the pinch gate in `csg/boolean/mod.rs` names the subtract case), and a
4140/// tangent edge only one side of which survives dissolves into its face.
4141/// What the record buys is the boolean's attribution: a refusal whose faces
4142/// the contact involves names the contact instead of the arrangement's own
4143/// symptom. The involved faces are the two carriers' and every face sharing
4144/// an edge a run end lies on (`TangentSectionRecord::faces`).
4145#[allow(clippy::too_many_arguments)]
4146fn tangent_curve_section(
4147    first: TaggedFace<'_>,
4148    second: TaggedFace<'_>,
4149    options: &ImprintOptions,
4150    first_faces: &[TaggedFace<'_>],
4151    second_faces: &[TaggedFace<'_>],
4152    face_edge_lists: &HashMap<FaceKey, Vec<&EdgeRecord>>,
4153    debug_pairs: bool,
4154) -> Result<Option<(TangentSectionRecord, Vec<Vec3>)>, KernelRefusal> {
4155    let _clock = ImprintSubphaseClock::new("tangent_section");
4156    let Some(contact) =
4157        crate::find_tangent_contact(&first.face.surface, &second.face.surface, options.tolerance)
4158            .or_refuse(KernelStage::Intersect, "find_tangent_contact")?
4159    else {
4160        return Ok(None);
4161    };
4162    if debug_pairs {
4163        eprintln!(
4164            "pair {}x{}: tangent-curve lane contact {:?}",
4165            first.face.id, second.face.id, contact
4166        );
4167    }
4168    if !contact.is_extended() {
4169        return Ok(None);
4170    }
4171    let is_plane = |face: TaggedFace<'_>| {
4172        matches!(face.face.surface.analytic(), Some(crate::AnalyticSurface::Plane { .. }))
4173    };
4174    let planar = is_plane(first) || is_plane(second);
4175    if !planar {
4176        // The curved/curved branch: recognised and named, not traced.
4177        return Ok(Some((
4178            TangentSectionRecord {
4179                first: first.key(),
4180                second: second.key(),
4181                start: contact.point,
4182                end: contact.point,
4183                length: 0.0,
4184                closed: false,
4185                stations: 0,
4186                planar: false,
4187                faces: vec![first.key(), second.key()],
4188                piece_ids: Vec::new(),
4189                grazing: Vec::new(),
4190            },
4191            Vec::new(),
4192        )));
4193    }
4194    let Some(curve) = crate::trace_tangent_curve(
4195        &first.face.surface,
4196        &second.face.surface,
4197        &contact,
4198        &SurfaceIntersectionOptions {
4199            tolerance: options.tolerance,
4200            maximum_step: options.maximum_ssi_step,
4201            ..Default::default()
4202        },
4203    )
4204    .or_refuse(KernelStage::Intersect, "trace_tangent_curve")?
4205    else {
4206        return Ok(None);
4207    };
4208    let mut longest: Option<Vec<Vec3>> = None;
4209    let mut longest_length = 0.0f64;
4210    for run in clip_branch_to_trims(&curve.points, first, second)? {
4211        if run.len() < 2 {
4212            continue;
4213        }
4214        let length: f64 = run.windows(2).map(|pair| pair[1].sub(pair[0]).length()).sum();
4215        if length > longest_length {
4216            longest_length = length;
4217            longest = Some(run);
4218        }
4219    }
4220    let Some(run) = longest else {
4221        return Ok(None);
4222    };
4223    if longest_length <= options.tolerance * 100.0 {
4224        return Ok(None);
4225    }
4226    if debug_pairs {
4227        eprintln!(
4228            "pair {}x{}: tangent-curve lane traced {} stations, run of {} inside both trims, length {:.6}, closed {}",
4229            first.face.id, second.face.id, curve.points.len(), run.len(), longest_length, curve.closed
4230        );
4231    }
4232    let closed = curve.closed && run.len() == curve.points.len();
4233    // The faces the contact involves: the carriers' own, and across every
4234    // edge of theirs that a run end lies on, the faces sharing that edge.
4235    let mut faces = vec![first.key(), second.key()];
4236    if !closed {
4237        let band = options.tolerance * 100.0;
4238        for end in [run[0], run[run.len() - 1]] {
4239            for face in [first, second] {
4240                let Some(edges) = face_edge_lists.get(&face.key()) else {
4241                    continue;
4242                };
4243                for edge in edges {
4244                    if edge.degenerate {
4245                        continue;
4246                    }
4247                    let Ok(projection) = project_point_to_curve(&edge.curve, end) else {
4248                        continue;
4249                    };
4250                    if projection.distance > band {
4251                        continue;
4252                    }
4253                    let siblings = if face.operand == first.operand { first_faces } else { second_faces };
4254                    for sibling in siblings {
4255                        let shares = sibling
4256                            .face
4257                            .loops
4258                            .iter()
4259                            .flat_map(|loop_record| &loop_record.coedges)
4260                            .any(|coedge| coedge.edge_id == edge.id);
4261                        if shares && !faces.contains(&sibling.key()) {
4262                            faces.push(sibling.key());
4263                        }
4264                    }
4265                }
4266            }
4267        }
4268    }
4269    if debug_pairs {
4270        eprintln!(
4271            "pair {}x{}: tangent-curve lane involves faces {:?}",
4272            first.face.id, second.face.id, faces
4273        );
4274    }
4275    Ok(Some((
4276        TangentSectionRecord {
4277            first: first.key(),
4278            second: second.key(),
4279            start: run[0],
4280            end: run[run.len() - 1],
4281            length: longest_length,
4282            closed,
4283            stations: run.len(),
4284            planar: true,
4285            faces,
4286            piece_ids: Vec::new(),
4287            grazing: Vec::new(),
4288        },
4289        run,
4290    )))
4291}
4292
4293/// Imprint a traced tangent run ([`ImprintOptions::tangent_curve_imprint`]):
4294/// the run's stations become a section curve — the exact line through its
4295/// ends when they are collinear (a plane's contact with a cylinder or cone is
4296/// a generatrix), the marched lane's polyline fit otherwise (a torus parallel)
4297/// — and `process_curve` mints it on both carriers exactly as it mints a
4298/// transverse section: pieces with pcurves on each face, the operand edges the
4299/// ends lie on split there. Returns the ids of the pieces minted, in order.
4300///
4301/// Only a run that SPLITS both faces is minted: a closed run, or one each of
4302/// whose ends lies, on each carrier, on that face's trim or on a section
4303/// piece already minted on it (the through-bore's contact ends on the wall's
4304/// top and bottom edges and, on the bore, on the circles the box's top and
4305/// bottom cut there). A run with an end inside a face — the blind pocket's
4306/// contact ends on the bore's cap rings but inside the wall, where both of
4307/// its sides are one face — would be a slit, and a slit is not a boundary:
4308/// measured with the slit minted, the wall's four edges came out one-use and
4309/// the pocket refused `NonIntegralGenus`. Such a contact stays recorded only,
4310/// as before.
4311#[allow(clippy::too_many_arguments)]
4312fn imprint_tangent_run(
4313    builder: &mut ImprintBuilder<'_>,
4314    run: &[Vec3],
4315    closed: bool,
4316    first: TaggedFace<'_>,
4317    second: TaggedFace<'_>,
4318    face_edge_lists: &HashMap<FaceKey, Vec<&EdgeRecord>>,
4319    options: &ImprintOptions,
4320    debug: bool,
4321) -> Result<Vec<u64>, KernelRefusal> {
4322    if run.len() < 2 {
4323        return Ok(Vec::new());
4324    }
4325    if !closed {
4326        let band = options.tolerance * 100.0;
4327        let within = |curve: &NurbsCurve, t0: f64, t1: f64, point: Vec3| -> bool {
4328            project_point_to_curve(curve, point)
4329                .map(|projection| {
4330                    projection.distance <= band
4331                        && projection.u >= t0.min(t1) - 1e-9
4332                        && projection.u <= t0.max(t1) + 1e-9
4333                })
4334                .unwrap_or(false)
4335        };
4336        let on_boundary = |face: TaggedFace<'_>, point: Vec3| -> bool {
4337            let on_trim = face_edge_lists
4338                .get(&face.key())
4339                .map(|edges| {
4340                    edges
4341                        .iter()
4342                        .any(|edge| !edge.degenerate && within(&edge.curve, edge.t0, edge.t1, point))
4343                })
4344                .unwrap_or(false);
4345            on_trim
4346                || builder
4347                    .pieces
4348                    .iter()
4349                    .any(|piece| piece.support_faces.contains(&face.key()) && within(&piece.curve, piece.t0, piece.t1, point))
4350        };
4351        let ends = [run[0], run[run.len() - 1]];
4352        for face in [first, second] {
4353            if !ends.iter().all(|end| on_boundary(face, *end)) {
4354                if debug {
4355                    eprintln!(
4356                        "pair {}x{}: tangent-curve lane run not imprinted: an end lies inside face {}:{}'s trim (a slit)",
4357                        first.face.id, second.face.id, face.operand, face.face.id
4358                    );
4359                }
4360                return Ok(Vec::new());
4361            }
4362        }
4363    }
4364    let start = run[0];
4365    let end = run[run.len() - 1];
4366    let chord = end.sub(start);
4367    let chord_length = chord.length();
4368    let fit_tolerance = options.tolerance.max(1e-7);
4369    let collinear = chord_length > fit_tolerance && {
4370        let direction = chord.scale(1.0 / chord_length);
4371        run.iter().all(|station| {
4372            let offset = station.sub(start);
4373            offset.sub(direction.scale(offset.dot(direction))).length() <= 10.0 * fit_tolerance
4374        })
4375    };
4376    let curve = if collinear {
4377        crate::make_line(start, end).or_refuse(KernelStage::Intersect, "make_line")?
4378    } else {
4379        fit_polyline_of_degree(
4380            run,
4381            fit_tolerance,
4382            run.len().min(MAX_FIT_STATIONS),
4383            options.local_fit,
4384            section_fit_degree(),
4385        )
4386        .or_refuse(KernelStage::Intersect, "fit_polyline_of_degree")?
4387        .curve
4388    };
4389    let before = builder.pieces.len();
4390    builder.process_curve(curve, first, second, &[first, second], &[first, second], true, None)?;
4391    let ids: Vec<u64> = builder.pieces[before..].iter().map(|piece| piece.id).collect();
4392    if debug {
4393        eprintln!(
4394            "pair {}x{}: tangent-curve lane imprinted the run as {} ({} piece(s) {:?})",
4395            first.face.id,
4396            second.face.id,
4397            if collinear { "a line" } else { "a fitted section" },
4398            ids.len(),
4399            ids
4400        );
4401    }
4402    Ok(ids)
4403}
4404
4405/// Split every piece an imprinted tangent section ENDS ON, at that end
4406/// (`ImprintOptions::tangent_curve_imprint`). A tangent run is clipped to both
4407/// trims, so its ends lie on operand edges — split by `process_curve` — or on
4408/// the trim of the OTHER carrier's neighbours, where they also lie on the
4409/// sections those neighbours minted on this carrier: the through-bore's
4410/// contact line ends on the circles the box's top and bottom cut on the bore,
4411/// at a point no edge pierce put a vertex on (the box edge grazes the bore
4412/// there, and a grazing pierce is deliberately not a junction). Without the
4413/// vertex, the bore's arrangement would split the circle where the line
4414/// meets it while the cap's arrangement keeps the circle whole — one closed
4415/// edge against two arcs, one-use at assembly. The piece is split here, at
4416/// the imprint, so every face it is minted on sees the vertex: the halves
4417/// take the tangent end's vertex id, the pcurves are split with the curve
4418/// where they were emitted on its knots and rebuilt on the face's chart
4419/// otherwise, and the piece's face lists and lane sets follow the halves. A
4420/// piece that resolves to an operand edge (`shared_edge`) is left as it is:
4421/// that edge's own split is the exchange pass's.
4422fn split_pieces_at_tangent_ends(
4423    builder: &mut ImprintBuilder<'_>,
4424    sections: &[TangentSectionRecord],
4425    first_faces: &[TaggedFace<'_>],
4426    second_faces: &[TaggedFace<'_>],
4427    options: &ImprintOptions,
4428    debug: bool,
4429) -> Result<(), KernelRefusal> {
4430    let tangent_ids: HashSet<u64> = sections.iter().flat_map(|section| section.piece_ids.iter().copied()).collect();
4431    if tangent_ids.is_empty() {
4432        return Ok(());
4433    }
4434    let overlap_limit = options.tolerance.max(1e-5);
4435    let vertex_points: HashMap<u64, Vec3> =
4436        builder.vertices.iter().map(|vertex| (vertex.id, vertex.point)).collect();
4437    // (end vertex, its point, the tangent piece's supports)
4438    let mut ends: Vec<(u64, Vec3, [FaceKey; 2])> = Vec::new();
4439    for piece in builder.pieces.iter().filter(|piece| tangent_ids.contains(&piece.id)) {
4440        for vertex_id in [piece.start_vertex_id, piece.end_vertex_id] {
4441            if let Some(point) = vertex_points.get(&vertex_id) {
4442                if !ends.iter().any(|(id, _, _)| *id == vertex_id) {
4443                    ends.push((vertex_id, *point, piece.support_faces));
4444                }
4445            }
4446        }
4447    }
4448    let face_of = |key: FaceKey| {
4449        first_faces
4450            .iter()
4451            .chain(second_faces)
4452            .copied()
4453            .find(|face| face.key() == key)
4454    };
4455    let mut index = 0;
4456    while index < builder.pieces.len() {
4457        let piece = &builder.pieces[index];
4458        if tangent_ids.contains(&piece.id) || piece.shared_edge.is_some() || !(piece.t1 > piece.t0) {
4459            index += 1;
4460            continue;
4461        }
4462        let mut split: Option<(u64, f64, Vec3)> = None;
4463        for (vertex_id, point, supports) in &ends {
4464            if *vertex_id == piece.start_vertex_id || *vertex_id == piece.end_vertex_id {
4465                continue;
4466            }
4467            if !supports.iter().any(|support| piece.support_faces.contains(support)) {
4468                continue;
4469            }
4470            let projection = project_point_to_curve(&piece.curve, *point)
4471                .or_refuse(KernelStage::Intersect, "project_point_to_curve")?;
4472            if projection.distance > overlap_limit {
4473                continue;
4474            }
4475            let span = piece.t1 - piece.t0;
4476            let margin = (span * KNOT_IDENTITY_TOL).max(2e-9);
4477            if projection.u <= piece.t0 + margin || projection.u >= piece.t1 - margin {
4478                continue;
4479            }
4480            // Interior in PARAMETER but at an END in space: a closed piece's
4481            // origin seen from the far side of its domain.
4482            if projection.point.sub(vertex_points[&piece.start_vertex_id]).length() <= overlap_limit
4483                || projection.point.sub(vertex_points[&piece.end_vertex_id]).length() <= overlap_limit
4484            {
4485                continue;
4486            }
4487            split = Some((*vertex_id, projection.u, *point));
4488            break;
4489        }
4490        let Some((vertex_id, parameter, point)) = split else {
4491            index += 1;
4492            continue;
4493        };
4494        let piece = builder.pieces.remove(index);
4495        let (left, right) = piece.curve.split(parameter).or_refuse(KernelStage::Intersect, "split")?;
4496        let [left_t0, _] = left.domain().or_refuse(KernelStage::Intersect, "domain")?;
4497        let [_, right_t1] = right.domain().or_refuse(KernelStage::Intersect, "domain")?;
4498        let start_point = vertex_points[&piece.start_vertex_id];
4499        let end_point = vertex_points[&piece.end_vertex_id];
4500        let left = snap_curve_ends(&left, start_point, point)?;
4501        let right = snap_curve_ends(&right, point, end_point)?;
4502        let left_id = builder.next_id;
4503        let right_id = builder.next_id + 1;
4504        builder.next_id += 2;
4505        let mut left_pcurves = Vec::with_capacity(piece.pcurves.len());
4506        let mut right_pcurves = Vec::with_capacity(piece.pcurves.len());
4507        for face_pcurve in &piece.pcurves {
4508            let key = FaceKey { operand: face_pcurve.operand, face_id: face_pcurve.face_id };
4509            let emitted = builder.emitted_pcurves.remove(&(piece.id, key));
4510            let halves = if emitted {
4511                match face_pcurve.pcurve.split(parameter) {
4512                    Ok((a, b)) => {
4513                        builder.emitted_pcurves.insert((left_id, key));
4514                        builder.emitted_pcurves.insert((right_id, key));
4515                        Some((a, b))
4516                    }
4517                    Err(_) => None,
4518                }
4519            } else {
4520                None
4521            };
4522            let (a, b) = match halves {
4523                Some(halves) => halves,
4524                None => {
4525                    let Some(face) = face_of(key) else {
4526                        return Err(KernelRefusal::internal(
4527                            KernelStage::Intersect,
4528                            "imprint.tangent_split",
4529                            format!("tangent-section split: piece {} has a pcurve on an unknown face {key:?}", piece.id),
4530                        ));
4531                    };
4532                    (
4533                        build_pcurve_on_surface_marched(face.chart(), &left)
4534                            .or_refuse(KernelStage::Intersect, "build_pcurve_on_surface_marched")?,
4535                        build_pcurve_on_surface_marched(face.chart(), &right)
4536                            .or_refuse(KernelStage::Intersect, "build_pcurve_on_surface_marched")?,
4537                    )
4538                }
4539            };
4540            left_pcurves.push(FacePcurve { operand: key.operand, face_id: key.face_id, pcurve: a });
4541            right_pcurves.push(FacePcurve { operand: key.operand, face_id: key.face_id, pcurve: b });
4542        }
4543        if builder.marched_pieces.remove(&piece.id) {
4544            builder.marched_pieces.insert(left_id);
4545            builder.marched_pieces.insert(right_id);
4546        }
4547        for ids in builder.by_face.values_mut() {
4548            if let Some(slot) = ids.iter().position(|id| *id == piece.id) {
4549                ids[slot] = left_id;
4550                ids.insert(slot + 1, right_id);
4551            }
4552        }
4553        if debug {
4554            eprintln!(
4555                "tangent-curve lane: piece {} split at vertex {} (t={parameter:.6}) into pieces {left_id} and {right_id}",
4556                piece.id, vertex_id
4557            );
4558        }
4559        builder.pieces.insert(
4560            index,
4561            ImprintPieceRecord {
4562                id: left_id,
4563                curve: left,
4564                t0: left_t0,
4565                t1: parameter,
4566                start_vertex_id: piece.start_vertex_id,
4567                end_vertex_id: vertex_id,
4568                pcurves: left_pcurves,
4569                support_faces: piece.support_faces,
4570                shared_edge: None,
4571            },
4572        );
4573        builder.pieces.insert(
4574            index + 1,
4575            ImprintPieceRecord {
4576                id: right_id,
4577                curve: right,
4578                t0: parameter,
4579                t1: right_t1,
4580                start_vertex_id: vertex_id,
4581                end_vertex_id: piece.end_vertex_id,
4582                pcurves: right_pcurves,
4583                support_faces: piece.support_faces,
4584                shared_edge: None,
4585            },
4586        );
4587        // Re-examine the halves: a run may end on the same piece twice.
4588    }
4589    Ok(())
4590}
4591
4592fn pair_normals_parallel_at(
4593    first: TaggedFace<'_>,
4594    second: TaggedFace<'_>,
4595    point: Vec3,
4596) -> Result<bool, KernelRefusal> {
4597    let mut normals = [Vec3::default(); 2];
4598    for (slot, face) in normals.iter_mut().zip([first, second]) {
4599        let projection = project_point_to_surface(&face.face.surface, point)
4600            .or_refuse(KernelStage::Intersect, "project_point_to_surface")?;
4601        let Ok(normal) = face.face.surface.normal(projection.u, projection.v) else {
4602            // A pole/singular parameter point cannot witness transversality;
4603            // treat it as tangential so the pair stays refused.
4604            return Ok(true);
4605        };
4606        *slot = normal;
4607    }
4608    Ok(normals[0].cross(normals[1]).length() <= crate::TRANSVERSE_SEED_CROSS)
4609}
4610
4611