pos.h 3.1 KB

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