diff --git a/vcg/space/index/spatial_hashing.h b/vcg/space/index/spatial_hashing.h index 66001215..fc61eff5 100644 --- a/vcg/space/index/spatial_hashing.h +++ b/vcg/space/index/spatial_hashing.h @@ -20,10 +20,19 @@ * for more details. * * * ****************************************************************************/ + +// marco +// added comments +// corrected bad reference in void Grid( const Point3i & _c, CellIterator & first, CellIterator & last ) + + /**************************************************************************** History $Log: not supported by cvs2svn $ +Revision 1.20 2006/07/26 08:12:56 pietroni +added InitEmpty Function + Revision 1.19 2006/07/10 12:43:13 turini explicit cast in _IsInHtable() to resolve a warning @@ -144,6 +153,12 @@ namespace vcg{ //type of container of pointer to object in a Cell //typedef typename std::pair EntryType ; + + /* EntryType is the entry data tyep stored into a cell. + * It is composed by: + * - a ObjType* pointer, pointing to the simplex to spatially index + * - an integer (temporal mark ??? ) ??? + */ class EntryType : public std::pair { public: @@ -165,7 +180,7 @@ namespace vcg{ { protected: - Point3i cell_n;//cell number + Point3i cell_n; // cell index public: @@ -175,7 +190,7 @@ namespace vcg{ Cell() {} - Cell(ObjType* sim,Point3i _cell,const int &_tempMark) + Cell(ObjType* sim, Point3i _cell, const int &_tempMark) { _entries.push_back(EntryType(sim,_tempMark)); cell_n=_cell; @@ -189,7 +204,7 @@ namespace vcg{ ///find the simplex into the cell bool Find(ObjType* sim,IteMap &I) { - for (I=_entries.begin();I<_entries.end();I++) + for (I=_entries.begin();I != _entries.end();I++) if ((*I).first==sim) return true; return false; @@ -216,10 +231,10 @@ namespace vcg{ }; // end struct Cell - //hash table definition - typedef typename STDEXT::hash_multimap Htable; //record of the hash table typedef typename std::pair HRecord; + //hash table definition + typedef typename STDEXT::hash_multimap Htable; //iterator to the hash table typedef typename Htable::iterator IteHtable; @@ -252,23 +267,35 @@ namespace vcg{ int count = (int) hash_table.count(h); if (count==0)///in this case there is no entry for that key return false; - else + + std::pair p = hash_table.equal_range(h); + IteHtable i = p.first; + + bool found = false; + if ( ((*i).second.CellN() == cell) ) + found = true; + else { - std::pair p =hash_table.equal_range(h); - IteHtable i = p.first; + do { + i++; + if ((*i).second.CellN() == cell) + { + found = true; + break; + } + } while (i != p.second); + } - while((i != p.second)&&((*i).second.CellN()!=cell))++i; - - if (i==p.second)///the scan is terminated and we have not found the right cell - { - conflicts++; - return false; - } - else ///we have found the right cell - { - result=i; - return true; - } + if (!found) /// the scan is terminated and + { + // we have not found the right cell + conflicts++; + return false; + } + else ///we have found the right cell + { + result=i; + return true; } } @@ -280,9 +307,15 @@ namespace vcg{ { IteHtable I; if (!_IsInHtable(cell,I)) + { + entry_inserted++; _InsertNewHentry(s,cell); + } else///there is the entry specified by the iterator I so update only the temporary mark + { + entry_updated++; (*I).second.Update(s,tempMark); + } } // hashing @@ -294,6 +327,7 @@ namespace vcg{ public: + int entry_inserted, entry_updated; /////We need some extra space for numerical precision. //template // void SetBBox( const Box3Type & b ) @@ -337,24 +371,33 @@ namespace vcg{ assert((grid_size.V(0)>0)&&(grid_size.V(1)>0)&&(grid_size.V(2)>0)); siz=grid_size; - voxel[0] = dim[0]/siz[0]; - voxel[1] = dim[1]/siz[1]; - voxel[2] = dim[2]/siz[2]; + // voxel[i] is the lenght of the edge i of the cell + // siz[i] is the number of cells in direction i + // dim[i] is the spatial dimension of the grid + voxel[0] = dim[0] / siz[0]; + voxel[1] = dim[1] / siz[1]; + voxel[2] = dim[2] / siz[2]; } /// Insert a mesh in the grid. template - void Set(const OBJITER & _oBegin, const OBJITER & _oEnd,const Box3x &_bbox=Box3x() ) + void Set(const OBJITER & _oBegin, const OBJITER & _oEnd,const Box3x &_bbox=Box3x() ) { OBJITER i; Box3x b; - Box3x &bbox = this->bbox; - CoordType &dim = this->dim; - Point3i &siz = this->siz; - CoordType &voxel = this->voxel; + Box3x &bbox = this->bbox; + CoordType &dim = this->dim; + Point3i &siz = this->siz; + CoordType &voxel = this->voxel; + + entry_inserted = 0; + entry_updated = 0; + + int _size = std::distance(_oBegin,_oEnd); + + HashSpace = _size; - int _size=std::distance(_oBegin,_oEnd); if(!_bbox.IsNull()) this->bbox=_bbox; else { @@ -369,15 +412,15 @@ namespace vcg{ bbox.max += CoordType(infl,infl,infl); } - 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]; + 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]; - for(i = _oBegin; i!= _oEnd; ++i) - Add(&(*i)); + for(i = _oBegin; i != _oEnd; ++i) + Add(&(*i)); } @@ -396,19 +439,36 @@ namespace vcg{ Grid(vcg::Point3i(x,y,z),first,last); } - ///return the simplexes on a specified cell + /* return the simplexes on a specified cell + * + * @param _c is the 3D integer index of the cell [IN] + * @param first is the pointer to the first entry stored into the cell _c + * @param second is the pointer to the last entry stored into the cell _c + * @note an entry is a pair composed by the simplex (e.g., a vertex, a face, ...) indexed by the grid and + * an integer representing a temporal time stamp + * @note the time stamp is not used here, it is used in the dynamic version of the spatial hashing + */ void Grid( const Point3i & _c, CellIterator & first, CellIterator & last ) { IteHtable I; if (_IsInHtable(_c,I))//if there is the cell then - { ///return pointers to first and last element cell elems - first= &*(*I).second._entries.begin(); - last= &*(*I).second._entries.end(); + { + // (*I) is the pair corresponding to _c + // (*I).second is the cell + // (*I).second._entries is the vector of simplices stored into the cell + // (*I).second._entries.begin() is the pointer to the first entry + // *(*I).second._entries.begin() is the pointer to the pointer to the first entry + // &*(*I).second._entries.begin() is the address of the pointer to the pointer to the first entry (hooray) + + // WARNING : (*I).second._entries.end() does not point to an entry, it is just a marker to end + // of the vector + first = &(*(*I).second._entries.begin()); + last= &*((*I).second._entries.end() - 1); } else { ///return 2 equals pointers - first=&*(*hash_table.begin()).second._entries.begin(); - last= &*(*hash_table.begin()).second._entries.begin(); + first =&(*(*hash_table.begin()).second._entries.begin()); + last = &(*((*hash_table.begin()).second._entries.begin() )); } }