cgma
|
00001 //------------------------------------------------------------------------- 00002 // Filename : OctTreeCell.hpp 00003 // 00004 // Purpose : Oct-tree node used by OctTree 00005 // 00006 // Special Notes : OctTree handles all memory allocation for this 00007 // class. 00008 // 00009 // Creator : Jason Kraftcheck 00010 // 00011 // Creation Date : 01/30/02 00012 //------------------------------------------------------------------------- 00013 00014 #ifndef OCT_TREE_CELL_HPP 00015 #define OCT_TREE_CELL_HPP 00016 00017 template <class X, class E> class OctTreeCell; 00018 class CubitVector; 00019 template <class X> class DLIList; 00020 00021 // Linked-list node used to hold CubitNodes in each box. 00022 template <class X, class E> struct OctTreeEntry 00023 { 00024 X* node; 00025 OctTreeEntry<X,E>* next; 00026 }; 00027 00028 // A node in the oct-tree. 00029 template <class X, class E> class OctTreeCell 00030 { 00031 private: 00032 00033 union { 00034 OctTreeEntry<X,E>* head_; // head of linked-list of CubitNodes 00035 OctTreeCell<X,E>* children_; // array of 8 child boxes 00036 }; 00037 // union of both the head pointer for the linked-list 00038 // of CubitNodes in a leaf node and a pointer to the 00039 // array of child boxes. 00040 // 00041 // This node is a leaf node iff node_count_ is non-zero 00042 // or both values in the data union are null. 00043 00044 int node_count_; 00045 // Number of nodes contained in a leaf node. If zero, 00046 // need to check if data.children is null to determine 00047 // if this is a leaf node. 00048 00049 void add_nodes( OctTreeEntry<X,E>* node ); 00050 // Join the passed linked-list to the data list. 00051 // asserts if not a leaf node. 00052 00053 public: 00054 00055 OctTreeCell( OctTreeEntry<X,E> array[], int size ); 00056 // create a root node 00057 // calling code provides storage for linked-list 00058 // nodes by providing 'array'. Do not delete 00059 // 'array' until this OctTreeCell and all its 00060 // children are destroyed. 00061 00062 inline OctTreeCell( ) : children_(0), node_count_(0) {} 00063 // Construct unused child node. This is provieded 00064 // for the cexternal memory allocator. 00065 00066 bool leaf() const { return node_count_ || !children_; } 00067 // Is this box a leaf in the tree? 00068 00069 bool split( const CubitVector& my_center, OctTreeCell<X,E>* memory ); 00070 // Change from leaf box to non-leaf. Splits nodes amongst 8 new 00071 // child boxes using the value of 'my_center'. May fail (return 00072 // false) if two few nodes are contained for a split to be sensible. 00073 // 00074 // Calling application provides memory for use in holding child 00075 // nodes. memory must be freed by the caller AFTER the destruction 00076 // of this object. 00077 00078 void append_nodes( DLIList<X*>& list ); 00079 // If this node is a leaf node, append all contained CubitNodes 00080 00081 void append_all_nodes( DLIList<X*>& list ); 00082 // If this node is a leaf node, append all contained CubitNodes. 00083 // Otherwise descend oct-tree getting CubitNodes contained in 00084 // all child leaf nodes. 00085 00086 enum { 00087 X_MIN = 0, 00088 Y_MIN = 0, 00089 Z_MIN = 0, 00090 X_MAX = 1, 00091 Y_MAX = 2, 00092 Z_MAX = 4 00093 }; 00094 // Constants for selecting one of 8 child boxes. 00095 // Can be either bitwise-or'ed (|) or added (+). 00096 // MAX values take precedence over MIN values 00097 // if both are specified. (MIN is just the 00098 // absense of MAX). 00099 00100 OctTreeCell<X,E>* child( int quadrant ); 00101 // quadrant should be a bitwise OR (or sum) of 00102 // the constants above. If both a MIN and MAX 00103 // value is specified for a given principal 00104 // direction, the M : children_(0), 00105 00106 void node_locations( CubitVector& box_min, 00107 CubitVector& box_max, 00108 CubitVector& average, 00109 CubitVector* std_dev = 0 ); 00110 // Get information about CubitNodes contained in 00111 // this box. Method does nothing when called on 00112 // non-leaf boxes. 00113 00114 int node_count() { return node_count_; } 00115 // CubitNodes contained in this box. 00116 // Always zero for non-leaf boxes. 00117 00118 }; 00119 00120 #include "OctTreeCell.cpp" 00121 00122 #endif 00123