|
|
@@ -9,14 +9,29 @@
|
|
|
#include "AABB.h"
|
|
|
#include <cassert>
|
|
|
|
|
|
+namespace
|
|
|
+{
|
|
|
+ // Sigh. This is a somewhat elaborate way of making
|
|
|
+ // igl::point_mesh_squared_distance build a correctly dimensioned AABB tree
|
|
|
+ // regardless of whether it has #columns known at compile time or not.
|
|
|
+ //
|
|
|
+ // The pattern below uses a class which can be partially specialized on
|
|
|
+ // whether columns are dynamic. For each case, we call this helper function at
|
|
|
+ // the top which has a known dimension as an extra template argument.
|
|
|
+ //
|
|
|
+ // In this case, the _code_ for the 2D and 3D cases is the same, so we avoid
|
|
|
+ // duplicating lines of code that only differ in the dimension. The cost
|
|
|
+ // appears to be spelling out _all_ of the template types over and over again
|
|
|
+ // making this all harder to parse.
|
|
|
template <
|
|
|
+ int DIM,
|
|
|
typename DerivedP,
|
|
|
typename DerivedV,
|
|
|
typename DerivedEle,
|
|
|
typename DerivedsqrD,
|
|
|
typename DerivedI,
|
|
|
typename DerivedC>
|
|
|
-IGL_INLINE void igl::point_mesh_squared_distance(
|
|
|
+IGL_INLINE void point_mesh_squared_distance(
|
|
|
const Eigen::MatrixBase<DerivedP> & P,
|
|
|
const Eigen::MatrixBase<DerivedV> & V,
|
|
|
const Eigen::MatrixBase<DerivedEle> & Ele,
|
|
|
@@ -24,28 +39,107 @@ IGL_INLINE void igl::point_mesh_squared_distance(
|
|
|
Eigen::PlainObjectBase<DerivedI> & I,
|
|
|
Eigen::PlainObjectBase<DerivedC> & C)
|
|
|
{
|
|
|
- using namespace std;
|
|
|
- const size_t dim = P.cols();
|
|
|
- assert((dim == 2 || dim == 3) && "P.cols() should be 2 or 3");
|
|
|
- assert(P.cols() == V.cols() && "P.cols() should equal V.cols()");
|
|
|
- switch(dim)
|
|
|
+ static_assert(DIM == 2 || DIM == 3, "DIM must be 2 or 3");
|
|
|
+ // Common code for 2D and 3D
|
|
|
+ igl::AABB<DerivedV, DIM> tree;
|
|
|
+ tree.init(V,Ele);
|
|
|
+ tree.squared_distance(V,Ele,P,sqrD,I,C);
|
|
|
+}
|
|
|
+
|
|
|
+// Class whose templates can be specialized on whether V has dynamic columns or
|
|
|
+// not.
|
|
|
+template <
|
|
|
+ typename DerivedP,
|
|
|
+ typename DerivedV,
|
|
|
+ typename DerivedEle,
|
|
|
+ typename DerivedsqrD,
|
|
|
+ typename DerivedI,
|
|
|
+ typename DerivedC,
|
|
|
+ bool DynamicCols>
|
|
|
+struct DIM_Handler;
|
|
|
+
|
|
|
+// Handle the case where V has dynamic columns
|
|
|
+template <
|
|
|
+ typename DerivedP,
|
|
|
+ typename DerivedV,
|
|
|
+ typename DerivedEle,
|
|
|
+ typename DerivedsqrD,
|
|
|
+ typename DerivedI,
|
|
|
+ typename DerivedC>
|
|
|
+struct DIM_Handler<
|
|
|
+ DerivedP, DerivedV, DerivedEle, DerivedsqrD, DerivedI, DerivedC,
|
|
|
+ true>
|
|
|
+{
|
|
|
+ static void compute(
|
|
|
+ const Eigen::MatrixBase<DerivedP> & P,
|
|
|
+ const Eigen::MatrixBase<DerivedV> & V,
|
|
|
+ const Eigen::MatrixBase<DerivedEle> & Ele,
|
|
|
+ Eigen::PlainObjectBase<DerivedsqrD> & sqrD,
|
|
|
+ Eigen::PlainObjectBase<DerivedI> & I,
|
|
|
+ Eigen::PlainObjectBase<DerivedC> & C)
|
|
|
{
|
|
|
- default:
|
|
|
- assert(false && "Unsupported dim");
|
|
|
- // fall-through and pray
|
|
|
- case 3:
|
|
|
+ if(V.cols() == 2)
|
|
|
{
|
|
|
- AABB<DerivedV,3> tree;
|
|
|
- tree.init(V,Ele);
|
|
|
- return tree.squared_distance(V,Ele,P,sqrD,I,C);
|
|
|
- }
|
|
|
- case 2:
|
|
|
+ point_mesh_squared_distance<2>(P,V,Ele,sqrD,I,C);
|
|
|
+ }else if(V.cols() == 3)
|
|
|
+ {
|
|
|
+ point_mesh_squared_distance<3>(P,V,Ele,sqrD,I,C);
|
|
|
+ }else
|
|
|
{
|
|
|
- AABB<DerivedV,2> tree;
|
|
|
- tree.init(V,Ele);
|
|
|
- return tree.squared_distance(V,Ele,P,sqrD,I,C);
|
|
|
+ assert(false && "V must be 2D or 3D");
|
|
|
}
|
|
|
}
|
|
|
+};
|
|
|
+
|
|
|
+// Handle the case where V has fixed size columns
|
|
|
+template <
|
|
|
+ typename DerivedP,
|
|
|
+ typename DerivedV,
|
|
|
+ typename DerivedEle,
|
|
|
+ typename DerivedsqrD,
|
|
|
+ typename DerivedI,
|
|
|
+ typename DerivedC>
|
|
|
+struct DIM_Handler<
|
|
|
+ DerivedP, DerivedV, DerivedEle, DerivedsqrD, DerivedI, DerivedC,
|
|
|
+ false>
|
|
|
+{
|
|
|
+ static void compute(
|
|
|
+ const Eigen::MatrixBase<DerivedP> & P,
|
|
|
+ const Eigen::MatrixBase<DerivedV> & V,
|
|
|
+ const Eigen::MatrixBase<DerivedEle> & Ele,
|
|
|
+ Eigen::PlainObjectBase<DerivedsqrD> & sqrD,
|
|
|
+ Eigen::PlainObjectBase<DerivedI> & I,
|
|
|
+ Eigen::PlainObjectBase<DerivedC> & C)
|
|
|
+ {
|
|
|
+ static_assert(DerivedV::ColsAtCompileTime == 2 || DerivedV::ColsAtCompileTime == 3, "V must be 2D or 3D");
|
|
|
+ point_mesh_squared_distance<DerivedV::ColsAtCompileTime>(P,V,Ele,sqrD,I,C);
|
|
|
+ }
|
|
|
+};
|
|
|
+}
|
|
|
+
|
|
|
+template <
|
|
|
+ typename DerivedP,
|
|
|
+ typename DerivedV,
|
|
|
+ typename DerivedEle,
|
|
|
+ typename DerivedsqrD,
|
|
|
+ typename DerivedI,
|
|
|
+ typename DerivedC>
|
|
|
+IGL_INLINE void igl::point_mesh_squared_distance(
|
|
|
+ const Eigen::MatrixBase<DerivedP> & P,
|
|
|
+ const Eigen::MatrixBase<DerivedV> & V,
|
|
|
+ const Eigen::MatrixBase<DerivedEle> & Ele,
|
|
|
+ Eigen::PlainObjectBase<DerivedsqrD> & sqrD,
|
|
|
+ Eigen::PlainObjectBase<DerivedI> & I,
|
|
|
+ Eigen::PlainObjectBase<DerivedC> & C)
|
|
|
+{
|
|
|
+ DIM_Handler<
|
|
|
+ DerivedP,
|
|
|
+ DerivedV,
|
|
|
+ DerivedEle,
|
|
|
+ DerivedsqrD,
|
|
|
+ DerivedI,
|
|
|
+ DerivedC,
|
|
|
+ DerivedV::ColsAtCompileTime == Eigen::Dynamic>::compute(P,V,Ele,sqrD,I,C);
|
|
|
}
|
|
|
|
|
|
#ifdef IGL_STATIC_LIBRARY
|