delaunay_triangulation.cpp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2016 Qingnan Zhou <qnzhou@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 "delaunay_triangulation.h"
  9. #include "../../unique_edge_map.h"
  10. #include "../../flip_edge.h"
  11. #include "ExactPredicate.h"
  12. #include "lexicographic_triangulation.h"
  13. #include <vector>
  14. #include <sstream>
  15. template<
  16. typename DerivedV,
  17. typename DerivedF>
  18. IGL_INLINE void igl::copyleft::cgal::delaunay_triangulation(
  19. const Eigen::PlainObjectBase<DerivedV>& V,
  20. Eigen::PlainObjectBase<DerivedF>& F)
  21. {
  22. assert(V.cols() == 2);
  23. typedef typename DerivedF::Scalar Index;
  24. typedef typename DerivedV::Scalar Scalar;
  25. typedef typename igl::copyleft::cgal::ExactPredicate<Scalar> Predicate;
  26. igl::copyleft::cgal::lexicographic_triangulation(V, F);
  27. const size_t num_faces = F.rows();
  28. if (num_faces == 0) {
  29. // Input points are degenerate. No faces will be generated.
  30. return;
  31. }
  32. assert(F.cols() == 3);
  33. Eigen::MatrixXi E;
  34. Eigen::MatrixXi uE;
  35. Eigen::VectorXi EMAP;
  36. std::vector<std::vector<Index> > uE2E;
  37. igl::unique_edge_map(F, E, uE, EMAP, uE2E);
  38. auto is_delaunay = [&V,&F,&uE2E,num_faces](size_t uei) {
  39. auto& half_edges = uE2E[uei];
  40. if (half_edges.size() != 2) {
  41. throw "Cannot flip non-manifold or boundary edge";
  42. }
  43. const size_t f1 = half_edges[0] % num_faces;
  44. const size_t f2 = half_edges[1] % num_faces;
  45. const size_t c1 = half_edges[0] / num_faces;
  46. const size_t c2 = half_edges[1] / num_faces;
  47. assert(c1 < 3);
  48. assert(c2 < 3);
  49. assert(f1 != f2);
  50. const size_t v1 = F(f1, (c1+1)%3);
  51. const size_t v2 = F(f1, (c1+2)%3);
  52. const size_t v4 = F(f1, c1);
  53. const size_t v3 = F(f2, c2);
  54. const Scalar p1[] = {V(v1, 0), V(v1, 1)};
  55. const Scalar p2[] = {V(v2, 0), V(v2, 1)};
  56. const Scalar p3[] = {V(v3, 0), V(v3, 1)};
  57. const Scalar p4[] = {V(v4, 0), V(v4, 1)};
  58. auto orientation = Predicate::incircle(p1, p2, p4, p3);
  59. return orientation <= 0;
  60. };
  61. bool all_delaunay = false;
  62. while(!all_delaunay) {
  63. all_delaunay = true;
  64. for (size_t i=0; i<uE2E.size(); i++) {
  65. if (uE2E[i].size() == 2) {
  66. if (!is_delaunay(i)) {
  67. all_delaunay = false;
  68. flip_edge(F, E, uE, EMAP, uE2E, i);
  69. }
  70. }
  71. }
  72. }
  73. }