connected_components.cpp 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2020 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 "connected_components.h"
  9. #include <queue>
  10. template < typename Atype, typename DerivedC, typename DerivedK>
  11. IGL_INLINE int igl::connected_components(
  12. const Eigen::SparseMatrix<Atype> & A,
  13. Eigen::PlainObjectBase<DerivedC> & C,
  14. Eigen::PlainObjectBase<DerivedK> & K)
  15. {
  16. typedef typename Eigen::SparseMatrix<Atype>::Index Index;
  17. const auto m = A.rows();
  18. assert(A.cols() == A.rows() && "A should be square");
  19. // 1.1 sec
  20. // m means not yet visited
  21. C.setConstant(m,1,m);
  22. // Could use amortized dynamic array but didn't see real win.
  23. K.setZero(m,1);
  24. typename DerivedC::Scalar c = 0;
  25. for(Eigen::Index f = 0;f<m;f++)
  26. {
  27. // already seen
  28. if(C(f)<m) continue;
  29. // start bfs
  30. std::queue<Index> Q;
  31. Q.push(f);
  32. while(!Q.empty())
  33. {
  34. const Index g = Q.front();
  35. Q.pop();
  36. // already seen
  37. if(C(g)<m) continue;
  38. // see it
  39. C(g) = c;
  40. K(c)++;
  41. for(typename Eigen::SparseMatrix<Atype>::InnerIterator it (A,g); it; ++it)
  42. {
  43. const Index n = it.index();
  44. // already seen
  45. if(C(n)<m) continue;
  46. Q.push(n);
  47. }
  48. }
  49. c++;
  50. }
  51. K.conservativeResize(c,1);
  52. return c;
  53. }
  54. #ifdef IGL_STATIC_LIBRARY
  55. // Explicit template instantiation
  56. // generated by autoexplicit.sh
  57. template int igl::connected_components<bool, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::SparseMatrix<bool, 0, int> const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
  58. // generated by autoexplicit.sh
  59. template int igl::connected_components<int, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::SparseMatrix<int, 0, int> const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
  60. #endif