point_spline_squared_distance.cpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. #include "point_spline_squared_distance.h"
  2. #include "point_cubic_squared_distance.h"
  3. #include "spline_eytzinger_aabb.h"
  4. #include "../eytzinger_aabb_sdf.h"
  5. #include "../parallel_for.h"
  6. #include "../cubic_monomial_bases.h"
  7. template <
  8. typename DerivedQ,
  9. typename DerivedP,
  10. typename DerivedC,
  11. typename DerivedsqrD,
  12. typename DerivedI,
  13. typename DerivedS,
  14. typename DerivedK>
  15. void igl::cycodebase::point_spline_squared_distance(
  16. const Eigen::MatrixBase<DerivedQ>& Q,
  17. const Eigen::MatrixBase<DerivedP>& P,
  18. const Eigen::MatrixBase<DerivedC>& C,
  19. Eigen::PlainObjectBase<DerivedsqrD>& sqrD,
  20. Eigen::PlainObjectBase<DerivedI>& I,
  21. Eigen::PlainObjectBase<DerivedS>& S,
  22. Eigen::PlainObjectBase<DerivedK>& K)
  23. {
  24. static_assert(
  25. DerivedQ::ColsAtCompileTime == DerivedP::ColsAtCompileTime,
  26. "Q and P must have the same number of columns.");
  27. using Scalar = typename DerivedQ::Scalar;
  28. Eigen::Matrix<Scalar,DerivedC::RowsAtCompileTime,DerivedP::ColsAtCompileTime,Eigen::RowMajor>
  29. B1,B2;
  30. Eigen::VectorXi leaf;
  31. spline_eytzinger_aabb(P, C, B1, B2,leaf);
  32. return point_spline_squared_distance(
  33. Q,P,C,B1,B2,leaf,sqrD,I,S,K);
  34. }
  35. template <
  36. typename DerivedQ,
  37. typename DerivedP,
  38. typename DerivedC,
  39. typename DerivedB,
  40. typename Derivedleaf,
  41. typename DerivedsqrD,
  42. typename DerivedI,
  43. typename DerivedS,
  44. typename DerivedK>
  45. void igl::cycodebase::point_spline_squared_distance(
  46. const Eigen::MatrixBase<DerivedQ>& Q,
  47. const Eigen::MatrixBase<DerivedP>& P,
  48. const Eigen::MatrixBase<DerivedC>& C,
  49. const Eigen::MatrixBase<DerivedB>& B1,
  50. const Eigen::MatrixBase<DerivedB>& B2,
  51. const Eigen::MatrixBase<Derivedleaf>& leaf,
  52. Eigen::PlainObjectBase<DerivedsqrD>& sqrD,
  53. Eigen::PlainObjectBase<DerivedI>& I,
  54. Eigen::PlainObjectBase<DerivedS>& S,
  55. Eigen::PlainObjectBase<DerivedK>& K)
  56. {
  57. using Scalar = typename DerivedQ::Scalar;
  58. using RowVectorS = Eigen::Matrix<Scalar, 1, DerivedQ::ColsAtCompileTime>;
  59. using MatrixS4D = Eigen::Matrix<Scalar,4,DerivedQ::ColsAtCompileTime>;
  60. using MatrixS3D = Eigen::Matrix<Scalar,3,DerivedQ::ColsAtCompileTime>;
  61. // Cache these.
  62. std::vector<MatrixS4D> C_vec(C.rows());
  63. std::vector<MatrixS3D> D_vec(C.rows());
  64. std::vector<Eigen::Matrix<Scalar,6,1>> B_vec(C.rows());
  65. {
  66. MatrixS4D M_unused;
  67. for(int j = 0; j < C.rows(); j++)
  68. {
  69. C_vec[j] = P(C.row(j), Eigen::all);
  70. cubic_monomial_bases( C_vec[j], M_unused, D_vec[j], B_vec[j]);
  71. }
  72. }
  73. sqrD.setConstant(Q.rows(),std::numeric_limits<Scalar>::infinity());
  74. S.resize(Q.rows());
  75. I.resize(Q.rows());
  76. K.resize(Q.rows(),Q.cols());
  77. //for(int i = 0; i < Q.rows(); i++)
  78. igl::parallel_for(Q.rows(), [&](const int i)
  79. {
  80. const Eigen::Matrix<Scalar,1,DerivedP::ColsAtCompileTime> q = Q.row(i);
  81. const std::function<Scalar(const int)> primitive_i = [&](const int j)
  82. {
  83. Scalar sqrD_ij,s_ij;
  84. RowVectorS k_ij;
  85. point_cubic_squared_distance( q,
  86. C_vec[j], D_vec[j], B_vec[j],
  87. sqrD_ij, s_ij, k_ij);
  88. if(sqrD_ij < sqrD(i))
  89. {
  90. sqrD(i) = sqrD_ij;
  91. S(i) = s_ij;
  92. K.row(i) = k_ij;
  93. I(i) = j;
  94. }
  95. return sqrD_ij;
  96. };
  97. // This is expected (un)signed **unsquared** _distance. So let it compute
  98. // that in there. We will square it and acculumate our results in the lambda
  99. // anyway. So dist_i is ignored.
  100. Scalar dist_i;
  101. igl::eytzinger_aabb_sdf<true>(q,primitive_i,B1,B2,leaf,dist_i);
  102. },1000);
  103. }
  104. #ifdef IGL_STATIC_LIBRARY
  105. // Explicit template instantiation
  106. // generated by autoexplicit.sh
  107. template void igl::cycodebase::point_spline_squared_distance<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 2, 1, -1, 2>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>>(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1>> const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1>> const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1>> const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 2, 1, -1, 2>> const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 2, 1, -1, 2>> const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1>> const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1>>&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1>>&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1>>&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1>>&);
  108. // generated by autoexplicit.sh
  109. template void igl::cycodebase::point_spline_squared_distance<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>>(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1>> const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1>> const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1>> const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 1, -1, -1>> const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 1, -1, -1>> const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1>> const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1>>&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1>>&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1>>&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1>>&);
  110. template void igl::cycodebase::point_spline_squared_distance<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>>(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1>> const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1>> const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1>> const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1>>&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1>>&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1>>&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1>>&);
  111. #endif