UNPKG

@webviz/subsurface-viewer

Version:

3D visualization component for subsurface reservoir data

128 lines 5.34 kB
export function makeFullMesh(e) { const params = e.data; const t0 = performance.now(); function crossProduct(a, b) { const c = [ a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0], ]; return c; } function normalize(a) { const L = Math.sqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2]); a[0] /= L; a[1] /= L; a[2] /= L; } const line_positions = []; const vertexArray = params.vertexArray; const indexArray = params.indexArray; const ntriangles = indexArray.length / 3; const nvertices = vertexArray.length / 3; const trianglesNormals = Array(ntriangles * 3).fill(0); const vertexsNormals = Array(vertexArray.length).fill(0); // Generate lines around each triangle and one normal for each triangle. for (let t_no = 0; t_no < ntriangles; t_no++) { let indx = indexArray[3 * t_no + 0]; const x0 = vertexArray[3 * indx + 0]; const y0 = vertexArray[3 * indx + 1]; const z0 = vertexArray[3 * indx + 2]; indx = indexArray[3 * t_no + 1]; const x1 = vertexArray[3 * indx + 0]; const y1 = vertexArray[3 * indx + 1]; const z1 = vertexArray[3 * indx + 2]; indx = indexArray[3 * t_no + 2]; const x2 = vertexArray[3 * indx + 0]; const y2 = vertexArray[3 * indx + 1]; const z2 = vertexArray[3 * indx + 2]; // Triangle lines. line_positions.push(x0, y0, z0); line_positions.push(x1, y1, z1); line_positions.push(x0, y0, z0); line_positions.push(x2, y2, z2); line_positions.push(x1, y1, z1); line_positions.push(x2, y2, z2); // Normal. const v1 = [x2 - x0, y2 - y0, z2 - z0]; const v2 = [x2 - x1, y2 - y1, z2 - z1]; const normal = crossProduct(v2, v1); trianglesNormals[3 * t_no + 0] = normal[0]; trianglesNormals[3 * t_no + 1] = normal[1]; trianglesNormals[3 * t_no + 2] = normal[2]; } // For each vertex keep a list of which triangles it is part of. const vertexTrianglesArray = Array(vertexArray.length / 3); for (let i = 0; i < vertexTrianglesArray.length; i++) { vertexTrianglesArray[i] = new Array(0); } for (let t_no = 0; t_no < ntriangles; t_no++) { const v1_idx = indexArray[3 * t_no + 0]; vertexTrianglesArray[v1_idx].push(t_no); const v2_idx = indexArray[3 * t_no + 1]; vertexTrianglesArray[v2_idx].push(t_no); const v3_idx = indexArray[3 * t_no + 2]; vertexTrianglesArray[v3_idx].push(t_no); } // The normal for each vertex is the mean of the normals belonging to the triangles that // share this vertex. for (let vertex_no = 0; vertex_no < nvertices; vertex_no++) { const n_triangles = vertexTrianglesArray[vertex_no].length; // No triangles this vertex is part of. Will be at leat 1. const t0 = vertexTrianglesArray[vertex_no][0]; // first triangle const normal_mean = [ trianglesNormals[3 * t0 + 0], trianglesNormals[3 * t0 + 1], trianglesNormals[3 * t0 + 2], ]; // possible rest of triangles for (let t_no = 1; t_no < n_triangles; t_no++) { const t = vertexTrianglesArray[vertex_no][t_no]; const normal = [ trianglesNormals[3 * t + 0], trianglesNormals[3 * t + 1], trianglesNormals[3 * t + 2], ]; normal_mean[0] += normal[0]; normal_mean[1] += normal[1]; normal_mean[2] += normal[2]; } normalize(normal_mean); vertexsNormals[3 * vertex_no + 0] = normal_mean[0]; vertexsNormals[3 * vertex_no + 1] = normal_mean[1]; vertexsNormals[3 * vertex_no + 2] = normal_mean[2]; // Debug. Verify normal calculations by displaying normals. const isDebug = params.displayNormals; if (isDebug) { const x0 = vertexArray[3 * vertex_no + 0]; const y0 = vertexArray[3 * vertex_no + 1]; const z0 = vertexArray[3 * vertex_no + 2]; const scale = 50; const x1 = x0 + normal_mean[0] * scale; const y1 = y0 + normal_mean[1] * scale; const z1 = z0 + normal_mean[2] * scale; line_positions.push(x0, y0, z0); line_positions.push(x1, y1, z1); } } const geometryTriangles = { topology: "triangle-list", attributes: { positions: { value: new Float32Array(vertexArray), size: 3 }, normals: { value: new Float32Array(vertexsNormals), size: 3 }, vertex_indexs: { value: new Int32Array(indexArray), size: 1 }, }, vertexCount: indexArray.length, indices: { value: new Uint32Array(indexArray), size: 1 }, }; const geometryLines = { topology: "line-list", attributes: { positions: { value: new Float32Array(line_positions), size: 3 }, }, vertexCount: line_positions.length / 3, }; const t1 = performance.now(); console.debug(`Task makeMesh took ${(t1 - t0) * 0.001} seconds.`); return [geometryTriangles, geometryLines]; } //# sourceMappingURL=webworker.js.map