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