@ifc-lite/clash 1.7.0 → 1.9.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 (89) hide show
  1. package/README.md +18 -0
  2. package/dist/adapters/ifcx.d.ts.map +1 -1
  3. package/dist/adapters/ifcx.js +22 -36
  4. package/dist/adapters/ifcx.js.map +1 -1
  5. package/dist/adapters/shared.d.ts +61 -0
  6. package/dist/adapters/shared.d.ts.map +1 -0
  7. package/dist/adapters/shared.js +143 -0
  8. package/dist/adapters/shared.js.map +1 -0
  9. package/dist/adapters/step.d.ts +62 -3
  10. package/dist/adapters/step.d.ts.map +1 -1
  11. package/dist/adapters/step.js +180 -89
  12. package/dist/adapters/step.js.map +1 -1
  13. package/dist/analysis.d.ts +10 -1
  14. package/dist/analysis.d.ts.map +1 -1
  15. package/dist/analysis.js +20 -0
  16. package/dist/analysis.js.map +1 -1
  17. package/dist/contact/index.d.ts +14 -0
  18. package/dist/contact/index.d.ts.map +1 -1
  19. package/dist/contact/index.js +14 -0
  20. package/dist/contact/index.js.map +1 -1
  21. package/dist/contact/min-distance.d.ts +87 -0
  22. package/dist/contact/min-distance.d.ts.map +1 -0
  23. package/dist/contact/min-distance.js +255 -0
  24. package/dist/contact/min-distance.js.map +1 -0
  25. package/dist/contact/narrow-phase.d.ts +3 -2
  26. package/dist/contact/narrow-phase.d.ts.map +1 -1
  27. package/dist/contact/narrow-phase.js +32 -14
  28. package/dist/contact/narrow-phase.js.map +1 -1
  29. package/dist/contact/shared-faces.js +10 -1
  30. package/dist/contact/shared-faces.js.map +1 -1
  31. package/dist/contact/tri-tri.d.ts +33 -7
  32. package/dist/contact/tri-tri.d.ts.map +1 -1
  33. package/dist/contact/tri-tri.js +37 -14
  34. package/dist/contact/tri-tri.js.map +1 -1
  35. package/dist/duplicate-metric.d.ts +26 -8
  36. package/dist/duplicate-metric.d.ts.map +1 -1
  37. package/dist/duplicate-metric.js +26 -8
  38. package/dist/duplicate-metric.js.map +1 -1
  39. package/dist/duplicates.d.ts +9 -0
  40. package/dist/duplicates.d.ts.map +1 -1
  41. package/dist/duplicates.js +53 -18
  42. package/dist/duplicates.js.map +1 -1
  43. package/dist/engine-ts/broad.js +20 -2
  44. package/dist/engine-ts/broad.js.map +1 -1
  45. package/dist/engine-ts/depth.d.ts +99 -0
  46. package/dist/engine-ts/depth.d.ts.map +1 -0
  47. package/dist/engine-ts/depth.js +172 -0
  48. package/dist/engine-ts/depth.js.map +1 -0
  49. package/dist/engine-ts/kernel.d.ts +3 -1
  50. package/dist/engine-ts/kernel.d.ts.map +1 -1
  51. package/dist/engine-ts/narrow.d.ts +7 -1
  52. package/dist/engine-ts/narrow.d.ts.map +1 -1
  53. package/dist/engine-ts/narrow.js +53 -95
  54. package/dist/engine-ts/narrow.js.map +1 -1
  55. package/dist/engine-ts/obb.d.ts +116 -0
  56. package/dist/engine-ts/obb.d.ts.map +1 -0
  57. package/dist/engine-ts/obb.js +331 -0
  58. package/dist/engine-ts/obb.js.map +1 -0
  59. package/dist/engine-ts/orchestrator.d.ts.map +1 -1
  60. package/dist/engine-ts/orchestrator.js +3 -13
  61. package/dist/engine-ts/orchestrator.js.map +1 -1
  62. package/dist/engine-ts/tri-mesh.d.ts +88 -22
  63. package/dist/engine-ts/tri-mesh.d.ts.map +1 -1
  64. package/dist/engine-ts/tri-mesh.js +155 -48
  65. package/dist/engine-ts/tri-mesh.js.map +1 -1
  66. package/dist/engine-ts/ts-kernel.d.ts.map +1 -1
  67. package/dist/engine-ts/ts-kernel.js +1 -0
  68. package/dist/engine-ts/ts-kernel.js.map +1 -1
  69. package/dist/engine-wasm/wasm-kernel.d.ts.map +1 -1
  70. package/dist/engine-wasm/wasm-kernel.js +7 -0
  71. package/dist/engine-wasm/wasm-kernel.js.map +1 -1
  72. package/dist/index.d.ts +2 -2
  73. package/dist/index.d.ts.map +1 -1
  74. package/dist/index.js +2 -2
  75. package/dist/index.js.map +1 -1
  76. package/dist/math/aabb.d.ts +10 -1
  77. package/dist/math/aabb.d.ts.map +1 -1
  78. package/dist/math/aabb.js +33 -13
  79. package/dist/math/aabb.js.map +1 -1
  80. package/dist/selectors.d.ts.map +1 -1
  81. package/dist/selectors.js +20 -4
  82. package/dist/selectors.js.map +1 -1
  83. package/dist/triage.d.ts.map +1 -1
  84. package/dist/triage.js +11 -3
  85. package/dist/triage.js.map +1 -1
  86. package/dist/types.d.ts +39 -0
  87. package/dist/types.d.ts.map +1 -1
  88. package/dist/types.js.map +1 -1
  89. package/package.json +10 -9
@@ -1,68 +1,10 @@
1
1
  /* This Source Code Form is subject to the terms of the Mozilla Public
2
2
  * License, v. 2.0. If a copy of the MPL was not distributed with this
3
3
  * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
- /**
5
- * STEP / IFC2x3 / IFC4 source adapter: turn an `IfcDataStore` plus its meshes
6
- * into representation-agnostic `ClashElement`s, and precompute the
7
- * void/host/assembly pair exclusions from IFC relationships.
8
- *
9
- * This module is the only part of the package that depends on
10
- * `@ifc-lite/parser` / `@ifc-lite/query`; it is reached via the
11
- * `@ifc-lite/clash/step` subpath so the core stays version-neutral.
12
- */
13
- import { getInheritanceChainAcrossSchemas, isIfcTypeLikeEntity, } from '@ifc-lite/parser';
14
4
  import { EntityNode } from '@ifc-lite/query';
15
5
  import { makeExclusionSet, qualifiedKey } from '../exclude.js';
16
6
  import { fromPositions } from '../math/aabb.js';
17
- /**
18
- * Types that are never physical clash candidates: voids, virtual/reference
19
- * geometry, and non-product material associations. Including them produced
20
- * phantom clashes (IfcVirtualElement, IfcOpeningElement, even
21
- * IfcMaterialConstituent) that no clash rule referenced - they are dropped from
22
- * the candidate set entirely, so "detect all" and per-rule runs only ever
23
- * consider real building elements. (#1464)
24
- *
25
- * Spatial containers are handled separately by {@link isSpatialContainerTag},
26
- * which derives them from the schema rather than from a list.
27
- */
28
- const NON_CLASHABLE_TAGS = new Set([
29
- 'IfcOpeningElement',
30
- 'IfcOpeningStandardCase',
31
- 'IfcVirtualElement',
32
- 'IfcGrid',
33
- 'IfcGridAxis',
34
- 'IfcAnnotation',
35
- 'IfcMaterial',
36
- 'IfcMaterialConstituent',
37
- 'IfcMaterialLayer',
38
- ]);
39
- /** Memoizes the schema walk below; IFC type names are a bounded vocabulary. */
40
- const spatialContainerByTag = new Map();
41
- /**
42
- * True for spatial *containers* - the entities whose geometry describes an
43
- * extent that, by construction, encloses the elements assigned to it. A storey
44
- * against the slab it contains is not a coordination problem, and IFC4.3
45
- * infrastructure exports routinely give IfcBuildingStorey / IfcRoad / IfcBridge
46
- * tessellated bodies, so every contained element clashed with its own
47
- * container. (follow-up to #1464)
48
- *
49
- * Derived from the schema, not enumerated: `getInheritanceChainAcrossSchemas`
50
- * walks the bundled IFC2X3 + IFC4 + IFC4X3 union, so the IFC4.3 facility leaves
51
- * (IfcRoad, IfcBridge, IfcFacilityPart, ...) resolve even though the parser's
52
- * own codegen pin is IFC4_ADD2_TC1 and would return an empty chain for them.
53
- * Both supertypes are checked because IFC2X3 has no `IfcSpatialElement` -
54
- * `IfcSpatialStructureElement` descends straight from `IfcProduct` there.
55
- * This subsumes the IfcSpace / IfcSpatialZone entries that #1464 listed by hand.
56
- */
57
- function isSpatialContainerTag(tag) {
58
- const cached = spatialContainerByTag.get(tag);
59
- if (cached !== undefined)
60
- return cached;
61
- const chain = getInheritanceChainAcrossSchemas(tag);
62
- const spatial = chain.some((a) => a === 'IfcSpatialElement' || a === 'IfcSpatialStructureElement');
63
- spatialContainerByTag.set(tag, spatial);
64
- return spatial;
65
- }
7
+ import { isNonClashableTag, mergeMeshes } from './shared.js';
66
8
  /**
67
9
  * Lift local-frame vertices into the model's world frame: `world = origin + local`
68
10
  * (the inverse of the renderer's per-element local frame). Returns a fresh f32
@@ -77,14 +19,91 @@ function worldFramePositions(local, o) {
77
19
  }
78
20
  return out;
79
21
  }
22
+ /**
23
+ * The durable key for an element that has NO stored GlobalId — a malformed /
24
+ * fallback-only IFC root, or every element of a GLB-sourced model, whose store
25
+ * carries geometry and no IFC entities at all.
26
+ *
27
+ * ## Why the model id is in it
28
+ *
29
+ * `key` is the element identity that `clashReviewKey` (`../review.ts`) and the
30
+ * viewer's `elementPairExclusion` (`apps/viewer/src/lib/clash/exclusions.ts`)
31
+ * are BOTH keyed on, and both drop `model` on purpose — in the viewer that is a
32
+ * per-load `crypto.randomUUID()`, so folding it in would make every saved
33
+ * review and every saved rule go inert on the next reload. A GlobalId is
34
+ * globally unique, so that works. An express id is only unique WITHIN a model:
35
+ * every file is numbered from 1, so a bare `expressid:2` names an element in
36
+ * every model of a federation at once, and a review status or an exclusion set
37
+ * on one model's element would silently cover another model's element.
38
+ *
39
+ * ## Why it is encoded
40
+ *
41
+ * `clashReviewKey` composes `rule`, `a.key` and `b.key` with a SPACE, on the
42
+ * stated ground that a space never occurs inside an IfcGUID. A model id is not
43
+ * an IfcGUID — the CLI passes `basename(filePath)` — so it can. Percent-
44
+ * encoding is injective (distinct model ids stay distinct keys) and emits no
45
+ * space, so the separator assumption keeps holding.
46
+ *
47
+ * The `expressid:` prefix is unchanged, and this is a pure fallback: an element
48
+ * WITH a GlobalId is keyed on it exactly as before.
49
+ */
50
+ function syntheticKey(modelId, expressId) {
51
+ return `expressid:${encodeURIComponent(modelId)}:${expressId}`;
52
+ }
53
+ /**
54
+ * Whether this store carries ANY GlobalId at all — i.e. whether a total miss
55
+ * says something about the ids we used, or only about the file.
56
+ *
57
+ * Called at most once per `elementsFromStep`, and only on the already-degraded
58
+ * path, so the scan is off every normal run. It short-circuits on the first
59
+ * hit, which is the answer for any real IFC.
60
+ */
61
+ function storeHasAnyGlobalId(store) {
62
+ const { entities } = store;
63
+ for (let i = 0; i < entities.count; i += 1) {
64
+ if (entities.getGlobalId(entities.expressId[i]))
65
+ return true;
66
+ }
67
+ return false;
68
+ }
80
69
  export function elementsFromStep(options) {
81
- const { store, meshes, modelId, federation, worldTransform, buildExclusions = true } = options;
70
+ const { store, meshes, modelId, federation, worldTransform, buildExclusions = true, meshIdOffset = 0, } = options;
82
71
  const elements = [];
72
+ // One expressId can back MULTIPLE elements: a GPU-instanced entity is fed
73
+ // in as one `MeshData` per occurrence, all sharing one `expressId` but
74
+ // holding distinct world-space positions and a distinct `occurrenceKey`
75
+ // (see `MeshData.occurrenceKey` doc, `packages/geometry/src/types.ts`).
76
+ // `byExpressId` fans relationship exclusions (below, `buildStepExclusions`)
77
+ // out across every occurrence at each side of a relationship, so a host's
78
+ // void/assembly exclusions cover every physical placement of the
79
+ // filler/sibling, not just whichever occurrence happened to be built last
80
+ // (same remedy as #1405 / #2865).
83
81
  const byExpressId = new Map();
82
+ /** Elements whose GlobalId lookup came back empty — see the check below. */
83
+ let missingGlobalIds = 0;
84
+ // Pass 1: group every mesh by its OWNING OCCURRENCE — `occurrenceKey` when
85
+ // present (a GPU-instanced entity's individual placement), else the bare
86
+ // expressId (every other mesh: at most one MeshData per expressId, so the
87
+ // expressId alone already identifies the occurrence) — filtering
88
+ // non-clashable tags and empty geometry up front, and folding each mesh's
89
+ // own origin into world-frame positions as it is collected. An entity with
90
+ // several mesh representations of the SAME occurrence (Body + Axis, several
91
+ // sub-meshes, ...) must become exactly ONE `ClashElement`, never one per
92
+ // mesh — see `./shared.ts`'s `mergeMeshes` doc for why, and `ifcx.ts` for
93
+ // the sibling adapter this mirrors. Grouping by the bare expressId alone
94
+ // (dropping `occurrenceKey`) would instead coalesce DISTINCT physical
95
+ // occurrences that merely share one expressId into one element, merging
96
+ // their geometry (and bounds) across unrelated world-space locations.
97
+ const groups = new Map();
98
+ const groupMeta = new Map();
84
99
  for (const mesh of meshes) {
85
100
  if (!mesh.positions || mesh.positions.length === 0)
86
101
  continue;
87
- const expressId = mesh.expressId;
102
+ // STORE-LOCAL id. Everything below that touches `store` — the entity table,
103
+ // `EntityNode`, the relationship graph in `buildStepExclusions` — must use
104
+ // this, never `mesh.expressId`, which the host may already have shifted
105
+ // into the global id space (see `meshIdOffset`).
106
+ const expressId = mesh.expressId - meshIdOffset;
88
107
  const node = new EntityNode(store, expressId);
89
108
  // Drop non-physical / non-product geometry up front so it never becomes a
90
109
  // clash candidate (no rule should have to exclude IfcSpace by hand). (#1464)
@@ -104,9 +123,7 @@ export function elementsFromStep(options) {
104
123
  // (which always shows classes 1 and 2) is a catalogue, not a place clash
105
124
  // runs from. Clashing origin-stacked templates against each other would be
106
125
  // pure noise, so excluding class 1 is the intended reading, not collateral.
107
- if (NON_CLASHABLE_TAGS.has(tag) ||
108
- isSpatialContainerTag(tag) ||
109
- isIfcTypeLikeEntity(tag.toUpperCase()))
126
+ if (isNonClashableTag(tag))
110
127
  continue;
111
128
  // The wasm geometry path stores positions in the element's LOCAL frame
112
129
  // (world = origin + position; see `MeshData.origin`). Clash works in world
@@ -119,32 +136,100 @@ export function elementsFromStep(options) {
119
136
  const positions = o && (o[0] !== 0 || o[1] !== 0 || o[2] !== 0)
120
137
  ? worldFramePositions(mesh.positions, o)
121
138
  : mesh.positions;
139
+ const occurrenceId = mesh.occurrenceKey ?? String(expressId);
140
+ const group = groups.get(occurrenceId);
141
+ if (group) {
142
+ group.push({ positions, indices: mesh.indices });
143
+ }
144
+ else {
145
+ groups.set(occurrenceId, [{ positions, indices: mesh.indices }]);
146
+ groupMeta.set(occurrenceId, { tag, expressId, occurrenceKey: mesh.occurrenceKey });
147
+ }
148
+ }
149
+ // Pass 2: one ClashElement per OCCURRENCE, geometry merged across every
150
+ // mesh of that same occurrence that survived the filter above.
151
+ for (const [occurrenceId, meshGroup] of groups) {
152
+ const { tag, expressId, occurrenceKey } = groupMeta.get(occurrenceId);
153
+ const node = new EntityNode(store, expressId);
154
+ const merged = mergeMeshes(meshGroup);
122
155
  // Read stored (table-backed) values directly. `node.globalId` / `node.name`
123
156
  // fall back to `extractEntityAttributesOnDemand` when the table value is
124
157
  // empty (common: Name is optional, globalId is empty for fallback-only /
125
- // malformed roots) — and with a fresh node per mesh that fallback would fire
126
- // once per element inside this loop (AGENTS.md hot-loop ban). The table
127
- // getters never trigger on-demand extraction. `node.type` (getTypeName) and
128
- // `node.storey()` (relationship-only) are table-backed and stay.
158
+ // malformed roots) — and with a fresh node per entity that fallback would
159
+ // fire once per element inside this loop (AGENTS.md hot-loop ban). The
160
+ // table getters never trigger on-demand extraction. `node.type`
161
+ // (getTypeName) and `node.storey()` (relationship-only) are table-backed
162
+ // and stay.
129
163
  const storedGlobalId = store.entities.getGlobalId(expressId);
130
164
  const storedName = store.entities.getName(expressId);
131
- // Fall back to a model-scoped synthetic key rather than dropping geometry:
132
- // malformed IFC roots / fallback-only elements still participate in clashes.
133
- const key = storedGlobalId || `expressid:${expressId}`;
165
+ // Fall back to a MODEL-SCOPED synthetic key rather than dropping geometry:
166
+ // malformed IFC roots, and whole GLB-sourced models, still participate in
167
+ // clashes. See {@link syntheticKey} for why the model id belongs in it.
168
+ const baseKey = storedGlobalId || syntheticKey(modelId, expressId);
169
+ // A GPU-instanced occurrence carries `mesh.occurrenceKey`; fold it into the
170
+ // identity so distinct physical occurrences of one expressId don't collapse
171
+ // onto one review/exclusion key. Flat meshes are unaffected (occurrenceKey
172
+ // absent, one bucket per expressId as before).
173
+ const key = occurrenceKey ? `${baseKey}:${occurrenceKey}` : baseKey;
174
+ if (!storedGlobalId)
175
+ missingGlobalIds += 1;
134
176
  const element = {
135
177
  key,
178
+ // `expressId` is local here, so the offset is applied exactly ONCE and
179
+ // the result is the id the renderer/selection channel already uses for
180
+ // this mesh — i.e. `mesh.expressId` again, whenever `meshIdOffset` and
181
+ // the federation agree (they are both read off the same `model.idOffset`
182
+ // in the viewer). See the federated round-trip test in `step.test.ts`.
183
+ // Deliberately shared across every occurrence of one expressId — the
184
+ // renderer/selection channel addresses instanced occurrences by their
185
+ // shared source entity id, not a per-occurrence one.
136
186
  ref: federation ? federation.toGlobalId(modelId, expressId) : expressId,
137
187
  model: modelId,
138
188
  tag,
139
189
  name: storedName || undefined,
140
190
  storey: node.storey()?.name || undefined,
141
- bounds: fromPositions(positions, worldTransform),
142
- positions,
143
- indices: mesh.indices,
191
+ bounds: fromPositions(merged.positions, worldTransform),
192
+ positions: merged.positions,
193
+ indices: merged.indices,
144
194
  transform: worldTransform,
145
195
  };
146
196
  elements.push(element);
147
- byExpressId.set(expressId, element);
197
+ const bucket = byExpressId.get(expressId);
198
+ if (bucket)
199
+ bucket.push(element);
200
+ else
201
+ byExpressId.set(expressId, [element]);
202
+ }
203
+ // A wrong `meshIdOffset` — above all a FORGOTTEN one — leaves ids that are
204
+ // positive, plausible and simply address the wrong rows, so nothing about an
205
+ // individual id gives it away. Its signature is the SHAPE of the damage:
206
+ // EVERY GlobalId lookup misses, never just some. A real file can carry the
207
+ // occasional fallback-only root with no GlobalId, but "not one element in
208
+ // this model has one" is a host wiring bug, and it is silent otherwise —
209
+ // `key` degrades to the synthetic fallback, `buildStepExclusions` below finds
210
+ // no relationships, and the caller gets a plausible-looking result set with
211
+ // the void/host/assembly exclusions quietly disabled.
212
+ //
213
+ // The `storeHasAnyGlobalId` guard is what keeps that from crying wolf. A
214
+ // total miss means "the ids we used are wrong" only if there was something to
215
+ // hit: a GLB-sourced model has an ENTITY-LESS store
216
+ // (`createMinimalGlbDataStore` -> `createSyntheticDataStore` in the viewer),
217
+ // so EVERY element missing is its normal, correct state, and warning on it
218
+ // would fire on a correct configuration on every run — which teaches people
219
+ // to ignore the one message that reports the real defect. The same goes for a
220
+ // file whose roots carry no GlobalId at all. When the store does hold
221
+ // GlobalIds and not one of our ids reached them, the ids are the problem.
222
+ //
223
+ // One `if` outside the loop, and the scan behind it runs only when the whole
224
+ // model already missed: no per-element cost.
225
+ if (elements.length > 0 &&
226
+ missingGlobalIds === elements.length &&
227
+ storeHasAnyGlobalId(store)) {
228
+ console.warn(`[clash/step] every element in model "${modelId}" (${elements.length}) resolved to an ` +
229
+ `empty GlobalId. This usually means \`meshIdOffset\` (used: ${meshIdOffset}) does not ` +
230
+ 'match the shift the host applied to `mesh.expressId`, so the store is being addressed ' +
231
+ 'with ids it does not contain — element keys, names and the void/host exclusions are ' +
232
+ 'all degraded.');
148
233
  }
149
234
  const exclusions = buildExclusions
150
235
  ? buildStepExclusions(store, byExpressId)
@@ -162,19 +247,28 @@ export function elementsFromStep(options) {
162
247
  */
163
248
  export function buildStepExclusions(store, byExpressId) {
164
249
  const pairs = [];
165
- for (const [expressId, element] of byExpressId) {
250
+ for (const [expressId, elementsAtId] of byExpressId) {
166
251
  const node = new EntityNode(store, expressId);
167
- const ek = qualifiedKey(element.model, element.key);
168
- for (const opening of node.voids()) {
169
- const openingElement = byExpressId.get(opening.expressId);
170
- if (openingElement) {
171
- pairs.push([ek, qualifiedKey(openingElement.model, openingElement.key)]);
252
+ // A relationship is stated between EXPRESS ids, not occurrences: fan it
253
+ // out across every occurrence bucketed at each side (usually one element
254
+ // each; more than one only for a GPU-instanced expressId), so a host's
255
+ // void/assembly exclusions cover every physical placement of the
256
+ // filler/sibling, not just whichever occurrence happened to be built last.
257
+ const pairAll = (otherId) => {
258
+ const others = byExpressId.get(otherId);
259
+ if (!others)
260
+ return;
261
+ for (const a of elementsAtId) {
262
+ const ek = qualifiedKey(a.model, a.key);
263
+ for (const b of others) {
264
+ pairs.push([ek, qualifiedKey(b.model, b.key)]);
265
+ }
172
266
  }
267
+ };
268
+ for (const opening of node.voids()) {
269
+ pairAll(opening.expressId);
173
270
  for (const filler of opening.filledBy()) {
174
- const fillerElement = byExpressId.get(filler.expressId);
175
- if (fillerElement) {
176
- pairs.push([ek, qualifiedKey(fillerElement.model, fillerElement.key)]);
177
- }
271
+ pairAll(filler.expressId);
178
272
  }
179
273
  }
180
274
  const parent = node.decomposedBy();
@@ -182,10 +276,7 @@ export function buildStepExclusions(store, byExpressId) {
182
276
  for (const sibling of parent.decomposes()) {
183
277
  if (sibling.expressId === expressId)
184
278
  continue;
185
- const siblingElement = byExpressId.get(sibling.expressId);
186
- if (siblingElement) {
187
- pairs.push([ek, qualifiedKey(siblingElement.model, siblingElement.key)]);
188
- }
279
+ pairAll(sibling.expressId);
189
280
  }
190
281
  }
191
282
  }
@@ -1 +1 @@
1
- {"version":3,"file":"step.js","sourceRoot":"","sources":["../../src/adapters/step.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"step.js","sourceRoot":"","sources":["../../src/adapters/step.ts"],"names":[],"mappings":"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"}
@@ -8,7 +8,16 @@
8
8
  * beam interpenetration and a shallow one share a severity. These helpers add
9
9
  * the geometric dimension (depth) so the two can be combined when prioritising.
10
10
  */
11
- import type { Clash, ClashResult, ClashRuleCoverage, ClashSeverity } from './types.js';
11
+ import type { Clash, ClashResult, ClashRuleCoverage, ClashSeverity, ClashSummary } from './types.js';
12
+ /**
13
+ * Tally a clash list into a {@link ClashSummary}: totals per rule, per sorted
14
+ * element-type pair, and per severity.
15
+ *
16
+ * Single home for the tally, so a result built by the engine, by the duplicate
17
+ * scan, or by a consumer that filtered a result down (e.g. user exclusions)
18
+ * cannot report buckets that disagree with `clashes`.
19
+ */
20
+ export declare function summarizeClashes(clashes: readonly Clash[]): ClashSummary;
12
21
  /** Severity ordering, most-severe first (lower rank = more severe). */
13
22
  export declare const SEVERITY_RANK: Record<ClashSeverity, number>;
14
23
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"analysis.d.ts","sourceRoot":"","sources":["../src/analysis.ts"],"names":[],"mappings":"AAIA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEvF,uEAAuE;AACvE,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAKvD,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,KAAK,GAAG,MAAM,CAEjD;AAED;;;;0EAI0E;AAC1E,eAAO,MAAM,gBAAgB,SAAO,CAAC;AA4CrC;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,GAAE,MAA8B,GAAG,OAAO,CAEjF;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CAEnE;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,MAAM,mBAAmB,GAAG,OAAO,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,CAAC;AAE/E,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,mBAAmB,CAOnG;AAED,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG,OAAO,GAAG,UAAU,CAAC;AAM5D;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,SAAS,KAAK,EAAE,EAAE,EAAE,EAAE,WAAW,GAAG,KAAK,EAAE,CAmB/E"}
1
+ {"version":3,"file":"analysis.d.ts","sourceRoot":"","sources":["../src/analysis.ts"],"names":[],"mappings":"AAIA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAErG;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,SAAS,KAAK,EAAE,GAAG,YAAY,CAWxE;AAED,uEAAuE;AACvE,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAKvD,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,KAAK,GAAG,MAAM,CAEjD;AAED;;;;0EAI0E;AAC1E,eAAO,MAAM,gBAAgB,SAAO,CAAC;AA4CrC;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,GAAE,MAA8B,GAAG,OAAO,CAEjF;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CAEnE;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,MAAM,mBAAmB,GAAG,OAAO,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,CAAC;AAE/E,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,mBAAmB,CAOnG;AAED,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG,OAAO,GAAG,UAAU,CAAC;AAM5D;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,SAAS,KAAK,EAAE,EAAE,EAAE,EAAE,WAAW,GAAG,KAAK,EAAE,CAmB/E"}
package/dist/analysis.js CHANGED
@@ -1,6 +1,26 @@
1
1
  /* This Source Code Form is subject to the terms of the Mozilla Public
2
2
  * License, v. 2.0. If a copy of the MPL was not distributed with this
3
3
  * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+ /**
5
+ * Tally a clash list into a {@link ClashSummary}: totals per rule, per sorted
6
+ * element-type pair, and per severity.
7
+ *
8
+ * Single home for the tally, so a result built by the engine, by the duplicate
9
+ * scan, or by a consumer that filtered a result down (e.g. user exclusions)
10
+ * cannot report buckets that disagree with `clashes`.
11
+ */
12
+ export function summarizeClashes(clashes) {
13
+ const byRule = {};
14
+ const byTypePair = {};
15
+ const bySeverity = { critical: 0, major: 0, minor: 0, info: 0 };
16
+ for (const c of clashes) {
17
+ byRule[c.rule] = (byRule[c.rule] ?? 0) + 1;
18
+ const pair = [c.a.tag, c.b.tag].sort().join(' vs ');
19
+ byTypePair[pair] = (byTypePair[pair] ?? 0) + 1;
20
+ bySeverity[c.severity] += 1;
21
+ }
22
+ return { total: clashes.length, byRule, byTypePair, bySeverity };
23
+ }
4
24
  /** Severity ordering, most-severe first (lower rank = more severe). */
5
25
  export const SEVERITY_RANK = {
6
26
  critical: 0,
@@ -1 +1 @@
1
- {"version":3,"file":"analysis.js","sourceRoot":"","sources":["../src/analysis.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAe/D,uEAAuE;AACvE,MAAM,CAAC,MAAM,aAAa,GAAkC;IAC1D,QAAQ,EAAE,CAAC;IACX,KAAK,EAAE,CAAC;IACR,KAAK,EAAE,CAAC;IACR,IAAI,EAAE,CAAC;CACR,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAAC,CAAQ;IACvC,OAAO,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;AAC1C,CAAC;AAED;;;;0EAI0E;AAC1E,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,CAAC;AAErC;;;;;;;;GAQG;AACH,MAAM,aAAa,GAAG,CAAC,GAAG,SAAS,CAAC,CAAC,QAAQ;AAE7C;;;;;;;;;;;;;;;;;;;GAmBG;AACH,SAAS,kBAAkB,CAAC,CAAQ;IAClC,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;QAC7C,KAAK,MAAM,KAAK,IAAI,CAAC,EAAE,CAAC;YACtB,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YAC1B,IAAI,CAAC,GAAG,MAAM;gBAAE,MAAM,GAAG,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC,GAAG,CAAC,gBAAgB,EAAE,MAAM,GAAG,aAAa,CAAC,CAAC;AAC5D,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,UAAU,CAAC,CAAQ,EAAE,MAAc,kBAAkB,CAAC,CAAC,CAAC;IACtE,OAAO,CAAC,CAAC,MAAM,KAAK,OAAO,IAAI,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,IAAI,gBAAgB,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC;AACrF,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,QAA2B;IACxD,OAAO,QAAQ,CAAC,QAAQ,KAAK,CAAC,IAAI,QAAQ,CAAC,QAAQ,KAAK,CAAC,CAAC;AAC5D,CAAC;AAuBD,MAAM,UAAU,oBAAoB,CAAC,MAAyC;IAC5E,MAAM,QAAQ,GAAG,MAAM,CAAC,YAAY,CAAC;IACrC,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IACzD,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,MAAM,CAAC;IAC1D,IAAI,UAAU,KAAK,CAAC;QAAE,OAAO,OAAO,CAAC;IACrC,IAAI,UAAU,KAAK,QAAQ,CAAC,MAAM;QAAE,OAAO,UAAU,CAAC;IACtD,OAAO,SAAS,CAAC;AACnB,CAAC;AAID,SAAS,KAAK,CAAC,CAAQ,EAAE,CAAQ;IAC/B,OAAO,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAChD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,OAAyB,EAAE,EAAe;IACpE,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;IAC5B,QAAQ,EAAE,EAAE,CAAC;QACX,KAAK,UAAU;YACb,GAAG,CAAC,IAAI,CACN,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CACP,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC;gBACrD,gBAAgB,CAAC,CAAC,CAAC,GAAG,gBAAgB,CAAC,CAAC,CAAC;gBACzC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CACd,CAAC;YACF,MAAM;QACR,KAAK,OAAO;YACV,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC,GAAG,gBAAgB,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YAC7E,MAAM;QACR,KAAK,UAAU;YACb,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,IAAI,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YAC3D,MAAM;IACV,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
1
+ {"version":3,"file":"analysis.js","sourceRoot":"","sources":["../src/analysis.ts"],"names":[],"mappings":"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"}
@@ -20,6 +20,20 @@ export type { Mesh, Vec3, AABB } from './types.js';
20
20
  export type { SharedFaceCluster, SharedFaceOptions } from './shared-faces.js';
21
21
  export type { TrianglePair, NarrowPhaseOptions } from './narrow-phase.js';
22
22
  export { narrowPhase, clusterSharedFaces };
23
+ /**
24
+ * Minimum-distance query, exposed here rather than left package-private
25
+ * because every consumer that wants it lives outside this package. The
26
+ * viewer's measure tool needs the exact surface-to-surface distance, and
27
+ * before this it could not reach any of the machinery: `triTriDistance` sits
28
+ * under `math/`, which has no export subpath, so a deep import is hard-blocked
29
+ * by `ERR_PACKAGE_PATH_NOT_EXPORTED`.
30
+ *
31
+ * `buildMeshBvh` / `queryMeshCross` come with it: a caller measuring one
32
+ * element against several should build each tree once rather than pay for it
33
+ * per query.
34
+ */
35
+ export { minDistanceBetweenMeshes, minDistanceBetweenBvhs, type MeshDistance, type MinDistanceOptions, } from './min-distance.js';
36
+ export { buildMeshBvh, queryMeshCross, type MeshBvh } from './mesh-bvh.js';
23
37
  export interface ContactOptions extends NarrowPhaseOptions, SharedFaceOptions {
24
38
  }
25
39
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/contact/index.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,WAAW,EAAE,KAAK,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACzE,OAAO,EACL,kBAAkB,EAClB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACvB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,IAAI,EAAQ,MAAM,YAAY,CAAC;AAE7C,YAAY,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AACnD,YAAY,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC9E,YAAY,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC1E,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,CAAC;AAE3C,MAAM,WAAW,cAAe,SAAQ,kBAAkB,EAAE,iBAAiB;CAAG;AAEhF;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,GAAE,cAAmB,GAAG,iBAAiB,EAAE,CAIhG"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/contact/index.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,WAAW,EAAE,KAAK,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACzE,OAAO,EACL,kBAAkB,EAClB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACvB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,IAAI,EAAQ,MAAM,YAAY,CAAC;AAE7C,YAAY,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AACnD,YAAY,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC9E,YAAY,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC1E,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,CAAC;AAE3C;;;;;;;;;;;GAWG;AACH,OAAO,EACL,wBAAwB,EACxB,sBAAsB,EACtB,KAAK,YAAY,EACjB,KAAK,kBAAkB,GACxB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,KAAK,OAAO,EAAE,MAAM,eAAe,CAAC;AAE3E,MAAM,WAAW,cAAe,SAAQ,kBAAkB,EAAE,iBAAiB;CAAG;AAEhF;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,GAAE,cAAmB,GAAG,iBAAiB,EAAE,CAIhG"}
@@ -19,6 +19,20 @@
19
19
  import { narrowPhase } from './narrow-phase.js';
20
20
  import { clusterSharedFaces, } from './shared-faces.js';
21
21
  export { narrowPhase, clusterSharedFaces };
22
+ /**
23
+ * Minimum-distance query, exposed here rather than left package-private
24
+ * because every consumer that wants it lives outside this package. The
25
+ * viewer's measure tool needs the exact surface-to-surface distance, and
26
+ * before this it could not reach any of the machinery: `triTriDistance` sits
27
+ * under `math/`, which has no export subpath, so a deep import is hard-blocked
28
+ * by `ERR_PACKAGE_PATH_NOT_EXPORTED`.
29
+ *
30
+ * `buildMeshBvh` / `queryMeshCross` come with it: a caller measuring one
31
+ * element against several should build each tree once rather than pay for it
32
+ * per query.
33
+ */
34
+ export { minDistanceBetweenMeshes, minDistanceBetweenBvhs, } from './min-distance.js';
35
+ export { buildMeshBvh, queryMeshCross } from './mesh-bvh.js';
22
36
  /**
23
37
  * Compute the contact interface(s) between two world-space meshes: the real
24
38
  * shared-face polygon (surface), intersection line, or point — not an AABB.
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/contact/index.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,WAAW,EAA2B,MAAM,mBAAmB,CAAC;AACzE,OAAO,EACL,kBAAkB,GAGnB,MAAM,mBAAmB,CAAC;AAM3B,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,CAAC;AAI3C;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,CAAO,EAAE,CAAO,EAAE,OAAuB,EAAE;IACzE,MAAM,KAAK,GAAG,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;IACtC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAClC,OAAO,kBAAkB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;AACzC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/contact/index.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,WAAW,EAA2B,MAAM,mBAAmB,CAAC;AACzE,OAAO,EACL,kBAAkB,GAGnB,MAAM,mBAAmB,CAAC;AAM3B,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,CAAC;AAE3C;;;;;;;;;;;GAWG;AACH,OAAO,EACL,wBAAwB,EACxB,sBAAsB,GAGvB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,YAAY,EAAE,cAAc,EAAgB,MAAM,eAAe,CAAC;AAI3E;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,CAAO,EAAE,CAAO,EAAE,OAAuB,EAAE;IACzE,MAAM,KAAK,GAAG,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;IACtC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAClC,OAAO,kBAAkB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;AACzC,CAAC"}
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Minimum distance between two world-space meshes, with the witness points.
3
+ *
4
+ * Why this is a new traversal rather than a new predicate: the exact
5
+ * triangle-to-triangle minimum distance already exists as `triTriDistance`
6
+ * (`../math/triangle-distance.ts`), and a second copy of that math would be one
7
+ * more thing to keep in step. What did NOT exist anywhere in this package is a
8
+ * traversal that can find the CLOSEST pair.
9
+ *
10
+ * Every other query here is an OVERLAP predicate: `Bvh.queryAABB`,
11
+ * `Bvh.queryPairs` and `queryMeshCross` all prune on AABB intersection, so for
12
+ * two disjoint meshes they return an empty candidate set and there is nothing
13
+ * left to measure. Inflating a clash `clearance` does not substitute either:
14
+ * `testPair` only ever considers triangle pairs already within its margin, so
15
+ * the answer is capped by the margin you guessed rather than found.
16
+ *
17
+ * So this is branch-and-bound over the two BVHs: descend the node pair whose
18
+ * AABB-to-AABB LOWER bound is smallest, and prune any pair whose lower bound is
19
+ * already >= the best real distance found so far. The bound is exact for
20
+ * axis-aligned boxes and never exceeds the true triangle distance, which is
21
+ * what makes the pruning safe: a pruned subtree cannot contain a closer pair.
22
+ */
23
+ import { type MeshBvh } from './mesh-bvh.js';
24
+ import type { BvhNode } from './bvh.js';
25
+ import type { Mesh, Vec3 } from './types.js';
26
+ export interface MeshDistance {
27
+ /** Minimum distance between the two surfaces. 0 when they touch or overlap. */
28
+ readonly distance: number;
29
+ /** Witness point on mesh A. */
30
+ readonly pointA: Vec3;
31
+ /** Witness point on mesh B. */
32
+ readonly pointB: Vec3;
33
+ /** Triangle indices the witness points lie on. */
34
+ readonly triangleA: number;
35
+ readonly triangleB: number;
36
+ }
37
+ export interface MinDistanceOptions {
38
+ /** Triangles per BVH leaf. Default 8, matching `buildMeshBvh`. */
39
+ readonly leafSize?: number;
40
+ /**
41
+ * Stop as soon as a distance at or below this is found. Use 0 to stop on
42
+ * first contact when only "do they touch" matters; leave unset for the exact
43
+ * distance.
44
+ */
45
+ readonly earlyExitAtOrBelow?: number;
46
+ }
47
+ /** A node pair waiting to be explored, with its lower bound on any pair beneath it. */
48
+ export interface PairEntry {
49
+ na: BvhNode;
50
+ nb: BvhNode;
51
+ lowerSq: number;
52
+ }
53
+ /**
54
+ * Binary min-heap over `lowerSq`. Exported for its own tests but deliberately
55
+ * NOT re-exported from `contact/index.ts`, so it stays out of the package's
56
+ * public surface: it is an implementation detail of the traversal, and a
57
+ * hand-rolled sift is precisely the kind of code that needs a direct contract
58
+ * test rather than being covered incidentally.
59
+ *
60
+ * Note that a broken heap order does NOT break the RESULT — the traversal
61
+ * still visits every unpruned pair and still finds the true minimum, just
62
+ * slower. That is why the distance tests cannot catch an inverted comparison
63
+ * here, and why this class is tested on its own terms.
64
+ *
65
+ * Small and local on purpose: this is the only
66
+ * priority queue in the package, and pulling in a dependency (or a generic
67
+ * implementation) for one traversal would be more surface than the ~25 lines
68
+ * it replaces.
69
+ */
70
+ export declare class PairHeap {
71
+ private readonly items;
72
+ push(entry: PairEntry): void;
73
+ pop(): PairEntry | undefined;
74
+ }
75
+ /**
76
+ * Exact minimum distance between two meshes, or `null` when either has no
77
+ * triangles (there is no distance to a mesh that is not there — deliberately
78
+ * distinct from returning 0, which would read as "they touch").
79
+ */
80
+ export declare function minDistanceBetweenMeshes(a: Mesh, b: Mesh, opts?: MinDistanceOptions): MeshDistance | null;
81
+ /**
82
+ * Same, for callers that already hold the BVHs. Worth having separately: the
83
+ * BVH is the expensive part, and a measure tool asking about one element
84
+ * against several others should build each mesh's tree once.
85
+ */
86
+ export declare function minDistanceBetweenBvhs(a: MeshBvh, b: MeshBvh, opts?: MinDistanceOptions): MeshDistance | null;
87
+ //# sourceMappingURL=min-distance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"min-distance.d.ts","sourceRoot":"","sources":["../../src/contact/min-distance.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAgB,KAAK,OAAO,EAAE,MAAM,eAAe,CAAC;AAI3D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,KAAK,EAAQ,IAAI,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEnD,MAAM,WAAW,YAAY;IAC3B,+EAA+E;IAC/E,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,+BAA+B;IAC/B,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC;IACtB,+BAA+B;IAC/B,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC;IACtB,kDAAkD;IAClD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,kBAAkB;IACjC,kEAAkE;IAClE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;OAIG;IACH,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;CACtC;AAmBD,uFAAuF;AACvF,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,OAAO,CAAC;IACZ,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,QAAQ;IACnB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAmB;IAEzC,IAAI,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI;IAY5B,GAAG,IAAI,SAAS,GAAG,SAAS;CAoB7B;AAUD;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,CAAC,EAAE,IAAI,EACP,CAAC,EAAE,IAAI,EACP,IAAI,GAAE,kBAAuB,GAC5B,YAAY,GAAG,IAAI,CAIrB;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,CAAC,EAAE,OAAO,EACV,CAAC,EAAE,OAAO,EACV,IAAI,GAAE,kBAAuB,GAC5B,YAAY,GAAG,IAAI,CAsIrB"}