Refactored CountInSphere / RemoveInSphere for the PoissonDisk sampling optimizations (now you can just count the element inside a given sphere without removing them.

This commit is contained in:
Paolo Cignoni 2013-06-24 07:57:18 +00:00
parent 9ad68bc573
commit be3e74ca6a
1 changed files with 50 additions and 47 deletions

View File

@ -178,14 +178,14 @@ protected:
return false; return false;
} }
public: public:
vcg::Box3i Add( ObjType* s) vcg::Box3i Add( ObjType* s)
{ {
Box3<ScalarType> b; Box3<ScalarType> b;
s->GetBBox(b); s->GetBBox(b);
vcg::Box3i bb; vcg::Box3i bb;
this->BoxToIBox(b,bb); this->BoxToIBox(b,bb);
//then insert all the cell of bb //then insert all the cell of bb
for (int i=bb.min.X();i<=bb.max.X();i++) for (int i=bb.min.X();i<=bb.max.X();i++)
for (int j=bb.min.Y();j<=bb.max.Y();j++) for (int j=bb.min.Y();j<=bb.max.Y();j++)
@ -206,33 +206,36 @@ protected:
return true; return true;
} ///insert a new cell } ///insert a new cell
int CountInSphere(const Point3<ScalarType> &p, const ScalarType radius, std::vector<HashIterator> &inSphVec)
{
Box3x b(p-Point3f(radius,radius,radius),p+Point3f(radius,radius,radius));
vcg::Box3i bb;
this->BoxToIBox(b,bb);
ScalarType r2=radius*radius;
inSphVec.clear();
for (int i=bb.min.X();i<=bb.max.X();i++)
for (int j=bb.min.Y();j<=bb.max.Y();j++)
for (int k=bb.min.Z();k<=bb.max.Z();k++)
{
std::pair<HashIterator,HashIterator> CellRange = hash_table.equal_range(Point3i(i,j,k));
for(HashIterator hi = CellRange.first; hi!=CellRange.second;++hi)
{
if(SquaredDistance(p,hi->second->cP()) <= r2)
inSphVec.push_back(hi);
}
}
return inSphVec.size();
}
int RemoveInSphere(const Point3<ScalarType> &p, const ScalarType radius) int RemoveInSphere(const Point3<ScalarType> &p, const ScalarType radius)
{ {
Box3x b(p-Point3f(radius,radius,radius),p+Point3f(radius,radius,radius)); std::vector<HashIterator> inSphVec;
vcg::Box3i bb; CountInSphere(p,radius,inSphVec);
this->BoxToIBox(b,bb); for(typename std::vector<HashIterator>::iterator vi=inSphVec.begin(); vi!=inSphVec.end();++vi)
ScalarType r2=radius*radius;
int cnt=0;
std::vector<HashIterator> toDel;
for (int i=bb.min.X();i<=bb.max.X();i++)
for (int j=bb.min.Y();j<=bb.max.Y();j++)
for (int k=bb.min.Z();k<=bb.max.Z();k++)
{
std::pair<HashIterator,HashIterator> CellRange = hash_table.equal_range(Point3i(i,j,k));
for(HashIterator hi = CellRange.first; hi!=CellRange.second;++hi)
{
if(SquaredDistance(p,hi->second->cP()) <= r2)
{
cnt++;
toDel.push_back(hi);
}
}
}
for(typename std::vector<HashIterator>::iterator vi=toDel.begin(); vi!=toDel.end();++vi)
hash_table.erase(*vi); hash_table.erase(*vi);
return cnt; return inSphVec.size();
} }
// Specialized version that is able to take in input a // Specialized version that is able to take in input a
template<class DistanceFunctor> template<class DistanceFunctor>
@ -264,10 +267,10 @@ protected:
return cnt; return cnt;
} }
// This version of the removal is specialized for the case where // This version of the removal is specialized for the case where
// an object has a pointshaped box and using the generic bbox interface is just a waste of time. // an object has a pointshaped box and using the generic bbox interface is just a waste of time.
void RemovePunctual( ObjType *s) void RemovePunctual( ObjType *s)
{ {
Point3i pi; Point3i pi;
PToIP(s->cP(),pi); PToIP(s->cP(),pi);
@ -313,7 +316,7 @@ protected:
voxel[0] = dim[0]/siz[0]; voxel[0] = dim[0]/siz[0];
voxel[1] = dim[1]/siz[1]; voxel[1] = dim[1]/siz[1];
voxel[2] = dim[2]/siz[2]; voxel[2] = dim[2]/siz[2];
hash_table.clear(); hash_table.clear();
} }
/// Insert a mesh in the grid. /// Insert a mesh in the grid.
@ -415,7 +418,7 @@ protected:
template <class OBJMARKER, class OBJPTRCONTAINER> template <class OBJMARKER, class OBJPTRCONTAINER>
unsigned int GetInBox(OBJMARKER & _marker, unsigned int GetInBox(OBJMARKER & _marker,
const Box3x _bbox, const Box3x _bbox,
OBJPTRCONTAINER & _objectPtrs) OBJPTRCONTAINER & _objectPtrs)
{ {
return(vcg::GridGetInBox<SpatialHashType,OBJMARKER,OBJPTRCONTAINER> return(vcg::GridGetInBox<SpatialHashType,OBJMARKER,OBJPTRCONTAINER>
@ -440,11 +443,11 @@ protected:
class DynamicSpatialHashTable: public SpatialHashTable<ContainerType,FLT> class DynamicSpatialHashTable: public SpatialHashTable<ContainerType,FLT>
{ {
public: public:
typedef typename SpatialHashTable<ContainerType,FLT>::CoordType CoordType; typedef typename SpatialHashTable<ContainerType,FLT>::CoordType CoordType;
typedef typename SpatialHashTable<ContainerType,FLT>::ObjType ObjType; typedef typename SpatialHashTable<ContainerType,FLT>::ObjType ObjType;
typedef typename SpatialHashTable<ContainerType,FLT>::ObjPtr ObjPtr; typedef typename SpatialHashTable<ContainerType,FLT>::ObjPtr ObjPtr;
typedef typename SpatialHashTable<ContainerType,FLT>::Box3x Box3x; typedef typename SpatialHashTable<ContainerType,FLT>::Box3x Box3x;
typedef typename SpatialHashTable<ContainerType,FLT>::CellIterator CellIterator; typedef typename SpatialHashTable<ContainerType,FLT>::CellIterator CellIterator;
void _UpdateHMark(ObjType* s){ s->HMark() = this->tempMark;} void _UpdateHMark(ObjType* s){ s->HMark() = this->tempMark;}