exterior_edges.cpp 2.6 KB

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