|
@@ -16,33 +16,57 @@ IGL_INLINE void igl::boundary_faces(
|
|
using namespace std;
|
|
using namespace std;
|
|
using namespace igl;
|
|
using namespace igl;
|
|
|
|
|
|
|
|
+ if(T.size() == 0)
|
|
|
|
+ {
|
|
|
|
+ F.clear();
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ int simplex_size = T[0].size();
|
|
// Get a list of all faces
|
|
// Get a list of all faces
|
|
- vector<vector<IntegerF> > allF(T.size()*4,vector<IntegerF>(3));
|
|
|
|
|
|
+ vector<vector<IntegerF> > allF(
|
|
|
|
+ T.size()*simplex_size,
|
|
|
|
+ vector<IntegerF>(simplex_size-1));
|
|
|
|
+
|
|
// Gather faces, loop over tets
|
|
// Gather faces, loop over tets
|
|
for(int i = 0; i< (int)T.size();i++)
|
|
for(int i = 0; i< (int)T.size();i++)
|
|
{
|
|
{
|
|
- assert(T[i].size() == 4);
|
|
|
|
- // get face in correct order
|
|
|
|
- allF[i*4+0][0] = T[i][1];
|
|
|
|
- allF[i*4+0][1] = T[i][3];
|
|
|
|
- allF[i*4+0][2] = T[i][2];
|
|
|
|
- // get face in correct order
|
|
|
|
- allF[i*4+1][0] = T[i][0];
|
|
|
|
- allF[i*4+1][1] = T[i][2];
|
|
|
|
- allF[i*4+1][2] = T[i][3];
|
|
|
|
- // get face in correct order
|
|
|
|
- allF[i*4+2][0] = T[i][0];
|
|
|
|
- allF[i*4+2][1] = T[i][3];
|
|
|
|
- allF[i*4+2][2] = T[i][1];
|
|
|
|
- // get face in correct order
|
|
|
|
- allF[i*4+3][0] = T[i][0];
|
|
|
|
- allF[i*4+3][1] = T[i][1];
|
|
|
|
- allF[i*4+3][2] = T[i][2];
|
|
|
|
|
|
+ assert(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][0];
|
|
|
|
+ allF[i*simplex_size+0][1] = T[i][1];
|
|
|
|
+ allF[i*simplex_size+1][0] = T[i][1];
|
|
|
|
+ allF[i*simplex_size+1][1] = T[i][2];
|
|
|
|
+ allF[i*simplex_size+2][0] = T[i][2];
|
|
|
|
+ allF[i*simplex_size+2][1] = T[i][0];
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
// Counts
|
|
// Counts
|
|
vector<int> C;
|
|
vector<int> C;
|
|
face_occurences(allF,C);
|
|
face_occurences(allF,C);
|
|
|
|
|
|
|
|
+ // Q: Why not just count the number of ones?
|
|
int twos = (int) count(C.begin(),C.end(),2);
|
|
int twos = (int) count(C.begin(),C.end(),2);
|
|
// Resize output to fit number of ones
|
|
// Resize output to fit number of ones
|
|
F.resize(allF.size() - twos);
|
|
F.resize(allF.size() - twos);
|
|
@@ -68,7 +92,7 @@ IGL_INLINE void igl::boundary_faces(
|
|
const Eigen::PlainObjectBase<DerivedT>& T,
|
|
const Eigen::PlainObjectBase<DerivedT>& T,
|
|
Eigen::PlainObjectBase<DerivedF>& F)
|
|
Eigen::PlainObjectBase<DerivedF>& F)
|
|
{
|
|
{
|
|
- assert(T.cols() == 0 || T.cols() == 4);
|
|
|
|
|
|
+ assert(T.cols() == 0 || T.cols() == 4 || T.cols() == 3);
|
|
using namespace std;
|
|
using namespace std;
|
|
using namespace Eigen;
|
|
using namespace Eigen;
|
|
using namespace igl;
|
|
using namespace igl;
|
|
@@ -79,6 +103,15 @@ IGL_INLINE void igl::boundary_faces(
|
|
boundary_faces(vT,vF);
|
|
boundary_faces(vT,vF);
|
|
list_to_matrix(vF,F);
|
|
list_to_matrix(vF,F);
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+template <typename DerivedT, typename DerivedF>
|
|
|
|
+IGL_INLINE Eigen::PlainObjectBase<DerivedF> igl::boundary_faces(
|
|
|
|
+ const Eigen::PlainObjectBase<DerivedT>& T)
|
|
|
|
+{
|
|
|
|
+ Eigen::Matrix<typename DerivedF::Scalar, Eigen::Dynamic, Eigen::Dynamic> F;
|
|
|
|
+ igl::boundary_faces(T,F);
|
|
|
|
+ return F;
|
|
|
|
+}
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
|
|
@@ -86,5 +119,6 @@ IGL_INLINE void igl::boundary_faces(
|
|
// Explicit template specialization
|
|
// Explicit template specialization
|
|
template void igl::boundary_faces<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
|
|
template void igl::boundary_faces<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
|
|
template void igl::boundary_faces<int, int>(std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > const&, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >&);
|
|
template void igl::boundary_faces<int, int>(std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > const&, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >&);
|
|
|
|
+template Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > igl::boundary_faces(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&);
|
|
#endif
|
|
#endif
|
|
|
|
|