@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.
- package/dist/adapters/step.d.ts.map +1 -1
- package/dist/adapters/step.js +19 -2
- package/dist/adapters/step.js.map +1 -1
- package/dist/analysis.d.ts +37 -1
- package/dist/analysis.d.ts.map +1 -1
- package/dist/analysis.js +39 -0
- package/dist/analysis.js.map +1 -1
- package/dist/contact/narrow-phase.d.ts +6 -1
- package/dist/contact/narrow-phase.d.ts.map +1 -1
- package/dist/contact/narrow-phase.js +65 -1
- package/dist/contact/narrow-phase.js.map +1 -1
- package/dist/contact/shared-faces.d.ts +5 -1
- package/dist/contact/shared-faces.d.ts.map +1 -1
- package/dist/contact/shared-faces.js +49 -1
- package/dist/contact/shared-faces.js.map +1 -1
- package/dist/contact/tri-tri.d.ts +33 -4
- package/dist/contact/tri-tri.d.ts.map +1 -1
- package/dist/contact/tri-tri.js +37 -11
- package/dist/contact/tri-tri.js.map +1 -1
- package/dist/duplicate-metric.d.ts +74 -0
- package/dist/duplicate-metric.d.ts.map +1 -0
- package/dist/duplicate-metric.js +117 -0
- package/dist/duplicate-metric.js.map +1 -0
- package/dist/duplicate-sets.d.ts +47 -0
- package/dist/duplicate-sets.d.ts.map +1 -0
- package/dist/duplicate-sets.js +124 -0
- package/dist/duplicate-sets.js.map +1 -0
- package/dist/duplicates.d.ts +99 -11
- package/dist/duplicates.d.ts.map +1 -1
- package/dist/duplicates.js +270 -76
- 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 +10 -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/grouping.d.ts +4 -0
- package/dist/grouping.d.ts.map +1 -1
- package/dist/grouping.js +18 -43
- package/dist/grouping.js.map +1 -1
- package/dist/index.d.ts +12 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -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/shape-signature.d.ts +41 -0
- package/dist/shape-signature.d.ts.map +1 -0
- package/dist/shape-signature.js +113 -0
- package/dist/shape-signature.js.map +1 -0
- 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 +60 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/union-find.d.ts +11 -0
- package/dist/union-find.d.ts.map +1 -0
- package/dist/union-find.js +44 -0
- package/dist/union-find.js.map +1 -0
- package/package.json +7 -6
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tri-tri.js","sourceRoot":"","sources":["../../src/contact/tri-tri.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAW/D,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAEhE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"tri-tri.js","sourceRoot":"","sources":["../../src/contact/tri-tri.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAW/D,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAEhE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAgC/D;+CAC+C;AAC/C,SAAS,WAAW,CAAC,QAAkB,EAAE,CAAO,EAAE,EAAU;IAC1D,IAAI,OAAO,QAAQ,KAAK,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAClD,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,QAAQ,CAAC;IACtC,MAAM,SAAS,GACb,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC;QAC5B,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC;QAC7B,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;QAChC,EAAE,CAAC;IACL,OAAO,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;AACpC,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,eAAe,CAAC,CAAW,EAAE,CAAW,EAAE,WAAqB,IAAI;IACjF,IAAI,YAAY,CAAC,CAAC,CAAC,IAAI,YAAY,CAAC,CAAC,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAEhE,aAAa;IACb,MAAM,EAAE,GAAG,iBAAiB,CAAC,CAAC,CAAC,CAAC;IAChC,MAAM,GAAG,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC;IACxB,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;IAC3B,MAAM,IAAI,GAAG,WAAW,CAAC,QAAQ,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC;IAC5C,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,GAAG,CAAC;IACxC,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,GAAG,CAAC;IACxC,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,GAAG,CAAC;IACxC,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAC9B,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAC9B,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAC9B,IAAI,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAErE,aAAa;IACb,MAAM,EAAE,GAAG,iBAAiB,CAAC,CAAC,CAAC,CAAC;IAChC,MAAM,GAAG,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC;IACxB,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;IAC3B,MAAM,IAAI,GAAG,WAAW,CAAC,QAAQ,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC;IAC5C,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,GAAG,CAAC;IACxC,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,GAAG,CAAC;IACxC,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,GAAG,CAAC;IACxC,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAC9B,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAC9B,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAC9B,IAAI,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAErE,qCAAqC;IACrC,IAAI,GAAG,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;IACrE,IAAI,GAAG,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;IAErE,mFAAmF;IACnF,MAAM,MAAM,GAAG,QAAQ,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;IAC1C,MAAM,MAAM,GAAG,QAAQ,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;IAC1C,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAEhD,qEAAqE;IACrE,qEAAqE;IACrE,iEAAiE;IACjE,gEAAgE;IAChE,MAAM,CAAC,GAAG,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IACzB,MAAM,KAAK,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;IAC9B,MAAM,OAAO,GACX,OAAO,QAAQ,KAAK,QAAQ;QAC1B,CAAC,CAAC,QAAQ;QACV,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,SAAS,CAAC,KAAK,CAAW,CAAC,CAAC;IACpE,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAW,CAAC;IACvC,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAW,CAAC;IACvC,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAW,CAAC;IACvC,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAW,CAAC;IACvC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAChC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAChC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAChC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAChC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAClC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAClC,IAAI,IAAI,GAAG,IAAI,GAAG,OAAO;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAEnD,sEAAsE;IACtE,kEAAkE;IAClE,MAAM,EAAE,GAAG,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;IACzD,MAAM,EAAE,GAAG,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;IACzD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC;AACnC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,CAAW,EAAE,CAAW,EAAE,QAAQ,GAAG,IAAI;IACzE,IAAI,YAAY,CAAC,CAAC,CAAC,IAAI,YAAY,CAAC,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IACrD,MAAM,EAAE,GAAG,iBAAiB,CAAC,CAAC,CAAC,CAAC;IAChC,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;IAC3B,MAAM,KAAK,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC;IAC1B,IAAI,KAAK,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC9B,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,KAAK,GAAG,QAAQ;QAAE,OAAO,KAAK,CAAC;IACnE,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,KAAK,GAAG,QAAQ;QAAE,OAAO,KAAK,CAAC;IACnE,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,KAAK,GAAG,QAAQ;QAAE,OAAO,KAAK,CAAC;IAEnE,MAAM,EAAE,GAAG,iBAAiB,CAAC,CAAC,CAAC,CAAC;IAChC,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;IAC3B,MAAM,KAAK,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC;IAC1B,IAAI,KAAK,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC9B,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,KAAK,GAAG,QAAQ;QAAE,OAAO,KAAK,CAAC;IACnE,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,KAAK,GAAG,QAAQ;QAAE,OAAO,KAAK,CAAC;IACnE,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,KAAK,GAAG,QAAQ;QAAE,OAAO,KAAK,CAAC;IAEnE,OAAO,IAAI,CAAC;AACd,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,qBAAqB,CAAC,CAAW,EAAE,CAAO;IACxD,MAAM,CAAC,GAAG,iBAAiB,CAAC,CAAC,CAAC,CAAC;IAC/B,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACtB,IAAI,EAAE,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IACvB,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;IACzB,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;AAC/B,CAAC;AAED,SAAS,MAAM,CAAC,CAAS,EAAE,GAAW;IACpC,IAAI,CAAC,GAAG,GAAG;QAAE,OAAO,CAAC,CAAC;IACtB,IAAI,CAAC,GAAG,CAAC,GAAG;QAAE,OAAO,CAAC,CAAC,CAAC;IACxB,OAAO,CAAC,CAAC;AACX,CAAC;AAED,SAAS,YAAY,CAAC,CAAO;IAC3B,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1B,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1B,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1B,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE;QAAE,OAAO,CAAC,CAAC;IACnC,IAAI,EAAE,IAAI,EAAE;QAAE,OAAO,CAAC,CAAC;IACvB,OAAO,CAAC,CAAC;AACX,CAAC;AAED,yGAAyG;AACzG,SAAS,SAAS,CAAC,CAAO,EAAE,CAAO,EAAE,EAAU,EAAE,EAAU;IACzD,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;IACzB,OAAO,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AACxB,CAAC;AAED,qEAAqE;AACrE,SAAS,QAAQ,CAAC,GAAa,EAAE,EAAU,EAAE,EAAU,EAAE,EAAU;IACjE,MAAM,GAAG,GAAW,EAAE,CAAC;IACvB,0BAA0B;IAC1B,IAAI,CAAC,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAAE,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;IAC1F,IAAI,CAAC,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAAE,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;IAC1F,IAAI,CAAC,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAAE,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;IAC1F,+CAA+C;IAC/C,IAAI,EAAE,KAAK,CAAC;QAAE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC/B,IAAI,EAAE,KAAK,CAAC;QAAE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC/B,IAAI,EAAE,KAAK,CAAC;QAAE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC/B,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAChC,MAAM,KAAK,GAAG,GAAG,CAAC,CAAC,CAAS,CAAC;IAC7B,MAAM,IAAI,GAAG,GAAG,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAS,CAAC;IACzC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;AACvB,CAAC;AAED;;;;;GAKG;AACH,SAAS,gBAAgB,CACvB,MAA6B,EAC7B,MAA6B,EAC7B,IAAe,EACf,CAAS;IAET,qDAAqD;IACrD,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAW,CAAC;IACtC,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAW,CAAC;IACtC,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAW,CAAC;IACtC,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAW,CAAC;IACtC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAChC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAChC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAChC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAChC,MAAM,SAAS,GAAG,CAAC,IAAI,IAAI,GAAG,KAAK,IAAI,CAAC,IAAI,IAAI,GAAG,KAAK,CAAC;IACzD,MAAM,SAAS,GAAG,CAAC,IAAI,IAAI,GAAG,KAAK,IAAI,CAAC,IAAI,IAAI,GAAG,KAAK,CAAC;IACzD,IAAI,SAAS;QAAE,OAAO,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IACjD,IAAI,SAAS;QAAE,OAAO,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IACjD,gDAAgD;IAChD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IAC/D,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IAC/D,OAAO,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AAClF,CAAC;AAED,SAAS,SAAS,CAAC,KAA4B,EAAE,IAAe,EAAE,CAAS;IACzE,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAW,CAAC;IACnC,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAW,CAAC;IACnC,MAAM,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC;IACpB,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,KAAK;QAAE,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC;IAC7C,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC;IAC1B,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACtC,CAAC;AAED,2EAA2E;AAC3E,0CAA0C;AAC1C,KAAK,IAAI,CAAC"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The AABB metrics `findDuplicates` matches on: the current distance gate
|
|
3
|
+
* ({@link boxDistance} bounded by `positionTolerance`, preconditioned on
|
|
4
|
+
* {@link boxesTouch}) and the legacy IoU {@link similarity} it superseded,
|
|
5
|
+
* kept only for callers that pass the deprecated `iouThreshold` /
|
|
6
|
+
* `exactThreshold` options. Split out of `duplicates.ts` (which owns the pass
|
|
7
|
+
* itself) to keep both under the ~400-line module limit; not part of the
|
|
8
|
+
* public package surface.
|
|
9
|
+
*/
|
|
10
|
+
import type { AABB } from '@ifc-lite/spatial';
|
|
11
|
+
/**
|
|
12
|
+
* Distance (m) between two boxes as *objects*: the largest distance any corner
|
|
13
|
+
* of `a` has to travel to reach the matching corner of `b`. Because the max over
|
|
14
|
+
* the eight corners picks, independently per axis, whichever face moved further,
|
|
15
|
+
* it reduces to the Euclidean norm of the three per-axis face offsets — one
|
|
16
|
+
* square root, no corner enumeration.
|
|
17
|
+
*
|
|
18
|
+
* Two properties make it the tolerance a user can reason about:
|
|
19
|
+
* - **Pure translation gives exactly the translation length.** Every corner
|
|
20
|
+
* moves by `d`, so the result is `|d|`, whatever the shape and whatever the
|
|
21
|
+
* direction. That is what makes *this metric* isotropic, where IoU was not.
|
|
22
|
+
* The gate around it is not: `findDuplicates` preconditions on
|
|
23
|
+
* {@link boxesTouch}, so the effective tolerance per axis is
|
|
24
|
+
* `min(positionTolerance, extent on that axis)` and an element thinner than
|
|
25
|
+
* the tolerance gets less than the full tolerance along its thin axis.
|
|
26
|
+
* - **A size difference counts too.** Concentric boxes whose faces differ by δ
|
|
27
|
+
* are δ apart, so this is centre distance *and* a shape check in one number,
|
|
28
|
+
* with no second, dimensionless knob.
|
|
29
|
+
*
|
|
30
|
+
* It is still AABB-only: two elements with the same bounds and different solids
|
|
31
|
+
* inside them are indistinguishable *to this function*. In practice that costs
|
|
32
|
+
* less than it sounds, because real nesting has clearance and clearance is what
|
|
33
|
+
* this measures. An element nested with a gap of `g` on two axes is `g·√2`
|
|
34
|
+
* away, so anything looser than 10/√2 ≈ 7 mm of annulus is rejected outright at
|
|
35
|
+
* the default tolerance — a duct in its shaft and a pipe in a standard sleeve
|
|
36
|
+
* both are. What survives is nesting tighter than that, and the shape signature
|
|
37
|
+
* then keeps it out of `major`. See `findDuplicates` for the measured
|
|
38
|
+
* envelope.
|
|
39
|
+
*/
|
|
40
|
+
export declare function boxDistance(a: AABB, b: AABB): number;
|
|
41
|
+
/** Do the boxes touch or overlap on every axis? Two elements that are disjoint
|
|
42
|
+
* in space are two objects, however close. Without this an element SMALLER than
|
|
43
|
+
* the tolerance (a 5 mm fixing at a 10 mm tolerance) would pair with a
|
|
44
|
+
* neighbour it never intersects. Touching (zero gap) counts, so coincident
|
|
45
|
+
* planar and point geometry still qualifies.
|
|
46
|
+
*
|
|
47
|
+
* Being a precondition, this — not `positionTolerance` alone — sets the
|
|
48
|
+
* EFFECTIVE tolerance: two copies separate once the offset exceeds the
|
|
49
|
+
* element's own extent on the offset axis, so the pass matches within
|
|
50
|
+
* `min(positionTolerance, extent on that axis)` per axis. Only elements
|
|
51
|
+
* thicker than the tolerance get the full tolerance on every axis; a 2 mm
|
|
52
|
+
* plate gets 10 mm in its plane and 2 mm along its normal at the 10 mm
|
|
53
|
+
* default. The zero-thickness sheet is the limiting case, not the only one.
|
|
54
|
+
* The same touch condition is enforced a second time, independently, by the
|
|
55
|
+
* sweep's eviction on whichever axis it sweeps (`duplicates.ts`), so widening
|
|
56
|
+
* only this test would not make the pass isotropic.
|
|
57
|
+
*
|
|
58
|
+
* That excludes pairs the legacy IoU fallback reported: sheets offset a few
|
|
59
|
+
* millimetres ALONG THEIR OWN NORMAL are disjoint (any gap on that axis fails
|
|
60
|
+
* this test), where the old `aabbApproxEqual` fallback called boxes within
|
|
61
|
+
* `positionTolerance` per axis the same place. Same reasoning as the 5 mm
|
|
62
|
+
* fixing: geometry with clear air between the surfaces is two objects, not one
|
|
63
|
+
* modelled twice. Inflating this test by the tolerance to make the pass
|
|
64
|
+
* isotropic would reopen exactly that case — it breaks both the "does not pair
|
|
65
|
+
* two small elements that do not even touch" and "does not pair two disjoint
|
|
66
|
+
* sheets offset along their own normal" tests, which is why the anisotropy is
|
|
67
|
+
* documented rather than removed. */
|
|
68
|
+
export declare function boxesTouch(a: AABB, b: AABB): boolean;
|
|
69
|
+
/** Legacy IoU similarity in `[0,1]`, falling back to box-equality for degenerate
|
|
70
|
+
* (zero-volume / planar) elements where IoU is undefined. */
|
|
71
|
+
export declare function similarity(a: AABB, b: AABB, tol: number): number;
|
|
72
|
+
/** Shortest dimension of a box — the depth one element is embedded in another. */
|
|
73
|
+
export declare function minExtent(b: AABB): number;
|
|
74
|
+
//# sourceMappingURL=duplicate-metric.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"duplicate-metric.d.ts","sourceRoot":"","sources":["../src/duplicate-metric.ts"],"names":[],"mappings":"AAIA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AA4B9C;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,GAAG,MAAM,CAOpD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;sCA0BsC;AACtC,wBAAgB,UAAU,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,GAAG,OAAO,CAKpD;AAED;8DAC8D;AAC9D,wBAAgB,UAAU,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAQhE;AAED,kFAAkF;AAClF,wBAAgB,SAAS,CAAC,CAAC,EAAE,IAAI,GAAG,MAAM,CAEzC"}
|
|
@@ -0,0 +1,117 @@
|
|
|
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
|
+
function aabbVolume(b) {
|
|
5
|
+
const dx = Math.max(0, b.max[0] - b.min[0]);
|
|
6
|
+
const dy = Math.max(0, b.max[1] - b.min[1]);
|
|
7
|
+
const dz = Math.max(0, b.max[2] - b.min[2]);
|
|
8
|
+
return dx * dy * dz;
|
|
9
|
+
}
|
|
10
|
+
/** Intersection-over-union of two AABBs (0 when disjoint). */
|
|
11
|
+
function aabbIoU(a, b) {
|
|
12
|
+
const ox = Math.min(a.max[0], b.max[0]) - Math.max(a.min[0], b.min[0]);
|
|
13
|
+
const oy = Math.min(a.max[1], b.max[1]) - Math.max(a.min[1], b.min[1]);
|
|
14
|
+
const oz = Math.min(a.max[2], b.max[2]) - Math.max(a.min[2], b.min[2]);
|
|
15
|
+
if (ox <= 0 || oy <= 0 || oz <= 0)
|
|
16
|
+
return 0;
|
|
17
|
+
const inter = ox * oy * oz;
|
|
18
|
+
const union = aabbVolume(a) + aabbVolume(b) - inter;
|
|
19
|
+
return union > 0 ? inter / union : 0;
|
|
20
|
+
}
|
|
21
|
+
function aabbApproxEqual(a, b, tol) {
|
|
22
|
+
for (let i = 0; i < 3; i += 1) {
|
|
23
|
+
if (Math.abs(a.min[i] - b.min[i]) > tol)
|
|
24
|
+
return false;
|
|
25
|
+
if (Math.abs(a.max[i] - b.max[i]) > tol)
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Distance (m) between two boxes as *objects*: the largest distance any corner
|
|
32
|
+
* of `a` has to travel to reach the matching corner of `b`. Because the max over
|
|
33
|
+
* the eight corners picks, independently per axis, whichever face moved further,
|
|
34
|
+
* it reduces to the Euclidean norm of the three per-axis face offsets — one
|
|
35
|
+
* square root, no corner enumeration.
|
|
36
|
+
*
|
|
37
|
+
* Two properties make it the tolerance a user can reason about:
|
|
38
|
+
* - **Pure translation gives exactly the translation length.** Every corner
|
|
39
|
+
* moves by `d`, so the result is `|d|`, whatever the shape and whatever the
|
|
40
|
+
* direction. That is what makes *this metric* isotropic, where IoU was not.
|
|
41
|
+
* The gate around it is not: `findDuplicates` preconditions on
|
|
42
|
+
* {@link boxesTouch}, so the effective tolerance per axis is
|
|
43
|
+
* `min(positionTolerance, extent on that axis)` and an element thinner than
|
|
44
|
+
* the tolerance gets less than the full tolerance along its thin axis.
|
|
45
|
+
* - **A size difference counts too.** Concentric boxes whose faces differ by δ
|
|
46
|
+
* are δ apart, so this is centre distance *and* a shape check in one number,
|
|
47
|
+
* with no second, dimensionless knob.
|
|
48
|
+
*
|
|
49
|
+
* It is still AABB-only: two elements with the same bounds and different solids
|
|
50
|
+
* inside them are indistinguishable *to this function*. In practice that costs
|
|
51
|
+
* less than it sounds, because real nesting has clearance and clearance is what
|
|
52
|
+
* this measures. An element nested with a gap of `g` on two axes is `g·√2`
|
|
53
|
+
* away, so anything looser than 10/√2 ≈ 7 mm of annulus is rejected outright at
|
|
54
|
+
* the default tolerance — a duct in its shaft and a pipe in a standard sleeve
|
|
55
|
+
* both are. What survives is nesting tighter than that, and the shape signature
|
|
56
|
+
* then keeps it out of `major`. See `findDuplicates` for the measured
|
|
57
|
+
* envelope.
|
|
58
|
+
*/
|
|
59
|
+
export function boxDistance(a, b) {
|
|
60
|
+
let sum = 0;
|
|
61
|
+
for (let i = 0; i < 3; i += 1) {
|
|
62
|
+
const d = Math.max(Math.abs(a.min[i] - b.min[i]), Math.abs(a.max[i] - b.max[i]));
|
|
63
|
+
sum += d * d;
|
|
64
|
+
}
|
|
65
|
+
return Math.sqrt(sum);
|
|
66
|
+
}
|
|
67
|
+
/** Do the boxes touch or overlap on every axis? Two elements that are disjoint
|
|
68
|
+
* in space are two objects, however close. Without this an element SMALLER than
|
|
69
|
+
* the tolerance (a 5 mm fixing at a 10 mm tolerance) would pair with a
|
|
70
|
+
* neighbour it never intersects. Touching (zero gap) counts, so coincident
|
|
71
|
+
* planar and point geometry still qualifies.
|
|
72
|
+
*
|
|
73
|
+
* Being a precondition, this — not `positionTolerance` alone — sets the
|
|
74
|
+
* EFFECTIVE tolerance: two copies separate once the offset exceeds the
|
|
75
|
+
* element's own extent on the offset axis, so the pass matches within
|
|
76
|
+
* `min(positionTolerance, extent on that axis)` per axis. Only elements
|
|
77
|
+
* thicker than the tolerance get the full tolerance on every axis; a 2 mm
|
|
78
|
+
* plate gets 10 mm in its plane and 2 mm along its normal at the 10 mm
|
|
79
|
+
* default. The zero-thickness sheet is the limiting case, not the only one.
|
|
80
|
+
* The same touch condition is enforced a second time, independently, by the
|
|
81
|
+
* sweep's eviction on whichever axis it sweeps (`duplicates.ts`), so widening
|
|
82
|
+
* only this test would not make the pass isotropic.
|
|
83
|
+
*
|
|
84
|
+
* That excludes pairs the legacy IoU fallback reported: sheets offset a few
|
|
85
|
+
* millimetres ALONG THEIR OWN NORMAL are disjoint (any gap on that axis fails
|
|
86
|
+
* this test), where the old `aabbApproxEqual` fallback called boxes within
|
|
87
|
+
* `positionTolerance` per axis the same place. Same reasoning as the 5 mm
|
|
88
|
+
* fixing: geometry with clear air between the surfaces is two objects, not one
|
|
89
|
+
* modelled twice. Inflating this test by the tolerance to make the pass
|
|
90
|
+
* isotropic would reopen exactly that case — it breaks both the "does not pair
|
|
91
|
+
* two small elements that do not even touch" and "does not pair two disjoint
|
|
92
|
+
* sheets offset along their own normal" tests, which is why the anisotropy is
|
|
93
|
+
* documented rather than removed. */
|
|
94
|
+
export function boxesTouch(a, b) {
|
|
95
|
+
for (let i = 0; i < 3; i += 1) {
|
|
96
|
+
if (Math.min(a.max[i], b.max[i]) < Math.max(a.min[i], b.min[i]))
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
101
|
+
/** Legacy IoU similarity in `[0,1]`, falling back to box-equality for degenerate
|
|
102
|
+
* (zero-volume / planar) elements where IoU is undefined. */
|
|
103
|
+
export function similarity(a, b, tol) {
|
|
104
|
+
const iou = aabbIoU(a, b);
|
|
105
|
+
if (iou > 0)
|
|
106
|
+
return iou;
|
|
107
|
+
// Both (near) degenerate: an exact box match still means "same place".
|
|
108
|
+
if (aabbVolume(a) <= 0 || aabbVolume(b) <= 0) {
|
|
109
|
+
return aabbApproxEqual(a, b, tol) ? 1 : 0;
|
|
110
|
+
}
|
|
111
|
+
return 0;
|
|
112
|
+
}
|
|
113
|
+
/** Shortest dimension of a box — the depth one element is embedded in another. */
|
|
114
|
+
export function minExtent(b) {
|
|
115
|
+
return Math.min(b.max[0] - b.min[0], b.max[1] - b.min[1], b.max[2] - b.min[2]);
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=duplicate-metric.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"duplicate-metric.js","sourceRoot":"","sources":["../src/duplicate-metric.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { ClashGroup, ClashResult } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Group a duplicate result into coincident **sets** — one finding per set of
|
|
4
|
+
* objects occupying the same place, rather than one per pair.
|
|
5
|
+
*
|
|
6
|
+
* `findDuplicates` reports pairwise. N coincident copies of one object therefore
|
|
7
|
+
* produce N(N−1)/2 rows and each copy is named in N−1 of them, so three
|
|
8
|
+
* triplicated columns read as nine findings with every object mentioned twice.
|
|
9
|
+
* No row is literally repeated, but the list badly overstates the problem.
|
|
10
|
+
*
|
|
11
|
+
* The partition here is the **connected components of the pair graph**: every
|
|
12
|
+
* reported clash is an edge between two model-qualified elements, and each
|
|
13
|
+
* component is one "these N objects are coincident" finding. Unlike
|
|
14
|
+
* `groupClashes({ by: 'cluster' })` this needs no epsilon and cannot fuse two
|
|
15
|
+
* unrelated duplicate sets that merely stand within a cluster radius of each
|
|
16
|
+
* other — it uses only the pairs the detector actually reported.
|
|
17
|
+
*
|
|
18
|
+
* Two properties worth stating plainly:
|
|
19
|
+
*
|
|
20
|
+
* - **Transitivity is approximated, knowingly.** A≈B and B≈C under
|
|
21
|
+
* `positionTolerance` (the default corner-distance gate) does not imply A≈C,
|
|
22
|
+
* yet connected components put all three in one
|
|
23
|
+
* set. We accept that: a chain of near-coincident objects is a single
|
|
24
|
+
* coordination issue, and the strict alternative (maximal cliques) is
|
|
25
|
+
* exponential and would put the same object back into several findings —
|
|
26
|
+
* the exact complaint this grouping exists to answer.
|
|
27
|
+
* - **Sets may span models.** Identity is `(model, key, ref)`, so the same
|
|
28
|
+
* object delivered in two files groups correctly, and two files that happen to
|
|
29
|
+
* reuse a key for different objects do not. `ref` is in there because a key
|
|
30
|
+
* can repeat *within* one model too — a file with duplicated GlobalIds, which
|
|
31
|
+
* is exactly the defect a duplicate hunt is looking for; on `(model, key)`
|
|
32
|
+
* alone those two elements collapsed into one node and the set they form
|
|
33
|
+
* counted "1 coincident object". Adding `ref` only ever splits nodes, never
|
|
34
|
+
* merges them.
|
|
35
|
+
*
|
|
36
|
+
* Components are computed per `rule`, so a mixed result never fuses a duplicate
|
|
37
|
+
* pair with a discipline clash — and only components of the `duplicates` rule
|
|
38
|
+
* are titled "coincident". Any other rule's component is titled as connected
|
|
39
|
+
* clashes, which is all its pair graph proves: those members intersect, they
|
|
40
|
+
* do not occupy the same place. Severity is the most severe member severity: a
|
|
41
|
+
* set containing any exact-duplicate (`major`) pair surfaces as `major`.
|
|
42
|
+
*
|
|
43
|
+
* `ClashResult` is untouched — the panel, grouping modes and BCF export keep
|
|
44
|
+
* consuming the pairwise shape; this is a reporting view over it.
|
|
45
|
+
*/
|
|
46
|
+
export declare function groupDuplicateSets(result: ClashResult): ClashGroup[];
|
|
47
|
+
//# sourceMappingURL=duplicate-sets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"duplicate-sets.d.ts","sourceRoot":"","sources":["../src/duplicate-sets.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAA0B,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAElF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,WAAW,GAAG,UAAU,EAAE,CAqEpE"}
|
|
@@ -0,0 +1,124 @@
|
|
|
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
|
+
/**
|
|
5
|
+
* Coincident-set grouping for duplicate results — the reader-facing view over
|
|
6
|
+
* the pairwise `ClashResult` that `findDuplicates` produces. Split out of
|
|
7
|
+
* `grouping.ts` (which owns the generic BCF-topic groupings) to keep both
|
|
8
|
+
* under the ~400-line module limit; re-exported through the package index.
|
|
9
|
+
*/
|
|
10
|
+
import { DUPLICATES_RULE } from './duplicates.js';
|
|
11
|
+
import { qualifiedKey } from './exclude.js';
|
|
12
|
+
import { makeGroup, sortGroups } from './grouping.js';
|
|
13
|
+
import { createUnionFind } from './union-find.js';
|
|
14
|
+
/**
|
|
15
|
+
* Group a duplicate result into coincident **sets** — one finding per set of
|
|
16
|
+
* objects occupying the same place, rather than one per pair.
|
|
17
|
+
*
|
|
18
|
+
* `findDuplicates` reports pairwise. N coincident copies of one object therefore
|
|
19
|
+
* produce N(N−1)/2 rows and each copy is named in N−1 of them, so three
|
|
20
|
+
* triplicated columns read as nine findings with every object mentioned twice.
|
|
21
|
+
* No row is literally repeated, but the list badly overstates the problem.
|
|
22
|
+
*
|
|
23
|
+
* The partition here is the **connected components of the pair graph**: every
|
|
24
|
+
* reported clash is an edge between two model-qualified elements, and each
|
|
25
|
+
* component is one "these N objects are coincident" finding. Unlike
|
|
26
|
+
* `groupClashes({ by: 'cluster' })` this needs no epsilon and cannot fuse two
|
|
27
|
+
* unrelated duplicate sets that merely stand within a cluster radius of each
|
|
28
|
+
* other — it uses only the pairs the detector actually reported.
|
|
29
|
+
*
|
|
30
|
+
* Two properties worth stating plainly:
|
|
31
|
+
*
|
|
32
|
+
* - **Transitivity is approximated, knowingly.** A≈B and B≈C under
|
|
33
|
+
* `positionTolerance` (the default corner-distance gate) does not imply A≈C,
|
|
34
|
+
* yet connected components put all three in one
|
|
35
|
+
* set. We accept that: a chain of near-coincident objects is a single
|
|
36
|
+
* coordination issue, and the strict alternative (maximal cliques) is
|
|
37
|
+
* exponential and would put the same object back into several findings —
|
|
38
|
+
* the exact complaint this grouping exists to answer.
|
|
39
|
+
* - **Sets may span models.** Identity is `(model, key, ref)`, so the same
|
|
40
|
+
* object delivered in two files groups correctly, and two files that happen to
|
|
41
|
+
* reuse a key for different objects do not. `ref` is in there because a key
|
|
42
|
+
* can repeat *within* one model too — a file with duplicated GlobalIds, which
|
|
43
|
+
* is exactly the defect a duplicate hunt is looking for; on `(model, key)`
|
|
44
|
+
* alone those two elements collapsed into one node and the set they form
|
|
45
|
+
* counted "1 coincident object". Adding `ref` only ever splits nodes, never
|
|
46
|
+
* merges them.
|
|
47
|
+
*
|
|
48
|
+
* Components are computed per `rule`, so a mixed result never fuses a duplicate
|
|
49
|
+
* pair with a discipline clash — and only components of the `duplicates` rule
|
|
50
|
+
* are titled "coincident". Any other rule's component is titled as connected
|
|
51
|
+
* clashes, which is all its pair graph proves: those members intersect, they
|
|
52
|
+
* do not occupy the same place. Severity is the most severe member severity: a
|
|
53
|
+
* set containing any exact-duplicate (`major`) pair surfaces as `major`.
|
|
54
|
+
*
|
|
55
|
+
* `ClashResult` is untouched — the panel, grouping modes and BCF export keep
|
|
56
|
+
* consuming the pairwise shape; this is a reporting view over it.
|
|
57
|
+
*/
|
|
58
|
+
export function groupDuplicateSets(result) {
|
|
59
|
+
const byRule = new Map();
|
|
60
|
+
for (const clash of result.clashes) {
|
|
61
|
+
const bucket = byRule.get(clash.rule);
|
|
62
|
+
if (bucket) {
|
|
63
|
+
bucket.push(clash);
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
byRule.set(clash.rule, [clash]);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
const groups = [];
|
|
70
|
+
for (const bucket of byRule.values()) {
|
|
71
|
+
// Number the participating elements in first-seen order; every clash is one
|
|
72
|
+
// edge between two of those nodes.
|
|
73
|
+
const nodeOf = new Map();
|
|
74
|
+
const idOf = (ref) => {
|
|
75
|
+
const k = `${qualifiedKey(ref.model, ref.key)}#${ref.ref}`;
|
|
76
|
+
const existing = nodeOf.get(k);
|
|
77
|
+
if (existing !== undefined)
|
|
78
|
+
return existing;
|
|
79
|
+
const assigned = nodeOf.size;
|
|
80
|
+
nodeOf.set(k, assigned);
|
|
81
|
+
return assigned;
|
|
82
|
+
};
|
|
83
|
+
const edges = bucket.map((clash) => [idOf(clash.a), idOf(clash.b)]);
|
|
84
|
+
const { find, union } = createUnionFind(nodeOf.size);
|
|
85
|
+
for (const [a, b] of edges) {
|
|
86
|
+
union(a, b);
|
|
87
|
+
}
|
|
88
|
+
// Collect each component's member clashes and its distinct element count —
|
|
89
|
+
// the latter is what the reader cares about ("these 3 objects are the same"),
|
|
90
|
+
// and it is NOT the member count once a set grows past a pair.
|
|
91
|
+
const components = new Map();
|
|
92
|
+
for (let i = 0; i < bucket.length; i += 1) {
|
|
93
|
+
const clash = bucket[i];
|
|
94
|
+
const root = find(edges[i][0]);
|
|
95
|
+
let comp = components.get(root);
|
|
96
|
+
if (!comp) {
|
|
97
|
+
comp = { members: [], nodes: new Set(), tags: new Set() };
|
|
98
|
+
components.set(root, comp);
|
|
99
|
+
}
|
|
100
|
+
comp.members.push(clash);
|
|
101
|
+
comp.nodes.add(edges[i][0]);
|
|
102
|
+
comp.nodes.add(edges[i][1]);
|
|
103
|
+
comp.tags.add(clash.a.tag);
|
|
104
|
+
comp.tags.add(clash.b.tag);
|
|
105
|
+
}
|
|
106
|
+
for (const comp of components.values()) {
|
|
107
|
+
const count = comp.nodes.size;
|
|
108
|
+
const tag = comp.tags.size === 1 ? `${[...comp.tags][0]} ` : '';
|
|
109
|
+
const members = [...comp.members].sort((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0));
|
|
110
|
+
// "Coincident" is a statement the `duplicates` rule actually made. For
|
|
111
|
+
// any other rule the members of a component merely clash transitively —
|
|
112
|
+
// intersecting-but-distinct elements — so the title must not upgrade
|
|
113
|
+
// that to coincidence (#2530 review: an SDK caller passing a discipline
|
|
114
|
+
// result here would otherwise get "7 coincident IfcPipeSegment objects").
|
|
115
|
+
const rule = comp.members[0].rule;
|
|
116
|
+
const title = rule === DUPLICATES_RULE.id
|
|
117
|
+
? `${count} coincident ${tag}objects`
|
|
118
|
+
: `${count} ${tag}objects in connected ${rule} clashes`;
|
|
119
|
+
groups.push(makeGroup(members, title, undefined, 'duplicate-set'));
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return sortGroups(groups);
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=duplicate-sets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"duplicate-sets.js","sourceRoot":"","sources":["../src/duplicate-sets.ts"],"names":[],"mappings":"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"}
|
package/dist/duplicates.d.ts
CHANGED
|
@@ -1,26 +1,114 @@
|
|
|
1
1
|
import type { ClashElement, ClashResult, ClashRule, ExclusionSet } from './types.js';
|
|
2
2
|
export interface DuplicateOptions {
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* How far apart (m) two elements may be and still count as the same object.
|
|
5
|
+
* This is the primary control and the number reported in
|
|
6
|
+
* `ClashResult.settings.tolerance`. It bounds {@link boxDistance}: for two
|
|
7
|
+
* equally-sized boxes that is exactly the distance between their centres, and
|
|
8
|
+
* a difference in size adds to it. Default 10 mm.
|
|
9
|
+
*
|
|
10
|
+
* It is an upper bound, not the whole gate. {@link boxesTouch} is applied
|
|
11
|
+
* first, and two copies stop touching once the offset exceeds the element's
|
|
12
|
+
* own extent on the offset axis, so the EFFECTIVE tolerance per axis is
|
|
13
|
+
* `min(positionTolerance, extent on that axis)`. A 200 mm wall gets the full
|
|
14
|
+
* 10 mm on all three axes; a 2 mm plate gets 10 mm in its plane and 2 mm
|
|
15
|
+
* along its normal. That is deliberate — see {@link boxesTouch} for why
|
|
16
|
+
* clear air between two surfaces makes them two objects — and it is pinned by
|
|
17
|
+
* the "effective tolerance is min(positionTolerance, extent) per axis" test.
|
|
18
|
+
*/
|
|
19
|
+
positionTolerance?: number;
|
|
20
|
+
/** Distance (m) at/below which a same-shape pair is treated as an EXACT
|
|
21
|
+
* duplicate (severity `major`) rather than a candidate overlap (`minor`).
|
|
22
|
+
* Default 1 mm. */
|
|
23
|
+
exactTolerance?: number;
|
|
24
|
+
/**
|
|
25
|
+
* @deprecated Superseded by {@link positionTolerance}. Minimum AABB
|
|
26
|
+
* intersection-over-union for a pair to count as overlapping. IoU is a ratio,
|
|
27
|
+
* so it imposed no fixed physical tolerance: for two equal boxes offset by `d`
|
|
28
|
+
* along an axis of extent `e` the IoU is `(e − d) / (e + d)`, and the default
|
|
29
|
+
* 0.9 therefore allowed `d ≤ e / 19` — 5 mm across a DN100 pipe but 421 mm
|
|
30
|
+
* across an 8 m slab, from one setting. Passing this (or `exactThreshold`)
|
|
31
|
+
* restores the pre-1.7 IoU **matching gate** — which pairs are reported, and
|
|
32
|
+
* the old `settings.tolerance` reading — rather than silently reinterpreting
|
|
33
|
+
* a number that means nothing in the new metric. It does NOT restore the
|
|
34
|
+
* whole pre-1.7 behaviour: severity is still decided by the area+volume
|
|
35
|
+
* shape signature (not the old triangle count), and self-pair identity is
|
|
36
|
+
* still `(model, ref)` (not key-based), so a file with duplicated GlobalIds
|
|
37
|
+
* reports pairs the old code hid.
|
|
7
38
|
*/
|
|
8
39
|
iouThreshold?: number;
|
|
9
|
-
/**
|
|
10
|
-
*
|
|
40
|
+
/** @deprecated Only meaningful in the legacy IoU mode selected by
|
|
41
|
+
* {@link iouThreshold}; use {@link exactTolerance}. */
|
|
11
42
|
exactThreshold?: number;
|
|
12
|
-
/** Centre-distance (m) under which two degenerate (planar) elements with no
|
|
13
|
-
* AABB volume are still considered coincident. */
|
|
14
|
-
positionTolerance?: number;
|
|
15
43
|
/** Pairs whose element keys are in here are skipped (voids/hosts/assemblies). */
|
|
16
44
|
exclusions?: ExclusionSet;
|
|
17
45
|
}
|
|
18
46
|
export declare const DUPLICATES_RULE: ClashRule;
|
|
19
47
|
/**
|
|
20
48
|
* Find duplicate / fully-overlapping elements. Returns a {@link ClashResult}
|
|
21
|
-
* where each clash is a near-coincident pair
|
|
22
|
-
*
|
|
23
|
-
*
|
|
49
|
+
* where each clash is a near-coincident pair. `settings.tolerance` is
|
|
50
|
+
* `positionTolerance`, the value that actually decided the matches.
|
|
51
|
+
*
|
|
52
|
+
* Severity says exactly this much:
|
|
53
|
+
* - `major` — some pair of the two elements' boxes coincides within
|
|
54
|
+
* `exactTolerance` **and** the two elements' meshes — summed over the
|
|
55
|
+
* several parts a multi-material / CSG element emits — agree to within 5% on
|
|
56
|
+
* both surface area and enclosed volume. Read it as "the same object, in the
|
|
57
|
+
* same place"; it survives one copy being re-tessellated, and it does not
|
|
58
|
+
* depend on which of a multi-part element's part pairings the sweep visited
|
|
59
|
+
* first.
|
|
60
|
+
* - `minor` — near-coincident, but something differs: the boxes are further
|
|
61
|
+
* apart than `exactTolerance`, the shapes disagree, or one element carries no
|
|
62
|
+
* measurable geometry.
|
|
63
|
+
*
|
|
64
|
+
* What `major` still cannot tell you: the signature is two scalars over the
|
|
65
|
+
* surface, so two genuinely different solids that happen to agree in both area
|
|
66
|
+
* and volume to within 5% are indistinguishable here, as are an element and its
|
|
67
|
+
* mirror image.
|
|
68
|
+
*
|
|
69
|
+
* ## The nested-solids limit
|
|
70
|
+
*
|
|
71
|
+
* Matching remains AABB-only, so an element nested inside another — a pipe in a
|
|
72
|
+
* sleeve, a duct in a shaft, an assembly and the envelope drawn round it — is,
|
|
73
|
+
* in principle, something this pass cannot tell from a duplicate. Two gates
|
|
74
|
+
* already narrow that to a documented residual, and `duplicates.test.ts` pins
|
|
75
|
+
* each case:
|
|
76
|
+
*
|
|
77
|
+
* - Nesting has clearance, and {@link boxDistance} measures clearance. Anything
|
|
78
|
+
* looser than ~7 mm of annulus is more than `positionTolerance` away and is
|
|
79
|
+
* never reported at all: a DN100 pipe in a DN125 sleeve is 17.7 mm away, a
|
|
80
|
+
* 400×300 duct in a 500×400 shaft is 70.7 mm.
|
|
81
|
+
* - Tighter nesting *is* reported, but only ever as `minor`. Reaching `major`
|
|
82
|
+
* additionally requires the two meshes to agree on surface area and enclosed
|
|
83
|
+
* volume within 5%, which distinct solids sharing a box do not: a 50 mm and a
|
|
84
|
+
* 55 mm tube are 9.1% / 17.4% apart, a railing and its envelope box 73.2% /
|
|
85
|
+
* 88.4%.
|
|
86
|
+
*
|
|
87
|
+
* So the residual is exactly this: a pair nested within a few millimetres is
|
|
88
|
+
* listed as a `minor` candidate overlap. That is the intended reading of
|
|
89
|
+
* `minor` — "these two coincide, and this pass will not claim they are the same
|
|
90
|
+
* object" — and a reviewer still sees it, which for a coincidence hunt is the
|
|
91
|
+
* safe direction.
|
|
92
|
+
*
|
|
93
|
+
* Measured across five public models (duplex, AC20-FZK-Haus, Office_A_20110811,
|
|
94
|
+
* dental_clinic, Infra-Bridge), *no* reported pair was a nested one: all 33
|
|
95
|
+
* findings are same-type pairs of equal bounds, and the count of nested or
|
|
96
|
+
* cross-type pairs stays 0 even at a 250 mm tolerance, 25× the default. Note
|
|
97
|
+
* what that does not cover — none of the five carries pipe or duct segments, so
|
|
98
|
+
* the pipe-in-sleeve case is evidenced only by the constructed fixtures above.
|
|
99
|
+
*
|
|
100
|
+
* Closing the residual would need a narrow phase, which this pass deliberately
|
|
101
|
+
* does not run, and the cheap substitutes are worse rather than merely weaker.
|
|
102
|
+
* An area-weighted centroid plus surface inertia — the obvious candidate, and
|
|
103
|
+
* the same O(triangles) cost as the signature (3.6 ms vs 2.6 ms over
|
|
104
|
+
* dental_clinic's 236,795 triangles) — discriminates *less* on every nested
|
|
105
|
+
* case measured, contributes nothing at all when the nesting is concentric
|
|
106
|
+
* (identical centroids for pipe-in-sleeve and pipe-plus-insulation), and is not
|
|
107
|
+
* tessellation-invariant: it reads 39.6% apart on one box against a finer
|
|
108
|
+
* triangulation of the same box, which would break the exact-duplicate case
|
|
109
|
+
* this signature exists to keep together. A voxel occupancy sample would
|
|
110
|
+
* separate nested from coincident, but it needs a cell size — reintroducing the
|
|
111
|
+
* scale-dependent knob that replacing the IoU gate removed.
|
|
24
112
|
*/
|
|
25
113
|
export declare function findDuplicates(elements: ClashElement[], options?: DuplicateOptions): ClashResult;
|
|
26
114
|
//# sourceMappingURL=duplicates.d.ts.map
|
package/dist/duplicates.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"duplicates.d.ts","sourceRoot":"","sources":["../src/duplicates.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"duplicates.d.ts","sourceRoot":"","sources":["../src/duplicates.ts"],"names":[],"mappings":"AAuCA,OAAO,KAAK,EAEV,YAAY,EAEZ,WAAW,EACX,SAAS,EAET,YAAY,EACb,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,gBAAgB;IAC/B;;;;;;;;;;;;;;;OAeG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;wBAEoB;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;;;;;;;;;;OAcG;IAIH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;4DACwD;IACxD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iFAAiF;IACjF,UAAU,CAAC,EAAE,YAAY,CAAC;CAC3B;AAWD,eAAO,MAAM,eAAe,EAAE,SAK7B,CAAC;AAOF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiEG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,YAAY,EAAE,EAAE,OAAO,GAAE,gBAAqB,GAAG,WAAW,CAwPpG"}
|