exterior_edges.cpp 3.2 KB

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