|
cgma
|
#include <WeightedOctree.hpp>
Classes | |
| class | Cell |
Public Member Functions | |
| WeightedOctree (int max_weight_per_box, double tolerance=1e-6) | |
| ~WeightedOctree () | |
| bool | initilizeTree (std::vector< X > &nodes, std::vector< Cell * > &newCells) |
| void | clear () |
| bool | addNode (const X &node, std::vector< Cell * > &oldCells, std::vector< Cell * > &newCells, std::vector< Cell * > &modifiedCells) |
| bool | removeNode (X &node, std::vector< Cell * > &oldCells, std::vector< Cell * > &newCells, std::vector< Cell * > &modifiedCells) |
Protected Member Functions | |
| bool | calculateCellCenter (Cell *cell) |
| void | mergeCellChildren (Cell *cell, std::vector< Cell * > &oldLeafs) |
| bool | splitCell (Cell *cell, std::vector< Cell * > &newLeafs) |
| bool | rebalanceBranch (Cell *cell, std::vector< Cell * > &oldLeafs, std::vector< Cell * > &newLeafs) |
| bool | recursiveSplitCell (Cell *cell, std::vector< Cell * > &newLeafs) |
Protected Attributes | |
| int | MaxBoxWeight |
| Cell * | Root |
| int | TotalWeight |
| std::map< X, Cell * > | NodeToCellMap |
| double | Tolerance |
| double | ToleranceSquared |
Definition at line 46 of file WeightedOctree.hpp.
| WeightedOctree< X, C, E >::WeightedOctree | ( | int | max_weight_per_box, |
| double | tolerance = 1e-6 |
||
| ) |
Definition at line 30 of file WeightedOctree.cpp.
{
this->Tolerance = tolerance < GEOMETRY_RESABS ? GEOMETRY_RESABS : tolerance;
this->ToleranceSquared=this->Tolerance*this->Tolerance;
this->MaxBoxWeight= max_weight_per_box < 0 ? DEFAULT_MAX_WEIGHT_PER_BOX : max_weight_per_box;
this->Root = new Cell();
}
| WeightedOctree< X, C, E >::~WeightedOctree | ( | ) |
Definition at line 50 of file WeightedOctree.cpp.
| bool WeightedOctree< X, C, E >::addNode | ( | const X & | node, |
| std::vector< Cell * > & | oldCells, | ||
| std::vector< Cell * > & | newCells, | ||
| std::vector< Cell * > & | modifiedCells | ||
| ) |
Definition at line 59 of file WeightedOctree.cpp.
{
newCells.clear();
oldCells.clear();
modifiedCells.clear();
Cell* currentCell=this->Root;
CubitVector coords = E::coordinates(node);
int weight=E::weight(node);
while(!currentCell->leaf())
{
int x = coords.x() < currentCell->center().x() ? Cell::X_MIN : Cell::X_MAX;
int y = coords.y() < currentCell->center().y() ? Cell::Y_MIN : Cell::Y_MAX;
int z = coords.z() < currentCell->center().z() ? Cell::Z_MIN : Cell::Z_MAX;
currentCell=currentCell->child(x|y|z);
}
currentCell->addNode(node);
currentCell->addWeight(weight);
this->NodeToCellMap[node]=currentCell;
Cell* currentParent=currentCell->parent();
while(currentParent)
{
currentParent->addWeight(weight);
currentParent=currentParent->parent();
}
typename std::map<X,Cell*>::iterator nodeIter;
if(currentCell->weight()>this->MaxBoxWeight && currentCell->nodeCount()>=2)
{
//Try to rebalance first.
if(currentCell->parent())
{
if(this->rebalanceBranch(currentCell->parent(),oldCells,newCells))
{
for(unsigned int i=0;i<newCells.size();i++)
{
Cell* cell=newCells[i];
std::vector<X> cellNodes;
cell->appendNodes(cellNodes);
for(unsigned int j=0;j<cellNodes.size();j++)
{
X& localNode=cellNodes[j];
nodeIter=this->NodeToCellMap.find(localNode);
if(nodeIter!=this->NodeToCellMap.end())
{
E::setLastCell(localNode,nodeIter->second);
}
this->NodeToCellMap[localNode]=cell;
}
}
return true;
}
}
//didn't rebalance so
//Try to split
if(this->splitCell(currentCell,newCells))
{
//The cell was split. We need to update the node map.
for(unsigned int i=0;i<newCells.size();i++)
{
Cell* cell=newCells[i];
std::vector<X> cellNodes;
cell->appendNodes(cellNodes);
for(unsigned int j=0;j<cellNodes.size();j++)
{
X& localNode=cellNodes[j];
nodeIter=this->NodeToCellMap.find(localNode);
if(nodeIter!=this->NodeToCellMap.end())
{
E::setLastCell(localNode,nodeIter->second);
}
this->NodeToCellMap[localNode]=cell;
}
}
oldCells.push_back(currentCell);
}
else
{
//the cells wasn't split
if(currentCell->nodeCount()==1)
{
newCells.push_back(currentCell);
}
else
{
modifiedCells.push_back(currentCell);
}
}
}
else
{
if(currentCell->nodeCount()==1)
{
newCells.push_back(currentCell);
}
else
{
modifiedCells.push_back(currentCell);
}
}
return true;
}
| bool WeightedOctree< X, C, E >::calculateCellCenter | ( | Cell * | cell | ) | [protected] |
Definition at line 260 of file WeightedOctree.cpp.
{
if(cell->nodeCount()==0)
{
return false;
}
std::vector<X> nodes;
cell->appendNodes(nodes);
//Calculate Center of cell.
double wx=0.0;
double wy=0.0;
double wz=0.0;
for(unsigned int i=0;i<nodes.size();i++)
{
const X& node = nodes[i];
CubitVector coords=E::coordinates(node);
int weight=E::weight(node);
wx+=coords.x()*weight;
wy+=coords.y()*weight;
wz+=coords.z()*weight;
}
wx/=cell->weight();
wy/=cell->weight();
wz/=cell->weight();
cell->setCenter(wx,wy,wz);
return true;
}
| void WeightedOctree< X, C, E >::clear | ( | ) |
Definition at line 532 of file WeightedOctree.cpp.
| bool WeightedOctree< X, C, E >::initilizeTree | ( | std::vector< X > & | nodes, |
| std::vector< Cell * > & | newCells | ||
| ) |
Definition at line 539 of file WeightedOctree.cpp.
{
if(this->Root->leaf() && this->Root->nodeCount()==0)
{
for(unsigned int i=0;i<nodes.size();i++)
{
const X& node= nodes[i];
this->Root->addNode(node);
int weight=E::weight(node);
this->Root->addWeight(weight);
}
if(!this->recursiveSplitCell(this->Root,newCells))
{
//this cell wasn't split;
newCells.push_back(this->Root);
}
return true;
}
return false;
}
| void WeightedOctree< X, C, E >::mergeCellChildren | ( | Cell * | cell, |
| std::vector< Cell * > & | oldLeafs | ||
| ) | [protected] |
Definition at line 363 of file WeightedOctree.cpp.
{
if(!cell->leaf())
{
std::vector<X> nodes;
for(unsigned int i=0;i<8;i++)
{
this->mergeCellChildren(cell->child(i),oldLeafs);
cell->child(i)->appendNodes(nodes);
delete cell->child(i);
cell->setChild(i,NULL);
}
for(unsigned int j=0;j<nodes.size();j++)
{
int nodeWeight=E::weight(nodes[j]);
cell->addNode(nodes[j]);
cell->addWeight(nodeWeight);
}
}
else if(cell->nodeCount()!=0)
{
oldLeafs.push_back(cell);
}
}
| bool WeightedOctree< X, C, E >::rebalanceBranch | ( | Cell * | cell, |
| std::vector< Cell * > & | oldLeafs, | ||
| std::vector< Cell * > & | newLeafs | ||
| ) | [protected] |
Definition at line 391 of file WeightedOctree.cpp.
{
if(cell->leaf())
return false;
for(unsigned int i=0;i<8;i++)
{
if(!cell->child(i)->leaf())
{
//Found a child that is not a leaf;
//Currently we only do 1 level rebalancing.
return false;
}
}
//All children are leafs;
std::vector<X> nodes;
cell->appendAllNodes(nodes);
cell->setWeight(0);
for(unsigned int i=0;i<nodes.size();i++)
{
const X& node = nodes[i];
cell->addNode(node);
int weight=E::weight(node);
cell->addWeight(weight);
}
//First find all cells with nodes;
if(cell->nodeCount()>=2 && cell->weight()>this->MaxBoxWeight)
{
// cell can be split.
//So we don't delete the children so they can be reused.
for(unsigned int i=0;i<8;i++)
{
cell->child(i)->removeAllNodes();
}
this->recursiveSplitCell(cell,newLeafs);
}
else
{
//cell won't be split so we delete all of the children.
for(unsigned int i=0;i<8;i++)
{
if(cell->child(i)->nodeCount()>0)
{
oldLeafs.push_back(cell->child(i));
}
delete cell->child(i);
cell->setChild(i,NULL);
}
newLeafs.push_back(cell);
}
return true;
}
| bool WeightedOctree< X, C, E >::recursiveSplitCell | ( | Cell * | cell, |
| std::vector< Cell * > & | newLeafs | ||
| ) | [protected] |
Definition at line 455 of file WeightedOctree.cpp.
{
if(!cell->leaf())
{
return false;
}
if(cell->nodeCount()>=2 && cell->weight()>this->MaxBoxWeight)
{
if(!cell->child(0))
{
for(int q=0;q<8;q++)
{
Cell* newCell= new Cell();
newCell->setParent(cell);
cell->setChild(q,newCell);
}
}
this->calculateCellCenter(cell);
std::vector<X> nodes;
cell->appendNodes(nodes);
//Assign nodes to children based on center.
int lastQuadrant=0;
for(unsigned int i=0;i<nodes.size();i++)
{
const X& node= nodes[i];
CubitVector coords = E::coordinates(node);
CubitVector center=cell->center();
int quadrant=0;
double distance=center.distance_between_squared(coords);
if(distance<this->ToleranceSquared)
{
lastQuadrant++;
if(lastQuadrant>=8)
{
lastQuadrant=0;
}
quadrant=lastQuadrant;
}
else
{
int x = coords.x() < center.x() ? Cell::X_MIN : Cell::X_MAX;
int y = coords.y() < center.y() ? Cell::Y_MIN : Cell::Y_MAX;
int z = coords.z() < center.z() ? Cell::Z_MIN : Cell::Z_MAX;
quadrant=x|y|z;
}
cell->child(quadrant)->addNode(node);
int weight=E::weight(node);
cell->child(quadrant)->addWeight(weight);
}
int weight=cell->weight();
cell->removeAllNodes();
cell->setWeight(weight);
for(unsigned int c=0;c<8;c++)
{
if(cell->child(c)->nodeCount()>0)
{
if(!this->recursiveSplitCell(cell->child(c),newLeafs))
{
newLeafs.push_back(cell->child(c));
}
}
}
return true;
}
return false;
}
| bool WeightedOctree< X, C, E >::removeNode | ( | X & | node, |
| std::vector< Cell * > & | oldCells, | ||
| std::vector< Cell * > & | newCells, | ||
| std::vector< Cell * > & | modifiedCells | ||
| ) |
Definition at line 177 of file WeightedOctree.cpp.
{
typename std::map<X,Cell*>::iterator iter;
iter=this->NodeToCellMap.find(node);
if(iter==this->NodeToCellMap.end())
{
return false;
}
Cell* currentCell=iter->second;
E::setLastCell(node,iter->second);
//remove node from cell.
if(currentCell->removeNode(node))
{
this->NodeToCellMap.erase(node);
int weight=E::weight(node);
currentCell->addWeight(-weight);
//update weight of parents.
Cell* currentParent=currentCell->parent();
while(currentParent)
{
currentParent->addWeight(-weight);
currentParent=currentParent->parent();
}
//Determine if the parent can be collapsed.
currentParent=currentCell->parent();
Cell* lastParent=NULL;
while(currentParent && currentParent->weight()<this->MaxBoxWeight)
{
//Traverse up the tree until the total weight is less that the max weight
lastParent=currentParent;
currentParent=currentParent->parent();
}
if(lastParent)
{
//Parent can be collapsed
this->mergeCellChildren(lastParent,oldCells);
newCells.push_back(lastParent);
std::vector<X> cellNodes;
lastParent->appendNodes(cellNodes);
for(unsigned int j=0;j<cellNodes.size();j++)
{
X& localNode=cellNodes[j];
iter=this->NodeToCellMap.find(localNode);
if(iter!=this->NodeToCellMap.end())
{
E::setLastCell(localNode,iter->second);
}
this->NodeToCellMap[localNode]=lastParent;
}
}
else
{
//Parent cannot be collapsed.
if(currentCell->nodeCount()==0)
{
oldCells.push_back(currentCell);
}
else
{
modifiedCells.push_back(currentCell);
}
}
return true;
}
return false;
}
| bool WeightedOctree< X, C, E >::splitCell | ( | Cell * | cell, |
| std::vector< Cell * > & | newLeafs | ||
| ) | [protected] |
Definition at line 292 of file WeightedOctree.cpp.
{
if(!cell->leaf())
{
return false;
}
if(cell->nodeCount()>=2 && cell->weight()>this->MaxBoxWeight)
{
for(int q=0;q<8;q++)
{
Cell* newCell= new Cell();
newCell->setParent(cell);
cell->setChild(q,newCell);
}
this->calculateCellCenter(cell);
std::vector<X> nodes;
cell->appendNodes(nodes);
//Assign nodes to children based on center.
int lastQuadrant=0;
for(unsigned int i=0;i<nodes.size();i++)
{
const X& node= nodes[i];
CubitVector coords = E::coordinates(node);
CubitVector center=cell->center();
int quadrant=0;
double distance=center.distance_between_squared(coords);
if(distance<this->ToleranceSquared)
{
lastQuadrant++;
if(lastQuadrant>=8)
{
lastQuadrant=0;
}
quadrant=lastQuadrant;
}
else
{
int x = coords.x() < center.x() ? Cell::X_MIN : Cell::X_MAX;
int y = coords.y() < center.y() ? Cell::Y_MIN : Cell::Y_MAX;
int z = coords.z() < center.z() ? Cell::Z_MIN : Cell::Z_MAX;
quadrant=x|y|z;
}
cell->child(quadrant)->addNode(node);
int weight=E::weight(node);
cell->child(quadrant)->addWeight(weight);
}
int weight=cell->weight();
cell->removeAllNodes();
cell->setWeight(weight);
for(unsigned int c=0;c<8;c++)
{
if(cell->child(c)->nodeCount()>0)
{
newLeafs.push_back(cell->child(c));
}
}
return true;
}
return false;
}
int WeightedOctree< X, C, E >::MaxBoxWeight [protected] |
Definition at line 176 of file WeightedOctree.hpp.
std::map<X,Cell*> WeightedOctree< X, C, E >::NodeToCellMap [protected] |
Definition at line 184 of file WeightedOctree.hpp.
Cell* WeightedOctree< X, C, E >::Root [protected] |
Definition at line 179 of file WeightedOctree.hpp.
double WeightedOctree< X, C, E >::Tolerance [protected] |
Definition at line 186 of file WeightedOctree.hpp.
double WeightedOctree< X, C, E >::ToleranceSquared [protected] |
Definition at line 187 of file WeightedOctree.hpp.
int WeightedOctree< X, C, E >::TotalWeight [protected] |
Definition at line 182 of file WeightedOctree.hpp.