diff --git a/vcg/complex/trimesh/smooth.h b/vcg/complex/trimesh/smooth.h index 5a8727b6..4c95d4bf 100644 --- a/vcg/complex/trimesh/smooth.h +++ b/vcg/complex/trimesh/smooth.h @@ -23,6 +23,10 @@ /**************************************************************************** History $Log: not supported by cvs2svn $ +Revision 1.19 2008/05/08 23:50:44 cignoni +renamed vertex quality smoothing +added face normal smoothing FF (and added a VF to the previous face normal smoothing) + Revision 1.18 2008/05/02 09:43:25 cignoni Added color smoothing, scale dependent laplacian changed a SD_old into SD fujumori, improved comments. @@ -101,20 +105,42 @@ first partial porting: compiled gcc,intel and msvc namespace vcg { +namespace tri +{ +/// +/** \addtogroup trimesh */ +/*@{*/ +/// Class of static functions to smooth and fair meshes and their attributes. + +template +class Smooth +{ -template +public: + typedef SmoothMeshType MeshType; + typedef typename MeshType::VertexType VertexType; + typedef typename MeshType::VertexType::CoordType CoordType; + typedef typename MeshType::VertexPointer VertexPointer; + typedef typename MeshType::VertexIterator VertexIterator; + typedef typename MeshType::ScalarType ScalarType; + typedef typename MeshType::FaceType FaceType; + typedef typename MeshType::FacePointer FacePointer; + typedef typename MeshType::FaceIterator FaceIterator; + typedef typename MeshType::FaceContainer FaceContainer; + typedef typename vcg::Box3 Box3Type; + typedef typename vcg::face::VFIterator VFLocalIterator; + class ScaleLaplacianInfo { public: - Point3 PntSum; - FLT LenSum; + CoordType PntSum; + ScalarType LenSum; }; // This is precisely what curvature flow does. // Curvature flow smoothes the surface by moving along the surface // normal n with a speed equal to the mean curvature -template -void LaplacianSmooth_CurvatureFlow(MESH_TYPE &m, int step, typename MESH_TYPE::ScalarType delta) +void VertexCoordLaplacianCurvatureFlow(MeshType &m, int step, ScalarType delta) { } @@ -122,27 +148,25 @@ void LaplacianSmooth_CurvatureFlow(MESH_TYPE &m, int step, typename MESH_TYPE:: // Another Laplacian smoothing variant, // here we sum the baricenter of the faces incidents on each vertex weighting them with the angle -template -void LaplacianSmooth_AngleWeighted(MESH_TYPE &m, int step, typename MESH_TYPE::ScalarType delta) +static void VertexCoordLaplacianAngleWeighted(MeshType &m, int step, ScalarType delta) { - SimpleTempData > TD(m.vert); - ScaleLaplacianInfo lpz; - lpz.PntSum=typename MESH_TYPE::CoordType(0,0,0); + ScaleLaplacianInfo lpz; + lpz.PntSum=CoordType(0,0,0); lpz.LenSum=0; - TD.Start(lpz); - typename MESH_TYPE::FaceIterator fi; + SimpleTempData TD(m.vert,lpz); + FaceIterator fi; for(int i=0;iP() + (*fi).V(1)->P() + (*fi).V(2)->P())/3.0; - typename MESH_TYPE::CoordType e0=((*fi).V(0)->P() - (*fi).V(1)->P()).Normalize(); - typename MESH_TYPE::CoordType e1=((*fi).V(1)->P() - (*fi).V(2)->P()).Normalize(); - typename MESH_TYPE::CoordType e2=((*fi).V(2)->P() - (*fi).V(0)->P()).Normalize(); + CoordType mp=((*fi).V(0)->P() + (*fi).V(1)->P() + (*fi).V(2)->P())/3.0; + CoordType e0=((*fi).V(0)->P() - (*fi).V(1)->P()).Normalize(); + CoordType e1=((*fi).V(1)->P() - (*fi).V(2)->P()).Normalize(); + CoordType e2=((*fi).V(2)->P() - (*fi).V(0)->P()).Normalize(); a[0]=AngleN(-e0,e2); a[1]=AngleN(-e1,e0); @@ -150,7 +174,7 @@ void LaplacianSmooth_AngleWeighted(MESH_TYPE &m, int step, typename MESH_TYPE:: //assert(fabs(M_PI -a[0] -a[1] -a[2])<0.0000001); for(int j=0;j<3;++j){ - typename MESH_TYPE::CoordType dir= (mp-(*fi).V(j)->P()).Normalize(); + CoordType dir= (mp-(*fi).V(j)->P()).Normalize(); TD[(*fi).V(j)].PntSum+=dir*a[j]; TD[(*fi).V(j)].LenSum+=a[j]; // well, it should be named angleSum } @@ -160,7 +184,6 @@ void LaplacianSmooth_AngleWeighted(MESH_TYPE &m, int step, typename MESH_TYPE:: (*vi).P() = (*vi).P() + (TD[*vi].PntSum/TD[*vi].LenSum ) * delta; } - TD.Stop(); }; // Scale dependent laplacian smoothing [Fujiwara 95] @@ -173,26 +196,25 @@ void LaplacianSmooth_AngleWeighted(MESH_TYPE &m, int step, typename MESH_TYPE:: // Note the delta parameter is in a absolute unit // it should be a small percentage of the shortest edge. -template -void ScaleDependentLaplacianSmooth_Fujiwara(MESH_TYPE &m, int step, typename MESH_TYPE::ScalarType delta) +static void VertexCoordScaleDependentLaplacian_Fujiwara(MeshType &m, int step, ScalarType delta) { - SimpleTempData > TD(m.vert); - ScaleLaplacianInfo lpz; - lpz.PntSum=typename MESH_TYPE::CoordType(0,0,0); + SimpleTempData TD(m.vert); + ScaleLaplacianInfo lpz; + lpz.PntSum=CoordType(0,0,0); lpz.LenSum=0; TD.Start(lpz); - typename MESH_TYPE::FaceIterator fi; + FaceIterator fi; for(int i=0;iP() -(*fi).V(j)->P(); - typename MESH_TYPE::ScalarType len=Norm(edge); + CoordType edge= (*fi).V1(j)->P() -(*fi).V(j)->P(); + ScalarType len=Norm(edge); edge/=len; TD[(*fi).V(j)].PntSum+=edge; TD[(*fi).V1(j)].PntSum-=edge; @@ -204,8 +226,8 @@ void ScaleDependentLaplacianSmooth_Fujiwara(MESH_TYPE &m, int step, typename ME for(int j=0;j<3;++j) // se l'edge j e' di bordo si riazzera tutto e si riparte if((*fi).IsB(j)) { - TD[(*fi).V(j)].PntSum=typename MESH_TYPE::CoordType(0,0,0); - TD[(*fi).V1(j)].PntSum=typename MESH_TYPE::CoordType(0,0,0); + TD[(*fi).V(j)].PntSum=CoordType(0,0,0); + TD[(*fi).V1(j)].PntSum=CoordType(0,0,0); TD[(*fi).V(j)].LenSum=0; TD[(*fi).V1(j)].LenSum=0; } @@ -215,8 +237,8 @@ void ScaleDependentLaplacianSmooth_Fujiwara(MESH_TYPE &m, int step, typename ME for(int j=0;j<3;++j) if((*fi).IsB(j)) { - typename MESH_TYPE::CoordType edge= (*fi).V1(j)->P() -(*fi).V(j)->P(); - typename MESH_TYPE::ScalarType len=Norm(edge); + CoordType edge= (*fi).V1(j)->P() -(*fi).V(j)->P(); + ScalarType len=Norm(edge); edge/=len; TD[(*fi).V(j)].PntSum+=edge; TD[(*fi).V1(j)].PntSum-=edge; @@ -237,33 +259,30 @@ void ScaleDependentLaplacianSmooth_Fujiwara(MESH_TYPE &m, int step, typename ME }; -template class LaplacianInfo { public: - Point3 sum; - FLT cnt; + CoordType sum; + ScalarType cnt; }; // Classical Laplacian Smoothing. Each vertex can be moved onto the average of the adjacent vertices. // Can smooth only the selected vertices and weight the smoothing according to the quality // In the latter case 0 means that the vertex is not moved and 1 means that the vertex is moved onto the computed position. -template -void LaplacianSmooth(MESH_TYPE &m, int step, bool SmoothSelected=false, float QualityWeight=0) +static void VertexCoordLaplacian(MeshType &m, int step, bool SmoothSelected=false, float QualityWeight=0) { - SimpleTempData > TD(m.vert); - LaplacianInfo lpz; - lpz.sum=typename MESH_TYPE::CoordType(0,0,0); + LaplacianInfo lpz; + lpz.sum=CoordType(0,0,0); lpz.cnt=1; - TD.Start(lpz); + SimpleTempData TD(m.vert,lpz); for(int i=0;i class HCSmoothInfo { public: - Point3 dif; - Point3 sum; + CoordType dif; + CoordType sum; int cnt; }; -template -void HCSmooth(MESH_TYPE &m, int step, bool SmoothSelected=false ) + +static void VertexCoordLaplacianHC(MeshType &m, int step, bool SmoothSelected=false ) { - typename MESH_TYPE::ScalarType beta=0.5; - SimpleTempData > TD(m.vert); - HCSmoothInfo lpz; - lpz.sum=typename MESH_TYPE::CoordType(0,0,0); - lpz.dif=typename MESH_TYPE::CoordType(0,0,0); + ScalarType beta=0.5; + HCSmoothInfo lpz; + lpz.sum=CoordType(0,0,0); + lpz.dif=CoordType(0,0,0); lpz.cnt=0; - TD.Start(lpz); + SimpleTempData TD(m.vert,lpz); // First Loop compute the laplacian - typename MESH_TYPE::FaceIterator fi; + FaceIterator fi; for(fi=m.face.begin();fi!=m.face.end();++fi)if(!(*fi).IsD()) { for(int j=0;j<3;++j) @@ -369,7 +384,7 @@ void HCSmooth(MESH_TYPE &m, int step, bool SmoothSelected=false ) } } } - typename MESH_TYPE::VertexIterator vi; + VertexIterator vi; for(vi=m.vert.begin();vi!=m.vert.end();++vi) if(!(*vi).IsD()) TD[*vi].sum/=(float)TD[*vi].cnt; @@ -395,8 +410,6 @@ void HCSmooth(MESH_TYPE &m, int step, bool SmoothSelected=false ) if(!SmoothSelected || (*vi).IsS()) (*vi).P()= TD[*vi].sum - (TD[*vi].sum - (*vi).P())*beta + (TD[*vi].dif)*(1.f-beta); } - - TD.Stop(); }; // Laplacian smooth of the quality. @@ -412,20 +425,19 @@ public: int cnt; }; -template void LaplacianSmoothColor(MESH_TYPE &m, int step, bool SmoothSelected=false) +static void VertexColorLaplacian(MeshType &m, int step, bool SmoothSelected=false) { - SimpleTempData TD(m.vert); ColorSmoothInfo csi; csi.r=0; csi.g=0; csi.b=0; csi.cnt=0; + SimpleTempData TD(m.vert,csi); - TD.Start(csi); for(int i=0;i void LaplacianSmoothColor(MESH_TYPE &m, int step, bool (*vi).C()[3] = (unsigned int) ceil((double) (TD[*vi].a / TD[*vi].cnt)); } } - - TD.Stop(); }; // Laplacian smooth of the quality. -template + class QualitySmoothInfo { public: - FLT sum; + ScalarType sum; int cnt; }; -template -void VertexQualitySmooth(MESH_TYPE &m, int step=1, bool SmoothSelected=false) + +static void VertexQualityLaplacian(MeshType &m, int step=1, bool SmoothSelected=false) { - SimpleTempData > TD(m.vert); - QualitySmoothInfo lpz; + QualitySmoothInfo lpz; lpz.sum=0; lpz.cnt=0; - TD.Start(lpz); + SimpleTempData TD(m.vert,lpz); + //TD.Start(lpz); for(int i=0;i0 ) if(!SmoothSelected || (*vi).IsS()) (*vi).Q()=TD[*vi].sum/TD[*vi].cnt; } - TD.Stop(); + //TD.Stop(); }; -template -void LaplacianSmoothNormals(MESH_TYPE &m, int step,bool SmoothSelected=false) + +static void VertexNormalLaplacian(MeshType &m, int step,bool SmoothSelected=false) { - SimpleTempData > TD(m.vert); - LaplacianInfo lpz; - lpz.sum=typename MESH_TYPE::CoordType(0,0,0); + SimpleTempData TD(m.vert); + LaplacianInfo lpz; + lpz.sum=CoordType(0,0,0); lpz.cnt=0; TD.Start(lpz); for(int i=0;i0 ) if(!SmoothSelected || (*vi).IsS()) @@ -617,31 +627,23 @@ void LaplacianSmoothNormals(MESH_TYPE &m, int step,bool SmoothSelected=false) // Smooth solo lungo la direzione di vista // alpha e' compreso fra 0(no smoot) e 1 (tutto smoot) // Nota che se smootare il bordo puo far fare bandierine. -template -void DepthSmooth(MESH_TYPE &m, - const typename MESH_TYPE::CoordType & viewpoint, - const typename MESH_TYPE::ScalarType alpha, +static void VertexCoordViewDepth(MeshType &m, + const CoordType & viewpoint, + const ScalarType alpha, int step, bool SmoothBorder=false ) { - typedef typename MESH_TYPE::CoordType v_type; - typedef typename MESH_TYPE::ScalarType s_type; - - - //const typename MESH_TYPE::CoordType viewpoint; - //const typename MESH_TYPE::ScalarType alpha; - - SimpleTempData > TD(m.vert); - LaplacianInfo lpz; - lpz.sum=typename MESH_TYPE::CoordType(0,0,0); + SimpleTempData TD(m.vert); + LaplacianInfo lpz; + lpz.sum=CoordType(0,0,0); lpz.cnt=0; TD.Start(lpz); for(int i=0;i0 ) { - v_type np = TD[*vi].sum/TD[*vi].cnt; - v_type d = (*vi).Supervisor_P() - viewpoint; d.Normalize(); - s_type s = d * ( np - (*vi).Supervisor_P() ); + CoordType np = TD[*vi].sum/TD[*vi].cnt; + CoordType d = (*vi).Supervisor_P() - viewpoint; d.Normalize(); + ScalarType s = d * ( np - (*vi).Supervisor_P() ); (*vi).Supervisor_P() += d * (s*alpha); } } @@ -700,18 +702,18 @@ void DepthSmooth(MESH_TYPE &m, /****************************************************************************************************************/ /****************************************************************************************************************/ // Classi di info -template + class PDVertInfo { public: - Point3 np; + CoordType np; }; -template + class PDFaceInfo { public: - Point3 m; + CoordType m; }; /***************************************************************************/ // Paso Doble Step 1 compute the smoothed normals @@ -723,16 +725,14 @@ public: // This is the Normal Smoothing approach of Shen and Berner // Fuzzy Vector Median-Based Surface Smoothing TVCG 2004 -template -void NormalSmoothSB(MESH_TYPE &m, - SimpleTempData > &TD, - typename MESH_TYPE::ScalarType sigma) + +void FaceNormalFuzzyVectorSB(MeshType &m, + SimpleTempData &TD, + ScalarType sigma) { int i; - typedef typename MESH_TYPE::CoordType CoordType; - typedef typename MESH_TYPE::ScalarType ScalarType; - typename MESH_TYPE::FaceIterator fi; + FaceIterator fi; for(fi=m.face.begin();fi!=m.face.end();++fi) { @@ -740,7 +740,7 @@ void NormalSmoothSB(MESH_TYPE &m, // 1) Clear all the visited flag of faces that are vertex-adjacent to fi for(i=0;i<3;++i) { - vcg::face::VFIterator ep(&*fi,i); + vcg::face::VFIterator ep(&*fi,i); while (!ep.End()) { ep.f->ClearV(); @@ -753,7 +753,7 @@ void NormalSmoothSB(MESH_TYPE &m, CoordType mm=CoordType(0,0,0); for(i=0;i<3;++i) { - vcg::face::VFIterator ep(&*fi,i); + vcg::face::VFIterator ep(&*fi,i); while (!ep.End()) { if(! (*ep.f).IsV() ) @@ -781,28 +781,24 @@ void NormalSmoothSB(MESH_TYPE &m, // Normals are normalized: // VF adjacency is present. -template -void FaceNormalSmoothVF(MESH_TYPE &m) +static void FaceNormalLaplacianVF(MeshType &m) { - SimpleTempData > TDF(m.face); + SimpleTempData TDF(m.face); - PDFaceInfo lpzf; - lpzf.m=typename MESH_TYPE::CoordType(0,0,0); + PDFaceInfo lpzf; + lpzf.m=CoordType(0,0,0); assert(tri::HasVFAdjacency(m)); TDF.Start(lpzf); int i; - typedef typename MESH_TYPE::CoordType CoordType; - typedef typename MESH_TYPE::ScalarType ScalarType; - typedef typename vcg::face::VFIterator VFLocalIterator; - typename MESH_TYPE::FaceIterator fi; + FaceIterator fi; - tri::UpdateNormals::AreaNormalizeFace(m); + tri::UpdateNormals::AreaNormalizeFace(m); for(fi=m.face.begin();fi!=m.face.end();++fi) if(!(*fi).IsD()) { - CoordType bc=Barycenter(*fi); + CoordType bc=Barycenter(*fi); // 1) Clear all the visited flag of faces that are vertex-adjacent to fi for(i=0;i<3;++i) { @@ -832,7 +828,7 @@ void FaceNormalSmoothVF(MESH_TYPE &m) for(fi=m.face.begin();fi!=m.face.end();++fi) (*fi).N()=TDF[*fi].m; - tri::UpdateNormals::NormalizeFace(m); + tri::UpdateNormals::NormalizeFace(m); TDF.Stop(); } @@ -843,24 +839,16 @@ void FaceNormalSmoothVF(MESH_TYPE &m) // Normals are normalized: // FF adjacency is present. -template -void FaceNormalSmoothFF(MESH_TYPE &m, int step=1, bool SmoothSelected=false ) -{ - SimpleTempData > TDF(m.face); - - PDFaceInfo lpzf; - lpzf.m=typename MESH_TYPE::CoordType(0,0,0); +static void FaceNormalLaplacianFF(MeshType &m, int step=1, bool SmoothSelected=false ) +{ + PDFaceInfo lpzf; + lpzf.m=CoordType(0,0,0); + SimpleTempData TDF(m.face,lpzf); assert(tri::HasFFAdjacency(m)); - TDF.Start(lpzf); - int i; - - typedef typename MESH_TYPE::CoordType CoordType; -// typedef typename MESH_TYPE::ScalarType ScalarType; -// typedef typename vcg::face::VFIterator VFLocalIterator; - typename MESH_TYPE::FaceIterator fi; - - tri::UpdateNormals::AreaNormalizeFace(m); + + FaceIterator fi; + tri::UpdateNormals::AreaNormalizeFace(m); for(int i=0;i::NormalizeFace(m); + tri::UpdateNormals::NormalizeFace(m); } - TDF.Stop(); } @@ -895,21 +882,19 @@ void FaceNormalSmoothFF(MESH_TYPE &m, int step=1, bool SmoothSelected=false ) // sigma == 1 Nothing is averaged. // Only within the specified range are averaged toghether. The averagin is weighted with the -template -void NormalSmooth(MESH_TYPE &m, - SimpleTempData > &TD, - typename MESH_TYPE::ScalarType sigma) + +static void FaceNormalAngleThreshold(MeshType &m, + SimpleTempData &TD, + ScalarType sigma) { int i; - typedef typename MESH_TYPE::CoordType CoordType; - typedef typename MESH_TYPE::ScalarType ScalarType; - typedef typename vcg::face::VFIterator VFLocalIterator; - typename MESH_TYPE::FaceIterator fi; + + FaceIterator fi; for(fi=m.face.begin();fi!=m.face.end();++fi) if(!(*fi).IsD()) { - CoordType bc=Barycenter(*fi); + CoordType bc=Barycenter(*fi); // 1) Clear all the visited flag of faces that are vertex-adjacent to fi for(i=0;i<3;++i) { @@ -954,19 +939,19 @@ void NormalSmooth(MESH_TYPE &m, // Restituisce il gradiente dell'area del triangolo nel punto p. // Nota che dovrebbe essere sempre un vettore che giace nel piano del triangolo e perpendicolare al lato opposto al vertice p. // Ottimizzato con Maple e poi pesantemente a mano. -template -Point3 TriAreaGradient(Point3 &p,Point3 &p0,Point3 &p1) + +CoordType TriAreaGradient(CoordType &p,CoordType &p0,CoordType &p1) { - Point3 dd = p1-p0; - Point3 d0 = p-p0; - Point3 d1 = p-p1; - Point3 grad; + CoordType dd = p1-p0; + CoordType d0 = p-p0; + CoordType d1 = p-p1; + CoordType grad; - FLT t16 = d0[1]* d1[2] - d0[2]* d1[1]; - FLT t5 = -d0[2]* d1[0] + d0[0]* d1[2]; - FLT t4 = -d0[0]* d1[1] + d0[1]* d1[0]; + ScalarType t16 = d0[1]* d1[2] - d0[2]* d1[1]; + ScalarType t5 = -d0[2]* d1[0] + d0[0]* d1[2]; + ScalarType t4 = -d0[0]* d1[1] + d0[1]* d1[0]; - FLT delta= sqrtf(t4*t4 + t5*t5 +t16*t16); + ScalarType delta= sqrtf(t4*t4 + t5*t5 +t16*t16); grad[0]= (t5 * (-dd[2]) + t4 * ( dd[1]))/delta; grad[1]= (t16 * (-dd[2]) + t4 * (-dd[0]))/delta; @@ -975,12 +960,12 @@ Point3 TriAreaGradient(Point3 &p,Point3 &p0,Point3 &p1) return grad; } -template -Point3 CrossProdGradient(Point3 &p, Point3 &p0, Point3 &p1, Point3 &m) +template +CoordType CrossProdGradient(CoordType &p, CoordType &p0, CoordType &p1, CoordType &m) { - Point3 grad; - Point3 p00=p0-p; - Point3 p01=p1-p; + CoordType grad; + CoordType p00=p0-p; + CoordType p01=p1-p; grad[0] = (-p00[2] + p01[2])*m[1] + (-p01[1] + p00[1])*m[2]; grad[1] = (-p01[2] + p00[2])*m[0] + (-p00[0] + p01[0])*m[2]; grad[2] = (-p00[1] + p01[1])*m[0] + (-p01[0] + p00[0])*m[1]; @@ -998,8 +983,8 @@ A(...) (2-2nm) = 2A - 2 (p0-p)^(p1-p) * m */ -template -Point3 FaceErrorGrad(Point3 &p,Point3 &p0,Point3 &p1, Point3 &m) + +CoordType FaceErrorGrad(CoordType &p,CoordType &p0,CoordType &p1, CoordType &m) { return TriAreaGradient(p,p0,p1) *2.0f - CrossProdGradient(p,p0,p1,m) *2.0f ; @@ -1008,17 +993,15 @@ Point3 FaceErrorGrad(Point3 &p,Point3 &p0,Point3 &p1, Point3 // Paso Doble Step 2 Fitta la mesh a un dato insieme di normali /***************************************************************************/ -template -void FitMesh(MESH_TYPE &m, - SimpleTempData > &TDV, - SimpleTempData > &TDF, + +void FitMesh(MeshType &m, + SimpleTempData &TDV, + SimpleTempData &TDF, float lambda) { - //vcg::face::Pos ep; - vcg::face::VFIterator ep; - typename MESH_TYPE::VertexIterator vi; - typedef typename MESH_TYPE::ScalarType ScalarType; - typedef typename MESH_TYPE::CoordType CoordType; + //vcg::face::Pos ep; + vcg::face::VFIterator ep; + VertexIterator vi; for(vi=m.vert.begin();vi!=m.vert.end();++vi) { CoordType ErrGrad=CoordType(0,0,0); @@ -1040,18 +1023,15 @@ void FitMesh(MESH_TYPE &m, /****************************************************************************************************************/ -template -void FastFitMesh(MESH_TYPE &m, - SimpleTempData > &TDV, - SimpleTempData > &TDF, + +static void FastFitMesh(MeshType &m, + SimpleTempData &TDV, + SimpleTempData &TDF, bool OnlySelected=false) { - //vcg::face::Pos ep; - vcg::face::VFIterator ep; - typename MESH_TYPE::VertexIterator vi; - typedef typename MESH_TYPE::ScalarType ScalarType; - typedef typename MESH_TYPE::CoordType CoordType; - typedef typename vcg::face::VFIterator VFLocalIterator; + //vcg::face::Pos ep; + vcg::face::VFIterator ep; + VertexIterator vi; for(vi=m.vert.begin();vi!=m.vert.end();++vi) { @@ -1060,7 +1040,7 @@ void FastFitMesh(MESH_TYPE &m, VFLocalIterator ep(&*vi); for (;!ep.End();++ep) { - CoordType bc=Barycenter(*ep.F()); + CoordType bc=Barycenter(*ep.F()); Sum += ep.F()->N()*(ep.F()->N()*(bc - (*vi).P())); ++cnt; } @@ -1081,21 +1061,13 @@ void FastFitMesh(MESH_TYPE &m, - - - -template -void PasoDobleSmooth(MeshType &m, int step, typename MeshType::ScalarType Sigma=0, int FitStep=10, typename MeshType::ScalarType FitLambda=0.05) +static void VertexCoordPasoDoble(MeshType &m, int step, typename MeshType::ScalarType Sigma=0, int FitStep=10, typename MeshType::ScalarType FitLambda=0.05) { - typedef typename MeshType::ScalarType ScalarType; - typedef typename MeshType::CoordType CoordType; - - - SimpleTempData< typename MeshType::VertContainer, PDVertInfo > TDV(m.vert); - SimpleTempData< typename MeshType::FaceContainer, PDFaceInfo > TDF(m.face); - PDVertInfo lpzv; + SimpleTempData< typename MeshType::VertContainer, PDVertInfo> TDV(m.vert); + SimpleTempData< typename MeshType::FaceContainer, PDFaceInfo> TDF(m.face); + PDVertInfo lpzv; lpzv.np=CoordType(0,0,0); - PDFaceInfo lpzf; + PDFaceInfo lpzf; lpzf.m=CoordType(0,0,0); assert(m.HasVFTopology()); @@ -1106,9 +1078,9 @@ void PasoDobleSmooth(MeshType &m, int step, typename MeshType::ScalarType Sigma= { vcg::tri::UpdateNormals::PerFace(m); - NormalSmooth(m,TDF,Sigma); + FaceNormalAngleThreshold(m,TDF,Sigma); for(int k=0;k(m,TDV,TDF,FitLambda); + FitMesh(m,TDV,TDF,FitLambda); } TDF.Stop(); @@ -1118,41 +1090,28 @@ void PasoDobleSmooth(MeshType &m, int step, typename MeshType::ScalarType Sigma= // The sigma parameter affect the normal smoothing step - -template -void PasoDobleSmoothFast(MeshType &m, int step, typename MeshType::ScalarType Sigma=0, int FitStep=50, bool SmoothSelected =false) +static void VertexCoordPasoDobleFast(MeshType &m, int step, typename MeshType::ScalarType Sigma=0, int FitStep=50, bool SmoothSelected =false) { - typedef typename MeshType::ScalarType ScalarType; - typedef typename MeshType::CoordType CoordType; - - - SimpleTempData< typename MeshType::VertContainer, PDVertInfo > TDV(m.vert); - SimpleTempData< typename MeshType::FaceContainer, PDFaceInfo > TDF(m.face); - PDVertInfo lpzv; + PDVertInfo lpzv; lpzv.np=CoordType(0,0,0); - PDFaceInfo lpzf; + PDFaceInfo lpzf; lpzf.m=CoordType(0,0,0); assert(m.HasVFTopology()); m.HasVFTopology(); - TDV.Start(lpzv); - TDF.Start(lpzf); + SimpleTempData< typename MeshType::VertContainer, PDVertInfo> TDV(m.vert,lpzv); + SimpleTempData< typename MeshType::FaceContainer, PDFaceInfo> TDF(m.face,lpzf); for(int j=0;j(m,TDF,Sigma); + FaceNormalAngleThreshold(m,TDF,Sigma); for(int j=0;j(m,TDV,TDF,SmoothSelected); - - - - TDF.Stop(); - TDV.Stop(); - + FastFitMesh(m,TDV,TDF,SmoothSelected); } +}; //end Smooth class - +} // End namespace tri } // End namespace vcg #endif // VCG_SMOOTH