facet_components.cpp 4.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2015 Alec Jacobson <[email protected]>
  4. // Copyright (C) 2020 Alec Jacobson <[email protected]>
  5. //
  6. // This Source Code Form is subject to the terms of the Mozilla Public License
  7. // v. 2.0. If a copy of the MPL was not distributed with this file, You can
  8. // obtain one at http://mozilla.org/MPL/2.0/.
  9. #include "facet_components.h"
  10. #include "triangle_triangle_adjacency.h"
  11. #include "facet_adjacency_matrix.h"
  12. #include "connected_components.h"
  13. #include <vector>
  14. #include <queue>
  15. template <typename DerivedF, typename DerivedC>
  16. IGL_INLINE int igl::facet_components(
  17. const Eigen::MatrixBase<DerivedF> & F,
  18. Eigen::PlainObjectBase<DerivedC> & C)
  19. {
  20. typedef typename DerivedF::Scalar Index;
  21. Eigen::SparseMatrix<Index> A;
  22. igl::facet_adjacency_matrix(F,A);
  23. Eigen::Matrix<Index,Eigen::Dynamic,1> counts;
  24. C = DerivedC::Zero(1,1);
  25. return connected_components(A,C,counts);
  26. }
  27. template <
  28. typename TTIndex,
  29. typename DerivedC,
  30. typename Derivedcounts>
  31. IGL_INLINE void igl::facet_components(
  32. const std::vector<std::vector<std::vector<TTIndex > > > & TT,
  33. Eigen::PlainObjectBase<DerivedC> & C,
  34. Eigen::PlainObjectBase<Derivedcounts> & counts)
  35. {
  36. typedef TTIndex Index;
  37. const Index m = TT.size();
  38. C.resize(m,1);
  39. std::vector<bool> seen(m,false);
  40. Index id = 0;
  41. std::vector<Index> vcounts;
  42. for(Index g = 0;g<m;g++)
  43. {
  44. if(seen[g])
  45. {
  46. continue;
  47. }
  48. vcounts.push_back(0);
  49. std::queue<Index> Q;
  50. Q.push(g);
  51. while(!Q.empty())
  52. {
  53. const Index f = Q.front();
  54. Q.pop();
  55. if(seen[f])
  56. {
  57. continue;
  58. }
  59. seen[f] = true;
  60. vcounts[id]++;
  61. C(f,0) = id;
  62. // Face f's neighbor lists opposite opposite each corner
  63. for(const auto & c : TT[f])
  64. {
  65. // Each neighbor
  66. for(const auto & n : c)
  67. {
  68. if(!seen[n])
  69. {
  70. Q.push(n);
  71. }
  72. }
  73. }
  74. }
  75. id++;
  76. }
  77. assert((size_t) id == vcounts.size());
  78. const size_t ncc = vcounts.size();
  79. assert((size_t)C.maxCoeff()+1 == ncc);
  80. counts.resize(ncc,1);
  81. for(size_t i = 0;i<ncc;i++)
  82. {
  83. counts(i) = vcounts[i];
  84. }
  85. }
  86. #ifdef IGL_STATIC_LIBRARY
  87. // Explicit template instantiation
  88. 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> >&);
  89. 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> >&);
  90. template int igl::facet_components<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
  91. #ifdef WIN32
  92. template void igl::facet_components<__int64,class Eigen::Matrix<__int64,-1,1,0,-1,1>,class Eigen::Matrix<__int64,-1,1,0,-1,1> >(class std::vector<class std::vector<class std::vector<__int64,class std::allocator<__int64> >,class std::allocator<class std::vector<__int64,class std::allocator<__int64> > > >,class std::allocator<class std::vector<class std::vector<__int64,class std::allocator<__int64> >,class std::allocator<class std::vector<__int64,class std::allocator<__int64> > > > > > const &,class Eigen::PlainObjectBase<class Eigen::Matrix<__int64,-1,1,0,-1,1> > &,class Eigen::PlainObjectBase<class Eigen::Matrix<__int64,-1,1,0,-1,1> > &);
  93. #endif
  94. #endif