resolve_intersections.cpp 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2016 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 "resolve_intersections.h"
  9. #include "subdivide_segments.h"
  10. #include "row_to_point.h"
  11. #include "../../unique.h"
  12. #include "../../list_to_matrix.h"
  13. #include "../../copyleft/cgal/assign_scalar.h"
  14. #include <CGAL/Exact_predicates_exact_constructions_kernel.h>
  15. #include <CGAL/Segment_2.h>
  16. #include <CGAL/Point_2.h>
  17. #include <algorithm>
  18. #include <vector>
  19. template <
  20. typename DerivedV,
  21. typename DerivedE,
  22. typename DerivedVI,
  23. typename DerivedEI,
  24. typename DerivedJ,
  25. typename DerivedIM>
  26. IGL_INLINE void igl::copyleft::cgal::resolve_intersections(
  27. const Eigen::PlainObjectBase<DerivedV> & V,
  28. const Eigen::PlainObjectBase<DerivedE> & E,
  29. Eigen::PlainObjectBase<DerivedVI> & VI,
  30. Eigen::PlainObjectBase<DerivedEI> & EI,
  31. Eigen::PlainObjectBase<DerivedJ> & J,
  32. Eigen::PlainObjectBase<DerivedIM> & IM)
  33. {
  34. using namespace Eigen;
  35. using namespace igl;
  36. using namespace std;
  37. // Exact scalar type
  38. typedef CGAL::Epeck K;
  39. typedef K::FT EScalar;
  40. typedef CGAL::Segment_2<K> Segment_2;
  41. typedef CGAL::Point_2<K> Point_2;
  42. typedef Matrix<EScalar,Dynamic,Dynamic> MatrixXE;
  43. // Convert vertex positions to exact kernel
  44. MatrixXE VE(V.rows(),V.cols());
  45. for(int i = 0;i<V.rows();i++)
  46. {
  47. for(int j = 0;j<V.cols();j++)
  48. {
  49. VE(i,j) = V(i,j);
  50. }
  51. }
  52. const int m = E.rows();
  53. // resolve all intersections: silly O(n²) implementation
  54. std::vector<std::vector<Point_2> > steiner(m);
  55. for(int i = 0;i<m;i++)
  56. {
  57. Segment_2 si(row_to_point<K>(VE,E(i,0)),row_to_point<K>(VE,E(i,1)));
  58. steiner[i].push_back(si.vertex(0));
  59. steiner[i].push_back(si.vertex(1));
  60. for(int j = i+1;j<m;j++)
  61. {
  62. Segment_2 sj(row_to_point<K>(VE,E(j,0)),row_to_point<K>(VE,E(j,1)));
  63. // do they intersect?
  64. if(CGAL::do_intersect(si,sj))
  65. {
  66. CGAL::Object result = CGAL::intersection(si,sj);
  67. if(const Point_2 * p = CGAL::object_cast<Point_2 >(&result))
  68. {
  69. steiner[i].push_back(*p);
  70. steiner[j].push_back(*p);
  71. // add intersection point
  72. }else if(const Segment_2 * s = CGAL::object_cast<Segment_2 >(&result))
  73. {
  74. // add both endpoints
  75. steiner[i].push_back(s->vertex(0));
  76. steiner[j].push_back(s->vertex(0));
  77. steiner[i].push_back(s->vertex(1));
  78. steiner[j].push_back(s->vertex(1));
  79. }else
  80. {
  81. assert(false && "Unknown intersection type");
  82. }
  83. }
  84. }
  85. }
  86. subdivide_segments(V,E,steiner,VI,EI,J,IM);
  87. }