edges_to_path.cpp 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. #include "edges_to_path.h"
  2. #include "dfs.h"
  3. #include "sort.h"
  4. #include "slice.h"
  5. #include "ismember.h"
  6. #include "unique.h"
  7. #include "adjacency_list.h"
  8. template <
  9. typename DerivedE,
  10. typename DerivedI,
  11. typename DerivedJ,
  12. typename DerivedK>
  13. IGL_INLINE void igl::edges_to_path(
  14. const Eigen::MatrixBase<DerivedE> & OE,
  15. Eigen::PlainObjectBase<DerivedI> & I,
  16. Eigen::PlainObjectBase<DerivedJ> & J,
  17. Eigen::PlainObjectBase<DerivedK> & K)
  18. {
  19. assert(OE.rows()>=1);
  20. if(OE.rows() == 1)
  21. {
  22. I.resize(2);
  23. I(0) = OE(0);
  24. I(1) = OE(1);
  25. J.resize(1);
  26. J(0) = 0;
  27. K.resize(1);
  28. K(0) = 0;
  29. }
  30. // Compute on reduced graph
  31. DerivedI U;
  32. Eigen::VectorXi vE;
  33. {
  34. Eigen::VectorXi IA;
  35. unique(OE,U,IA,vE);
  36. }
  37. Eigen::VectorXi V = Eigen::VectorXi::Zero(vE.maxCoeff()+1);
  38. for(int e = 0;e<vE.size();e++)
  39. {
  40. V(vE(e))++;
  41. assert(V(vE(e))<=2);
  42. }
  43. // Try to find a vertex with valence = 1
  44. int c = 2;
  45. int s = vE(0);
  46. for(int v = 0;v<V.size();v++)
  47. {
  48. if(V(v) == 1)
  49. {
  50. c = V(v);
  51. s = v;
  52. break;
  53. }
  54. }
  55. assert(V(s) == c);
  56. assert(c == 2 || c == 1);
  57. // reshape E to be #E by 2
  58. DerivedE E = Eigen::Map<DerivedE>(vE.data(),OE.rows(),OE.cols()).eval();
  59. {
  60. std::vector<std::vector<int> > A;
  61. igl::adjacency_list(E,A);
  62. Eigen::VectorXi P,C;
  63. dfs(A,s,I,P,C);
  64. }
  65. if(c == 2)
  66. {
  67. I.conservativeResize(I.size()+1);
  68. I(I.size()-1) = I(0);
  69. }
  70. DerivedE sE;
  71. Eigen::Matrix<typename DerivedI::Scalar,Eigen::Dynamic,2> sEI;
  72. {
  73. Eigen::MatrixXi _;
  74. sort(E,2,true,sE,_);
  75. Eigen::Matrix<typename DerivedI::Scalar,Eigen::Dynamic,2> EI(I.size()-1,2);
  76. EI.col(0) = I.head(I.size()-1);
  77. EI.col(1) = I.tail(I.size()-1);
  78. sort(EI,2,true,sEI,_);
  79. }
  80. {
  81. Eigen::Array<bool,Eigen::Dynamic,1> F;
  82. ismember_rows(sEI,sE,F,J);
  83. }
  84. K.resize(I.size()-1);
  85. for(int k = 0;k<K.size();k++)
  86. {
  87. K(k) = (E(J(k),0) != I(k) ? 1 : 0);
  88. }
  89. // Map vertex indices onto original graph
  90. slice(U,DerivedI(I),1,I);
  91. }
  92. #ifdef IGL_STATIC_LIBRARY
  93. // Explicit template instantiation
  94. // generated by autoexplicit.sh
  95. template void igl::edges_to_path<Eigen::Matrix<int, -1, 2, 0, -1, 2>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
  96. #endif