Removed warning. Changed a surely verified if condition into an assert.
(chosing the min between 3 elems we had a if-else chain where the last if was useless unless you have NAN )
This commit is contained in:
parent
1c1e3f778a
commit
a29df708da
|
@ -8,7 +8,7 @@
|
||||||
* \ *
|
* \ *
|
||||||
* All rights reserved. *
|
* All rights reserved. *
|
||||||
* *
|
* *
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
* it under the terms of the GNU General Public License as published by *
|
* it under the terms of the GNU General Public License as published by *
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
* (at your option) any later version. *
|
* (at your option) any later version. *
|
||||||
|
@ -30,7 +30,7 @@
|
||||||
#include <vcg/space/distance3.h>
|
#include <vcg/space/distance3.h>
|
||||||
|
|
||||||
namespace vcg {
|
namespace vcg {
|
||||||
namespace face{
|
namespace face{
|
||||||
/*
|
/*
|
||||||
Basic Wrapper for getting point-triangular face distance
|
Basic Wrapper for getting point-triangular face distance
|
||||||
distance is unsigned;
|
distance is unsigned;
|
||||||
|
@ -54,199 +54,199 @@ namespace vcg {
|
||||||
typedef typename FaceType::ScalarType ScalarType;
|
typedef typename FaceType::ScalarType ScalarType;
|
||||||
const ScalarType EPS = ScalarType( 0.000001);
|
const ScalarType EPS = ScalarType( 0.000001);
|
||||||
|
|
||||||
ScalarType b,b0,b1,b2;
|
ScalarType b,b0,b1,b2;
|
||||||
|
|
||||||
ScalarType d = SignedDistancePlanePoint( f.cPlane(), q );
|
ScalarType d = SignedDistancePlanePoint( f.cPlane(), q );
|
||||||
if( d>dist || d<-dist ) return false;
|
if( d>dist || d<-dist ) return false;
|
||||||
|
|
||||||
Point3<ScalarType> t = f.cPlane().Direction();
|
Point3<ScalarType> t = f.cPlane().Direction();
|
||||||
p = q - t*d; // p is the projection of q on the face plane
|
p = q - t*d; // p is the projection of q on the face plane
|
||||||
// Now Choose the best plane and test to see if p is inside the triangle
|
// Now Choose the best plane and test to see if p is inside the triangle
|
||||||
|
|
||||||
switch( f.cFlags() & (FaceType::NORMX|FaceType::NORMY|FaceType::NORMZ) )
|
|
||||||
{
|
|
||||||
case FaceType::NORMX:
|
|
||||||
b0 = f.cEdge(1)[1]*(p[2] - f.cP(1)[2]) - f.cEdge(1)[2]*(p[1] - f.cP(1)[1]);
|
|
||||||
if(b0<=0)
|
|
||||||
{
|
|
||||||
b0 = PSDist(q,f.cV(1)->cP(),f.cV(2)->cP(),p);
|
|
||||||
if(dist>b0) { dist = b0; return true; }
|
|
||||||
else return false;
|
|
||||||
}
|
|
||||||
b1 = f.cEdge(2)[1]*(p[2] - f.cP(2)[2]) - f.cEdge(2)[2]*(p[1] - f.cP(2)[1]);
|
|
||||||
if(b1<=0)
|
|
||||||
{
|
|
||||||
b1 = PSDist(q,f.cV(2)->cP(),f.cV(0)->cP(),p);
|
|
||||||
if(dist>b1) { dist = b1; return true; }
|
|
||||||
else return false;
|
|
||||||
}
|
|
||||||
b2 = f.cEdge(0)[1]*(p[2] - f.cP(0)[2]) - f.cEdge(0)[2]*(p[1] - f.cP(0)[1]);
|
|
||||||
if(b2<=0)
|
|
||||||
{
|
|
||||||
b2 = PSDist(q,f.cV(0)->cP(),f.cV(1)->cP(),p);
|
|
||||||
if(dist>b2) { dist = b2; return true; }
|
|
||||||
else return false;
|
|
||||||
}
|
|
||||||
// if all these tests failed the projection p should be inside.
|
|
||||||
// Some further tests for more robustness...
|
|
||||||
if( (b=std::min(b0,std::min(b1,b2)) ) < EPS*DoubleArea(f))
|
|
||||||
{
|
|
||||||
ScalarType bt;
|
|
||||||
if(b==b0) bt = PSDist(q,f.cV(1)->cP(),f.cV(2)->cP(),p);
|
|
||||||
else if(b==b1) bt = PSDist(q,f.cV(2)->cP(),f.cV(0)->cP(),p);
|
|
||||||
else { assert(b==b2);
|
|
||||||
bt = PSDist(q,f.cV(0)->cP(),f.cV(1)->cP(),p);
|
|
||||||
}
|
|
||||||
if(dist>bt) { dist = bt; return true; }
|
|
||||||
else return false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FaceType::NORMY:
|
switch( f.cFlags() & (FaceType::NORMX|FaceType::NORMY|FaceType::NORMZ) )
|
||||||
b0 = f.cEdge(1)[2]*(p[0] - f.cP(1)[0]) - f.cEdge(1)[0]*(p[2] - f.cP(1)[2]);
|
{
|
||||||
if(b0<=0)
|
case FaceType::NORMX:
|
||||||
{
|
b0 = f.cEdge(1)[1]*(p[2] - f.cP(1)[2]) - f.cEdge(1)[2]*(p[1] - f.cP(1)[1]);
|
||||||
b0 = PSDist(q,f.cV(1)->cP(),f.cV(2)->cP(),p);
|
if(b0<=0)
|
||||||
if(dist>b0) { dist = b0; return true; }
|
{
|
||||||
else return false;
|
b0 = PSDist(q,f.cV(1)->cP(),f.cV(2)->cP(),p);
|
||||||
}
|
if(dist>b0) { dist = b0; return true; }
|
||||||
b1 = f.cEdge(2)[2]*(p[0] - f.cP(2)[0]) - f.cEdge(2)[0]*(p[2] - f.cP(2)[2]);
|
else return false;
|
||||||
if(b1<=0)
|
}
|
||||||
{
|
b1 = f.cEdge(2)[1]*(p[2] - f.cP(2)[2]) - f.cEdge(2)[2]*(p[1] - f.cP(2)[1]);
|
||||||
b1 = PSDist(q,f.cV(2)->cP(),f.cV(0)->cP(),p);
|
if(b1<=0)
|
||||||
if(dist>b1) { dist = b1; return true; }
|
{
|
||||||
else return false;
|
b1 = PSDist(q,f.cV(2)->cP(),f.cV(0)->cP(),p);
|
||||||
}
|
if(dist>b1) { dist = b1; return true; }
|
||||||
b2 = f.cEdge(0)[2]*(p[0] - f.cP(0)[0]) - f.cEdge(0)[0]*(p[2] - f.cP(0)[2]);
|
else return false;
|
||||||
if(b2<=0)
|
}
|
||||||
{
|
b2 = f.cEdge(0)[1]*(p[2] - f.cP(0)[2]) - f.cEdge(0)[2]*(p[1] - f.cP(0)[1]);
|
||||||
b2 = PSDist(q,f.cV(0)->cP(),f.cV(1)->cP(),p);
|
if(b2<=0)
|
||||||
if(dist>b2) { dist = b2; return true; }
|
{
|
||||||
else return false;
|
b2 = PSDist(q,f.cV(0)->cP(),f.cV(1)->cP(),p);
|
||||||
}
|
if(dist>b2) { dist = b2; return true; }
|
||||||
if( (b=math::Min<ScalarType>(b0,b1,b2)) < EPS*DoubleArea(f))
|
else return false;
|
||||||
{
|
}
|
||||||
ScalarType bt;
|
// if all these tests failed the projection p should be inside.
|
||||||
if(b==b0) bt = PSDist(q,f.cV(1)->cP(),f.cV(2)->cP(),p);
|
// Some further tests for more robustness...
|
||||||
else if(b==b1) bt = PSDist(q,f.cV(2)->cP(),f.cV(0)->cP(),p);
|
if( (b=std::min(b0,std::min(b1,b2)) ) < EPS*DoubleArea(f))
|
||||||
else { assert(b==b2);
|
{
|
||||||
bt = PSDist(q,f.cV(0)->cP(),f.cV(1)->cP(),p);
|
ScalarType bt;
|
||||||
}
|
if(b==b0) bt = PSDist(q,f.cV(1)->cP(),f.cV(2)->cP(),p);
|
||||||
if(dist>bt) { dist = bt; return true; }
|
else if(b==b1) bt = PSDist(q,f.cV(2)->cP(),f.cV(0)->cP(),p);
|
||||||
else return false;
|
else { assert(b==b2);
|
||||||
}
|
bt = PSDist(q,f.cV(0)->cP(),f.cV(1)->cP(),p);
|
||||||
break;
|
}
|
||||||
|
if(dist>bt) { dist = bt; return true; }
|
||||||
|
else return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case FaceType::NORMZ:
|
case FaceType::NORMY:
|
||||||
b0 = f.cEdge(1)[0]*(p[1] - f.cP(1)[1]) - f.cEdge(1)[1]*(p[0] - f.cP(1)[0]);
|
b0 = f.cEdge(1)[2]*(p[0] - f.cP(1)[0]) - f.cEdge(1)[0]*(p[2] - f.cP(1)[2]);
|
||||||
if(b0<=0)
|
if(b0<=0)
|
||||||
{
|
{
|
||||||
b0 = PSDist(q,f.cV(1)->cP(),f.cV(2)->cP(),p);
|
b0 = PSDist(q,f.cV(1)->cP(),f.cV(2)->cP(),p);
|
||||||
if(dist>b0) { dist = b0; return true; }
|
if(dist>b0) { dist = b0; return true; }
|
||||||
else return false;
|
else return false;
|
||||||
}
|
}
|
||||||
b1 = f.cEdge(2)[0]*(p[1] - f.cP(2)[1]) - f.cEdge(2)[1]*(p[0] - f.cP(2)[0]);
|
b1 = f.cEdge(2)[2]*(p[0] - f.cP(2)[0]) - f.cEdge(2)[0]*(p[2] - f.cP(2)[2]);
|
||||||
if(b1<=0)
|
if(b1<=0)
|
||||||
{
|
{
|
||||||
b1 = PSDist(q,f.cV(2)->cP(),f.cV(0)->cP(),p);
|
b1 = PSDist(q,f.cV(2)->cP(),f.cV(0)->cP(),p);
|
||||||
if(dist>b1) { dist = b1; return true; }
|
if(dist>b1) { dist = b1; return true; }
|
||||||
else return false;
|
else return false;
|
||||||
}
|
}
|
||||||
b2 = f.cEdge(0)[0]*(p[1] - f.cP(0)[1]) - f.cEdge(0)[1]*(p[0] - f.cP(0)[0]);
|
b2 = f.cEdge(0)[2]*(p[0] - f.cP(0)[0]) - f.cEdge(0)[0]*(p[2] - f.cP(0)[2]);
|
||||||
if(b2<=0)
|
if(b2<=0)
|
||||||
{
|
{
|
||||||
b2 = PSDist(q,f.cV(0)->cP(),f.cV(1)->cP(),p);
|
b2 = PSDist(q,f.cV(0)->cP(),f.cV(1)->cP(),p);
|
||||||
if(dist>b2) { dist = b2; return true; }
|
if(dist>b2) { dist = b2; return true; }
|
||||||
else return false;
|
else return false;
|
||||||
}
|
}
|
||||||
if( (b=math::Min<ScalarType>(b0,b1,b2)) < EPS*DoubleArea(f))
|
if( (b=math::Min<ScalarType>(b0,b1,b2)) < EPS*DoubleArea(f))
|
||||||
{
|
{
|
||||||
ScalarType bt;
|
ScalarType bt;
|
||||||
if(b==b0) bt = PSDist(q,f.cV(1)->cP(),f.cV(2)->cP(),p);
|
if(b==b0) bt = PSDist(q,f.cV(1)->cP(),f.cV(2)->cP(),p);
|
||||||
else if(b==b1) bt = PSDist(q,f.cV(2)->cP(),f.cV(0)->cP(),p);
|
else if(b==b1) bt = PSDist(q,f.cV(2)->cP(),f.cV(0)->cP(),p);
|
||||||
else { assert(b==b2);
|
else { assert(b==b2);
|
||||||
bt = PSDist(q,f.cV(0)->cP(),f.cV(1)->cP(),p);
|
bt = PSDist(q,f.cV(0)->cP(),f.cV(1)->cP(),p);
|
||||||
}
|
}
|
||||||
|
if(dist>bt) { dist = bt; return true; }
|
||||||
|
else return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
if(dist>bt) { dist = bt; return true; }
|
case FaceType::NORMZ:
|
||||||
else return false;
|
b0 = f.cEdge(1)[0]*(p[1] - f.cP(1)[1]) - f.cEdge(1)[1]*(p[0] - f.cP(1)[0]);
|
||||||
}
|
if(b0<=0)
|
||||||
break;
|
{
|
||||||
|
b0 = PSDist(q,f.cV(1)->cP(),f.cV(2)->cP(),p);
|
||||||
|
if(dist>b0) { dist = b0; return true; }
|
||||||
|
else return false;
|
||||||
|
}
|
||||||
|
b1 = f.cEdge(2)[0]*(p[1] - f.cP(2)[1]) - f.cEdge(2)[1]*(p[0] - f.cP(2)[0]);
|
||||||
|
if(b1<=0)
|
||||||
|
{
|
||||||
|
b1 = PSDist(q,f.cV(2)->cP(),f.cV(0)->cP(),p);
|
||||||
|
if(dist>b1) { dist = b1; return true; }
|
||||||
|
else return false;
|
||||||
|
}
|
||||||
|
b2 = f.cEdge(0)[0]*(p[1] - f.cP(0)[1]) - f.cEdge(0)[1]*(p[0] - f.cP(0)[0]);
|
||||||
|
if(b2<=0)
|
||||||
|
{
|
||||||
|
b2 = PSDist(q,f.cV(0)->cP(),f.cV(1)->cP(),p);
|
||||||
|
if(dist>b2) { dist = b2; return true; }
|
||||||
|
else return false;
|
||||||
|
}
|
||||||
|
if( (b=math::Min<ScalarType>(b0,b1,b2)) < EPS*DoubleArea(f))
|
||||||
|
{
|
||||||
|
ScalarType bt;
|
||||||
|
if(b==b0) bt = PSDist(q,f.cV(1)->cP(),f.cV(2)->cP(),p);
|
||||||
|
else if(b==b1) bt = PSDist(q,f.cV(2)->cP(),f.cV(0)->cP(),p);
|
||||||
|
else { assert(b==b2);
|
||||||
|
bt = PSDist(q,f.cV(0)->cP(),f.cV(1)->cP(),p);
|
||||||
|
}
|
||||||
|
|
||||||
} // end switch
|
if(dist>bt) { dist = bt; return true; }
|
||||||
|
else return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
dist = ScalarType(fabs(d));
|
} // end switch
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class S>
|
dist = ScalarType(fabs(d));
|
||||||
class PointDistanceEPFunctor {
|
return true;
|
||||||
public:
|
}
|
||||||
typedef S ScalarType;
|
|
||||||
typedef Point3<ScalarType> QueryType;
|
|
||||||
static inline const Point3<ScalarType> & Pos(const QueryType & qt) {return qt;}
|
|
||||||
|
|
||||||
template <class FACETYPE, class SCALARTYPE>
|
template <class S>
|
||||||
inline bool operator () (const FACETYPE & f, const Point3<SCALARTYPE> & p, SCALARTYPE & minDist, Point3<SCALARTYPE> & q) {
|
class PointDistanceEPFunctor {
|
||||||
const Point3<typename FACETYPE::ScalarType> fp = Point3<typename FACETYPE::ScalarType>::Construct(p);
|
public:
|
||||||
Point3<typename FACETYPE::ScalarType> fq;
|
typedef S ScalarType;
|
||||||
typename FACETYPE::ScalarType md = (typename FACETYPE::ScalarType)(minDist);
|
typedef Point3<ScalarType> QueryType;
|
||||||
const bool ret = PointDistanceEP(f, fp, md, fq);
|
static inline const Point3<ScalarType> & Pos(const QueryType & qt) {return qt;}
|
||||||
minDist = (SCALARTYPE)(md);
|
|
||||||
q = Point3<SCALARTYPE>::Construct(fq);
|
template <class FACETYPE, class SCALARTYPE>
|
||||||
return (ret);
|
inline bool operator () (const FACETYPE & f, const Point3<SCALARTYPE> & p, SCALARTYPE & minDist, Point3<SCALARTYPE> & q) {
|
||||||
}
|
const Point3<typename FACETYPE::ScalarType> fp = Point3<typename FACETYPE::ScalarType>::Construct(p);
|
||||||
};
|
Point3<typename FACETYPE::ScalarType> fq;
|
||||||
|
typename FACETYPE::ScalarType md = (typename FACETYPE::ScalarType)(minDist);
|
||||||
|
const bool ret = PointDistanceEP(f, fp, md, fq);
|
||||||
|
minDist = (SCALARTYPE)(md);
|
||||||
|
q = Point3<SCALARTYPE>::Construct(fq);
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template <class S>
|
template <class S>
|
||||||
class PointNormalDistanceFunctor {
|
class PointNormalDistanceFunctor {
|
||||||
public:
|
public:
|
||||||
typedef typename S::ScalarType ScalarType;
|
typedef typename S::ScalarType ScalarType;
|
||||||
typedef S QueryType;
|
typedef S QueryType;
|
||||||
static inline const Point3<ScalarType> & Pos(const QueryType & qt) {return qt.P();}
|
static inline const Point3<ScalarType> & Pos(const QueryType & qt) {return qt.P();}
|
||||||
|
|
||||||
|
|
||||||
static ScalarType & Alpha(){static ScalarType alpha = 1.0; return alpha;}
|
static ScalarType & Alpha(){static ScalarType alpha = 1.0; return alpha;}
|
||||||
static ScalarType & Beta (){static ScalarType beta = 1.0; return beta;}
|
static ScalarType & Beta (){static ScalarType beta = 1.0; return beta;}
|
||||||
static ScalarType & Gamma(){static ScalarType gamma = 1.0; return gamma;}
|
static ScalarType & Gamma(){static ScalarType gamma = 1.0; return gamma;}
|
||||||
static ScalarType & InterPoint(){static ScalarType interpoint= 1.0; return interpoint;}
|
static ScalarType & InterPoint(){static ScalarType interpoint= 1.0; return interpoint;}
|
||||||
|
|
||||||
|
|
||||||
template <class FACETYPE, class SCALARTYPE>
|
template <class FACETYPE, class SCALARTYPE>
|
||||||
inline bool operator () (const FACETYPE &f, const typename FACETYPE::VertexType &p,
|
inline bool operator () (const FACETYPE &f, const typename FACETYPE::VertexType &p,
|
||||||
SCALARTYPE & minDist,Point3<SCALARTYPE> & q)
|
SCALARTYPE & minDist,Point3<SCALARTYPE> & q)
|
||||||
{
|
{
|
||||||
const Point3<typename FACETYPE::ScalarType> fp = Point3<typename FACETYPE::ScalarType>::Construct(p.cP());
|
const Point3<typename FACETYPE::ScalarType> fp = Point3<typename FACETYPE::ScalarType>::Construct(p.cP());
|
||||||
const Point3<typename FACETYPE::ScalarType> fn = Point3<typename FACETYPE::ScalarType>::Construct(p.cN());
|
const Point3<typename FACETYPE::ScalarType> fn = Point3<typename FACETYPE::ScalarType>::Construct(p.cN());
|
||||||
Point3<typename FACETYPE::ScalarType> fq;
|
Point3<typename FACETYPE::ScalarType> fq;
|
||||||
typename FACETYPE::ScalarType md = (typename FACETYPE::ScalarType)(minDist);
|
typename FACETYPE::ScalarType md = (typename FACETYPE::ScalarType)(minDist);
|
||||||
const bool ret=PointDistance(f,fp,md,fq);
|
const bool ret=PointDistance(f,fp,md,fq);
|
||||||
|
|
||||||
SCALARTYPE dev=InterPoint()*(pow((ScalarType)(1-f.cN().dot(fn)),(ScalarType)Beta())/(Gamma()*md+0.1));
|
SCALARTYPE dev=InterPoint()*(pow((ScalarType)(1-f.cN().dot(fn)),(ScalarType)Beta())/(Gamma()*md+0.1));
|
||||||
|
|
||||||
if (md+dev < minDist){
|
if (md+dev < minDist){
|
||||||
minDist = (SCALARTYPE)(md+dev);
|
minDist = (SCALARTYPE)(md+dev);
|
||||||
q = Point3<SCALARTYPE>::Construct(fq);
|
q = Point3<SCALARTYPE>::Construct(fq);
|
||||||
//q.N() = f.N();
|
//q.N() = f.N();
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// BASIC VERSION of the Point-face distance that does not require the EdgePlane Additional data.
|
/// BASIC VERSION of the Point-face distance that does not require the EdgePlane Additional data.
|
||||||
/// Given a face and a point, returns the closest point of the face to p.
|
/// Given a face and a point, returns the closest point of the face to p.
|
||||||
|
|
||||||
template <class FaceType>
|
template <class FaceType>
|
||||||
bool PointDistanceBase(
|
bool PointDistanceBase(
|
||||||
const FaceType &f, /// the face to be tested
|
const FaceType &f, /// the face to be tested
|
||||||
const vcg::Point3<typename FaceType::ScalarType> & q, /// the point tested
|
const vcg::Point3<typename FaceType::ScalarType> & q, /// the point tested
|
||||||
typename FaceType::ScalarType & dist, /// bailout distance. It must be initialized with the max admittable value.
|
typename FaceType::ScalarType & dist, /// bailout distance. It must be initialized with the max admittable value.
|
||||||
vcg::Point3<typename FaceType::ScalarType> & p )
|
vcg::Point3<typename FaceType::ScalarType> & p )
|
||||||
{
|
{
|
||||||
typedef typename FaceType::ScalarType ScalarType;
|
typedef typename FaceType::ScalarType ScalarType;
|
||||||
|
|
||||||
if(f.cN()==Point3<ScalarType>(0,0,0)) // to correctly manage the case of degenerate triangles we consider them as segments.
|
if(f.cN()==Point3<ScalarType>(0,0,0)) // to correctly manage the case of degenerate triangles we consider them as segments.
|
||||||
{
|
{
|
||||||
|
@ -269,200 +269,200 @@ namespace vcg {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Plane3<ScalarType,true> fPlane;
|
Plane3<ScalarType,true> fPlane;
|
||||||
fPlane.Init(f.cP(0),f.cN());
|
fPlane.Init(f.cP(0),f.cN());
|
||||||
const ScalarType EPS = ScalarType( 0.000001);
|
const ScalarType EPS = ScalarType( 0.000001);
|
||||||
ScalarType b,b0,b1,b2;
|
ScalarType b,b0,b1,b2;
|
||||||
// Calcolo distanza punto piano
|
// Calcolo distanza punto piano
|
||||||
ScalarType d = SignedDistancePlanePoint( fPlane, q );
|
ScalarType d = SignedDistancePlanePoint( fPlane, q );
|
||||||
if( d>dist || d<-dist ) // Risultato peggiore: niente di fatto
|
if( d>dist || d<-dist ) // Risultato peggiore: niente di fatto
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Projection of query point onto the triangle plane
|
|
||||||
p = q - fPlane.Direction()*d;
|
|
||||||
|
|
||||||
Point3<ScalarType> fEdge[3];
|
// Projection of query point onto the triangle plane
|
||||||
fEdge[0] = f.cP(1); fEdge[0] -= f.cP(0);
|
p = q - fPlane.Direction()*d;
|
||||||
fEdge[1] = f.cP(2); fEdge[1] -= f.cP(1);
|
|
||||||
fEdge[2] = f.cP(0); fEdge[2] -= f.cP(2);
|
|
||||||
|
|
||||||
/*
|
|
||||||
This piece of code is part of the EdgePlane initialization structure: note that the edges are scaled!.
|
|
||||||
|
|
||||||
if(nx>ny && nx>nz) { f.Flags() |= FaceType::NORMX; d = 1/f.Plane().Direction()[0]; }
|
|
||||||
else if(ny>nz) { f.Flags() |= FaceType::NORMY; d = 1/f.Plane().Direction()[1]; }
|
|
||||||
else { f.Flags() |= FaceType::NORMZ; d = 1/f.Plane().Direction()[2]; }
|
|
||||||
f.Edge(0)*=d; f.Edge(1)*=d;f.Edge(2)*=d;
|
|
||||||
|
|
||||||
So we must apply the same scaling according to the plane orientation, eg in the case of NORMX
|
|
||||||
scaleFactor= 1/fPlane.Direction()[0];
|
|
||||||
fEdge[0]*=d; fEdge[1]*=d;fEdge[2]*=d;
|
|
||||||
*/
|
|
||||||
|
|
||||||
int bestAxis;
|
Point3<ScalarType> fEdge[3];
|
||||||
if(fabs(f.cN()[0])>fabs(f.cN()[1]))
|
fEdge[0] = f.cP(1); fEdge[0] -= f.cP(0);
|
||||||
{
|
fEdge[1] = f.cP(2); fEdge[1] -= f.cP(1);
|
||||||
if(fabs(f.cN()[0])>fabs(f.cN()[2])) bestAxis = 0;
|
fEdge[2] = f.cP(0); fEdge[2] -= f.cP(2);
|
||||||
else bestAxis = 2;
|
|
||||||
} else {
|
|
||||||
if(fabs(f.cN()[1])>fabs(f.cN()[2])) bestAxis=1; /* 1 > 0 ? 2 */
|
|
||||||
else bestAxis=2; /* 2 > 1 ? 2 */
|
|
||||||
}
|
|
||||||
|
|
||||||
ScalarType scaleFactor;
|
/*
|
||||||
|
This piece of code is part of the EdgePlane initialization structure: note that the edges are scaled!.
|
||||||
|
|
||||||
switch( bestAxis )
|
if(nx>ny && nx>nz) { f.Flags() |= FaceType::NORMX; d = 1/f.Plane().Direction()[0]; }
|
||||||
{
|
else if(ny>nz) { f.Flags() |= FaceType::NORMY; d = 1/f.Plane().Direction()[1]; }
|
||||||
case 0: /************* X AXIS **************/
|
else { f.Flags() |= FaceType::NORMZ; d = 1/f.Plane().Direction()[2]; }
|
||||||
scaleFactor= 1/fPlane.Direction()[0];
|
f.Edge(0)*=d; f.Edge(1)*=d;f.Edge(2)*=d;
|
||||||
fEdge[0]*=scaleFactor; fEdge[1]*=scaleFactor; fEdge[2]*=scaleFactor;
|
|
||||||
|
So we must apply the same scaling according to the plane orientation, eg in the case of NORMX
|
||||||
b0 = fEdge[1][1]*(p[2] - f.cP(1)[2]) - fEdge[1][2]*(p[1] - f.cP(1)[1]);
|
scaleFactor= 1/fPlane.Direction()[0];
|
||||||
if(b0<=0)
|
fEdge[0]*=d; fEdge[1]*=d;fEdge[2]*=d;
|
||||||
{
|
*/
|
||||||
b0 = PSDist(q,f.cV(1)->cP(),f.cV(2)->cP(),p);
|
|
||||||
if(dist>b0) { dist = b0; return true; }
|
int bestAxis;
|
||||||
else return false;
|
if(fabs(f.cN()[0])>fabs(f.cN()[1]))
|
||||||
}
|
{
|
||||||
b1 = fEdge[2][1]*(p[2] - f.cP(2)[2]) - fEdge[2][2]*(p[1] - f.cP(2)[1]);
|
if(fabs(f.cN()[0])>fabs(f.cN()[2])) bestAxis = 0;
|
||||||
if(b1<=0)
|
else bestAxis = 2;
|
||||||
{
|
} else {
|
||||||
b1 = PSDist(q,f.cV(2)->cP(),f.cV(0)->cP(),p);
|
if(fabs(f.cN()[1])>fabs(f.cN()[2])) bestAxis=1; /* 1 > 0 ? 2 */
|
||||||
if(dist>b1) { dist = b1; return true; }
|
else bestAxis=2; /* 2 > 1 ? 2 */
|
||||||
else return false;
|
}
|
||||||
}
|
|
||||||
b2 = fEdge[0][1]*(p[2] - f.cP(0)[2]) - fEdge[0][2]*(p[1] - f.cP(0)[1]);
|
ScalarType scaleFactor;
|
||||||
if(b2<=0)
|
|
||||||
{
|
switch( bestAxis )
|
||||||
b2 = PSDist(q,f.cV(0)->cP(),f.cV(1)->cP(),p);
|
{
|
||||||
if(dist>b2) { dist = b2; return true; }
|
case 0: /************* X AXIS **************/
|
||||||
else return false;
|
scaleFactor= 1/fPlane.Direction()[0];
|
||||||
}
|
fEdge[0]*=scaleFactor; fEdge[1]*=scaleFactor; fEdge[2]*=scaleFactor;
|
||||||
// sono tutti e tre > 0 quindi dovrebbe essere dentro;
|
|
||||||
// per sicurezza se il piu' piccolo dei tre e' < epsilon (scalato rispetto all'area della faccia
|
b0 = fEdge[1][1]*(p[2] - f.cP(1)[2]) - fEdge[1][2]*(p[1] - f.cP(1)[1]);
|
||||||
// per renderlo dimension independent.) allora si usa ancora la distanza punto
|
if(b0<=0)
|
||||||
// segmento che e' piu robusta della punto piano, e si fa dalla parte a cui siamo piu'
|
{
|
||||||
// vicini (come prodotto vettore)
|
b0 = PSDist(q,f.cV(1)->cP(),f.cV(2)->cP(),p);
|
||||||
// Nota: si potrebbe rendere un pochino piu' veloce sostituendo Area()
|
if(dist>b0) { dist = b0; return true; }
|
||||||
// con il prodotto vettore dei due edge in 2d lungo il piano migliore.
|
else return false;
|
||||||
if( (b=vcg::math::Min<ScalarType>(b0,b1,b2)) < EPS*DoubleArea(f))
|
}
|
||||||
{
|
b1 = fEdge[2][1]*(p[2] - f.cP(2)[2]) - fEdge[2][2]*(p[1] - f.cP(2)[1]);
|
||||||
ScalarType bt;
|
if(b1<=0)
|
||||||
if(b==b0) bt = PSDist(q,f.cV(1)->cP(),f.cV(2)->cP(),p);
|
{
|
||||||
else if(b==b1) bt = PSDist(q,f.cV(2)->cP(),f.cV(0)->cP(),p);
|
b1 = PSDist(q,f.cV(2)->cP(),f.cV(0)->cP(),p);
|
||||||
else if(b==b2) bt = PSDist(q,f.cV(0)->cP(),f.cV(1)->cP(),p);
|
if(dist>b1) { dist = b1; return true; }
|
||||||
//printf("Warning area:%g %g %g %g thr:%g bt:%g\n",Area(), b0,b1,b2,EPSILON*Area(),bt);
|
else return false;
|
||||||
if(dist>bt) { dist = bt; return true; }
|
}
|
||||||
else return false;
|
b2 = fEdge[0][1]*(p[2] - f.cP(0)[2]) - fEdge[0][2]*(p[1] - f.cP(0)[1]);
|
||||||
}
|
if(b2<=0)
|
||||||
break;
|
{
|
||||||
|
b2 = PSDist(q,f.cV(0)->cP(),f.cV(1)->cP(),p);
|
||||||
case 1: /************* Y AXIS **************/
|
if(dist>b2) { dist = b2; return true; }
|
||||||
scaleFactor= 1/fPlane.Direction()[1];
|
else return false;
|
||||||
fEdge[0]*=scaleFactor; fEdge[1]*=scaleFactor; fEdge[2]*=scaleFactor;
|
}
|
||||||
|
// sono tutti e tre > 0 quindi dovrebbe essere dentro;
|
||||||
b0 = fEdge[1][2]*(p[0] - f.cP(1)[0]) - fEdge[1][0]*(p[2] - f.cP(1)[2]);
|
// per sicurezza se il piu' piccolo dei tre e' < epsilon (scalato rispetto all'area della faccia
|
||||||
if(b0<=0)
|
// per renderlo dimension independent.) allora si usa ancora la distanza punto
|
||||||
{
|
// segmento che e' piu robusta della punto piano, e si fa dalla parte a cui siamo piu'
|
||||||
b0 = PSDist(q,f.cV(1)->cP(),f.cV(2)->cP(),p);
|
// vicini (come prodotto vettore)
|
||||||
if(dist>b0) { dist = b0; return true; }
|
// Nota: si potrebbe rendere un pochino piu' veloce sostituendo Area()
|
||||||
else return false;
|
// con il prodotto vettore dei due edge in 2d lungo il piano migliore.
|
||||||
}
|
if( (b=vcg::math::Min<ScalarType>(b0,b1,b2)) < EPS*DoubleArea(f))
|
||||||
b1 = fEdge[2][2]*(p[0] - f.cP(2)[0]) - fEdge[2][0]*(p[2] - f.cP(2)[2]);
|
{
|
||||||
if(b1<=0)
|
ScalarType bt;
|
||||||
{
|
if(b==b0) bt = PSDist(q,f.cV(1)->cP(),f.cV(2)->cP(),p);
|
||||||
b1 = PSDist(q,f.cV(2)->cP(),f.cV(0)->cP(),p);
|
else if(b==b1) bt = PSDist(q,f.cV(2)->cP(),f.cV(0)->cP(),p);
|
||||||
if(dist>b1) { dist = b1; return true; }
|
else {assert(b==b2); bt = PSDist(q,f.cV(0)->cP(),f.cV(1)->cP(),p);}
|
||||||
else return false;
|
//printf("Warning area:%g %g %g %g thr:%g bt:%g\n",Area(), b0,b1,b2,EPSILON*Area(),bt);
|
||||||
}
|
if(dist>bt) { dist = bt; return true; }
|
||||||
b2 = fEdge[0][2]*(p[0] - f.cP(0)[0]) - fEdge[0][0]*(p[2] - f.cP(0)[2]);
|
else return false;
|
||||||
if(b2<=0)
|
}
|
||||||
{
|
break;
|
||||||
b2 = PSDist(q,f.cV(0)->cP(),f.cV(1)->cP(),p);
|
|
||||||
if(dist>b2) { dist = b2; return true; }
|
case 1: /************* Y AXIS **************/
|
||||||
else return false;
|
scaleFactor= 1/fPlane.Direction()[1];
|
||||||
}
|
fEdge[0]*=scaleFactor; fEdge[1]*=scaleFactor; fEdge[2]*=scaleFactor;
|
||||||
|
|
||||||
|
b0 = fEdge[1][2]*(p[0] - f.cP(1)[0]) - fEdge[1][0]*(p[2] - f.cP(1)[2]);
|
||||||
|
if(b0<=0)
|
||||||
|
{
|
||||||
|
b0 = PSDist(q,f.cV(1)->cP(),f.cV(2)->cP(),p);
|
||||||
|
if(dist>b0) { dist = b0; return true; }
|
||||||
|
else return false;
|
||||||
|
}
|
||||||
|
b1 = fEdge[2][2]*(p[0] - f.cP(2)[0]) - fEdge[2][0]*(p[2] - f.cP(2)[2]);
|
||||||
|
if(b1<=0)
|
||||||
|
{
|
||||||
|
b1 = PSDist(q,f.cV(2)->cP(),f.cV(0)->cP(),p);
|
||||||
|
if(dist>b1) { dist = b1; return true; }
|
||||||
|
else return false;
|
||||||
|
}
|
||||||
|
b2 = fEdge[0][2]*(p[0] - f.cP(0)[0]) - fEdge[0][0]*(p[2] - f.cP(0)[2]);
|
||||||
|
if(b2<=0)
|
||||||
|
{
|
||||||
|
b2 = PSDist(q,f.cV(0)->cP(),f.cV(1)->cP(),p);
|
||||||
|
if(dist>b2) { dist = b2; return true; }
|
||||||
|
else return false;
|
||||||
|
}
|
||||||
if( (b=vcg::math::Min<ScalarType>(b0,b1,b2)) < EPS*DoubleArea(f))
|
if( (b=vcg::math::Min<ScalarType>(b0,b1,b2)) < EPS*DoubleArea(f))
|
||||||
{
|
{
|
||||||
ScalarType bt;
|
ScalarType bt;
|
||||||
if(b==b0) bt = PSDist(q,f.cV(1)->cP(),f.cV(2)->cP(),p);
|
if(b==b0) bt = PSDist(q,f.cV(1)->cP(),f.cV(2)->cP(),p);
|
||||||
else if(b==b1) bt = PSDist(q,f.cV(2)->cP(),f.cV(0)->cP(),p);
|
else if(b==b1) bt = PSDist(q,f.cV(2)->cP(),f.cV(0)->cP(),p);
|
||||||
else if(b==b2) bt = PSDist(q,f.cV(0)->cP(),f.cV(1)->cP(),p);
|
else{ assert(b==b2); bt = PSDist(q,f.cV(0)->cP(),f.cV(1)->cP(),p);}
|
||||||
//printf("Warning area:%g %g %g %g thr:%g bt:%g\n",Area(), b0,b1,b2,EPSILON*Area(),bt);
|
//printf("Warning area:%g %g %g %g thr:%g bt:%g\n",Area(), b0,b1,b2,EPSILON*Area(),bt);
|
||||||
if(dist>bt) { dist = bt; return true; }
|
if(dist>bt) { dist = bt; return true; }
|
||||||
else return false;
|
else return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2: /************* Z AXIS **************/
|
|
||||||
scaleFactor= 1/fPlane.Direction()[2];
|
|
||||||
fEdge[0]*=scaleFactor; fEdge[1]*=scaleFactor; fEdge[2]*=scaleFactor;
|
|
||||||
|
|
||||||
b0 = fEdge[1][0]*(p[1] - f.cP(1)[1]) - fEdge[1][1]*(p[0] - f.cP(1)[0]);
|
|
||||||
if(b0<=0)
|
|
||||||
{
|
|
||||||
b0 = PSDist(q,f.cV(1)->cP(),f.cV(2)->cP(),p);
|
|
||||||
if(dist>b0) { dist = b0; return true; }
|
|
||||||
else return false;
|
|
||||||
}
|
|
||||||
b1 = fEdge[2][0]*(p[1] - f.cP(2)[1]) - fEdge[2][1]*(p[0] - f.cP(2)[0]);
|
|
||||||
if(b1<=0)
|
|
||||||
{
|
|
||||||
b1 = PSDist(q,f.cV(2)->cP(),f.cV(0)->cP(),p);
|
|
||||||
if(dist>b1) { dist = b1; return true; }
|
|
||||||
else return false;
|
|
||||||
}
|
|
||||||
b2 = fEdge[0][0]*(p[1] - f.cP(0)[1]) - fEdge[0][1]*(p[0] - f.cP(0)[0]);
|
|
||||||
if(b2<=0)
|
|
||||||
{
|
|
||||||
b2 = PSDist(q,f.cV(0)->cP(),f.cV(1)->cP(),p);
|
|
||||||
if(dist>b2) { dist = b2; return true; }
|
|
||||||
else return false;
|
|
||||||
}
|
|
||||||
if( (b=vcg::math::Min<ScalarType>(b0,b1,b2)) < EPS*DoubleArea(f))
|
|
||||||
{
|
|
||||||
ScalarType bt;
|
|
||||||
if(b==b0) bt = PSDist(q,f.cV(1)->cP(),f.cV(2)->cP(),p);
|
|
||||||
else if(b==b1) bt = PSDist(q,f.cV(2)->cP(),f.cV(0)->cP(),p);
|
|
||||||
else if(b==b2) bt = PSDist(q,f.cV(0)->cP(),f.cV(1)->cP(),p);
|
|
||||||
//printf("Warning area:%g %g %g %g thr:%g bt:%g\n",Area(), b0,b1,b2,EPSILON*Area(),bt);
|
|
||||||
|
|
||||||
if(dist>bt) { dist = bt; return true; }
|
|
||||||
else return false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default: assert(0); // if you get this assert it means that you forgot to set the required UpdateFlags<MeshType>::FaceProjection(m);
|
|
||||||
|
|
||||||
}
|
case 2: /************* Z AXIS **************/
|
||||||
|
scaleFactor= 1/fPlane.Direction()[2];
|
||||||
dist = ScalarType(fabs(d));
|
fEdge[0]*=scaleFactor; fEdge[1]*=scaleFactor; fEdge[2]*=scaleFactor;
|
||||||
//dist = Distance(p,q);
|
|
||||||
return true;
|
b0 = fEdge[1][0]*(p[1] - f.cP(1)[1]) - fEdge[1][1]*(p[0] - f.cP(1)[0]);
|
||||||
}
|
if(b0<=0)
|
||||||
|
{
|
||||||
template <class S>
|
b0 = PSDist(q,f.cV(1)->cP(),f.cV(2)->cP(),p);
|
||||||
class PointDistanceBaseFunctor {
|
if(dist>b0) { dist = b0; return true; }
|
||||||
|
else return false;
|
||||||
|
}
|
||||||
|
b1 = fEdge[2][0]*(p[1] - f.cP(2)[1]) - fEdge[2][1]*(p[0] - f.cP(2)[0]);
|
||||||
|
if(b1<=0)
|
||||||
|
{
|
||||||
|
b1 = PSDist(q,f.cV(2)->cP(),f.cV(0)->cP(),p);
|
||||||
|
if(dist>b1) { dist = b1; return true; }
|
||||||
|
else return false;
|
||||||
|
}
|
||||||
|
b2 = fEdge[0][0]*(p[1] - f.cP(0)[1]) - fEdge[0][1]*(p[0] - f.cP(0)[0]);
|
||||||
|
if(b2<=0)
|
||||||
|
{
|
||||||
|
b2 = PSDist(q,f.cV(0)->cP(),f.cV(1)->cP(),p);
|
||||||
|
if(dist>b2) { dist = b2; return true; }
|
||||||
|
else return false;
|
||||||
|
}
|
||||||
|
if( (b=vcg::math::Min<ScalarType>(b0,b1,b2)) < EPS*DoubleArea(f))
|
||||||
|
{
|
||||||
|
ScalarType bt;
|
||||||
|
if(b==b0) bt = PSDist(q,f.cV(1)->cP(),f.cV(2)->cP(),p);
|
||||||
|
else if(b==b1) bt = PSDist(q,f.cV(2)->cP(),f.cV(0)->cP(),p);
|
||||||
|
else { assert(b==b2); bt = PSDist(q,f.cV(0)->cP(),f.cV(1)->cP(),p); }
|
||||||
|
//printf("Warning area:%g %g %g %g thr:%g bt:%g\n",Area(), b0,b1,b2,EPSILON*Area(),bt);
|
||||||
|
|
||||||
|
if(dist>bt) { dist = bt; return true; }
|
||||||
|
else return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default: assert(0); // if you get this assert it means that you forgot to set the required UpdateFlags<MeshType>::FaceProjection(m);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
dist = ScalarType(fabs(d));
|
||||||
|
//dist = Distance(p,q);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class S>
|
||||||
|
class PointDistanceBaseFunctor {
|
||||||
public:
|
public:
|
||||||
typedef S ScalarType;
|
typedef S ScalarType;
|
||||||
typedef Point3<ScalarType> QueryType;
|
typedef Point3<ScalarType> QueryType;
|
||||||
|
|
||||||
|
static inline const Point3<ScalarType> & Pos(const Point3<ScalarType> & qt) {return qt;}
|
||||||
|
template <class FACETYPE, class SCALARTYPE>
|
||||||
|
inline bool operator () (const FACETYPE & f, const Point3<SCALARTYPE> & p, SCALARTYPE & minDist, Point3<SCALARTYPE> & q) {
|
||||||
|
const Point3<typename FACETYPE::ScalarType> fp = Point3<typename FACETYPE::ScalarType>::Construct(p);
|
||||||
|
Point3<typename FACETYPE::ScalarType> fq;
|
||||||
|
typename FACETYPE::ScalarType md = (typename FACETYPE::ScalarType)(minDist);
|
||||||
|
const bool ret = PointDistanceBase(f, fp, md, fq);
|
||||||
|
minDist = (SCALARTYPE)(md);
|
||||||
|
q = Point3<SCALARTYPE>::Construct(fq);
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static inline const Point3<ScalarType> & Pos(const Point3<ScalarType> & qt) {return qt;}
|
|
||||||
template <class FACETYPE, class SCALARTYPE>
|
|
||||||
inline bool operator () (const FACETYPE & f, const Point3<SCALARTYPE> & p, SCALARTYPE & minDist, Point3<SCALARTYPE> & q) {
|
|
||||||
const Point3<typename FACETYPE::ScalarType> fp = Point3<typename FACETYPE::ScalarType>::Construct(p);
|
|
||||||
Point3<typename FACETYPE::ScalarType> fq;
|
|
||||||
typename FACETYPE::ScalarType md = (typename FACETYPE::ScalarType)(minDist);
|
|
||||||
const bool ret = PointDistanceBase(f, fp, md, fq);
|
|
||||||
minDist = (SCALARTYPE)(md);
|
|
||||||
q = Point3<SCALARTYPE>::Construct(fq);
|
|
||||||
return (ret);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // end namespace face
|
} // end namespace face
|
||||||
|
|
||||||
} // end namespace vcg
|
} // end namespace vcg
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue