intersect_other.cpp 3.8 KB

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