HalfEdgeIterator.h 3.3 KB

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