1 // This file is part of libigl, a simple c++ geometry processing library.
2 //
3 // Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public License
6 // v. 2.0. If a copy of the MPL was not distributed with this file, You can
7 // obtain one at http://mozilla.org/MPL/2.0/.
8 #include "on_boundary.h"
9
10 // IGL includes
11 #include "sort.h"
12 #include "face_occurrences.h"
13
14 // STL includes
15
16 template <typename IntegerT>
on_boundary(const std::vector<std::vector<IntegerT>> & T,std::vector<bool> & I,std::vector<std::vector<bool>> & C)17 IGL_INLINE void igl::on_boundary(
18 const std::vector<std::vector<IntegerT> > & T,
19 std::vector<bool> & I,
20 std::vector<std::vector<bool> > & C)
21 {
22 using namespace std;
23 if(T.empty())
24 {
25 I.clear();
26 C.clear();
27 return;
28 }
29
30 switch(T[0].size())
31 {
32 case 3:
33 {
34 // Get a list of all faces
35 vector<vector<IntegerT> > F(T.size()*3,vector<IntegerT>(2));
36 // Gather faces, loop over tets
37 for(int i = 0; i< (int)T.size();i++)
38 {
39 assert(T[i].size() == 3);
40 // get face in correct order
41 F[i*3+0][0] = T[i][1];
42 F[i*3+0][1] = T[i][2];
43 F[i*3+1][0] = T[i][2];
44 F[i*3+1][1] = T[i][0];
45 F[i*3+2][0] = T[i][0];
46 F[i*3+2][1] = T[i][1];
47 }
48 // Counts
49 vector<int> FC;
50 face_occurrences(F,FC);
51 C.resize(T.size(),vector<bool>(3));
52 I.resize(T.size(),false);
53 for(int i = 0; i< (int)T.size();i++)
54 {
55 for(int j = 0;j<3;j++)
56 {
57 assert(FC[i*3+j] == 2 || FC[i*3+j] == 1);
58 C[i][j] = FC[i*3+j]==1;
59 // if any are on boundary set to true
60 I[i] = I[i] || C[i][j];
61 }
62 }
63 return;
64 }
65 case 4:
66 {
67 // Get a list of all faces
68 vector<vector<IntegerT> > F(T.size()*4,vector<IntegerT>(3));
69 // Gather faces, loop over tets
70 for(int i = 0; i< (int)T.size();i++)
71 {
72 assert(T[i].size() == 4);
73 // get face in correct order
74 F[i*4+0][0] = T[i][1];
75 F[i*4+0][1] = T[i][3];
76 F[i*4+0][2] = T[i][2];
77 // get face in correct order
78 F[i*4+1][0] = T[i][0];
79 F[i*4+1][1] = T[i][2];
80 F[i*4+1][2] = T[i][3];
81 // get face in correct order
82 F[i*4+2][0] = T[i][0];
83 F[i*4+2][1] = T[i][3];
84 F[i*4+2][2] = T[i][1];
85 // get face in correct order
86 F[i*4+3][0] = T[i][0];
87 F[i*4+3][1] = T[i][1];
88 F[i*4+3][2] = T[i][2];
89 }
90 // Counts
91 vector<int> FC;
92 face_occurrences(F,FC);
93 C.resize(T.size(),vector<bool>(4));
94 I.resize(T.size(),false);
95 for(int i = 0; i< (int)T.size();i++)
96 {
97 for(int j = 0;j<4;j++)
98 {
99 assert(FC[i*4+j] == 2 || FC[i*4+j] == 1);
100 C[i][j] = FC[i*4+j]==1;
101 // if any are on boundary set to true
102 I[i] = I[i] || C[i][j];
103 }
104 }
105 return;
106 }
107 }
108
109
110 }
111
112 #include "list_to_matrix.h"
113 #include "matrix_to_list.h"
114
115 template <typename DerivedT, typename DerivedI, typename DerivedC>
on_boundary(const Eigen::MatrixBase<DerivedT> & T,Eigen::PlainObjectBase<DerivedI> & I,Eigen::PlainObjectBase<DerivedC> & C)116 IGL_INLINE void igl::on_boundary(
117 const Eigen::MatrixBase<DerivedT>& T,
118 Eigen::PlainObjectBase<DerivedI>& I,
119 Eigen::PlainObjectBase<DerivedC>& C)
120 {
121 assert(T.cols() == 0 || T.cols() == 4 || T.cols() == 3);
122 using namespace std;
123 using namespace Eigen;
124 // Cop out: use vector of vectors version
125 vector<vector<typename DerivedT::Scalar> > vT;
126 matrix_to_list(T,vT);
127 vector<bool> vI;
128 vector<vector<bool> > vC;
129 on_boundary(vT,vI,vC);
130 list_to_matrix(vI,I);
131 list_to_matrix(vC,C);
132 }
133
134
135 #ifdef IGL_STATIC_LIBRARY
136 // Explicit template instantiation
137 // generated by autoexplicit.sh
138 template void igl::on_boundary<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Array<bool, -1, 1, 0, -1, 1>, Eigen::Array<bool, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Array<bool, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Array<bool, -1, 3, 0, -1, 3> >&);
139 template void igl::on_boundary<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
140 template void igl::on_boundary<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Array<bool, -1, 1, 0, -1, 1>, Eigen::Array<bool, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Array<bool, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Array<bool, -1, -1, 0, -1, -1> >&);
141 #endif
142