resolved hash code conflicts

This commit is contained in:
Nico Pietroni 2005-06-01 13:47:59 +00:00
parent 536ba5ab48
commit cd855e4e57
1 changed files with 621 additions and 349 deletions

View File

@ -24,6 +24,9 @@
History History
$Log: not supported by cvs2svn $ $Log: not supported by cvs2svn $
Revision 1.5 2005/03/15 09:50:44 ganovelli
there was a debug line, now removed
Revision 1.4 2005/03/14 15:11:18 ganovelli Revision 1.4 2005/03/14 15:11:18 ganovelli
ClosestK added and other minor changes ClosestK added and other minor changes
@ -49,178 +52,348 @@ added vcg header
#include <vector> #include <vector>
#include <algorithm> #include <algorithm>
#ifdef WIN32 #ifdef WIN32
#include <hash_map> #include <hash_map>
#define STDEXT stdext #define STDEXT stdext
#else #else
#include <ext/hash_map> #include <ext/hash_map>
#define STDEXT __gnu_cxx #define STDEXT __gnu_cxx
#endif #endif
namespace vcg{ namespace vcg{
/** Spatial Hash Table /** Spatial Hash Table
Spatial Hashing as described in Spatial Hashing as described in
"Optimized Spatial Hashing for Collision Detection of Deformable Objects", "Optimized Spatial Hashing for Collision Detection of Deformable Objects",
Matthias Teschner and Bruno Heidelberger and Matthias Muller and Danat Pomeranets and Markus Gross Matthias Teschner and Bruno Heidelberger and Matthias Muller and Danat Pomeranets and Markus Gross
*/ */
template <class ElemType> template <class ElemType>
class SpatialHashTable{ class SpatialHashTable{
public: public:
typedef typename ElemType::CoordType CoordType; typedef typename ElemType::CoordType CoordType;
typedef typename CoordType::ScalarType ScalarType; typedef typename CoordType::ScalarType ScalarType;
//element of a cell //type of entries element of a cell
typedef typename std::pair<ElemType*,int> MapCellElem; typedef typename std::pair<ElemType*,int> EntryType;
//element stored in the hash table //This Class Identify the cell
struct HElement struct HElement
{ {
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
Point3i cell_n;//cell number
public:
//elements
std::map<ElemType*,int> _entries;
//iterator to the map element into the cell //iterator to the map element into the cell
typedef typename std::map<ElemType*,int>::iterator IteMap; typedef typename std::map<ElemType*,int>::iterator IteMap;
std::map<ElemType*,int> elem;
//int flag;
public:
HElement() HElement()
{ {}
// flag=0;
}
HElement(ElemType* sim,const int &_tempMark) HElement(ElemType* sim,const int &_tempMark,CoordType _min,CoordType _max,Point3i _cell)
{ {
elem.insert(MapCellElem(sim,_tempMark)); _entries.insert(EntryType(sim,_tempMark));
// flag=0; min=_min;
max=_max;
assert(min<max);
cell_n=_cell;
} }
///return true if the element is in the cell ///return true if the element is in the cell
bool IsIn(ElemType* sim) bool IsIn(ElemType* sim)
{ {int n=elem.count(sim);
int n=elem.count(sim);
return (n==1); return (n==1);
} }
///return the number of elements stored in the cell
int Size() int Size()
{ {return (int)(_entries.size());}
return (int)(elem.size());
}
///update or insert an element into a cell ///update or insert an element into a cell
void Update(ElemType* sim, const int & _tempMark) void Update(ElemType* sim, const int & _tempMark)
{ {
std::pair<IteMap, bool> res=elem.insert(MapCellElem(sim,_tempMark)); IteMap I=_entries.find(sim);
//the element was already in the map structure so update the temporary mark
if (res.second==false) if (I!=_entries.end())//the entry exist in the cell
{ (*I).second=_tempMark;
//update the temporary mark else
IteMap ite=res.first; _entries.insert(_entries.begin(),EntryType(sim,_tempMark));
(*ite).second=_tempMark;
} //at the end update the temporary mark on the simplex
sim->Mark()=_tempMark;
} }
//return an array of all simplexes of the map that have a right timestamp or are not deleted ///given an iterator to the instance of the entry in the cell
void Elems(const int & _tempMark,std::vector<ElemType*> & res) ///return true if the the entry is valid
///(using temporary mark).
bool IsUpdated(IteMap &I)
{ {
/* if ((*I).second >= (*I).first->Mark())
return true;
else
{
printf("DISUPDATED\N");
return false;
}*/
return ((*I).second >= (*I).first->Mark());
}
for (IteMap ite=elem.begin();ite!=elem.end();ite++) ///given an simplex pointer
///return true if the the entry corripondent to that
///simplex is valid or not
///(using temporary mark).
bool IsUpdated(ElemType* sim)
{
IteMap I=_entries.find(sim);
if (I!=_entries.end())
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<ElemType*> & res)
{
for (IteMap ite=_entries.begin();ite!=_entries.end();ite++)
{ {
ElemType* sim=(*ite).first; ElemType* sim=(*ite).first;
int t=(*ite).second; if (IsUpdated(ite)&&(!sim->IsD()))
if ((!sim->IsD())&&(t>=_tempMark))
res.push_back(sim); res.push_back(sim);
} }
} }
CoordType Min()
{return min;}
CoordType Max()
{return max;}
Point3i CellN()
{return cell_n;}
bool operator ==(const HElement &h)
{return (cell_n==h.CellN());}
bool operator !=(const HElement &h)
{return ((cell_n!=h.CellN()));}
}; // end struct HElement }; // end struct HElement
///this Iterator returns all the elements that
///are in a specified box.
struct ClosersIterator{ struct ClosersIterator{
private:
CoordType p; CoordType p;
SpatialHashTable<ElemType> * sh; SpatialHashTable<ElemType> * sh; ///pointer to spatial hash table structure
vcg::Point3i mincorner,maxcorner; vcg::Point3i mincorner,maxcorner; ///corners of the box where the scannig is performed
ScalarType sq_radius; 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
// current position ///advance the current coordinate of one step inside the space box
vcg::Point3i curr_ic; // triple corresponding to the cell ///set and to true if scannig fo cells is complete
HElement * curr_c; // current cell void Advance(){
typename HElement::IteMap curr_i; // current iterator if(curr_ic[0] < maxcorner[0])
bool end; ++curr_ic[0];
bool Advance(){
if(curr_ic[0] < maxcorner[0]) ++curr_ic[0];
else{ else{
if(curr_ic[1] < maxcorner[1]) ++curr_ic[1]; if(curr_ic[1] < maxcorner[1])
++curr_ic[1];
else{ else{
if(curr_ic[2] < maxcorner[2]) ++curr_ic[2]; if(curr_ic[2] < maxcorner[2])
++curr_ic[2];
else else
return false; end=true;
curr_ic[1] = mincorner[1]; curr_ic[1] = mincorner[1];
} }
curr_ic[0] = mincorner[0]; curr_ic[0] = mincorner[0];
} }
curr_c = &(*(sh->hash_table.find(sh->Hash(curr_ic)))).second;
return true;
}
void Init(SpatialHashTable<ElemType> * _sh, CoordType _p, const ScalarType &_radius)
{
sh = _sh;
p =_p;
CoordType halfDiag(_radius,_radius,_radius);
mincorner = sh->Cell(p-halfDiag);
maxcorner = sh->Cell(p+halfDiag);
curr_ic = mincorner;
sq_radius = _radius * _radius;
IteHtable iht = sh->hash_table.find(sh->Hash(curr_ic));
// initialize the iterator to the first element
bool isempty = (iht == sh->hash_table.end());
if(isempty)
while( Advance() && (isempty=sh->IsEmptyCell(curr_ic)));
if(!isempty){
curr_c = &(*(sh->hash_table.find(sh->Hash(curr_ic)))).second;
curr_i = curr_c->elem.begin();
end = false;
}
else
end = true;
} }
void operator ++() { //operator Next
bool isempty = true; //go to next simplex without considering temporary mark
HElement::IteMap e = curr_c->elem.end(); void Next() {
SpatialHashTable<ElemType>::IteHtable I;
HElement::IteMap e = curr_c->_entries.end();
--e; --e;
///if the current index
//is not at the end of element in the cell so advance of one step
if(curr_i != e) if(curr_i != e)
++curr_i; ++curr_i;
else{ else{
while( Advance() && (isempty=sh->IsEmptyCell(curr_ic))); ///Advance until find a cell that isn't empty or the scan is complete
if(!isempty){ Advance();
curr_c = &(*(sh->hash_table.find(sh->Hash(curr_ic)))).second;
curr_i = curr_c->elem.begin(); while((!End())&&(sh->numElemCell(curr_ic,I)==0))
{Advance();}
if (!End())
{
curr_c = &((*I).second);
curr_i = curr_c->_entries.begin();
}
}
}
public:
/////Initialize the iterator, p is the center of the box and _edge is his size
//void Init(SpatialHashTable<ElemType> * _sh, CoordType _p, const ScalarType &_edge)
//{
// sh = _sh;
// p =_p;
// ///find the box
// CoordType halfDiag(_edge,_edge,_edge);
// mincorner = sh->PointToCell(p-halfDiag);
// maxcorner = sh->PointToCell(p+halfDiag);
// ///set the initial cell of the iterator as the one that stay on the
// /// left lower position
// curr_ic = mincorner;
// ///find the cell corrisponding to first podsition
// IteHtable iht = sh->hash_table.find(sh->Hash(curr_ic));
// ///advance until find a cell that contain at least one updated element
// //and initialize the current cell and iterator inside it
// bool isempty = (iht == sh->hash_table.end());
// if(isempty)
// 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();
// end = false;
// }
// else
// end = true;
//}
void AssertUpdated()
{
ScalarType Xs=(*curr_i).first->P().X();
ScalarType Ys=(*curr_i).first->P().Y();
ScalarType Zs=(*curr_i).first->P().Z();
ScalarType Xm=curr_c->Min().X();
ScalarType Ym=curr_c->Min().Y();
ScalarType Zm=curr_c->Min().Z();
ScalarType XM=curr_c->Max().X();
ScalarType YM=curr_c->Max().Y();
ScalarType ZM=curr_c->Max().Z();
if ((Xs<Xm)||(Xs>XM)||(Ys<Ym)||(Ys>YM)||(Zs<Zm)||(Zs>ZM))
printf("ERROR %d %d %d %d %d");
}
///Initialize the iterator, p is the center of the box and _edge is his size
void Init(SpatialHashTable<ElemType> * _sh, CoordType _p, const ScalarType &_edge)
{
end=false;
sh = _sh;
p =_p;
SpatialHashTable<ElemType>::IteHtable I;
///find the box
CoordType halfDiag(_edge,_edge,_edge);
mincorner = sh->PointToCell(p-halfDiag);
maxcorner = sh->PointToCell(p+halfDiag);
///set the initial cell of the iterator as the one that stay on the
/// left lower position
curr_ic = mincorner;
//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 else
end = true; {///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();
} }
} }
}
/////operator ++ of the itearator
//void Next() {
// bool isempty = true;
// HElement::IteMap e = curr_c->_entries.end();
// --e;
// ///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;
// ///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;
// }
//}
///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 *(){ ElemType * operator *(){
return (*curr_i).first; return (*curr_i).first;
} }
///return true if the scanning of elements is complete
bool End(){ bool End(){
//bool __ = (curr_i == curr_c->elem.end());
//return ( (curr_ic == maxcorner) && (curr_i == curr_c->elem.end()) );
return end; return end;
} }
}; // end struct CloserIterator }; // end struct CloserIterator
//hash table definition //hash table definition
typedef typename STDEXT::hash_map<int,HElement> Htable; //typedef typename STDEXT::hash_map<int,HElement> Htable;
typedef typename STDEXT::hash_multimap<int,HElement> Htable;
//hash table definition
//typedef typename STDEXT::hash_map<vcg::Point3i,HElement> Htable;
//record of the hash table //record of the hash table
typedef typename std::pair<int,HElement> HRecord; typedef typename std::pair<int,HElement> HRecord;
//iterator to the hash table //iterator to the hash table
@ -229,6 +402,7 @@ public:
SpatialHashTable(){}; SpatialHashTable(){};
~SpatialHashTable(){}; ~SpatialHashTable(){};
private:
//ContSimplex & _simplex; //ContSimplex & _simplex;
int tempMark; int tempMark;
@ -241,56 +415,73 @@ public:
CoordType min; CoordType min;
CoordType max; CoordType max;
int conflicts;
/*Point3i min;
Point3i max;*/
void Init(CoordType _min,CoordType _max,ScalarType _l) ///insert a new cell
{ void _InsertNewHentry(ElemType* s,Point3i cell)
min=_min;
max=_max;
l=_l;
CoordType d=max-min;
//num = (int) floor(d.V(0)*d.V(1)*d.V(2)/l);
num = (int) floor(100*d.V(0)*d.V(1)*d.V(2)/l);
tempMark=0;
}
void InsertInCell(ElemType* s,Point3i cell)
{ {
int h=Hash(cell); int h=Hash(cell);
//insert a cell if there isn't CoordType _min;
if (hash_table.count(h)==0) CoordType _max;
hash_table.insert(HRecord(h,HElement(s,tempMark))); _min=CellToPoint(cell);
//otherwise insert the element or update the temporary mark _max=_min+CoordType(l,l,l);
hash_table.insert(HRecord(h,HElement(s,tempMark,_min,_max,cell)));
s->Mark()=tempMark;
}
bool _IsInHtable(Point3i cell,IteHtable &result)
{
int h=Hash(cell);
int count=hash_table.count(h);
if (count==0)///in this case there is no entry for that key
return false;
else else
{ {
IteHtable HI=hash_table.find(h); ////std::pair<Htable::const_iterator, Htable::const_iterator> p =hash_table.equal_range(h);
// (*HI).second.flag|=_flag; std::pair<IteHtable, IteHtable> p =hash_table.equal_range(h);
(*HI).second.Update(s,tempMark); IteHtable i = p.first;
}
}
while((i != p.second)&&((*i).second.CellN()!=cell))++i;
std::vector<Point3i> AddElem( ElemType* s) if (i==p.second)///the scan is terminated and we have not fuond the cell
{ {
std::vector<Point3i> box=BoxCells(s->BBox().min,s->BBox().max); conflicts++;
for (std::vector<Point3i>::iterator bi=box.begin();bi<box.end();bi++) return false;
InsertInCell(s,*bi); }
return box; else ///we have found the right cell
{
result=i;
return true;
}
}
} }
template<class ContElemType> ///insert an element in a specified cell if the cell doesn't exist than
void AddElems( ContElemType & elem_set) ///create it.
void _InsertInCell(ElemType* s,Point3i cell)
{ {
typename ContElemType::iterator i; IteHtable I;
for(i = elem_set.begin(); i!= elem_set.end(); ++i) if (!_IsInHtable(cell,I))
AddElem(&(*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);
} }
std::vector<Point3i> BoxCells(CoordType _min,CoordType _max) // 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 the cells intersected by the Bounding box of the simplex
void BoxCells(CoordType _min,CoordType _max,std::vector<Point3i>& ret)
{ {
std::vector<Point3i> ret;
ret.clear(); ret.clear();
Point3i MinI=Cell(_min); Point3i MinI=PointToCell(_min);
Point3i MaxI=Cell(_max); Point3i MaxI=PointToCell(_max);
int dimx=abs(MaxI.V(0)-MinI.V(0)); int dimx=abs(MaxI.V(0)-MinI.V(0));
int dimy=abs(MaxI.V(1)-MinI.V(1)); int dimy=abs(MaxI.V(1)-MinI.V(1));
int dimz=abs(MaxI.V(2)-MinI.V(2)); int dimz=abs(MaxI.V(2)-MinI.V(2));
@ -302,17 +493,91 @@ public:
Point3i cell=Point3i(MinI.V(0)+x,MinI.V(1)+y,MinI.V(2)+z); Point3i cell=Point3i(MinI.V(0)+x,MinI.V(1)+y,MinI.V(2)+z);
ret.push_back(cell); ret.push_back(cell);
} }
return ret; assert(ret.size()!=0);
} }
//********************************************************************* /*void getAtCell(Point3i _c,std::vector<ElemType*> & res)
template <class A> {
bool usefirst(const A & a,const A & b)const {return a.first < b.first;} std::vector<ElemType> result;
int h=Hash(_c);
if (numElemCell(_c)!=0){
IteHtable h_res=hash_table.find(h);
((*h_res).second.Elems(tempMark,res));
}
}*/
int ClosestK(const int& k, ///add to the vector the simplexes with that eddress
ElemType* e, void getAtCell(Point3i _c,std::vector<ElemType*> & res)
std::vector<ElemType*>& res) { {
int h=Hash(_c);
IteHtable I;
if (_IsInHtable(_c,I))//if there is the cell then
(*I).second.Elems(res);
}
Point3i PointToCell(CoordType p)
{
int x=(int)floor((p.V(0)-(ScalarType)min.V(0))/l);
int y=(int)floor((p.V(1)-(ScalarType)min.V(1))/l);
int z=(int)floor((p.V(2)-(ScalarType)min.V(2))/l);
return (vcg::Point3i(x,y,z));
}
CoordType CellToPoint(Point3i c)
{
ScalarType x=(((ScalarType)c.V(0)+min.V(0))*l);
ScalarType y=(((ScalarType)c.V(1)+min.V(1))*l);
ScalarType z=(((ScalarType)c.V(2)+min.V(2))*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)
{
l=_l;
min=_min;
max=_max;
num=HashSpace;
tempMark=0;
conflicts=0;
}
std::vector<Point3i> AddElem( ElemType* s)
{
std::vector<Point3i> box;
BoxCells(s->BBox().min,s->BBox().max,box);
for (std::vector<Point3i>::iterator bi=box.begin();bi<box.end();bi++)
_InsertInCell(s,*bi);
return box;
}
/*void AddElem( ElemType* s)
{
std::vector<Point3i> box;
BoxCells(s->BBox().min,s->BBox().max,box);
for (std::vector<Point3i>::iterator bi=box.begin();bi<box.end();bi++)
_InsertInCell(s,*bi);
}*/
template<class ContElemType>
void AddElems( ContElemType & elem_set)
{
typename ContElemType::iterator i;
for(i = elem_set.begin(); i!= elem_set.end(); ++i)
AddElem(&(*i));
}
////*********************************************************************
//template <class A>
// bool usefirst(const A & a,const A & b)const {return a.first < b.first;}
int ClosestK(const int& k,ElemType* e, std::vector<ElemType*>& res)
{
typedef std::pair<ScalarType,ElemType*> ElemDist; typedef std::pair<ScalarType,ElemType*> ElemDist;
std::vector<ElemDist > neigh_dist; std::vector<ElemDist > neigh_dist;
std::vector<ElemDist >::iterator ite_nd; std::vector<ElemDist >::iterator ite_nd;
@ -333,7 +598,7 @@ public:
int x,y,z; int x,y,z;
vcg::Point3i mincorner,maxcorner,c; vcg::Point3i mincorner,maxcorner,c;
c = Cell(p); c = PointToCell(p);
mincorner = maxcorner = c; mincorner = maxcorner = c;
neigh_dist.push_back(ElemDist(-1,e)); neigh_dist.push_back(ElemDist(-1,e));
ite_nd = neigh_dist.begin(); ite_nd = neigh_dist.begin();
@ -361,7 +626,7 @@ public:
( x == maxcorner[0]) ( x == maxcorner[0])
)++x; else x=maxcorner[0]; )++x; else x=maxcorner[0];
} }
// ,usefirst<ElemDist> ---<std::vector<ElemDist >::iterator > // ,usefirst<ElemDist> ---<std::vector<ElemDist >::iterator >
ite_nd =neigh_dist.begin(); ite_nd =neigh_dist.begin();
std::advance(ite_nd,res.size()); std::advance(ite_nd,res.size());
std::sort(ite_nd,neigh_dist.end()); std::sort(ite_nd,neigh_dist.end());
@ -379,7 +644,7 @@ public:
} }
return 0; return 0;
} }
//********************************************************************** //**********************************************************************
// return the elem closer than radius // return the elem closer than radius
@ -389,8 +654,7 @@ public:
ClosersIterator cli; ClosersIterator cli;
cli.Init(this,p,radius); cli.Init(this,p,radius);
while(!cli.End()){ while(!cli.End()){
if ( (((*cli)->P() -p )*((*cli)->P() -p ) < radius*radius) && if ( (((*cli)->P() -p )*((*cli)->P() -p ) < radius*radius))// &&(*cli.curr_i).second >= tempMark)
(*cli.curr_i).second >= tempMark)
closers.push_back(*cli); closers.push_back(*cli);
++cli; ++cli;
} }
@ -404,15 +668,15 @@ public:
inline Point3i MinCell() inline Point3i MinCell()
{ {
return Cell(min); return PointToCell(min);
} }
inline Point3i MaxCell() inline Point3i MaxCell()
{ {
return Cell(max); return PointToCell(max);
} }
inline int numElemCell(Point3i _c) /*inline int numElemCell(Point3i _c)
{ {
int h=Hash(_c); int h=Hash(_c);
if (hash_table.count(h)==0) if (hash_table.count(h)==0)
@ -422,59 +686,67 @@ public:
IteHtable Ih=hash_table.find(h); IteHtable Ih=hash_table.find(h);
return ((*Ih).second.Size()); return ((*Ih).second.Size());
} }
}*/
///return the number of elemnts in the cell ond the iterator to the cell
///if the cell exist
int numElemCell(Point3i _c,IteHtable &I)
{
int h=Hash(_c);
if (_IsInHtable(_c,I))
return ((*I).second.Size());
else
return 0;
} }
inline bool IsEmptyCell(Point3i _c) /*inline bool IsEmptyCell(Point3i _c)
{
return(numElemCell(_c)==0);
}*/
/*inline bool IsEmptyCell(Point3i _c)
{ {
int h=Hash(_c); int h=Hash(_c);
if (hash_table.count(h)==0) if (hash_table.count(h)==0)
return true; return true;
else else
return false; return false;
} }*/
///return the number of cell created
int CellNumber()
{return (hash_table.size());}
int Conflicts()
{return conflicts;}
void Clear() void Clear()
{ {
hash_table.clear(); hash_table.clear();
} }
//void std::vector<ElemType> getAt(CoordType _p,std::vector<ElemType> & res) void UpdateTmark()
//{ {tempMark++;}
// std::vector<ElemType> result;
// Point3i c=Cell(_p);
// return (getAtCell(c,res));
//}
void getAtCell(Point3i _c,std::vector<ElemType*> & res) ///only debug
void DrawCell(HElement &c)
{ {
std::vector<ElemType> result; glPushMatrix();
int h=Hash(_c); glTranslate(c.Min()+vcg::Point3d(l/2,l/2,l/2));
if (numElemCell(_c)!=0){ glutWireCube(l);
IteHtable h_res=hash_table.find(h); glPopMatrix();
((*h_res).second.Elems(tempMark,res));
}
} }
const Point3i Cell(const CoordType & p) const void Draw()
{ {
int x=(int)floor(p.V(0)/l); for (IteHtable I=hash_table.begin();I!=hash_table.end();I++)
int y=(int)floor(p.V(1)/l); DrawCell((*I).second);
int z=(int)floor(p.V(2)/l);
return Point3i(x,y,z);
} }
// hashing
const int Hash(Point3i p) const ///only debug
{
vcg::Point3i dim(100,100,100); }; // end class
return ((p.V(0)*P0 ^ p.V(1)*P1 ^ p.V(2)*P2)%num);
// return ( p[2]-min[2] )* dim[0]*dim[1] +
// ( p[1]-min[1] )* dim[1] +
// ( p[0]-min[0] );
}
private:
}; // end class
}// end namespace }// end namespace