// This file is part of libigl, a simple c++ geometry processing library. // // Copyright (C) 2013 Alec Jacobson // // 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 "mvc.h" #include #include #include // Broken Implementation IGL_INLINE void igl::mvc(const Eigen::MatrixXd &V, const Eigen::MatrixXd &C, Eigen::MatrixXd &W) { // at least three control points assert(C.rows()>2); // dimension of points assert(C.cols() == 3 || C.cols() == 2); assert(V.cols() == 3 || V.cols() == 2); // number of polygon points int num = C.rows(); Eigen::MatrixXd V1,C1; int i_prev, i_next; // check if either are 3D but really all z's are 0 bool V_flat = (V.cols() == 3) && (std::sqrt( (V.col(3)).dot(V.col(3)) ) < 1e-10); bool C_flat = (C.cols() == 3) && (std::sqrt( (C.col(3)).dot(C.col(3)) ) < 1e-10); // if both are essentially 2D then ignore z-coords if((C.cols() == 2 || C_flat) && (V.cols() == 2 || V_flat)) { // ignore z coordinate V1 = V.block(0,0,V.rows(),2); C1 = C.block(0,0,C.rows(),2); } else { // give dummy z coordinate to either mesh or poly if(V.rows() == 2) { V1 = Eigen::MatrixXd(V.rows(),3); V1.block(0,0,V.rows(),2) = V; } else V1 = V; if(C.rows() == 2) { C1 = Eigen::MatrixXd(C.rows(),3); C1.block(0,0,C.rows(),2) = C; } else C1 = C; // check that C is planar // average normal around poly corners Eigen::Vector3d n = Eigen::Vector3d::Zero(); // take centroid as point on plane Eigen::Vector3d p = Eigen::Vector3d::Zero(); for (int i = 0; i0)?(i-1):(num-1); i_next = (i1e-10) std::cerr<<"Distance from V to plane of C is large..."< solver = basis.colPivHouseholderQr(); // Throw away coordinates in normal direction V1 = solver.solve(V1.transpose()).transpose().block(0,0,V1.rows(),2); C1 = solver.solve(C1.transpose()).transpose().block(0,0,C1.rows(),2); } // vectors from V to every C, where CmV(i,j,:) is the vector from domain // vertex j to handle i double EPS = 1e-10; Eigen::MatrixXd WW = Eigen::MatrixXd(C1.rows(), V1.rows()); Eigen::MatrixXd dist_C_V (C1.rows(), V1.rows()); std::vector< std::pair > on_corner(0); std::vector< std::pair > on_segment(0); for (int i = 0; i0)?(i-1):(num-1); i_next = (i