intersect_other.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2014 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 "intersect_other.h"
  9. #include "CGAL_includes.hpp"
  10. #include "mesh_to_cgal_triangle_list.h"
  11. #ifndef IGL_FIRST_HIT_EXCEPTION
  12. #define IGL_FIRST_HIT_EXCEPTION 10
  13. #endif
  14. IGL_INLINE void igl::cgal::intersect_other(
  15. const Eigen::MatrixXd & V,
  16. const Eigen::MatrixXi & F,
  17. const Eigen::MatrixXd & U,
  18. const Eigen::MatrixXi & G,
  19. const bool first_only,
  20. Eigen::MatrixXi & IF)
  21. {
  22. using namespace std;
  23. using namespace Eigen;
  24. typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
  25. // 3D Primitives
  26. typedef CGAL::Point_3<Kernel> Point_3;
  27. typedef CGAL::Segment_3<Kernel> Segment_3;
  28. typedef CGAL::Triangle_3<Kernel> Triangle_3;
  29. typedef CGAL::Plane_3<Kernel> Plane_3;
  30. typedef CGAL::Tetrahedron_3<Kernel> Tetrahedron_3;
  31. // 2D Primitives
  32. typedef CGAL::Point_2<Kernel> Point_2;
  33. typedef CGAL::Segment_2<Kernel> Segment_2;
  34. typedef CGAL::Triangle_2<Kernel> Triangle_2;
  35. // 2D Constrained Delaunay Triangulation types
  36. typedef CGAL::Triangulation_vertex_base_2<Kernel> TVB_2;
  37. typedef CGAL::Constrained_triangulation_face_base_2<Kernel> CTFB_2;
  38. typedef CGAL::Triangulation_data_structure_2<TVB_2,CTFB_2> TDS_2;
  39. typedef CGAL::Exact_intersections_tag Itag;
  40. typedef CGAL::Constrained_Delaunay_triangulation_2<Kernel,TDS_2,Itag>
  41. CDT_2;
  42. typedef CGAL::Constrained_triangulation_plus_2<CDT_2> CDT_plus_2;
  43. // Axis-align boxes for all-pairs self-intersection detection
  44. typedef std::vector<Triangle_3> Triangles;
  45. typedef typename Triangles::iterator TrianglesIterator;
  46. typedef typename Triangles::const_iterator TrianglesConstIterator;
  47. typedef
  48. CGAL::Box_intersection_d::Box_with_handle_d<double,3,TrianglesIterator>
  49. Box;
  50. Triangles TF,TG;
  51. // Compute and process self intersections
  52. mesh_to_cgal_triangle_list(V,F,TF);
  53. mesh_to_cgal_triangle_list(U,G,TG);
  54. // http://www.cgal.org/Manual/latest/doc_html/cgal_manual/Box_intersection_d/Chapter_main.html#Section_63.5
  55. // Create the corresponding vector of bounding boxes
  56. std::vector<Box> F_boxes,G_boxes;
  57. const auto box_up = [](Triangles & T, std::vector<Box> & boxes)
  58. {
  59. boxes.reserve(T.size());
  60. for (
  61. TrianglesIterator tit = T.begin();
  62. tit != T.end();
  63. ++tit)
  64. {
  65. boxes.push_back(Box(tit->bbox(), tit));
  66. }
  67. };
  68. box_up(TF,F_boxes);
  69. box_up(TG,G_boxes);
  70. std::list<int> lIF;
  71. const auto cb = [&](const Box &a, const Box &b)
  72. {
  73. using namespace std;
  74. // index in F and T
  75. int fa = a.handle()-TF.begin();
  76. int fb = b.handle()-TG.begin();
  77. const Triangle_3 & A = *a.handle();
  78. const Triangle_3 & B = *b.handle();
  79. if(CGAL::do_intersect(A,B))
  80. {
  81. // There was an intersection
  82. lIF.push_back(fa);
  83. lIF.push_back(fb);
  84. if(first_only)
  85. {
  86. throw IGL_FIRST_HIT_EXCEPTION;
  87. }
  88. }
  89. };
  90. try{
  91. CGAL::box_intersection_d(
  92. F_boxes.begin(), F_boxes.end(),
  93. G_boxes.begin(), G_boxes.end(),
  94. cb);
  95. }catch(int e)
  96. {
  97. // Rethrow if not FIRST_HIT_EXCEPTION
  98. if(e != IGL_FIRST_HIT_EXCEPTION)
  99. {
  100. throw e;
  101. }
  102. // Otherwise just fall through
  103. }
  104. // Convert lIF to Eigen matrix
  105. assert(lIF.size()%2 == 0);
  106. IF.resize(lIF.size()/2,2);
  107. {
  108. int i=0;
  109. for(
  110. list<int>::const_iterator ifit = lIF.begin();
  111. ifit!=lIF.end();
  112. )
  113. {
  114. IF(i,0) = (*ifit);
  115. ifit++;
  116. IF(i,1) = (*ifit);
  117. ifit++;
  118. i++;
  119. }
  120. }
  121. }
  122. #ifdef IGL_STATIC_LIBRARY
  123. // Explicit template specialization
  124. #endif