拉普拉斯平滑断开面

问题描述 投票:0回答:1

我已经在 JavaScript 中并使用 Three.js 实现了拉普拉斯平滑,但它似乎没有按预期工作。每当我在网格上使用悬停和平滑时,面就会断开连接并且变得越来越小。这段代码有什么问题?

平滑后网格的输出图像,白色圆圈为画笔,indices 为包含画笔下所有索引的数组。

indices.forEach( index => {

    if (params.brush === 'smooth') {

      for (let i = 0; i < 3; i++) {

        const currentVector = new THREE.Vector3().fromBufferAttribute(posAttr, index);
        const nbI = neighborMap.get(index); // Get the neighbors of the current vertex
        if (!nbI || nbI.size === 0) return; // Skip if no neighbors

        const nbIAr = Array.from(nbI); // Convert neighbor Set to array

        // Initialize average position to zero
        const avgPos = new THREE.Vector3();
        const neighborCount = nbIAr.length;

        // Calculate the average position of the neighboring vertices
        nbIAr.forEach(neighborIndex => {
          const neighborPos = new THREE.Vector3().fromBufferAttribute(posAttr, neighborIndex);
          avgPos.add(neighborPos); // Accumulate neighbor positions
        });

        avgPos.divideScalar(neighborCount); // Compute the average


        // Compute the Laplacian (difference between average and current position)
        const laplacian = new THREE.Vector3().subVectors(avgPos, currentVector);



        // Update the vertex position by moving it toward the average
        const lamdaValue = 0.005
        currentVector.addScaledVector(laplacian, lamdaValue); // λ

        tempVec.copy(currentVector);

      }
    }

    posAttr.setXYZ(index, tempVec.x, tempVec.y, tempVec.z);
    normalAttr.setXYZ(index, 0, 0, 0);

  });

我增加了 lamda 的值,它使顶点移得很远,

javascript three.js 3d mesh smoothing
1个回答
0
投票

我在平滑过程中遇到的面断开和缩小的问题与加载 STL 文件时在 Three.js 中使用

BufferGeometryUtils.mergeVertices
有关。 STL 文件不包含索引数据,因此该函数尝试生成索引。但生成的索引数据不适合拉普拉斯平滑算法,导致网格失真。

我通过加载 PLY 文件发现了这个问题,该文件默认包含索引数据。使用 PLY 文件时,拉普拉斯平滑按预期工作。

© www.soinside.com 2019 - 2024. All rights reserved.