convex_hull.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2017 Alec Jacobson <[email protected]>
  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 "convex_hull.h"
  9. #include "../../ismember_rows.h"
  10. #include "polyhedron_to_mesh.h"
  11. #include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
  12. #include <CGAL/Polyhedron_3.h>
  13. #include <CGAL/Surface_mesh.h>
  14. #include <CGAL/convex_hull_3.h>
  15. #include <vector>
  16. template <
  17. typename DerivedV,
  18. typename DerivedW,
  19. typename DerivedG>
  20. IGL_INLINE void igl::copyleft::cgal::convex_hull(
  21. const Eigen::MatrixBase<DerivedV> & V,
  22. Eigen::PlainObjectBase<DerivedW> & W,
  23. Eigen::PlainObjectBase<DerivedG> & G)
  24. {
  25. typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
  26. switch(V.cols())
  27. {
  28. case 3:
  29. {
  30. typedef K::Point_3 Point_3;
  31. //typedef CGAL::Delaunay_triangulation_3<K> Delaunay;
  32. //typedef Delaunay::Vertex_handle Vertex_handle;
  33. //typedef CGAL::Surface_mesh<Point_3> Surface_mesh;
  34. typedef CGAL::Polyhedron_3<K> Polyhedron_3;
  35. std::vector<Point_3> points(V.rows());
  36. for(int i = 0;i<V.rows();i++)
  37. {
  38. points[i] = Point_3(V(i,0),V(i,1),V(i,2));
  39. }
  40. Polyhedron_3 poly;
  41. CGAL::convex_hull_3(points.begin(),points.end(),poly);
  42. // https://stackoverflow.com/a/27535366/148668
  43. // It always should be.
  44. assert(poly.is_pure_triangle() && "Assuming CGAL outputs a triangle mesh");
  45. polyhedron_to_mesh(poly,W,G);
  46. break;
  47. }
  48. case 2:
  49. {
  50. typedef K::Point_2 Point_2;
  51. std::vector<Point_2> points(V.rows());
  52. std::vector<Point_2> result;
  53. for(int i = 0;i<V.rows();i++)
  54. {
  55. points[i] = Point_2(V(i,0),V(i,1));
  56. }
  57. CGAL::convex_hull_2(points.begin(),points.end(),std::back_inserter(result));
  58. W.resize(result.size(),2);
  59. G.resize(result.size(),2);
  60. for(int i = 0;i<result.size();i++)
  61. {
  62. W(i,0) = result[i].x();
  63. W(i,1) = result[i].y();
  64. G(i,0) = i;
  65. G(i,1) = (i+1)%result.size();
  66. }
  67. break;
  68. }
  69. }
  70. }
  71. template <
  72. typename DerivedV,
  73. typename DerivedF>
  74. IGL_INLINE void igl::copyleft::cgal::convex_hull(
  75. const Eigen::MatrixBase<DerivedV> & V,
  76. Eigen::PlainObjectBase<DerivedF> & F)
  77. {
  78. Eigen::Matrix<typename DerivedV::Scalar, Eigen::Dynamic, Eigen::Dynamic> W;
  79. Eigen::Matrix<typename DerivedF::Scalar, Eigen::Dynamic, Eigen::Dynamic> G;
  80. convex_hull(V,W,G);
  81. // This is a lazy way to reindex into the original mesh
  82. Eigen::Matrix<bool,Eigen::Dynamic,1> I;
  83. Eigen::VectorXi J;
  84. igl::ismember_rows(W,V,I,J);
  85. assert(I.all() && "Should find all W in V");
  86. F.resizeLike(G);
  87. for(int f = 0;f<G.rows();f++)
  88. {
  89. for(int c = 0;c<3;c++)
  90. {
  91. F(f,c) = J(G(f,c));
  92. }
  93. }
  94. }
  95. #ifdef IGL_STATIC_LIBRARY
  96. // Explicit template instantiation
  97. template void igl::copyleft::cgal::convex_hull<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
  98. // generated by autoexplicit.sh
  99. template void igl::copyleft::cgal::convex_hull<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
  100. template void igl::copyleft::cgal::convex_hull<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
  101. template void igl::copyleft::cgal::convex_hull<Eigen::Matrix<double, -1, 2, 0, -1, 2>, Eigen::Matrix<double, -1, 2, 0, -1, 2>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 2, 0, -1, 2> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 2, 0, -1, 2> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
  102. #endif