/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2004-2016 \/)\/ * * Visual Computing Lab /\/| * * ISTI - Italian National Research Council | * * \ * * All rights reserved. * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * * for more details. * * * ****************************************************************************/ #ifndef MESH_TO_MATRIX #define MESH_TO_MATRIX #include #include #include #include using namespace std; namespace vcg { namespace tri { template < typename MeshType > class MeshToMatrix { // define types typedef typename MeshType::FaceType FaceType; typedef typename MeshType::FaceIterator FaceIterator; typedef typename MeshType::VertexType VertexType; typedef typename MeshType::VertexIterator VertexIterator; typedef typename MeshType::CoordType CoordType; typedef typename MeshType::ScalarType ScalarType; typedef typename Eigen::Matrix MatrixXm; static void GetTriEdgeAdjacency(const MatrixXm& V, const Eigen::MatrixXi& F, Eigen::MatrixXi& EV, Eigen::MatrixXi& FE, Eigen::MatrixXi& EF) { (void)V; //assert(igl::is_manifold(V,F)); std::vector > ETT; for(int f=0;f v2) std::swap(v1,v2); std::vector r(4); r[0] = v1; r[1] = v2; r[2] = f; r[3] = i; ETT.push_back(r); } std::sort(ETT.begin(),ETT.end()); // count the number of edges (assume manifoldness) int En = 1; // the last is always counted for(unsigned i=0;i& r1 = ETT[i]; EV(En,0) = r1[0]; EV(En,1) = r1[1]; EF(En,0) = r1[2]; FE(r1[2],r1[3]) = En; } else { std::vector& r1 = ETT[i]; std::vector& r2 = ETT[i+1]; EV(En,0) = r1[0]; EV(En,1) = r1[1]; EF(En,0) = r1[2]; EF(En,1) = r2[2]; FE(r1[2],r1[3]) = En; FE(r2[2],r2[3]) = En; ++i; // skip the next one } ++En; } // Sort the relation EF, accordingly to EV // the first one is the face on the left of the edge for(unsigned i=0; i::FaceFace(mesh); FFp = Eigen::MatrixXi(mesh.FN(),3); FFi = Eigen::MatrixXi(mesh.FN(),3); for (int i = 0; i < mesh.FN(); i++) for (int j = 0; j < 3; j++) { FaceType *AdjF=mesh.face[i].FFp(j); if (AdjF==&mesh.face[i]) { FFp(i,j)=-1; FFi(i,j)=-1; } else { FFp(i,j)=tri::Index(mesh,AdjF); FFi(i,j)=mesh.face[i].FFi(j); } } } static void GetUVData(const MeshType &mesh, MatrixXm & uv) { tri::RequireVertexCompactness(mesh); tri::RequirePerVertexTexCoord(mesh); uv = MatrixXm(mesh.VN(), 2); // per vertices uv for (int i = 0; i < mesh.VN(); i++) { uv(i,0) = mesh.vert[i].cT().U(); uv(i,1) = mesh.vert[i].cT().V(); } } // get edge to face and edge to vertex adjacency static void GetTriEdgeAdjacency(const MeshType &mesh, Eigen::MatrixXi& EV, Eigen::MatrixXi& FE, Eigen::MatrixXi& EF) { Eigen::MatrixXi faces; MatrixXm vert; GetTriMeshData(mesh,faces,vert); GetTriEdgeAdjacency(vert,faces,EV,FE,EF); } static Eigen::Vector3d VectorFromCoord(CoordType v) { Eigen::Vector3d ret(v[0],v[1],v[2]); return ret; } template< class VecType > static void PerVertexArea(MeshType &m, VecType &h) { tri::RequireCompactness(m); h.resize(m.vn); for(int i=0;iVN();++j) h[tri::Index(m,fi->V(j))] += a; } } template< class VecType > static void PerFaceArea(MeshType &m, VecType &h) { tri::RequireCompactness(m); h.resize(m.fn); for(int i=0;i > &index, std::vector &entry, bool vertexCoord=true) { tri::RequireCompactness(m); typename MeshType::template PerVertexAttributeHandle h = tri::Allocator:: template GetPerVertexAttribute(m, "area"); for(int i=0;iVN();++j) h[tri::Index(m,fi->V(j))] += a; } ScalarType maxA=0; for(int i=0;i(currI,currI)); entry.push_back(h[i]/maxA); } } else { int currI=i; index.push_back(std::pair(currI,currI)); entry.push_back(h[i]/maxA); } } tri::Allocator::template DeletePerVertexAttribute(m,h); } static void GetLaplacianEntry(MeshType &mesh, FaceType &f, std::vector > &index, std::vector &entry, bool cotangent, ScalarType weight = 1, bool vertexCoord=true) { if (cotangent) vcg::tri::MeshAssert::OnlyTriFace(mesh); for (int i=0;i::template CotangentWeight(f,i); } //get the index of the vertices int indexV0=Index(mesh,f.V0(i)); int indexV1=Index(mesh,f.V1(i)); if (vertexCoord) { //then assemble the matrix for (int j=0;j<3;j++) { //multiply by 3 and add the component int currI0=(indexV0*3)+j; int currI1=(indexV1*3)+j; index.push_back(std::pair(currI0,currI0)); entry.push_back(weight); index.push_back(std::pair(currI0,currI1)); entry.push_back(-weight); index.push_back(std::pair(currI1,currI1)); entry.push_back(weight); index.push_back(std::pair(currI1,currI0)); entry.push_back(-weight); } } else { int currI0=(indexV0); int currI1=(indexV1); index.push_back(std::pair(currI0,currI0)); entry.push_back(weight); index.push_back(std::pair(currI0,currI1)); entry.push_back(-weight); index.push_back(std::pair(currI1,currI1)); entry.push_back(weight); index.push_back(std::pair(currI1,currI0)); entry.push_back(-weight); } } } static void GetLaplacianMatrix(MeshType &mesh, std::vector > &index, std::vector &entry, bool cotangent, ScalarType weight = 1, bool vertexCoord=true ) { //store the index and the scalar for the sparse matrix for (size_t i=0;i