// 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 "boundary_facets.h" #include "face_occurrences.h" // IGL includes #include "sort.h" // STL includes #include #include template IGL_INLINE void igl::boundary_facets( const std::vector > & T, std::vector > & F) { using namespace std; if(T.size() == 0) { F.clear(); return; } int simplex_size = T[0].size(); // Get a list of all faces vector > allF( T.size()*simplex_size, vector(simplex_size-1)); // Gather faces, loop over tets for(int i = 0; i< (int)T.size();i++) { assert((int)T[i].size() == simplex_size); switch(simplex_size) { case 4: // get face in correct order allF[i*simplex_size+0][0] = T[i][1]; allF[i*simplex_size+0][1] = T[i][3]; allF[i*simplex_size+0][2] = T[i][2]; // get face in correct order allF[i*simplex_size+1][0] = T[i][0]; allF[i*simplex_size+1][1] = T[i][2]; allF[i*simplex_size+1][2] = T[i][3]; // get face in correct order allF[i*simplex_size+2][0] = T[i][0]; allF[i*simplex_size+2][1] = T[i][3]; allF[i*simplex_size+2][2] = T[i][1]; // get face in correct order allF[i*simplex_size+3][0] = T[i][0]; allF[i*simplex_size+3][1] = T[i][1]; allF[i*simplex_size+3][2] = T[i][2]; break; case 3: allF[i*simplex_size+0][0] = T[i][1]; allF[i*simplex_size+0][1] = T[i][2]; allF[i*simplex_size+1][0] = T[i][2]; allF[i*simplex_size+1][1] = T[i][0]; allF[i*simplex_size+2][0] = T[i][0]; allF[i*simplex_size+2][1] = T[i][1]; break; } } // Counts vector C; face_occurrences(allF,C); // Q: Why not just count the number of ones? // A: because we are including non-manifold edges as boundary edges int twos = (int) count(C.begin(),C.end(),2); //int ones = (int) count(C.begin(),C.end(),1); // Resize output to fit number of ones F.resize(allF.size() - twos); //F.resize(ones); int k = 0; for(int i = 0;i< (int)allF.size();i++) { if(C[i] != 2) { assert(k<(int)F.size()); F[k] = allF[i]; k++; } } assert(k==(int)F.size()); //if(k != F.size()) //{ // printf("%d =? %d\n",k,F.size()); //} } #include "list_to_matrix.h" #include "matrix_to_list.h" template IGL_INLINE void igl::boundary_facets( const Eigen::PlainObjectBase& T, Eigen::PlainObjectBase& F) { assert(T.cols() == 0 || T.cols() == 4 || T.cols() == 3); using namespace std; using namespace Eigen; // Cop out: use vector of vectors version vector > vT; matrix_to_list(T,vT); vector > vF; boundary_facets(vT,vF); list_to_matrix(vF,F); } template Ret igl::boundary_facets( const Eigen::PlainObjectBase& T) { Ret F; igl::boundary_facets(T,F); return F; } #ifdef IGL_STATIC_LIBRARY // Explicit template instantiation // generated by autoexplicit.sh template void igl::boundary_facets, Eigen::Matrix >(Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase >&); // generated by autoexplicit.sh template void igl::boundary_facets, Eigen::Matrix >(Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase >&); template void igl::boundary_facets, Eigen::Matrix >(Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase >&); template void igl::boundary_facets(std::vector >, std::allocator > > > const&, std::vector >, std::allocator > > >&); //template Eigen::PlainObjectBase > igl::boundary_facets(Eigen::PlainObjectBase > const&); template Eigen::Matrix igl::boundary_facets, Eigen::Matrix >(Eigen::PlainObjectBase > const&); template void igl::boundary_facets, Eigen::Matrix >(Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase >&); #endif