eytzinger_aabb_sdf.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. #include "eytzinger_aabb_sdf.h"
  2. #include "parallel_for.h"
  3. template <
  4. typename Derivedp,
  5. typename Func,
  6. typename DerivedB,
  7. typename Derivedleaf
  8. >
  9. IGL_INLINE void igl::eytzinger_aabb_sdf(
  10. const Eigen::MatrixBase<Derivedp> & p,
  11. const Func & primitive,
  12. const Eigen::MatrixBase<DerivedB> & B1,
  13. const Eigen::MatrixBase<DerivedB> & B2,
  14. const Eigen::MatrixBase<Derivedleaf> & leaf,
  15. typename Derivedp::Scalar & f)
  16. {
  17. using Scalar = typename Derivedp::Scalar;
  18. using RowVectorS = Eigen::Matrix<Scalar, 1, Derivedp::ColsAtCompileTime>;
  19. // https://iquilezles.org/articles/distfunctions/
  20. const auto box_sdf = [&p](const RowVectorS& b1, const RowVectorS& b2) -> Scalar
  21. {
  22. // half diagonal
  23. const RowVectorS b = 0.5*(b2 - b1);
  24. // relative position
  25. const RowVectorS r = p - 0.5*(b1 + b2);
  26. const RowVectorS q = r.cwiseAbs() - b;
  27. const Scalar t1 = q.cwiseMax(0.0).squaredNorm();
  28. const Scalar t2 = std::min(q.maxCoeff(),0.0);
  29. return std::sqrt(t1 + t2);
  30. };
  31. // List of current active nodes
  32. std::vector<std::pair<int,Scalar>> active;
  33. active.reserve(50);
  34. active.emplace_back(0,box_sdf(B1.row(0), B2.row(0)));
  35. f = std::numeric_limits<Scalar>::infinity();
  36. while(!active.empty())
  37. {
  38. const auto [i, box_f] = active.back();
  39. active.pop_back();
  40. if(box_f >= f){ continue; }
  41. if(leaf(i) >= 0)
  42. {
  43. f = std::min(f,primitive(leaf(i)));
  44. }else
  45. {
  46. const int left_i = 2*i + 1;
  47. const int right_i = 2*i + 2;
  48. const Scalar left_f = box_sdf(B1.row(left_i), B2.row(left_i));
  49. const Scalar right_f = box_sdf(B1.row(right_i), B2.row(right_i));
  50. if(left_f < right_f)
  51. {
  52. active.emplace_back(right_i, right_f);
  53. active.emplace_back(left_i, left_f);
  54. }else
  55. {
  56. active.emplace_back(left_i, left_f);
  57. active.emplace_back(right_i, right_f);
  58. }
  59. }
  60. }
  61. }
  62. template <
  63. typename DerivedP,
  64. typename Func,
  65. typename DerivedB,
  66. typename Derivedleaf,
  67. typename DerivedS
  68. >
  69. IGL_INLINE void igl::eytzinger_aabb_sdf(
  70. const Eigen::MatrixBase<DerivedP> & P,
  71. const Func & primitive,
  72. const Eigen::MatrixBase<DerivedB> & B1,
  73. const Eigen::MatrixBase<DerivedB> & B2,
  74. const Eigen::MatrixBase<Derivedleaf> & leaf,
  75. Eigen::PlainObjectBase<DerivedS> & S)
  76. {
  77. using Scalar = typename DerivedS::Scalar;
  78. S.resize(P.rows());
  79. //for(int i = 0; i < P.rows(); i++)
  80. igl::parallel_for(P.rows(), [&](const int i)
  81. {
  82. const Eigen::Matrix<Scalar,1,DerivedP::ColsAtCompileTime> p = P.row(i);
  83. const std::function<Scalar(const int)> primitive_i = [&](const int j)
  84. {
  85. return primitive(p,j);
  86. };
  87. igl::eytzinger_aabb_sdf(p,primitive_i,B1,B2,leaf,S(i));
  88. },1000);
  89. }
  90. #ifdef IGL_STATIC_LIBRARY
  91. // Explicit template instantiation
  92. // generated by autoexplicit.sh
  93. template void igl::eytzinger_aabb_sdf<Eigen::Matrix<double, -1, 3, 1, -1, 3>, std::function<double (Eigen::Matrix<double, 1, 3, 1, 1, 3> const&, int)>, Eigen::Matrix<double, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>>(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 1, -1, 3>> const&, std::function<double (Eigen::Matrix<double, 1, 3, 1, 1, 3> const&, int)> const&, 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<int, -1, 1, 0, -1, 1>> const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1>>&);
  94. template void igl::eytzinger_aabb_sdf<Eigen::Matrix<double, 1, 3, 1, 1, 3>, std::function<double (int)>, Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1>>(Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3>> const&, std::function<double (int)> const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3>> const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3>> const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1>> const&, Eigen::Matrix<double, 1, 3, 1, 1, 3>::Scalar&);
  95. template void igl::eytzinger_aabb_sdf<Eigen::Matrix<double, -1, 3, 0, -1, 3>, std::function<double (Eigen::Matrix<double, 1, 3, 1, 1, 3> const&, int)>, Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>>(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3>> const&, std::function<double (Eigen::Matrix<double, 1, 3, 1, 1, 3> const&, int)> const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3>> const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3>> const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1>> const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1>>&);
  96. #endif