faces_first.cpp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
  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. using namespace std;
  22. using namespace Eigen;
  23. vector<bool> in_face(V.rows());
  24. for(int i = 0; i<F.rows(); i++)
  25. {
  26. for(int j = 0; j<F.cols(); j++)
  27. {
  28. in_face[F(i,j)] = true;
  29. }
  30. }
  31. // count number of vertices not in faces
  32. int num_in_F = 0;
  33. for(int i = 0;i<V.rows();i++)
  34. {
  35. num_in_F += (in_face[i]?1:0);
  36. }
  37. // list of unique vertices that occur in F
  38. VectorXi U(num_in_F);
  39. // list of unique vertices that do not occur in F
  40. VectorXi NU(V.rows()-num_in_F);
  41. int Ui = 0;
  42. int NUi = 0;
  43. // loop over vertices
  44. for(int i = 0;i<V.rows();i++)
  45. {
  46. if(in_face[i])
  47. {
  48. U(Ui) = i;
  49. Ui++;
  50. }else
  51. {
  52. NU(NUi) = i;
  53. NUi++;
  54. }
  55. }
  56. IM.resize(V.rows());
  57. // reindex vertices that occur in faces to be first
  58. for(int i = 0;i<U.size();i++)
  59. {
  60. IM(U(i)) = i;
  61. }
  62. // reindex vertices that do not occur in faces to come after those that do
  63. for(int i = 0;i<NU.size();i++)
  64. {
  65. IM(NU(i)) = i+U.size();
  66. }
  67. RF.resizeLike(F);
  68. // Reindex faces
  69. for(int i = 0; i<F.rows(); i++)
  70. {
  71. for(int j = 0; j<F.cols(); j++)
  72. {
  73. RF(i,j) = IM(F(i,j));
  74. }
  75. }
  76. RV.resizeLike(V);
  77. // Reorder vertices
  78. for(int i = 0;i<V.rows();i++)
  79. {
  80. RV.row(IM(i)) = V.row(i);
  81. }
  82. }
  83. template <typename MatV, typename MatF, typename VecI>
  84. IGL_INLINE void igl::faces_first(
  85. MatV & V,
  86. MatF & F,
  87. VecI & IM)
  88. {
  89. MatV RV;
  90. // Copying F may not be needed, seems RF = F is safe (whereas RV = V is not)
  91. MatF RF;
  92. igl::faces_first(V,F,RV,RF,IM);
  93. V = RV;
  94. F = RF;
  95. }
  96. #ifdef IGL_STATIC_LIBRARY
  97. // Explicit template instantiation
  98. 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>&);
  99. #endif