ray_mesh_intersect.cpp 3.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2016 Alec Jacobson <alecjacobson@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 "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. // loop over all triangles
  32. for(int f = 0;f<F.rows();f++)
  33. {
  34. // Should be but can't be const
  35. RowVector3d v0 = V.row(F(f,0)).template cast<double>();
  36. RowVector3d v1 = V.row(F(f,1)).template cast<double>();
  37. RowVector3d v2 = V.row(F(f,2)).template cast<double>();
  38. // shoot ray, record hit
  39. double t,u,v;
  40. if(intersect_triangle1(
  41. s_d.data(), dir_d.data(), v0.data(), v1.data(), v2.data(), &t, &u, &v) &&
  42. t>0)
  43. {
  44. hits.push_back({(int)f,(int)-1,(float)u,(float)v,(float)t});
  45. }
  46. }
  47. // Sort hits based on distance
  48. std::sort(
  49. hits.begin(),
  50. hits.end(),
  51. [](const Hit & a, const Hit & b)->bool{ return a.t < b.t;});
  52. return hits.size() > 0;
  53. }
  54. template <
  55. typename Derivedsource,
  56. typename Deriveddir,
  57. typename DerivedV,
  58. typename DerivedF>
  59. IGL_INLINE bool igl::ray_mesh_intersect(
  60. const Eigen::MatrixBase<Derivedsource> & source,
  61. const Eigen::MatrixBase<Deriveddir> & dir,
  62. const Eigen::MatrixBase<DerivedV> & V,
  63. const Eigen::MatrixBase<DerivedF> & F,
  64. igl::Hit & hit)
  65. {
  66. std::vector<igl::Hit> hits;
  67. ray_mesh_intersect(source,dir,V,F,hits);
  68. if(hits.size() > 0)
  69. {
  70. hit = hits.front();
  71. return true;
  72. }else
  73. {
  74. return false;
  75. }
  76. }
  77. #ifdef IGL_STATIC_LIBRARY
  78. // Explicit template instantiation
  79. 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> >&);
  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&, igl::Hit&);
  81. 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&);
  82. #endif