ray_mesh_intersect.cpp 6.9 KB

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