// 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/. #ifndef IGL_SHAPEUP_H #define IGL_SHAPEUP_H #include "shapeup.h" #include #include #include #include #include //This file implements the following algorithm: //Boaziz et al. //Shape-Up: Shaping Discrete Geometry with Projections //Computer Graphics Forum (Proc. SGP) 31(5), 2012 namespace igl { //This function does the precomputation of the necessary operators for the shape-up projection process. IGL_INLINE void shapeup_precomputation(const Eigen::MatrixXd& V, const Eigen::VectorXi& D, const Eigen::MatrixXi& F, const Eigen::VectorXi& SD, const Eigen::MatrixXi& S, const Eigen::VectorXi& h, const Eigen::VectorXd& w, const double shapeCoeff, const double closeCoeff, struct ShapeupData& sudata) { using namespace Eigen; //The integration solve is separable to x,y,z components sudata.V=V; sudata.F=F; sudata.D=D; sudata.SD=SD; sudata.S=S; sudata.h=h; sudata.closeCoeff=closeCoeff; sudata.shapeCoeff=shapeCoeff; sudata.Q.conservativeResize(SD.sum(), V.rows()); //Shape matrix (integration); sudata.C.conservativeResize(h.rows(), V.rows()); //Closeness matrix for handles std::vector > QTriplets; int currRow=0; for (int i=0;i(currRow+j, S(i,k), (1.0-avgCoeff))); else QTriplets.push_back(Triplet(currRow+j, S(i,k), (-avgCoeff))); } } currRow+=SD(i); } sudata.Q.setFromTriplets(QTriplets.begin(), QTriplets.end()); std::vector > CTriplets; for (int i=0;i(i,h(i), 1.0)); sudata.C.setFromTriplets(CTriplets.begin(), CTriplets.end()); igl::cat(1, sudata.Q, sudata.C, sudata.A); sudata.At=sudata.A.transpose(); //to save up this expensive computation. //weight matrix vector > WTriplets; //std::cout<<"w: "<(currRow+j,currRow+j,shapeCoeff*w(i))); currRow+=SD(i); } for (int i=0;i(SD.sum()+i, SD.sum()+i, closeCoeff)); sudata.W.resize(SD.sum()+h.size(), SD.sum()+h.size()); sudata.W.setFromTriplets(WTriplets.begin(), WTriplets.end()); sudata.E=sudata.At*sudata.W*sudata.A; sudata.solver.compute(sudata.E); } IGL_INLINE void shapeup_compute(void (*projection)(int , const hedra::ShapeupData&, const Eigen::MatrixXd& , Eigen::MatrixXd&), const Eigen::MatrixXd& vh, const struct ShapeupData& sudata, Eigen::MatrixXd& currV, const int maxIterations=50, const double vTolerance=10e-6) { using namespace Eigen; MatrixXd prevV=currV; MatrixXd PV; MatrixXd b(sudata.A.rows(),3); b.block(sudata.Q.rows(), 0, sudata.h.rows(),3)=vh; //this stays constant throughout the iterations //std::cout<<"vh: "<(); //std::cout<<"Iteration: "<