faces_first.cpp 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. #include "faces_first.h"
  2. #include <vector>
  3. #include <Eigen/Dense>
  4. template <typename MatV, typename MatF, typename VecI>
  5. IGL_INLINE void igl::faces_first(
  6. const MatV & V,
  7. const MatF & F,
  8. MatV & RV,
  9. MatF & RF,
  10. VecI & IM)
  11. {
  12. assert(&V != &RV);
  13. assert(&F != &RF);
  14. using namespace std;
  15. using namespace Eigen;
  16. vector<bool> in_face(V.rows());
  17. for(int i = 0; i<F.rows(); i++)
  18. {
  19. for(int j = 0; j<F.cols(); j++)
  20. {
  21. in_face[F(i,j)] = true;
  22. }
  23. }
  24. // count number of vertices not in faces
  25. int num_in_F = 0;
  26. for(int i = 0;i<V.rows();i++)
  27. {
  28. num_in_F += (in_face[i]?1:0);
  29. }
  30. // list of unique vertices that occur in F
  31. VectorXi U(num_in_F);
  32. // list of unique vertices that do not occur in F
  33. VectorXi NU(V.rows()-num_in_F);
  34. int Ui = 0;
  35. int NUi = 0;
  36. // loop over vertices
  37. for(int i = 0;i<V.rows();i++)
  38. {
  39. if(in_face[i])
  40. {
  41. U(Ui) = i;
  42. Ui++;
  43. }else
  44. {
  45. NU(NUi) = i;
  46. NUi++;
  47. }
  48. }
  49. IM.resize(V.rows());
  50. // reindex vertices that occur in faces to be first
  51. for(int i = 0;i<U.size();i++)
  52. {
  53. IM(U(i)) = i;
  54. }
  55. // reindex vertices that do not occur in faces to come after those that do
  56. for(int i = 0;i<NU.size();i++)
  57. {
  58. IM(NU(i)) = i+U.size();
  59. }
  60. RF.resize(F.rows(),F.cols());
  61. // Reindex faces
  62. for(int i = 0; i<F.rows(); i++)
  63. {
  64. for(int j = 0; j<F.cols(); j++)
  65. {
  66. RF(i,j) = IM(F(i,j));
  67. }
  68. }
  69. RV.resize(V.rows(),V.cols());
  70. // Reorder vertices
  71. for(int i = 0;i<V.rows();i++)
  72. {
  73. RV.row(IM(i)) = V.row(i);
  74. }
  75. }
  76. template <typename MatV, typename MatF, typename VecI>
  77. IGL_INLINE void igl::faces_first(
  78. MatV & V,
  79. MatF & F,
  80. VecI & IM)
  81. {
  82. MatV RV;
  83. // Copying F may not be needed, seems RF = F is safe (whereas RV = V is not)
  84. MatF RF;
  85. igl::faces_first(V,F,RV,RF,IM);
  86. V = RV;
  87. F = RF;
  88. }
  89. #ifndef IGL_HEADER_ONLY
  90. // Explicit template specialization
  91. template void igl::faces_first<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::Matrix<double, -1, -1, 0, -1, -1>&, Eigen::Matrix<int, -1, -1, 0, -1, -1>&, Eigen::Matrix<int, -1, 1, 0, -1, 1>&);
  92. #endif