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); };
IGL_INLINE void igl::bounding_box( const Eigen::PlainObjectBase<DerivedV>& V, Eigen::PlainObjectBase<DerivedBV>& BV, Eigen::PlainObjectBase<DerivedBF>& BF) { using namespace std; const int dim = V.cols(); const auto & minV = V.colwise().minCoeff(); const auto & maxV = V.colwise().maxCoeff(); // 2^n vertices BV.resize((1<<dim),dim); // Recursive lambda to generate all 2^n combinations const std::function<void(const int,const int,int*,int)> combos = [&BV,&minV,&maxV,&combos]( const int dim, const int i, int * X, const int pre_index) { for(X[i] = 0;X[i]<2;X[i]++) { int index = pre_index*2+X[i]; if((i+1)<dim) { combos(dim,i+1,X,index); }else { for(int d = 0;d<dim;d++) { BV(index,d) = (X[d]?minV[d]:maxV[d]); } } } }; Eigen::VectorXi X(dim); combos(dim,0,X.data(),0); switch(dim) { case 2: BF.resize(4,2); BF<< 3,1, 1,0, 0,2, 2,3; break; case 3: BF.resize(12,3); BF<< 2,0,6, 0,4,6, 5,4,0, 5,0,1, 6,4,5, 5,7,6, 3,0,2, 1,0,3, 3,2,6, 6,7,3, 5,1,3, 3,7,5; break; default: assert(false && "Unsupported dimension."); break; } }