line_mesh_intersection.cpp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2013 Daniele Panozzo <daniele.panozzo@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 "line_mesh_intersection.h"
  9. // For error printing
  10. #include <cstdio>
  11. #include <vector>
  12. #include <igl/per_vertex_normals.h>
  13. #include <igl/embree/EmbreeIntersector.h>
  14. template <typename ScalarMatrix, typename IndexMatrix>
  15. IGL_INLINE ScalarMatrix igl::embree::line_mesh_intersection
  16. (
  17. const ScalarMatrix & V_source,
  18. const ScalarMatrix & N_source,
  19. const ScalarMatrix & V_target,
  20. const IndexMatrix & F_target
  21. )
  22. {
  23. double tol = 0.00001;
  24. Eigen::MatrixXd ray_pos = V_source;
  25. Eigen::MatrixXd ray_dir = N_source;
  26. // Allocate matrix for the result
  27. ScalarMatrix R;
  28. R.resize(V_source.rows(), 3);
  29. // Initialize embree
  30. EmbreeIntersector embree;
  31. embree.init(V_target.template cast<float>(),F_target.template cast<int>());
  32. // Shoot rays from the source to the target
  33. for (unsigned i=0; i<ray_pos.rows(); ++i)
  34. {
  35. igl::embree::Hit A,B;
  36. // Shoot ray A
  37. Eigen::RowVector3d A_pos = ray_pos.row(i) + tol * ray_dir.row(i);
  38. Eigen::RowVector3d A_dir = -ray_dir.row(i);
  39. bool A_hit = embree.intersectBeam(A_pos.cast<float>(), A_dir.cast<float>(),A);
  40. Eigen::RowVector3d B_pos = ray_pos.row(i) - tol * ray_dir.row(i);
  41. Eigen::RowVector3d B_dir = ray_dir.row(i);
  42. bool B_hit = embree.intersectBeam(B_pos.cast<float>(), B_dir.cast<float>(),B);
  43. int choice = -1;
  44. if (A_hit && ! B_hit)
  45. choice = 0;
  46. else if (!A_hit && B_hit)
  47. choice = 1;
  48. else if (A_hit && B_hit)
  49. choice = A.t > B.t;
  50. Eigen::RowVector3d temp;
  51. if (choice == -1)
  52. temp << -1, 0, 0;
  53. else if (choice == 0)
  54. temp << A.id, A.u, A.v;
  55. else if (choice == 1)
  56. temp << B.id, B.u, B.v;
  57. R.row(i) = temp;
  58. }
  59. return R;
  60. }
  61. #ifdef IGL_STATIC_LIBRARY
  62. template Eigen::Matrix<double, -1, -1, 0, -1, -1> igl::embree::line_mesh_intersection<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::Matrix<double, -1, -1, 0, -1, -1> const&, Eigen::Matrix<double, -1, -1, 0, -1, -1> const&, Eigen::Matrix<double, -1, -1, 0, -1, -1> const&, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&);
  63. #endif