faces_first.cpp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2013 Alec Jacobson <[email protected]>
  4. //
  5. // This Source Code Form is subject to the terms of the Mozilla Public License
  6. // v. 2.0. If a copy of the MPL was not distributed with this file, You can
  7. // obtain one at http://mozilla.org/MPL/2.0/.
  8. #include "faces_first.h"
  9. #include <vector>
  10. #include <Eigen/Dense>
  11. template <typename MatV, typename MatF, typename VecI>
  12. IGL_INLINE void igl::faces_first(
  13. const MatV & V,
  14. const MatF & F,
  15. MatV & RV,
  16. MatF & RF,
  17. VecI & IM)
  18. {
  19. assert(&V != &RV);
  20. assert(&F != &RF);
  21. std::vector<bool> in_face(V.rows());
  22. for(int i = 0; i<F.rows(); i++)
  23. {
  24. for(int j = 0; j<F.cols(); j++)
  25. {
  26. in_face[F(i,j)] = true;
  27. }
  28. }
  29. // count number of vertices not in faces
  30. int num_in_F = 0;
  31. for(int i = 0;i<V.rows();i++)
  32. {
  33. num_in_F += (in_face[i]?1:0);
  34. }
  35. // list of unique vertices that occur in F
  36. Eigen::VectorXi U(num_in_F);
  37. // list of unique vertices that do not occur in F
  38. Eigen::VectorXi NU(V.rows()-num_in_F);
  39. int Ui = 0;
  40. int NUi = 0;
  41. // loop over vertices
  42. for(int i = 0;i<V.rows();i++)
  43. {
  44. if(in_face[i])
  45. {
  46. U(Ui) = i;
  47. Ui++;
  48. }else
  49. {
  50. NU(NUi) = i;
  51. NUi++;
  52. }
  53. }
  54. IM.resize(V.rows());
  55. // reindex vertices that occur in faces to be first
  56. for(int i = 0;i<U.size();i++)
  57. {
  58. IM(U(i)) = i;
  59. }
  60. // reindex vertices that do not occur in faces to come after those that do
  61. for(int i = 0;i<NU.size();i++)
  62. {
  63. IM(NU(i)) = i+U.size();
  64. }
  65. RF.resizeLike(F);
  66. // Reindex faces
  67. for(int i = 0; i<F.rows(); i++)
  68. {
  69. for(int j = 0; j<F.cols(); j++)
  70. {
  71. RF(i,j) = IM(F(i,j));
  72. }
  73. }
  74. RV.resizeLike(V);
  75. // Reorder vertices
  76. for(int i = 0;i<V.rows();i++)
  77. {
  78. RV.row(IM(i)) = V.row(i);
  79. }
  80. }
  81. template <typename MatV, typename MatF, typename VecI>
  82. IGL_INLINE void igl::faces_first(
  83. MatV & V,
  84. MatF & F,
  85. VecI & IM)
  86. {
  87. MatV RV;
  88. // Copying F may not be needed, seems RF = F is safe (whereas RV = V is not)
  89. MatF RF;
  90. igl::faces_first(V,F,RV,RF,IM);
  91. V = RV;
  92. F = RF;
  93. }
  94. #ifdef IGL_STATIC_LIBRARY
  95. // Explicit template instantiation
  96. 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>&);
  97. #endif