Skip to main content

brep_kernel/offset/offset_shell/
pipeline.rs

1use crate::{KernelRefusal, KernelStage, OrRefuse};
2use super::*;
3
4/// Put every face on one normal convention (surface normal on the CCW
5/// parameter-winding side) and then restore outward normals. The offset shell's
6/// source and offset skins are assembled as independent components whose
7/// per-face `same_sense` can follow opposite conventions; `validate()` only
8/// checks coedge-direction coherence (the `forward` flags), so a joined,
9/// watertight, coedge-coherent manifold can still be normal-incoherent and
10/// report the wrong volume. Re-deriving `same_sense` from the loop winding makes
11/// the coedge-coherent manifold normal-coherent; the signed-volume flip then
12/// orients it outward. Only invoked after a non-coplanar rim weld, so the
13/// coplanar cylinder/prism shells keep their exact assembled orientation.
14fn coheres_face_normals(solid: &mut BrepSolid) -> Result<(), KernelRefusal> {
15    for face in solid.shells.iter_mut().flat_map(|shell| &mut shell.faces) {
16        face.same_sense = parameter_space_area(face).or_refuse(KernelStage::Sew, "parameter_space_area")? > 0.0;
17    }
18    // Outward is a PER-SHELL property: a through-hole shelled at both ends
19    // legitimately produces two disjoint closed components (the outer wall
20    // tube and the hole wall tube), and a single global signed-volume flip
21    // cannot orient both.
22    for shell_index in 0..solid.shells.len() {
23        let single = BrepSolid {
24            mass_properties_cache: Default::default(),
25            id: solid.id,
26            vertices: solid.vertices.clone(),
27            edges: solid.edges.clone(),
28            shells: vec![solid.shells[shell_index].clone()],
29            genus: 0,
30            kind: crate::BodyKind::Solid,
31        };
32        if crate::solid_signed_volume(&single).or_refuse(KernelStage::Sew, "solid_signed_volume")? < 0.0 {
33            flip_shell_faces(&mut solid.shells[shell_index])?;
34        }
35    }
36    Ok(())
37}
38
39/// Mint a vertex at every SELF-TOUCH of the source's faces before the shell
40/// reads their trims.
41///
42/// A face whose loops touch at an EDGE INTERIOR is a pinched region: the
43/// reported 2026-09-09 document's r = 6 through-hole kisses both r = 4 fillet
44/// setbacks on the top face, at (16, 20, 10) and (10, 20, 16), with no vertex
45/// there.  The fragment stage's 2D arrangement resolves such a pinch by
46/// carving the touched-off corner into its own region, whose loop walks the
47/// closed hole chain in a PARTIAL run — which `build_loop` can only assemble
48/// when the touch is a vertex of both touching edges, and otherwise refuses
49/// with "chain N fragmented into an incomplete run".
50///
51/// The boolean lane mints that vertex inside `build_imprints`
52/// (`imprint/self_touch.rs`).  Nothing minted it here: the shell fragments
53/// its SOURCE against an EMPTY imprint, and its offset carriers — whose trims
54/// are copied from the source faces — deliberately keep their boundaries
55/// un-split, so both arrived at the arrangement pinched.  Splitting the
56/// source once, before the carriers are built from it, fixes both: every
57/// carrier inherits the split trim by construction.
58///
59/// Returns `None` when no face self-touches, so every part that was never
60/// pinched keeps its exact previous path.  Escape hatch:
61/// `BREP_SELF_TOUCH_SPLIT=0`, the same one the imprint lane honours.
62fn split_self_touching_source(source: &BrepSolid) -> Result<Option<BrepSolid>, KernelRefusal> {
63    if std::env::var("BREP_SELF_TOUCH_SPLIT").as_deref() == Ok("0") {
64        return Ok(None);
65    }
66    // The same derivation `offset_shell_impl` uses for every other band, so
67    // the source scan and the carrier-pair scans agree on what "touching"
68    // means.
69    let scale = crate::solid_scale(source);
70    let tolerance = 1e-7f64.max(scale * 1e-9);
71    let edge_splits = crate::imprint::self_touch_edge_splits(source, SOURCE_OPERAND, tolerance, scale)?;
72    if edge_splits.is_empty() {
73        return Ok(None);
74    }
75    os_debug!(
76        "self-touch: source split on {} edge(s): {:?}",
77        edge_splits.len(),
78        edge_splits
79            .iter()
80            .map(|split| split.edge_id)
81            .collect::<Vec<_>>(),
82    );
83    let imprint = ImprintResultRecord {
84        edge_splits,
85        ..empty_imprint()
86    };
87    Ok(Some(apply_edge_splits(source, SOURCE_OPERAND, &imprint)?))
88}
89
90/// How far past the grown outline a planar opening wall that meets a RULED
91/// opening is padded, in units of the offset-skin band the wall selection reads
92/// (see the wall construction).
93///
94/// Measured on the torus wedge through the pipeline, grown by 0.05, 0.1, 0.5
95/// and 0.999 (band 2e-3): a clearance of 2 or 2.5 bands still shreds the cap
96/// into 22 to 36 faces with the area 5% to 11% high; from 4 bands on every
97/// member builds its 6 faces, and from 4 to 32 bands each member's volume moves
98/// by at most 1.2e-7. 16 sits four times above the first clean reading.
99const RULED_NEIGHBOUR_CLEARANCE_BANDS: f64 = 16.0;
100
101/// How far past its opening plane an inward carrier is grown, as a fraction of
102/// the shell distance (see the fall-short reach in the carrier loop).
103const REACH_CLEARANCE: f64 = 0.25;
104
105/// What the pipeline assembles.
106#[derive(Clone, Copy, Debug, Eq, PartialEq)]
107pub(super) enum Body {
108    /// A shell: the retained source faces, their offset skins and the walls
109    /// at the openings, bounding the material between source and offset.
110    Shell,
111    /// The offset body itself: the offset skins alone, closed by their
112    /// mutual sections; `opening_face_ids` are HELD faces, copied at
113    /// distance zero as walls, with no source face assembled and no skin
114    /// flipped. The whole-solid offset and the boolean fallback's offset
115    /// body are built this way.
116    Whole,
117}
118
119
120#[cfg(not(test))]
121fn forced_direct_refusal() -> Option<KernelRefusal> {
122    None
123}
124
125pub fn offset_shell(
126    source: &BrepSolid,
127    opening_face_ids: &[u64],
128    distance: f64,
129) -> Result<OffsetShellResultRecord, KernelRefusal> {
130    let direct = match forced_direct_refusal() {
131        Some(forced) => Err(forced),
132        None => offset_body(source, opening_face_ids, distance, Body::Shell, "offset_shell"),
133    };
134    match direct {
135        Ok(result) => Ok(result),
136        // The boolean lane answers the direct construction's own named
137        // refusals; when it refuses too, the direct refusal is the one
138        // reported, because it names the cause.
139        Err(direct) if super::solid::direct_refusal_takes_the_boolean_lane(&direct) => {
140            os_debug!("direct pipeline refused ({direct}); taking the boolean lane");
141            match super::solid::offset_shell_by_boolean(source, opening_face_ids, distance) {
142                Ok(result) => Ok(result),
143                Err(boolean) => {
144                    os_debug!("boolean lane refused too ({boolean})");
145                    Err(direct)
146                }
147            }
148        }
149        Err(direct) => Err(direct),
150    }
151}
152
153/// The pipeline's one timed entry: `offset_shell` and `offset_solid` both run
154/// through it, so the `timing.*` split and the acceptance step are the same.
155pub(super) fn offset_body(
156    source: &BrepSolid,
157    opening_face_ids: &[u64],
158    distance: f64,
159    body: Body,
160    entry: &str,
161) -> Result<OffsetShellResultRecord, KernelRefusal> {
162    profile::reset();
163    let started = web_time::Instant::now();
164    let result = offset_shell_any_lane(source, opening_face_ids, distance, body).and_then(|result| {
165        let mut clock = web_time::Instant::now();
166        let connected = outward_shell_is_connected(source, distance, &result);
167        profile::lap(&mut clock, profile::ACCEPTANCE);
168        connected.map(|()| result)
169    });
170    profile::add(profile::TOTAL, started.elapsed());
171    profile::report(entry);
172    result
173}
174
175/// Every shell of an OUTWARD result must bound volume. The shell is the grown
176/// body less the source with the openings held, so it can be disconnected
177/// (opening a cylinder's lateral face leaves its two grown caps as two
178/// slabs), but each of its shells encloses material. A shell that encloses
179/// none, a lone face that happened to close, is a fragment of an assembly that
180/// went wrong and still validated. Measured on 2026-09-26: a free-form D whose
181/// fitted opening wall sat within the fit tolerance of its carriers' sections
182/// returned its body plus 62 single-face shells of volume under 3e-24, each
183/// valid, with the right total volume. So this refuses by name for EVERY
184/// outward shell, not only for the lane that produced those.
185pub(super) fn outward_shell_is_connected(
186    source: &BrepSolid,
187    distance: f64,
188    result: &OffsetShellResultRecord,
189) -> Result<(), KernelRefusal> {
190    if distance >= 0.0 || result.solid.shells.len() <= 1 {
191        return Ok(());
192    }
193    let scale = crate::solid_scale(source).max(1.0);
194    let volumes = result
195        .solid
196        .shells
197        .iter()
198        .map(|shell| {
199            let mut one = result.solid.clone();
200            one.shells = vec![shell.clone()];
201            crate::solid_mass_properties(&one)
202                .map(|properties| properties.volume)
203                .or_refuse(KernelStage::Validate, "solid_mass_properties")
204        })
205        .collect::<Result<Vec<f64>, KernelRefusal>>()?;
206    let total = volumes.iter().map(|volume| volume.abs()).sum::<f64>();
207    let floor = (1e-9 * total).max(1e-12 * scale * scale * scale);
208    let empty = volumes.iter().filter(|volume| volume.abs() <= floor).count();
209    if empty == 0 {
210        return Ok(());
211    }
212    Err(refusals::empty_shell(result.solid.shells.len(), empty, floor).into())
213}
214
215fn offset_shell_any_lane(
216    source: &BrepSolid,
217    opening_face_ids: &[u64],
218    distance: f64,
219    body: Body,
220) -> Result<OffsetShellResultRecord, KernelRefusal> {
221    // Pinched source faces are un-modellable by the arrangement until the
222    // touch is a vertex; do it once here so BOTH `offset_shell_impl` attempts
223    // and every carrier built from the source see the same topology.
224    let prepared = split_self_touching_source(source)?;
225    let source = prepared.as_ref().unwrap_or(source);
226    // The revolved-wedge lane answers a SHELL question (the material between
227    // a revolve and its grown image); the offset body takes the pipeline.
228    if body == Body::Whole {
229        return imprint_attempts(source, opening_face_ids, distance, body);
230    }
231    // An outward shell of the one circular face of a partial revolve is planar
232    // in the meridian half-plane, fold band and all: build it there and revolve
233    // it once (`revolved_wedge.rs`). Anything else declines and takes the
234    // imprint pipeline, unchanged.
235    match revolved_wedge::recognize(source, opening_face_ids, distance) {
236        Ok(revolved_wedge::Recognition::Wedge(wedge)) => {
237            os_debug!("revolved wedge lane: {}", wedge.report());
238            return revolved_wedge::build(&wedge, source);
239        }
240        Ok(revolved_wedge::Recognition::Declined(reason)) => {
241            os_debug!("revolved wedge lane declined: {reason}");
242        }
243        // A source the lane cannot even read is not one it takes; the pipeline
244        // owns every refusal.
245        Err(error) => {
246            os_debug!("revolved wedge lane declined: could not read the source ({error})");
247        }
248    }
249    imprint_attempts(source, opening_face_ids, distance, body)
250}
251
252
253fn imprint_attempts(
254    source: &BrepSolid,
255    opening_face_ids: &[u64],
256    distance: f64,
257    body: Body,
258) -> Result<OffsetShellResultRecord, KernelRefusal> {
259    // First try with oblique hole-wall carriers extended past their opening
260    // planes (the lane that closes tilted/conical through-holes). If that
261    // extension fired but the arrangement could not assemble the harder
262    // configuration it produced (e.g. the extended bore genuinely intersects
263    // other offset walls), fall back to the un-extended pipeline so every
264    // previously-supported shape keeps its exact path and every refusal keeps
265    // the canonical honesty-gate message.
266    let mut extension_fired = false;
267    let mut reflex_rebuilds = 0usize;
268    let mut shadowed_points = Vec::new();
269    let mut omitted = HashSet::default();
270    let mut vacated_notes = Vec::new();
271    let result = match offset_shell_impl(
272        source,
273        opening_face_ids,
274        distance,
275        body,
276        true,
277        &mut extension_fired,
278        &mut reflex_rebuilds,
279        &HashSet::default(),
280        &mut shadowed_points,
281        &mut omitted,
282        &mut vacated_notes,
283    ) {
284        Ok(result) => {
285            // Attribution marker: which pipeline produced this result. A
286            // retry-produced Ok can silently mask a broken extension lane —
287            // always say which attempt won. The reflex-rebuild count rides
288            // along because that lane fires on BOTH attempts: "extension
289            // idle" alone would misread as "the plain pipeline did this".
290            os_debug!(
291                "offset_shell result: FIRST attempt (extension {}, reflex-rebuilt {})",
292                if extension_fired { "fired" } else { "idle" },
293                reflex_rebuilds,
294            );
295            Ok(result)
296        }
297        Err(error) if extension_fired => {
298            os_debug!("extended pipeline failed ({error}); retrying without carrier extension");
299            let mut unused = false;
300            let mut retry_reflex = 0usize;
301            shadowed_points.clear();
302            omitted.clear();
303            let retried = offset_shell_impl(
304                source,
305                opening_face_ids,
306                distance,
307                body,
308                false,
309                &mut unused,
310                &mut retry_reflex,
311                &HashSet::default(),
312                &mut shadowed_points,
313                &mut omitted,
314                &mut vacated_notes,
315            );
316            os_debug!(
317                "offset_shell result: RETRY without extension ({}, reflex-rebuilt {retry_reflex})",
318                if retried.is_ok() { "ok" } else { "err" },
319            );
320            retried
321        }
322        Err(error) => Err(error),
323    };
324    // A refusal from a shell whose selection saw two offsets CROSS inside
325    // material thinner than twice the distance says so first: a rib thinner
326    // than 2d shelled inward is that configuration, and the assembly's own
327    // message names only the symptom. A refusal that already names its cause
328    // keeps it. The crossing is looked for here, on the failure path only.
329    match result {
330        // A refusal that already names its CAUSE keeps its own sentence; one
331        // that names a symptom ("connector edge left its plane", an assembly
332        // message) is worth a cause in front of it. Reading the whole prefix as
333        // "anything this module wrote" was too wide: the twin bosses came out
334        // led by a notch sentence when their cause was the shadow cascade, and
335        // the partial cone lost its junction cause behind a connector's.
336        // Each cause is put IN FRONT of the symptom with `with_message`, so the
337        // symptom's class (an assembly's `NonIntegralGenus`, …) survives.
338        Err(error) if !refusal_names_its_cause(&error.message) => {
339            let crossing = name_offset_crossing(source, opening_face_ids, distance, &shadowed_points);
340            let junction = crossing
341                .is_none()
342                .then(|| name_retained_opening_junction(source, opening_face_ids, distance))
343                .flatten();
344            Err(cause_in_front(error, crossing, junction, vacated_notes.first()))
345        }
346        result => result,
347    }
348}
349
350/// The symptom `error` with the first named cause IN FRONT of it: an offset
351/// crossing, else a retained/opening junction, else a vacated rim's note.
352/// Each prefix is a `with_message`, so the symptom's CLASS (an assembly's
353/// `NonIntegralGenus`, …) survives the sentence put before it.
354pub(super) fn cause_in_front(
355    error: KernelRefusal,
356    crossing: Option<String>,
357    junction: Option<String>,
358    note: Option<&String>,
359) -> KernelRefusal {
360    if let Some(crossing) = crossing {
361        return error.with_message(|error| {
362            format!(
363                "offset_shell: {crossing}; a skin partly shadowed that way is not yet \
364                 assembled ({error})"
365            )
366        });
367    }
368    if let Some(junction) = junction {
369        return error.with_message(|error| format!("offset_shell: {junction} ({error})"));
370    }
371    // A rim the closure could not bridge, with what it measured, in front of
372    // whatever the assembly then said about the hole it left.
373    match note {
374        Some(note) => error.with_message(|error| {
375            format!(
376                "offset_shell: a rim vacated by an omitted support was left open — {note} \
377                 ({error})"
378            )
379        }),
380        None => error,
381    }
382}
383
384/// The refusals this module's own cause-naming lanes produce. Anything else is
385/// a symptom another stage reported, and takes a cause in front of it.
386fn refusal_names_its_cause(error: &str) -> bool {
387    [
388        " coincide near ",
389        "cannot tell whether",
390        "omitting the shadowed offsets of source faces",
391        "no retained face keeps any offset skin",
392        "is shadowed at every one of its",
393        "a rim vacated by an omitted support was left open",
394        "junction, so its offset ends inside the cavity",
395        "cross near",
396        // The opening-wall lane's own named refusals, so a cause of mine never
397        // arrives in front of one of theirs.
398        "folds where the carve",
399        "is curved and not a ruled surface",
400        "cannot be built",
401    ]
402    .iter()
403    .any(|name| error.contains(name))
404}
405
406fn offset_shell_impl(
407    source: &BrepSolid,
408    opening_face_ids: &[u64],
409    distance: f64,
410    body: Body,
411    extend_oblique_carriers: bool,
412    extension_fired: &mut bool,
413    reflex_rebuilds: &mut usize,
414    shadowed_supports: &HashSet<u64>,
415    shadowed_points: &mut Vec<(Vec3, u64)>,
416    omitted_supports: &mut HashSet<u64>,
417    vacated_notes: &mut Vec<String>,
418) -> Result<OffsetShellResultRecord, KernelRefusal> {
419    profile::attempt();
420    let mut clock = web_time::Instant::now();
421    omitted_supports.clone_from(shadowed_supports);
422    vacated_notes.clear();
423    if !distance.is_finite() || distance.abs() <= MINIMUM_DISTANCE {
424        return Err(KernelRefusal::input(KernelStage::Collect, "offset_shell_distance", "offset_shell: distance must be finite and non-zero"));
425    }
426    if opening_face_ids.is_empty() && body == Body::Shell {
427        return Err(KernelRefusal::input(KernelStage::Collect, "offset_shell_no_opening", "offset_shell: at least one opening face is required"));
428    }
429    let source_faces = source
430        .shells
431        .iter()
432        .flat_map(|shell| &shell.faces)
433        .collect::<Vec<_>>();
434    let opening_set = opening_face_ids.iter().copied().collect::<HashSet<_>>();
435    if opening_set
436        .iter()
437        .any(|id| !source_faces.iter().any(|face| face.id == *id))
438    {
439        return Err(KernelRefusal::input(KernelStage::Collect, "offset_shell_foreign_opening", "offset_shell: opening face does not belong to source"));
440    }
441    let retained = source_faces
442        .iter()
443        .filter(|face| !opening_set.contains(&face.id))
444        .map(|face| face.id)
445        .collect::<Vec<_>>();
446    if retained.is_empty() {
447        return Err(refusals::no_retained_face().into());
448    }
449    let mut carriers = Vec::new();
450    // Faces whose folded part was carved away, by source face id. Later stages
451    // that read a retained face's TRIM — the apex-cap scan below is the one —
452    // must read the carved trim, not the one the source still carries.
453    let mut carved_supports = HashMap::<u64, FaceRecord>::default();
454
455    for face_id in &retained {
456        let face = source_faces.iter().find(|face| face.id == *face_id).unwrap();
457        profile::lap(&mut clock, profile::CARRIER_TRIM);
458        let collapsed = offset_support_collapsed(face, distance)?;
459        profile::lap(&mut clock, profile::CARRIER_REGULARITY);
460        if collapsed {
461            os_debug!("omitting collapsed offset support for source face {face_id}");
462            continue;
463        }
464        // A support a previous pass found SHADOWED contributes no skin, and its
465        // carrier must not imprint its neighbours either — see the selection.
466        if shadowed_supports.contains(face_id) {
467            os_debug!("omitting shadowed offset support for source face {face_id}");
468            continue;
469        }
470        // A planar carrier whose source face meets a neighbour at a REFLEX
471        // (concave) edge extends its trim by |distance|: at such a junction
472        // the offset skin must GROW past the source footprint to meet the
473        // neighbour's offset (a pocket wall's source [5,15] → skin
474        // [3.5,16.5]); a source-sized trim leaves a gap no miter can bridge.
475        // The surplus at the face's convex ends is clipped by the imprints +
476        // on-skin filter. Convex-only faces keep their exact source-sized
477        // trim — extending them perturbs delicately-selected fragment
478        // landscapes for no benefit.
479        let miter = source_faces
480            .iter()
481            .find(|face| face.id == *face_id)
482            .map(|face| face_reflex_miter_tan(source, face))
483            .transpose()?
484            .flatten();
485        // The offsets of two faces joined at a reflex edge meet d·tan(θn/2)
486        // past the source rim — d only for a perpendicular join. Scale the
487        // extension to the worst sampled miter (×1.5 headroom so the true
488        // intersection lands strictly INSIDE the extended trim, never on its
489        // boundary where the arrangement drops boundary-coincident cuts) and
490        // cap it: a near-tangential join would ask for an unbounded trim.
491        let reflex_extension = miter.map(|worst_tan| {
492            (distance.abs() * worst_tan * 1.5)
493                .max(distance.abs())
494                .min(distance.abs() * 12.0)
495        });
496        if let Some(extension) = reflex_extension {
497            os_debug!("carrier for src face {face_id}: reflex-extended by {extension:.4}");
498        }
499        // OUTWARD: every retained carrier grows by |distance| across its
500        // sharp and opening-facing sides (the offsets of a convex junction
501        // meet past both source rims; a wall plane cuts the surplus), and
502        // by nothing across a smooth junction into a retained neighbour —
503        // see `outward_carrier_extension`. A reflex junction needs no
504        // outward growth at all (those offsets cross inside the trims).
505        let extension = if distance < 0.0 {
506            outward_carrier_extension(source, face, &source_faces, &opening_set, distance.abs())?
507        } else {
508            let mut inward = crate::CarrierExtension::uniform(reflex_extension.unwrap_or(0.0));
509            // An INWARD carrier that falls short of the planar opening it meets
510            // is grown until it crosses that plane, so the imprint cuts the
511            // skin there instead of leaving a rim for the ruled weld to cork
512            // below the opening (`fallshort_opening_reach`).
513            if let Some((at_v_max, reach)) =
514                fallshort_opening_reach(source, face, &source_faces, &opening_set, distance)?
515            {
516                // Past the plane by a quarter of the shell's own thickness, so
517                // the section is strictly inside the carrier's trim rather than
518                // on its boundary. Measured 2026-09-17 over the offset-shell
519                // suite: every fraction from 0.01 to 2.0 of |d| gives the same
520                // 73 passing members, while a margin sized in COINCIDENCE BANDS
521                // (1 to 32 of them, 2e-5 each here) breaks the sphere-under-
522                // frustum member by 9.4e-2 — the fragile margins are the ones
523                // far below the construction's own length.
524                let grown = reach + REACH_CLEARANCE * distance.abs();
525                if at_v_max {
526                    inward.v_max = inward.v_max.max(grown);
527                } else {
528                    inward.v_min = inward.v_min.max(grown);
529                }
530                os_debug!(
531                    "carrier for src face {face_id}: inward reach to its opening plane {reach:.6}                      at v_{} ",
532                    if at_v_max { "max" } else { "min" },
533                );
534            }
535            // A CURVED opening has no such construction, and the pipeline
536            // closes the cavity with whatever completion reaches for: measured
537            // 7.6% short on the hemisphere cup shelled through its dome.
538            if let Some((opening, gap)) =
539                offset_falls_short_of_curved_opening(source, face, &source_faces, &opening_set, distance)?
540            {
541                return Err(KernelRefusal::unsupported(KernelStage::Refine, "offset_shell_curved_opening_short", format!(
542                    "offset_shell: the offset skin of source face {face_id} stops {gap:.3e} short of \
543                     curved opening face {opening}; only a planar opening's skin is grown to meet it"
544                )));
545            }
546            inward
547        };
548        if distance < 0.0 {
549            os_debug!(
550                "carrier for src face {face_id}: outward extension u=({:.3},{:.3}) v=({:.3},{:.3})",
551                extension.u_min,
552                extension.u_max,
553                extension.v_min,
554                extension.v_max,
555            );
556        }
557        // CARVE: a support whose offset folds over PART of its trim keeps the
558        // regular part and drops the rest, instead of being built whole with
559        // the fold in it. The carrier is built over the CARVED source, so the
560        // trim it clones stops at the fold locus — and, because that trim no
561        // longer reaches past the offset's pinch, `offset_surface`'s apex-cone
562        // pinch retrim does not fire and the cloned pcurves still name the
563        // pointwise offset.
564        //
565        // A carve that cannot be made is not a licence to build the folded
566        // support anyway: the refusal is the answer, because a carrier with an
567        // inverted patch in it welds into a shell that validates and bounds the
568        // wrong solid.
569        profile::lap(&mut clock, profile::CARRIER_TRIM);
570        let carved = carve_folded_support(source, face, distance)?;
571        profile::lap(&mut clock, profile::CARRIER_REGULARITY);
572        // A CUT RIM — the face's rim with a planar opening running across
573        // its surface rather than along a v end — has the trim rebuilt over
574        // the surface's full rectangle so the opening plane truncates the
575        // offset skin (`cut_rim_full_rectangle_source`); like the carve, a
576        // substitute source the carrier is built over.
577        let cut_rim = if carved.is_none() {
578            cut_rim_full_rectangle_source(source, face, &source_faces, &opening_set, distance)?
579        } else {
580            None
581        };
582        // A curved face's SHARP outward u-side: the carrier is built over the
583        // surface continued past it, so it reaches the mitre with its sharp
584        // neighbour's offset (`sharp_side_continued_source`).
585        let sharp_side = if carved.is_none() && cut_rim.is_none() {
586            sharp_side_continued_source(source, face, &source_faces, &opening_set, distance, &extension)?
587        } else {
588            None
589        };
590        let carrier_source = match (&carved, &cut_rim) {
591            (None, None) if sharp_side.is_some() => sharp_side.as_ref().unwrap(),
592            (None, Some(rebuilt)) => rebuilt,
593            (Some(carved), _) => {
594                os_debug!(
595                    "carving the fold off source face {face_id}: {:.1}% of its trim kept, \
596                     {} new boundary pcurve(s)",
597                    carved.kept_fraction * 100.0,
598                    carved.fold_boundary
599                );
600                carved_supports.insert(*face_id, carved.face.clone());
601                &carved.solid
602            }
603            (None, None) => source,
604        };
605        profile::lap(&mut clock, profile::CARRIER_TRIM);
606        let (mut carrier, lane) = carrier_solid_sided_lane(carrier_source, *face_id, distance, &extension)?;
607        profile::carrier_built(lane, clock.elapsed());
608        clock = web_time::Instant::now();
609        if (distance < 0.0 || reflex_extension.is_some()) && face.surface.is_affine().or_refuse(KernelStage::Sew, "is_affine")? {
610            // PADDED planes: the pad slides the plane's net while the trim's
611            // loops are cloned in uv, so an INTERIOR loop (a bore or boss rim
612            // in the face) is carried outward with the grown outline instead
613            // of following the neighbour's offset.
614            //   OUTWARD: a bore's rim grew (r=4.68 → 5.15) while the shrunk
615            //   offset bore (r=3.68) that must hole this plane fell inside the
616            //   enlarged void, so neither the imprint nor the orphan-rim weld
617            //   could cut it.
618            //   INWARD, reflex-extended: the same slide moves a REFLEX hole
619            //   rim the wrong way — a sphere sitting under a frustum's base
620            //   annulus (the user's 2026-09-07 document) had its r=8.3 rim
621            //   scaled to 9.22 while the shrunk offset sphere (r=7.3) crosses
622            //   the offset plane at r=7.23, inside the enlarged hole: the
623            //   pair imprint found nothing and the rim stayed one-use.
624            // Drop the interior loops (as the wall carriers do): the
625            // neighbour's carrier imprints — or its rim, welded in as a
626            // hole — cut the true opening, and the seeded selection drops
627            // the disk over it. A CONVEX interior rim on the same face (a
628            // through-bore in a pocket floor) is safe to drop too: its
629            // offset bore imprints at r+d and the ring inside is rejected by
630            // class (Out) or by the on-skin filter, no seed involved.
631            drop_wall_interior_loops(&mut carrier)?;
632            // A free-form outline grown uniformly outward is trimmed by its
633            // outline OFFSET, not the slid net's scaled trim
634            // (`outline_offset_carrier`).
635            let uniform = extension.u_min == extension.u_max
636                && extension.u_min == extension.v_min
637                && extension.u_min == extension.v_max;
638            if distance < 0.0 && uniform {
639                // Past the walls' sections by the same clearance a planar
640                // neighbour of a ruled wall gets, so each section lies
641                // strictly INSIDE the fitted trim rather than on it.
642                let clearance =
643                    RULED_NEIGHBOUR_CLEARANCE_BANDS * offset_skin_band(crate::solid_scale(source), distance);
644                if let Some(rebuilt) = outline_offset_carrier(source, face, extension.u_min, clearance, &carrier)? {
645                    os_debug!(
646                        "carrier for src face {face_id}: outline trimmed by its offset by {:.4}",
647                        extension.u_min + clearance
648                    );
649                    carrier = rebuilt;
650                }
651            }
652        }
653        // An inward reflex junction needs a construction plane extending PAST
654        // the source rim. Sliding the net under a free-form trim scales that
655        // trim instead: a notched revolve cap's notch grows, and clips away the
656        // sections with the box's offsets. Even its curved convex boundary can
657        // fall inside the neighbouring offset section after that scaling.
658        // Use the extended plane's full rectangle and let the neighbouring
659        // carriers cut the skin. The source face and the offset surface stay
660        // unchanged. Unlike an outline offset, this needs no approximation of
661        // the planar rim's parallel curve (which may collapse at a tight turn).
662        if distance > 0.0
663            && reflex_extension.is_some()
664            && face.surface.is_affine().or_refuse(KernelStage::Refine, "is_affine")?
665            && outline_has_free_element(source, face)?
666        {
667            carrier = full_rectangle_face(&carrier, &carrier.shells[0].faces[0])?;
668        }
669        // The rim a shadowed support's removal VACATED in this carrier's trim:
670        // a slot narrower than 2|d| that runs out through this face leaves a
671        // notch its own skin has to close, because the dilation fills the slot.
672        // The source face keeps its notch; only the carrier is bridged.
673        if distance < 0.0 && !shadowed_supports.is_empty() {
674            let report = close_vacated_rims(
675                &mut carrier,
676                source_faces
677                    .iter()
678                    .find(|face| face.id == *face_id)
679                    .copied()
680                    .unwrap_or(face),
681                &source_faces,
682                shadowed_supports,
683            )?;
684            if report.closed > 0 {
685                os_debug!(
686                    "carrier for src face {face_id}: {} vacated rim run(s) bridged",
687                    report.closed
688                );
689            }
690            for declined in &report.declined {
691                os_debug!("carrier for src face {face_id}: vacated rim left alone — {declined}");
692                vacated_notes.push(format!("source face {face_id}: {declined}"));
693            }
694        }
695        carriers.push(Carrier {
696            solid: carrier,
697            source_face_id: *face_id,
698            kind: OffsetFaceRole::Offset,
699        });
700    }
701    profile::lap(&mut clock, profile::CARRIER_TRIM);
702    // APEX-CAP carriers: a retained face whose DEGENERATE edge (an apex
703    // point, e.g. a conic crater's tip) offsets into a RING is an EXTERIOR
704    // cone offset — the parallel surface truncates at the ring and the exact
705    // rolling-ball offset closes it with a SPHERE of radius |distance| about
706    // the apex. Emit that sphere as an extra carrier: the ring imprint
707    // (sphere × offset frustum) splits it, the on-skin filter keeps exactly
708    // the cap sector (its points are |d| from the apex and ≥|d| from the
709    // rest of the face), and the ring becomes two-use.
710    let mut apex_cap_sources = HashSet::default();
711    let mut apex_cap_pairs: Vec<(usize, usize)> = Vec::new();
712    {
713        let retained_count = carriers.len();
714        for index in 0..retained_count {
715            // A CARVED support's trim is the carved one. Its coedges name edges
716            // that live only in the carved clone, so the `source.edges` lookup
717            // below finds nothing and the apex-cap lane skips the face — which
718            // is right: the carve already ended that carrier at the offset's own
719            // pinch, and there is no apex ring left to cap.
720            let carved_face = carved_supports.get(&carriers[index].source_face_id);
721            let source_face = carved_face
722                .or_else(|| source_by_id_lookup(&source_faces, carriers[index].source_face_id));
723            let Some(source_face) = source_face else {
724                continue;
725            };
726            let carrier_surface = carriers[index].solid.shells[0].faces[0].surface.clone();
727            for coedge in source_face
728                .loops
729                .iter()
730                .flat_map(|loop_record| &loop_record.coedges)
731            {
732                let Some(edge) = source
733                    .edges
734                    .iter()
735                    .find(|edge| edge.id == coedge.edge_id)
736                else {
737                    continue;
738                };
739                if !edge.degenerate {
740                    continue;
741                }
742                // Image of the degenerate edge on the offset surface.
743                let [p0, p1] = coedge.pcurve.domain().or_refuse(KernelStage::Sew, "domain")?;
744                let mut ring = Vec::new();
745                for sample in 0..=8 {
746                    let uv = coedge
747                        .pcurve
748                        .evaluate(p0 + (p1 - p0) * sample as f64 / 8.0).or_refuse(KernelStage::Sew, "evaluate")?;
749                    ring.push(carrier_surface.evaluate(uv.x, uv.y).or_refuse(KernelStage::Sew, "evaluate")?);
750                }
751                let spread = ring
752                    .iter()
753                    .map(|point| point.sub(ring[0]).length())
754                    .fold(0.0f64, f64::max);
755                if spread <= distance.abs() * 1e-2 {
756                    continue;
757                }
758                let apex = source
759                    .vertices
760                    .iter()
761                    .find(|vertex| vertex.id == edge.start_vertex_id)
762                    .map(|vertex| vertex.point)
763                    .ok_or_else(|| "offset_shell: apex vertex missing".to_string()).or_refuse(KernelStage::Sew, "offset_shell_apex_vertex_missing")?;
764                let centroid = ring
765                    .iter()
766                    .fold(Vec3::default(), |sum, point| sum.add(*point))
767                    .scale(1.0 / ring.len() as f64);
768                let axis = apex.sub(centroid);
769                let axis = if axis.length() > 1e-9 {
770                    axis.normalized().or_refuse(KernelStage::Sew, "normalized")?
771                } else {
772                    Vec3::new(0.0, 0.0, 1.0)
773                };
774                os_debug!(
775                    "apex-cap carrier for src face {} at ({:.3},{:.3},{:.3}) r={:.3}",
776                    carriers[index].source_face_id,
777                    apex.x,
778                    apex.y,
779                    apex.z,
780                    distance.abs(),
781                );
782                apex_cap_sources.insert(index);
783                apex_cap_sources.insert(carriers.len());
784                apex_cap_pairs.push((index, carriers.len()));
785                carriers.push(Carrier {
786                    solid: crate::make_sphere_brep(apex, distance.abs(), axis).or_refuse(KernelStage::Sew, "make_sphere_brep")?,
787                    source_face_id: carriers[index].source_face_id,
788                    kind: OffsetFaceRole::Offset,
789                });
790            }
791        }
792    }
793    profile::lap(&mut clock, profile::APEX_CAPS);
794    // A fold the carve's probe did not see (`outward_fold_the_carve_missed`):
795    // a band too thin for its grid is built whole, and the torus wedge grown by
796    // 1.001 then held the reflected lemon beyond its axis. Asked of every
797    // retained face the carve neither carved nor omitted, on every outward
798    // shell: a ruled wall is what first let the pipeline CLOSE such a shape,
799    // but the geometry is the trigger. Refused by name, the tangent onset
800    // included; a partial revolve of that kind is the revolved-wedge lane's
801    // question, and that lane runs in front of this pipeline.
802    if distance < 0.0 {
803        for face_id in &retained {
804            if carved_supports.contains_key(face_id)
805                || !carriers.iter().any(|carrier| carrier.source_face_id == *face_id)
806            {
807                continue;
808            }
809            let face = source_by_id_lookup(&source_faces, *face_id).unwrap();
810            if let Some(fold) = outward_fold_the_carve_missed(face, distance)? {
811                return Err(KernelRefusal::unsupported(KernelStage::Refine, "offset_shell_outward_fold_band", format!(
812                    "offset_shell: the outward offset of source face {face_id} folds where the carve \
813                     saw no fold (area factor {:.3e} at u={:.6}, v={:.6}); a fold band that thin is \
814                     not built",
815                    fold.factor, fold.u, fold.v
816                )));
817            }
818        }
819    }
820    profile::lap(&mut clock, profile::CARRIER_REGULARITY);
821    // Wall carriers built as a RULED opening face extended along itself, by
822    // carrier index: the in-front guard reads their sides off the surface
823    // normal where it would read a plane's.
824    let mut ruled_walls = HashSet::default();
825    // Inward walls at reflex rims need construction area beyond the source
826    // opening too. Track them for source imprints and material-side selection.
827    let mut inward_extended_walls = HashSet::default();
828    let mut reflex_wall_neighbors = HashMap::default();
829    // OUTWARD through a CURVED opening. A ruled one — the cone a revolved
830    // straight profile edge sweeps, a cylinder — has its wall built as the
831    // opening face held in place and EXTENDED along itself, exactly as a plane
832    // is padded (`extended_ruled_wall`); the pad is the plane's, read off the
833    // same convex junctions. Built first, so the planar walls know which
834    // neighbours are ruled walls.
835    //
836    // Any other curved opening is refused by name. Its wall used to be the
837    // unpadded source face, which never reaches the grown offset: on a torus
838    // wedge whose chord revolves to a cone, the pair offset x cone cut 0
839    // pieces, the cone's one fragment was dropped as a void cross-section, and
840    // the result read "completion produced non-integral genus" with 12 open
841    // edges. No outward shell in the kernel suites or the case corpus closed
842    // through that wall (census, 2026-09-17).
843    let mut ruled_built = HashMap::<u64, BrepSolid>::default();
844    if distance < 0.0 {
845        for face_id in opening_face_ids {
846            let source_face = source_by_id_lookup(&source_faces, *face_id).unwrap();
847            if source_face.surface.is_affine().or_refuse(KernelStage::Sew, "is_affine")? {
848                continue;
849            }
850            if !ruled_opening(source_face)? {
851                return Err(KernelRefusal::unsupported(KernelStage::Refine, "offset_shell_curved_opening", format!(
852                    "offset_shell: opening face {face_id} is curved and not a ruled surface; an \
853                     outward wall is built only on a planar or ruled opening"
854                )));
855            }
856            let pad = outward_wall_pad(
857                source,
858                source_face,
859                &source_faces,
860                &opening_set,
861                distance.abs(),
862            )?;
863            let tolerance = 1e-7f64.max(crate::solid_scale(source) * 1e-9);
864            match extended_ruled_wall(source, source_face, pad, tolerance)? {
865                Ok(wall) => {
866                    os_debug!(
867                        "wall for opening face {face_id}: ruled, pad {pad:.4}, sides reach {:.4?}",
868                        wall.reached
869                    );
870                    ruled_built.insert(*face_id, wall.solid);
871                }
872                Err(reason) => {
873                    return Err(KernelRefusal::unsupported(KernelStage::Refine, "offset_shell_ruled_wall", format!(
874                        "offset_shell: the outward wall of ruled opening face {face_id} cannot be \
875                         built: {reason}"
876                    )));
877                }
878            }
879        }
880    }
881    let ruled_openings = ruled_built
882        .keys()
883        .filter_map(|id| source_by_id_lookup(&source_faces, *id))
884        .collect::<Vec<_>>();
885    for face_id in opening_face_ids {
886        let source_face = source_faces
887            .iter()
888            .find(|face| face.id == *face_id)
889            .unwrap();
890        if let Some(wall) = ruled_built.remove(face_id) {
891            ruled_walls.insert(carriers.len());
892            carriers.push(Carrier {
893                solid: wall,
894                source_face_id: *face_id,
895                kind: OffsetFaceRole::Wall,
896            });
897            continue;
898        }
899        if distance > 0.0
900            && source_face.surface.is_affine().or_refuse(KernelStage::Refine, "is_affine")?
901        {
902            if let Some((pad, neighbors)) =
903                inward_wall_pad(source, source_face, &source_faces, &opening_set, distance)?
904            {
905                // Scaling a notched/free-form outline can still clip the new
906                // rim. Use the whole plane rectangle; source and offset
907                // imprints below recover both exact boundaries of the wall.
908                let padded = carrier_solid(source, *face_id, 0.0, pad)?;
909                let wall = full_rectangle_face(&padded, &padded.shells[0].faces[0])?;
910                inward_extended_walls.insert(carriers.len());
911                reflex_wall_neighbors.insert(carriers.len(), neighbors);
912                carriers.push(Carrier {
913                    solid: wall,
914                    source_face_id: *face_id,
915                    kind: OffsetFaceRole::Wall,
916                });
917                continue;
918            }
919        }
920        carriers.push(Carrier {
921            solid: if distance < 0.0 && source_face.surface.is_affine().or_refuse(KernelStage::Sew, "is_affine")? {
922                let pad = outward_wall_pad(
923                    source,
924                    source_face,
925                    &source_faces,
926                    &opening_set,
927                    distance.abs(),
928                )?;
929                // A plane meeting a RULED opening is padded past the grown
930                // outline, not onto it. Padded by exactly the pad, its trim's
931                // arc lands ON the grown offset's section wherever the join is
932                // perpendicular, and the ruled wall's section then ENDS on that
933                // coincident pair: on the torus wedge the cap shredded into 60
934                // slivers along the grown circle. The clearance is counted in
935                // the band that decides whether the strip beyond the grown
936                // outline is wall or void, so the strip always resolves as its
937                // own fragment and is dropped as void.
938                let pad = if ruled_openings
939                    .iter()
940                    .any(|ruled| source_faces_adjacent(source_face, ruled))
941                {
942                    pad + RULED_NEIGHBOUR_CLEARANCE_BANDS
943                        * offset_skin_band(crate::solid_scale(source), distance)
944                } else if outline_has_free_element(source, source_face)? {
945                    // A free-form outline's wall is a FIT: without the same
946                    // clearance its outline sits within the fit tolerance of
947                    // the carriers' own sections on the plane, and the
948                    // near-coincident curves shred the wall's imprint (26 to
949                    // 121 fragments on the free-form D band, 2026-09-26). With
950                    // it, the surplus ring is cut away cleanly.
951                    pad + RULED_NEIGHBOUR_CLEARANCE_BANDS * offset_skin_band(crate::solid_scale(source), distance)
952                } else {
953                    pad
954                };
955                os_debug!("wall for opening face {face_id}: outward pad {pad:.4}");
956                // The wall is the opening's outline OFFSET by the pad in its
957                // own plane (`outline_offset.rs`). The pad used to SCALE that
958                // outline about the patch centre, which is the offset only for
959                // a rectangle filling its patch or a circle centred on it: an
960                // L-shaped opening's notch edges pass through the centre and
961                // did not move at all, so the notch faces' grown offsets
962                // crossed the plane outside the wall ("non-integral genus",
963                // `l-step-open-bottom` at d = −1.5 in the membrane census).
964                //
965                // An outline this module does not offset keeps the scaled wall,
966                // but only when that wall still COVERS the offset outline along
967                // every edge a retained face meets — which is what the sections
968                // have to land inside. Otherwise the shell refuses by name
969                // rather than assembling an open rim.
970                let mut scaled = carrier_solid(source, *face_id, 0.0, pad)?;
971                drop_wall_interior_loops(&mut scaled)?;
972                let mut wall = match offset_outline_wall(source, source_face, pad)? {
973                    Ok(outline) => {
974                        // Where the scaled wall already trims the offset
975                        // outline's own region — a rectangle filling its patch,
976                        // a circle centred on it — it is kept, so no shell that
977                        // was right before is rebuilt on a different patch.
978                        let same = walls_trim_the_same_region(
979                            &outline,
980                            &scaled,
981                            1e-9f64.max(crate::solid_scale(source) * 1e-11),
982                        )?;
983                        if same {
984                            os_debug!("wall for opening face {face_id}: scaled, which IS its outline offset");
985                            scaled
986                        } else {
987                            os_debug!("wall for opening face {face_id}: outline offset by {pad:.4}");
988                            outline
989                        }
990                    }
991                    Err(reason) => {
992                        let carrier_surfaces = carriers
993                            .iter()
994                            .filter(|carrier| matches!(carrier.kind, OffsetFaceRole::Offset))
995                            .map(|carrier| (carrier.source_face_id, &carrier.solid.shells[0].faces[0].surface))
996                            .collect::<Vec<_>>();
997                        if let Err(uncovered) = scaled_wall_covers_offset(
998                            source,
999                            source_face,
1000                            &scaled,
1001                            pad,
1002                            &source_faces,
1003                            &opening_set,
1004                            &carrier_surfaces,
1005                        )? {
1006                            return Err(KernelRefusal::unsupported(KernelStage::Refine, "offset_shell_opening_wall_coverage", format!(
1007                                "offset_shell: opening face {face_id}'s outline is not offset \
1008                                 ({reason}), and its scaled outward wall does not contain every \
1009                                 retained neighbour's grown offset section (a point of one lies \
1010                                 {uncovered:.3e} outside)"
1011                            )));
1012                        }
1013                        os_debug!(
1014                            "wall for opening face {face_id}: scaled, which covers its offset ({reason})"
1015                        );
1016                        scaled
1017                    }
1018                };
1019                // The pad extends the wall by STRETCHING the plane's 2x2 net
1020                // while the trim pcurves are cloned in UV, so every loop
1021                // scales about the patch centre by (w+2|d|)/w. For the OUTER
1022                // loop of a full-domain rectangle that lands exactly on the
1023                // grown outline — the intended wall extent. But an INTERIOR
1024                // loop (a carve outline: a bore, gouge or crater rim in the
1025                // opening face) is scaled OUTWARD too, and the enlarged hole
1026                // then swallows both circles the wall must be cut by (the
1027                // source carve rim from the wall x source imprint and the
1028                // shrunk rim from the wall x offset-carrier imprint) — the
1029                // imprints clip to nothing and the rims dangle one-use. Drop
1030                // interior loops instead: the wall covers the carve mouth,
1031                // the imprints cut the true rims, and selection (void-wall
1032                // guard + on-skin filter) drops the fragments over the void.
1033                drop_wall_interior_loops(&mut wall)?;
1034                wall
1035            } else {
1036                standalone_face(source, *face_id)?
1037            },
1038            source_face_id: *face_id,
1039            kind: OffsetFaceRole::Wall,
1040        });
1041    }
1042    if carriers.len() >= SOURCE_OPERAND as usize {
1043        return Err(KernelRefusal::unsupported(KernelStage::Collect, "offset_shell_carrier_count", "offset_shell: too many carrier faces for current ABI"));
1044    }
1045    profile::lap(&mut clock, profile::WALLS);
1046    // The characteristic length every tolerance below is derived from.  This
1047    // was `max ‖vertex‖` — the distance from the WORLD ORIGIN — until audit
1048    // slice 0: that form made every band widen as the part was moved away from
1049    // the origin while ignoring the part's actual size, so the same shell
1050    // solved to different tolerances depending only on where it was modelled.
1051    // `solid_scale` is the bbox diagonal, floored at 1.0 exactly as the old
1052    // fold was, so this changes ONE thing: placement-dependence.
1053    let scale = crate::solid_scale(source);
1054    crate::report_scale_migration("offset_shell", scale, || {
1055        source
1056            .vertices
1057            .iter()
1058            .map(|vertex| vertex.point.length())
1059            .fold(1.0, f64::max)
1060    });
1061    let smooth = synchronize_smooth_offset_boundaries(&mut carriers, &source_faces, scale)?;
1062    // Reflex-rim rebuilds run on BOTH attempts: the fallback for a broken
1063    // extension is an honest refusal, but the fallback for a skipped reflex
1064    // rebuild is a silently WRONG (membrane-capped) shell.
1065    let reflex_rebuilt = rebuild_reflex_rim_carriers(
1066        &mut carriers,
1067        source,
1068        &source_faces,
1069        &smooth.pairs,
1070        scale,
1071        distance,
1072    )?;
1073    *reflex_rebuilds = reflex_rebuilt.len();
1074    if extend_oblique_carriers {
1075        let oblique_extended = extend_offset_carriers_past_open_hole_rims(
1076            &mut carriers,
1077            source,
1078            &source_faces,
1079            &opening_set,
1080            &smooth.pairs,
1081            scale,
1082        )?;
1083        let mut already_extended = oblique_extended.clone();
1084        already_extended.extend(reflex_rebuilt.iter().copied());
1085        let fallshort_extended = extend_fallshort_curved_carriers(
1086            &mut carriers,
1087            source,
1088            &source_faces,
1089            &opening_set,
1090            &smooth.pairs,
1091            &already_extended,
1092            scale,
1093            distance,
1094        )?;
1095        *extension_fired = !oblique_extended.is_empty() || fallshort_extended > 0;
1096        os_debug!(
1097            "extended {} oblique + {fallshort_extended} fall-short carriers past their opening planes",
1098            oblique_extended.len(),
1099        );
1100    }
1101    profile::lap(&mut clock, profile::EXTENSION);
1102    let tolerance = 1e-7f64.max(scale * 1e-9);
1103    let pair_tolerance = (scale * 1e-8).max(2e-6);
1104    let reach = distance.abs() * 4.0 + pair_tolerance;
1105    let carrier_samples = carriers
1106        .iter()
1107        .map(|carrier| carrier_extent_points(&carrier.solid))
1108        .collect::<Result<Vec<_>, _>>()?;
1109    let carrier_bounds = carrier_samples
1110        .iter()
1111        .map(|samples| Bounds::from_points(samples))
1112        .collect::<Option<Vec<_>>>()
1113        .ok_or_else(|| "offset_shell: carrier has no boundary samples".to_string()).or_refuse(KernelStage::Sew, "offset_shell_carrier_has_no_boundary_samples")?;
1114    let source_by_id = source_faces
1115        .iter()
1116        .map(|face| (face.id, *face))
1117        .collect::<HashMap<_, _>>();
1118    let source_samples = source_faces
1119        .iter()
1120        .map(|face| {
1121            let standalone = standalone_face(source, face.id)?;
1122            Ok((face.id, edge_sample_points(&standalone)?))
1123        })
1124        .collect::<Result<HashMap<_, _>, KernelRefusal>>()?;
1125    if debug_enabled() {
1126        for (index, carrier) in carriers.iter().enumerate() {
1127            let face = &carrier.solid.shells[0].faces[0];
1128            let samples = &carrier_samples[index];
1129            let bounds =
1130                samples
1131                    .iter()
1132                    .fold((Vec3::default(), Vec3::default()), |(low, high), point| {
1133                        (
1134                            Vec3 {
1135                                x: low.x.min(point.x),
1136                                y: low.y.min(point.y),
1137                                z: low.z.min(point.z),
1138                            },
1139                            Vec3 {
1140                                x: high.x.max(point.x),
1141                                y: high.y.max(point.y),
1142                                z: high.z.max(point.z),
1143                            },
1144                        )
1145                    });
1146            let surface = &face.surface;
1147            let rational = surface
1148                .control_points
1149                .iter()
1150                .flatten()
1151                .any(|point| (point.w - 1.0).abs() > 1e-12);
1152            os_debug!(
1153                "carrier[{index}] kind={:?} source_face={} loops={} deg=({},{}) net={}x{} rational={rational} bounds=({:.3},{:.3},{:.3})..({:.3},{:.3},{:.3})",
1154                carrier.kind, carrier.source_face_id, face.loops.len(),
1155                surface.degree_u, surface.degree_v,
1156                surface.control_points.len(),
1157                surface.control_points.first().map(|row| row.len()).unwrap_or(0),
1158                bounds.0.x, bounds.0.y, bounds.0.z, bounds.1.x, bounds.1.y, bounds.1.z,
1159            );
1160        }
1161        for (index, carrier) in carriers.iter().enumerate() {
1162            if !matches!(carrier.kind, OffsetFaceRole::Offset) {
1163                continue;
1164            }
1165            let source_face = source_by_id[&carrier.source_face_id];
1166            let carrier_surface = &carrier.solid.shells[0].faces[0].surface;
1167            let (ku, kv) = (
1168                crate::KnotVector::new(
1169                    source_face.surface.knots_u.clone(),
1170                    source_face.surface.degree_u,
1171                ),
1172                crate::KnotVector::new(
1173                    source_face.surface.knots_v.clone(),
1174                    source_face.surface.degree_v,
1175                ),
1176            );
1177            if let (Ok(ku), Ok(kv)) = (ku, kv) {
1178                let [u0, u1] = ku.domain();
1179                let [v0, v1] = kv.domain();
1180                let mut worst = 0.0f64;
1181                let mut worst_at = (0.0f64, 0.0f64);
1182                for iu in 0..=24 {
1183                    for iv in 0..=24 {
1184                        let u = u0 + (u1 - u0) * iu as f64 / 24.0;
1185                        let v = v0 + (v1 - v0) * iv as f64 / 24.0;
1186                        let expected = face_offsets(source_face)
1187                            .at(u, v, -distance)
1188                            .map(|sample| sample.point);
1189                        let actual = carrier_surface.evaluate(u, v);
1190                        if let (Ok(expected), Ok(actual)) = (expected, actual) {
1191                            let error = expected.sub(actual).length();
1192                            if error > worst {
1193                                worst = error;
1194                                worst_at = (u, v);
1195                            }
1196                        }
1197                    }
1198                }
1199                let mut normal_swing = 0.0f64;
1200                let mut previous: Option<Vec3> = None;
1201                for iu in 0..=48 {
1202                    let u = u0 + (u1 - u0) * iu as f64 / 48.0;
1203                    let v = (v0 + v1) / 2.0;
1204                    if let Ok(normal) = face_normal(source_face, u, v) {
1205                        if let Some(previous) = previous {
1206                            normal_swing = normal_swing.max(previous.sub(normal).length());
1207                        }
1208                        previous = Some(normal);
1209                    }
1210                }
1211                let weights = source_face
1212                    .surface
1213                    .control_points
1214                    .iter()
1215                    .flatten()
1216                    .map(|point| point.w)
1217                    .fold((f64::MAX, f64::MIN), |(low, high), w| {
1218                        (low.min(w), high.max(w))
1219                    });
1220                os_debug!(
1221                    "carrier[{index}] offset fit error max={worst:.6} at=({:.4},{:.4}) domain_u=({u0:.4},{u1:.4}) normal_step_max={normal_swing:.4} src_net={}x{} src_deg=({},{}) src_w=({:.4},{:.4}) knots_u={:?}",
1222                    worst_at.0, worst_at.1,
1223                    source_face.surface.control_points.len(),
1224                    source_face.surface.control_points.first().map(|row| row.len()).unwrap_or(0),
1225                    source_face.surface.degree_u, source_face.surface.degree_v,
1226                    weights.0, weights.1,
1227                    &source_face.surface.knots_u,
1228                );
1229            }
1230        }
1231        os_debug!("smooth pairs: {:?}", smooth.pairs);
1232    }
1233    let mut imprint = empty_imprint();
1234    let mut next_piece_id = 1;
1235    let mut next_vertex_id = 1;
1236    for first in 0..carriers.len() {
1237        for second in first + 1..carriers.len() {
1238            let first_source = source_by_id[&carriers[first].source_face_id];
1239            let second_source = source_by_id[&carriers[second].source_face_id];
1240            if matches!(carriers[first].kind, OffsetFaceRole::Wall)
1241                && matches!(carriers[second].kind, OffsetFaceRole::Wall)
1242            {
1243                // Unextended inward walls are the opening faces themselves:
1244                // they never overlap; adjacent ones only touch along their
1245                // shared edge, so there is nothing to imprint. OUTWARD walls
1246                // are the opening planes EXTENDED by |distance|: the walls of
1247                // two ADJACENT openings cross along the line of their shared
1248                // source edge, and each wall ring must stop there (the sheet
1249                // past that line lies in front of the other opening). Without
1250                // the cut the wall × source chain below stays open on the
1251                // shared-edge side (its neighbour there is an opening, not a
1252                // retained face), the wall never fragments into its ring, and
1253                // every source rim along both openings dangles one-use.
1254                // Extended inward walls need those mutual cuts as well.
1255                if (distance > 0.0
1256                    && !inward_extended_walls.contains(&first)
1257                    && !inward_extended_walls.contains(&second))
1258                    || !source_faces_adjacent(first_source, second_source)
1259                {
1260                    continue;
1261                }
1262            }
1263            if smooth.pairs.contains(&(first, second)) {
1264                os_debug!("pair ({first},{second}) skipped: smooth");
1265                continue;
1266            }
1267            if !carrier_bounds[first].intersects(carrier_bounds[second], pair_tolerance) {
1268                os_debug!("pair ({first},{second}) skipped: bounds");
1269                continue;
1270            }
1271            if !source_faces_adjacent(first_source, second_source)
1272                && sample_separation(
1273                    &source_samples[&first_source.id],
1274                    &source_samples[&second_source.id],
1275                ) > reach
1276            {
1277                os_debug!("pair ({first},{second}) skipped: separation");
1278                continue;
1279            }
1280            let pair = match crate::imprint::build_carrier_imprints(
1281                &carriers[first].solid,
1282                &carriers[second].solid,
1283                &ImprintOptions {
1284                    tolerance,
1285                    maximum_fit_points: 96,
1286                    // The GLOBAL interpolation lane. `local_fit: true` until
1287                    // 2026-09-13, which cost three orders on every smooth
1288                    // section: measured on the apex cone's base circle, the
1289                    // local lane needs 3,070 control points to reach 2.0e-5
1290                    // where the global one reaches 1.4e-8 with 384. What the
1291                    // local lane is for — a rim through a corner, where its
1292                    // monotonicity limiter holds a kink the global cubic rings
1293                    // across, 4.9x measured — is now the fit's own fallback:
1294                    // `fit_polyline` re-runs the other lane whenever the asked
1295                    // one cannot meet the tolerance and returns the better
1296                    // MEASURED curve, so this flag chooses which ladder is
1297                    // paid for first, never which curve is delivered.
1298                    local_fit: false,
1299                    fit_chunk_points: None,
1300                    // Offset carriers can meet in short, tightly curved
1301                    // branches. The general SSI default (diagonal / 15) is
1302                    // too coarse here and lets independently fitted branches
1303                    // miss a shared junction when thickness crosses one of
1304                    // those branches.
1305                    maximum_ssi_step: Some((scale * 0.0005).max(tolerance * 100.0)),
1306                    span_budget: None,
1307                    hermite_sections: false,
1308                    tangent_curve_lane: false,
1309                    exact_iso_pcurves: false,
1310                    march_starts: false,
1311                    two_radius_junctions: false,
1312                    tangent_curve_imprint: false,
1313                },
1314            ) {
1315                Ok(pair) => pair,
1316                // A failed pair imprint (e.g. the marching SSI exhausting its
1317                // step budget on a long closed sphere/plane intersection) is
1318                // not fatal to the shell: the affected rim simply stays
1319                // unsplit and the rim-weld passes below get to close it. The
1320                // final watertightness gate still refuses anything the welds
1321                // cannot reach, so tolerating the miss only enlarges the
1322                // honest success set.
1323                Err(error) => {
1324                    os_debug!("pair ({first},{second}) imprint failed: {error}");
1325                    continue;
1326                }
1327            };
1328            let pieces_before = imprint.pieces.len();
1329            merge_pair_imprint(
1330                &mut imprint,
1331                pair,
1332                first as u8,
1333                second as u8,
1334                &mut next_piece_id,
1335                &mut next_vertex_id,
1336                tolerance,
1337                scale,
1338            );
1339            os_debug!(
1340                "pair ({first},{second}) src=({},{}) pieces+={}",
1341                carriers[first].source_face_id,
1342                carriers[second].source_face_id,
1343                imprint.pieces.len() - pieces_before,
1344            );
1345        }
1346    }
1347    if body == Body::Shell && (distance < 0.0 || !inward_extended_walls.is_empty()) {
1348        // An extended opening-wall carrier (outward, or inward at a reflex
1349        // rim) no longer carries the source outline. OUTWARD it has the GROWN
1350        // outline. Its inner boundary — where the wall ring stops at the
1351        // source solid — is the source outline, and the retained SOURCE faces
1352        // are not carriers, so no carrier×carrier pair ever imprints it.
1353        // Un-cut, the wall stays one whole-plane fragment covering the
1354        // opening void, and the source faces' rim edges dangle one-use.
1355        // Imprint each wall carrier against the retained source faces that
1356        // share an edge with its opening: the wall then fragments into the
1357        // ring (kept) and the opening hole (dropped by the void guard).
1358        for index in 0..carriers.len() {
1359            if !matches!(carriers[index].kind, OffsetFaceRole::Wall) {
1360                continue;
1361            }
1362            if distance > 0.0 && !inward_extended_walls.contains(&index) {
1363                continue;
1364            }
1365            let opening = source_by_id[&carriers[index].source_face_id];
1366            for retained_id in &retained {
1367                let retained_face = source_by_id[retained_id];
1368                if !source_faces_adjacent(opening, retained_face) {
1369                    continue;
1370                }
1371                let neighbor = standalone_face(source, *retained_id)?;
1372                let pair = match build_imprints(
1373                    &carriers[index].solid,
1374                    &neighbor,
1375                    &ImprintOptions {
1376                        tolerance,
1377                        maximum_fit_points: 96,
1378                        // The global lane, as above.
1379                        local_fit: false,
1380                        fit_chunk_points: None,
1381                        maximum_ssi_step: Some((scale * 0.0005).max(tolerance * 100.0)),
1382                        span_budget: None,
1383                        hermite_sections: false,
1384                        tangent_curve_lane: false,
1385                        exact_iso_pcurves: false,
1386                        march_starts: false,
1387                        two_radius_junctions: false,
1388                        tangent_curve_imprint: false,
1389                    },
1390                ) {
1391                    Ok(pair) => pair,
1392                    Err(error) => {
1393                        os_debug!(
1394                            "wall×source pair ({index},{retained_id}) imprint failed: {error}"
1395                        );
1396                        continue;
1397                    }
1398                };
1399                let pieces_before = imprint.pieces.len();
1400                merge_pair_imprint(
1401                    &mut imprint,
1402                    pair,
1403                    index as u8,
1404                    SOURCE_OPERAND,
1405                    &mut next_piece_id,
1406                    &mut next_vertex_id,
1407                    tolerance,
1408                    scale,
1409                );
1410                os_debug!(
1411                    "wall×source pair ({index},{retained_id}) pieces+={}",
1412                    imprint.pieces.len() - pieces_before,
1413                );
1414            }
1415        }
1416    }
1417    // APEX-CAP ring splits: the cap × cone section lies ON the cone
1418    // carrier's promoted ring edge (an overlap, not a crossing), so
1419    // `build_imprints` mints no edge splits for the cone side. Without them
1420    // the cone keeps ONE closed ring edge while the cap carries the section
1421    // as arcs — mismatched segmentation, both sides one-use. Record the arc
1422    // junctions as splits on the cone's coincident edge.
1423    for (cone_index, cap_index) in &apex_cap_pairs {
1424        let cap_face_id = carriers[*cap_index].solid.shells[0].faces[0].id;
1425        let piece_ids = imprint
1426            .by_face
1427            .iter()
1428            .find(|entry| entry.operand == *cap_index as u8 && entry.face_id == cap_face_id)
1429            .map(|entry| entry.piece_ids.clone())
1430            .unwrap_or_default();
1431        let coincidence_band = 2e-5f64.max(scale * 1e-7);
1432        for piece_id in piece_ids {
1433            let Some((curve, t0, t1)) = imprint
1434                .pieces
1435                .iter()
1436                .find(|piece| piece.id == piece_id)
1437                .map(|piece| (piece.curve.clone(), piece.t0, piece.t1))
1438            else {
1439                continue;
1440            };
1441            for endpoint in [curve.evaluate(t0).or_refuse(KernelStage::Sew, "evaluate")?, curve.evaluate(t1).or_refuse(KernelStage::Sew, "evaluate")?] {
1442                for edge in &carriers[*cone_index].solid.edges {
1443                    if edge.degenerate {
1444                        continue;
1445                    }
1446                    let projection = crate::project_point_to_curve(&edge.curve, endpoint).or_refuse(KernelStage::Sew, "project_point_to_curve")?;
1447                    if projection.distance > coincidence_band
1448                        || projection.u < edge.t0 + 1e-9
1449                        || projection.u > edge.t1 - 1e-9
1450                    {
1451                        continue;
1452                    }
1453                    let parameter = projection.u;
1454                    if let Some(existing) = imprint.edge_splits.iter_mut().find(|split| {
1455                        split.operand == *cone_index as u8 && split.edge_id == edge.id
1456                    }) {
1457                        if !existing
1458                            .parameters
1459                            .iter()
1460                            .any(|value| (*value - parameter).abs() <= 1e-8)
1461                        {
1462                            existing.parameters.push(parameter);
1463                        }
1464                    } else {
1465                        imprint.edge_splits.push(EdgeSplitRecord {
1466                            operand: *cone_index as u8,
1467                            edge_id: edge.id,
1468                            parameters: vec![parameter],
1469                        });
1470                    }
1471                    os_debug!(
1472                        "apex-cap ring split: cone carrier {cone_index} edge {} at t={parameter:.6}",
1473                        edge.id,
1474                    );
1475                }
1476            }
1477        }
1478    }
1479    if debug_enabled() {
1480        for piece in &imprint.pieces {
1481            let start = piece.curve.evaluate(piece.t0);
1482            let mid = piece.curve.evaluate((piece.t0 + piece.t1) * 0.5);
1483            let end = piece.curve.evaluate(piece.t1);
1484            if let (Ok(start), Ok(mid), Ok(end)) = (start, mid, end) {
1485                os_debug!(
1486                    "piece[{}] ({:.4},{:.4},{:.4})..({:.4},{:.4},{:.4})..({:.4},{:.4},{:.4})",
1487                    piece.id,
1488                    start.x,
1489                    start.y,
1490                    start.z,
1491                    mid.x,
1492                    mid.y,
1493                    mid.z,
1494                    end.x,
1495                    end.y,
1496                    end.z,
1497                );
1498            }
1499        }
1500    }
1501    synchronize_smooth_edge_splits(&mut imprint, &smooth.edge_pairs);
1502    // This decides whether an imprint is genuinely the carrier's existing
1503    // trim, not whether independently fitted curves can later be sewn. The
1504    // looser assembly tolerance can erase a short separating branch while it
1505    // is still departing a boundary.
1506    let boundary_coincidence_tolerance = 2e-5f64.max(scale * 1e-7);
1507    let piece_geometry = imprint
1508        .pieces
1509        .iter()
1510        .map(|piece| {
1511            (
1512                piece.id,
1513                FragmentEdgeGeometry {
1514                    curve: piece.curve.clone(),
1515                    t0: piece.t0,
1516                    t1: piece.t1,
1517                },
1518            )
1519        })
1520        .collect::<HashMap<_, _>>();
1521    for (index, carrier) in carriers.iter().enumerate() {
1522        if !matches!(carrier.kind, OffsetFaceRole::Offset) {
1523            continue;
1524        }
1525        let boundaries = carrier
1526            .solid
1527            .edges
1528            .iter()
1529            .map(|edge| FragmentEdgeGeometry {
1530                curve: edge.curve.clone(),
1531                t0: edge.t0,
1532                t1: edge.t1,
1533            })
1534            .collect::<Vec<_>>();
1535        if let Some(by_face) = imprint
1536            .by_face
1537            .iter_mut()
1538            .find(|entry| entry.operand == index as u8)
1539        {
1540            let before = by_face.piece_ids.clone();
1541            by_face.piece_ids.retain(|piece_id| {
1542                let piece = &piece_geometry[piece_id];
1543                !boundaries.iter().any(|boundary| {
1544                    fragment_edge_lies_on(piece, boundary, boundary_coincidence_tolerance)
1545                        .unwrap_or(false)
1546                })
1547            });
1548            if debug_enabled() && before.len() != by_face.piece_ids.len() {
1549                os_debug!(
1550                    "carrier[{index}] dropped boundary-coincident pieces: {:?} -> {:?}",
1551                    before,
1552                    by_face.piece_ids,
1553                );
1554            }
1555        }
1556    }
1557
1558    if debug_enabled() {
1559        for entry in &imprint.by_face {
1560            os_debug!(
1561                "by_face operand={} face={} pieces={:?}",
1562                entry.operand,
1563                entry.face_id,
1564                entry.piece_ids,
1565            );
1566        }
1567    }
1568    profile::lap(&mut clock, profile::IMPRINT);
1569    let mut split_carriers = Vec::new();
1570    let mut fragments_by_carrier = Vec::new();
1571    for (index, carrier) in carriers.iter().enumerate() {
1572        // Offset carriers keep their boundary un-split (their trims never
1573        // coincide with imprints — the boundary-coincidence filter drops such
1574        // pieces instead). An apex-cap ring breaks that assumption: the
1575        // frustum's ring is its TRIM boundary while the cap crosses it as TWO
1576        // imprint arcs — without splitting, the two sides segment differently
1577        // and both stay one-use. Split exactly the cap-affected carriers.
1578        let split = if matches!(carrier.kind, OffsetFaceRole::Offset)
1579            && !apex_cap_sources.contains(&index)
1580        {
1581            carrier.solid.clone()
1582        } else {
1583            apply_edge_splits(&carrier.solid, index as u8, &imprint)?
1584        };
1585        let fragment_clock = web_time::Instant::now();
1586        let fragments = fragment_solid(&split, index as u8, &imprint)?;
1587        os_debug!(
1588            "carrier[{index}] kind={:?} src={} fragments={} ({:.3} ms)",
1589            carrier.kind,
1590            carrier.source_face_id,
1591            fragments.len(),
1592            fragment_clock.elapsed().as_secs_f64() * 1e3,
1593        );
1594        if debug_enabled() {
1595            for (fragment_index, fragment) in fragments.iter().enumerate() {
1596                let mut boundary_count = 0usize;
1597                let mut imprint_pieces = Vec::new();
1598                let mut derived_count = 0usize;
1599                for coedge in fragment
1600                    .loops
1601                    .iter()
1602                    .flat_map(|loop_record| &loop_record.coedges)
1603                {
1604                    match &coedge.source {
1605                        FragmentEdgeSource::Boundary { .. }
1606                        | FragmentEdgeSource::SharedBoundary { .. } => boundary_count += 1,
1607                        FragmentEdgeSource::Imprint { piece_id } => imprint_pieces.push(*piece_id),
1608                        FragmentEdgeSource::Derived { .. } => derived_count += 1,
1609                    }
1610                }
1611                os_debug!(
1612                    "  frag[{index}.{fragment_index}] test=({:.3},{:.3},{:.3}) uv=({:.3},{:.3}) boundary={boundary_count} derived={derived_count} pieces={imprint_pieces:?}",
1613                    fragment.test_point.x, fragment.test_point.y, fragment.test_point.z,
1614                    fragment.test_uv.x, fragment.test_uv.y,
1615                );
1616            }
1617        }
1618        split_carriers.push(split);
1619        fragments_by_carrier.push(fragments);
1620    }
1621    profile::lap(&mut clock, profile::FRAGMENT);
1622    let mut assembly_sources = [(SOURCE_OPERAND, source)]
1623        .into_iter()
1624        .collect::<HashMap<_, _>>();
1625    for (index, carrier) in split_carriers.iter().enumerate() {
1626        assembly_sources.insert(index as u8, carrier);
1627    }
1628
1629    let source_edge_by_id = source
1630        .edges
1631        .iter()
1632        .map(|edge| (edge.id, edge))
1633        .collect::<HashMap<_, _>>();
1634    let retained_faces_with_edges = retained
1635        .iter()
1636        .map(|face_id| {
1637            let face = source_by_id[face_id];
1638            let edges = face
1639                .loops
1640                .iter()
1641                .flat_map(|loop_record| &loop_record.coedges)
1642                .filter_map(|coedge| source_edge_by_id.get(&coedge.edge_id).copied())
1643                .collect::<Vec<_>>();
1644            (face, edges)
1645        })
1646        .collect::<Vec<_>>();
1647    let offset_skin_tolerance = offset_skin_band(scale, distance);
1648    // OUTWARD shells: a wall fragment lying IN FRONT of another opening —
1649    // past that opening's plane on its void side, within the extent of its
1650    // (extended) wall carrier — is not material: an opening removes
1651    // everything in front of it. Such a fragment is the sheet of this wall
1652    // between the source outline and the grown outline on the far side of an
1653    // ADJACENT opening's shared edge (the x∈[−1,0] strip of an opened −Z
1654    // face's wall, in front of the opened −X face). It sits within |distance|
1655    // of a retained face's corner edge, so the void-cross-section guard reads
1656    // it as wall thickness; only the other opening's plane tells it apart.
1657    //
1658    // A RULED opening's wall is curved, so it has no one plane: its front is
1659    // read at the point's foot on the wall carrier, along the carrier's normal
1660    // turned to the opening face's outward side. On the torus wedge that is
1661    // what drops the start and end caps' strips beyond the extended chord,
1662    // which lie within |distance| of the torus and in front of the cone.
1663    let mut opening_planes: Vec<(usize, Vec3, Vec3)> = Vec::new();
1664    let mut opening_ruled: Vec<(usize, f64)> = Vec::new();
1665    if distance < 0.0 {
1666        for (index, carrier) in carriers.iter().enumerate() {
1667            if !matches!(carrier.kind, OffsetFaceRole::Wall) {
1668                continue;
1669            }
1670            let opening = source_by_id[&carrier.source_face_id];
1671            let [u0, u1] = opening.surface.domain_u().or_refuse(KernelStage::Sew, "domain_u")?;
1672            let [v0, v1] = opening.surface.domain_v().or_refuse(KernelStage::Sew, "domain_v")?;
1673            let (u, v) = ((u0 + u1) * 0.5, (v0 + v1) * 0.5);
1674            if ruled_walls.contains(&index) {
1675                let wall = &split_carriers[index].shells[0].faces[0];
1676                let probe = project_point_to_surface(&wall.surface, opening.surface.evaluate(u, v).or_refuse(KernelStage::Sew, "evaluate")?).or_refuse(KernelStage::Sew, "project_point_to_surface")?;
1677                let side = face_normal(wall, probe.u, probe.v)?.dot(face_normal(opening, u, v)?);
1678                opening_ruled.push((index, if side < 0.0 { -1.0 } else { 1.0 }));
1679                continue;
1680            }
1681            if !opening.surface.is_affine().or_refuse(KernelStage::Sew, "is_affine")? {
1682                continue;
1683            }
1684            opening_planes.push((
1685                index,
1686                opening.surface.evaluate(u, v).or_refuse(KernelStage::Sew, "evaluate")?,
1687                face_normal(opening, u, v)?,
1688            ));
1689        }
1690    }
1691    let in_front_of_other_opening = |wall_index: usize, point: Vec3| -> Result<bool, KernelRefusal> {
1692        let band = 2e-3f64.max(scale * 5e-5);
1693        for (index, plane_point, outward) in &opening_planes {
1694            if *index == wall_index || point.sub(*plane_point).dot(*outward) <= band {
1695                continue;
1696            }
1697            let face = &split_carriers[*index].shells[0].faces[0];
1698            let projection = project_point_to_surface(&face.surface, point).or_refuse(KernelStage::Sew, "project_point_to_surface")?;
1699            let uv = Vec2 {
1700                x: projection.u,
1701                y: projection.v,
1702            };
1703            if parameter_point_in_face(face, uv, 1e-8).or_refuse(KernelStage::Sew, "parameter_point_in_face")? != PolygonClass::Outside {
1704                return Ok(true);
1705            }
1706        }
1707        for (index, side) in &opening_ruled {
1708            if *index == wall_index {
1709                continue;
1710            }
1711            let face = &split_carriers[*index].shells[0].faces[0];
1712            let projection = project_point_to_surface(&face.surface, point).or_refuse(KernelStage::Sew, "project_point_to_surface")?;
1713            let outward = face_normal(face, projection.u, projection.v)?.scale(*side);
1714            if point.sub(projection.point).dot(outward) <= band {
1715                continue;
1716            }
1717            let uv = Vec2 {
1718                x: projection.u,
1719                y: projection.v,
1720            };
1721            if parameter_point_in_face(face, uv, 1e-8).or_refuse(KernelStage::Sew, "parameter_point_in_face")? != PolygonClass::Outside {
1722                return Ok(true);
1723            }
1724        }
1725        Ok(false)
1726    };
1727
1728    let mut chosen_offsets = Vec::new();
1729    let mut chosen_walls = Vec::new();
1730    let mut newly_shadowed = HashSet::<u64>::default();
1731    for (index, carrier) in carriers.iter().enumerate() {
1732        let raw_seeds = source_seeds(source, carrier.source_face_id)?;
1733        let mut seeds = Vec::with_capacity(raw_seeds.len());
1734        for raw_seed in raw_seeds {
1735            let seed = if matches!(carrier.kind, OffsetFaceRole::Offset) {
1736                offset_seed(
1737                    source_by_id[&carrier.source_face_id],
1738                    raw_seed,
1739                    &split_carriers[index].shells[0].faces[0].surface,
1740                    distance,
1741                    2e-3f64.max(scale * 5e-5),
1742                )?
1743                .unwrap_or(raw_seed)
1744            } else if inward_extended_walls.contains(&index) {
1745                offset_seed(
1746                    source_by_id[&carrier.source_face_id],
1747                    raw_seed,
1748                    &split_carriers[index].shells[0].faces[0].surface,
1749                    0.0,
1750                    2e-3f64.max(scale * 5e-5),
1751                )?
1752                .unwrap_or(raw_seed)
1753            } else {
1754                raw_seed
1755            };
1756            if seed.sub(raw_seed).length() > 1e-9 {
1757                os_debug!(
1758                    "  seed[{index}] moved from ({:.4},{:.4}) to the offset image ({:.4},{:.4})",
1759                    raw_seed.x,
1760                    raw_seed.y,
1761                    seed.x,
1762                    seed.y
1763                );
1764            }
1765            seeds.push(seed);
1766        }
1767        let seed = seeds[0];
1768        if matches!(carrier.kind, OffsetFaceRole::Offset) {
1769            // Fragments whose test point sits at the full offset distance
1770            // from every retained source face are the true offset-skin
1771            // regions. Fragments closer to some other face are shadowed
1772            // pockets/strips that another carrier owns.
1773            // A fragment whose offset lies ON another retained face's offset
1774            // (material exactly twice the shell distance thick: a slot, fin or
1775            // floor at t = 2d) reads as SHADOWED by that face. One hair
1776            // thinner, the same fragment reads shadowed on its own and is
1777            // dropped by the on-skin filter, or omits its carrier by the
1778            // skinless rule below, so the answer is the limit of that
1779            // construction: the census's L∞ forms are continuous across the
1780            // onset. Without this the fragment read On, was selected, and the
1781            // shell refused as "a cavity pinched to zero thickness". The
1782            // coincidence test is `coincident_offset_face`'s (the other face's
1783            // distance within `offset_skin_tolerance` of |d|, its foot on the
1784            // opposite side of the point from this face's own), taken only on
1785            // the THIN side of the onset.
1786            let mut readings = Vec::with_capacity(fragments_by_carrier[index].len());
1787            for fragment in &fragments_by_carrier[index] {
1788                let reading = offset_skin_reading(
1789                    fragment.test_point,
1790                    &retained_faces_with_edges,
1791                    distance,
1792                    offset_skin_tolerance,
1793                );
1794                let reading = match reading {
1795                    SkinReading::On => match coincident_offset_face(
1796                        fragment.test_point,
1797                        carrier.source_face_id,
1798                        &retained_faces_with_edges,
1799                        distance,
1800                        offset_skin_tolerance,
1801                    )? {
1802                        // ONE-SIDED and tight: only material no thicker than
1803                        // 2|d| (to 10× the model tolerance) takes the thin
1804                        // construction, which is exact there. A wall inside
1805                        // the skin band but genuinely thicker than 2|d| keeps
1806                        // its sliver cavity's named refusal below; taking the
1807                        // thin construction there would fill a real cavity.
1808                        Some((face, separation)) if separation <= distance.abs() + tolerance * 10.0 => {
1809                            SkinReading::Shadowed { face, separation }
1810                        }
1811                        _ => SkinReading::On,
1812                    },
1813                    other => other,
1814                };
1815                readings.push(reading);
1816            }
1817            for (fragment, reading) in fragments_by_carrier[index].iter().zip(&readings) {
1818                if let SkinReading::Unmeasured { face, reason } = reading {
1819                    return Err(unmeasured_skin_refusal(fragment.test_point, *face, reason));
1820                }
1821            }
1822            // EVERY fragment measured nearer than the distance to some other
1823            // retained face: this support's offset is SHADOWED over its whole
1824            // extended carrier — the side walls of a slot narrower than 2|d|
1825            // grown outward, a pocket floor within 2d of the face under it.
1826            // It owns no skin. It used to switch the filter off and keep its
1827            // seeded fragment anyway, which built a closed, validating shell
1828            // with an inverted box inside it (+90 on a width-2 slot grown by
1829            // 1.5, with the 90 of material at its centre missing). Dropping
1830            // only its fragments is not enough: its carrier has already cut
1831            // its neighbours, and the top skin over that slot keeps a hole
1832            // nothing fills. So the pass is re-run with the support omitted
1833            // before the imprint, like a collapsed one. An apex-cap sphere
1834            // shares its cone's source id and is not judged here.
1835            //
1836            // Only the FIRST pass omits. A test point speaks for its fragment
1837            // because every other carrier's imprint bounds it; omitting a
1838            // carrier removes cuts, merges fragments and moves test points,
1839            // but changes no distance, so a support that reads shadowed only
1840            // AFTER an omission is reading a test point that no longer stands
1841            // for its fragment. Measured on two bosses 1 apart grown outward
1842            // by 1.5: once the facing boss walls were omitted, the plate's
1843            // grown top — one uncut fragment, mostly skin — read shadowed at
1844            // its single test point.
1845            //
1846            // "Every fragment" counts a fragment the selection would drop by
1847            // CLASS as not skin, as the selection does: the extended carrier's
1848            // surplus past a slot's end reads at least the distance from every
1849            // face, lies inside the source, and on a slot 1 wide grown outward
1850            // left the slot floor unjudged until the side walls were gone.
1851            // ADRIFT: a fragment whose test point is farther from its OWN face
1852            // than the distance, in the mitered metric, is not that face's skin
1853            // — it is inside the cavity, past where its neighbours' offsets cut
1854            // it. A rib, a pin or a divider thinner than 2d shelled inward
1855            // keeps such fragments, and the assembly then fails on them.
1856            let adrift = fragments_by_carrier[index]
1857                .iter()
1858                .map(|fragment| {
1859                    point_adrift_of_its_own_offset(
1860                        fragment.test_point,
1861                        carrier.source_face_id,
1862                        &retained_faces_with_edges,
1863                        distance,
1864                        offset_skin_tolerance,
1865                    )
1866                })
1867                .collect::<Vec<_>>();
1868            let mut skinless = readings
1869                .iter()
1870                .any(|reading| matches!(reading, SkinReading::Shadowed { .. }))
1871                || adrift.iter().any(|flag| *flag);
1872            for (fragment, reading) in fragments_by_carrier[index].iter().zip(&readings) {
1873                if !skinless {
1874                    break;
1875                }
1876                if matches!(reading, SkinReading::On)
1877                    && !adrift[fragments_by_carrier[index]
1878                        .iter()
1879                        .position(|other| std::ptr::eq(other, fragment))
1880                        .unwrap_or(0)]
1881                {
1882                    let class = classify_point(fragment.test_point, source, tolerance * 10.0).or_refuse(KernelStage::Sew, "classify_point")?.class;
1883                    skinless = (distance > 0.0 && class == PointClass::Out)
1884                        || (distance < 0.0 && class == PointClass::In);
1885                }
1886            }
1887            if skinless && !apex_cap_sources.contains(&index) {
1888                if !shadowed_supports.is_empty() {
1889                    let mut omitted = shadowed_supports.iter().copied().collect::<Vec<_>>();
1890                    omitted.sort_unstable();
1891                    return Err(KernelRefusal::unsupported(KernelStage::Select, "offset_shell_shadow_cascade", format!(
1892                        "offset_shell: omitting the shadowed offsets of source faces {omitted:?} \
1893                         leaves the offset of source face {} shadowed at every one of its {} \
1894                         fragment test points, which no longer stand for their fragments once \
1895                         those carriers stop cutting it",
1896                        carrier.source_face_id,
1897                        readings.len()
1898                    )));
1899                }
1900                os_debug!(
1901                    "  select[{index}] src={} SHADOWED over all {} fragment(s): {:?}",
1902                    carrier.source_face_id,
1903                    readings.len(),
1904                    readings
1905                );
1906                newly_shadowed.insert(carrier.source_face_id);
1907                continue;
1908            }
1909            // Partly shadowed: keep a bounded sample of the shadowed test
1910            // points, so a refusal can say where two offsets cross.
1911            for (fragment, reading) in fragments_by_carrier[index].iter().zip(&readings) {
1912                if shadowed_points.len() >= MAXIMUM_CROSSING_READS {
1913                    break;
1914                }
1915                if matches!(reading, SkinReading::Shadowed { .. }) {
1916                    shadowed_points.push((fragment.test_point, carrier.source_face_id));
1917                }
1918            }
1919            let on_skin = readings
1920                .iter()
1921                .zip(&adrift)
1922                .map(|(reading, adrift)| matches!(reading, SkinReading::On) && !adrift)
1923                .collect::<Vec<_>>();
1924            // A synthetic apex sphere has no source-face seed of its own to
1925            // fall back to. When its whole cap is hidden by retained offsets,
1926            // keep its cuts but contribute no skin. Otherwise the fallback
1927            // selects the uncut sphere as a stray patch inside the material.
1928            // The parent cone remains subject to the ordinary selection.
1929            let skin_filter_active = on_skin.iter().any(|flag| *flag)
1930                || apex_cap_pairs.iter().any(|(_, cap)| *cap == index);
1931            let opening_limits = if inward_extended_walls.is_empty() {
1932                Vec::new()
1933            } else {
1934                let openings = inward_extended_walls
1935                    .iter()
1936                    .map(|index| source_by_id[&carriers[*index].source_face_id])
1937                    .collect::<Vec<_>>();
1938                opening_trim_halfspaces(source_by_id[&carrier.source_face_id], &openings, tolerance)?
1939            };
1940            let mut classified = Vec::new();
1941            let mut viable = Vec::new();
1942            for (fragment_index, fragment) in fragments_by_carrier[index].iter().enumerate() {
1943                let class = classify_point(fragment.test_point, source, tolerance * 10.0).or_refuse(KernelStage::Sew, "classify_point")?.class;
1944                let excluded_by_class = (distance > 0.0 && class == PointClass::Out)
1945                    || (distance < 0.0 && class == PointClass::In);
1946                let contact = if excluded_by_class {
1947                    false
1948                } else {
1949                    distance > 0.0
1950                        && fragment_has_sustained_source_contact(
1951                            fragment,
1952                            &source_faces,
1953                            &assembly_sources,
1954                            &imprint,
1955                            2e-3f64.max(scale * 5e-5),
1956                        )?
1957                };
1958                os_debug!(
1959                    "  select[{index}.{fragment_index}] class={class:?} contact={contact} on_skin={} seed_in={:?} uv=({:.3},{:.3})",
1960                    on_skin[fragment_index],
1961                    parameter_point_in_face(&fragment_as_trim(fragment), seed, 1e-8),
1962                    fragment.test_uv.x, fragment.test_uv.y,
1963                );
1964                let past_opening = opening_limits.iter().any(|(origin, normal)| {
1965                    fragment.test_point.sub(*origin).dot(*normal) < -tolerance * 10.0
1966                });
1967                if excluded_by_class
1968                    || past_opening
1969                    || (skin_filter_active && !on_skin[fragment_index])
1970                {
1971                    continue;
1972                }
1973                classified.push(fragment.clone());
1974                if contact {
1975                    continue;
1976                }
1977                viable.push(fragment.clone());
1978            }
1979            // One skin per REGION of the source face (see `source_seeds`):
1980            // every region of a pinched face is offset like a face of its
1981            // own, and the selection below answers each region's seed. An
1982            // ordinary face has the one seed and the one answer it always had.
1983            let mut region_skins = Vec::new();
1984            for &seed in &seeds {
1985                os_debug!("  select[{index}] seed=({:.4},{:.4})", seed.x, seed.y);
1986                let seeded = viable
1987                    .iter()
1988                    .filter(|fragment| {
1989                        parameter_point_in_face(&fragment_as_trim(fragment), seed, 1e-8)
1990                            .is_ok_and(|class| class != PolygonClass::Outside)
1991                    })
1992                    .cloned()
1993                    .collect::<Vec<_>>();
1994                let seeded_classified = classified
1995                    .iter()
1996                    .filter(|fragment| {
1997                        parameter_point_in_face(&fragment_as_trim(fragment), seed, 1e-8)
1998                            .is_ok_and(|class| class != PolygonClass::Outside)
1999                    })
2000                    .cloned()
2001                    .collect::<Vec<_>>();
2002                let selected = if viable.is_empty() {
2003                    if !skin_filter_active {
2004                        // NOTHING on this carrier reads on-skin: every classified
2005                        // fragment's test point is measurably CLOSER than the
2006                        // offset distance to some retained face — a buried strip
2007                        // another carrier owns. Forcing the largest one in anyway
2008                        // plants a wrong skin patch that collides with the
2009                        // completion phase's reconstruction (3-use edges).
2010                        // Contribute nothing: `complete_opening_boundary_cycles`
2011                        // rebuilds the true skin from the carrier surface, and the
2012                        // watertight gate still refuses if it cannot.
2013                        None
2014                    } else {
2015                        let mut by_area = classified
2016                            .iter()
2017                            .cloned()
2018                            .map(|fragment| {
2019                                let area = parameter_space_area(&fragment_as_trim(&fragment)).or_refuse(KernelStage::Sew, "parameter_space_area")?.abs();
2020                                Ok((fragment, area))
2021                            })
2022                            .collect::<Result<Vec<_>, KernelRefusal>>()?;
2023                        by_area.sort_by(|a, b| b.1.total_cmp(&a.1));
2024                        by_area.into_iter().next().map(|entry| entry.0)
2025                    }
2026                } else if !seeded_classified.is_empty() {
2027                    let mut candidates = seeded_classified;
2028                    candidates.sort_by(|a, b| {
2029                        a.test_uv
2030                            .sub(seed)
2031                            .length()
2032                            .total_cmp(&b.test_uv.sub(seed).length())
2033                    });
2034                    candidates.into_iter().next()
2035                } else if viable.len() > 2 {
2036                    let mut by_area = viable
2037                        .iter()
2038                        .cloned()
2039                        .map(|fragment| {
2040                            let area = parameter_space_area(&fragment_as_trim(&fragment)).or_refuse(KernelStage::Sew, "parameter_space_area")?.abs();
2041                            Ok((fragment, area))
2042                        })
2043                        .collect::<Result<Vec<_>, KernelRefusal>>()?;
2044                    by_area.sort_by(|a, b| b.1.total_cmp(&a.1));
2045                    by_area.into_iter().next().map(|entry| entry.0)
2046                } else {
2047                    let mut candidates = if seeded.is_empty() { viable.clone() } else { seeded };
2048                    candidates.sort_by(|a, b| {
2049                        a.test_uv
2050                            .sub(seed)
2051                            .length()
2052                            .total_cmp(&b.test_uv.sub(seed).length())
2053                    });
2054                    candidates.into_iter().next()
2055                };
2056                if let Some(fragment) = &selected {
2057                    os_debug!(
2058                        "  select[{index}] src={} chosen test point departs its own face's offset \
2059                         distance by {:?}",
2060                        carrier.source_face_id,
2061                        own_offset_departure(
2062                            fragment.test_point,
2063                            carrier.source_face_id,
2064                            &retained_faces_with_edges,
2065                            distance
2066                        )
2067                    );
2068                    os_debug!(
2069                        "  select[{index}] src={} chosen test point departs in the MITER metric by {:?}",
2070                        carrier.source_face_id,
2071                        own_miter_departure(
2072                            fragment.test_point,
2073                            carrier.source_face_id,
2074                            &retained_faces_with_edges,
2075                            distance
2076                        )
2077                    );
2078                    if let Some((other, separation)) = coincident_offset_face(
2079                        fragment.test_point,
2080                        carrier.source_face_id,
2081                        &retained_faces_with_edges,
2082                        distance,
2083                        offset_skin_tolerance,
2084                    )? {
2085                        return Err(KernelRefusal::unsupported(KernelStage::Select, "offset_shell_coincident_offsets", format!(
2086                            "offset_shell: the offsets of source faces {} and {other} coincide near \
2087                             ({:.4}, {:.4}, {:.4}) — the material between those faces is twice the \
2088                             shell distance thick (separation {separation:.6} against {:.6}, band \
2089                             {offset_skin_tolerance:.1e}), so the cavity between them has no \
2090                             thickness there; a cavity pinched to zero thickness is not supported",
2091                            carrier.source_face_id,
2092                            fragment.test_point.x,
2093                            fragment.test_point.y,
2094                            fragment.test_point.z,
2095                            distance.abs(),
2096                        )));
2097                    }
2098                }
2099                if let Some(fragment) = selected {
2100                    // A pinched face's seeds each find their own region; a
2101                    // fallback that ignores the seed can answer the same
2102                    // fragment twice, and one skin must enter once.
2103                    if !region_skins
2104                        .iter()
2105                        .any(|other: &FaceFragmentRecord| {
2106                            other.test_point.sub(fragment.test_point).length() <= 1e-12
2107                        })
2108                    {
2109                        region_skins.push(fragment);
2110                    }
2111                }
2112            }
2113            if !inward_extended_walls.is_empty() && skin_filter_active {
2114                // The extended opening cuts beyond the source footprint.
2115                // Other finite carriers can subdivide a connected offset
2116                // region there (the box/revolve report splits both box caps
2117                // at x=1). A single source seed keeps only one of those cells.
2118                // Keep every cell already proved inside the source and on
2119                // the offset skin, then merge their shared boundaries.
2120                region_skins = classified;
2121            }
2122            chosen_offsets.extend(region_skins);
2123        } else if body == Body::Whole {
2124            // A HELD face of the offset body: its carrier is the face at
2125            // distance zero, cut by the neighbouring offset skins; the body
2126            // keeps the region the face's own seed lies in, whole. There is
2127            // no source rim to stop at and no void in front of it.
2128            for (fragment_index, fragment) in fragments_by_carrier[index].iter().enumerate() {
2129                if seeds.iter().any(|seed| {
2130                    parameter_point_in_face(&fragment_as_trim(fragment), *seed, 1e-8)
2131                        .is_ok_and(|class| class != PolygonClass::Outside)
2132                }) {
2133                    os_debug!("  held[{index}.{fragment_index}] kept: contains the face's seed");
2134                    chosen_walls.push(fragment.clone());
2135                }
2136            }
2137        } else {
2138            // Keep arrangement order stable. Besides making the result
2139            // reproducible, this matches the reference kernel's Set insertion
2140            // order when the final manifold-wall guard admits fragments.
2141            let opening = source_by_id[&carrier.source_face_id];
2142            let wall_seeds = opening_wall_seeds(
2143                opening,
2144                &split_carriers[index].shells[0].faces[0],
2145                source,
2146                &opening_set,
2147                distance,
2148            )?;
2149            // The wall-seed exemptions below rest on "the coplanar-rim weld
2150            // cuts the void hole later" — which only ever happens on PLANAR
2151            // opening carriers. A curved carrier (e.g. the sphere face used
2152            // directly as the opening) keeps its un-split fragment forever:
2153            // exempting it would seal the opening with the source face itself
2154            // and fabricate a closed hollow solid. Curved carriers therefore
2155            // get the strict void guard.
2156            let carrier_planar =
2157                surface_is_planar(&split_carriers[index].shells[0].faces[0].surface, tolerance)
2158                    .unwrap_or(false);
2159            let extended_inward = inward_extended_walls.contains(&index);
2160            let outside_source = |point| -> Result<bool, KernelRefusal> {
2161                Ok(extended_inward
2162                    && classify_point(point, source, tolerance * 10.0)
2163                        .or_refuse(KernelStage::Select, "classify_point")?.class == PointClass::Out)
2164            };
2165            let wall_on_skin = |point| {
2166                if extended_inward {
2167                    let inside_source = classify_point(point, source, tolerance * 10.0)
2168                        .or_refuse(KernelStage::Select, "classify_point")?.class == PointClass::In;
2169                    point_on_inward_opening_skin(
2170                        point,
2171                        &retained_faces_with_edges,
2172                        &reflex_wall_neighbors[&index],
2173                        inside_source,
2174                        distance,
2175                        offset_skin_tolerance,
2176                    )
2177                } else {
2178                    point_on_offset_skin(
2179                        point,
2180                        &retained_faces_with_edges,
2181                        distance,
2182                        offset_skin_tolerance,
2183                    )
2184                }
2185            };
2186            let mut selected_indices = Vec::new();
2187            for (fragment_index, fragment) in fragments_by_carrier[index].iter().enumerate() {
2188                if outside_source(fragment.test_point)? {
2189                    continue;
2190                }
2191                if parameter_point_in_face(&fragment_as_trim(fragment), seed, 1e-8).or_refuse(KernelStage::Sew, "parameter_point_in_face")?
2192                    == PolygonClass::Outside
2193                {
2194                    if in_front_of_other_opening(index, fragment.test_point)? {
2195                        os_debug!(
2196                            "  wall[{index}.{fragment_index}] skipped: in front of another \
2197                             opening at ({:.3},{:.3},{:.3})",
2198                            fragment.test_point.x,
2199                            fragment.test_point.y,
2200                            fragment.test_point.z,
2201                        );
2202                        continue;
2203                    }
2204                    // Wall = the material cross-section exposed at the
2205                    // opening: every point of a genuine wall fragment lies
2206                    // WITHIN the offset distance of some retained face (it is
2207                    // the thickness between that face and its offset skin). A
2208                    // fragment at ≥ distance from EVERY retained face — and
2209                    // containing no expected wall seed (an un-split cap
2210                    // fragment can span both the void AND the wall annulus;
2211                    // the coplanar-rim weld cuts its hole later) — is the
2212                    // core's own cross-section: a HOLE in the opening (e.g.
2213                    // the corner void where a carve's offset circle passes
2214                    // just inside the opening's corner). Welding it shut
2215                    // would fabricate a wall over the void.
2216                    if wall_on_skin(fragment.test_point)? && !(carrier_planar
2217                        && !extended_inward
2218                        && wall_seeds.iter().any(|wall_seed| {
2219                            parameter_point_in_face(&fragment_as_trim(fragment), *wall_seed, 1e-8)
2220                                .is_ok_and(|class| class != PolygonClass::Outside)
2221                        }))
2222                    {
2223                        os_debug!(
2224                            "  wall[{index}.{fragment_index}] skipped: void cross-section at \
2225                             ({:.3},{:.3},{:.3})",
2226                            fragment.test_point.x,
2227                            fragment.test_point.y,
2228                            fragment.test_point.z,
2229                        );
2230                        continue;
2231                    }
2232                    // A SURPLUS fragment beyond a sharp convex corner: it
2233                    // touches the wall's own outline, no edge of it was cut by
2234                    // the SOURCE (the rim every genuine wall region borders),
2235                    // and it holds no wall seed. The void test above reads it
2236                    // as material, because it measures a planar neighbour in the
2237                    // MITER metric (its extended plane, 0.277 from this region
2238                    // on the free-form D turning 83.7° at d = 0.3). The
2239                    // opening wall's clearance cuts such a region off between
2240                    // the carriers' tails past the mitre, and kept, it
2241                    // assembled as "non-integral genus" (8 of the D band's 42
2242                    // cells, 2026-09-26).
2243                    if distance < 0.0
2244                        && wall_surplus_beyond_the_sections(fragment, index as u8, |piece_id| {
2245                            imprint.pieces.iter().find(|piece| piece.id == piece_id).is_some_and(|piece| {
2246                                piece.support_faces.iter().any(|key| key.operand == SOURCE_OPERAND)
2247                            })
2248                        })
2249                        && !wall_seeds.iter().any(|wall_seed| {
2250                            parameter_point_in_face(&fragment_as_trim(fragment), *wall_seed, 1e-8)
2251                                .is_ok_and(|class| class != PolygonClass::Outside)
2252                        })
2253                    {
2254                        os_debug!(
2255                            "  wall[{index}.{fragment_index}] skipped: surplus beyond the sections at \
2256                             ({:.3},{:.3},{:.3}), touching the wall outline and no source rim",
2257                            fragment.test_point.x,
2258                            fragment.test_point.y,
2259                            fragment.test_point.z,
2260                        );
2261                        continue;
2262                    }
2263                    selected_indices.push(fragment_index);
2264                }
2265            }
2266            for wall_seed in wall_seeds {
2267                let fragments = &fragments_by_carrier[index];
2268                let nearest_containing = fragments
2269                    .iter()
2270                    .enumerate()
2271                    .filter(|(_, fragment)| {
2272                        parameter_point_in_face(&fragment_as_trim(fragment), wall_seed, 1e-8)
2273                            .is_ok_and(|class| class != PolygonClass::Outside)
2274                    })
2275                    .min_by(|(_, first), (_, second)| {
2276                        first
2277                            .test_uv
2278                            .sub(wall_seed)
2279                            .length()
2280                            .total_cmp(&second.test_uv.sub(wall_seed).length())
2281                    })
2282                    .map(|(fragment_index, _)| fragment_index);
2283                // Arrangement fitting can leave the seed just outside every
2284                // fragment by a small amount. Match the reference kernel's
2285                // geometric fallback instead of silently omitting the wall
2286                // fragment and leaving the assembled shell open.
2287                let nearest = if nearest_containing.is_some() {
2288                    nearest_containing
2289                } else {
2290                    let seed_point = split_carriers[index].shells[0].faces[0]
2291                        .surface
2292                        .evaluate(wall_seed.x, wall_seed.y).or_refuse(KernelStage::Sew, "evaluate")?;
2293                    fragments
2294                        .iter()
2295                        .enumerate()
2296                        .min_by(|(_, first), (_, second)| {
2297                            first
2298                                .test_point
2299                                .sub(seed_point)
2300                                .length()
2301                                .total_cmp(&second.test_point.sub(seed_point).length())
2302                        })
2303                        .map(|(fragment_index, _)| fragment_index)
2304                };
2305                if let Some(fragment_index) = nearest {
2306                    let candidate = &fragments_by_carrier[index][fragment_index];
2307                    if outside_source(candidate.test_point)?
2308                        || in_front_of_other_opening(index, candidate.test_point)?
2309                    {
2310                        continue;
2311                    }
2312                    // Void-cross-section guard. On a PLANAR carrier it applies
2313                    // to the GEOMETRIC FALLBACK only: a fragment that
2314                    // genuinely contains this wall seed is wall content by
2315                    // construction (even when un-split it also spans void —
2316                    // the rim weld cuts the hole later), but a merely-nearest
2317                    // fragment must not resurrect a hole in the opening. On a
2318                    // CURVED carrier no later weld cuts the hole, so even a
2319                    // seed-containing fragment gets the strict guard.
2320                    // Extended inward walls are cut by the source as well:
2321                    // a seed must not resurrect the opposite side of a
2322                    // reflex rim merely because its unsigned distance is small.
2323                    if (nearest_containing.is_none() || !carrier_planar || extended_inward)
2324                        && wall_on_skin(candidate.test_point)?
2325                    {
2326                        os_debug!(
2327                            "  wall[{index}.{fragment_index}] seed-hit skipped: void \
2328                             cross-section (planar={carrier_planar}) at ({:.3},{:.3},{:.3})",
2329                            candidate.test_point.x,
2330                            candidate.test_point.y,
2331                            candidate.test_point.z,
2332                        );
2333                        continue;
2334                    }
2335                    let existing = chosen_offsets.iter().cloned().chain(
2336                        selected_indices
2337                            .iter()
2338                            .map(|selected| fragments_by_carrier[index][*selected].clone()),
2339                    );
2340                    if !selected_indices.contains(&fragment_index)
2341                        && !would_overuse_existing_boundary(
2342                            candidate,
2343                            existing,
2344                            &assembly_sources,
2345                            &imprint,
2346                            2e-3,
2347                        )?
2348                    {
2349                        selected_indices.push(fragment_index);
2350                    }
2351                }
2352            }
2353            for fragment_index in selected_indices.iter().copied() {
2354                let mut fragment = fragments_by_carrier[index][fragment_index].clone();
2355                // Past a reflex rim the wall closes the cavity on the other
2356                // side of the opening plane, so its normal reverses too.
2357                if extended_inward
2358                    && classify_point(fragment.test_point, source, tolerance * 10.0)
2359                        .or_refuse(KernelStage::Select, "classify_point")?.class == PointClass::In
2360                {
2361                    flip_fragment(&mut fragment)?;
2362                }
2363                chosen_walls.push(fragment);
2364            }
2365        }
2366    }
2367    if debug_enabled() {
2368        for fragment in &chosen_offsets {
2369            os_debug!(
2370                "chosen offset: operand={} src={} test=({:.3},{:.3},{:.3})",
2371                fragment.operand,
2372                carriers[fragment.operand as usize].source_face_id,
2373                fragment.test_point.x,
2374                fragment.test_point.y,
2375                fragment.test_point.z,
2376            );
2377            for (loop_index, loop_record) in fragment.loops.iter().enumerate() {
2378                for coedge in &loop_record.coedges {
2379                    let surface = &fragment.surface;
2380                    let [c0, c1] = coedge.pcurve.domain().unwrap_or([0.0, 0.0]);
2381                    let uv0 = coedge.pcurve.evaluate(c0);
2382                    let uv1 = coedge.pcurve.evaluate(c1);
2383                    if let (Ok(uv0), Ok(uv1)) = (uv0, uv1) {
2384                        let p0 = surface.evaluate(uv0.x, uv0.y);
2385                        let p1 = surface.evaluate(uv1.x, uv1.y);
2386                        if let (Ok(p0), Ok(p1)) = (p0, p1) {
2387                            let kind = match &coedge.source {
2388                                FragmentEdgeSource::Boundary { edge_id, .. } => {
2389                                    format!("bnd:{edge_id}")
2390                                }
2391                                FragmentEdgeSource::SharedBoundary { edge_id, .. } => {
2392                                    format!("sbnd:{edge_id}")
2393                                }
2394                                FragmentEdgeSource::Imprint { piece_id } => {
2395                                    format!("imp:{piece_id}")
2396                                }
2397                                FragmentEdgeSource::Derived { .. } => "derived".to_string(),
2398                            };
2399                            os_debug!(
2400                                "    loop{loop_index} {kind} ({:.4},{:.4},{:.4})..({:.4},{:.4},{:.4})",
2401                                p0.x, p0.y, p0.z, p1.x, p1.y, p1.z,
2402                            );
2403                        }
2404                    }
2405                }
2406            }
2407        }
2408        for fragment in &chosen_walls {
2409            os_debug!(
2410                "chosen wall: operand={} src={} test=({:.3},{:.3},{:.3})",
2411                fragment.operand,
2412                carriers[fragment.operand as usize].source_face_id,
2413                fragment.test_point.x,
2414                fragment.test_point.y,
2415                fragment.test_point.z,
2416            );
2417        }
2418    }
2419    if !newly_shadowed.is_empty() {
2420        let mut omitted = shadowed_supports.clone();
2421        omitted.extend(newly_shadowed.iter().copied());
2422        os_debug!(
2423            "re-running without shadowed offset supports {:?} (omitted before: {:?})",
2424            newly_shadowed,
2425            shadowed_supports
2426        );
2427        // What this pass sampled belongs to carriers the next pass may not
2428        // build.
2429        shadowed_points.clear();
2430        profile::lap(&mut clock, profile::SELECT);
2431        return offset_shell_impl(
2432            source,
2433            opening_face_ids,
2434            distance,
2435            body,
2436            extend_oblique_carriers,
2437            extension_fired,
2438            reflex_rebuilds,
2439            &omitted,
2440            shadowed_points,
2441            omitted_supports,
2442            vacated_notes,
2443        );
2444    }
2445    if chosen_offsets.is_empty() && !shadowed_supports.is_empty() {
2446        let mut omitted = shadowed_supports.iter().copied().collect::<Vec<_>>();
2447        omitted.sort_unstable();
2448        return Err(KernelRefusal::unsupported(KernelStage::Select, "offset_shell_all_shadowed", format!(
2449            "offset_shell: no retained face keeps any offset skin once the shadowed offsets of \
2450             source faces {omitted:?} are omitted — the solid is nowhere thicker than twice the \
2451             shell distance, so there is no cavity to shell"
2452        )));
2453    }
2454    if chosen_offsets.is_empty() {
2455        return Err(KernelRefusal::internal(KernelStage::Select, "offset_shell_no_boundary", "offset_shell: carrier intersections produced no offset boundary"));
2456    }
2457    // Opening-wall fragments can overlap at dense carrier junctions. The
2458    // seed-time guard above handles geometric containment; this final pass
2459    // mirrors the topology-level rule and counts exact fragment edge sources.
2460    let mut boundary_use_count = HashMap::<[i64; 9], usize>::default();
2461    for fragment in &chosen_offsets {
2462        for coedge in fragment
2463            .loops
2464            .iter()
2465            .flat_map(|loop_record| &loop_record.coedges)
2466        {
2467            let key = fragment_edge_segment_key(&coedge.source, &assembly_sources, &imprint)?;
2468            *boundary_use_count.entry(key).or_default() += 1;
2469        }
2470    }
2471    let mut manifold_walls = Vec::new();
2472    for fragment in chosen_walls {
2473        let keys = fragment
2474            .loops
2475            .iter()
2476            .flat_map(|loop_record| &loop_record.coedges)
2477            .map(|coedge| fragment_edge_segment_key(&coedge.source, &assembly_sources, &imprint))
2478            .collect::<Result<Vec<_>, _>>()?;
2479        if !keys
2480            .iter()
2481            .any(|key| boundary_use_count.get(key).copied().unwrap_or(0) >= 2)
2482        {
2483            for key in keys {
2484                *boundary_use_count.entry(key).or_default() += 1;
2485            }
2486            manifold_walls.push(fragment);
2487        }
2488    }
2489    os_debug!(
2490        "manifold walls kept: {} operands={:?}",
2491        manifold_walls.len(),
2492        manifold_walls
2493            .iter()
2494            .map(|fragment| fragment.operand)
2495            .collect::<Vec<_>>(),
2496    );
2497    let chosen_walls = manifold_walls;
2498
2499    profile::lap(&mut clock, profile::SELECT);
2500    let stage_clock = web_time::Instant::now();
2501    // The offset BODY has no source face in it: it is the skins (and the held
2502    // faces) alone, oriented as the source is, so nothing is flipped either.
2503    let source_fragments = if body == Body::Whole {
2504        Vec::new()
2505    } else {
2506        fragment_solid(source, SOURCE_OPERAND, &empty_imprint())?
2507    };
2508    os_debug!("stage: source fragments {:.3}s", stage_clock.elapsed().as_secs_f64());
2509    let mut selected = source_fragments
2510        .into_iter()
2511        .filter(|fragment| retained.contains(&fragment.source_face_id))
2512        .collect::<Vec<_>>();
2513    let mut face_images = selected
2514        .iter()
2515        .map(|fragment| OffsetShellFaceImageRecord {
2516            role: OffsetFaceRole::Source,
2517            source_face_id: fragment.source_face_id,
2518        })
2519        .collect::<Vec<_>>();
2520    if distance < 0.0 {
2521        for fragment in &mut selected {
2522            flip_fragment(fragment)?;
2523        }
2524    }
2525    if distance > 0.0 && body == Body::Shell {
2526        for fragment in &mut chosen_offsets {
2527            flip_fragment(fragment)?;
2528        }
2529    }
2530    face_images.extend(
2531        chosen_offsets
2532            .iter()
2533            .map(|fragment| OffsetShellFaceImageRecord {
2534                role: OffsetFaceRole::Offset,
2535                source_face_id: carriers[fragment.operand as usize].source_face_id,
2536            }),
2537    );
2538    face_images.extend(
2539        chosen_walls
2540            .iter()
2541            .map(|fragment| OffsetShellFaceImageRecord {
2542                role: OffsetFaceRole::Wall,
2543                source_face_id: carriers[fragment.operand as usize].source_face_id,
2544            }),
2545    );
2546    selected.extend(chosen_offsets);
2547    selected.extend(chosen_walls);
2548    let mut solid = assemble_open_fragments(
2549        selected,
2550        &assembly_sources,
2551        &imprint,
2552        2e-3f64.max(scale * 5e-5),
2553    )?;
2554    os_debug!("stage: assembled open fragments {:.3}s", stage_clock.elapsed().as_secs_f64());
2555    orient_open_solid_faces(&mut solid)?;
2556    os_debug!("stage: oriented {:.3}s", stage_clock.elapsed().as_secs_f64());
2557    let connector_images = complete_sharp_offset_connectors(
2558        &mut solid,
2559        source,
2560        &face_images,
2561        distance,
2562        2e-3f64.max(scale * 5e-5),
2563    )?;
2564    os_debug!(
2565        "sharp connector completion added {} faces ({:.3}s)",
2566        connector_images.len(),
2567        stage_clock.elapsed().as_secs_f64()
2568    );
2569    if !connector_images.is_empty() {
2570        // Wall fragments were arranged before the sharp seam was closed, so
2571        // their prospective inner boundary was an open chain. Rebuild the
2572        // wall from the now-closed source/offset cycles instead of retaining
2573        // that pre-connector fragment.
2574        for shell in &mut solid.shells {
2575            shell.faces.retain(|face| {
2576                !matches!(
2577                    face_images
2578                        .get(face.id.saturating_sub(1) as usize)
2579                        .map(|image| image.role),
2580                    Some(OffsetFaceRole::Wall)
2581                )
2582            });
2583        }
2584        solid.shells.retain(|shell| !shell.faces.is_empty());
2585    }
2586    face_images.extend(connector_images);
2587    orient_open_solid_faces(&mut solid)?;
2588    // Weld curved-face offset rims that the wall fragmentation left orphaned
2589    // into their coplanar opening cap (cylinder / straight-hole shells). This
2590    // is the seam-rim consistency step the offset pipeline previously lacked.
2591    let welded_rims = weld_coplanar_orphan_rims(&mut solid, 2e-3f64.max(scale * 5e-5))?;
2592    os_debug!("welded {welded_rims} coplanar orphan rims into opening caps");
2593    // A rim that is not a circle: a free-form or non-iso rim whose offset image
2594    // falls short of the opening. It runs after every earlier weld because it
2595    // only ever sees rims none of them closed.
2596    let rim_band = weld_free_form_rim_bands(
2597        &mut solid,
2598        &mut face_images,
2599        &carriers,
2600        source,
2601        2e-3f64.max(scale * 5e-5),
2602    )?;
2603    let rim_bands = rim_band.welded;
2604    os_debug!("welded {rim_bands} free-form rim bands");
2605    // Weld leftover coaxial coplanar rim PAIRS (a through-hole's exposed wall
2606    // thickness at each opening) into new planar annulus faces.
2607    let pair_rims =
2608        weld_coplanar_rim_pair_annuli(&mut solid, &mut face_images, 2e-3f64.max(scale * 5e-5))?;
2609    os_debug!("welded {pair_rims} coplanar rim pairs into annulus walls");
2610    if debug_enabled() {
2611        for (shell_index, shell) in solid.shells.iter().enumerate() {
2612            for face in &shell.faces {
2613                os_debug!(
2614                    "POSTWELD shell {} face {} same_sense={} loops={}",
2615                    shell_index,
2616                    face.id,
2617                    face.same_sense,
2618                    face.loops.len()
2619                );
2620                for (loop_index, loop_record) in face.loops.iter().enumerate() {
2621                    let walk = loop_record
2622                        .coedges
2623                        .iter()
2624                        .map(|coedge| {
2625                            let spin = (|| -> Result<f64, KernelRefusal> {
2626                                let [d0, d1] = coedge.pcurve.domain().or_refuse(KernelStage::Sew, "domain")?;
2627                                let a = coedge.pcurve.evaluate(d0 + (d1 - d0) * 0.45).or_refuse(KernelStage::Sew, "evaluate")?;
2628                                let b = coedge.pcurve.evaluate(d0 + (d1 - d0) * 0.55).or_refuse(KernelStage::Sew, "evaluate")?;
2629                                let pa = face.surface.evaluate(a.x, a.y).or_refuse(KernelStage::Sew, "evaluate")?;
2630                                let pb = face.surface.evaluate(b.x, b.y).or_refuse(KernelStage::Sew, "evaluate")?;
2631                                Ok(pa.cross(pb).z)
2632                            })()
2633                            .unwrap_or(f64::NAN);
2634                            format!(
2635                                "{}{}(spin{:+.0})",
2636                                if coedge.forward { "+" } else { "-" },
2637                                coedge.edge_id,
2638                                spin.signum()
2639                            )
2640                        })
2641                        .collect::<Vec<_>>();
2642                    os_debug!("    loop {} {:?}", loop_index, walk);
2643                }
2644            }
2645        }
2646    }
2647    let completion_carriers = carriers.iter().collect::<Vec<_>>();
2648    let completion_tolerance = 2e-3f64.max(scale * 5e-5);
2649    // Unify geometric duplicate arc records BEFORE completion: a ring that is
2650    // already covered by both its faces (frustum + apex cap) must not read as
2651    // an open boundary, or completion papers over it with duplicate faces.
2652    let duplicate_welds = weld_duplicate_one_use_arcs(&mut solid, completion_tolerance)?;
2653    os_debug!("welded {duplicate_welds} duplicate one-use boundary arcs");
2654    if debug_enabled() {
2655        let mut use_counts = HashMap::<u64, usize>::default();
2656        for coedge in solid
2657            .shells
2658            .iter()
2659            .flat_map(|shell| &shell.faces)
2660            .flat_map(|face| &face.loops)
2661            .flat_map(|loop_record| &loop_record.coedges)
2662        {
2663            *use_counts.entry(coedge.edge_id).or_default() += 1;
2664        }
2665        let open = use_counts.values().filter(|count| **count == 1).count();
2666        os_debug!(
2667            "assembled: faces={} open_edges={open}",
2668            solid
2669                .shells
2670                .iter()
2671                .map(|shell| shell.faces.len())
2672                .sum::<usize>()
2673        );
2674    }
2675    let completed_images = complete_opening_boundary_cycles(
2676        &mut solid,
2677        &completion_carriers,
2678        &face_images,
2679        completion_tolerance,
2680    )?;
2681    os_debug!("completion added {} faces", completed_images.len());
2682    face_images.extend(completed_images);
2683    let solid = merge_same_surface_faces_open(&solid, (1e-7f64).max(scale * 1e-9))?;
2684    let assembly_tolerance = 2e-3f64.max(scale * 5e-5);
2685    // No faceted fallback here: an offset shell must be made of real analytic
2686    // surfaces. Failing loudly beats silently returning a tessellated BREP
2687    // with destroyed face provenance.
2688    // A shell the rim band lane recognized but could not close fails here as it
2689    // always did; the refusal now carries the lane's reason.
2690    let mut solid = finalize_assembled_solid(solid, assembly_tolerance).map_err(|error| {
2691        match &rim_band.decline {
2692            Some(reason) => error.with_message(|message| format!("{message}; offset_shell: {reason}")),
2693            None => error,
2694        }
2695    })?;
2696    crate::offset_retrim::reconstruct_analytic_shell(&mut solid)?;
2697    if rim_bands + pair_rims > 0 || !inward_extended_walls.is_empty() {
2698        // Rim welds and extended reflex walls join independently-oriented skins;
2699        // put the whole finalized manifold on one normal convention so the
2700        // shell reports its exact wall volume (coplanar-only shells keep
2701        // their assembled sense).
2702        coheres_face_normals(&mut solid)?;
2703    }
2704    let solid = solid;
2705    profile::lap(&mut clock, profile::ASSEMBLY);
2706    face_images = solid
2707        .shells
2708        .iter()
2709        .flat_map(|shell| &shell.faces)
2710        .map(|face| {
2711            face_images
2712                .get(face.id.saturating_sub(1) as usize)
2713                .cloned()
2714                .ok_or_else(|| "offset_shell: merged face lost provenance".to_string())
2715        })
2716        .collect::<Result<Vec<_>, _>>().or_refuse(KernelStage::Sew, "offset_shell_merged_face_lost_provenance")?;
2717    // A bore's end ring carries the bore wall's provenance whichever
2718    // construction built it (the opening's fragmentation or the rim-pair
2719    // weld), so its name does not depend on the path the rims took.
2720    let bore_rings = claim_bore_end_rings(&solid, &mut face_images)?;
2721    os_debug!("{bore_rings} bore end rings took the bore wall's provenance");
2722    // Honesty gate: a real rim left one-use is a hole in the shell that the
2723    // degenerate marking hides from `validate()` (degenerate edges are allowed
2724    // to be face-local). Refuse such a result instead of shipping a
2725    // non-watertight solid as valid. A rim is a CLOSED edge whose interior
2726    // sweeps measurably away from its seam vertex — a genuine circle, not a
2727    // legitimate pole point placeholder (which stays one-use by design).
2728    let mut rim_use_counts = HashMap::<u64, usize>::default();
2729    for coedge in solid
2730        .shells
2731        .iter()
2732        .flat_map(|shell| &shell.faces)
2733        .flat_map(|face| &face.loops)
2734        .flat_map(|loop_record| &loop_record.coedges)
2735    {
2736        *rim_use_counts.entry(coedge.edge_id).or_default() += 1;
2737    }
2738    if debug_enabled() {
2739        for (shell_index, shell) in solid.shells.iter().enumerate() {
2740            for face in &shell.faces {
2741                let role = face_images
2742                    .get(face.id.saturating_sub(1) as usize)
2743                    .map(|image| image.role);
2744                let c = face.surface.evaluate(0.5, 0.5).unwrap_or_default();
2745                os_debug!(
2746                    "DUMPFACE shell {} face {} affine={} role={:?} loops={} center=({:.3},{:.3},{:.3})",
2747                    shell_index, face.id, face.surface.is_affine().unwrap_or(false), role,
2748                    face.loops.len(), c.x, c.y, c.z
2749                );
2750                for (li, lp) in face.loops.iter().enumerate() {
2751                    let ids = lp.coedges.iter().map(|c| c.edge_id).collect::<Vec<_>>();
2752                    os_debug!("    loop {} edges {:?}", li, ids);
2753                }
2754            }
2755        }
2756        for edge in &solid.edges {
2757            let uses = rim_use_counts.get(&edge.id).copied().unwrap_or(0);
2758            let s = edge.curve.evaluate(edge.t0).or_refuse(KernelStage::Sew, "evaluate")?;
2759            let m = edge.curve.evaluate((edge.t0 + edge.t1) * 0.5).or_refuse(KernelStage::Sew, "evaluate")?;
2760            let q = edge.curve.evaluate(edge.t0 + (edge.t1 - edge.t0) * 0.25).or_refuse(KernelStage::Sew, "evaluate")?;
2761            os_debug!(
2762                "DUMPEDGE edge {} uses={} closed={} deg={} cpts={} cdeg={} knots={:?} start=({:.3},{:.3},{:.3}) q=({:.3},{:.3},{:.3}) mid=({:.3},{:.3},{:.3})",
2763                edge.id, uses, edge.start_vertex_id == edge.end_vertex_id, edge.degenerate,
2764                edge.curve.control_points.len(), edge.curve.degree, edge.curve.knots,
2765                s.x, s.y, s.z, q.x, q.y, q.z, m.x, m.y, m.z
2766            );
2767        }
2768    }
2769    for edge in &solid.edges {
2770        if rim_use_counts.get(&edge.id).copied().unwrap_or(0) != 1
2771            || edge.start_vertex_id != edge.end_vertex_id
2772        {
2773            continue;
2774        }
2775        let anchor = edge.curve.evaluate(edge.t0).or_refuse(KernelStage::Sew, "evaluate")?;
2776        let sweep_threshold = 1e-4f64.max(scale * 1e-6);
2777        let sweeps = [0.25, 0.5, 0.75].into_iter().any(|fraction| {
2778            edge.curve
2779                .evaluate(edge.t0 + (edge.t1 - edge.t0) * fraction)
2780                .map(|point| point.sub(anchor).length() > sweep_threshold)
2781                .unwrap_or(false)
2782        });
2783        if sweeps {
2784            if debug_enabled() {
2785                let rim_mid = edge.curve.evaluate((edge.t0 + edge.t1) * 0.5).or_refuse(KernelStage::Sew, "evaluate")?;
2786                os_debug!(
2787                    "PROBE orphan rim edge {} anchor=({:.4},{:.4},{:.4}) mid=({:.4},{:.4},{:.4})",
2788                    edge.id,
2789                    anchor.x,
2790                    anchor.y,
2791                    anchor.z,
2792                    rim_mid.x,
2793                    rim_mid.y,
2794                    rim_mid.z
2795                );
2796                for (shell_index, shell) in solid.shells.iter().enumerate() {
2797                    for face in &shell.faces {
2798                        let uses_rim = face
2799                            .loops
2800                            .iter()
2801                            .flat_map(|l| &l.coedges)
2802                            .any(|c| c.edge_id == edge.id);
2803                        let affine = face.surface.is_affine().unwrap_or(false);
2804                        let on = edge_on_surface(edge, &face.surface, 2e-3f64.max(scale * 5e-5))
2805                            .unwrap_or(false);
2806                        let proj = project_point_to_surface(&face.surface, rim_mid).or_refuse(KernelStage::Sew, "project_point_to_surface")?;
2807                        let contains = if on {
2808                            parameter_point_in_face(
2809                                face,
2810                                Vec2 {
2811                                    x: proj.u,
2812                                    y: proj.v,
2813                                },
2814                                2e-3f64.max(scale * 5e-5),
2815                            ).or_refuse(KernelStage::Sew, "parameter_point_in_face")? != PolygonClass::Outside
2816                        } else {
2817                            false
2818                        };
2819                        if on || uses_rim {
2820                            os_debug!(
2821                                "  face {} shell {} affine={} uses_rim={} on_surf={} proj_dist={:.5} contains={}",
2822                                face.id, shell_index, affine, uses_rim, on, proj.distance, contains
2823                            );
2824                        }
2825                    }
2826                }
2827            }
2828            return Err(refusals::unwelded_curved_rim(edge.id, anchor).into());
2829        }
2830    }
2831    // The shell's single exit. An offset skin that crosses another wall, or
2832    // folds through itself where the source turned tighter than the distance,
2833    // leaves a body that validates and measures — so it is asked here, and
2834    // repaired or refused by name rather than returned.
2835    let mut solid = solid;
2836    // Face-local rim construction and planar merging can reuse wire IDs.
2837    // Reserve every existing ID, then replace only duplicates so the completed
2838    // body can cross the arena/buffer ingestion boundary. These IDs have no
2839    // external references; face/edge identities and provenance stay intact.
2840    let mut loop_ids = HashSet::default();
2841    let mut coedge_ids = HashSet::default();
2842    for face in solid.shells.iter().flat_map(|shell| &shell.faces) {
2843        for wire in &face.loops {
2844            loop_ids.insert(wire.id);
2845            coedge_ids.extend(wire.coedges.iter().map(|coedge| coedge.id));
2846        }
2847    }
2848    let mut seen_loops = HashSet::default();
2849    let mut seen_coedges = HashSet::default();
2850    let mut next_loop = 1;
2851    let mut next_coedge = 1;
2852    for face in solid.shells.iter_mut().flat_map(|shell| &mut shell.faces) {
2853        for wire in &mut face.loops {
2854            if !seen_loops.insert(wire.id) {
2855                while !loop_ids.insert(next_loop) { next_loop += 1; }
2856                wire.id = next_loop;
2857            }
2858            for coedge in &mut wire.coedges {
2859                if !seen_coedges.insert(coedge.id) {
2860                    while !coedge_ids.insert(next_coedge) { next_coedge += 1; }
2861                    coedge.id = next_coedge;
2862                }
2863            }
2864        }
2865    }
2866    let solid = super::acceptance::accept_offset_result(solid)?;
2867    profile::lap(&mut clock, profile::ACCEPTANCE);
2868    Ok(OffsetShellResultRecord { solid, face_images })
2869}
2870
2871/// Run offset shell with stable counters and validation diagnostics suitable
2872/// for automated regressions and UI presentation.
2873pub fn offset_shell_with_diagnostics(
2874    source: &BrepSolid,
2875    opening_face_ids: &[u64],
2876    distance: f64,
2877    tolerances: Option<KernelTolerances>,
2878) -> Result<KernelOutcome<OffsetShellResultRecord>, KernelRefusal> {
2879    let policy = tolerances.unwrap_or_else(|| KernelTolerances::for_solid(source, 1e-7));
2880    policy.check().or_refuse(KernelStage::Sew, "check")?;
2881    let mut diagnostics = KernelDiagnostics::default();
2882    diagnostics.count_n(
2883        "collect.source_faces",
2884        source
2885            .shells
2886            .iter()
2887            .map(|shell| shell.faces.len() as u64)
2888            .sum(),
2889    );
2890    diagnostics.count_n("collect.opening_faces", opening_face_ids.len() as u64);
2891    diagnostics.measure_max("offset.distance", distance.abs());
2892    diagnostics.measure_max("tolerance.model", policy.model);
2893    // Tally every pcurve fit the shell makes (its own re-trims and any boolean
2894    // it runs) so `pcurve.unmet_floor` reports a trim that stopped at the
2895    // sample ceiling instead of passing it off as one that met the floor.
2896    let fit_scope = crate::PcurveFitScope::open();
2897    // Same for the polyline fits of its carrier×carrier sections, which is
2898    // where a marched rim's accuracy is decided (`geometry/fit.rs`).
2899    let polyline_scope = crate::PolylineFitScope::open();
2900    let result = offset_shell(source, opening_face_ids, distance)?;
2901    fit_scope.close().report_into(&mut diagnostics);
2902    polyline_scope.close().report_into(&mut diagnostics);
2903    // The phase split of the run that just finished (`profile.rs`), in the
2904    // boolean's `timing.<phase>_ms` shape so one reader serves both.
2905    let timings = profile::snapshot();
2906    diagnostics.count_n("shell.attempts", timings.attempts);
2907    for (phase, count) in &timings.carriers {
2908        diagnostics.count_n(format!("shell.{phase}"), *count);
2909    }
2910    for (phase, ms) in &timings.ms {
2911        diagnostics.measure_max(format!("timing.{phase}_ms"), *ms);
2912    }
2913    diagnostics.count_n(
2914        "sew.output_faces",
2915        result
2916            .solid
2917            .shells
2918            .iter()
2919            .map(|shell| shell.faces.len() as u64)
2920            .sum(),
2921    );
2922    diagnostics.count_n("sew.face_images", result.face_images.len() as u64);
2923    let validation = result.solid.validate_detailed(&policy);
2924    diagnostics.measure_max("validate.max_pcurve_error", validation.max_pcurve_error);
2925    diagnostics.count_n("validate.issues", validation.issues.len() as u64);
2926    diagnostics.count_n(
2927        "validate.wire_warnings",
2928        validation.wire_warnings.len() as u64,
2929    );
2930    for warning in validation.wire_warnings {
2931        diagnostics.event(
2932            DiagnosticSeverity::Warning,
2933            KernelStage::Validate,
2934            "validate.uv_wire",
2935            warning.message,
2936        );
2937    }
2938    if !validation.issues.is_empty() {
2939        for issue in &validation.issues {
2940            diagnostics.event(
2941                DiagnosticSeverity::Error,
2942                KernelStage::Validate,
2943                "validate.brep",
2944                issue.message.clone(),
2945            );
2946        }
2947        return Err(KernelRefusal::internal(KernelStage::Validate, "offset_shell_diagnostic_result", format!(
2948            "offset_shell: invalid diagnostic result: {:?}",
2949            validation.issues
2950        )));
2951    }
2952    Ok(KernelOutcome {
2953        value: result,
2954        diagnostics,
2955    })
2956}
2957
2958/// Whether a wall fragment lies wholly in the wall's surplus: it has an edge on
2959/// the wall carrier's own outline (`Boundary` of operand `wall_operand`) and no
2960/// edge imprinted by the SOURCE solid, whose rim every genuine opening-wall
2961/// region borders. `cut_by_source` answers whether an imprint piece has the
2962/// source among its two support faces.
2963pub(super) fn wall_surplus_beyond_the_sections(
2964    fragment: &FaceFragmentRecord,
2965    wall_operand: u8,
2966    cut_by_source: impl Fn(u64) -> bool,
2967) -> bool {
2968    let mut on_outline = false;
2969    for coedge in fragment.loops.iter().flat_map(|record| &record.coedges) {
2970        match &coedge.source {
2971            FragmentEdgeSource::Boundary { operand, .. } if *operand == wall_operand => on_outline = true,
2972            FragmentEdgeSource::Boundary { operand, .. } | FragmentEdgeSource::SharedBoundary { operand, .. }
2973                if *operand == SOURCE_OPERAND =>
2974            {
2975                return false;
2976            }
2977            FragmentEdgeSource::Imprint { piece_id } => {
2978                if cut_by_source(*piece_id) {
2979                    return false;
2980                }
2981            }
2982            _ => {}
2983        }
2984    }
2985    on_outline
2986}
2987