@@ -970,17 +970,34 @@ function toolSmooth( mesh, iVerts, intensity ) {
970970 const mAr = mesh . getMaterials ( ) ;
971971 const nbVerts = iVerts . length ;
972972 const smoothVerts = new Float32Array ( getMemory ( nbVerts * 4 * 3 ) , 0 , nbVerts * 3 ) ;
973+
974+ // Taubin lambda-mu smoothing: two passes to prevent volume shrinkage
975+ const lambda = 0.5 ;
976+ const mu = - 0.53 ;
977+
978+ // Forward pass (shrink)
973979 laplacianSmooth ( mesh , iVerts , smoothVerts ) ;
974980 for ( let i = 0 ; i < nbVerts ; ++ i ) {
975981
976982 const ind = iVerts [ i ] * 3 ;
977- const vx = vAr [ ind ] , vy = vAr [ ind + 1 ] , vz = vAr [ ind + 2 ] ;
978983 const i3 = i * 3 ;
979- const mI = intensity * mAr [ ind + 2 ] ;
980- const intComp = 1.0 - mI ;
981- vAr [ ind ] = vx * intComp + smoothVerts [ i3 ] * mI ;
982- vAr [ ind + 1 ] = vy * intComp + smoothVerts [ i3 + 1 ] * mI ;
983- vAr [ ind + 2 ] = vz * intComp + smoothVerts [ i3 + 2 ] * mI ;
984+ const mI = intensity * mAr [ ind + 2 ] * lambda ;
985+ vAr [ ind ] += ( smoothVerts [ i3 ] - vAr [ ind ] ) * mI ;
986+ vAr [ ind + 1 ] += ( smoothVerts [ i3 + 1 ] - vAr [ ind + 1 ] ) * mI ;
987+ vAr [ ind + 2 ] += ( smoothVerts [ i3 + 2 ] - vAr [ ind + 2 ] ) * mI ;
988+
989+ }
990+
991+ // Backward pass (expand to restore volume)
992+ laplacianSmooth ( mesh , iVerts , smoothVerts ) ;
993+ for ( let i = 0 ; i < nbVerts ; ++ i ) {
994+
995+ const ind = iVerts [ i ] * 3 ;
996+ const i3 = i * 3 ;
997+ const mI = intensity * mAr [ ind + 2 ] * mu ;
998+ vAr [ ind ] += ( smoothVerts [ i3 ] - vAr [ ind ] ) * mI ;
999+ vAr [ ind + 1 ] += ( smoothVerts [ i3 + 1 ] - vAr [ ind + 1 ] ) * mI ;
1000+ vAr [ ind + 2 ] += ( smoothVerts [ i3 + 2 ] - vAr [ ind + 2 ] ) * mI ;
9841001
9851002 }
9861003
0 commit comments