edges_to_path.cpp 1.9 KB

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