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
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
// 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/.
//! The intersection SOLID of a clashing pair — the overlap volume itself, as a
//! mesh the viewer can draw opaque while ghosting both parents (the BIMcollab
//! Zoom / Solibri presentation). A contact point tells you two elements touch;
//! this tells you how deep, in what shape, and in which direction.
//!
//! # On demand, never eager
//!
//! One model here yields 81 clashes. This entry point computes ONE pair and is
//! meant to be called when a clash row is selected, exactly like the existing
//! on-demand `@ifc-lite/clash/contact` path. Nothing in the detection sweep
//! calls it.
//!
//! # Why this is gated, and what the gate is
//!
//! The exact CSG kernel snaps every input coordinate to
//! [`SNAP_GRID`](crate::kernel::mesh_bridge) = `2^-16 m ≈ 15.26 µm` and treats
//! faces within [`near_band_from_extent`] of each other as coplanar. Inside that
//! band a thin overlap is not a thin solid — it is a *coplanar contact*, and the
//! arrangement returns a wedge rather than the slab. Measured on the analytic
//! box oracle (`tests/clash_intersection_oracle.rs`), a slab overlap reports:
//!
//! | penetration depth | reported volume |
//! |---|---|
//! | ≤ 8 snap cells (≤ 122 µm) | exactly **2/3** of the truth (−33 %), at every world scale |
//! | 10–24 cells (153–366 µm) | high by 5e-5 (at the origin) to 0.33 (at 1000 m) |
//! | ≥ 4 × the near band | **exact**, to f64, at every tessellation and world scale |
//!
//! So a naive "call the kernel and show the answer" API would draw a solid that
//! is a third too small for precisely the shallow clashes a coordinator cares
//! most about — and would report a volume for a 15 µm graze as if it meant
//! something. This module therefore refuses to return a solid it cannot stand
//! behind, and says why. The viewer draws the existing contact marker instead.
//!
//! This is a real limit, not a conservatism knob: below the near band there is
//! no exact solid to compute, only a coplanar contact, and the arrangement's
//! own output cannot tell you otherwise. **No intersection solid exists for
//! those pairs at this kernel's resolution**, and inventing one would be a
//! sliver, not a finding.
//!
//! Note what the sub-micron distances this kernel reports are NOT: evidence of
//! fine coordination issues. `TriMesh` ingests geometry as `f32` and queries it
//! in `f64`, so those distances land on the `f32` ULP at the pair's coordinate
//! magnitude — `2^-22 m ≈ 0.238 µm` for coordinates in `[2, 4)` — repeated
//! bit-identically across unrelated pairs, which is the signature of a
//! quantization floor rather than a physical graze. Do not state a real-world
//! graze distance here without a reproducible per-pair measurement behind it.
use crate;
use crateTri;
use crateintersection_tris;
use cratenear_band_from_extent;
use crateMesh;
/// Multiple of the kernel's near-coplanar band above which the intersection
/// volume was measured to be exactly analytic.
///
/// Evidence (`clash_intersection_oracle::intersection_is_exact_at_and_above_the_
/// trust_threshold` plus the recorded sweep in this module's docs): at world
/// offsets 0, 10, 100 and 1000 m the reported volume is exact from `4 ×` the
/// band upward, and carries a scale-dependent error below it. Lowering this
/// constant re-admits that error; it is not a free tightening.
const TRUST_BAND_MULTIPLE: f64 = 4.0;
/// Why no solid is being returned.
// Not `Eq`: `BelowKernelResolution` carries f64 measurements.
/// The overlap volume of one clashing pair.
///
/// `Solid` carries a closed, world-space triangle mesh in **f64** — not the f32
/// of [`Mesh`] — because the caller reports its volume, and the f32 round-trip
/// costs ~1e-7 relative on a quantity that is otherwise exact.
/// Enclosed volume of a closed f64 triangle soup (divergence theorem).
/// 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`] 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.
/// Largest coordinate magnitude across both operands — the `extent` the kernel's
/// own near-coplanar band is sized from, so the gate widens with world distance
/// exactly as the kernel's own tolerance does.
/// The intersection solid of two world-space meshes, or an honest reason there
/// is none.
///
/// Both operands must already be in the **common world frame**: for a federated
/// pair the models' placements must be baked into `positions` before the call.
/// This function applies no transform and has no way to detect a missing one.
///
/// Costs one exact boolean of the two meshes; see the module docs for why the
/// result is gated rather than returned raw.