point_mesh_squared_distance.cpp 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2014 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 "point_mesh_squared_distance.h"
  9. #include "AABB.h"
  10. #include <cassert>
  11. namespace
  12. {
  13. // Sigh. This is a somewhat elaborate way of making
  14. // igl::point_mesh_squared_distance build a correctly dimensioned AABB tree
  15. // regardless of whether it has #columns known at compile time or not.
  16. //
  17. // The pattern below uses a class which can be partially specialized on
  18. // whether columns are dynamic. For each case, we call this helper function at
  19. // the top which has a known dimension as an extra template argument.
  20. //
  21. // In this case, the _code_ for the 2D and 3D cases is the same, so we avoid
  22. // duplicating lines of code that only differ in the dimension. The cost
  23. // appears to be spelling out _all_ of the template types over and over again
  24. // making this all harder to parse.
  25. template <
  26. int DIM,
  27. typename DerivedP,
  28. typename DerivedV,
  29. typename DerivedEle,
  30. typename DerivedsqrD,
  31. typename DerivedI,
  32. typename DerivedC>
  33. IGL_INLINE void point_mesh_squared_distance(
  34. const Eigen::MatrixBase<DerivedP> & P,
  35. const Eigen::MatrixBase<DerivedV> & V,
  36. const Eigen::MatrixBase<DerivedEle> & Ele,
  37. Eigen::PlainObjectBase<DerivedsqrD> & sqrD,
  38. Eigen::PlainObjectBase<DerivedI> & I,
  39. Eigen::PlainObjectBase<DerivedC> & C)
  40. {
  41. static_assert(DIM == 2 || DIM == 3, "DIM must be 2 or 3");
  42. // Common code for 2D and 3D
  43. igl::AABB<DerivedV, DIM> tree;
  44. tree.init(V,Ele);
  45. tree.squared_distance(V,Ele,P,sqrD,I,C);
  46. }
  47. // Class whose templates can be specialized on whether V has dynamic columns or
  48. // not.
  49. template <
  50. typename DerivedP,
  51. typename DerivedV,
  52. typename DerivedEle,
  53. typename DerivedsqrD,
  54. typename DerivedI,
  55. typename DerivedC,
  56. bool DynamicCols>
  57. struct point_mesh_squared_distance_DIM_Handler;
  58. // Handle the case where V has dynamic columns
  59. template <
  60. typename DerivedP,
  61. typename DerivedV,
  62. typename DerivedEle,
  63. typename DerivedsqrD,
  64. typename DerivedI,
  65. typename DerivedC>
  66. struct point_mesh_squared_distance_DIM_Handler<
  67. DerivedP, DerivedV, DerivedEle, DerivedsqrD, DerivedI, DerivedC,
  68. true>
  69. {
  70. static void compute(
  71. const Eigen::MatrixBase<DerivedP> & P,
  72. const Eigen::MatrixBase<DerivedV> & V,
  73. const Eigen::MatrixBase<DerivedEle> & Ele,
  74. Eigen::PlainObjectBase<DerivedsqrD> & sqrD,
  75. Eigen::PlainObjectBase<DerivedI> & I,
  76. Eigen::PlainObjectBase<DerivedC> & C)
  77. {
  78. if(V.cols() == 2)
  79. {
  80. point_mesh_squared_distance<2>(P,V,Ele,sqrD,I,C);
  81. }else if(V.cols() == 3)
  82. {
  83. point_mesh_squared_distance<3>(P,V,Ele,sqrD,I,C);
  84. }else
  85. {
  86. assert(false && "V must be 2D or 3D");
  87. }
  88. }
  89. };
  90. // Handle the case where V has fixed size columns
  91. template <
  92. typename DerivedP,
  93. typename DerivedV,
  94. typename DerivedEle,
  95. typename DerivedsqrD,
  96. typename DerivedI,
  97. typename DerivedC>
  98. struct point_mesh_squared_distance_DIM_Handler<
  99. DerivedP, DerivedV, DerivedEle, DerivedsqrD, DerivedI, DerivedC,
  100. false>
  101. {
  102. static void compute(
  103. const Eigen::MatrixBase<DerivedP> & P,
  104. const Eigen::MatrixBase<DerivedV> & V,
  105. const Eigen::MatrixBase<DerivedEle> & Ele,
  106. Eigen::PlainObjectBase<DerivedsqrD> & sqrD,
  107. Eigen::PlainObjectBase<DerivedI> & I,
  108. Eigen::PlainObjectBase<DerivedC> & C)
  109. {
  110. constexpr int DIM =
  111. DerivedP::ColsAtCompileTime != Eigen::Dynamic ? DerivedP::ColsAtCompileTime :
  112. DerivedV::ColsAtCompileTime != Eigen::Dynamic ? DerivedV::ColsAtCompileTime :
  113. DerivedC::ColsAtCompileTime != Eigen::Dynamic ? DerivedC::ColsAtCompileTime :
  114. Eigen::Dynamic;
  115. static_assert(DIM == 2 || DIM == 3, "DIM must be 2 or 3");
  116. point_mesh_squared_distance<DIM>(P,V,Ele,sqrD,I,C);
  117. }
  118. };
  119. }
  120. template <
  121. typename DerivedP,
  122. typename DerivedV,
  123. typename DerivedEle,
  124. typename DerivedsqrD,
  125. typename DerivedI,
  126. typename DerivedC>
  127. IGL_INLINE void igl::point_mesh_squared_distance(
  128. const Eigen::MatrixBase<DerivedP> & P,
  129. const Eigen::MatrixBase<DerivedV> & V,
  130. const Eigen::MatrixBase<DerivedEle> & Ele,
  131. Eigen::PlainObjectBase<DerivedsqrD> & sqrD,
  132. Eigen::PlainObjectBase<DerivedI> & I,
  133. Eigen::PlainObjectBase<DerivedC> & C)
  134. {
  135. constexpr int DIM =
  136. DerivedP::ColsAtCompileTime != Eigen::Dynamic ? DerivedP::ColsAtCompileTime :
  137. DerivedV::ColsAtCompileTime != Eigen::Dynamic ? DerivedV::ColsAtCompileTime :
  138. DerivedC::ColsAtCompileTime != Eigen::Dynamic ? DerivedC::ColsAtCompileTime :
  139. Eigen::Dynamic;
  140. point_mesh_squared_distance_DIM_Handler<
  141. DerivedP,
  142. DerivedV,
  143. DerivedEle,
  144. DerivedsqrD,
  145. DerivedI,
  146. DerivedC,
  147. DIM == Eigen::Dynamic>::compute(P,V,Ele,sqrD,I,C);
  148. }
  149. #ifdef IGL_STATIC_LIBRARY
  150. template void igl::point_mesh_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::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>> &);
  151. template void igl::point_mesh_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::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> >&);
  152. template void igl::point_mesh_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<long, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 3, 0, -1, 3> >(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<long, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);
  153. template void igl::point_mesh_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::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> >&);
  154. template void igl::point_mesh_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::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> >&);
  155. #ifdef WIN32
  156. template void igl::point_mesh_squared_distance<class Eigen::Matrix<double, -1, -1, 0, -1, -1>, class Eigen::Matrix<double, -1, -1, 0, -1, -1>, class Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, class Eigen::Matrix<__int64, -1, 1, 0, -1, 1>, class Eigen::Matrix<double, -1, 3, 0, -1, 3>>(class Eigen::MatrixBase<class Eigen::Matrix<double, -1, -1, 0, -1, -1>> const &, class Eigen::MatrixBase<class Eigen::Matrix<double, -1, -1, 0, -1, -1>> const &, class Eigen::MatrixBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<double, -1, 1, 0, -1, 1>> &, class Eigen::PlainObjectBase<class Eigen::Matrix<__int64, -1, 1, 0, -1, 1>> &, class Eigen::PlainObjectBase<class Eigen::Matrix<double, -1, 3, 0, -1, 3>> &);
  157. template void igl::point_mesh_squared_distance<class Eigen::Matrix<double, -1, -1, 0, -1, -1>, class Eigen::Matrix<double, -1, -1, 0, -1, -1>, class Eigen::Matrix<int, -1, -1, 0, -1, -1>, class Eigen::Matrix<double, -1, 1, 0, -1, 1>, class Eigen::Matrix<__int64, -1, 1, 0, -1, 1>, class Eigen::Matrix<double, -1, 3, 0, -1, 3>>(class Eigen::MatrixBase<class Eigen::Matrix<double, -1, -1, 0, -1, -1>> const &, class Eigen::MatrixBase<class Eigen::Matrix<double, -1, -1, 0, -1, -1>> const &, class Eigen::MatrixBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<double, -1, 1, 0, -1, 1>> &, class Eigen::PlainObjectBase<class Eigen::Matrix<__int64, -1, 1, 0, -1, 1>> &, class Eigen::PlainObjectBase<class Eigen::Matrix<double, -1, 3, 0, -1, 3>> &);
  158. #endif
  159. #endif