line_mesh_intersection.cpp 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  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::line_mesh_intersection(
  16. // const ScalarMatrix & V_source,
  17. // const IndexMatrix & F_source,
  18. // const ScalarMatrix & V_target,
  19. // const IndexMatrix & F_target
  20. //)
  21. //{
  22. // // Compute normals for the tri
  23. // Eigen::MatrixXd ray_dir;
  24. // igl::per_vertex_normals(V_source, F_source, ray_dir);
  25. //
  26. // return line_mesh_intersection(V_source,ray_dir,V_target,F_target);
  27. //}
  28. template <typename ScalarMatrix, typename IndexMatrix>
  29. IGL_INLINE ScalarMatrix igl::line_mesh_intersection
  30. (
  31. const ScalarMatrix & V_source,
  32. const ScalarMatrix & N_source,
  33. const ScalarMatrix & V_target,
  34. const IndexMatrix & F_target
  35. )
  36. {
  37. double tol = 0.00001;
  38. Eigen::MatrixXd ray_pos = V_source;
  39. Eigen::MatrixXd ray_dir = N_source;
  40. // Allocate matrix for the result
  41. ScalarMatrix R;
  42. R.resize(V_source.rows(), 3);
  43. // Initialize embree
  44. igl::EmbreeIntersector embree;
  45. embree.init(V_target.template cast<float>(),F_target.template cast<int>());
  46. // Shoot rays from the source to the target
  47. for (unsigned i=0; i<ray_pos.rows(); ++i)
  48. {
  49. igl::Hit A,B;
  50. // Shoot ray A
  51. Eigen::RowVector3d A_pos = ray_pos.row(i) + tol * ray_dir.row(i);
  52. Eigen::RowVector3d A_dir = -ray_dir.row(i);
  53. bool A_hit = embree.intersectRay(A_pos.cast<float>(), A_dir.cast<float>(),A);
  54. Eigen::RowVector3d B_pos = ray_pos.row(i) - tol * ray_dir.row(i);
  55. Eigen::RowVector3d B_dir = ray_dir.row(i);
  56. bool B_hit = embree.intersectRay(B_pos.cast<float>(), B_dir.cast<float>(),B);
  57. int choice = -1;
  58. if (A_hit && ! B_hit)
  59. choice = 0;
  60. else if (!A_hit && B_hit)
  61. choice = 1;
  62. else if (A_hit && B_hit)
  63. choice = A.t > B.t;
  64. Eigen::RowVector3d temp;
  65. if (choice == -1)
  66. temp << -1, 0, 0;
  67. else if (choice == 0)
  68. temp << A.id, A.u, A.v;
  69. else if (choice == 1)
  70. temp << B.id, B.u, B.v;
  71. R.row(i) = temp;
  72. }
  73. return R;
  74. }