is_intrinsic_delaunay.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2018 Alec Jacobson <alecjacobson@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. #include "is_intrinsic_delaunay.h"
  9. #include "unique_edge_map.h"
  10. #include <cassert>
  11. template <
  12. typename Derivedl,
  13. typename DerivedF,
  14. typename DerivedD>
  15. IGL_INLINE void igl::is_intrinsic_delaunay(
  16. const Eigen::MatrixBase<Derivedl> & l,
  17. const Eigen::MatrixBase<DerivedF> & F,
  18. Eigen::PlainObjectBase<DerivedD> & D)
  19. {
  20. typedef Eigen::Matrix<typename DerivedF::Scalar,Eigen::Dynamic,2> MatrixX2I;
  21. typedef Eigen::Matrix<typename DerivedF::Scalar,Eigen::Dynamic,1> VectorXI;
  22. MatrixX2I E,uE;
  23. VectorXI EMAP;
  24. std::vector<std::vector<typename DerivedF::Scalar> > uE2E;
  25. igl::unique_edge_map(F, E, uE, EMAP, uE2E);
  26. const int num_faces = F.rows();
  27. D.setConstant(F.rows(),F.cols(),false);
  28. // loop over all unique edges
  29. for(int ue = 0;ue < uE2E.size(); ue++)
  30. {
  31. const bool ue_is_d = is_intrinsic_delaunay(l,F,uE2E,ue);
  32. // Set for all instances
  33. for(int e = 0;e<uE2E[ue].size();e++)
  34. {
  35. D( uE2E[ue][e]%num_faces, uE2E[ue][e]/num_faces) = ue_is_d;
  36. }
  37. }
  38. }
  39. template <
  40. typename Derivedl,
  41. typename DerivedF,
  42. typename uE2EType,
  43. typename ueiType>
  44. IGL_INLINE bool igl::is_intrinsic_delaunay(
  45. const Eigen::MatrixBase<Derivedl> & l,
  46. const Eigen::MatrixBase<DerivedF> & F,
  47. const std::vector<std::vector<uE2EType> > & uE2E,
  48. const ueiType uei)
  49. {
  50. if(uE2E[uei].size() == 1) return true;
  51. if(uE2E[uei].size() > 2) return false;
  52. typedef typename Derivedl::Scalar Scalar;
  53. typedef typename DerivedF::Scalar Index;
  54. // .
  55. // /|
  56. // c/ |
  57. // / |
  58. // / |
  59. // .α | a
  60. // \ |
  61. // \ |
  62. // b\ |
  63. // \|
  64. //
  65. // tan(α/2)
  66. const auto tan_alpha_over_2 = [](
  67. const Scalar & a,
  68. const Scalar & b,
  69. const Scalar & c)->Scalar
  70. {
  71. // Fisher 2007
  72. return sqrt(((a-b+c)*(a+b-c))/((a+b+c)*(-a+b+c)));
  73. };
  74. const auto cot_alpha = [&tan_alpha_over_2](
  75. const Scalar & a,
  76. const Scalar & b,
  77. const Scalar & c)->Scalar
  78. {
  79. // Fisher 2007
  80. const Scalar t = tan_alpha_over_2(a,b,c);
  81. return (1.0-t*t)/(2*t);
  82. };
  83. // . //
  84. // /|\ //
  85. // a/ | \d //
  86. // / e \ //
  87. // / | \ //
  88. // .α---|-f-β. //
  89. // \ | / //
  90. // \ | / //
  91. // b\ | /c //
  92. // \|/ //
  93. // . //
  94. const Index num_faces = F.rows();
  95. assert(uE2E[uei].size() == 2 && "edge should have 2 incident faces");
  96. const Index he_left = uE2E[uei][0];
  97. const Index he_right = uE2E[uei][1];
  98. const Index f_left = he_left%num_faces;
  99. const Index c_left = he_left/num_faces;
  100. const Index f_right = he_right%num_faces;
  101. const Index c_right = he_right/num_faces;
  102. assert( std::abs(l(f_left,c_left)-l(f_right,c_right) < igl::EPS<Scalar>()) );
  103. const Scalar e = l(f_left,c_left);
  104. const Scalar a = l(f_left,(c_left+1)%3);
  105. const Scalar b = l(f_left,(c_left+2)%3);
  106. const Scalar c = l(f_right,(c_right+1)%3);
  107. const Scalar d = l(f_right,(c_right+2)%3);
  108. const Scalar w = cot_alpha(e,a,b) + cot_alpha(e,c,d);
  109. return w >= 0;
  110. }
  111. #ifdef IGL_STATIC_LIBRARY
  112. // Explicit template instantiation
  113. // generated by autoexplicit.sh
  114. template void igl::is_intrinsic_delaunay<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<bool, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<bool, -1, -1, 0, -1, -1> >&);
  115. #endif