diff --git a/vcg/complex/algorithms/implicit_smooth.h b/vcg/complex/algorithms/implicit_smooth.h index a6279d19..f5d3b5ae 100644 --- a/vcg/complex/algorithms/implicit_smooth.h +++ b/vcg/complex/algorithms/implicit_smooth.h @@ -85,6 +85,8 @@ public: std::vector ConstrainedF; //the degree of laplacian int degree; + //this is to say if we smooth the positions or the quality + bool SmoothQ; Parameter() { @@ -94,6 +96,7 @@ public: fixBorder=false; useCotWeight=false; lapWeight=1; + SmoothQ=false; } }; @@ -129,7 +132,8 @@ private: static void CollectHardConstraints(MeshType &mesh,const Parameter &SParam, std::vector > &IndexC, - std::vector &WeightC) + std::vector &WeightC, + bool SmoothQ=false) { std::vector To_Fix; @@ -153,12 +157,21 @@ private: for (size_t i=0;i(IndexV,IndexV)); + WeightC.push_back((ScalarType)PENALTY); + } + }else + { + int IndexV=To_Fix[i]; IndexC.push_back(std::pair(IndexV,IndexV)); WeightC.push_back((ScalarType)PENALTY); } + } } @@ -246,21 +259,39 @@ public: std::vector ValuesM; //add the entries for mass matrix - if (SParam.useMassMatrix) MeshToMatrix::MassMatrixEntry(mesh,IndexM,ValuesM); + if (SParam.useMassMatrix) + MeshToMatrix::MassMatrixEntry(mesh,IndexM,ValuesM,!SParam.SmoothQ); + //then add entries for lagrange mult due to barycentric constraints for (size_t i=0;i(baseIndex+j,baseIndex+j)); + IndexM.push_back(std::pair(baseIndex,baseIndex)); ValuesM.push_back(1); } + else + { + for (int j=0;j<3;j++) + { + IndexM.push_back(std::pair(baseIndex+j,baseIndex+j)); + ValuesM.push_back(1); + } + } } //add the hard constraints - CollectHardConstraints(mesh,SParam,IndexM,ValuesM); + CollectHardConstraints(mesh,SParam,IndexM,ValuesM,SParam.SmoothQ); + //initialize sparse mass matrix - InitSparse(IndexM,ValuesM,matr_size*3,matr_size*3,M); + if (!SParam.SmoothQ) + InitSparse(IndexM,ValuesM,matr_size*3,matr_size*3,M); + else + InitSparse(IndexM,ValuesM,matr_size,matr_size,M); //initialize the barycentric matrix std::vector > IndexB; @@ -270,17 +301,25 @@ public: std::vector ValuesRhs; //then also collect hard constraints - CollectBarycentricConstraints(mesh,SParam,IndexB,ValuesB,IndexRhs,ValuesRhs); - //initialize sparse constraint matrix - InitSparse(IndexB,ValuesB,matr_size*3,matr_size*3,B); + if (!SParam.SmoothQ) + { + CollectBarycentricConstraints(mesh,SParam,IndexB,ValuesB,IndexRhs,ValuesRhs); + //initialize sparse constraint matrix + InitSparse(IndexB,ValuesB,matr_size*3,matr_size*3,B); + } + else + InitSparse(IndexB,ValuesB,matr_size,matr_size,B); //get the entries for laplacian matrix std::vector > IndexL; std::vector ValuesL; - MeshToMatrix::GetLaplacianMatrix(mesh,IndexL,ValuesL,SParam.useCotWeight,SParam.lapWeight); + MeshToMatrix::GetLaplacianMatrix(mesh,IndexL,ValuesL,SParam.useCotWeight,SParam.lapWeight,!SParam.SmoothQ); //initialize sparse laplacian matrix - InitSparse(IndexL,ValuesL,matr_size*3,matr_size*3,L); + if (!SParam.SmoothQ) + InitSparse(IndexL,ValuesL,matr_size*3,matr_size*3,L); + else + InitSparse(IndexL,ValuesL,matr_size,matr_size,L); for (int i=0;i<(SParam.degree-1);i++)L=L*L; @@ -291,15 +330,30 @@ public: Eigen::SimplicialCholesky > solver(S); assert(solver.info() == Eigen::Success); - MatrixXm V(matr_size*3,1); + MatrixXm V; + if (!SParam.SmoothQ) + V=MatrixXm(matr_size*3,1); + else + V=MatrixXm(matr_size,1); //set the first part of the matrix with vertex values - for (size_t i=0;i