// This file is part of libigl, a simple c++ geometry processing library. // // Copyright (C) 2017 Amir Vaxman // // This Source Code Form is subject to the terms of the Mozilla Public License // v. 2.0. If a copy of the MPL was not distributed with this file, You can // obtain one at http://mozilla.org/MPL/2.0/. #include #include #include #include #include #include #include #include namespace igl { //This projection does nothing but render points into projP. Mostly used for "echoing" the global step IGL_INLINE bool shapeup_identity_projection(const Eigen::PlainObjectBase& P, const Eigen::PlainObjectBase& SC, const Eigen::PlainObjectBase& S, Eigen::PlainObjectBase& projP){ projP.conservativeResize(SC.rows(), 3*SC.maxCoeff()); for (int i=0;i& P, const Eigen::PlainObjectBase& SC, const Eigen::PlainObjectBase& S, Eigen::PlainObjectBase& projP){ projP.conservativeResize(SC.rows(), 3*SC.maxCoeff()); for (int currRow=0;currRow svd(corrMat, Eigen::ComputeFullU | Eigen::ComputeFullV); Eigen::MatrixXd R=svd.matrixU()*svd.matrixV().transpose(); //getting scale by edge length change average. TODO: by singular values Eigen::VectorXd sourceEdgeLengths(N); Eigen::VectorXd targetEdgeLengths(N); for (int j=0;j IGL_INLINE bool shapeup_precomputation(const Eigen::PlainObjectBase& P, const Eigen::PlainObjectBase& SC, const Eigen::PlainObjectBase& S, const Eigen::PlainObjectBase& E, const Eigen::PlainObjectBase& b, const Eigen::PlainObjectBase& wShape, const Eigen::PlainObjectBase& wSmooth, ShapeupData & sudata) { using namespace std; using namespace Eigen; sudata.P=P; sudata.SC=SC; sudata.S=S; sudata.b=b; typedef typename DerivedP::Scalar Scalar; //checking for consistency of the input assert(SC.rows()==S.rows()); assert(SC.rows()==wShape.rows()); assert(E.rows()==wSmooth.rows()); assert(b.rows()!=0); //would lead to matrix becoming SPD sudata.DShape.conservativeResize(SC.sum(), P.rows()); //Shape matrix (integration); sudata.DClose.conservativeResize(b.rows(), P.rows()); //Closeness matrix for positional constraints sudata.DSmooth.conservativeResize(E.rows(), P.rows()); //smoothness matrix //Building shape matrix std::vector > DShapeTriplets; int currRow=0; for (int i=0;i(currRow+j, S(i,k), (1.0-avgCoeff))); else DShapeTriplets.push_back(Triplet(currRow+j, S(i,k), (-avgCoeff))); } } currRow+=SC(i); } sudata.DShape.setFromTriplets(DShapeTriplets.begin(), DShapeTriplets.end()); //Building closeness matrix std::vector > DCloseTriplets; for (int i=0;i(i,b(i), 1.0)); sudata.DClose.setFromTriplets(DCloseTriplets.begin(), DCloseTriplets.end()); //Building smoothness matrix std::vector > DSmoothTriplets; for (int i=0; i(i, E(i, 0), -1)); DSmoothTriplets.push_back(Triplet(i, E(i, 1), 1)); } SparseMatrix tempMat; igl::cat(1, sudata.DShape, sudata.DClose, tempMat); igl::cat(1, tempMat, sudata.DSmooth, sudata.A); //weight matrix vector > WTriplets; //one weight per set in S. currRow=0; for (int i=0;i(currRow+j,currRow+j,sudata.shapeCoeff*wShape(i))); currRow+=SC(i); } for (int i=0;i(SC.sum()+i, SC.sum()+i, sudata.closeCoeff)); for (int i=0;i(SC.sum()+b.size()+i, SC.sum()+b.size()+i, sudata.smoothCoeff*wSmooth(i))); sudata.W.conservativeResize(SC.sum()+b.size()+E.rows(), SC.sum()+b.size()+E.rows()); sudata.W.setFromTriplets(WTriplets.begin(), WTriplets.end()); sudata.At=sudata.A.transpose(); //for efficieny, as we use the transpose a lot in the iteration sudata.Q=sudata.At*sudata.W*sudata.A; return min_quad_with_fixed_precompute(sudata.Q,VectorXi(),SparseMatrix(),true,sudata.solver_data); } template < typename DerivedP, typename DerivedSC, typename DerivedS> IGL_INLINE bool shapeup_solve(const Eigen::PlainObjectBase& bc, const std::function&, const Eigen::PlainObjectBase&, const Eigen::PlainObjectBase&, Eigen::PlainObjectBase&)>& local_projection, const Eigen::PlainObjectBase& P0, const ShapeupData & sudata, const bool quietIterations, Eigen::PlainObjectBase& P) { using namespace Eigen; using namespace std; MatrixXd currP=P0; MatrixXd prevP=P0; MatrixXd projP; assert(bc.rows()==sudata.b.rows()); MatrixXd rhs(sudata.A.rows(), 3); rhs.setZero(); rhs.block(sudata.DShape.rows(), 0, sudata.b.rows(),3)=bc; //this stays constant throughout the iterations if (!quietIterations){ cout<<"Shapeup Iterations, "<(); if (!quietIterations) cout << "Iteration "<, typename Eigen::Matrix, typename Eigen::Matrix, typename Eigen::Matrix >(Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, igl::ShapeupData&); template bool igl::shapeup_solve, typename Eigen::Matrix, typename Eigen::Matrix >(const Eigen::PlainObjectBase >& bc, const std::function >&, const Eigen::PlainObjectBase >&, const Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >& ) >& local_projection, const Eigen::PlainObjectBase >& P0, const igl::ShapeupData & sudata, const bool quietIterations, Eigen::PlainObjectBase >& P); #endif