// 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 "on_boundary.h" // IGL includes #include "sort.h" #include "face_occurrences.h" // STL includes template IGL_INLINE void igl::on_boundary( const std::vector > & T, std::vector & I, std::vector > & C) { using namespace std; if(T.empty()) { I.clear(); C.clear(); return; } switch(T[0].size()) { case 3: { // Get a list of all faces vector > F(T.size()*3,vector(2)); // Gather faces, loop over tets for(int i = 0; i< (int)T.size();i++) { assert(T[i].size() == 3); // get face in correct order F[i*3+0][0] = T[i][1]; F[i*3+0][1] = T[i][2]; F[i*3+1][0] = T[i][2]; F[i*3+1][1] = T[i][0]; F[i*3+2][0] = T[i][0]; F[i*3+2][1] = T[i][1]; } // Counts vector FC; face_occurrences(F,FC); C.resize(T.size(),vector(3)); I.resize(T.size(),false); for(int i = 0; i< (int)T.size();i++) { for(int j = 0;j<3;j++) { assert(FC[i*3+j] == 2 || FC[i*3+j] == 1); C[i][j] = FC[i*3+j]==1; // if any are on boundary set to true I[i] = I[i] || C[i][j]; } } return; } case 4: { // Get a list of all faces vector > F(T.size()*4,vector(3)); // Gather faces, loop over tets for(int i = 0; i< (int)T.size();i++) { assert(T[i].size() == 4); // get face in correct order F[i*4+0][0] = T[i][1]; F[i*4+0][1] = T[i][3]; F[i*4+0][2] = T[i][2]; // get face in correct order F[i*4+1][0] = T[i][0]; F[i*4+1][1] = T[i][2]; F[i*4+1][2] = T[i][3]; // get face in correct order F[i*4+2][0] = T[i][0]; F[i*4+2][1] = T[i][3]; F[i*4+2][2] = T[i][1]; // get face in correct order F[i*4+3][0] = T[i][0]; F[i*4+3][1] = T[i][1]; F[i*4+3][2] = T[i][2]; } // Counts vector FC; face_occurrences(F,FC); C.resize(T.size(),vector(4)); I.resize(T.size(),false); for(int i = 0; i< (int)T.size();i++) { for(int j = 0;j<4;j++) { assert(FC[i*4+j] == 2 || FC[i*4+j] == 1); C[i][j] = FC[i*4+j]==1; // if any are on boundary set to true I[i] = I[i] || C[i][j]; } } return; } } } #include "list_to_matrix.h" #include "matrix_to_list.h" template IGL_INLINE void igl::on_boundary( const Eigen::MatrixBase& T, Eigen::PlainObjectBase& I, Eigen::PlainObjectBase& C) { 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 vI; vector > vC; on_boundary(vT,vI,vC); list_to_matrix(vI,I); list_to_matrix(vC,C); } #ifdef IGL_STATIC_LIBRARY // Explicit template instantiation // generated by autoexplicit.sh template void igl::on_boundary, Eigen::Array, Eigen::Array >(Eigen::MatrixBase > const&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); template void igl::on_boundary, Eigen::Matrix, Eigen::Matrix >(Eigen::MatrixBase > const&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); template void igl::on_boundary, Eigen::Array, Eigen::Array >(Eigen::MatrixBase > const&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); #endif