triangle_triangle_intersect_shared_edge.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. #include "triangle_triangle_intersect_shared_edge.h"
  2. #include "PI.h"
  3. #include <Eigen/Geometry>
  4. #include <type_traits>
  5. //#define IGL_TRIANGLE_TRIANGLE_INTERSECT_SHARED_EDGE_DEBUG
  6. #ifdef IGL_TRIANGLE_TRIANGLE_INTERSECT_SHARED_EDGE_DEBUG
  7. // CGAL::Epeck
  8. #include <CGAL/Exact_predicates_exact_constructions_kernel.h>
  9. #warning "🐌🐌🐌🐌🐌🐌🐌🐌 Slow debug mode for igl::triangle_triangle_intersect"
  10. #endif
  11. template <
  12. typename DerivedV,
  13. typename DerivedF,
  14. typename Derivedp>
  15. IGL_INLINE bool igl::triangle_triangle_intersect_shared_edge(
  16. const Eigen::MatrixBase<DerivedV> & V,
  17. const Eigen::MatrixBase<DerivedF> & F,
  18. const int f,
  19. const int c,
  20. const Eigen::MatrixBase<Derivedp> & p,
  21. const int g,
  22. const typename DerivedV::Scalar epsilon)
  23. {
  24. constexpr bool stinker = false;
  25. static_assert(
  26. std::is_same<typename DerivedV::Scalar,typename Derivedp::Scalar>::value,
  27. "V and p should have same Scalar type");
  28. assert(V.cols() == 3);
  29. assert(p.cols() == 3);
  30. #ifdef IGL_TRIANGLE_TRIANGLE_INTERSECT_DEBUG
  31. using Kernel = CGAL::Epeck;
  32. typedef CGAL::Point_3<Kernel> Point_3;
  33. typedef CGAL::Segment_3<Kernel> Segment_3;
  34. typedef CGAL::Triangle_3<Kernel> Triangle_3;
  35. bool cgal_found_intersection = false;
  36. Point_3 Vg[3];
  37. Point_3 Vf[3];
  38. for(int i = 0;i<3;i++)
  39. {
  40. Vg[i] = Point_3(V(F(g,i),0),V(F(g,i),1),V(F(g,i),2));
  41. if(i == c)
  42. {
  43. Vf[i] = Point_3(p(0),p(1),p(2));
  44. }else
  45. {
  46. Vf[i] = Point_3(V(F(f,i),0),V(F(f,i),1),V(F(f,i),2));
  47. }
  48. }
  49. Triangle_3 Tg(Vg[0],Vg[1],Vg[2]);
  50. Triangle_3 Tf(Vf[0],Vf[1],Vf[2]);
  51. #endif
  52. bool found_intersection = false;
  53. // Only intersects if the dihedral angle is zero (precondition: no zero
  54. // area triangles before or after collapse)
  55. // normal of g
  56. const auto vg10 = (V.row(F(g,1))-V.row(F(g,0))).template head<3>();
  57. const auto vg20 = (V.row(F(g,2))-V.row(F(g,0))).template head<3>();
  58. const auto ng = vg10.cross(vg20);
  59. // normal of f (with p replaced)
  60. const auto vf1p = (V.row(F(f,(c+1)%3))-p).template head<3>();
  61. const auto vf2p = (V.row(F(f,(c+2)%3))-p).template head<3>();
  62. const auto nf = vf1p.cross(vf2p);
  63. // normalized edge vector
  64. const auto o_vec_un = (V.row(F(f,(c+2)%3))-V.row(F(f,(c+1)%3))).template head<3>();
  65. const auto o_vec = o_vec_un.stableNormalized();
  66. const auto theta = std::abs(std::atan2(o_vec.dot(ng.cross(nf)),ng.dot(nf)));
  67. if(stinker){ printf(" theta: %g\n",theta); }
  68. // This magic number should be a parameter
  69. if(theta < igl::PI - epsilon)
  70. {
  71. return false;
  72. }
  73. // Triangles really really might intersect.
  74. found_intersection = true;
  75. // Find intersection
  76. #ifdef IGL_TRIANGLE_TRIANGLE_INTERSECT_SHARED_EDGE_DEBUG
  77. if(CGAL::do_intersect(Tg,Tf))
  78. {
  79. CGAL::Object obj = CGAL::intersection(Tg,Tf);
  80. if(const Segment_3 *iseg = CGAL::object_cast<Segment_3 >(&obj))
  81. {
  82. printf(" ❌ segment is just the edge.\n");
  83. }else if(const Point_3 *ipoint = CGAL::object_cast<Point_3 >(&obj))
  84. {
  85. printf(" 🤔 how just a single point?\n");
  86. } else if(const Triangle_3 *itri = CGAL::object_cast<Triangle_3 >(&obj))
  87. {
  88. cgal_found_intersection = true;
  89. printf(" ✅ sure it's a triangle\n");
  90. } else if(const std::vector<Point_3 > *polyp =
  91. CGAL::object_cast< std::vector<Point_3 > >(&obj))
  92. {
  93. printf(" ✅ polygon\n");
  94. }else {
  95. printf(" 🤔 da fuke?\n");
  96. }
  97. }
  98. assert(found_intersection == cgal_found_intersection);
  99. #endif
  100. return found_intersection;
  101. }
  102. #ifdef IGL_STATIC_LIBRARY
  103. // Explicit template instantiation
  104. // generated by autoexplicit.sh
  105. template bool igl::triangle_triangle_intersect_shared_edge<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1> const, 1, -1, false> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, int, int, Eigen::MatrixBase<Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1> const, 1, -1, false> > const&, int, Eigen::Matrix<double, -1, -1, 0, -1, -1>::Scalar);
  106. // generated by autoexplicit.sh
  107. template bool igl::triangle_triangle_intersect_shared_edge<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, 1, -1, 1, 1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, int, int, Eigen::MatrixBase<Eigen::Matrix<double, 1, -1, 1, 1, -1> > const&, int, Eigen::Matrix<double, -1, -1, 0, -1, -1>::Scalar);
  108. // generated by autoexplicit.sh
  109. template bool igl::triangle_triangle_intersect_shared_edge<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 1, -1, false> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, int, int, Eigen::MatrixBase<Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 1, -1, false> > const&, int, Eigen::Matrix<double, -1, -1, 0, -1, -1>::Scalar);
  110. #endif