edgetopology.cpp 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. #include "edgetopology.h"
  2. #include <algorithm>
  3. #include "is_manifold.h"
  4. IGL_INLINE void igl::edgetopology(
  5. const Eigen::MatrixXd& V,
  6. const Eigen::MatrixXi& F,
  7. Eigen::MatrixXi& EV,
  8. Eigen::MatrixXi& FE,
  9. Eigen::MatrixXi& EF)
  10. {
  11. // Only needs to be edge-manifold
  12. assert(igl::is_manifold(V,F));
  13. std::vector<std::vector<int> > ETT;
  14. for(int f=0;f<F.rows();++f)
  15. for (int i=0;i<3;++i)
  16. {
  17. // v1 v2 f vi
  18. int v1 = F(f,i);
  19. int v2 = F(f,(i+1)%3);
  20. if (v1 > v2) std::swap(v1,v2);
  21. std::vector<int> r(4);
  22. r[0] = v1; r[1] = v2;
  23. r[2] = f; r[3] = i;
  24. ETT.push_back(r);
  25. }
  26. std::sort(ETT.begin(),ETT.end());
  27. // count the number of edges (assume manifoldness)
  28. int En = 1; // the last is always counted
  29. for(unsigned i=0;i<ETT.size()-1;++i)
  30. if (!((ETT[i][0] == ETT[i+1][0]) && (ETT[i][1] == ETT[i+1][1])))
  31. ++En;
  32. EV = Eigen::MatrixXi::Constant((int)(En),2,-1);
  33. FE = Eigen::MatrixXi::Constant((int)(F.rows()),3,-1);
  34. EF = Eigen::MatrixXi::Constant((int)(En),2,-1);
  35. En = 0;
  36. for(unsigned i=0;i<ETT.size();++i)
  37. {
  38. if (i == ETT.size()-1 ||
  39. !((ETT[i][0] == ETT[i+1][0]) && (ETT[i][1] == ETT[i+1][1]))
  40. )
  41. {
  42. // Border edge
  43. std::vector<int>& r1 = ETT[i];
  44. EV(En,0) = r1[0];
  45. EV(En,1) = r1[1];
  46. EF(En,0) = r1[2];
  47. FE(r1[2],r1[3]) = En;
  48. }
  49. else
  50. {
  51. std::vector<int>& r1 = ETT[i];
  52. std::vector<int>& r2 = ETT[i+1];
  53. EV(En,0) = r1[0];
  54. EV(En,1) = r1[1];
  55. EF(En,0) = r1[2];
  56. EF(En,1) = r2[2];
  57. FE(r1[2],r1[3]) = En;
  58. FE(r2[2],r2[3]) = En;
  59. ++i; // skip the next one
  60. }
  61. ++En;
  62. }
  63. // Sort the relation EF, accordingly to EV
  64. // the first one is the face on the left of the edge
  65. for(unsigned i=0; i<EF.rows(); ++i)
  66. {
  67. int fid = EF(i,0);
  68. bool flip = true;
  69. // search for edge EV.row(i)
  70. for (unsigned j=0; j<3; ++j)
  71. {
  72. if ((F(fid,j) == EV(i,0)) && (F(fid,(j+1)%3) == EV(i,1)))
  73. flip = false;
  74. }
  75. if (flip)
  76. {
  77. int tmp = EF(i,0);
  78. EF(i,0) = EF(i,1);
  79. EF(i,1) = tmp;
  80. }
  81. }
  82. }
  83. #ifndef IGL_HEADER_ONLY
  84. // Explicit template specialization
  85. #endif