|
@@ -8,7 +8,8 @@
|
|
|
#include "triangle_triangle_adjacency.h"
|
|
|
#include "is_edge_manifold.h"
|
|
|
#include "all_edges.h"
|
|
|
-#include <map>
|
|
|
+#include "unique_simplices.h"
|
|
|
+#include "unique_edge_map.h"
|
|
|
#include <algorithm>
|
|
|
|
|
|
template <typename Scalar, typename Index>
|
|
@@ -107,59 +108,105 @@ template <
|
|
|
const Eigen::PlainObjectBase<DerivedF> & F,
|
|
|
std::vector<std::vector<std::vector<TTIndex> > > & TT,
|
|
|
std::vector<std::vector<std::vector<TTiIndex> > > & TTi)
|
|
|
+{
|
|
|
+ return triangle_triangle_adjacency(F,true,TT,TTi);
|
|
|
+}
|
|
|
+
|
|
|
+template <
|
|
|
+ typename DerivedF,
|
|
|
+ typename TTIndex>
|
|
|
+ IGL_INLINE void igl::triangle_triangle_adjacency(
|
|
|
+ const Eigen::PlainObjectBase<DerivedF> & F,
|
|
|
+ std::vector<std::vector<std::vector<TTIndex> > > & TT)
|
|
|
+{
|
|
|
+ std::vector<std::vector<std::vector<TTIndex> > > not_used;
|
|
|
+ return triangle_triangle_adjacency(F,false,TT,not_used);
|
|
|
+}
|
|
|
+
|
|
|
+template <
|
|
|
+ typename DerivedF,
|
|
|
+ typename TTIndex,
|
|
|
+ typename TTiIndex>
|
|
|
+ IGL_INLINE void igl::triangle_triangle_adjacency(
|
|
|
+ const Eigen::PlainObjectBase<DerivedF> & F,
|
|
|
+ const bool construct_TTi,
|
|
|
+ std::vector<std::vector<std::vector<TTIndex> > > & TT,
|
|
|
+ std::vector<std::vector<std::vector<TTiIndex> > > & TTi)
|
|
|
{
|
|
|
using namespace Eigen;
|
|
|
using namespace std;
|
|
|
- using namespace igl;
|
|
|
assert(F.cols() == 3 && "Faces must be triangles");
|
|
|
- typedef typename DerivedF::Index Index;
|
|
|
// number of faces
|
|
|
const int m = F.rows();
|
|
|
- // All occurances of directed edges
|
|
|
- MatrixXi E;
|
|
|
- all_edges(F,E);
|
|
|
- assert(E.rows() == 3*m);
|
|
|
- // uE2E[i] --> {j,k,...} means unique edge i corresponds to face edges j and
|
|
|
- // k (where j-edge comes is the j/m edge of face j%m)
|
|
|
- map<pair<Index,Index>,vector<Index> > uE2E;
|
|
|
- for(int e = 0;e<E.rows();e++)
|
|
|
- {
|
|
|
- Index i = E(e,0);
|
|
|
- Index j = E(e,1);
|
|
|
- if(i<j)
|
|
|
- {
|
|
|
- uE2E[pair<Index,Index>(i,j)].push_back(e);
|
|
|
- }else
|
|
|
- {
|
|
|
- uE2E[pair<Index,Index>(j,i)].push_back(e);
|
|
|
- }
|
|
|
- }
|
|
|
+ typedef typename DerivedF::Index Index;
|
|
|
+ typedef Matrix<typename DerivedF::Scalar,Dynamic,2> MatrixX2I;
|
|
|
+ typedef Matrix<typename DerivedF::Index,Dynamic,1> VectorXI;
|
|
|
+ MatrixX2I E,uE;
|
|
|
+ VectorXI EMAP;
|
|
|
+ vector<vector<Index> > uE2E;
|
|
|
+ unique_edge_map(F,E,uE,EMAP,uE2E);
|
|
|
+ return triangle_triangle_adjacency(E,EMAP,uE2E,construct_TTi,TT,TTi);
|
|
|
+}
|
|
|
+
|
|
|
+template <
|
|
|
+ typename DerivedE,
|
|
|
+ typename DerivedEMAP,
|
|
|
+ typename uE2EType,
|
|
|
+ typename TTIndex,
|
|
|
+ typename TTiIndex>
|
|
|
+ IGL_INLINE void igl::triangle_triangle_adjacency(
|
|
|
+ const Eigen::PlainObjectBase<DerivedE> & E,
|
|
|
+ const Eigen::PlainObjectBase<DerivedEMAP> & EMAP,
|
|
|
+ const std::vector<std::vector<uE2EType> > & uE2E,
|
|
|
+ const bool construct_TTi,
|
|
|
+ std::vector<std::vector<std::vector<TTIndex> > > & TT,
|
|
|
+ std::vector<std::vector<std::vector<TTiIndex> > > & TTi)
|
|
|
+{
|
|
|
+ using namespace std;
|
|
|
+ using namespace Eigen;
|
|
|
+ typedef typename DerivedE::Index Index;
|
|
|
+ const size_t m = E.rows()/3;
|
|
|
+ assert(E.rows() == m*3 && "E should come from list of triangles.");
|
|
|
// E2E[i] --> {j,k,...} means face edge i corresponds to other faces edges j
|
|
|
// and k
|
|
|
- TT.resize (m,vector<vector<TTIndex> >(F.cols()));
|
|
|
- TTi.resize(m,vector<vector<TTiIndex> >(F.cols()));
|
|
|
- for(int e = 0;e<E.rows();e++)
|
|
|
+ TT.resize (m,vector<vector<TTIndex> >(3));
|
|
|
+ if(construct_TTi)
|
|
|
+ {
|
|
|
+ TTi.resize(m,vector<vector<TTiIndex> >(3));
|
|
|
+ }
|
|
|
+
|
|
|
+ // No race conditions because TT*[f][c]'s are in bijection with e's
|
|
|
+ // Minimum number of iterms per openmp thread
|
|
|
+ const size_t ne = E.rows();
|
|
|
+# ifndef IGL_OMP_MIN_VALUE
|
|
|
+# define IGL_OMP_MIN_VALUE 1000
|
|
|
+# endif
|
|
|
+# pragma omp parallel for if (ne>IGL_OMP_MIN_VALUE)
|
|
|
+ // Slightly better memory access than loop over E
|
|
|
+ for(Index f = 0;f<m;f++)
|
|
|
{
|
|
|
- const Index i = E(e,0);
|
|
|
- const Index j = E(e,1);
|
|
|
- const Index f = e%m;
|
|
|
- const Index c = e/m;
|
|
|
- const vector<Index> & N =
|
|
|
- i<j ? uE2E[pair<Index,Index>(i,j)] : uE2E[pair<Index,Index>(j,i)];
|
|
|
- for(const auto & ne : N)
|
|
|
+ for(Index c = 0;c<3;c++)
|
|
|
{
|
|
|
- const Index nf = ne%m;
|
|
|
- const Index nc = ne/m;
|
|
|
- TT[f][c].push_back(nf);
|
|
|
- TTi[f][c].push_back(nc);
|
|
|
+ const Index e = f + m*c;
|
|
|
+ const Index i = E(e,0);
|
|
|
+ const Index j = E(e,1);
|
|
|
+ //const Index f = e%m;
|
|
|
+ //const Index c = e/m;
|
|
|
+ const vector<Index> & N = uE2E[EMAP(e)];
|
|
|
+ for(const auto & ne : N)
|
|
|
+ {
|
|
|
+ const Index nf = ne%m;
|
|
|
+ TT[f][c].push_back(nf);
|
|
|
+ if(construct_TTi)
|
|
|
+ {
|
|
|
+ const Index nc = ne/m;
|
|
|
+ TTi[f][c].push_back(nc);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
#ifdef IGL_STATIC_LIBRARY
|
|
|
// Explicit template specialization
|
|
|
-template void igl::triangle_triangle_adjacency<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
|
|
|
-// generated by autoexplicit.sh
|
|
|
-template void igl::triangle_triangle_adjacency<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> >&);
|
|
|
-template void igl::triangle_triangle_adjacency<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<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> >&);
|
|
|
#endif
|