|
|
@@ -13,6 +13,7 @@
|
|
|
#include "per_vertex_normals.h"
|
|
|
#include "point_mesh_squared_distance.h"
|
|
|
#include "pseudonormal_test.h"
|
|
|
+#include "fast_winding_number.h"
|
|
|
|
|
|
|
|
|
template <
|
|
|
@@ -37,10 +38,17 @@ IGL_INLINE void igl::signed_distance(
|
|
|
{
|
|
|
using namespace Eigen;
|
|
|
using namespace std;
|
|
|
+
|
|
|
const int dim = V.cols();
|
|
|
+
|
|
|
assert((V.cols() == 3||V.cols() == 2) && "V should have 3d or 2d positions");
|
|
|
assert((P.cols() == 3||P.cols() == 2) && "P should have 3d or 2d positions");
|
|
|
assert(V.cols() == P.cols() && "V should have same dimension as P");
|
|
|
+
|
|
|
+ if (sign_type == SIGNED_DISTANCE_TYPE_FAST_WINDING_NUMBER){
|
|
|
+ assert(V.cols() == 3 && "V should be 3D for fast winding number");
|
|
|
+ }
|
|
|
+
|
|
|
// Only unsigned distance is supported for non-triangles
|
|
|
if(sign_type != SIGNED_DISTANCE_TYPE_UNSIGNED)
|
|
|
{
|
|
|
@@ -67,6 +75,9 @@ IGL_INLINE void igl::signed_distance(
|
|
|
Eigen::Matrix<typename DerivedF::Scalar,Eigen::Dynamic,2> E;
|
|
|
Eigen::Matrix<typename DerivedF::Scalar,Eigen::Dynamic,1> EMAP;
|
|
|
WindingNumberAABB<RowVector3S,DerivedV,DerivedF> hier3;
|
|
|
+ igl::FastWindingNumberBVH fwn_bvh;
|
|
|
+ Eigen::VectorXf W;
|
|
|
+
|
|
|
switch(sign_type)
|
|
|
{
|
|
|
default:
|
|
|
@@ -88,6 +99,10 @@ IGL_INLINE void igl::signed_distance(
|
|
|
break;
|
|
|
}
|
|
|
break;
|
|
|
+ case SIGNED_DISTANCE_TYPE_FAST_WINDING_NUMBER:
|
|
|
+ // assert above ensures dim == 3
|
|
|
+ igl::fast_winding_number(V.template cast<float>().eval(), F, 2, fwn_bvh);
|
|
|
+
|
|
|
case SIGNED_DISTANCE_TYPE_PSEUDONORMAL:
|
|
|
switch(dim)
|
|
|
{
|
|
|
@@ -187,6 +202,14 @@ IGL_INLINE void igl::signed_distance(
|
|
|
}
|
|
|
break;
|
|
|
}
|
|
|
+ case SIGNED_DISTANCE_TYPE_FAST_WINDING_NUMBER:
|
|
|
+ {
|
|
|
+ //assert above ensured 3D
|
|
|
+ Scalar w = fast_winding_number(fwn_bvh, 2, q3.template cast<float>().eval());
|
|
|
+ s = 1.-2.*std::abs(w);
|
|
|
+
|
|
|
+ break;
|
|
|
+ }
|
|
|
case SIGNED_DISTANCE_TYPE_PSEUDONORMAL:
|
|
|
{
|
|
|
RowVector3S n3;
|
|
|
@@ -439,7 +462,6 @@ IGL_INLINE void igl::signed_distance_winding_number(
|
|
|
using namespace std;
|
|
|
typedef Eigen::Matrix<typename DerivedV::Scalar,1,2> RowVector2S;
|
|
|
sqrd = tree.squared_distance(V,F,RowVector2S(q),i,(RowVector2S&)c);
|
|
|
- Scalar w;
|
|
|
// TODO: using .data() like this is very dangerous... This is assuming
|
|
|
// colmajor order
|
|
|
assert(!V.derived().IsRowMajor);
|
|
|
@@ -447,6 +469,55 @@ IGL_INLINE void igl::signed_distance_winding_number(
|
|
|
s = 1.-2.*winding_number(V,F,q);
|
|
|
}
|
|
|
|
|
|
+//Multi point by parrallel for on single point
|
|
|
+template <
|
|
|
+ typename DerivedP,
|
|
|
+ typename DerivedV,
|
|
|
+ typename DerivedF,
|
|
|
+ typename DerivedS>
|
|
|
+IGL_INLINE void igl::signed_distance_fast_winding_number(
|
|
|
+ const Eigen::MatrixBase<DerivedP> & P,
|
|
|
+ const Eigen::MatrixBase<DerivedV> & V,
|
|
|
+ const Eigen::MatrixBase<DerivedF> & F,
|
|
|
+ const AABB<DerivedV,3> & tree,
|
|
|
+ const igl::FastWindingNumberBVH & fwn_bvh,
|
|
|
+ Eigen::PlainObjectBase<DerivedS> & S)
|
|
|
+ {
|
|
|
+ typedef Eigen::Matrix<typename DerivedV::Scalar,1,3> RowVector3S;
|
|
|
+ S.resize(P.rows(),1);
|
|
|
+ int min_parallel = 10000;
|
|
|
+ parallel_for(P.rows(), [&](const int p)
|
|
|
+ {
|
|
|
+ RowVector3S q;
|
|
|
+ q.head(P.row(p).size()) = P.row(p);
|
|
|
+ // get sdf for single point, update result matrix
|
|
|
+ S(p) = signed_distance_fast_winding_number(q, V, F, tree,fwn_bvh);
|
|
|
+ }
|
|
|
+ ,min_parallel);
|
|
|
+ }
|
|
|
+
|
|
|
+//Single Point
|
|
|
+template <
|
|
|
+ typename Derivedq,
|
|
|
+ typename DerivedV,
|
|
|
+ typename DerivedF>
|
|
|
+IGL_INLINE typename DerivedV::Scalar igl::signed_distance_fast_winding_number(
|
|
|
+ const Eigen::MatrixBase<Derivedq> & q,
|
|
|
+ const Eigen::MatrixBase<DerivedV> & V,
|
|
|
+ const Eigen::MatrixBase<DerivedF> & F,
|
|
|
+ const AABB<DerivedV,3> & tree,
|
|
|
+ const igl::FastWindingNumberBVH & fwn_bvh)
|
|
|
+ {
|
|
|
+ typedef typename DerivedV::Scalar Scalar;
|
|
|
+ Scalar s,sqrd;
|
|
|
+ Eigen::Matrix<Scalar,1,3> c;
|
|
|
+ int i = -1;
|
|
|
+ sqrd = tree.squared_distance(V,F,q,i,c);
|
|
|
+ Scalar w = fast_winding_number(fwn_bvh,2,q.template cast<float>());
|
|
|
+ //0.5 is on surface
|
|
|
+ return sqrt(sqrd)*(1.-2.*std::abs(w));
|
|
|
+ }
|
|
|
+
|
|
|
#ifdef IGL_STATIC_LIBRARY
|
|
|
// Explicit template instantiation
|
|
|
// generated by autoexplicit.sh
|
|
|
@@ -463,4 +534,5 @@ template void igl::signed_distance_pseudonormal<Eigen::Matrix<double, -1, -1, 0,
|
|
|
template void igl::signed_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&, igl::SignedDistanceType, 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> >&);
|
|
|
template void igl::signed_distance_winding_number<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, double, Eigen::Matrix<double, 1, 3, 1, 1, 3> >(igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3> const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::WindingNumberAABB<Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, double&, double&, int&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&);
|
|
|
template Eigen::Matrix<double, -1, -1, 0, -1, -1>::Scalar igl::signed_distance_winding_number<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, 3, 1, 0, 3, 1> >(igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3> const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::WindingNumberAABB<Eigen::Matrix<double, 3, 1, 0, 3, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 3, 1, 0, 3, 1> > const&);
|
|
|
+template void igl::signed_distance_fast_winding_number<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::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&, igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3> const&, igl::FastWindingNumberBVH const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
|
|
|
#endif
|