From ea41fb5580dd58cc54651548d5b3f428bf4103ff Mon Sep 17 00:00:00 2001 From: nicopietroni Date: Thu, 16 Dec 2004 18:00:51 +0000 Subject: [PATCH] first release version --- vcg/space/index/spatial_hashing.h | 359 ++++++++++++++++++++++++++++++ 1 file changed, 359 insertions(+) create mode 100644 vcg/space/index/spatial_hashing.h diff --git a/vcg/space/index/spatial_hashing.h b/vcg/space/index/spatial_hashing.h new file mode 100644 index 00000000..76ba4a89 --- /dev/null +++ b/vcg/space/index/spatial_hashing.h @@ -0,0 +1,359 @@ +#ifndef SPATIAL_HASHING +#define SPATIAL_HASHING + +//#define P0 73856093 +//#define P1 19349663 +//#define P2 83492791 + +#define P0 73 +#define P1 19 +#define P2 83 + +#include +#include +#include + +template + +class SpatialHashTable{ + +public: + + typedef typename SimplexType* SimplexPointer; + typedef typename SimplexType::CoordType Point3x; + typedef typename Point3x::ScalarType ScalarType; + + + //iterator to the map element into the cell + typedef typename std::map::iterator IteMap; + //element of a cell + typedef typename std::pair MapCellElem; + + //element stored in the hash table + struct Helement + { + + std::map Elem; + //int flag; + + public: + + Helement() + { + // flag=0; + } + + Helement(SimplexType* sim,int _tempMark) + { + Elem.insert(MapCellElem(sim,_tempMark)); + // flag=0; + } + + ///return true if the element is in the cell + bool IsIn(SimplexType* sim) + { + int n=Elem.count(sim); + return (n==1); + } + + int Size() + { + return (Elem.size()); + } + + ///update or insert an element into a cell + void Update(SimplexType* sim,int _tempMark) + { + std::pair res=Elem.insert(MapCellElem(sim,_tempMark)); + //the element was already in the map structure so update the temporary mark + if (res.second==false) + { + //update the temporary mark + IteMap ite=res.first; + (*ite).second=_tempMark; + } + } + + //return an array of all simplexes of the map that have a right timastamp or are not deleted + std::vector Simplexes(int _tempMark) + { + std::vector result; + result.clear(); + for (IteMap ite=Elem.begin();ite!=Elem.end();ite++) + { + SimplexType* sim=(*ite).first; + int t=(*ite).second; + if ((!sim->IsD())&&(t>=_tempMark)) + result.push_back(sim); + } + return (result); + } + }; + + //enum { + // // First user bit + // USER0 = 0x0001 // First user bit + // }; + + //static int &LastBitFlag() + // { + // static int b =USER0; + // return b; + // } + + ///// allocate a bit among the flags that can be used by user. + //static inline int NewBitFlag() + // { + // LastBitFlag()=LastBitFlag()<<1; + // return LastBitFlag(); + // } + + //// de-allocate a bit among the flags that can be used by user. + //static inline bool DeleteBitFlag(int bitval) + // { + // if(LastBitFlag()==bitval) { + // LastBitFlag()= LastBitFlag()>>1; + // return true; + // } + // assert(0); + // return false; + // } + + //hash table definition + typedef typename std::hash_map Htable; + //record of the hash table + typedef typename std::pair HRecord; + //iterator to the hash table + typedef typename Htable::iterator IteHtable; + + + //SpatialHashTable(ContSimplex & r_):_simplex(r_){}; + SpatialHashTable(){}; + ~SpatialHashTable(){}; + + + //ContSimplex & _simplex; + int TempMark; + Htable hash_table; + + int num; + float l; + + + Point3x min; + Point3x max; + + + void Init(Point3x _min,Point3x _max,ScalarType _l) + { + min=_min; + max=_max; + l=_l; + Point3x d=max-min; + num=floor(d.V(0)*d.V(1)*d.V(2)/l); + TempMark=0; + } + + void InsertInCell(SimplexType* s,Point3i cell) + { + int h=Hash(cell); + //insert a cell if there isn't + if (hash_table.count(h)==0) + hash_table.insert(HRecord(h,Helement(s,TempMark))); + //otherwise insert the element or update the temporary mark + else + { + IteHtable HI=hash_table.find(h); +// (*HI).second.flag|=_flag; + (*HI).second.Update(s,TempMark); + } + } + + + std::vector addBox(SimplexType* s,Point3x _min,Point3x _max) + { + + std::vector box=BoxCells(_min,_max); + for (std::vector::iterator bi=box.begin();bi BoxCells(Point3x _min,Point3x _max) + { + std::vector ret; + ret.clear(); + Point3i MinI=Cell(_min); + Point3i MaxI=Cell(_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); + } + return ret; + } + + std::vector Cells(SimplexType *s) + { + Point3x min=Point3x((*s).V(0)->P()); + Point3x max=min; + + //find min max coordinate of bounding box + for (int i=1;i<3;i++) + { + if (min.V(0)>(*s).V(i)->P().V(0)) + min.V(0)=(*s).V(i)->P().V(0); + if (min.V(1)>(*s).V(i)->P().V(1)) + min.V(1)=(*s).V(i)->P().V(1); + if (min.V(2)>(*s).V(i)->P().V(2)) + min.V(2)=(*s).V(i)->P().V(2); + + if (max.V(0)<(*s).V(i)->P().V(0)) + max.V(0)=(*s).V(i)->P().V(0); + if (max.V(1)<(*s).V(i)->P().V(1)) + max.V(1)=(*s).V(i)->P().V(1); + if (max.V(2)>(*s).V(i)->P().V(2)) + max.V(2)=(*s).V(i)->P().V(2); + } + + return BoxCells(s,min,max); + } + + std::vector addSimplex(SimplexType *s) + { + Point3x min=Point3x((*s).V(0)->P()); + Point3x max=min; + + //find min max coordinate of bounding box + for (int i=1;i<3;i++) + { + if (min.V(0)>(*s).V(i)->P().V(0)) + min.V(0)=(*s).V(i)->P().V(0); + if (min.V(1)>(*s).V(i)->P().V(1)) + min.V(1)=(*s).V(i)->P().V(1); + if (min.V(2)>(*s).V(i)->P().V(2)) + min.V(2)=(*s).V(i)->P().V(2); + + if (max.V(0)<(*s).V(i)->P().V(0)) + max.V(0)=(*s).V(i)->P().V(0); + if (max.V(1)<(*s).V(i)->P().V(1)) + max.V(1)=(*s).V(i)->P().V(1); + if (max.V(2)>(*s).V(i)->P().V(2)) + max.V(2)=(*s).V(i)->P().V(2); + } + + ///now set the cell touched by the bounding box of the triangle + return (addBox(s,min,max)); + } + + inline Point3i MinCell() + { + return Cell(min); + } + + inline Point3i MaxCell() + { + return Cell(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()); + } + } + + ///refresh all the alement in the container + /*void RefreshElements() + { + TempMark++; + for (SimplexIterator si=_simplex.begin();si<_simplex.end();++si) + { + if (!(*si).IsD()) + addSimplex(&*si); + } + }*/ + + ///erase all element of the hash table where the timestamp is old + //void Clean() + //{ + // for (IteHtable Ih=hash_table.begin();Ih!=hash_table.end();Ih++) + // //if after clean there are no element erase the cell + // if ((*Ih).second.Clean(TempMark)) + // hash_table.erase(Ih); + //} + + /*void Clean() + { + hash_table.clear(); + RefreshElements(); + }*/ + + void Clear() + { + hash_table.clear(); + } + + /*int FlagCell(Point3i p) + { + int h=Hash(p); + if (hash_table.count(h)==0) + return 0; + else + { + IteHtable Ih=hash_table.find(h); + return ((*Ih).second.Flag()); + } + }*/ + + std::vector getAt(Point3x _p) + { + std::vector result; + Point3i c=Cell(p); + return (getAtCell(c)); + } + + std::vector getAtCell(Point3i _c) + { + std::vector result; + int h=Hash(_c); + if (numElemCell(_c)==0) + { + return result; + } + else + { + IteHtable res=hash_table.find(h); + return ((*res).second.Simplexes(TempMark)); + } + } + + +private: + + Point3i Cell(Point3x p) + { + int x=floor(p.V(0)/l); + int y=floor(p.V(1)/l); + int z=floor(p.V(2)/l); + return Point3i(x,y,z); + } + + int Hash(Point3i p) + { + return ((p.V(0)*P0 ^ p.V(1)*P1 ^ p.V(2)*P2)%num); + } + +}; +#endif \ No newline at end of file