1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
//! Geometric helpers for [`super::intersection_solid`]: enclosed volume of a
//! triangle soup, connected-component partitioning of the kernel's raw
//! arrangement output, and the per-operand near-band used to size the trust
//! gate. Split out of `clash_solid.rs` so that file stays under the
//! module-size rule; `intersection_solid` itself, and the reasoning for HOW
//! these are used, stays there.
use cratedot3;
use crateTri;
use crateNearBand;
use crateMesh;
/// Enclosed volume of a closed f64 triangle soup (divergence theorem).
pub
/// Partitions `tris` into disjoint connected components by shared-vertex
/// adjacency, returning each component as a list of indices into `tris`.
///
/// Two triangles are in the same component iff they share a vertex at the
/// exact same f64 bit pattern — the same equality the welding step in
/// [`intersection_solid`](super::intersection_solid) already keys on, since
/// the kernel's arrangement output shares vertex coordinates exactly between
/// adjacent triangles rather than rounding them independently. A single
/// clashing pair's exact boolean can legitimately produce more than one such
/// component (e.g. a non-convex operand overlapping the other in two
/// separate places), and each is its own solid with its own thinnest extent
/// — see the thickness gate's comment in `intersection_solid` for why
/// pooling them together was wrong.
///
/// # Known limitation: shared-VERTEX, not shared-EDGE, is a coarser notion
/// of connectedness than "one overlap region" (PR #2573 review)
///
/// Two triangles that touch at a single bit-identical vertex — no shared
/// edge — are unioned into one component here, even when they are otherwise
/// two disjoint overlap regions that merely snap to a common point (e.g. a
/// 0.1 mm sliver and a 10 m-scale triangle pinned together at one corner,
/// `clash_solid_tests::two_triangles_sharing_only_one_vertex_are_still_
/// pooled_into_one_component_a_known_limitation`). Merged that way, the
/// gate's per-component extent loop pools their bounding boxes into a span
/// as large as the operands themselves — structurally the same
/// pooled-bounding-box overshoot that
/// `two_disjoint_below_band_slivers_are_withheld_not_pooled_into_one_
/// bounding_box` (`clash_intersection_oracle.rs`) was written to close for
/// full disjointness, reached here instead via a shared touching vertex.
///
/// This is left unfixed rather than reflex-fixed to shared-EDGE adjacency
/// (the standard notion of surface connectedness), for two reasons:
///
/// 1. **Not shown reachable through the public API.** The 25-case
/// `clash_intersection_oracle` suite, and direct attempts to construct two
/// disjoint overlap wedges that snap to a shared vertex through
/// `intersection_solid`, did not produce this arrangement — only a
/// hand-built call to this private function did. It is a demonstrated
/// algorithmic gap, not a proven wrong answer from real geometry.
/// 2. **Switching to shared-EDGE adjacency was tried and regressed a real,
/// previously-passing case.** Requiring triangles to share a full edge
/// (both endpoints bit-identical, undirected) broke
/// `rotated_near_band_overlap_is_withheld_exactly_as_the_axis_aligned_
/// one_is` (`clash_intersection_oracle.rs`): at 1 snap cell, tessellation
/// 1, it reported `thickness_m == 0` instead of the true ~15.26 µm depth
/// — a genuinely connected wedge the kernel's arrangement produced got
/// split into components that no longer shared a full edge with their
/// neighbours. This is consistent with (not confirmed as) a non-conforming
/// triangulation on that wedge — a T-junction where two facets share a
/// vertex along a boundary without matching it on both sides — which
/// shared-vertex adjacency tolerates and shared-edge adjacency does not.
/// Whatever the exact mechanism, the observation stands: the kernel's own
/// arrangement output does not reliably satisfy "adjacent facets share a
/// full edge," so requiring it here is not a safe tightening, and shipping
/// it would trade an unreached vertex-sharing gap for a demonstrated,
/// reproducible regression on real kernel output.
///
/// Union-find over triangle indices, unioned via a vertex-key → first-seen
/// triangle map: O(tris) with a small constant, same asymptotic cost as the
/// welding pass right below it.
pub
/// Per-axis coordinate extents across both operands, for sizing the trust
/// gate's band PROJECTED onto whichever candidate axis the thickness below is
/// measured along.
///
/// Until the world-frame fix this used a single scalar (max |coordinate| over
/// ALL THREE axes of both operands), which sizes the band from whichever axis
/// happens to carry the largest world offset — including one the measured
/// thickness never touches. A pair 10 km out in X but overlapping along Z
/// then got a band derived entirely from the irrelevant X magnitude,
/// ballooning the required thickness to ~9.5 mm and withholding a genuine
/// 5 mm Z overlap that is a `Solid` at the origin
/// (`clash_solid_world_frame_tests.rs`). [`NearBand::scaled_band2`] keeps the
/// extents PER AXIS so the caller can project onto the SAME axis the
/// thickness itself is measured along — exactly the fix `near_band.rs`
/// applied to the kernel's own near-coplanar reconciliation.
/// Runs the intersection-solid trust gate over `tris`, split into its
/// disjoint [`component_groups`] and measured along every axis in `axes`.
///
/// `Some((thickness, required))` when ANY (component, axis) extent sits
/// inside that axis's OWN `TRUST_BAND_MULTIPLE`-scaled band projected via
/// `band.scaled_band2` — the pair must be withheld. `None` when every single
/// one of them clears its own band — the pair can be trusted. The returned
/// pair is the (component, axis) with the SMALLEST extent, kept only for
/// `DegenerateReason::BelowKernelResolution`'s report; it does not select
/// which band was consulted (see below).
///
/// PR #2923 review finding, fixed here: the previous form tracked a single
/// global argmin-thickness `(thickness, required)` pair and compared ONLY
/// that axis's own extent against ONLY that axis's own band
/// (`if t < thickness { thickness = t; required = ...axis...; }`, then one
/// `thickness < required` check outside the loop). `required` ended up being
/// the band of whichever axis happened to have the smallest extent overall —
/// so an axis whose OWN extent sat inside its OWN band stopped being gated
/// the moment some other axis happened to be even thinner. Concretely: two
/// axis-aligned boxes 10 km out in X with a genuine 3-axis overlap of
/// X = 2 mm, Y = 1 m, Z = 0.6 mm picked Z as the argmin (0.6 mm) and checked
/// only `required_Z` (~0.49 mm, so 0.6 mm passed) — while X (2 mm) was never
/// checked against `required_X` (~9.5 mm, since the X-normal faces at 10 km
/// sit inside a ~2.4 mm near band), and X is precisely the axis the kernel
/// already collapsed. `untrusted` now accumulates `t < required` across
/// EVERY (component, axis) pair independently, so no axis's own violation
/// can be shadowed by another axis being thinner still.
pub
pub