From 54c8562e3acf16677c2e4d0345677d3623cf988e Mon Sep 17 00:00:00 2001 From: nicopietroni Date: Mon, 19 Sep 2005 13:35:45 +0000 Subject: [PATCH] use of standard grid interface use of vector instead of map inside the cell removed closest iterator --- vcg/space/index/spatial_hashing.h | 858 ++++++++++++------------------ 1 file changed, 333 insertions(+), 525 deletions(-) diff --git a/vcg/space/index/spatial_hashing.h b/vcg/space/index/spatial_hashing.h index 1a0857ec..9cb02adf 100644 --- a/vcg/space/index/spatial_hashing.h +++ b/vcg/space/index/spatial_hashing.h @@ -24,6 +24,9 @@ History $Log: not supported by cvs2svn $ +Revision 1.7 2005/06/15 11:44:47 pietroni +minor changes + Revision 1.6 2005/06/01 13:47:59 pietroni resolved hash code conflicts @@ -47,11 +50,13 @@ added vcg header #ifndef VCGLIB_SPATIAL_HASHING #define VCGLIB_SPATIAL_HASHING + #define P0 73856093 #define P1 19349663 #define P2 83492791 -#include +#include +//#include #include #include #ifdef WIN32 @@ -62,73 +67,114 @@ added vcg header #define STDEXT __gnu_cxx #endif + namespace vcg{ /** Spatial Hash Table Spatial Hashing as described in - "Optimized Spatial Hashing for Collision Detection of Deformable Objects", + "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 - class SpatialHashTable{ + template < typename ContainerType,class FLT=float > + class SpatialHashTable:public BasicGrid + { public: - typedef typename ElemType::CoordType CoordType; - typedef typename CoordType::ScalarType ScalarType; + typedef typename ContainerType::value_type ObjType; + typedef ObjType* ObjPtr; + typedef typename ObjType::ScalarType ScalarType; + typedef Point3 CoordType; - //type of entries element of a cell - typedef typename std::pair EntryType; + //type of container of pointer to object in a Cell + //typedef typename std::pair EntryType ; + class EntryType : public std::pair + { + public: + EntryType(ObjType* sim,const int &_tempMark) + { + first=sim; + second=_tempMark; + } - //This Class Identify the cell - struct HElement + ObjType& operator *(){return (*this->first);} + }; + + //typedef typename std::map CellContainerType; + typedef typename std::vector CellContainerType; + typedef typename CellContainerType::iterator IteMap; + typedef typename EntryType* CellIterator; + + ////iterator to elems on a cell (need to define method Elem() for Space Iterators) + //class CellIterator :public IteMap + //{ + // //std::vector::iterator i; + //public: + // CellIterator(){} + // inline CellIterator & operator = ( IteMap const &c) + // {this->); }; + // ObjType* operator *(){return ((* this)->first);} + //}; + + //This Class Identify the cell + struct Cell { private: ///the min and max point corresponding to the cell - used to inverse hashing - CoordType min;//coordinate min of the cell - CoordType max;//coordinate max of the cell + //CoordType min;//coordinate min of the cell + //CoordType max;//coordinate max of the cell + Point3i cell_n;//cell number - + //iterator to the map element into the cell + //typedef typename CellContainerType::iterator IteMap; + public: //elements - std::map _entries; - - //iterator to the map element into the cell - typedef typename std::map::iterator IteMap; + CellContainerType _entries; - HElement() + Cell() {} - HElement(ElemType* sim,const int &_tempMark,CoordType _min,CoordType _max,Point3i _cell) + Cell(ObjType* sim,Point3i _cell,const int &_tempMark) { - _entries.insert(EntryType(sim,_tempMark)); - min=_min; + _entries.push_back(EntryType(sim,_tempMark)); + /*min=_min; max=_max; - assert(minMark()=_tempMark; @@ -147,294 +193,162 @@ namespace vcg{ ///return true if the the entry corripondent to that ///simplex is valid or not ///(using temporary mark). - bool IsUpdated(ElemType* sim) + bool IsUpdated(ObjType* sim) { - IteMap I=_entries.find(sim); - if (I!=_entries.end()) + IteMap I; + if (Find(sim,I)) return(IsUpdated(I)); else return false; } - //add to the vector all simplexes of the map that have a right timestamp or are not deleted - void Elems(std::vector & res) - { - for (IteMap ite=_entries.begin();ite!=_entries.end();ite++) - { - ElemType* sim=(*ite).first; - if (IsUpdated(ite)&&(!sim->IsD())) - res.push_back(sim); - } - } - - - CoordType Min() - {return min;} - - CoordType Max() - {return max;} - Point3i CellN() {return cell_n;} - bool operator ==(const HElement &h) + bool operator ==(const Cell &h) {return (cell_n==h.CellN());} - bool operator !=(const HElement &h) + bool operator !=(const Cell &h) {return ((cell_n!=h.CellN()));} - - void Assert() - { - for (IteMap ite=_entries.begin();ite!=_entries.end();ite++) - { - ElemType* sim=(*ite).first; - if (IsUpdated(sim)) - { - ScalarType Xs=sim->P().X(); - ScalarType Ys=sim->P().Y(); - ScalarType Zs=sim->P().Z(); - ScalarType Xm=Min().X()-0.2; - ScalarType Ym=Min().Y()-0.2; - ScalarType Zm=Min().Z()-0.2; - ScalarType XM=Max().X()+0.2; - ScalarType YM=Max().Y()+0.2; - ScalarType ZM=Max().Z()+0.2; - if ((XsXM)||(YsYM)||(ZsZM)) - { - printf("---ERROR---\n"); - printf("Point=%f,%f,%f.\n",Xs,Ys,Zs); - printf("cellMin=%f,%f,%f\n",Xm,Ym,Zm); - printf("cellMax=%f,%f,%f\n",XM,YM,ZM); - - } - } - } - } - }; // end struct HElement - ///this Iterator returns all the elements that - ///are in a specified box. - struct ClosersIterator{ + }; // end struct Cell - private: - CoordType p; - SpatialHashTable * sh; ///pointer to spatial hash table structure - vcg::Point3i mincorner,maxcorner; ///corners of the box where the scannig is performed - vcg::Point3i curr_ic; /// triple corresponding to the cell coordinate - HElement * curr_c; /// current cell pointer - typename HElement::IteMap curr_i; /// current iterator inside the cell - bool end; ///return true if the scanning of the elements is terminated - - ///advance the current coordinate of one step inside the space box - ///set and to true if scannig fo cells is complete - void Advance(){ - if(curr_ic[0] < maxcorner[0]) - ++curr_ic[0]; - else{ - if(curr_ic[1] < maxcorner[1]) - ++curr_ic[1]; - else{ - if(curr_ic[2] < maxcorner[2]) - ++curr_ic[2]; - else - end=true; - curr_ic[1] = mincorner[1]; - } - curr_ic[0] = mincorner[0]; - } - - } + ////This Class Identify the cell + //struct Cell + //{ + //private: - //operator Next - //go to next simplex without considering temporary mark - void Next() { - SpatialHashTable::IteHtable I; + // ///the min and max point corresponding to the cell - used to inverse hashing + // //CoordType min;//coordinate min of the cell + // //CoordType max;//coordinate max of the cell - HElement::IteMap e = curr_c->_entries.end(); - --e; + // Point3i cell_n;//cell number + // //iterator to the map element into the cell + // //typedef typename CellContainerType::iterator IteMap; - ///if the current index - //is not at the end of element in the cell so advance of one step - if(curr_i != e) - ++curr_i; - else{ - ///Advance until find a cell that isn't empty or the scan is complete - Advance(); + //public: - while((!End())&&(sh->numElemCell(curr_ic,I)==0)) - {Advance();} + // //elements + // CellContainerType _entries; - if (!End()) - { - curr_c = &((*I).second); - curr_i = curr_c->_entries.begin(); - } - } - } + // Cell() + // {} - public: + // Cell(ObjType* sim,Point3i _cell,const int &_tempMark) + // { + // _entries.insert(EntryType(sim,_tempMark)); + // /*min=_min; + // max=_max; + // assert(minP().X(); - ScalarType Ys=sim->P().Y(); - ScalarType Zs=sim->P().Z(); - ScalarType Xm=curr_c->Min().X()-0.2; - ScalarType Ym=curr_c->Min().Y()-0.2; - ScalarType Zm=curr_c->Min().Z()-0.2; - ScalarType XM=curr_c->Max().X()+0.2; - ScalarType YM=curr_c->Max().Y()+0.2; - ScalarType ZM=curr_c->Max().Z()+0.2; - if ((XsXM)||(YsYM)||(ZsZM)) - { - printf("---ERROR---\n"); - printf("Point=%f,%f,%f.\n",Xs,Ys,Zs); - printf("cellMin=%f,%f,%f\n",Xm,Ym,Zm); - printf("cellMax=%f,%f,%f\n",XM,YM,ZM); - printf("tempMark Simplex=%d\n",sim->Mark()); - printf("tempMark Global=%d\n",sh->tempMark); - if (curr_c->IsUpdated(sim)) - printf("updated"); - else - printf("disupdated"); - } - } + // ///return true if the element is in the cell + // bool IsIn(ObjType* sim) + // { + // int n=elem.count(sim); + // assert((n==0)||(n==1)); + // return (n==1); + // } - ///Initialize the iterator, p is the center of the box and _edge is his size - void Init(SpatialHashTable * _sh, CoordType _p, const ScalarType &_edge) - { - end=false; - sh = _sh; - p =_p; - SpatialHashTable::IteHtable I; + // ///return the number of elements stored in the cell + // int Size() + // {return (int)(_entries.size());} - ///find the box - CoordType halfDiag(_edge,_edge,_edge); - mincorner = sh->PointToCell(p-halfDiag); - maxcorner = sh->PointToCell(p+halfDiag); + // ///update or insert an element into a cell + // void Update(ObjType* sim, const int & _tempMark) + // { + // IteMap I=_entries.find(sim); - ///set the initial cell of the iterator as the one that stay on the - /// left lower position - curr_ic = mincorner; + // if (I!=_entries.end())//the entry exist in the cell + // (*I).second=_tempMark; + // else + // _entries.insert(_entries.begin(),EntryType(sim,_tempMark)); - //if the fist position isn't empty - if (sh->numElemCell(curr_ic,I)>0) - { - curr_c = &((*I).second); - curr_i = curr_c->_entries.begin(); - } - else - {///advance until don't find an non empty cell - while((!End())&&(sh->numElemCell(curr_ic,I)==0)) - Advance(); - } - ///then if is not finished find the first updated occorrency - if (!End()) - { - curr_c = &((*I).second); - curr_i = curr_c->_entries.begin(); - while ((!curr_c->IsUpdated(curr_i))&&(!end)) - Next(); - } - } + // //at the end update the temporary mark on the simplex + // sim->Mark()=_tempMark; + // //Assert(); + // } - /////operator ++ of the itearator - //void Next() { - // bool isempty = true; - // HElement::IteMap e = curr_c->_entries.end(); - // --e; + // ///given an iterator to the instance of the entry in the cell + // ///return true if the the entry is valid + // ///(using temporary mark). + // bool IsUpdated(CellIterator &I) + // { + // return ((*I).second >= (*I).first->Mark()); + // } - // ///if the current index - // //is not at the end of elemnt in the cell so advance of one step - // if(curr_i != e) - // ++curr_i; + // ///given an simplex pointer + // ///return true if the the entry corripondent to that + // ///simplex is valid or not + // ///(using temporary mark). + // bool IsUpdated(ObjType* sim) + // { + // IteMap I=_entries.find(sim); + // if (I!=_entries.end()) + // return(IsUpdated(I)); + // else + // return false; + // } - // ///if the elemants on the cell are terminated then switch to another cell - // if(curr_i == e) - // { - // ///Advance until find a cell that isn't empty - // while( Advance() && (isempty=sh->IsEmptyCell(curr_ic))); - // if(!isempty){ - // curr_c = &(*(sh->hash_table.find(sh->Hash(curr_ic)))).second; - // curr_i = curr_c->_entries.begin(); - // } - // else - // end = true; - // } - //} - - + // ////add to the vector all simplexes of the map that have a right timestamp or are not deleted + // //void Elems(std::vector & res) + // //{ + // // for (IteMap ite=_entries.begin();ite!=_entries.end();ite++) + // // { + // // ObjType* sim=(*ite).first; + // // if (IsUpdated(ite)&&(!sim->IsD())) + // // res.push_back(sim); + // // } + // //} - ///operator ++ of the itearator - void operator ++() - { - Next(); - while ((!curr_c->IsUpdated(curr_i))&&(!end)) - Next(); - - assert(curr_c->IsUpdated(curr_i)||(end)); - } - ///dereferent operator - ElemType * operator *(){ - return (*curr_i).first; - } + // Point3i CellN() + // {return cell_n;} - ///return true if the scanning of elements is complete - bool End(){ - return end; - } + // bool operator ==(const Cell &h) + // {return (cell_n==h.CellN());} - }; // end struct CloserIterator + // bool operator !=(const Cell &h) + // {return ((cell_n!=h.CellN()));} + + + //}; // end struct Cell //hash table definition - //typedef typename STDEXT::hash_map Htable; - typedef typename STDEXT::hash_multimap Htable; - //hash table definition - //typedef typename STDEXT::hash_map Htable; + typedef typename STDEXT::hash_multimap Htable; //record of the hash table - typedef typename std::pair HRecord; + typedef typename std::pair HRecord; //iterator to the hash table typedef typename Htable::iterator IteHtable; - SpatialHashTable(){}; + SpatialHashTable(){HashSpace=1000;};//default value for hash_space ~SpatialHashTable(){}; int tempMark; protected: - //ContSimplex & _simplex; - Htable hash_table; + + ///number of possible hash code [0...HashSpace] + int HashSpace; - int num; - float l; - - - CoordType min; - CoordType max; - + ///number of conflicts created int conflicts; - /*Point3i min; - Point3i max;*/ ///insert a new cell - void _InsertNewHentry(ElemType* s,Point3i cell) + void _InsertNewHentry(ObjType* s,Point3i cell) { int h=Hash(cell); - CoordType _min; - CoordType _max; - _min=CellToPoint(cell); - _max=_min+CoordType(l,l,l); - hash_table.insert(HRecord(h,HElement(s,tempMark,_min,_max,cell))); - //Assert(); + hash_table.insert(HRecord(h,Cell(s,cell,tempMark))); s->Mark()=tempMark; + //Assert(); } + ///return true and return the iterator to the cell if exist bool _IsInHtable(Point3i cell,IteHtable &result) { int h=Hash(cell); @@ -449,7 +363,7 @@ namespace vcg{ while((i != p.second)&&((*i).second.CellN()!=cell))++i; - if (i==p.second)///the scan is terminated and we have not fuond the cell + if (i==p.second)///the scan is terminated and we have not found the right cell { conflicts++; return false; @@ -464,296 +378,190 @@ namespace vcg{ ///insert an element in a specified cell if the cell doesn't exist than ///create it. - void _InsertInCell(ElemType* s,Point3i cell) + void _InsertInCell(ObjType* s,Point3i cell) { IteHtable I; if (!_IsInHtable(cell,I)) _InsertNewHentry(s,cell); else///there is the entry specified by the iterator I so update only the temporary mark (*I).second.Update(s,tempMark); - - //Assert(); } - + // hashing const int Hash(Point3i p) const { - //vcg::Point3i dim(100,100,100); - return ((p.V(0)*P0 ^ p.V(1)*P1 ^ p.V(2)*P2)%num); + return ((p.V(0)*P0 ^ p.V(1)*P1 ^ p.V(2)*P2)%HashSpace); } - ///return the cells intersected by the Bounding box of the simplex - virtual void BoxCells(CoordType _min,CoordType _max,std::vector& ret) - { - ret.clear(); - Point3i MinI=PointToCell(_min); - Point3i MaxI=PointToCell(_max); - int dimx=abs(MaxI.V(0)-MinI.V(0)); - int dimy=abs(MaxI.V(1)-MinI.V(1)); - int dimz=abs(MaxI.V(2)-MinI.V(2)); - - for (int x=0;x<=dimx;x++) - for (int y=0;y<=dimy;y++) - for (int z=0;z<=dimz;z++) - { - Point3i cell=Point3i(MinI.V(0)+x,MinI.V(1)+y,MinI.V(2)+z); - ret.push_back(cell); - } - assert(ret.size()!=0); - } - /*void getAtCell(Point3i _c,std::vector & res) - { - std::vector result; - int h=Hash(_c); - if (numElemCell(_c)!=0){ - IteHtable h_res=hash_table.find(h); - ((*h_res).second.Elems(tempMark,res)); - } - }*/ - - - Point3i PointToCell(CoordType p) - { - int x=(int)floor((p.V(0)-(ScalarType)min.V(0))/(ScalarType)l); - int y=(int)floor((p.V(1)-(ScalarType)min.V(1))/(ScalarType)l); - int z=(int)floor((p.V(2)-(ScalarType)min.V(2))/(ScalarType)l); - return (vcg::Point3i(x,y,z)); - } - - CoordType CellToPoint(Point3i c) - { - ScalarType x=(((ScalarType)c.V(0)+min.V(0))*(ScalarType)l); - ScalarType y=(((ScalarType)c.V(1)+min.V(1))*(ScalarType)l); - ScalarType z=(((ScalarType)c.V(2)+min.V(2))*(ScalarType)l); - return (CoordType(x,y,z)); - } public: - - ///initialize the structure HashSpace is one estimation about - ///how many keys the system have to generate in order to obtain as less - ///conflicts as possible - void Init(CoordType _min,CoordType _max,ScalarType _l,int HashSpace=1000) + + ///We need some extra space for numerical precision. + template + void SetBBox( const Box3Type & b ) { - l=_l; - min=_min; - max=_max; - num=HashSpace; - tempMark=0; - conflicts=0; - } - - virtual std::vector AddElem( ElemType* s) - { - std::vector box; - BoxCells(s->BBox().min,s->BBox().max,box); - for (std::vector::iterator bi=box.begin();bi box; + /*std::vector box; BoxCells(s->BBox().min,s->BBox().max,box); - for (std::vector::iterator bi=box.begin();bi::iterator bi=box.begin();bi b; + s->GetBBox(b); + vcg::Box3i bb; + BoxToIBox(b,bb); + //then insert all the cell of bb + 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++) + _InsertInCell(s,vcg::Point3i(i,j,k)); + + 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 + 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, 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 + /////conflicts as possible + //void Init(CoordType _min,CoordType _max,ScalarType _l,int HashSpace=1000) + //{ + // l=_l; + // min=_min; + // max=_max; + // HashSpace=HashSpace; + // tempMark=0; + // conflicts=0; + //} + + + + /*void AddElem( ObjType* s) + { + std::vector box; + BoxCells(s->BBox().min,s->BBox().max,box); + for (std::vector::iterator bi=box.begin();bi & res) + { + IteHtable I; + if (_IsInHtable(_c,I))//if there is the cell then + (*I).second.Elems(res); + } + + + std::vector Cells(ObjType *s) + { + return BoxCells(s,s->BBox().min,s->BBox().max); + } + + /*inline Point3i MinCell() + { + return PointToCell(min); + } + + inline Point3i MaxCell() + { + return PointToCell(max); }*/ - template - void AddElems( ContElemType & elem_set) + ///return the number of elemnts in the cell and the iterator to the cell + ///if the cell exist + int numElemCell(Point3i _c,IteHtable &I) { - typename ContElemType::iterator i; - for(i = elem_set.begin(); i!= elem_set.end(); ++i) - AddElem(&(*i)); + if (_IsInHtable(_c,I)) + return ((*I).second.Size()); + else + return 0; } - + ///return the number of cell created + int CellNumber() + {return (hash_table.size());} - ////********************************************************************* - //template - // bool usefirst(const A & a,const A & b)const {return a.first < b.first;} + int Conflicts() + {return conflicts;} - int ClosestK(const int& k,ElemType* e, std::vector& res) - { - typedef std::pair ElemDist; - std::vector neigh_dist; - std::vector::iterator ite_nd; - std::vector neigh; - std::vector::iterator i_neigh; - typename ElemType::CoordType p = e->P(); - ScalarType radius,tmp,d; + void Clear() + { + hash_table.clear(); + } - // set the radius as the distance to the closest face - radius = p[2]-floor(p[2]/l)*l; - if(radius > l*0.5) radius = l -radius; - tmp = p[1]-floor(p[1]/l)*l; - if(tmp > l*0.5) tmp = l -tmp; - if(radius > tmp) tmp = radius; - tmp = p[0]-floor(p[0]/l)*l; - if(tmp > l*0.5) tmp = l -tmp; - if(radius > tmp) radius = tmp; + void SetHashSpace() + { + HashSpace + } - int x,y,z; - vcg::Point3i mincorner,maxcorner,c; - c = PointToCell(p); - mincorner = maxcorner = c; - neigh_dist.push_back(ElemDist(-1,e)); - ite_nd = neigh_dist.begin(); + void UpdateTmark() + {tempMark++;} - while((int)res.size() < k) - { - //run on the border - for( z = mincorner[2]; z <= maxcorner[2]; ++z) - for( y = mincorner[1]; y <= maxcorner[1]; ++y) - for( x = mincorner[0]; x <= maxcorner[0];) - { - - neigh.clear(); - getAtCell(vcg::Point3i(x,y,z),neigh); - for(i_neigh = neigh.begin(); i_neigh != neigh.end(); ++i_neigh) - { - d = Distance(p,(*i_neigh)->P()); - if( (*i_neigh) != e) - neigh_dist.push_back(ElemDist(d,*i_neigh)); - } - if( - ( ( y == mincorner[1]) || ( y == maxcorner[1])) || - ( ( z == mincorner[2]) || ( z == maxcorner[2])) || - ( x == maxcorner[0]) - )++x; else x=maxcorner[0]; - } - // ,usefirst ---::iterator > - ite_nd =neigh_dist.begin(); - std::advance(ite_nd,res.size()); - std::sort(ite_nd,neigh_dist.end()); - while ( ( (int)res.size() < k ) && (ite_nd != neigh_dist.end())) - { - if((*ite_nd).first < radius) - res.push_back( (*ite_nd).second ); - ++ite_nd; - } - - mincorner -= vcg::Point3i(1,1,1); - maxcorner += vcg::Point3i(1,1,1); - radius+=l; - - } - return 0; - } - //********************************************************************** - - ///return the simplexes on a specified cell - void getAtCell(Point3i _c,std::vector & res) - { - IteHtable I; - if (_IsInHtable(_c,I))//if there is the cell then - (*I).second.Elems(res); - } - - // return the elem closer than radius - int CloserThan( typename ElemType::CoordType p, - typename ElemType::ScalarType radius, - std::vector & closers){ - ClosersIterator cli; - cli.Init(this,p,radius); - while(!cli.End()){ - if ( (((*cli)->P() -p )*((*cli)->P() -p ) < radius*radius))// &&(*cli.curr_i).second >= tempMark) - closers.push_back(*cli); - ++cli; - } - return (int)closers.size(); - } - - std::vector Cells(ElemType *s) - { - return BoxCells(s,s->BBox().min,s->BBox().max); - } - - inline Point3i MinCell() - { - return PointToCell(min); - } - - inline Point3i MaxCell() - { - return PointToCell(max); - } - - /*inline int numElemCell(Point3i _c) - { - int h=Hash(_c); - if (hash_table.count(h)==0) - return 0; - else - { - IteHtable Ih=hash_table.find(h); - return ((*Ih).second.Size()); - } - }*/ - - ///return the number of elemnts in the cell and the iterator to the cell - ///if the cell exist - int numElemCell(Point3i _c,IteHtable &I) - { - if (_IsInHtable(_c,I)) - return ((*I).second.Size()); - else - return 0; - } - - /*inline bool IsEmptyCell(Point3i _c) - { - return(numElemCell(_c)==0); - }*/ - - /*inline bool IsEmptyCell(Point3i _c) - { - int h=Hash(_c); - if (hash_table.count(h)==0) - return true; - else - return false; - }*/ - - ///return the number of cell created - int CellNumber() - {return (hash_table.size());} - - int Conflicts() - {return conflicts;} - - void Clear() - { - hash_table.clear(); - } - - void UpdateTmark() - {tempMark++;} - - ///only debug - void DrawCell(HElement &c) - { - glPushMatrix(); - glTranslate(c.Min()+vcg::Point3d(l/2,l/2,l/2)); - glutWireCube(l); - glPopMatrix(); - } - - void Draw() - { - for (IteHtable I=hash_table.begin();I!=hash_table.end();I++) - DrawCell((*I).second); - } - - ///only debug - void Assert() - { - for (IteHtable I=hash_table.begin();I!=hash_table.end();I++) - (((*I).second).Assert()); - } }; // end class }// end namespace