cgma
WeightedOctree.hpp
Go to the documentation of this file.
00001 //-------------------------------------------------------------------------
00002 // Filename      : WeightedOctree.hpp
00003 //
00004 // Purpose       : Class for O(ln n) search for nodes within a specified
00005 //                 tolerance of a specified position.
00006 //
00007 //
00008 // Creator       : Corey McBride 
00009 //
00010 // Creation Date : 02/18/10
00011 //-------------------------------------------------------------------------
00012 
00013 #ifndef WEIGHTEDOCT_TREE_HPP
00014 #define WEIGHTEDOCT_TREE_HPP
00015 
00016 #include "CubitVector.hpp"
00017 #include <vector>
00018 #include <map>
00019 
00020 
00021 template <class X> class DefaultWeightedNodeQuery
00022 {
00023   public:
00024     static inline CubitVector coordinates(const X& x)
00025     {
00026       return x.coordinates();
00027     }
00028     static inline int weight(const X& x)
00029     {
00030       return x.weight();
00031     }
00032 
00033     template<class C>
00034     static inline void setLastCell( X& x,C* c)
00035     {
00036        x.setLastCell(c);
00037     }
00038 
00039 };
00040 struct DefaultOctreeCell
00041 {
00042 };
00043 
00044 
00045 template < class X, class C = DefaultOctreeCell, class E = DefaultWeightedNodeQuery<X> >
00046 class WeightedOctree
00047 {
00048   public:
00049    class Cell: public C
00050     {
00051 
00052     public:
00053       Cell();
00054        
00055     
00056     bool removeNode(const X& node);
00057     void addNode( const X&  node );
00058       // asserts if not a leaf node.
00059       
00060     bool leaf(); 
00061       // Is this box a leaf in the tree?
00062 
00063     void appendNodes( std::vector<X>& list );
00064     const std::vector<X>& nodes() const { return Nodes; }
00065 
00066       // If this node is a leaf node, append all contained CubitNodes
00067 
00068 
00069     int nodeCount() { return Nodes.size(); }
00070 
00071     void setWeight(int w);
00072     void addWeight(int w);
00073     int weight();
00074 
00075     void setCenter(double& x,double& y,double& z);
00076     void setCenter(CubitVector& center);
00077     CubitVector& center() {return Center;}
00078 
00079     void removeAllNodes();
00080 
00081 
00082 
00083       enum {
00084         X_MIN = 0,
00085         Y_MIN = 0,
00086         Z_MIN = 0,
00087         X_MAX = 1,
00088         Y_MAX = 2,
00089         Z_MAX = 4
00090       };
00091       // Constants for selecting one of 8 child boxes.
00092       // Can be either bitwise-or'ed (|) or added (+).
00093       // MAX values take precedence over MIN values 
00094       // if both are specified.  (MIN is just the
00095       // absense of MAX).
00096       //
00097       Cell* child( int quadrant )
00098       {
00099         assert( quadrant >= 0 && quadrant < 8);
00100         return this->Children[quadrant];
00101       }
00102       // quadrant should be a bitwise OR (or sum) of 
00103       // the constants above.  If both a MIN and MAX 
00104       // value is specified for a given principal 
00105       // direction, the M  : children_(0),
00106 
00107       void setChild(int quadrant,Cell* c);
00108 
00109       void setParent(Cell*);
00110       Cell* parent() {return this->Parent;}
00111 
00112       void appendAllNodes( std::vector<X>& list );
00113       // If this node is a leaf node, append all contained CubitNodes.
00114       // Otherwise descend oct-tree getting CubitNodes contained in
00115       // all child leaf nodes.
00116 
00117 
00118     protected:
00119       Cell* Parent;
00120       Cell* Children[8]; 
00121 
00122       std::vector<X> Nodes;
00123       int TotalWeight;
00124       CubitVector Center;
00125       bool IsLeaf;
00126 
00127     };
00128 
00129 
00130    
00131   public:
00132 
00133     WeightedOctree(int max_weight_per_box,double tolerance=1e-6);
00134       //- Constructor
00135       //- tolerance - tolerance for comparison of node positions
00136       //- max_weight_per_box - subdivide box if total weight exceeds this 
00137       //- min_box_dimension - don't subdivide boxes in tree if
00138       //-                     all three dimensions are less than this
00139 
00140     ~WeightedOctree();
00141       // - Destructor
00142     
00143     bool initilizeTree(std::vector<X>& nodes,std::vector<Cell*>& newCells);
00144     void clear();
00145 
00146     bool addNode(const X& node,
00147       std::vector<Cell*>& oldCells,
00148       std::vector<Cell*>& newCells,
00149       std::vector<Cell*>& modifiedCells);
00150     bool removeNode(X& node,
00151       std::vector<Cell*>& oldCells,
00152       std::vector<Cell*>& newCells,
00153       std::vector<Cell*>& modifiedCells);
00154 
00155 
00156 
00157   protected:
00158     bool calculateCellCenter(Cell* cell); 
00159 
00160     void mergeCellChildren(Cell* cell,std::vector<Cell*>& oldLeafs);
00161 
00162     bool splitCell(Cell* cell,std::vector<Cell*>& newLeafs);
00163       // Change from leaf cell to non-leaf.  Splits nodes amongst 8 new
00164       // cell boxes using the value of centroid of the cell
00165       
00166 
00167      bool rebalanceBranch(Cell* cell,
00168          std::vector<Cell*>& oldLeafs,
00169          std::vector<Cell*>& newLeafs);
00170 
00171      bool recursiveSplitCell(Cell* cell,
00172          std::vector<Cell*>& newLeafs);
00173 
00174 
00175 
00176     int MaxBoxWeight;
00177       // values passed to constructor
00178   
00179     Cell* Root;
00180       // root of oct-tree
00181 
00182     int TotalWeight;
00183     
00184     std::map<X,Cell*> NodeToCellMap;
00185 
00186     double Tolerance;
00187     double ToleranceSquared;
00188   
00189 
00190  
00191 
00192 };
00193 
00194 #include "WeightedOctree.cpp"
00195 
00196 #endif
00197 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines