ray_mesh_intersect.cpp 3.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  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. template <
  14. typename Derivedsource,
  15. typename Deriveddir,
  16. typename DerivedV,
  17. typename DerivedF>
  18. IGL_INLINE bool igl::ray_mesh_intersect(
  19. const Eigen::MatrixBase<Derivedsource> & s,
  20. const Eigen::MatrixBase<Deriveddir> & dir,
  21. const Eigen::MatrixBase<DerivedV> & V,
  22. const Eigen::MatrixBase<DerivedF> & F,
  23. std::vector<igl::Hit> & hits)
  24. {
  25. using namespace Eigen;
  26. using namespace std;
  27. // Should be but can't be const
  28. Vector3d s_d = s.template cast<double>();
  29. Vector3d dir_d = dir.template cast<double>();
  30. hits.clear();
  31. hits.reserve(F.rows());
  32. // loop over all triangles
  33. for(int f = 0;f<F.rows();f++)
  34. {
  35. // Should be but can't be const
  36. RowVector3d v0 = V.row(F(f,0)).template cast<double>();
  37. RowVector3d v1 = V.row(F(f,1)).template cast<double>();
  38. RowVector3d v2 = V.row(F(f,2)).template cast<double>();
  39. // shoot ray, record hit
  40. double t,u,v;
  41. if(intersect_triangle1(
  42. s_d.data(), dir_d.data(), v0.data(), v1.data(), v2.data(), &t, &u, &v) &&
  43. t>0)
  44. {
  45. hits.push_back({(int)f,(int)-1,(float)u,(float)v,(float)t});
  46. }
  47. }
  48. // Sort hits based on distance
  49. std::sort(
  50. hits.begin(),
  51. hits.end(),
  52. [](const Hit & a, const Hit & b)->bool{ return a.t < b.t;});
  53. return hits.size() > 0;
  54. }
  55. template <
  56. typename Derivedsource,
  57. typename Deriveddir,
  58. typename DerivedV,
  59. typename DerivedF>
  60. IGL_INLINE bool igl::ray_mesh_intersect(
  61. const Eigen::MatrixBase<Derivedsource> & source,
  62. const Eigen::MatrixBase<Deriveddir> & dir,
  63. const Eigen::MatrixBase<DerivedV> & V,
  64. const Eigen::MatrixBase<DerivedF> & F,
  65. igl::Hit & hit)
  66. {
  67. std::vector<igl::Hit> hits;
  68. ray_mesh_intersect(source,dir,V,F,hits);
  69. if(hits.size() > 0)
  70. {
  71. hit = hits.front();
  72. return true;
  73. }else
  74. {
  75. return false;
  76. }
  77. }
  78. #ifdef IGL_STATIC_LIBRARY
  79. // Explicit template instantiation
  80. 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> >&);
  81. 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&);
  82. 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&);
  83. #endif