HalfEdgeIterator.h 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2014 Daniele Panozzo <daniele.panozzo@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. #ifndef IGL_HALFEDGEITERATOR_H
  9. #define IGL_HALFEDGEITERATOR_H
  10. #include <Eigen/Core>
  11. #include <vector>
  12. #include <igl/igl_inline.h>
  13. namespace igl
  14. {
  15. // HalfEdgeIterator - Fake halfedge for fast and easy navigation on triangle meshes with vertex_triangle_adjacency and
  16. // triangle_triangle adjacency
  17. template <typename DerivedF>
  18. class HalfEdgeIterator
  19. {
  20. public:
  21. // Init the HalfEdgeIterator by specifying Face,Edge Index and Orientation
  22. IGL_INLINE HalfEdgeIterator(
  23. const Eigen::PlainObjectBase<DerivedF>& _F,
  24. const Eigen::PlainObjectBase<DerivedF>& _FF,
  25. const Eigen::PlainObjectBase<DerivedF>& _FFi,
  26. int _fi,
  27. int _ei,
  28. bool _reverse = false
  29. )
  30. : fi(_fi), ei(_ei), reverse(_reverse), F(_F), FF(_FF), FFi(_FFi)
  31. {}
  32. // Change Face
  33. IGL_INLINE void flipF()
  34. {
  35. if (isBorder())
  36. return;
  37. int fin = (FF)(fi,ei);
  38. int ein = (FFi)(fi,ei);
  39. int reversen = !reverse;
  40. fi = fin;
  41. ei = ein;
  42. reverse = reversen;
  43. }
  44. // Change Edge
  45. IGL_INLINE void flipE()
  46. {
  47. if (!reverse)
  48. ei = (ei+2)%3; // ei-1
  49. else
  50. ei = (ei+1)%3;
  51. reverse = !reverse;
  52. }
  53. // Change Vertex
  54. IGL_INLINE void flipV()
  55. {
  56. reverse = !reverse;
  57. }
  58. IGL_INLINE bool isBorder()
  59. {
  60. return (FF)(fi,ei) == -1;
  61. }
  62. /*!
  63. * Returns the next edge skipping the border
  64. * _________
  65. * /\ c | b /\
  66. * / \ | / \
  67. * / d \ | / a \
  68. * /______\|/______\
  69. * v
  70. * In this example, if a and d are of-border and the pos is iterating counterclockwise, this method iterate through the faces incident on vertex v,
  71. * producing the sequence a, b, c, d, a, b, c, ...
  72. */
  73. IGL_INLINE bool NextFE()
  74. {
  75. if ( isBorder() ) // we are on a border
  76. {
  77. do
  78. {
  79. flipF();
  80. flipE();
  81. } while (!isBorder());
  82. flipE();
  83. return false;
  84. }
  85. else
  86. {
  87. flipF();
  88. flipE();
  89. return true;
  90. }
  91. }
  92. // Get vertex index
  93. IGL_INLINE int Vi()
  94. {
  95. assert(fi >= 0);
  96. assert(fi < F.rows());
  97. assert(ei >= 0);
  98. assert(ei <= 2);
  99. if (!reverse)
  100. return (*F)(fi,ei);
  101. else
  102. return (*F)(fi,(ei+1)%3);
  103. }
  104. // Get face index
  105. IGL_INLINE int Fi()
  106. {
  107. return fi;
  108. }
  109. // Get edge index
  110. IGL_INLINE int Ei()
  111. {
  112. return ei;
  113. }
  114. IGL_INLINE bool operator==(HalfEdgeIterator& p2)
  115. {
  116. return
  117. (
  118. (fi == p2.fi) &&
  119. (ei == p2.ei) &&
  120. (reverse == p2.reverse) &&
  121. (F == p2.F) &&
  122. (FF == p2.FF) &&
  123. (FFi == p2.FFi)
  124. );
  125. }
  126. private:
  127. int fi;
  128. int ei;
  129. bool reverse;
  130. const Eigen::PlainObjectBase<DerivedF>& F;
  131. const Eigen::PlainObjectBase<DerivedF>& FF;
  132. const Eigen::PlainObjectBase<DerivedF>& FFi;
  133. };
  134. }
  135. #endif