is_intrinsic_delaunay.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  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 "tan_half_angle.h"
  11. #include "EPS.h"
  12. #include <cassert>
  13. template <
  14. typename Derivedl,
  15. typename DerivedF,
  16. typename DerivedD>
  17. IGL_INLINE void igl::is_intrinsic_delaunay(
  18. const Eigen::MatrixBase<Derivedl> & l,
  19. const Eigen::MatrixBase<DerivedF> & F,
  20. Eigen::PlainObjectBase<DerivedD> & D)
  21. {
  22. typedef Eigen::Matrix<typename DerivedF::Scalar,Eigen::Dynamic,2> MatrixX2I;
  23. typedef Eigen::Matrix<typename DerivedF::Scalar,Eigen::Dynamic,1> VectorXI;
  24. MatrixX2I E,uE;
  25. VectorXI EMAP;
  26. std::vector<std::vector<typename DerivedF::Scalar> > uE2E;
  27. igl::unique_edge_map(F, E, uE, EMAP, uE2E);
  28. const int num_faces = F.rows();
  29. D.setConstant(F.rows(),F.cols(),false);
  30. // loop over all unique edges
  31. for(int ue = 0;ue < uE2E.size(); ue++)
  32. {
  33. const bool ue_is_d = is_intrinsic_delaunay(l,F,uE2E,ue);
  34. // Set for all instances
  35. for(int e = 0;e<uE2E[ue].size();e++)
  36. {
  37. D( uE2E[ue][e]%num_faces, uE2E[ue][e]/num_faces) = ue_is_d;
  38. }
  39. }
  40. }
  41. template <
  42. typename Derivedl,
  43. typename DerivedF,
  44. typename uE2EType,
  45. typename ueiType>
  46. IGL_INLINE bool igl::is_intrinsic_delaunay(
  47. const Eigen::MatrixBase<Derivedl> & l,
  48. const Eigen::MatrixBase<DerivedF> & F,
  49. const std::vector<std::vector<uE2EType> > & uE2E,
  50. const ueiType uei)
  51. {
  52. if(uE2E[uei].size() == 1) return true;
  53. if(uE2E[uei].size() > 2) return false;
  54. typedef typename Derivedl::Scalar Scalar;
  55. typedef typename DerivedF::Scalar Index;
  56. const auto cot_alpha = [](
  57. const Scalar & a,
  58. const Scalar & b,
  59. const Scalar & c)->Scalar
  60. {
  61. // Fisher 2007
  62. const Scalar t = tan_half_angle(a,b,c);
  63. return (1.0-t*t)/(2*t);
  64. };
  65. // . //
  66. // /|\ //
  67. // a/ | \d //
  68. // / e \ //
  69. // / | \ //
  70. // .α---|-f-β. //
  71. // \ | / //
  72. // \ | / //
  73. // b\ | /c //
  74. // \|/ //
  75. // . //
  76. const Index num_faces = F.rows();
  77. assert(uE2E[uei].size() == 2 && "edge should have 2 incident faces");
  78. const Index he1 = uE2E[uei][0];
  79. const Index he2 = uE2E[uei][1];
  80. const Index f1 = he1%num_faces;
  81. const Index c1 = he1/num_faces;
  82. const Index f2 = he2%num_faces;
  83. const Index c2 = he2/num_faces;
  84. assert( std::abs(l(f1,c1)-l(f2,c2)) < igl::EPS<Scalar>());
  85. const Scalar e = l(f1,c1);
  86. const Scalar a = l(f1,(c1+1)%3);
  87. const Scalar b = l(f1,(c1+2)%3);
  88. const Scalar c = l(f2,(c2+1)%3);
  89. const Scalar d = l(f2,(c2+2)%3);
  90. const Scalar w = cot_alpha(e,a,b) + cot_alpha(e,c,d);
  91. return w >= 0;
  92. }
  93. #ifdef IGL_STATIC_LIBRARY
  94. // Explicit template instantiation
  95. // generated by autoexplicit.sh
  96. 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, 3, 0, -1, 3> >(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, 3, 0, -1, 3> >&);
  97. // generated by autoexplicit.sh
  98. template bool igl::is_intrinsic_delaunay<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, int, unsigned long>(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > const&, unsigned long);
  99. 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> >&);
  100. #endif