exterior_edges.cpp 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. #include "exterior_edges.h"
  2. #include "all_edges.h"
  3. #include "sort.h"
  4. #include "unique.h"
  5. #include <cassert>
  6. #include <unordered_map>
  7. #include <utility>
  8. #include <iostream>
  9. //template <typename T> inline int sgn(T val) {
  10. // return (T(0) < val) - (val < T(0));
  11. //}
  12. //static void mod2(std::pair<const std::pair<const int, const int>, int>& p)
  13. //{
  14. // using namespace std;
  15. // // Be sure that sign of mod matches sign of argument
  16. // p.second = p.second%2 ? sgn(p.second) : 0;
  17. //}
  18. //// http://stackoverflow.com/a/5517869/148668
  19. //struct Compare
  20. //{
  21. // int i;
  22. // Compare(const int& i) : i(i) {}
  23. //};
  24. //bool operator==(const std::pair<std::pair<const int, const int>,int>&p, const Compare& c)
  25. //{
  26. // return c.i == p.second;
  27. //}
  28. //bool operator==(const Compare& c, const std::pair<std::pair<const int, const int>, int> &p)
  29. //{
  30. // return c.i == p.second;
  31. //}
  32. IGL_INLINE void igl::exterior_edges(
  33. const Eigen::MatrixXi & F,
  34. Eigen::MatrixXi & E)
  35. {
  36. using namespace Eigen;
  37. using namespace std;
  38. assert(F.cols() == 3);
  39. const size_t m = F.rows();
  40. MatrixXi all_E,sall_E,sort_order;
  41. // Sort each edge by index
  42. all_edges(F,all_E);
  43. sort(all_E,2,true,sall_E,sort_order);
  44. // Find unique edges
  45. MatrixXi uE;
  46. VectorXi IA,EMAP;
  47. unique_rows(sall_E,uE,IA,EMAP);
  48. VectorXi counts = VectorXi::Zero(uE.rows());
  49. for(size_t a = 0;a<3*m;a++)
  50. {
  51. counts(EMAP(a)) += (sort_order(a)==0?1:-1);
  52. }
  53. E.resize(all_E.rows(),2);
  54. {
  55. int e = 0;
  56. const size_t nue = uE.rows();
  57. // Append each unique edge with a non-zero amount of signed occurances
  58. for(size_t ue = 0; ue<nue; ue++)
  59. {
  60. const int count = counts(ue);
  61. size_t i,j;
  62. if(count == 0)
  63. {
  64. continue;
  65. }else if(count < 0)
  66. {
  67. i = uE(ue,1);
  68. j = uE(ue,0);
  69. }else if(count > 0)
  70. {
  71. i = uE(ue,0);
  72. j = uE(ue,1);
  73. }
  74. // Append edge for every repeated entry
  75. const int abs_count = abs(count);
  76. for(size_t k = 0;k<abs_count;k++)
  77. {
  78. E(e,0) = i;
  79. E(e,1) = j;
  80. e++;
  81. }
  82. }
  83. E.conservativeResize(e,2);
  84. }
  85. }
  86. IGL_INLINE Eigen::MatrixXi igl::exterior_edges( const Eigen::MatrixXi & F)
  87. {
  88. using namespace Eigen;
  89. MatrixXi E;
  90. exterior_edges(F,E);
  91. return E;
  92. }