javascriptthree.js3dmeshsmoothing

Laplacian Smooth disconnecting faces


I have implemented Laplacian smooth in JavaScript and using Three.js, but it seems to be not working as expected. Whenever I use hover and smooth over meshes, the faces are disconnecting and getting smaller and smaller. What's wrong with this code ?

Output image of mesh after smoothing, the white circle is brush, and indices is the array which contains all the indices under the brush.

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);

  });

I have increased value of lamda and it moved the vertex far away,


Solution

  • The issue I was facing with faces disconnecting and shrinking during smoothing is related to the use of BufferGeometryUtils.mergeVertices in Three.js, when loading an STL file. STL files do not contain index data, so this function attempts to generate indices. However, the generated index data is not suitable for the Laplacian smoothing algorithm, causing the mesh distortion.

    I discovered the issue by loading a PLY file instead, which contains index data by default. When using the PLY file, the Laplacian smoothing worked as expected.