ray_mesh_intersect.cpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2016 Alec Jacobson <[email protected]>
  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 "ray_mesh_intersect.h"
  9. extern "C"
  10. {
  11. #include "raytri.c"
  12. }
  13. namespace igl {
  14. template <
  15. typename Derivedsource,
  16. typename Deriveddir,
  17. typename DerivedV,
  18. typename DerivedF>
  19. IGL_INLINE bool ray_triangle_intersect(
  20. const Eigen::MatrixBase<Derivedsource> & s,
  21. const Eigen::MatrixBase<Deriveddir> & dir,
  22. const Eigen::MatrixBase<DerivedV> & V,
  23. const Eigen::MatrixBase<DerivedF> & F,
  24. const int f,
  25. igl::Hit& hit)
  26. {
  27. using namespace Eigen;
  28. // intersect_triangle1 needs non-const inputs.
  29. Vector3d s_d = s.template cast<double>();
  30. Vector3d dir_d = dir.template cast<double>();
  31. RowVector3d v0 = V.row(F(f,0)).template cast<double>();
  32. RowVector3d v1 = V.row(F(f,1)).template cast<double>();
  33. RowVector3d v2 = V.row(F(f,2)).template cast<double>();
  34. // shoot ray, record hit
  35. double t,u,v;
  36. if(intersect_triangle1(
  37. s_d.data(), dir_d.data(), v0.data(), v1.data(), v2.data(), &t, &u, &v) &&
  38. t>0)
  39. {
  40. hit = {static_cast<int>(f),static_cast<int>(-1),
  41. static_cast<float>(u),static_cast<float>(v),
  42. static_cast<float>(t)};
  43. return true;
  44. }
  45. return false;
  46. }
  47. template <
  48. typename Derivedsource,
  49. typename Deriveddir,
  50. typename DerivedV,
  51. typename DerivedF>
  52. IGL_INLINE bool ray_mesh_intersect(
  53. const Eigen::MatrixBase<Derivedsource> & s,
  54. const Eigen::MatrixBase<Deriveddir> & dir,
  55. const Eigen::MatrixBase<DerivedV> & V,
  56. const Eigen::MatrixBase<DerivedF> & F,
  57. std::vector<igl::Hit> & hits)
  58. {
  59. using namespace Eigen;
  60. hits.clear();
  61. hits.reserve(F.rows());
  62. // loop over all triangles
  63. for(int f = 0;f<F.rows();f++)
  64. {
  65. igl::Hit hit;
  66. if(ray_triangle_intersect(s, dir, V, F, f, hit))
  67. {
  68. hits.push_back(hit);
  69. }
  70. }
  71. // Sort hits based on distance
  72. std::sort(
  73. hits.begin(),
  74. hits.end(),
  75. [](const Hit & a, const Hit & b)->bool{ return a.t < b.t;});
  76. return hits.size() > 0;
  77. }
  78. template <
  79. typename Derivedsource,
  80. typename Deriveddir,
  81. typename DerivedV,
  82. typename DerivedF>
  83. IGL_INLINE bool ray_mesh_intersect(
  84. const Eigen::MatrixBase<Derivedsource> & s,
  85. const Eigen::MatrixBase<Deriveddir> & dir,
  86. const Eigen::MatrixBase<DerivedV> & V,
  87. const Eigen::MatrixBase<DerivedF> & F,
  88. igl::Hit & hit)
  89. {
  90. if (F.rows() == 1)
  91. {
  92. // Shortcut for AABB based queries.
  93. return ray_triangle_intersect(s, dir, V, F, 0, hit);
  94. }else
  95. {
  96. std::vector<igl::Hit> hits;
  97. ray_mesh_intersect(s,dir,V,F,hits);
  98. if(hits.size() > 0)
  99. {
  100. hit = hits.front();
  101. return true;
  102. }else
  103. {
  104. return false;
  105. }
  106. }
  107. }
  108. }
  109. #ifdef IGL_STATIC_LIBRARY
  110. // Explicit template instantiation
  111. // generated by autoexplicit.sh
  112. template bool igl::ray_mesh_intersect<Eigen::Matrix<float, 1, 3, 1, 1, 3>, Eigen::Matrix<float, 1, 3, 1, 1, 3>, Eigen::Matrix<float, -1, -1, 0, -1, -1>, Eigen::Block<Eigen::Matrix<int, -1, -1, 0, -1, -1> const, 1, -1, false> >(Eigen::MatrixBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<float, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Block<Eigen::Matrix<int, -1, -1, 0, -1, -1> const, 1, -1, false> > const&, std::vector<igl::Hit, std::allocator<igl::Hit> >&);
  113. // generated by autoexplicit.sh
  114. template bool igl::ray_mesh_intersect<Eigen::Matrix<float, 3, 1, 0, 3, 1>, Eigen::Matrix<float, 3, 1, 0, 3, 1>, Eigen::Matrix<float, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<float, 3, 1, 0, 3, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<float, 3, 1, 0, 3, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<float, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<igl::Hit, std::allocator<igl::Hit> >&);
  115. // generated by autoexplicit.sh
  116. template bool igl::ray_mesh_intersect<Eigen::Matrix<float, 3, 1, 0, 3, 1>, Eigen::Matrix<float, 3, 1, 0, 3, 1>, Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, 3, 1, 0, 3, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<float, 3, 1, 0, 3, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, std::vector<igl::Hit, std::allocator<igl::Hit> >&);
  117. template bool igl::ray_mesh_intersect<Eigen::Matrix<float, 3, 1, 0, 3, 1>, Eigen::Matrix<float, 3, 1, 0, 3, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<float, 3, 1, 0, 3, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<float, 3, 1, 0, 3, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<igl::Hit, std::allocator<igl::Hit> >&);
  118. template bool igl::ray_mesh_intersect<Eigen::Matrix<float, 3, 1, 0, 3, 1>, Eigen::Matrix<float, 3, 1, 0, 3, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<float, 3, 1, 0, 3, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<float, 3, 1, 0, 3, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::Hit&);
  119. template bool igl::ray_mesh_intersect<Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Block<Eigen::Matrix<int, -1, -1, 0, -1, -1> const, 1, -1, false> >(Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Block<Eigen::Matrix<int, -1, -1, 0, -1, -1> const, 1, -1, false> > const&, igl::Hit&);
  120. #endif