point_mesh_squared_distance.cpp 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  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 <typename Kernel>
  11. IGL_INLINE void igl::point_mesh_squared_distance(
  12. const Eigen::MatrixXd & P,
  13. const Eigen::MatrixXd & V,
  14. const Eigen::MatrixXi & F,
  15. Eigen::VectorXd & sqrD,
  16. Eigen::VectorXi & I,
  17. Eigen::MatrixXd & C)
  18. {
  19. using namespace std;
  20. typedef CGAL::Point_3<Kernel> Point_3;
  21. typedef CGAL::Triangle_3<Kernel> Triangle_3;
  22. typedef typename std::vector<Triangle_3>::iterator Iterator;
  23. typedef CGAL::AABB_triangle_primitive<Kernel, Iterator> Primitive;
  24. typedef CGAL::AABB_traits<Kernel, Primitive> AABB_triangle_traits;
  25. typedef CGAL::AABB_tree<AABB_triangle_traits> Tree;
  26. typedef typename Tree::Point_and_primitive_id Point_and_primitive_id;
  27. // Must be 3D
  28. assert(V.cols() == 3);
  29. assert(P.cols() == 3);
  30. // Must be triangles
  31. assert(F.cols() == 3);
  32. // Make list of cgal triangles
  33. Tree tree;
  34. vector<Triangle_3> T;
  35. mesh_to_cgal_triangle_list(V,F,T);
  36. tree.insert(T.begin(),T.end());
  37. tree.accelerate_distance_queries();
  38. const int n = P.rows();
  39. sqrD.resize(n,1);
  40. I.resize(n,1);
  41. C.resize(n,P.cols());
  42. for(int p = 0;p < n;p++)
  43. {
  44. Point_3 query(P(p,0),P(p,1),P(p,2));
  45. // Find closest point and primitive id
  46. Point_and_primitive_id pp = tree.closest_point_and_primitive(query);
  47. Point_3 closest_point = pp.first;
  48. C(p,0) = CGAL::to_double(closest_point[0]);
  49. C(p,1) = CGAL::to_double(closest_point[1]);
  50. C(p,2) = CGAL::to_double(closest_point[2]);
  51. sqrD(p) = CGAL::to_double((closest_point-query).squared_length());
  52. I(p) = pp.second - T.begin();
  53. }
  54. }
  55. #ifdef IGL_STATIC_LIBRARY
  56. // Explicit template specialization
  57. template void igl::point_mesh_squared_distance<CGAL::Epeck>( const Eigen::MatrixXd & P, const Eigen::MatrixXd & V, const Eigen::MatrixXi & F, Eigen::VectorXd & sqrD, Eigen::VectorXi & I, Eigen::MatrixXd & C);
  58. #endif