facet_components.cpp 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2015 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 "facet_components.h"
  9. #include <igl/triangle_triangle_adjacency.h>
  10. #include <vector>
  11. #include <queue>
  12. template <typename DerivedF, typename DerivedC>
  13. IGL_INLINE void igl::facet_components(
  14. const Eigen::PlainObjectBase<DerivedF> & F,
  15. Eigen::PlainObjectBase<DerivedC> & C)
  16. {
  17. using namespace std;
  18. typedef typename DerivedF::Index Index;
  19. vector<vector<vector<Index > > > TT;
  20. vector<vector<vector<Index > > > TTi;
  21. triangle_triangle_adjacency(F,TT,TTi);
  22. Eigen::VectorXi counts;
  23. return facet_components(TT,C,counts);
  24. }
  25. template <
  26. typename TTIndex,
  27. typename DerivedC,
  28. typename Derivedcounts>
  29. IGL_INLINE void igl::facet_components(
  30. const std::vector<std::vector<std::vector<TTIndex > > > & TT,
  31. Eigen::PlainObjectBase<DerivedC> & C,
  32. Eigen::PlainObjectBase<Derivedcounts> & counts)
  33. {
  34. using namespace std;
  35. typedef TTIndex Index;
  36. const Index m = TT.size();
  37. C.resize(m,1);
  38. vector<bool> seen(m,false);
  39. Index id = 0;
  40. vector<Index> vcounts;
  41. for(Index g = 0;g<m;g++)
  42. {
  43. if(seen[g])
  44. {
  45. continue;
  46. }
  47. vcounts.push_back(0);
  48. queue<Index> Q;
  49. Q.push(g);
  50. while(!Q.empty())
  51. {
  52. const Index f = Q.front();
  53. Q.pop();
  54. if(seen[f])
  55. {
  56. continue;
  57. }
  58. seen[f] = true;
  59. vcounts[id]++;
  60. C(f,0) = id;
  61. // Face f's neighbor lists opposite opposite each corner
  62. for(const auto & c : TT[f])
  63. {
  64. // Each neighbor
  65. for(const auto & n : c)
  66. {
  67. if(!seen[n])
  68. {
  69. Q.push(n);
  70. }
  71. }
  72. }
  73. }
  74. id++;
  75. }
  76. assert((size_t) id == vcounts.size());
  77. const size_t ncc = vcounts.size();
  78. assert((size_t)C.maxCoeff()+1 == ncc);
  79. counts.resize(ncc,1);
  80. for(size_t i = 0;i<ncc;i++)
  81. {
  82. counts(i) = vcounts[i];
  83. }
  84. }
  85. #ifdef IGL_STATIC_LIBRARY
  86. // Explicit template specialization
  87. template void igl::facet_components<long, Eigen::Matrix<long, -1, 1, 0, -1, 1>, Eigen::Matrix<long, -1, 1, 0, -1, 1> >(std::vector<std::vector<std::vector<long, std::allocator<long> >, std::allocator<std::vector<long, std::allocator<long> > > >, std::allocator<std::vector<std::vector<long, std::allocator<long> >, std::allocator<std::vector<long, std::allocator<long> > > > > > const&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&);
  88. template void igl::facet_components<int, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(std::vector<std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >, std::allocator<std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > > > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
  89. #endif