resolved hash code conflicts
This commit is contained in:
parent
536ba5ab48
commit
cd855e4e57
|
|
@ -24,6 +24,9 @@
|
|||
History
|
||||
|
||||
$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
|
||||
ClosestK added and other minor changes
|
||||
|
||||
|
|
@ -71,156 +74,326 @@ public:
|
|||
typedef typename CoordType::ScalarType ScalarType;
|
||||
|
||||
|
||||
//element of a cell
|
||||
typedef typename std::pair<ElemType*,int> MapCellElem;
|
||||
//type of entries element of a cell
|
||||
typedef typename std::pair<ElemType*,int> EntryType;
|
||||
|
||||
//element stored in the hash table
|
||||
//This Class Identify the cell
|
||||
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
|
||||
typedef typename std::map<ElemType*,int>::iterator IteMap;
|
||||
|
||||
std::map<ElemType*,int> elem;
|
||||
//int flag;
|
||||
|
||||
public:
|
||||
|
||||
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));
|
||||
// flag=0;
|
||||
_entries.insert(EntryType(sim,_tempMark));
|
||||
min=_min;
|
||||
max=_max;
|
||||
assert(min<max);
|
||||
cell_n=_cell;
|
||||
}
|
||||
|
||||
///return true if the element is in the cell
|
||||
bool IsIn(ElemType* sim)
|
||||
{
|
||||
int n=elem.count(sim);
|
||||
{int n=elem.count(sim);
|
||||
return (n==1);
|
||||
}
|
||||
|
||||
///return the number of elements stored in the cell
|
||||
int Size()
|
||||
{
|
||||
return (int)(elem.size());
|
||||
}
|
||||
{return (int)(_entries.size());}
|
||||
|
||||
///update or insert an element into a cell
|
||||
void Update(ElemType* sim, const int & _tempMark)
|
||||
{
|
||||
std::pair<IteMap, bool> 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;
|
||||
}
|
||||
IteMap I=_entries.find(sim);
|
||||
|
||||
if (I!=_entries.end())//the entry exist in the cell
|
||||
(*I).second=_tempMark;
|
||||
else
|
||||
_entries.insert(_entries.begin(),EntryType(sim,_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
|
||||
void Elems(const int & _tempMark,std::vector<ElemType*> & res)
|
||||
///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(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;
|
||||
int t=(*ite).second;
|
||||
if ((!sim->IsD())&&(t>=_tempMark))
|
||||
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)
|
||||
{return (cell_n==h.CellN());}
|
||||
|
||||
bool operator !=(const HElement &h)
|
||||
{return ((cell_n!=h.CellN()));}
|
||||
|
||||
|
||||
}; // end struct HElement
|
||||
|
||||
|
||||
///this Iterator returns all the elements that
|
||||
///are in a specified box.
|
||||
struct ClosersIterator{
|
||||
|
||||
private:
|
||||
CoordType p;
|
||||
SpatialHashTable<ElemType> * sh;
|
||||
vcg::Point3i mincorner,maxcorner;
|
||||
ScalarType sq_radius;
|
||||
SpatialHashTable<ElemType> * 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
|
||||
|
||||
// current position
|
||||
vcg::Point3i curr_ic; // triple corresponding to the cell
|
||||
HElement * curr_c; // current cell
|
||||
typename HElement::IteMap curr_i; // current iterator
|
||||
bool end;
|
||||
|
||||
bool Advance(){
|
||||
if(curr_ic[0] < maxcorner[0]) ++curr_ic[0];
|
||||
///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];
|
||||
if(curr_ic[1] < maxcorner[1])
|
||||
++curr_ic[1];
|
||||
else{
|
||||
if(curr_ic[2] < maxcorner[2]) ++curr_ic[2];
|
||||
if(curr_ic[2] < maxcorner[2])
|
||||
++curr_ic[2];
|
||||
else
|
||||
return false;
|
||||
end=true;
|
||||
curr_ic[1] = mincorner[1];
|
||||
}
|
||||
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 ++() {
|
||||
bool isempty = true;
|
||||
HElement::IteMap e = curr_c->elem.end();
|
||||
//operator Next
|
||||
//go to next simplex without considering temporary mark
|
||||
void Next() {
|
||||
SpatialHashTable<ElemType>::IteHtable I;
|
||||
|
||||
HElement::IteMap e = curr_c->_entries.end();
|
||||
--e;
|
||||
|
||||
///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{
|
||||
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();
|
||||
///Advance until find a cell that isn't empty or the scan is complete
|
||||
Advance();
|
||||
|
||||
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
|
||||
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 *(){
|
||||
return (*curr_i).first;
|
||||
}
|
||||
|
||||
///return true if the scanning of elements is complete
|
||||
bool End(){
|
||||
//bool __ = (curr_i == curr_c->elem.end());
|
||||
//return ( (curr_ic == maxcorner) && (curr_i == curr_c->elem.end()) );
|
||||
return end;
|
||||
}
|
||||
|
||||
}; // end struct CloserIterator
|
||||
|
||||
|
||||
//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
|
||||
typedef typename std::pair<int,HElement> HRecord;
|
||||
//iterator to the hash table
|
||||
|
|
@ -229,6 +402,7 @@ public:
|
|||
SpatialHashTable(){};
|
||||
~SpatialHashTable(){};
|
||||
|
||||
private:
|
||||
|
||||
//ContSimplex & _simplex;
|
||||
int tempMark;
|
||||
|
|
@ -241,56 +415,73 @@ public:
|
|||
CoordType min;
|
||||
CoordType max;
|
||||
|
||||
int conflicts;
|
||||
/*Point3i min;
|
||||
Point3i max;*/
|
||||
|
||||
void Init(CoordType _min,CoordType _max,ScalarType _l)
|
||||
{
|
||||
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)
|
||||
///insert a new cell
|
||||
void _InsertNewHentry(ElemType* 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
|
||||
CoordType _min;
|
||||
CoordType _max;
|
||||
_min=CellToPoint(cell);
|
||||
_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
|
||||
{
|
||||
IteHtable HI=hash_table.find(h);
|
||||
// (*HI).second.flag|=_flag;
|
||||
(*HI).second.Update(s,tempMark);
|
||||
}
|
||||
}
|
||||
////std::pair<Htable::const_iterator, Htable::const_iterator> p =hash_table.equal_range(h);
|
||||
std::pair<IteHtable, IteHtable> p =hash_table.equal_range(h);
|
||||
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);
|
||||
for (std::vector<Point3i>::iterator bi=box.begin();bi<box.end();bi++)
|
||||
InsertInCell(s,*bi);
|
||||
return box;
|
||||
conflicts++;
|
||||
return false;
|
||||
}
|
||||
else ///we have found the right cell
|
||||
{
|
||||
result=i;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<class ContElemType>
|
||||
void AddElems( ContElemType & elem_set)
|
||||
///insert an element in a specified cell if the cell doesn't exist than
|
||||
///create it.
|
||||
void _InsertInCell(ElemType* s,Point3i cell)
|
||||
{
|
||||
typename ContElemType::iterator i;
|
||||
for(i = elem_set.begin(); i!= elem_set.end(); ++i)
|
||||
AddElem(&(*i));
|
||||
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);
|
||||
}
|
||||
|
||||
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();
|
||||
Point3i MinI=Cell(_min);
|
||||
Point3i MaxI=Cell(_max);
|
||||
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));
|
||||
|
|
@ -302,17 +493,91 @@ public:
|
|||
Point3i cell=Point3i(MinI.V(0)+x,MinI.V(1)+y,MinI.V(2)+z);
|
||||
ret.push_back(cell);
|
||||
}
|
||||
return ret;
|
||||
assert(ret.size()!=0);
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
template <class A>
|
||||
bool usefirst(const A & a,const A & b)const {return a.first < b.first;}
|
||||
/*void getAtCell(Point3i _c,std::vector<ElemType*> & res)
|
||||
{
|
||||
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,
|
||||
ElemType* e,
|
||||
std::vector<ElemType*>& res) {
|
||||
///add to the vector the simplexes with that eddress
|
||||
void getAtCell(Point3i _c,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;
|
||||
std::vector<ElemDist > neigh_dist;
|
||||
std::vector<ElemDist >::iterator ite_nd;
|
||||
|
|
@ -333,7 +598,7 @@ public:
|
|||
|
||||
int x,y,z;
|
||||
vcg::Point3i mincorner,maxcorner,c;
|
||||
c = Cell(p);
|
||||
c = PointToCell(p);
|
||||
mincorner = maxcorner = c;
|
||||
neigh_dist.push_back(ElemDist(-1,e));
|
||||
ite_nd = neigh_dist.begin();
|
||||
|
|
@ -389,8 +654,7 @@ public:
|
|||
ClosersIterator cli;
|
||||
cli.Init(this,p,radius);
|
||||
while(!cli.End()){
|
||||
if ( (((*cli)->P() -p )*((*cli)->P() -p ) < radius*radius) &&
|
||||
(*cli.curr_i).second >= tempMark)
|
||||
if ( (((*cli)->P() -p )*((*cli)->P() -p ) < radius*radius))// &&(*cli.curr_i).second >= tempMark)
|
||||
closers.push_back(*cli);
|
||||
++cli;
|
||||
}
|
||||
|
|
@ -404,15 +668,15 @@ public:
|
|||
|
||||
inline Point3i MinCell()
|
||||
{
|
||||
return Cell(min);
|
||||
return PointToCell(min);
|
||||
}
|
||||
|
||||
inline Point3i MaxCell()
|
||||
{
|
||||
return Cell(max);
|
||||
return PointToCell(max);
|
||||
}
|
||||
|
||||
inline int numElemCell(Point3i _c)
|
||||
/*inline int numElemCell(Point3i _c)
|
||||
{
|
||||
int h=Hash(_c);
|
||||
if (hash_table.count(h)==0)
|
||||
|
|
@ -422,58 +686,66 @@ public:
|
|||
IteHtable Ih=hash_table.find(h);
|
||||
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);
|
||||
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 std::vector<ElemType> getAt(CoordType _p,std::vector<ElemType> & res)
|
||||
//{
|
||||
// std::vector<ElemType> result;
|
||||
// Point3i c=Cell(_p);
|
||||
// return (getAtCell(c,res));
|
||||
//}
|
||||
void UpdateTmark()
|
||||
{tempMark++;}
|
||||
|
||||
void getAtCell(Point3i _c,std::vector<ElemType*> & res)
|
||||
///only debug
|
||||
void DrawCell(HElement &c)
|
||||
{
|
||||
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));
|
||||
}
|
||||
glPushMatrix();
|
||||
glTranslate(c.Min()+vcg::Point3d(l/2,l/2,l/2));
|
||||
glutWireCube(l);
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
const Point3i Cell(const CoordType & p) const
|
||||
void Draw()
|
||||
{
|
||||
int x=(int)floor(p.V(0)/l);
|
||||
int y=(int)floor(p.V(1)/l);
|
||||
int z=(int)floor(p.V(2)/l);
|
||||
return Point3i(x,y,z);
|
||||
for (IteHtable I=hash_table.begin();I!=hash_table.end();I++)
|
||||
DrawCell((*I).second);
|
||||
}
|
||||
|
||||
// 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[2]-min[2] )* dim[0]*dim[1] +
|
||||
// ( p[1]-min[1] )* dim[1] +
|
||||
// ( p[0]-min[0] );
|
||||
}
|
||||
private:
|
||||
|
||||
///only debug
|
||||
|
||||
}; // end class
|
||||
|
||||
}// end namespace
|
||||
|
|
|
|||
Loading…
Reference in New Issue