edges_to_path.cpp 2.9 KB

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