added wrapping to functions defined in GridClosest:

- GetClosest
     - GetKClosest
     - DoRay
This commit is contained in:
Nico Pietroni 2005-09-30 13:15:21 +00:00
parent 6416a20ba2
commit a3c311feda
2 changed files with 160 additions and 225 deletions

View File

@ -24,6 +24,10 @@
History
$Log: not supported by cvs2svn $
Revision 1.25 2005/09/21 09:22:51 pietroni
removed closest functions. Closest function is now on index\\Closest.h
Users must use trimesh\\closest.h to perform spatial query.
Revision 1.24 2005/09/16 11:57:15 cignoni
Removed two wrong typenames
@ -114,6 +118,7 @@ Initial commit
#include <vcg/space/box3.h>
#include <vcg/space/line3.h>
#include <vcg/space/index/grid_util.h>
#include <vcg/space/index/grid_closest.h>
#include <vcg/simplex/face/distance.h>
namespace vcg {
@ -149,18 +154,17 @@ namespace vcg {
point of the object to point)
*/
template < typename ContainerType,class FLT=float >
class GridStaticPtr:public BasicGrid<FLT>
template < typename OBJTYPE,class FLT=float >
class GridStaticPtr:public BasicGrid<OBJTYPE,FLT>
{
public:
typedef typename ContainerType::value_type ObjType;
typedef OBJTYPE ObjType;
typedef ObjType* ObjPtr;
typedef typename ObjType::ScalarType ScalarType;
typedef Point3<ScalarType> CoordType;
typedef Box3<ScalarType> Box3x;
typedef Line3<ScalarType> Line3x;
typedef typename GridStaticPtr<OBJTYPE,FLT> GridPtrType;
/** Internal class for keeping the first pointer of object.
Definizione Link dentro la griglia. Classe di supporto per GridStaticObj.
@ -328,185 +332,38 @@ namespace vcg {
}
///** Returns the closest posistion of a point p and its distance
//@param p a 3d point
//@param max_dist maximum distance not to search beyond.
//@param dist_funct (templated type) a functor object used to calculate distance from a grid object to the point p.
//@param min_dist the returned closest distance
//@param res the returned closest point
//@return The closest element
//*/
///*
// A DISTFUNCT object must implement an operator () with signature:
// bool operator () (const ObjType& obj, const CoordType & p, ScalarType & min_dist, CoordType & res);
//*/
//template <class DISTFUNCTOR,class TMARKER>
// ObjPtr GetClosest( const CoordType & p, const ScalarType & max_dist, DISTFUNCTOR & dist_funct, ScalarType & min_dist, CoordType & res,TMARKER tm)
//{
// // Initialize min_dist with max_dist to exploit early rejection test.
// min_dist = max_dist;
// ScalarType dx = ( (p[0]-bbox.min[0])/voxel[0] );
// ScalarType dy = ( (p[1]-bbox.min[1])/voxel[1] );
// ScalarType dz = ( (p[2]-bbox.min[2])/voxel[2] );
// int ix = int( dx );
// int iy = int( dy );
// int iz = int( dz );
// if (!bbox.IsIn(p))
// assert (0);///the grid has to be extended until the point
// double voxel_min=voxel[0];
// if (voxel_min<voxel[1]) voxel_min=voxel[1];
// if (voxel_min<voxel[2]) voxel_min=voxel[2];
// ScalarType radius=(dx-ScalarType(ix));
// if (radius>0.5) radius=(1.0-radius); radius*=voxel[0];
// ScalarType tmp=dy-ScalarType(iy);
// if (tmp>0.5) tmp=1.0-tmp;
// tmp*=voxel[1];
// if (radius>tmp) radius=tmp;
// tmp=dz-ScalarType(iz);
// if (tmp>0.5) tmp=1.0-tmp;
// tmp*=voxel[2];
// if (radius>tmp) radius=tmp;
// CoordType t_res;
// //ScalarType min_dist=1e10;
// ObjPtr winner=NULL;
// tm.UnMarkAll();
// Link *first, *last;
// Link *l;
// if ((ix>=0) && (iy>=0) && (iz>=0) &&
// (ix<siz[0]) && (iy<siz[1]) && (iz<siz[2])) {
// Grid( ix, iy, iz, first, last );
// for(l=first;l!=last;++l)
// if (!(**l).IsD())
// {
// if( ! tm.IsMarked(l->Elem()))
// {
// //if (!l->Elem()->IsD() && l->Elem()->Dist(p,min_dist,t_res)) {
// //if (!l->Elem()->IsD() && dist_funct(*(l->Elem()), p, min_dist, t_res)) { // <-- NEW: use of distance functor
// if (dist_funct((**l), p, min_dist, t_res)) // <-- NEW: use of distance functor
// {
// winner=l->Elem();
// res=t_res;
// }
// tm.Mark(l->Elem());
// }
// }
// };
// //return winner;
// Point3i done_min=Point3i(ix,iy,iz), done_max=Point3i(ix,iy,iz);
// //printf(".");
// while (min_dist>radius) {
// //if (dy-ScalarType(iy))
// done_min[0]--; if (done_min[0]<0) done_min[0]=0;
// done_min[1]--; if (done_min[1]<0) done_min[1]=0;
// done_min[2]--; if (done_min[2]<0) done_min[2]=0;
// done_max[0]++; if (done_max[0]>=siz[0]-1) done_max[0]=siz[0]-1;
// done_max[1]++; if (done_max[1]>=siz[1]-1) done_max[1]=siz[1]-1;
// done_max[2]++; if (done_max[2]>=siz[2]-1) done_max[2]=siz[2]-1;
// radius+=voxel_min;
// //printf("+");
// for (ix=done_min[0]; ix<=done_max[0]; ix++)
// for (iy=done_min[1]; iy<=done_max[1]; iy++)
// for (iz=done_min[2]; iz<=done_max[2]; iz++)
// {
// Grid( ix, iy, iz, first, last );
// for(l=first;l!=last;++l)
// {
// if (!(**l).IsD())
// {
// if( ! tm.IsMarked(l->Elem()))
// {
// //if (!l->Elem()->IsD() && l->Elem()->Dist(p,min_dist,t_res)) {
// if (dist_funct((**l), p, min_dist, t_res)) // <-- NEW: use of distance functor
// {
// winner=l->Elem();
// res=t_res;
// };
// tm.Mark(l->Elem());
// }
// }
// };
// }
// };
// return winner;
//};
///** Returns the closest posistion of a point p and its distance (OLD VERSION)
//@param p a 3d point
//@param min_dist the returned closest distance
//@param res the returned closest point
//@return The closest element
//*/
///*
// NOTE: kept for backward compatibility.
// Same as template <class DISTFUNCT> GetClosest() but without maximum distance rejection
// and distance functor and with the assumption that ObjType expose a Dist() method
// acting like a DISTFUNCT funcor;
//*/
//class BackCompDist {
// public:
// inline bool operator () (const ObjType & obj, const CoordType & pt, ScalarType & mindist, CoordType & result) {
// return (vcg::face::PointDistance<ObjType>(obj,pt, mindist, result));
// }
// };
//template <class TMARKER>
//ObjPtr GetClosest( const CoordType & p, ScalarType & min_dist, CoordType & res,TMARKER &tm) {
//
// const ScalarType max_dist = min_dist;
// return (this->GetClosest<BackCompDist,TMARKER>(p, max_dist, BackCompDist(), min_dist, res,tm));
//}
/// Inserisce una mesh nella griglia. Nota: prima bisogna
/// chiamare SetBBox che setta dim in maniera corretta
void Set( ContainerType & s )
/// Insert a mesh in the grid
template <class OBJITER>
void Set(const OBJITER & _oBegin, const OBJITER & _oEnd)
{
Set(s,s.size());
}
/// Inserisce una mesh nella griglia. Nota: prima bisogna
/// chiamare SetBBox che setta dim in maniera corretta
void Set( ContainerType & s,int _size )
{
Point3i _siz;
BestDim( _size, dim, _siz );
Set(s,_siz);
}
void Set(ContainerType & s, Point3i _siz)
{
siz=_siz;
// Calcola la dimensione della griglia
OBJITER i;
bbox.min=Point3<FLT>(0,0,0);
bbox.max=Point3<FLT>(0,0,0);
Box3<FLT> b;
for(i = _oBegin; i!= _oEnd; ++i)
{
(*i).GetBBox(b);
bbox.Add(b);
}
int _size=std::distance<OBJITER>(_oBegin,_oEnd);
dim = bbox.max - bbox.min;
BestDim( _size, dim, siz );
// find voxel size
voxel[0] = dim[0]/siz[0];
voxel[1] = dim[1]/siz[1];
voxel[2] = dim[2]/siz[2];
// "Alloca" la griglia: +1 per la sentinella
grid.resize( siz[0]*siz[1]*siz[2]+1 );
// Ciclo inserimento dei tetraedri: creazione link
links.clear();
typename ContainerType::iterator pt;
for(pt=s.begin(); pt!=s.end(); ++pt)
for(i=_oBegin; i!=_oEnd; ++i)
{
Box3x bb; // Boundig box del tetraedro corrente
(*pt).GetBBox(bb);
(*i).GetBBox(bb);
bb.Intersect(bbox);
if(! bb.IsNull() )
{
@ -523,7 +380,7 @@ namespace vcg {
for(x=ib.min[0];x<=ib.max[0];++x)
// Inserire calcolo cella corrente
// if( pt->Intersect( ... )
links.push_back( Link(&(*pt),by+x) );
links.push_back( Link(&(*i),by+x) );
}
}
}
@ -563,7 +420,31 @@ namespace vcg {
return sizeof(GridStaticPtr)+ sizeof(Link)*links.size() +
sizeof(Cell) * grid.size();
}
}; //end class GridStaticObj
template <class OBJPOINTDISTFUNCTOR, class OBJMARKER>
ObjPtr GetClosest(OBJPOINTDISTFUNCTOR & _getPointDistance, OBJMARKER & _marker,
const CoordType & _p, const ScalarType & _maxDist,ScalarType & _minDist, CoordType & _closestPt)
{
return (vcg::GridClosest<GridPtrType,OBJPOINTDISTFUNCTOR,OBJMARKER>(*this,_getPointDistance,_marker, _p,_maxDist,_minDist,_closestPt));
}
template <class OBJPOINTDISTFUNCTOR, class OBJMARKER, class OBJPTRCONTAINER,class DISTCONTAINER, class POINTCONTAINER>
unsigned int GetKClosest(OBJPOINTDISTFUNCTOR & _getPointDistance,OBJMARKER & _marker,
const unsigned int _k, const CoordType & _p, const ScalarType & _maxDist,OBJPTRCONTAINER & _objectPtrs,
DISTCONTAINER & _distances, POINTCONTAINER & _points)
{
return (vcg::GridGetKClosest<GridPtrType,
OBJPOINTDISTFUNCTOR,OBJMARKER,OBJPTRCONTAINER,DISTCONTAINER,POINTCONTAINER>(*this,_getPointDistance,_marker,_k,_p,_maxDist,_objectPtrs,_distances,_points));
}
template <class OBJRAYISECTFUNCTOR, class OBJMARKER>
ObjPtr DoRay(OBJRAYISECTFUNCTOR & _rayIntersector, OBJMARKER & _marker, const Ray3<ScalarType> & _ray, const ScalarType & _maxDist, ScalarType & _t)
{
return(vcg::GridDoRay<GridPtrType,OBJRAYISECTFUNCTOR,OBJMARKER>(*this,_rayIntersector,_marker,_ray,_maxDist,_t));
}
}; //end class GridStaticPtr
}; // end namespace

View File

@ -21,9 +21,12 @@
* *
****************************************************************************/
/****************************************************************************
History
History
$Log: not supported by cvs2svn $
Revision 1.9 2005/09/21 14:22:49 pietroni
Added DynamicSpatialHAshTable class
Revision 1.8 2005/09/19 13:35:45 pietroni
use of standard grid interface
use of vector instead of map inside the cell
@ -61,6 +64,7 @@ added vcg header
#define P2 83492791
#include <vcg/space/index/grid_util.h>
#include <vcg/space/index/grid_closest.h>
//#include <map>
#include <vector>
#include <algorithm>
@ -81,17 +85,19 @@ namespace vcg{
"Optimized Spatial Hashing for Coll ision Detection of Deformable Objects",
Matthias Teschner and Bruno Heidelberger and Matthias Muller and Danat Pomeranets and Markus Gross
*/
template < typename ContainerType,class FLT=double>
class SpatialHashTable:public BasicGrid<FLT>
template < typename OBJTYPE,class FLT=double>
class SpatialHashTable:public BasicGrid<OBJTYPE,FLT>
{
public:
typedef typename ContainerType::value_type ObjType;
typedef OBJTYPE ObjType;
typedef ObjType* ObjPtr;
typedef typename ObjType::ScalarType ScalarType;
typedef Point3<ScalarType> CoordType;
typedef typename SpatialHashTable<ObjType,FLT> SpatialHashType;
//typedef typename SpatialHashTable<ObjType,FLT> GridType;
//type of container of pointer to object in a Cell
//typedef typename std::pair<ObjType*,int> EntryType ;
@ -149,10 +155,10 @@ namespace vcg{
///find the simplex into the cell
bool Find(ObjType* sim,IteMap &I)
{
for (I=_entries.begin();I<_entries.end();I++)
if ((*I).first==sim)
return true;
return false;
for (I=_entries.begin();I<_entries.end();I++)
if ((*I).first==sim)
return true;
return false;
}
///update or insert an element into a cell
@ -161,7 +167,7 @@ namespace vcg{
IteMap I;
if (Find(sim,I))
{///update temporary mark
(*I).second=_tempMark;
(*I).second=_tempMark;
}
else
_entries.push_back(EntryType(sim,_tempMark));
@ -209,7 +215,7 @@ namespace vcg{
bool operator !=(const Cell &h)
{return ((cell_n!=h.CellN()));}
protected:
protected:
virtual void UpdateHMark(ObjType* s){}
}; // end struct Cell
@ -229,7 +235,7 @@ namespace vcg{
protected:
Htable hash_table;
///number of possible hash code [0...HashSpace]
int HashSpace;
@ -243,7 +249,7 @@ namespace vcg{
hash_table.insert(HRecord(h,Cell(s,cell,tempMark)));
//Assert();
}
///return true and return the iterator to the cell if exist
bool _IsInHtable(Point3i cell,IteHtable &result)
{
@ -273,7 +279,7 @@ namespace vcg{
}
virtual void _UpdateHMark(ObjType* s){}
///insert an element in a specified cell if the cell doesn't exist than
///create it.
void _InsertInCell(ObjType* s,Point3i cell)
@ -293,20 +299,20 @@ namespace vcg{
return ((p.V(0)*P0 ^ p.V(1)*P1 ^ p.V(2)*P2)%HashSpace);
}
public:
///We need some extra space for numerical precision.
template <class Box3Type>
void SetBBox( const Box3Type & b )
{
bbox.Import( b );
ScalarType t = bbox.Diag()/100.0;
if(t == 0) t = ScalarType(1e20); // <--- Some doubts on this (Cigno 5/1/04)
bbox.Offset(t);
dim = bbox.max - bbox.min;
}
/////We need some extra space for numerical precision.
//template <class Box3Type>
// void SetBBox( const Box3Type & b )
//{
// bbox.Import( b );
// ScalarType t = bbox.Diag()/100.0;
// if(t == 0) t = ScalarType(1e20); // <--- Some doubts on this (Cigno 5/1/04)
// bbox.Offset(t);
// dim = bbox.max - bbox.min;
//}
virtual vcg::Box3i Add( ObjType* s)
{
/*std::vector<Point3i> box;
@ -325,34 +331,59 @@ namespace vcg{
return bb;
}
/// Insert a mesh in the grid.SetBBox() function must be called before
/// Hash space is cardinality of hash key set
void Set( ContainerType & s)
{
Set(s,s.size());
}
///// Insert a mesh in the grid.SetBBox() function must be called before
///// Hash space is cardinality of hash key set
//void Set( ContainerType & s)
//{
// Set(s,s.size());
//}
///// Insert a mesh in the grid.SetBBox() function must be called before
//void Set( ContainerType & s,int _size )
//{
// Point3i _siz;
// BestDim( _size, dim, _siz );
// Set(s,_siz);
//}
/// Insert a mesh in the grid.SetBBox() function must be called before
void Set( ContainerType & s,int _size )
template <class OBJITER>
void Set(const OBJITER & _oBegin, const OBJITER & _oEnd)
{
Point3i _siz;
BestDim( _size, dim, _siz );
Set(s,_siz);
}
/// Insert a mesh in the grid.SetBBox() function must be called before
void Set(ContainerType & s, Point3i _siz)
{
siz=_siz;
OBJITER i;
bbox.min=Point3<FLT>(0,0,0);
bbox.max=Point3<FLT>(0,0,0);
Box3<FLT> b;
for(i = _oBegin; i!= _oEnd; ++i)
{
(*i).GetBBox(b);
bbox.Add(b);
}
int _size=std::distance<OBJITER>(_oBegin,_oEnd);
dim = bbox.max - bbox.min;
BestDim( _size, dim, siz );
// find voxel size
voxel[0] = dim[0]/siz[0];
voxel[1] = dim[1]/siz[1];
voxel[2] = dim[2]/siz[2];
typename ContainerType::iterator i;
for(i = s.begin(); i!= s.end(); ++i)
for(i = _oBegin; i!= _oEnd; ++i)
Add(&(*i));
}
//void Set(ContainerType & s, Point3i _siz)
//{
// siz=_siz;
// // find voxel size
// voxel[0] = dim[0]/siz[0];
// voxel[1] = dim[1]/siz[1];
// voxel[2] = dim[2]/siz[2];
// typename ContainerType::iterator i;
// for(i = s.begin(); i!= s.end(); ++i)
// Add(&(*i));
//}
//
/////initialize the structure HashSpace is one estimation about
/////how many keys the system have to generate in order to obtain as less
@ -367,7 +398,7 @@ namespace vcg{
// conflicts=0;
//}
/*void AddElem( ObjType* s)
{
@ -376,7 +407,7 @@ namespace vcg{
for (std::vector<Point3i>::iterator bi=box.begin();bi<box.end();bi++)
_InsertInCell(s,*bi);
}*/
///return the simplexes of the cell that contain p
void Grid( const Point3d & p, CellIterator & first, CellIterator & last )
{
@ -423,12 +454,12 @@ namespace vcg{
/*inline Point3i MinCell()
{
return PointToCell(min);
return PointToCell(min);
}
inline Point3i MaxCell()
{
return PointToCell(max);
return PointToCell(max);
}*/
///return the number of elemnts in the cell and the iterator to the cell
@ -462,8 +493,31 @@ namespace vcg{
{tempMark++;}
template <class OBJPOINTDISTFUNCTOR, class OBJMARKER>
ObjPtr GetClosest(OBJPOINTDISTFUNCTOR & _getPointDistance, OBJMARKER & _marker,
const CoordType & _p, const ScalarType & _maxDist,ScalarType & _minDist, CoordType & _closestPt)
{
return (vcg::GridClosest<SpatialHashType,OBJPOINTDISTFUNCTOR,OBJMARKER>(*this,_getPointDistance,_marker, _p,_maxDist,_minDist,_closestPt));
}
template <class OBJPOINTDISTFUNCTOR, class OBJMARKER, class OBJPTRCONTAINER,class DISTCONTAINER, class POINTCONTAINER>
unsigned int GetKClosest(OBJPOINTDISTFUNCTOR & _getPointDistance,OBJMARKER & _marker,
const unsigned int _k, const CoordType & _p, const ScalarType & _maxDist,OBJPTRCONTAINER & _objectPtrs,
DISTCONTAINER & _distances, POINTCONTAINER & _points)
{
return (vcg::GridGetKClosest<SpatialHashType,
OBJPOINTDISTFUNCTOR,OBJMARKER,OBJPTRCONTAINER,DISTCONTAINER,POINTCONTAINER>(*this,_getPointDistance,_marker,_k,_p,_maxDist,_objectPtrs,_distances,_points));
}
template <class OBJRAYISECTFUNCTOR, class OBJMARKER>
ObjPtr DoRay(OBJRAYISECTFUNCTOR & _rayIntersector, OBJMARKER & _marker, const Ray3<ScalarType> & _ray, const ScalarType & _maxDist, ScalarType & _t)
{
return(vcg::GridDoRay<SpatialHashType,OBJRAYISECTFUNCTOR,OBJMARKER>(*this,_rayIntersector,_marker,_ray,_maxDist,_t));
}
}; // end class
/** Spatial Hash Table Dynamic
Update the Hmark value on the simplex for dynamic updating of contents of the cell.
The simplex must have the HMark() function.
@ -473,7 +527,7 @@ namespace vcg{
{
void _UpdateHMark(ObjType* s){s->HMark()=tempMark;}
};
}// end namespace
#undef P0