@ifc-lite/clash 1.6.8 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/dist/adapters/step.d.ts.map +1 -1
  2. package/dist/adapters/step.js +19 -2
  3. package/dist/adapters/step.js.map +1 -1
  4. package/dist/analysis.d.ts +37 -1
  5. package/dist/analysis.d.ts.map +1 -1
  6. package/dist/analysis.js +39 -0
  7. package/dist/analysis.js.map +1 -1
  8. package/dist/contact/narrow-phase.d.ts +6 -1
  9. package/dist/contact/narrow-phase.d.ts.map +1 -1
  10. package/dist/contact/narrow-phase.js +65 -1
  11. package/dist/contact/narrow-phase.js.map +1 -1
  12. package/dist/contact/shared-faces.d.ts +5 -1
  13. package/dist/contact/shared-faces.d.ts.map +1 -1
  14. package/dist/contact/shared-faces.js +49 -1
  15. package/dist/contact/shared-faces.js.map +1 -1
  16. package/dist/contact/tri-tri.d.ts +33 -4
  17. package/dist/contact/tri-tri.d.ts.map +1 -1
  18. package/dist/contact/tri-tri.js +37 -11
  19. package/dist/contact/tri-tri.js.map +1 -1
  20. package/dist/duplicate-metric.d.ts +74 -0
  21. package/dist/duplicate-metric.d.ts.map +1 -0
  22. package/dist/duplicate-metric.js +117 -0
  23. package/dist/duplicate-metric.js.map +1 -0
  24. package/dist/duplicate-sets.d.ts +47 -0
  25. package/dist/duplicate-sets.d.ts.map +1 -0
  26. package/dist/duplicate-sets.js +124 -0
  27. package/dist/duplicate-sets.js.map +1 -0
  28. package/dist/duplicates.d.ts +99 -11
  29. package/dist/duplicates.d.ts.map +1 -1
  30. package/dist/duplicates.js +270 -76
  31. package/dist/duplicates.js.map +1 -1
  32. package/dist/engine-ts/depth.d.ts +99 -0
  33. package/dist/engine-ts/depth.d.ts.map +1 -0
  34. package/dist/engine-ts/depth.js +172 -0
  35. package/dist/engine-ts/depth.js.map +1 -0
  36. package/dist/engine-ts/kernel.d.ts +3 -1
  37. package/dist/engine-ts/kernel.d.ts.map +1 -1
  38. package/dist/engine-ts/narrow.d.ts +7 -1
  39. package/dist/engine-ts/narrow.d.ts.map +1 -1
  40. package/dist/engine-ts/narrow.js +53 -95
  41. package/dist/engine-ts/narrow.js.map +1 -1
  42. package/dist/engine-ts/obb.d.ts +116 -0
  43. package/dist/engine-ts/obb.d.ts.map +1 -0
  44. package/dist/engine-ts/obb.js +331 -0
  45. package/dist/engine-ts/obb.js.map +1 -0
  46. package/dist/engine-ts/orchestrator.d.ts.map +1 -1
  47. package/dist/engine-ts/orchestrator.js +10 -13
  48. package/dist/engine-ts/orchestrator.js.map +1 -1
  49. package/dist/engine-ts/tri-mesh.d.ts +84 -22
  50. package/dist/engine-ts/tri-mesh.d.ts.map +1 -1
  51. package/dist/engine-ts/tri-mesh.js +151 -48
  52. package/dist/engine-ts/tri-mesh.js.map +1 -1
  53. package/dist/engine-ts/ts-kernel.d.ts.map +1 -1
  54. package/dist/engine-ts/ts-kernel.js +1 -0
  55. package/dist/engine-ts/ts-kernel.js.map +1 -1
  56. package/dist/engine-wasm/wasm-kernel.d.ts.map +1 -1
  57. package/dist/engine-wasm/wasm-kernel.js +7 -0
  58. package/dist/engine-wasm/wasm-kernel.js.map +1 -1
  59. package/dist/grouping.d.ts +4 -0
  60. package/dist/grouping.d.ts.map +1 -1
  61. package/dist/grouping.js +18 -43
  62. package/dist/grouping.js.map +1 -1
  63. package/dist/index.d.ts +12 -2
  64. package/dist/index.d.ts.map +1 -1
  65. package/dist/index.js +12 -2
  66. package/dist/index.js.map +1 -1
  67. package/dist/math/aabb.d.ts +10 -1
  68. package/dist/math/aabb.d.ts.map +1 -1
  69. package/dist/math/aabb.js +33 -13
  70. package/dist/math/aabb.js.map +1 -1
  71. package/dist/shape-signature.d.ts +41 -0
  72. package/dist/shape-signature.d.ts.map +1 -0
  73. package/dist/shape-signature.js +113 -0
  74. package/dist/shape-signature.js.map +1 -0
  75. package/dist/triage.d.ts.map +1 -1
  76. package/dist/triage.js +11 -3
  77. package/dist/triage.js.map +1 -1
  78. package/dist/types.d.ts +60 -0
  79. package/dist/types.d.ts.map +1 -1
  80. package/dist/types.js.map +1 -1
  81. package/dist/union-find.d.ts +11 -0
  82. package/dist/union-find.d.ts.map +1 -0
  83. package/dist/union-find.js +44 -0
  84. package/dist/union-find.js.map +1 -0
  85. package/package.json +7 -6
@@ -0,0 +1,331 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+ import { sub, cross, dot } from '../math/vec3.js';
5
+ /** Tolerance for normal-direction dedup and offset-plane clustering. Same
6
+ * literal in the Rust kernel — see `rust/clash/src/obb.rs`. */
7
+ export const OBB_EPS = 1e-6;
8
+ function normalize(v) {
9
+ const len = Math.sqrt(dot(v, v));
10
+ if (!(len > OBB_EPS))
11
+ return null;
12
+ return [v[0] / len, v[1] / len, v[2] / len];
13
+ }
14
+ /** Flip `n` so its largest-magnitude component is positive, so a face and its
15
+ * antipodal opposite face collapse to the same canonical axis direction. Ties
16
+ * broken in x, y, z order — identical to the Rust `canonical`. */
17
+ function canonical(n) {
18
+ const ax = Math.abs(n[0]);
19
+ const ay = Math.abs(n[1]);
20
+ const az = Math.abs(n[2]);
21
+ let idx = 0;
22
+ if (ay > ax && ay >= az)
23
+ idx = 1;
24
+ else if (az > ax && az > ay)
25
+ idx = 2;
26
+ return n[idx] < 0 ? [-n[0], -n[1], -n[2]] : n;
27
+ }
28
+ /**
29
+ * Detect whether `mesh` is a rectangular box: every (non-degenerate)
30
+ * triangle's normal falls into exactly 3 mutually orthogonal canonical
31
+ * directions, and every vertex of the triangles in a direction group lies on
32
+ * one of exactly two offset planes along that direction. That combination —
33
+ * 3 orthogonal face families, 2 planes each — forces the mesh to be a closed
34
+ * rectangular box (it rejects, for example, an axis-aligned L-shape, whose
35
+ * notch adds a third offset plane on two of the axes). Triangulation-
36
+ * independent: subdividing a box's faces adds triangles but never a new
37
+ * canonical direction or a third offset plane, so the detection (and the
38
+ * resulting `Obb`) is identical at any tessellation.
39
+ *
40
+ * Returns `null` — not a best-effort guess — when the check fails, so a
41
+ * caller that only trusts a non-null result never certifies a shape this
42
+ * function could not confirm.
43
+ */
44
+ export function detectObb(mesh) {
45
+ if (mesh.count === 0)
46
+ return null;
47
+ const groups = [];
48
+ const groupOfTri = new Array(mesh.count).fill(-1);
49
+ for (let t = 0; t < mesh.count; t += 1) {
50
+ const [a, b, c] = mesh.tri(t);
51
+ const n = normalize(cross(sub(b, a), sub(c, a)));
52
+ if (!n)
53
+ continue; // degenerate triangle: contributes no face-normal evidence
54
+ const cn = canonical(n);
55
+ let gi = -1;
56
+ for (let g = 0; g < groups.length; g += 1) {
57
+ if (dot(groups[g], cn) > 1 - OBB_EPS) {
58
+ gi = g;
59
+ break;
60
+ }
61
+ }
62
+ if (gi === -1) {
63
+ if (groups.length >= 3)
64
+ return null; // a 4th face-normal family: not a box
65
+ groups.push(cn);
66
+ gi = groups.length - 1;
67
+ }
68
+ groupOfTri[t] = gi;
69
+ }
70
+ if (groups.length !== 3)
71
+ return null;
72
+ for (let i = 0; i < 3; i += 1) {
73
+ for (let j = i + 1; j < 3; j += 1) {
74
+ if (Math.abs(dot(groups[i], groups[j])) > OBB_EPS)
75
+ return null;
76
+ }
77
+ }
78
+ const minOff = [Infinity, Infinity, Infinity];
79
+ const maxOff = [-Infinity, -Infinity, -Infinity];
80
+ for (let t = 0; t < mesh.count; t += 1) {
81
+ const gi = groupOfTri[t];
82
+ if (gi === -1)
83
+ continue;
84
+ const [a, b, c] = mesh.tri(t);
85
+ for (const v of [a, b, c]) {
86
+ const o = dot(v, groups[gi]);
87
+ if (o < minOff[gi])
88
+ minOff[gi] = o;
89
+ if (o > maxOff[gi])
90
+ maxOff[gi] = o;
91
+ }
92
+ }
93
+ // Reject a 3rd offset plane on any axis (e.g. an L-shaped footprint).
94
+ for (let t = 0; t < mesh.count; t += 1) {
95
+ const gi = groupOfTri[t];
96
+ if (gi === -1)
97
+ continue;
98
+ const [a, b, c] = mesh.tri(t);
99
+ for (const v of [a, b, c]) {
100
+ const o = dot(v, groups[gi]);
101
+ const scale = Math.max(1, Math.abs(minOff[gi]), Math.abs(maxOff[gi]));
102
+ const nearMin = Math.abs(o - minOff[gi]) <= OBB_EPS * scale;
103
+ const nearMax = Math.abs(o - maxOff[gi]) <= OBB_EPS * scale;
104
+ if (!nearMin && !nearMax)
105
+ return null;
106
+ }
107
+ }
108
+ const half = [0, 0, 0];
109
+ const c0 = [0, 0, 0];
110
+ for (let i = 0; i < 3; i += 1) {
111
+ half[i] = (maxOff[i] - minOff[i]) / 2;
112
+ c0[i] = (maxOff[i] + minOff[i]) / 2;
113
+ // Reject a zero-thickness "box": a face family whose triangles are all
114
+ // coplanar passes the 2-plane test above (minOff == maxOff, so both
115
+ // `nearMin` and `nearMax` hold for every vertex) with no positive
116
+ // extent along that axis. An open shell (a slab exported without its
117
+ // top face, or partial `IfcTriangulatedFaceSet` geometry) can produce
118
+ // exactly this — 3 orthogonal families, but one degenerate — and must
119
+ // not be certified as a box (review: #2536).
120
+ if (!(half[i] > OBB_EPS))
121
+ return null;
122
+ }
123
+ const center = [
124
+ c0[0] * groups[0][0] + c0[1] * groups[1][0] + c0[2] * groups[2][0],
125
+ c0[0] * groups[0][1] + c0[1] * groups[1][1] + c0[2] * groups[2][1],
126
+ c0[0] * groups[0][2] + c0[1] * groups[1][2] + c0[2] * groups[2][2],
127
+ ];
128
+ return { center, axes: [groups[0], groups[1], groups[2]], half };
129
+ }
130
+ /**
131
+ * Bound, in f64 ulps, on the absolute error of one component of the cross
132
+ * product of two UNIT vectors (each component is a product-difference of
133
+ * magnitude-<=1 terms: ~2 ulps), with headroom for the normalisation and the
134
+ * per-projection dot rounding it feeds. Shared by the axis noise bound in
135
+ * {@link obbPenetrationDepth}; same literal in the Rust kernel.
136
+ */
137
+ export const AXIS_NOISE_ULPS = 8;
138
+ /**
139
+ * Exact penetration depth between two oriented boxes: the minimum overlap
140
+ * over the 15 canonical OBB-OBB separating-axis candidates (each box's 3 face
141
+ * normals, plus the 9 pairwise cross products of one box's axes with the
142
+ * other's) — the standard result (Gottschalk, "Collision Queries using
143
+ * Oriented Bounding Boxes") that the minimum-translation-distance axis for two
144
+ * boxes is always among these 15.
145
+ *
146
+ * Cross-product candidates are conditioned by their length: both operands are
147
+ * unit axes, so `|L| = sin(angle between them)`, and normalising amplifies
148
+ * the ~ulp-level absolute error of the cross product into a direction error
149
+ * of up to `AXIS_NOISE_ULPS * EPS / |L|` radians. Each candidate's verdict
150
+ * therefore carries a SCALE-RELATIVE noise bound (see `testAxis`), and a
151
+ * verdict inside its own noise band is skipped — not trusted to separate,
152
+ * not trusted as a depth (review: #2536; the same
153
+ * tolerance-from-the-wrong-quantity class as #2598/#2600/#2529 — an earlier
154
+ * ABSOLUTE `len > 1e-6` guard here both divided by lengths whose noise
155
+ * dwarfs a thin overlap at large operand scale, and hard-dropped axes that
156
+ * were fine: for kilometre-scale near-parallel beams the dropped common
157
+ * normal IS the
158
+ * minimum-translation axis, and the min over the remaining axes over-reported
159
+ * a 0.02 m edge contact as a certified 0.45 m depth — see `obb.test.ts`).
160
+ *
161
+ * Returns `null` if any candidate axis reports, beyond its noise band, zero
162
+ * or negative overlap — the boxes would be separated along it, contradicting
163
+ * the caller's own crossing test — so a numerical edge case degrades to
164
+ * `null` (caller falls back to the AABB estimate) rather than reporting a
165
+ * wrong depth.
166
+ */
167
+ export function obbPenetrationDepth(a, b) {
168
+ const T = [b.center[0] - a.center[0], b.center[1] - a.center[1], b.center[2] - a.center[2]];
169
+ // Operand scale for the per-axis noise bound: the sum of BOTH boxes' three
170
+ // half-extents plus the center offset's components. A direction error of
171
+ // `e` radians in a candidate axis perturbs each projection term by up to
172
+ // (that term's extent) * e, so the summed extents bound the total overlap
173
+ // error at `extentSum * e`. Deliberately NOT the projected radii rA/rB of
174
+ // the axis under test: an extent nearly PERPENDICULAR to the axis projects
175
+ // to ~0 yet contributes its full magnitude of noise (a 1 km beam projects
176
+ // nothing onto its cross-section normal but sways that normal's projection
177
+ // by up to 1 km * e), the same the-world-magnitude-is-the-wrong-quantity
178
+ // trap as the local-extent tolerance in
179
+ // `packages/drawing-2d/src/section-cutter.ts` (#2622), with the roles
180
+ // reversed: here the SUMMED extents are the right quantity and the
181
+ // projected ones are the trap.
182
+ const extentSum = a.half[0] + a.half[1] + a.half[2] +
183
+ b.half[0] + b.half[1] + b.half[2] +
184
+ Math.abs(T[0]) + Math.abs(T[1]) + Math.abs(T[2]);
185
+ let depth = Infinity;
186
+ function testAxis(L) {
187
+ const len = Math.sqrt(dot(L, L));
188
+ // Exactly parallel axes: the cross product is zero and the candidate
189
+ // direction is spanned by the remaining axes (for boxes with a parallel
190
+ // axis pair the face axes alone realise the minimum — the classical SAT
191
+ // redundancy result), so skipping is exact, and it avoids 0/0 below.
192
+ if (!(len > 0))
193
+ return true;
194
+ const u = [L[0] / len, L[1] / len, L[2] / len];
195
+ const rA = a.half[0] * Math.abs(dot(a.axes[0], u)) +
196
+ a.half[1] * Math.abs(dot(a.axes[1], u)) +
197
+ a.half[2] * Math.abs(dot(a.axes[2], u));
198
+ const rB = b.half[0] * Math.abs(dot(b.axes[0], u)) +
199
+ b.half[1] * Math.abs(dot(b.axes[1], u)) +
200
+ b.half[2] * Math.abs(dot(b.axes[2], u));
201
+ const dist = Math.abs(dot(T, u));
202
+ const overlap = rA + rB - dist;
203
+ // Scale-relative conditioning guard, replacing an absolute `len > 1e-6`
204
+ // (review: #2536). `u`'s direction is uncertain by up to
205
+ // `AXIS_NOISE_ULPS * EPS / len` radians (cancellation shrinks `|L|` to
206
+ // sin(angle) but leaves the cross product's ~ulp absolute error intact),
207
+ // so `overlap` is uncertain by up to `extentSum` times that. A verdict
208
+ // inside the band is SKIPPED: in a separating-axis test, dropping a
209
+ // candidate can only fail to find a separation — it reports the minimum
210
+ // over the remaining axes, every one of which is a valid upper bound on
211
+ // the true depth — never invent one, so the result stays conservative
212
+ // (it may keep a clash a perfect test would separate, but never
213
+ // separates a genuine overlap). Do not "harden" this into returning
214
+ // false: that would turn unresolvable noise into a fabricated
215
+ // separation. Verdicts OUTSIDE the band are kept whatever `len` is —
216
+ // their own magnitude proves the noise did not decide them.
217
+ const noise = extentSum * ((AXIS_NOISE_ULPS * Number.EPSILON) / len);
218
+ if (Math.abs(overlap) <= noise)
219
+ return true;
220
+ if (overlap <= 0)
221
+ return false;
222
+ if (overlap < depth)
223
+ depth = overlap;
224
+ return true;
225
+ }
226
+ for (let i = 0; i < 3; i += 1)
227
+ if (!testAxis(a.axes[i]))
228
+ return null;
229
+ for (let i = 0; i < 3; i += 1)
230
+ if (!testAxis(b.axes[i]))
231
+ return null;
232
+ for (let i = 0; i < 3; i += 1) {
233
+ for (let j = 0; j < 3; j += 1) {
234
+ if (!testAxis(cross(a.axes[i], b.axes[j])))
235
+ return null;
236
+ }
237
+ }
238
+ return depth === Infinity ? null : depth;
239
+ }
240
+ /**
241
+ * Projected radius of `o` onto unit axis `u`: half the length of `o`'s
242
+ * shadow on `u`. The same per-axis projection {@link obbPenetrationDepth}'s
243
+ * `testAxis` computes for the 15-candidate SAT — factored out here so the
244
+ * through-penetration containment test below can reuse it for ANY axis, not
245
+ * only one drawn from a shared a/b frame.
246
+ */
247
+ function projRadius(o, u) {
248
+ return (o.half[0] * Math.abs(dot(o.axes[0], u)) +
249
+ o.half[1] * Math.abs(dot(o.axes[1], u)) +
250
+ o.half[2] * Math.abs(dot(o.axes[2], u)));
251
+ }
252
+ /**
253
+ * Whether `p`'s own axes reveal a through-penetration of `p` piercing `q` —
254
+ * `p`'s footprint, in the plane perpendicular to one of `p`'s OWN axes, fits
255
+ * inside `q`'s cross-section there (edges included), while along that axis `p`
256
+ * extends beyond `q` and out the far side. `q`'s extent along any of `p`'s
257
+ * axes is `projRadius(q, axis)` — the general SAT projection, valid whether
258
+ * or not `q`'s own axes align with `p`'s — so this needs no shared frame.
259
+ */
260
+ function piercesAlong(p, q, centerDelta) {
261
+ const margin = (h) => OBB_EPS * Math.max(1, h);
262
+ for (let k = 0; k < 3; k += 1) {
263
+ const i = (k + 1) % 3;
264
+ const j = (k + 2) % 3;
265
+ const axisK = p.axes[k];
266
+ const axisI = p.axes[i];
267
+ const axisJ = p.axes[j];
268
+ const offK = dot(centerDelta, axisK);
269
+ const offI = dot(centerDelta, axisI);
270
+ const offJ = dot(centerDelta, axisJ);
271
+ const rQk = projRadius(q, axisK);
272
+ const rQi = projRadius(q, axisI);
273
+ const rQj = projRadius(q, axisJ);
274
+ // P's footprint on the other two axes fits inside Q's, edges INCLUDED —
275
+ // the tolerance opens the test up rather than tightening it. An earlier
276
+ // version demanded a real margin (`rQi - margin(rQi)`) so that two slabs
277
+ // sharing a footprint would not read as a piercing member; but what
278
+ // actually disqualifies that pair is the `k`-axis test below, and the
279
+ // strict form instead rejected the commonest configuration in any
280
+ // building — two walls crossing at an X-junction, where each pierces the
281
+ // other clean through in thickness but the shared height TIES. That pair
282
+ // reported the full 3 m wall height as a certified `'mesh'` penetration
283
+ // (review: #2536 — `main` reported the honest 0.200 m). The strict form
284
+ // was also discontinuous: tilting one wall by 1e-6 rad flipped it back to
285
+ // `true`, so a hair of rotation moved the reported depth from 3.000 m to
286
+ // 0.200 m.
287
+ const pInsideQ = Math.abs(offI) + p.half[i] <= rQi + margin(rQi) && Math.abs(offJ) + p.half[j] <= rQj + margin(rQj);
288
+ // "Exits the far side" along k means P's interval extends past Q's on
289
+ // BOTH ends, not merely that P's half-extent is the bigger number — a
290
+ // footing embedded 75 mm into a slab from ABOVE is longer than the slab
291
+ // along Z (it does not fit inside it) but only pokes out the TOP, not
292
+ // the bottom, so it is a partial overlap, not a through-penetration.
293
+ // Requiring `p.half[k] > rQk + |offK|` is exactly "P's interval strictly
294
+ // contains Q's interval on axis k", i.e. P pokes out past Q on both sides.
295
+ if (pInsideQ && p.half[k] > rQk + Math.abs(offK) + margin(rQk))
296
+ return true;
297
+ }
298
+ return false;
299
+ }
300
+ /**
301
+ * Whether `a` and `b` are in a THROUGH-PENETRATION configuration: one box's
302
+ * cross-section, in the plane perpendicular to one of ITS OWN axes, is fully
303
+ * inside the other's footprint there, while along that axis it extends
304
+ * beyond the other and out the far side — a thin member piercing clean
305
+ * through a wall/slab, not a partial overlap. The relation is checked BOTH
306
+ * ways, so it also holds for the MUTUAL case: two walls crossing at an
307
+ * X-junction, each piercing the other clean through in thickness.
308
+ *
309
+ * This matters because {@link obbPenetrationDepth} reports the minimum
310
+ * TRANSLATION distance to separate the pair, which for this shape is
311
+ * dominated by the piercing member's own extent along the piercing axis, not
312
+ * by how much material it actually crossed (review: #2536 — a 2 m duct
313
+ * through a 200 mm wall reported 1.1 m, not 0.2 m). Detecting the shape lets
314
+ * the caller decline to certify that number as a measured depth.
315
+ *
316
+ * Tests containment against EACH box's own axes independently (via
317
+ * {@link piercesAlong}'s general per-axis projection, the same projection
318
+ * {@link obbPenetrationDepth} already computes for its 15 SAT candidates) —
319
+ * unlike an earlier version restricted to a frame shared by both boxes'
320
+ * axes up to sign, this also catches a member piercing through at a generic
321
+ * relative rotation (e.g. a duct crossing a wall at 15 degrees, review:
322
+ * #2536 follow-up — the earlier version measured -1.1177 there, `'mesh'`-
323
+ * labelled, against a true ~0.207 m).
324
+ */
325
+ export function isThroughPenetration(a, b) {
326
+ const d = [b.center[0] - a.center[0], b.center[1] - a.center[1], b.center[2] - a.center[2]];
327
+ const negD = [-d[0], -d[1], -d[2]];
328
+ // A piercing B along one of A's own axes, or B piercing A along one of B's.
329
+ return piercesAlong(a, b, d) || piercesAlong(b, a, negD);
330
+ }
331
+ //# sourceMappingURL=obb.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"obb.js","sourceRoot":"","sources":["../../src/engine-ts/obb.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../../src/engine-ts/orchestrator.ts"],"names":[],"mappings":"AAOA,OAAO,EAGL,KAAK,YAAY,EAEjB,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,KAAK,aAAa,EAGnB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C;;;;;;GAMG;AACH,wBAAsB,QAAQ,CAC5B,QAAQ,EAAE,YAAY,EAAE,EACxB,KAAK,EAAE,SAAS,EAAE,EAClB,QAAQ,EAAE,aAAa,EACvB,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,WAAW,CAAC,CAoGtB"}
1
+ {"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../../src/engine-ts/orchestrator.ts"],"names":[],"mappings":"AAQA,OAAO,EAGL,KAAK,YAAY,EAEjB,KAAK,WAAW,EAChB,KAAK,SAAS,EAEd,KAAK,aAAa,EACnB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C;;;;;;GAMG;AACH,wBAAsB,QAAQ,CAC5B,QAAQ,EAAE,YAAY,EAAE,EACxB,KAAK,EAAE,SAAS,EAAE,EAClB,QAAQ,EAAE,aAAa,EACvB,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,WAAW,CAAC,CA4GtB"}
@@ -4,6 +4,7 @@
4
4
  import { matchesSelector } from '../selectors.js';
5
5
  import { inferClashSeverity } from '../disciplines.js';
6
6
  import { isExcluded, qualifiedKey } from '../exclude.js';
7
+ import { summarizeClashes } from '../analysis.js';
7
8
  import { DEFAULT_CLASH_SETTINGS, } from '../types.js';
8
9
  /**
9
10
  * Backend-agnostic clash orchestration: selection, exclusions, severity, stable
@@ -18,6 +19,7 @@ export async function runClash(elements, rules, settings, kernel) {
18
19
  const exclusions = excludeVoidsAndHosts ? settings.exclusions : undefined;
19
20
  const maxPairs = settings.maxCandidatePairs ?? Infinity;
20
21
  const clashes = [];
22
+ const ruleCoverage = [];
21
23
  const seen = new Set();
22
24
  let droppedPairs = 0;
23
25
  // A single GLOBAL candidate-pair budget across the whole run (not per rule),
@@ -41,6 +43,11 @@ export async function runClash(elements, rules, settings, kernel) {
41
43
  if (groupB && matchesSelector(tag, rule.b))
42
44
  groupB.push(i);
43
45
  }
46
+ ruleCoverage.push({
47
+ rule: rule.id,
48
+ matchedA: groupA.length,
49
+ matchedB: groupB ? groupB.length : null,
50
+ });
44
51
  const ruleTolerance = rule.tolerance ?? tolerance;
45
52
  settings.onProgress?.({ phase: 'broad', rule: rule.id, done: 0, total: 0 });
46
53
  const { records, candidatesProcessed, candidatesDropped } = await kernel.detectRule(elements, groupA, groupB, rule, ruleTolerance, remaining, settings.signal, settings.onProgress
@@ -74,6 +81,7 @@ export async function runClash(elements, rules, settings, kernel) {
74
81
  rule: rule.id,
75
82
  status: rec.status,
76
83
  distance: rec.distance,
84
+ distanceKind: rec.distanceKind,
77
85
  point: rec.point,
78
86
  bounds: rec.bounds,
79
87
  severity: rule.severity ?? inferClashSeverity(elA.tag, elB.tag),
@@ -87,8 +95,9 @@ export async function runClash(elements, rules, settings, kernel) {
87
95
  clashes.sort(byKeyThenRule);
88
96
  const result = {
89
97
  clashes,
90
- summary: buildSummary(clashes),
98
+ summary: summarizeClashes(clashes),
91
99
  rulesRun: rules,
100
+ ruleCoverage,
92
101
  settings: { tolerance, excludeVoidsAndHosts },
93
102
  };
94
103
  if (droppedPairs > 0) {
@@ -112,16 +121,4 @@ function byKeyThenRule(x, y) {
112
121
  function cmp(a, b) {
113
122
  return a < b ? -1 : a > b ? 1 : 0;
114
123
  }
115
- function buildSummary(clashes) {
116
- const byRule = {};
117
- const byTypePair = {};
118
- const bySeverity = { critical: 0, major: 0, minor: 0, info: 0 };
119
- for (const c of clashes) {
120
- byRule[c.rule] = (byRule[c.rule] ?? 0) + 1;
121
- const pair = [c.a.tag, c.b.tag].sort().join(' vs ');
122
- byTypePair[pair] = (byTypePair[pair] ?? 0) + 1;
123
- bySeverity[c.severity] += 1;
124
- }
125
- return { total: clashes.length, byRule, byTypePair, bySeverity };
126
- }
127
124
  //# sourceMappingURL=orchestrator.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"orchestrator.js","sourceRoot":"","sources":["../../src/engine-ts/orchestrator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"orchestrator.js","sourceRoot":"","sources":["../../src/engine-ts/orchestrator.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,16 @@
1
1
  import { type AABB } from '@ifc-lite/spatial';
2
2
  import type { Mat4, Vec3 } from '../types.js';
3
+ import { type Obb } from './obb.js';
4
+ /**
5
+ * Fixed ray direction for point-in-solid tests: `normalize([1, √3, √5])`.
6
+ * Deliberately NON-axis-aligned so the ray never grazes the edges/vertices of
7
+ * axis-aligned boxes (which would double-count crossings). Written as exact
8
+ * IEEE-754 literals (not computed via `normalize()`) so the Rust kernel uses
9
+ * byte-identical components — `|RAY_DIR| === 1` exactly.
10
+ */
11
+ export declare const RAY_DIR: Vec3;
12
+ /** Parallel-reject + forward-crossing threshold. Same literal in the Rust kernel. */
13
+ export declare const RAY_EPS = 1e-9;
3
14
  /**
4
15
  * A triangle mesh with a per-triangle BVH for narrow-phase queries. Built once
5
16
  * per element per run and cached by the engine, so each element's triangle
@@ -11,6 +22,18 @@ export declare class TriMesh {
11
22
  private readonly indices;
12
23
  private readonly transform?;
13
24
  private readonly bvh;
25
+ /**
26
+ * Starting half-size for the expanding-cube probe in `distanceToSurface`: a
27
+ * power-of-two fraction of the mesh's longest axis, scaled down by the cube
28
+ * root of the triangle count so it lands near the average triangle size.
29
+ * Derived with exact power-of-two arithmetic (no `pow`/`cbrt`, whose last bit
30
+ * is not guaranteed to agree between JS and Rust) — the Rust
31
+ * `TriMesh::probe_seed` computes the identical value.
32
+ */
33
+ private readonly probeSeed;
34
+ /** Memoized `detectObb(this)` result; `undefined` until first requested.
35
+ * Computed at most once per element per run, same lifetime as the mesh. */
36
+ private obbCache;
14
37
  constructor(positions: Float32Array, indices: Uint32Array, transform?: Mat4);
15
38
  /** World-space vertex `i` (applies the element transform if present). */
16
39
  vertex(i: number): Vec3;
@@ -19,6 +42,9 @@ export declare class TriMesh {
19
42
  triBounds(t: number): AABB;
20
43
  /** Triangle indices whose bounds intersect `bounds`. */
21
44
  queryTris(bounds: AABB): number[];
45
+ /** Memoized `Obb` for this mesh, or `null` when the mesh is not (within
46
+ * tolerance) a rectangular box. See `obb.ts` for the detection rule. */
47
+ getObb(): Obb | null;
22
48
  /**
23
49
  * Mean of every vertex (world-space, transform applied), summed in index
24
50
  * order. A rigid-invariant interior probe for the volumetric-overlap check in
@@ -29,34 +55,70 @@ export declare class TriMesh {
29
55
  * `vertex_centroid`. Only called in the rare coplanar-overlap branch.
30
56
  */
31
57
  vertexCentroid(): Vec3;
32
- /**
33
- * True when `p` is inside this closed mesh. Casts a fixed-direction ray and
34
- * counts forward crossings against every triangle (Möller–Trumbore,
35
- * double-sided so winding doesn't matter); an odd count means inside.
36
- *
37
- * Iterates all triangles in index order — deliberately NOT the BVH — so the
38
- * result is bit-identical to the Rust `contains_point`. Only invoked in the
39
- * rare enclosed-solid branch of the narrow phase, so the O(n) cost is fine.
40
- */
58
+ /** Minimum point-to-triangle distance over `tris`, as a squared distance. */
59
+ private minDistSqOver;
60
+ /** Exhaustive fallback for `distanceToSurface`: every triangle, index order. */
61
+ private distanceToSurfaceScan;
41
62
  /**
42
63
  * Exact distance from `p` to this mesh's surface: the minimum point-to-
43
- * triangle distance over every triangle. Iterated in index order (not the
44
- * BVH) so the code shape stays identical to the Rust `distance_to_surface`;
45
- * the minimum itself is order-independent. Only invoked from the contained-
46
- * pair depth measurement (#1866), so the O(n) scan is fine.
64
+ * triangle distance over the whole mesh.
65
+ *
66
+ * Not on the narrow-phase hot path as of PR #2536 (its former caller,
67
+ * `maxPenetrationInto`, was removed see `obb.ts`): a nearest-crossing-
68
+ * VERTEX distance-to-surface probe is a sampling artifact that converges to
69
+ * 0 under retessellation rather than to the true penetration depth. Kept as
70
+ * a genuinely exact, independently tested primitive (see the shared probe
71
+ * fixture in `tri-mesh.test.ts` / `kernel_tests.rs`) for future callers that
72
+ * need it — e.g. clearance-to-nearest-surface — not as dead weight. Driven
73
+ * by the triangle BVH rather than a linear scan so it stays cheap when it IS
74
+ * called. The BVH is used through a plain `queryAABB`, so the value is still
75
+ * the exact global minimum:
76
+ *
77
+ * TODO(remove-by: no production caller has appeared by the next
78
+ * clash-engine feature pass, or on maintainer request): tracking issue
79
+ * https://github.com/LTplus-AG/ifc-lite/issues/2646.
80
+ *
81
+ * 1. Query the cube of half-size `h` centred on `p`. Every triangle within
82
+ * distance `h` of `p` has its closest point inside that cube, hence its
83
+ * AABB intersects the cube, hence it is in the candidate set.
84
+ * 2. If the candidate minimum `d` satisfies `d <= h`, the true minimum is
85
+ * `<= h` too, so its triangle was a candidate and `d` IS the true minimum.
86
+ * 3. Otherwise `d` is still an upper bound on the true minimum, so one more
87
+ * query at half-size `d` provably captures the closest triangle.
88
+ *
89
+ * The reported value is therefore the same minimum the linear scan returns —
90
+ * `min` selects an element, it does not accumulate, so visiting a superset of
91
+ * the argmin in a different order returns the identical `f64`. The Rust
92
+ * `distance_to_surface` runs the identical sequence of queries on the identical
93
+ * BVH, so the two kernels stay bit-identical to each other (see the shared
94
+ * probe fixture in `tri-mesh.test.ts` / `kernel_tests.rs`).
95
+ *
96
+ * The `wider.length === 0` arm below is unreachable, not a tested fallback:
97
+ * `cubeAround(p, d)` with `d > h` strictly contains `cubeAround(p, h)`, whose
98
+ * query was already non-empty, so every triangle that made `hits` non-empty
99
+ * also intersects the wider cube — `wider` cannot come back empty. It is kept
100
+ * only as defence-in-depth against a future `queryTris` regression, not as a
101
+ * code path with coverage; do not read it as a tested safety net.
47
102
  */
48
103
  distanceToSurface(p: Vec3): number;
49
104
  /**
50
- * Mesh-level penetration of this mesh into `other`, measured at the vertices
51
- * of the triangles flagged in `crossFlags` (the pairs the narrow phase saw
52
- * genuinely crossing `other`): the maximum distance-to-surface of `other`
53
- * over those vertices that lie inside `other`. Each vertex is visited once
54
- * (deduped by vertex index, in index order bit-identical to the Rust
55
- * `max_penetration_into`). Returns 0 when no flagged vertex is inside, e.g.
56
- * a thin member piercing straight through, whose crossing-triangle vertices
57
- * all sit outside `other` (#1866).
105
+ * True when `p` is inside this closed mesh. Casts a fixed-direction ray and
106
+ * counts forward crossings (Möller–Trumbore, double-sided so winding doesn't
107
+ * matter); an odd count means inside.
108
+ *
109
+ * Only the triangles the BVH reports along the ray are tested. A triangle the
110
+ * ray hits at `tHit > RAY_EPS > 0` is hit inside its own AABB, so the slab
111
+ * test admits it the candidate set is a superset of the triangles a linear
112
+ * scan would count, and the crossing count is an integer sum, so the parity
113
+ * (and hence the verdict) is unchanged by the visit order. `RAY_DIR` is a
114
+ * unit vector exactly, so `BVH.raycast`'s normalisation is the identity and
115
+ * the slab test sees exactly `RAY_DIR`; the Rust `Bvh::raycast` mirrors this
116
+ * traversal operation for operation, keeping the two kernels bit-identical.
58
117
  */
59
- maxPenetrationInto(other: TriMesh, crossFlags: Uint8Array): number;
60
118
  containsPoint(p: Vec3): boolean;
119
+ /** Number of vertices in this mesh (positions are packed `x, y, z`). */
120
+ vertexCount(): number;
121
+ /** The three vertex indices of triangle `t` (local, 0-based). */
122
+ triIndices(t: number): [number, number, number];
61
123
  }
62
124
  //# sourceMappingURL=tri-mesh.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tri-mesh.d.ts","sourceRoot":"","sources":["../../src/engine-ts/tri-mesh.ts"],"names":[],"mappings":"AAIA,OAAO,EAAO,KAAK,IAAI,EAAuB,MAAM,mBAAmB,CAAC;AACxE,OAAO,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAe9C;;;;GAIG;AACH,qBAAa,OAAO;IAClB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAe;IACzC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAc;IACtC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAO;IAClC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAM;gBAEd,SAAS,EAAE,YAAY,EAAE,OAAO,EAAE,WAAW,EAAE,SAAS,CAAC,EAAE,IAAI;IAa3E,yEAAyE;IACzE,MAAM,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI;IAqBvB,sDAAsD;IACtD,GAAG,CAAC,CAAC,EAAE,MAAM,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC;IASlC,SAAS,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI;IAgB1B,wDAAwD;IACxD,SAAS,CAAC,MAAM,EAAE,IAAI,GAAG,MAAM,EAAE;IAKjC;;;;;;;;OAQG;IACH,cAAc,IAAI,IAAI;IAetB;;;;;;;;OAQG;IACH;;;;;;OAMG;IACH,iBAAiB,CAAC,CAAC,EAAE,IAAI,GAAG,MAAM;IAWlC;;;;;;;;;OASG;IACH,kBAAkB,CAAC,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,GAAG,MAAM;IAmBlE,aAAa,CAAC,CAAC,EAAE,IAAI,GAAG,OAAO;CAqBhC"}
1
+ {"version":3,"file":"tri-mesh.d.ts","sourceRoot":"","sources":["../../src/engine-ts/tri-mesh.ts"],"names":[],"mappings":"AAIA,OAAO,EAAO,KAAK,IAAI,EAAuB,MAAM,mBAAmB,CAAC;AACxE,OAAO,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAG9C,OAAO,EAAa,KAAK,GAAG,EAAE,MAAM,UAAU,CAAC;AAE/C;;;;;;GAMG;AACH,eAAO,MAAM,OAAO,EAAE,IAAmE,CAAC;AAC1F,qFAAqF;AACrF,eAAO,MAAM,OAAO,OAAO,CAAC;AAU5B;;;;GAIG;AACH,qBAAa,OAAO;IAClB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAe;IACzC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAc;IACtC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAO;IAClC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAM;IAC1B;;;;;;;OAOG;IACH,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC;+EAC2E;IAC3E,OAAO,CAAC,QAAQ,CAAyB;gBAE7B,SAAS,EAAE,YAAY,EAAE,OAAO,EAAE,WAAW,EAAE,SAAS,CAAC,EAAE,IAAI;IAmC3E,yEAAyE;IACzE,MAAM,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI;IAqBvB,sDAAsD;IACtD,GAAG,CAAC,CAAC,EAAE,MAAM,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC;IASlC,SAAS,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI;IAgB1B,wDAAwD;IACxD,SAAS,CAAC,MAAM,EAAE,IAAI,GAAG,MAAM,EAAE;IAKjC;4EACwE;IACxE,MAAM,IAAI,GAAG,GAAG,IAAI;IAKpB;;;;;;;;OAQG;IACH,cAAc,IAAI,IAAI;IAetB,6EAA6E;IAC7E,OAAO,CAAC,aAAa;IAWrB,gFAAgF;IAChF,OAAO,CAAC,qBAAqB;IAW7B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAwCG;IACH,iBAAiB,CAAC,CAAC,EAAE,IAAI,GAAG,MAAM;IAoBlC;;;;;;;;;;;;;OAaG;IACH,aAAa,CAAC,CAAC,EAAE,IAAI,GAAG,OAAO;IAsB/B,wEAAwE;IACxE,WAAW,IAAI,MAAM;IAIrB,iEAAiE;IACjE,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;CAIhD"}