MOAB: Mesh Oriented datABase
(version 5.2.1)
|
00001 /**\file Tree.hpp 00002 * \class moab::Tree 00003 * \brief Parent class of various tree types in MOAB 00004 */ 00005 00006 #ifndef MOAB_TREE_HPP 00007 #define MOAB_TREE_HPP 00008 00009 #include "moab/Interface.hpp" 00010 #include "moab/BoundBox.hpp" 00011 #include "moab/CartVect.hpp" 00012 #include "moab/FileOptions.hpp" 00013 #include "moab/TreeStats.hpp" 00014 00015 #include <string> 00016 #include <vector> 00017 #include <math.h> 00018 #include <assert.h> 00019 00020 namespace moab 00021 { 00022 00023 class Interface; 00024 class Range; 00025 class ElemEvaluator; 00026 00027 class Tree 00028 { 00029 public: 00030 /** \brief Constructor (bare) 00031 * \param iface MOAB instance 00032 */ 00033 Tree( Interface* iface ); 00034 00035 /** \brief Destructor 00036 */ 00037 virtual ~Tree(); 00038 00039 /** \brief Destroy the tree maintained by this object, optionally checking we have the right 00040 * root. \param root If non-NULL, check that this is the root, return failure if not 00041 */ 00042 virtual ErrorCode reset_tree() = 0; 00043 00044 /** \brief Delete the entity sets associated with the tree, starting with the root and 00045 * traversing children 00046 */ 00047 ErrorCode delete_tree_sets(); 00048 00049 /** Build the tree 00050 * Build a tree with the entities input. If a non-NULL tree_root_set pointer is input, 00051 * use the pointed-to set as the root of this tree (*tree_root_set!=0) otherwise construct 00052 * a new root set and pass its handle back in *tree_root_set. Options vary by tree type, 00053 * with a few common to all types of trees. Common options: 00054 * MAX_PER_LEAF: max entities per leaf; default = 6 00055 * MAX_DEPTH: max depth of the tree; default = 30 00056 * MIN_WIDTH: minimum width of box, used like a tolerance; default = 1.0e-10 00057 * MESHSET_FLAGS: flags passed into meshset creation for tree nodes; should be a value from 00058 * ENTITY_SET_PROPERTY (see Types.hpp); default = MESHSET_SET 00059 * CLEAN_UP: if false, do not delete tree sets upon tree class destruction; default = true 00060 * TAG_NAME: tag name to store tree information on tree nodes; default determined by tree type 00061 * \param entities Entities with which to build the tree 00062 * \param tree_root Root set for tree (see function description) 00063 * \param opts Options for tree (see function description) 00064 * \return Error is returned only on build failure 00065 */ 00066 virtual ErrorCode build_tree( const Range& entities, EntityHandle* tree_root_set = NULL, 00067 FileOptions* options = NULL ) = 0; 00068 00069 /** \brief Get bounding box for tree below tree_node, or entire tree 00070 * If no tree has been built yet, returns +/- DBL_MAX for all dimensions. Note for some tree 00071 * types, boxes are not available for non-root nodes, and this function will return failure if 00072 * non-root is passed in \param box The box for this tree \param tree_node If non-NULL, node for 00073 * which box is requested, tree root if NULL \return Only returns error on fatal condition 00074 */ 00075 virtual ErrorCode get_bounding_box( BoundBox& box, EntityHandle* tree_node = NULL ) const; 00076 00077 /** \brief Return some basic information about the tree 00078 * Stats are returned for tree starting from input node or tree root (root = 0) 00079 * \param root If non-0, give stats below and including root 00080 * \param min Minimum corner of bounding box 00081 * \param max Maximum corner of bounding box 00082 * \param max_dep Maximum depth of tree below root 00083 */ 00084 virtual ErrorCode get_info( EntityHandle root, double min[3], double max[3], unsigned int& max_dep ); 00085 00086 /** \brief Find all trees, by bounding box tag 00087 */ 00088 ErrorCode find_all_trees( Range& results ); 00089 00090 /** \brief Get leaf containing input position. 00091 * 00092 * Does not take into account global bounding box of tree. 00093 * - Therefore there is always one leaf containing the point. 00094 * - If caller wants to account for global bounding box, then 00095 * caller can test against that box and not call this method 00096 * at all if the point is outside the box, as there is no leaf 00097 * containing the point in that case. 00098 * \param point Point to be located in tree 00099 * \param leaf_out Leaf containing point 00100 * \param iter_tol Tolerance for convergence of point search 00101 * \param inside_tol Tolerance for inside element calculation 00102 * \param multiple_leaves Some tree types can have multiple leaves containing a point; 00103 * if non-NULL, this parameter is returned true if multiple leaves contain 00104 * the input point 00105 * \param start_node Start from this tree node (non-NULL) instead of tree root (NULL) 00106 * \return Non-success returned only in case of failure; not-found indicated by leaf_out=0 00107 */ 00108 virtual ErrorCode point_search( const double* point, EntityHandle& leaf_out, const double iter_tol = 1.0e-10, 00109 const double inside_tol = 1.0e-6, bool* multiple_leaves = NULL, 00110 EntityHandle* start_node = NULL, CartVect* params = NULL ) = 0; 00111 00112 /** \brief Find all leaves within a given distance from point 00113 * If dists_out input non-NULL, also returns distances from each leaf; if 00114 * point i is inside leaf, 0 is given as dists_out[i]. 00115 * If params_out is non-NULL and myEval is non-NULL, will evaluate individual entities 00116 * in tree nodes and return containing entities in leaves_out. In those cases, if params_out 00117 * is also non-NULL, will return parameters in those elements in that vector. 00118 * \param point Point to be located in tree 00119 * \param distance Distance within which to query 00120 * \param leaves_out Leaves within distance or containing point 00121 * \param iter_tol Tolerance for convergence of point search 00122 * \param inside_tol Tolerance for inside element calculation 00123 * \param dists_out If non-NULL, will contain distsances to leaves 00124 * \param params_out If non-NULL, will contain parameters of the point in the ents in leaves_out 00125 * \param start_node Start from this tree node (non-NULL) instead of tree root (NULL) 00126 */ 00127 virtual ErrorCode distance_search( const double* point, const double distance, 00128 std::vector< EntityHandle >& leaves_out, const double iter_tol = 1.0e-10, 00129 const double inside_tol = 1.0e-6, std::vector< double >* dists_out = NULL, 00130 std::vector< CartVect >* params_out = NULL, 00131 EntityHandle* start_node = NULL ) = 0; 00132 00133 /** \brief Return the MOAB interface associated with this tree 00134 */ 00135 Interface* moab() 00136 { 00137 return mbImpl; 00138 } 00139 00140 /** \brief Return the MOAB interface associated with this tree 00141 */ 00142 const Interface* moab() const 00143 { 00144 return mbImpl; 00145 } 00146 00147 /** \brief Get max depth set on tree */ 00148 double get_max_depth() 00149 { 00150 return maxDepth; 00151 } 00152 00153 /** \brief Get max entities per leaf set on tree */ 00154 double get_max_per_leaf() 00155 { 00156 return maxPerLeaf; 00157 } 00158 00159 /** \brief Get tree traversal stats object */ 00160 TreeStats& tree_stats() 00161 { 00162 return treeStats; 00163 } 00164 00165 /** \brief Get tree traversal stats object */ 00166 const TreeStats& tree_stats() const 00167 { 00168 return treeStats; 00169 } 00170 00171 /** \brief Create tree root and tag with bounding box 00172 */ 00173 ErrorCode create_root( const double box_min[3], const double box_max[3], EntityHandle& root_handle ); 00174 00175 //! print various things about this tree 00176 virtual ErrorCode print() = 0; 00177 00178 //! get/set the ElemEvaluator 00179 inline ElemEvaluator* get_eval() 00180 { 00181 return myEval; 00182 } 00183 00184 //! get/set the ElemEvaluator 00185 inline void set_eval( ElemEvaluator* eval ) 00186 { 00187 myEval = eval; 00188 } 00189 00190 /** \brief Parse options for this tree, including common options for all trees 00191 * \param opts Options 00192 */ 00193 virtual ErrorCode parse_options( FileOptions& opts ) = 0; 00194 00195 protected: 00196 /** \brief Parse options common to all trees 00197 * \param options Options for representing tree; see Tree::build_tree() and subclass 00198 * build_tree() functions for allowed options \return Non-success returned from base class 00199 * function only under catastrophic circumstances; derived classes also can recognize 00200 * subclass-specific options 00201 */ 00202 ErrorCode parse_common_options( FileOptions& options ); 00203 00204 /** \brief Get the box tag, possibly constructing it first 00205 * \param create_if_missing If true and it has not been made yet, make it 00206 */ 00207 Tag get_box_tag( bool create_if_missing = true ); 00208 00209 // moab instance 00210 Interface* mbImpl; 00211 00212 // bounding box for entire tree 00213 BoundBox boundBox; 00214 00215 // max entities per leaf 00216 int maxPerLeaf; 00217 00218 // max depth of tree 00219 int maxDepth; 00220 00221 // tree depth, set by build_tree 00222 int treeDepth; 00223 00224 // min width of box, handled like tolerance 00225 double minWidth; 00226 00227 // meshset creation flags 00228 unsigned int meshsetFlags; 00229 00230 // clean up flag 00231 bool cleanUp; 00232 00233 // tree root 00234 EntityHandle myRoot; 00235 00236 // tag used to mark bounding box of nodes 00237 Tag boxTag; 00238 00239 // tag name used for boxTag 00240 std::string boxTagName; 00241 00242 // tree traversal stats 00243 TreeStats treeStats; 00244 00245 // element evaluator 00246 ElemEvaluator* myEval; 00247 }; 00248 00249 inline Tree::Tree( Interface* iface ) 00250 : mbImpl( iface ), maxPerLeaf( 6 ), maxDepth( 30 ), treeDepth( -1 ), minWidth( 1.0e-10 ), meshsetFlags( 0 ), 00251 cleanUp( true ), myRoot( 0 ), boxTag( 0 ), myEval( 0 ) 00252 { 00253 } 00254 00255 inline Tree::~Tree() {} 00256 00257 inline ErrorCode Tree::get_bounding_box( BoundBox& box, EntityHandle* tree_node ) const 00258 { 00259 if( ( tree_node && *tree_node == myRoot ) || !tree_node ) 00260 { 00261 box = boundBox; 00262 return MB_SUCCESS; 00263 } 00264 else 00265 return MB_FAILURE; 00266 } 00267 00268 inline ErrorCode Tree::get_info( EntityHandle /* root */, double* /*min[3]*/, double* /* max[3]*/, 00269 unsigned int& /*dep*/ ) 00270 { 00271 return MB_NOT_IMPLEMENTED; 00272 } 00273 00274 inline Tag Tree::get_box_tag( bool create_if_missing ) 00275 { 00276 if( !boxTag && create_if_missing ) 00277 { 00278 assert( boxTagName.length() > 0 ); 00279 ErrorCode rval = 00280 moab()->tag_get_handle( boxTagName.c_str(), 6, MB_TYPE_DOUBLE, boxTag, MB_TAG_CREAT | MB_TAG_SPARSE ); 00281 if( MB_INVALID_SIZE == rval ) 00282 { 00283 // delete the tag and get it again, legacy file... 00284 rval = moab()->tag_delete( boxTag ); 00285 if( MB_SUCCESS != rval ) return 0; 00286 boxTag = 0; 00287 return get_box_tag( true ); 00288 } 00289 00290 if( MB_SUCCESS != rval ) return 0; 00291 } 00292 00293 return boxTag; 00294 } 00295 00296 } // namespace moab 00297 00298 #endif