SIGNIFICANT CHANGE
About the point to mesh distance functionalities Now the two different 'path' for this distance computation (with or without the precomputation of planes and edges for triangular faces) are well distinct and with different names: PointDistanceEP and PointDistanceBase See the sample/trimesh_closest sample for more details
This commit is contained in:
parent
58eced0506
commit
7ffb878913
|
@ -91,7 +91,7 @@ namespace vcg {
|
|||
// UGrid<MESH::FaceContainer >, ma non sono riuscito a definirlo implicitamente
|
||||
|
||||
template <class MESH, class GRID>
|
||||
typename MESH::FaceType * GetClosestFace( MESH & mesh, GRID & gr, const typename GRID::CoordType & _p,
|
||||
typename MESH::FaceType * GetClosestFaceEP( MESH & mesh, GRID & gr, const typename GRID::CoordType & _p,
|
||||
const typename GRID::ScalarType & _maxDist, typename GRID::ScalarType & _minDist,
|
||||
typename GRID::CoordType &_closestPt, typename GRID::CoordType & _normf,
|
||||
typename GRID::CoordType & _ip)
|
||||
|
@ -101,7 +101,7 @@ namespace vcg {
|
|||
|
||||
typedef FaceTmark<MESH> MarkerFace;
|
||||
MarkerFace mf(&mesh);
|
||||
vcg::face::PointDistanceFunctor<ScalarType> FDistFunct;
|
||||
vcg::face::PointDistanceEPFunctor<ScalarType> FDistFunct;
|
||||
_minDist=_maxDist;
|
||||
typename MESH::FaceType* bestf= gr.GetClosest(FDistFunct, mf, _p, _maxDist, _minDist, _closestPt);
|
||||
|
||||
|
@ -120,21 +120,8 @@ namespace vcg {
|
|||
return (0);
|
||||
}
|
||||
|
||||
/*template <class MESH, class GRID>
|
||||
typename MESH::FaceType * GetClosestFace( MESH & mesh,GRID & gr,const typename GRID::CoordType & _p,
|
||||
const typename GRID::ScalarType & _maxDist,typename GRID::ScalarType & _minDist,
|
||||
typename GRID::CoordType &_closestPt,typename GRID::CoordType & _normf)
|
||||
{
|
||||
Point3<typename GRID::ScalarType> _ip;
|
||||
typedef FaceTmark<MESH> MarkerFace;
|
||||
MarkerFace mf;
|
||||
mf.SetMesh(&mesh);
|
||||
vcg::face::PointDistanceFunctor FDistFunct;
|
||||
typename MESH::FaceType* bestf= gr.GetClosest(FDistFunct,mf,_p,_maxDist,_minDist,_closestPt) );
|
||||
}*/
|
||||
|
||||
template <class MESH, class GRID>
|
||||
typename MESH::FaceType * GetClosestFace( MESH & mesh,GRID & gr,const typename GRID::CoordType & _p,
|
||||
typename MESH::FaceType * GetClosestFaceBase( MESH & mesh,GRID & gr,const typename GRID::CoordType & _p,
|
||||
const typename GRID::ScalarType & _maxDist,typename GRID::ScalarType & _minDist,
|
||||
typename GRID::CoordType &_closestPt)
|
||||
{
|
||||
|
@ -143,7 +130,22 @@ namespace vcg {
|
|||
typedef FaceTmark<MESH> MarkerFace;
|
||||
MarkerFace mf;
|
||||
mf.SetMesh(&mesh);
|
||||
vcg::face::PointDistanceFunctor<ScalarType> PDistFunct;
|
||||
vcg::face::PointDistanceBaseFunctor<ScalarType> PDistFunct;
|
||||
_minDist=_maxDist;
|
||||
return (gr.GetClosest(PDistFunct,mf,_p,_maxDist,_minDist,_closestPt));
|
||||
}
|
||||
|
||||
template <class MESH, class GRID>
|
||||
typename MESH::FaceType * GetClosestFaceEP( MESH & mesh,GRID & gr,const typename GRID::CoordType & _p,
|
||||
const typename GRID::ScalarType & _maxDist,typename GRID::ScalarType & _minDist,
|
||||
typename GRID::CoordType &_closestPt)
|
||||
{
|
||||
typedef typename GRID::ScalarType ScalarType;
|
||||
typedef Point3<ScalarType> Point3x;
|
||||
typedef FaceTmark<MESH> MarkerFace;
|
||||
MarkerFace mf;
|
||||
mf.SetMesh(&mesh);
|
||||
vcg::face::PointDistanceEPFunctor<ScalarType> PDistFunct;
|
||||
_minDist=_maxDist;
|
||||
return (gr.GetClosest(PDistFunct,mf,_p,_maxDist,_minDist,_closestPt));
|
||||
}
|
||||
|
@ -214,14 +216,14 @@ namespace vcg {
|
|||
}
|
||||
|
||||
template <class MESH, class GRID, class OBJPTRCONTAINER,class DISTCONTAINER, class POINTCONTAINER>
|
||||
unsigned int GetKClosestFace(MESH & mesh,GRID & gr, const unsigned int _k,
|
||||
unsigned int GetKClosestFaceEP(MESH & mesh,GRID & gr, const unsigned int _k,
|
||||
const typename GRID::CoordType & _p, const typename GRID::ScalarType & _maxDist,
|
||||
OBJPTRCONTAINER & _objectPtrs,DISTCONTAINER & _distances, POINTCONTAINER & _points)
|
||||
{
|
||||
typedef FaceTmark<MESH> MarkerFace;
|
||||
MarkerFace mf;
|
||||
mf.SetMesh(&mesh);
|
||||
vcg::face::PointDistanceFunctor<typename MESH::ScalarType> FDistFunct;
|
||||
vcg::face::PointDistanceEPFunctor<typename MESH::ScalarType> FDistFunct;
|
||||
return (gr.GetKClosest /*<vcg::face::PointDistanceFunctor, MarkerFace,OBJPTRCONTAINER,DISTCONTAINER,POINTCONTAINER>*/
|
||||
(FDistFunct,mf,_k,_p,_maxDist,_objectPtrs,_distances,_points));
|
||||
}
|
||||
|
@ -256,7 +258,7 @@ namespace vcg {
|
|||
}
|
||||
|
||||
template <class MESH, class GRID, class OBJPTRCONTAINER, class DISTCONTAINER, class POINTCONTAINER>
|
||||
unsigned int GetInSphereFace(MESH & mesh,
|
||||
unsigned int GetInSphereFaceBase(MESH & mesh,
|
||||
GRID & gr,
|
||||
const typename GRID::CoordType & _p,
|
||||
const typename GRID::ScalarType & _r,
|
||||
|
@ -267,7 +269,7 @@ namespace vcg {
|
|||
typedef FaceTmark<MESH> MarkerFace;
|
||||
MarkerFace mf;
|
||||
mf.SetMesh(&mesh);
|
||||
typedef vcg::face::PointDistanceFunctor<typename MESH::ScalarType> FDistFunct;
|
||||
typedef vcg::face::PointDistanceBaseFunctor<typename MESH::ScalarType> FDistFunct;
|
||||
return (gr.GetInSphere/*<FDistFunct,MarkerFace,OBJPTRCONTAINER,DISTCONTAINER,POINTCONTAINER>*/
|
||||
(FDistFunct(),mf,_p,_r,_objectPtrs,_distances,_points));
|
||||
}
|
||||
|
@ -413,20 +415,20 @@ namespace vcg {
|
|||
//**ITERATORS DEFINITION**//
|
||||
|
||||
template <class GRID,class MESH>
|
||||
class ClosestFaceIterator:public vcg::ClosestIterator<GRID,
|
||||
vcg::face::PointDistanceFunctor<typename MESH::ScalarType>, FaceTmark<MESH> >
|
||||
class ClosestFaceEPIterator:public vcg::ClosestIterator<GRID,
|
||||
vcg::face::PointDistanceEPFunctor<typename MESH::ScalarType>, FaceTmark<MESH> >
|
||||
{
|
||||
public:
|
||||
typedef GRID GridType;
|
||||
typedef MESH MeshType;
|
||||
typedef FaceTmark<MESH> MarkerFace;
|
||||
typedef vcg::face::PointDistanceFunctor<typename MESH::ScalarType> PDistFunct;
|
||||
typedef vcg::face::PointDistanceEPFunctor<typename MESH::ScalarType> PDistFunct;
|
||||
typedef vcg::ClosestIterator<GRID,PDistFunct, FaceTmark<MESH> > ClosestBaseType;
|
||||
typedef typename MESH::FaceType FaceType;
|
||||
typedef typename MESH::ScalarType ScalarType;
|
||||
|
||||
//ClosestFaceIterator(GridType &_Si):ClosestBaseType(_Si,PDistFunct<FaceType,ScalarType>()){}
|
||||
ClosestFaceIterator(GridType &_Si):ClosestBaseType(_Si,PDistFunct()){}
|
||||
ClosestFaceEPIterator(GridType &_Si):ClosestBaseType(_Si,PDistFunct()){}
|
||||
|
||||
// Commented out: it seems unuseful and make gcc complain. p.
|
||||
void SetMesh(MeshType *m)
|
||||
|
|
|
@ -397,7 +397,7 @@ void IntersectionBallMesh( IndexingType * grid, TriMeshType & m, const vcg::Sph
|
|||
|
||||
if(tol == 0) tol = M_PI * ball.Radius() * ball.Radius() / 100000;
|
||||
|
||||
vcg::tri::GetInSphereFace(m,*grid, ball.Center(), ball.Radius(),closestsF,distances,witnesses);
|
||||
vcg::tri::GetInSphereFaceBase(m,*grid, ball.Center(), ball.Radius(),closestsF,distances,witnesses);
|
||||
for(cfi =closestsF.begin(); cfi != closestsF.end(); ++cfi)
|
||||
if(!(**cfi).IsD() && IntersectionSphereTriangle<ScalarType>(ball ,(**cfi), witness , &info))
|
||||
closests.push_back(&(**cfi));
|
||||
|
|
|
@ -19,42 +19,6 @@
|
|||
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) *
|
||||
* for more details. *
|
||||
* *
|
||||
****************************************************************************/
|
||||
/****************************************************************************
|
||||
History
|
||||
|
||||
$Log: not supported by cvs2svn $
|
||||
Revision 1.10 2006/01/22 10:06:23 cignoni
|
||||
Corrected use of Area with the unambiguous DoubleArea
|
||||
|
||||
Revision 1.9 2005/09/28 19:35:06 m_di_benedetto
|
||||
Added class PointDistanceFunctor.
|
||||
|
||||
Revision 1.8 2005/09/14 12:58:44 pietroni
|
||||
changed min calls to Min<ScalarType> of math.h of vcglib
|
||||
|
||||
Revision 1.7 2005/09/14 09:58:32 pietroni
|
||||
removed vcg::math::Min<ScalarType> definition generate warnings
|
||||
|
||||
Revision 1.6 2005/09/14 09:03:54 pietroni
|
||||
added definition of vcg::math::Min<ScalarType> function
|
||||
|
||||
Revision 1.5 2005/02/02 16:44:34 pietroni
|
||||
1 warning corrected added casting in const ScalarType EPSILON = ScalarType( 0.000001);
|
||||
|
||||
Revision 1.4 2005/01/28 12:00:33 cignoni
|
||||
small gcc compiling issues for namespaces
|
||||
|
||||
Revision 1.3 2005/01/24 15:35:25 cignoni
|
||||
Removed a 'using namespace'
|
||||
|
||||
Revision 1.2 2005/01/21 17:11:03 pietroni
|
||||
changed Dist Function to PointDistance... the function is on vcg::face::PointDistance this file will contain all distance functions between a face and othe entities
|
||||
|
||||
Revision 1.1 2004/05/12 18:50:25 ganovelli
|
||||
created
|
||||
|
||||
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __VCGLIB_FACE_DISTANCE
|
||||
|
@ -68,54 +32,36 @@ created
|
|||
namespace vcg {
|
||||
namespace face{
|
||||
/*
|
||||
Point face distance
|
||||
trova il punto <p> sulla faccia piu' vicino a <q>, con possibilit<EFBFBD> di
|
||||
rejection veloce su se la distanza trovata <EFBFBD> maggiore di <rejdist>
|
||||
Basic Wrapper for getting point-triangular face distance
|
||||
distance is unsigned;
|
||||
|
||||
Commenti del 12/11/02
|
||||
Funziona solo se la faccia e di quelle di tipo E (con edge e piano per faccia gia' calcolati)
|
||||
algoritmo:
|
||||
1) si calcola la proiezione <p> di q sul piano della faccia
|
||||
2) se la distanza punto piano e' > rejdist ritorna
|
||||
3) si lavora sul piano migliore e si cerca di capire se il punto sta dentro il triangolo:
|
||||
a) prodotto vettore tra edge triangolo (v[i+1]-v[i]) e (p-v[i])
|
||||
b) se il risultato e' negativo (gira in senso orario) allora il punto
|
||||
sta fuori da quella parte e si fa la distanza punto segmento.
|
||||
c) se il risultato sempre positivo allora sta dentro il triangolo
|
||||
4) e si restituisce la distanza punto /piano gia` calcolata
|
||||
return true if the closest point <q> on <f> is nearer than the passed <dist>;
|
||||
return false otherwiswe (and q is not valid)
|
||||
|
||||
Note sulla robustezza:
|
||||
il calcolo del prodotto vettore e` la cosa piu` delicata:
|
||||
possibili fallimenti quando a^b ~= 0
|
||||
1) doveva essere <= 0 e viene positivo (q era fuori o sulla linea dell'edge)
|
||||
allora capita che si faccia la distanza punto piano anziche` la distanza punto seg
|
||||
2) doveva essere > 0 e viene <=0 (q era dentro il triangolo)
|
||||
This wrapper requires that your face has
|
||||
- Per Face Flags well initialized
|
||||
- Per Face EdgePlane component initialized.
|
||||
Initialization must be done with:
|
||||
|
||||
*/
|
||||
tri::UpdateEdges<MeshType>::Set(yourMesh);
|
||||
*/
|
||||
template <class FaceType>
|
||||
bool PointDistance( const FaceType &f,
|
||||
bool PointDistanceEP( const FaceType &f,
|
||||
const vcg::Point3<typename FaceType::ScalarType> & q,
|
||||
typename FaceType::ScalarType & dist,
|
||||
vcg::Point3<typename FaceType::ScalarType> & p )
|
||||
{
|
||||
typedef typename FaceType::ScalarType ScalarType;
|
||||
|
||||
const ScalarType EPS = ScalarType( 0.000001);
|
||||
|
||||
//const ScalarType EPSILON = 0.00000001;
|
||||
ScalarType b,b0,b1,b2;
|
||||
// Calcolo distanza punto piano
|
||||
ScalarType d = SignedDistancePlanePoint( f.cPlane(), q );
|
||||
if( d>dist || d<-dist ) // Risultato peggiore: niente di fatto
|
||||
return false;
|
||||
|
||||
// Calcolo del punto sul piano
|
||||
// NOTA: aggiunto un '-d' in fondo Paolo C.
|
||||
ScalarType d = SignedDistancePlanePoint( f.cPlane(), q );
|
||||
if( d>dist || d<-dist ) return false;
|
||||
|
||||
Point3<ScalarType> t = f.cPlane().Direction();
|
||||
t[0] *= -d;
|
||||
t[1] *= -d;
|
||||
t[2] *= -d;
|
||||
p = q; p += t;
|
||||
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
|
||||
|
||||
switch( f.Flags() & (FaceType::NORMX|FaceType::NORMY|FaceType::NORMZ) )
|
||||
{
|
||||
|
@ -141,13 +87,8 @@ namespace vcg {
|
|||
if(dist>b2) { dist = b2; return true; }
|
||||
else return false;
|
||||
}
|
||||
// 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
|
||||
// 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'
|
||||
// vicini (come prodotto vettore)
|
||||
// Nota: si potrebbe rendere un pochino piu' veloce sostituendo Area()
|
||||
// con il prodotto vettore dei due edge in 2d lungo il piano migliore.
|
||||
// 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;
|
||||
|
@ -156,7 +97,6 @@ namespace vcg {
|
|||
else { assert(b==b2);
|
||||
bt = PSDist(q,f.V(0)->cP(),f.V(1)->cP(),p);
|
||||
}
|
||||
//printf("Warning area:%g %g %g %g thr:%g bt:%g\n",Area(), b0,b1,b2,EPS*Area(),bt);
|
||||
if(dist>bt) { dist = bt; return true; }
|
||||
else return false;
|
||||
}
|
||||
|
@ -192,7 +132,6 @@ namespace vcg {
|
|||
else { assert(b==b2);
|
||||
bt = PSDist(q,f.V(0)->cP(),f.V(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;
|
||||
}
|
||||
|
@ -228,22 +167,20 @@ namespace vcg {
|
|||
else { assert(b==b2);
|
||||
bt = PSDist(q,f.V(0)->cP(),f.V(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;
|
||||
|
||||
}
|
||||
} // end switch
|
||||
|
||||
dist = ScalarType(fabs(d));
|
||||
//dist = Distance(p,q);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class S>
|
||||
class PointDistanceFunctor {
|
||||
class PointDistanceEPFunctor {
|
||||
public:
|
||||
typedef S ScalarType;
|
||||
typedef Point3<ScalarType> QueryType;
|
||||
|
@ -254,7 +191,7 @@ namespace vcg {
|
|||
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 = PointDistance(f, fp, md, fq);
|
||||
const bool ret = PointDistanceEP(f, fp, md, fq);
|
||||
minDist = (SCALARTYPE)(md);
|
||||
q = Point3<SCALARTYPE>::Construct(fq);
|
||||
return (ret);
|
||||
|
@ -301,8 +238,6 @@ namespace vcg {
|
|||
|
||||
/// 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.
|
||||
/// it assumes that the face has Normalized Normal.
|
||||
// UpdateNormals::PerFaceNormalized(m)
|
||||
|
||||
template <class FaceType>
|
||||
bool PointDistanceBase(
|
||||
|
@ -312,12 +247,6 @@ namespace vcg {
|
|||
vcg::Point3<typename FaceType::ScalarType> & p )
|
||||
{
|
||||
typedef typename FaceType::ScalarType ScalarType;
|
||||
// remember that the macro NDEBUG is defined when you want to optimize a lot.
|
||||
#ifndef NDEBUG
|
||||
static int staticCnt=0; // small piece of code that sometime check that face normals are really normalized
|
||||
if((staticCnt++%100)==0)
|
||||
assert((f.cN().SquaredNorm() ==0) || (f.cN().SquaredNorm() > 0.9999 && f.cN().SquaredNorm()<1.0001)); // if you get this assert you have forgot to make a UpdateNormals::PerFaceNormalized(m)
|
||||
#endif
|
||||
|
||||
if(f.cN()==Point3<ScalarType>(0,0,0)) // to correctly manage the case of degenerate triangles we consider them as segments.
|
||||
{
|
||||
|
@ -340,7 +269,7 @@ namespace vcg {
|
|||
return true;
|
||||
}
|
||||
|
||||
Plane3<ScalarType> fPlane;
|
||||
Plane3<ScalarType,true> fPlane;
|
||||
fPlane.Init(f.cP(0),f.cN());
|
||||
const ScalarType EPS = ScalarType( 0.000001);
|
||||
ScalarType b,b0,b1,b2;
|
||||
|
@ -349,13 +278,8 @@ namespace vcg {
|
|||
if( d>dist || d<-dist ) // Risultato peggiore: niente di fatto
|
||||
return false;
|
||||
|
||||
// Calcolo del punto sul piano
|
||||
// NOTA: aggiunto un '-d' in fondo Paolo C.
|
||||
Point3<ScalarType> t = fPlane.Direction();
|
||||
t[0] *= -d;
|
||||
t[1] *= -d;
|
||||
t[2] *= -d;
|
||||
p = q; p += t;
|
||||
// Projection of query point onto the triangle plane
|
||||
p = q - fPlane.Direction()*d;
|
||||
|
||||
Point3<ScalarType> fEdge[3];
|
||||
fEdge[0] = f.cP(1); fEdge[0] -= f.cP(0);
|
||||
|
|
Loading…
Reference in New Issue