point_mesh_squared_distance.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  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 "point_mesh_squared_distance.h"
  9. #include "mesh_to_cgal_triangle_list.h"
  10. template <
  11. typename Kernel,
  12. typename DerivedP,
  13. typename DerivedV,
  14. typename DerivedF,
  15. typename DerivedsqrD,
  16. typename DerivedI,
  17. typename DerivedC>
  18. IGL_INLINE void igl::copyleft::cgal::point_mesh_squared_distance(
  19. const Eigen::PlainObjectBase<DerivedP> & P,
  20. const Eigen::PlainObjectBase<DerivedV> & V,
  21. const Eigen::PlainObjectBase<DerivedF> & F,
  22. Eigen::PlainObjectBase<DerivedsqrD> & sqrD,
  23. Eigen::PlainObjectBase<DerivedI> & I,
  24. Eigen::PlainObjectBase<DerivedC> & C)
  25. {
  26. using namespace std;
  27. typedef CGAL::Triangle_3<Kernel> Triangle_3;
  28. typedef typename std::vector<Triangle_3>::iterator Iterator;
  29. typedef CGAL::AABB_triangle_primitive<Kernel, Iterator> Primitive;
  30. typedef CGAL::AABB_traits<Kernel, Primitive> AABB_triangle_traits;
  31. typedef CGAL::AABB_tree<AABB_triangle_traits> Tree;
  32. Tree tree;
  33. vector<Triangle_3> T;
  34. point_mesh_squared_distance_precompute(V,F,tree,T);
  35. return point_mesh_squared_distance(P,tree,T,sqrD,I,C);
  36. }
  37. template <typename Kernel, typename DerivedV, typename DerivedF>
  38. IGL_INLINE void igl::copyleft::cgal::point_mesh_squared_distance_precompute(
  39. const Eigen::PlainObjectBase<DerivedV> & V,
  40. const Eigen::PlainObjectBase<DerivedF> & F,
  41. CGAL::AABB_tree<
  42. CGAL::AABB_traits<Kernel,
  43. CGAL::AABB_triangle_primitive<Kernel,
  44. typename std::vector<CGAL::Triangle_3<Kernel> >::iterator
  45. >
  46. >
  47. > & tree,
  48. std::vector<CGAL::Triangle_3<Kernel> > & T)
  49. {
  50. using namespace std;
  51. typedef CGAL::Triangle_3<Kernel> Triangle_3;
  52. typedef CGAL::Point_3<Kernel> Point_3;
  53. typedef typename std::vector<Triangle_3>::iterator Iterator;
  54. typedef CGAL::AABB_triangle_primitive<Kernel, Iterator> Primitive;
  55. typedef CGAL::AABB_traits<Kernel, Primitive> AABB_triangle_traits;
  56. typedef CGAL::AABB_tree<AABB_triangle_traits> Tree;
  57. // Must be 3D
  58. assert(V.cols() == 3);
  59. // Must be triangles
  60. assert(F.cols() == 3);
  61. // WTF ALERT!!!!
  62. //
  63. // There's a bug in clang probably or at least in cgal. Without calling this
  64. // line (I guess invoking some compilation from <vector>), clang will vomit
  65. // errors inside CGAL.
  66. //
  67. // http://stackoverflow.com/questions/27748442/is-clangs-c11-support-reliable
  68. T.reserve(0);
  69. // Make list of cgal triangles
  70. mesh_to_cgal_triangle_list(V,F,T);
  71. tree.clear();
  72. tree.insert(T.begin(),T.end());
  73. tree.accelerate_distance_queries();
  74. // accelerate_distance_queries doesn't seem actually to do _all_ of the
  75. // precomputation. the tree (despite being const) will still do more
  76. // precomputation and reorganizing on the first call of `closest_point` or
  77. // `closest_point_and_primitive`. Therefor, call it once here.
  78. tree.closest_point_and_primitive(Point_3(0,0,0));
  79. }
  80. template <
  81. typename Kernel,
  82. typename DerivedP,
  83. typename DerivedsqrD,
  84. typename DerivedI,
  85. typename DerivedC>
  86. IGL_INLINE void igl::copyleft::cgal::point_mesh_squared_distance(
  87. const Eigen::PlainObjectBase<DerivedP> & P,
  88. const CGAL::AABB_tree<
  89. CGAL::AABB_traits<Kernel,
  90. CGAL::AABB_triangle_primitive<Kernel,
  91. typename std::vector<CGAL::Triangle_3<Kernel> >::iterator
  92. >
  93. >
  94. > & tree,
  95. const std::vector<CGAL::Triangle_3<Kernel> > & T,
  96. Eigen::PlainObjectBase<DerivedsqrD> & sqrD,
  97. Eigen::PlainObjectBase<DerivedI> & I,
  98. Eigen::PlainObjectBase<DerivedC> & C)
  99. {
  100. typedef CGAL::Triangle_3<Kernel> Triangle_3;
  101. typedef typename std::vector<Triangle_3>::iterator Iterator;
  102. typedef CGAL::AABB_triangle_primitive<Kernel, Iterator> Primitive;
  103. typedef CGAL::AABB_traits<Kernel, Primitive> AABB_triangle_traits;
  104. typedef CGAL::AABB_tree<AABB_triangle_traits> Tree;
  105. typedef typename Tree::Point_and_primitive_id Point_and_primitive_id;
  106. typedef CGAL::Point_3<Kernel> Point_3;
  107. assert(P.cols() == 3);
  108. const int n = P.rows();
  109. sqrD.resize(n,1);
  110. I.resize(n,1);
  111. C.resize(n,P.cols());
  112. for(int p = 0;p < n;p++)
  113. {
  114. Point_3 query(P(p,0),P(p,1),P(p,2));
  115. // Find closest point and primitive id
  116. Point_and_primitive_id pp = tree.closest_point_and_primitive(query);
  117. Point_3 closest_point = pp.first;
  118. assign_scalar(closest_point[0],C(p,0));
  119. assign_scalar(closest_point[1],C(p,1));
  120. assign_scalar(closest_point[2],C(p,2));
  121. assign_scalar((closest_point-query).squared_length(),sqrD(p));
  122. I(p) = pp.second - T.begin();
  123. }
  124. }
  125. #ifdef IGL_STATIC_LIBRARY
  126. // Explicit template specialization
  127. #endif