// This file is part of libigl, a simple c++ geometry processing library. // // Copyright (C) 2014 Daniele Panozzo // // 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 "lscm.h" // Bug in unsupported/Eigen/SparseExtra needs iostream first #include #include #include #include #include #include #include IGL_INLINE Eigen::MatrixXd igl::lscm( const Eigen::MatrixXd& V, const Eigen::MatrixXi& F, const Eigen::VectorXi& b, const Eigen::MatrixXd& bc) { using namespace Eigen; // Assemble the area matrix (note that A is #Vx2 by #Vx2) SparseMatrix A; igl::areamatrix(V,F,A); // Assemble the cotan laplacian matrix SparseMatrix L; igl::cotmatrix(V,F,L); SparseMatrix I2(2,2); I2.insert(0,0) = 1; I2.insert(1,1) = 1; SparseMatrix L_flat = igl::kronecker_product(I2,L); VectorXi b_flat = b; MatrixXd bc_flat = bc; if (b.size() < 2) { // if no boundary conditions are provided, fix two boundary points Eigen::VectorXi bnd; igl::boundary_vertices_sorted(V,F,bnd); int v1 = bnd(0); int v2 = bnd(round(bnd.size()/2)); b_flat.resize(4); b_flat << v1, v1+1, v2, v2+1; bc_flat.resize(4,1); bc_flat << 0, 1, 0, 0; } // Minimize the LSCM energy SparseMatrix Q = -0.5*L_flat + A; const VectorXd B_flat = VectorXd::Zero(V.rows()*2); igl::min_quad_with_fixed_data data; igl::min_quad_with_fixed_precompute(Q,b_flat,SparseMatrix(),true,data); MatrixXd W_flat; if(!min_quad_with_fixed_solve(data,B_flat,bc_flat,VectorXd(),W_flat)) assert(false); MatrixXd V_uv(V.rows(),2); for (unsigned i=0;i