MCPcopy Create free account
hub / github.com/CNCKitchen/stlTexturizer / findIntersectingTriangles

Function findIntersectingTriangles

js/meshValidation.js:71–192  ·  view source on GitHub ↗

* Find pairs of intersecting triangles using spatial hashing for the broad * phase and the Separating Axis Theorem for the narrow phase. * Skips triangle pairs that share any vertex (topological neighbors). * * @param {THREE.BufferGeometry} geometry * @param {{ get:() => number }} token - abor

(geometry, token)

Source from the content-addressed store, hash-verified

69 * phase and the Separating Axis Theorem for the narrow phase.
70 * Skips triangle pairs that share any vertex (topological neighbors).
71 *
72 * @param {THREE.BufferGeometry} geometry
73 * @param {{ get:() => number }} token - abort when token.get() !== startValue
74 * @returns {Promise<number>} count of intersecting triangle pairs
75 */
76async function findIntersectingTriangles(geometry, token) {
77 const startToken = token.get();
78 const pos = geometry.attributes.position.array;
79 const triCount = pos.length / 9;
80
81 // Assign a numeric ID to each unique vertex position (quantized).
82 // Two triangles that share any vertex are topological neighbors and must be
83 // skipped — they touch at that vertex and SAT would flag them otherwise.
84 const QUANT = 1e4;
85 const posToId = new QuantizedPointMap(QUANT, Math.min(triCount * 3, 1 << 22));
86 let nextVId = 0;
87 const triVerts = new Uint32Array(triCount * 3);
88 for (let t = 0; t < triCount; t++) {
89 const b = t * 9;
90 for (let v = 0; v < 3; v++) {
91 const off = b + v * 3;
92 const id = posToId.getOrSet(pos[off], pos[off+1], pos[off+2], nextVId);
93 if (posToId.inserted) nextVId++;
94 triVerts[t * 3 + v] = id;
95 }
96 }
97
98 function sharesVertex(a, b) {
99 const aBase = a * 3, bBase = b * 3;
100 for (let i = 0; i < 3; i++) {
101 const vid = triVerts[aBase + i];
102 if (vid === triVerts[bBase] || vid === triVerts[bBase + 1] || vid === triVerts[bBase + 2]) return true;
103 }
104 return false;
105 }
106
107 // Build per-triangle AABB
108 const minX = new Float32Array(triCount);
109 const minY = new Float32Array(triCount);
110 const minZ = new Float32Array(triCount);
111 const maxX = new Float32Array(triCount);
112 const maxY = new Float32Array(triCount);
113 const maxZ = new Float32Array(triCount);
114
115 for (let t = 0; t < triCount; t++) {
116 const b = t * 9;
117 const ax = pos[b], ay = pos[b+1], az = pos[b+2];
118 const bx = pos[b+3], by = pos[b+4], bz = pos[b+5];
119 const cx = pos[b+6], cy = pos[b+7], cz = pos[b+8];
120 minX[t] = Math.min(ax, bx, cx); maxX[t] = Math.max(ax, bx, cx);
121 minY[t] = Math.min(ay, by, cy); maxY[t] = Math.max(ay, by, cy);
122 minZ[t] = Math.min(az, bz, cz); maxZ[t] = Math.max(az, bz, cz);
123 }
124
125 // Determine grid cell size from median AABB extent
126 const extents = new Float32Array(triCount);
127 for (let t = 0; t < triCount; t++) {
128 extents[t] = Math.max(maxX[t] - minX[t], maxY[t] - minY[t], maxZ[t] - minZ[t]);

Callers 1

runExpensiveDiagnosticsFunction · 0.85

Calls 7

getOrSetMethod · 0.95
sharesVertexFunction · 0.85
trianglesIntersectSATFunction · 0.85
getMethod · 0.80
pushMethod · 0.80
cellKeyFunction · 0.70
yieldFrameFunction · 0.70

Tested by

no test coverage detected