faces_first.h 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. #ifndef IGL_FACES_FIRST_H
  2. #define IGL_FACES_FIRST_H
  3. namespace igl
  4. {
  5. // FACES_FIRST Reorder vertices so that vertices in face list come before
  6. // vertices that don't appear in the face list. This is especially useful if
  7. // the face list contains only surface faces and you want surface vertices
  8. // listed before internal vertices
  9. //
  10. // [RV,RT,RF,IM] = faces_first(V,T,F);
  11. //
  12. // Templates:
  13. // MatV matrix for vertex positions, e.g. MatrixXd
  14. // MatF matrix for vertex positions, e.g. MatrixXi
  15. // VecI matrix for vertex positions, e.g. VectorXi
  16. // Input:
  17. // V # vertices by 3 vertex positions
  18. // F # faces by 3 list of face indices
  19. // Output:
  20. // RV # vertices by 3 vertex positions, order such that if the jth vertex is
  21. // some face in F, and the kth vertex is not then j comes before k
  22. // RF # faces by 3 list of face indices, reindexed to use RV
  23. // IM # faces by 1 list of indices such that: RF = IM(F) and RT = IM(T)
  24. // and RV(IM,:) = V
  25. //
  26. template <typename MatV, typename MatF, typename VecI>
  27. void faces_first(
  28. const MatV & V,
  29. const MatF & F,
  30. MatV & RV,
  31. MatF & RF,
  32. VecI & IM);
  33. }
  34. // Implementation
  35. #include <vector>
  36. #include <Eigen/Dense>
  37. template <typename MatV, typename MatF, typename VecI>
  38. void igl::faces_first(
  39. const MatV & V,
  40. const MatF & F,
  41. MatV & RV,
  42. MatF & RF,
  43. VecI & IM)
  44. {
  45. using namespace std;
  46. using namespace Eigen;
  47. vector<bool> in_face(V.rows());
  48. for(int i = 0; i<F.rows(); i++)
  49. {
  50. for(int j = 0; j<F.cols(); j++)
  51. {
  52. in_face[F(i,j)] = true;
  53. }
  54. }
  55. // count number of vertices not in faces
  56. int num_in_F = 0;
  57. for(int i = 0;i<V.rows();i++)
  58. {
  59. num_in_F += (in_face[i]?1:0);
  60. }
  61. // list of unique vertices that occur in F
  62. VectorXi U(num_in_F);
  63. // list of unique vertices that do not occur in F
  64. VectorXi NU(V.rows()-num_in_F);
  65. int Ui = 0;
  66. int NUi = 0;
  67. // loop over vertices
  68. for(int i = 0;i<V.rows();i++)
  69. {
  70. if(in_face[i])
  71. {
  72. U(Ui) = i;
  73. Ui++;
  74. }else
  75. {
  76. NU(NUi) = i;
  77. NUi++;
  78. }
  79. }
  80. IM.resize(V.rows());
  81. // reindex vertices that occur in faces to be first
  82. for(int i = 0;i<U.size();i++)
  83. {
  84. IM(U(i)) = i;
  85. }
  86. // reindex vertices that do not occur in faces to come after those that do
  87. for(int i = 0;i<NU.size();i++)
  88. {
  89. IM(NU(i)) = i+U.size();
  90. }
  91. RF.resize(F.rows(),F.cols());
  92. // Reindex faces
  93. for(int i = 0; i<F.rows(); i++)
  94. {
  95. for(int j = 0; j<F.cols(); j++)
  96. {
  97. RF(i,j) = IM(F(i,j));
  98. }
  99. }
  100. RV.resize(V.rows(),V.cols());
  101. // Reorder vertices
  102. for(int i = 0;i<V.rows();i++)
  103. {
  104. RV.row(IM(i)) = V.row(i);
  105. }
  106. }
  107. #endif