@ifc-lite/clash 1.7.0 → 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.
- package/dist/analysis.d.ts +10 -1
- package/dist/analysis.d.ts.map +1 -1
- package/dist/analysis.js +20 -0
- package/dist/analysis.js.map +1 -1
- package/dist/contact/narrow-phase.d.ts +3 -2
- package/dist/contact/narrow-phase.d.ts.map +1 -1
- package/dist/contact/narrow-phase.js +32 -14
- package/dist/contact/narrow-phase.js.map +1 -1
- package/dist/contact/tri-tri.d.ts +33 -7
- package/dist/contact/tri-tri.d.ts.map +1 -1
- package/dist/contact/tri-tri.js +37 -14
- package/dist/contact/tri-tri.js.map +1 -1
- package/dist/duplicate-metric.d.ts +26 -8
- package/dist/duplicate-metric.d.ts.map +1 -1
- package/dist/duplicate-metric.js +26 -8
- package/dist/duplicate-metric.js.map +1 -1
- package/dist/duplicates.d.ts +9 -0
- package/dist/duplicates.d.ts.map +1 -1
- package/dist/duplicates.js +53 -18
- package/dist/duplicates.js.map +1 -1
- package/dist/engine-ts/depth.d.ts +99 -0
- package/dist/engine-ts/depth.d.ts.map +1 -0
- package/dist/engine-ts/depth.js +172 -0
- package/dist/engine-ts/depth.js.map +1 -0
- package/dist/engine-ts/kernel.d.ts +3 -1
- package/dist/engine-ts/kernel.d.ts.map +1 -1
- package/dist/engine-ts/narrow.d.ts +7 -1
- package/dist/engine-ts/narrow.d.ts.map +1 -1
- package/dist/engine-ts/narrow.js +53 -95
- package/dist/engine-ts/narrow.js.map +1 -1
- package/dist/engine-ts/obb.d.ts +116 -0
- package/dist/engine-ts/obb.d.ts.map +1 -0
- package/dist/engine-ts/obb.js +331 -0
- package/dist/engine-ts/obb.js.map +1 -0
- package/dist/engine-ts/orchestrator.d.ts.map +1 -1
- package/dist/engine-ts/orchestrator.js +3 -13
- package/dist/engine-ts/orchestrator.js.map +1 -1
- package/dist/engine-ts/tri-mesh.d.ts +84 -22
- package/dist/engine-ts/tri-mesh.d.ts.map +1 -1
- package/dist/engine-ts/tri-mesh.js +151 -48
- package/dist/engine-ts/tri-mesh.js.map +1 -1
- package/dist/engine-ts/ts-kernel.d.ts.map +1 -1
- package/dist/engine-ts/ts-kernel.js +1 -0
- package/dist/engine-ts/ts-kernel.js.map +1 -1
- package/dist/engine-wasm/wasm-kernel.d.ts.map +1 -1
- package/dist/engine-wasm/wasm-kernel.js +7 -0
- package/dist/engine-wasm/wasm-kernel.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/math/aabb.d.ts +10 -1
- package/dist/math/aabb.d.ts.map +1 -1
- package/dist/math/aabb.js +33 -13
- package/dist/math/aabb.js.map +1 -1
- package/dist/triage.d.ts.map +1 -1
- package/dist/triage.js +11 -3
- package/dist/triage.js.map +1 -1
- package/dist/types.d.ts +39 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +4 -3
|
@@ -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":"
|
|
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
|
|
@@ -80,6 +81,7 @@ export async function runClash(elements, rules, settings, kernel) {
|
|
|
80
81
|
rule: rule.id,
|
|
81
82
|
status: rec.status,
|
|
82
83
|
distance: rec.distance,
|
|
84
|
+
distanceKind: rec.distanceKind,
|
|
83
85
|
point: rec.point,
|
|
84
86
|
bounds: rec.bounds,
|
|
85
87
|
severity: rule.severity ?? inferClashSeverity(elA.tag, elB.tag),
|
|
@@ -93,7 +95,7 @@ export async function runClash(elements, rules, settings, kernel) {
|
|
|
93
95
|
clashes.sort(byKeyThenRule);
|
|
94
96
|
const result = {
|
|
95
97
|
clashes,
|
|
96
|
-
summary:
|
|
98
|
+
summary: summarizeClashes(clashes),
|
|
97
99
|
rulesRun: rules,
|
|
98
100
|
ruleCoverage,
|
|
99
101
|
settings: { tolerance, excludeVoidsAndHosts },
|
|
@@ -119,16 +121,4 @@ function byKeyThenRule(x, y) {
|
|
|
119
121
|
function cmp(a, b) {
|
|
120
122
|
return a < b ? -1 : a > b ? 1 : 0;
|
|
121
123
|
}
|
|
122
|
-
function buildSummary(clashes) {
|
|
123
|
-
const byRule = {};
|
|
124
|
-
const byTypePair = {};
|
|
125
|
-
const bySeverity = { critical: 0, major: 0, minor: 0, info: 0 };
|
|
126
|
-
for (const c of clashes) {
|
|
127
|
-
byRule[c.rule] = (byRule[c.rule] ?? 0) + 1;
|
|
128
|
-
const pair = [c.a.tag, c.b.tag].sort().join(' vs ');
|
|
129
|
-
byTypePair[pair] = (byTypePair[pair] ?? 0) + 1;
|
|
130
|
-
bySeverity[c.severity] += 1;
|
|
131
|
-
}
|
|
132
|
-
return { total: clashes.length, byRule, byTypePair, bySeverity };
|
|
133
|
-
}
|
|
134
124
|
//# sourceMappingURL=orchestrator.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"orchestrator.js","sourceRoot":"","sources":["../../src/engine-ts/orchestrator.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AACzD,OAAO,EACL,sBAAsB,
|
|
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
|
-
|
|
34
|
-
|
|
35
|
-
|
|
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
|
|
44
|
-
*
|
|
45
|
-
* the
|
|
46
|
-
*
|
|
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
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
* `
|
|
56
|
-
*
|
|
57
|
-
*
|
|
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;
|
|
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"}
|