triangle_triangle_intersect.cpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. #include "triangle_triangle_intersect.h"
  2. #include "triangle_triangle_intersect_shared_edge.h"
  3. #include "triangle_triangle_intersect_shared_vertex.h"
  4. #include "tri_tri_intersect.h"
  5. #include <Eigen/Geometry>
  6. #include <stdio.h>
  7. //#define IGL_TRIANGLE_TRIANGLE_INTERSECT_DEBUG
  8. #ifdef IGL_TRIANGLE_TRIANGLE_INTERSECT_DEBUG
  9. // CGAL::Epeck
  10. #include <CGAL/Exact_predicates_exact_constructions_kernel.h>
  11. #warning "🐌🐌🐌🐌🐌🐌🐌🐌 Slow debug mode for igl::triangle_triangle_intersect"
  12. #endif
  13. template <
  14. typename DerivedV,
  15. typename DerivedF,
  16. typename DerivedE,
  17. typename DerivedEMAP,
  18. typename DerivedEF,
  19. typename Derivedp>
  20. IGL_INLINE bool igl::triangle_triangle_intersect(
  21. const Eigen::MatrixBase<DerivedV> & V,
  22. const Eigen::MatrixBase<DerivedF> & F,
  23. const Eigen::MatrixBase<DerivedE> & E,
  24. const Eigen::MatrixBase<DerivedEMAP> & EMAP,
  25. const Eigen::MatrixBase<DerivedEF> & EF,
  26. const int f,
  27. const int c,
  28. const Eigen::MatrixBase<Derivedp> & p,
  29. const int g)
  30. {
  31. static_assert(
  32. std::is_same<typename DerivedV::Scalar,typename Derivedp::Scalar>::value,
  33. "V and p should have same Scalar type");
  34. assert(V.cols() == 3);
  35. assert(p.cols() == 3);
  36. #ifdef IGL_TRIANGLE_TRIANGLE_INTERSECT_DEBUG
  37. using Kernel = CGAL::Epeck;
  38. typedef CGAL::Point_3<Kernel> Point_3;
  39. typedef CGAL::Segment_3<Kernel> Segment_3;
  40. typedef CGAL::Triangle_3<Kernel> Triangle_3;
  41. bool cgal_found_intersection = false;
  42. Point_3 Vg[3];
  43. Point_3 Vf[3];
  44. for(int i = 0;i<3;i++)
  45. {
  46. Vg[i] = Point_3(V(F(g,i),0),V(F(g,i),1),V(F(g,i),2));
  47. if(i == c)
  48. {
  49. Vf[i] = Point_3(p(0),p(1),p(2));
  50. }else
  51. {
  52. Vf[i] = Point_3(V(F(f,i),0),V(F(f,i),1),V(F(f,i),2));
  53. }
  54. }
  55. Triangle_3 Tg(Vg[0],Vg[1],Vg[2]);
  56. Triangle_3 Tf(Vf[0],Vf[1],Vf[2]);
  57. #endif
  58. // I'm leaving this debug printing stuff in for a bit until I trust this
  59. // better.
  60. constexpr bool stinker = false;
  61. //const bool stinker = (f==1492 && g==1554);
  62. if(stinker) { printf("👀\n"); }
  63. bool found_intersection = false;
  64. // So edge opposite F(f,c) is the outer edge.
  65. const bool share_edge_opposite_c = [&]()
  66. {
  67. const int o = EMAP(f + c*F.rows());
  68. return (EF(o,0) == f && EF(o,1) == g) || (EF(o,1) == f && EF(o,0) == g);
  69. }();
  70. const int o = EMAP(f + c*F.rows());
  71. // Do they share the edge opposite c?
  72. if(share_edge_opposite_c)
  73. {
  74. if(stinker) { printf("⚠️ shares an edge\n"); }
  75. found_intersection = triangle_triangle_intersect_shared_edge(V,F,f,c,p,g,1e-8);
  76. }else
  77. {
  78. if(stinker) { printf("does not share an edge\n"); }
  79. // Do they share a vertex?
  80. int sf,sg;
  81. bool found_shared_vertex = false;
  82. for(sf = 0;sf<3;sf++)
  83. {
  84. if(sf == c){ continue;}
  85. for(sg = 0;sg<3;sg++)
  86. {
  87. if(F(f,sf) == F(g,sg))
  88. {
  89. found_shared_vertex = true;
  90. break;
  91. }
  92. }
  93. if(found_shared_vertex) { break;}
  94. }
  95. if(found_shared_vertex)
  96. {
  97. if(stinker) { printf("⚠️ shares a vertex\n"); }
  98. found_intersection =
  99. triangle_triangle_intersect_shared_vertex(V,F,f,sf,c,p,g,sg,1e-14);
  100. }else
  101. {
  102. bool coplanar;
  103. Eigen::RowVector3d i1,i2;
  104. found_intersection = igl::tri_tri_intersection_test_3d(
  105. V.row(F(g,0)).template cast<double>(),
  106. V.row(F(g,1)).template cast<double>(),
  107. V.row(F(g,2)).template cast<double>(),
  108. p.template cast<double>(),
  109. V.row(F(f,(c+1)%3)).template cast<double>(),
  110. V.row(F(f,(c+2)%3)).template cast<double>(),
  111. coplanar,
  112. i1,i2);
  113. if(stinker) { printf("tri_tri_intersection_test_3d says %s\n",found_intersection?"☠️":"✅"); }
  114. #ifdef IGL_TRIANGLE_TRIANGLE_INTERSECT_DEBUG
  115. if(CGAL::do_intersect(Tg,Tf))
  116. {
  117. cgal_found_intersection = true;
  118. printf(" ✅ sure it's anything\n");
  119. }
  120. assert(found_intersection == cgal_found_intersection);
  121. #endif
  122. }
  123. }
  124. if(stinker) { printf("%s\n",found_intersection?"☠️":"✅"); }
  125. return found_intersection;
  126. }
  127. #ifdef IGL_STATIC_LIBRARY
  128. // Explicit template instantiation
  129. template bool igl::triangle_triangle_intersect<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -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&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -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);
  130. template bool igl::triangle_triangle_intersect<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -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&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -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);
  131. #endif