inline void igl::PlanarizerShapeUp<DerivedV, DerivedF>::planarize(Eigen::PlainObjectBase<DerivedV> &Vout) { Eigen::Matrix<typename DerivedV::Scalar, Eigen::Dynamic, 1> planarity; Vout = Vin; for (int iter =0; iter<maxIter; ++iter) { igl::quad_planarity(Vout, Fin, planarity); typename DerivedV::Scalar nonPlanarity = planarity.cwiseAbs().maxCoeff(); //std::cerr<<"iter #"<<iter<<": max non-planarity: "<<nonPlanarity<<std::endl; if (nonPlanarity<threshold) break; assembleP(); Vv = solver.solve(Q.transpose()*P); if(solver.info()!=Eigen::Success) { std::cerr << "Linear solve failed - PlanarizerShapeUp.cpp" << std::endl; assert(0); } for (int i =0;i<numV;++i) Vout.row(i) << Vv.segment(3*i,3).transpose(); } // set the mean of Vout to the mean of Vin Eigen::Matrix<typename DerivedV::Scalar, 1, 3> oldMean, newMean; oldMean = Vin.colwise().mean(); newMean = Vout.colwise().mean(); Vout.rowwise() += (oldMean - newMean); };
inline void igl::PlanarizerShapeUp<DerivedV, DerivedF>::assembleP() { P.setZero(3*ni*numF); for (int fi = 0; fi< numF; fi++) { // todo: this can be made faster by omitting the selector matrix Eigen::SparseMatrix<typename DerivedV::Scalar > Sfi; assembleSelector(fi, Sfi); Eigen::SparseMatrix<typename DerivedV::Scalar > NSi = Ni*Sfi; Eigen::Matrix<typename DerivedV::Scalar, Eigen::Dynamic, 1> Vi = NSi*Vv; Eigen::Matrix<typename DerivedV::Scalar, Eigen::Dynamic, Eigen::Dynamic> CC(3,ni); for (int i = 0; i <ni; ++i) CC.col(i) = Vi.segment(3*i, 3); Eigen::Matrix<typename DerivedV::Scalar, 3, 3> C = CC*CC.transpose(); // Alec: Doesn't compile Eigen::EigenSolver<Eigen::Matrix<typename DerivedV::Scalar, 3, 3>> es(C); // the real() is for compilation purposes Eigen::Matrix<typename DerivedV::Scalar, 3, 1> lambda = es.eigenvalues().real(); Eigen::Matrix<typename DerivedV::Scalar, 3, 3> U = es.eigenvectors().real(); int min_i; lambda.cwiseAbs().minCoeff(&min_i); U.col(min_i).setZero(); Eigen::Matrix<typename DerivedV::Scalar, Eigen::Dynamic, Eigen::Dynamic> PP = U*U.transpose()*CC; for (int i = 0; i <ni; ++i) P.segment(3*ni*fi+3*i, 3) = weightsSqrt[fi]*PP.col(i); } }