MOAB: Mesh Oriented datABase
(version 5.4.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 <cmath> 00018 #include <cassert> 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, 00067 EntityHandle* tree_root_set = NULL, 00068 FileOptions* options = NULL ) = 0; 00069 00070 /** \brief Get bounding box for tree below tree_node, or entire tree 00071 * If no tree has been built yet, returns +/- DBL_MAX for all dimensions. Note for some tree 00072 * types, boxes are not available for non-root nodes, and this function will return failure if 00073 * non-root is passed in \param box The box for this tree \param tree_node If non-NULL, node for 00074 * which box is requested, tree root if NULL \return Only returns error on fatal condition 00075 */ 00076 virtual ErrorCode get_bounding_box( BoundBox& box, EntityHandle* tree_node = NULL ) const; 00077 00078 /** \brief Return some basic information about the tree 00079 * Stats are returned for tree starting from input node or tree root (root = 0) 00080 * \param root If non-0, give stats below and including root 00081 * \param min Minimum corner of bounding box 00082 * \param max Maximum corner of bounding box 00083 * \param max_dep Maximum depth of tree below root 00084 */ 00085 virtual ErrorCode get_info( EntityHandle root, double min[3], double max[3], unsigned int& max_dep ); 00086 00087 /** \brief Find all trees, by bounding box tag 00088 */ 00089 ErrorCode find_all_trees( Range& results ); 00090 00091 /** \brief Get leaf containing input position. 00092 * 00093 * Does not take into account global bounding box of tree. 00094 * - Therefore there is always one leaf containing the point. 00095 * - If caller wants to account for global bounding box, then 00096 * caller can test against that box and not call this method 00097 * at all if the point is outside the box, as there is no leaf 00098 * containing the point in that case. 00099 * \param point Point to be located in tree 00100 * \param leaf_out Leaf containing point 00101 * \param iter_tol Tolerance for convergence of point search 00102 * \param inside_tol Tolerance for inside element calculation 00103 * \param multiple_leaves Some tree types can have multiple leaves containing a point; 00104 * if non-NULL, this parameter is returned true if multiple leaves contain 00105 * the input point 00106 * \param start_node Start from this tree node (non-NULL) instead of tree root (NULL) 00107 * \return Non-success returned only in case of failure; not-found indicated by leaf_out=0 00108 */ 00109 virtual ErrorCode point_search( const double* point, 00110 EntityHandle& leaf_out, 00111 const double iter_tol = 1.0e-10, 00112 const double inside_tol = 1.0e-6, 00113 bool* multiple_leaves = NULL, 00114 EntityHandle* start_node = NULL, 00115 CartVect* params = NULL ) = 0; 00116 00117 /** \brief Find all leaves within a given distance from point 00118 * If dists_out input non-NULL, also returns distances from each leaf; if 00119 * point i is inside leaf, 0 is given as dists_out[i]. 00120 * If params_out is non-NULL and myEval is non-NULL, will evaluate individual entities 00121 * in tree nodes and return containing entities in leaves_out. In those cases, if params_out 00122 * is also non-NULL, will return parameters in those elements in that vector. 00123 * \param point Point to be located in tree 00124 * \param distance Distance within which to query 00125 * \param leaves_out Leaves within distance or containing point 00126 * \param iter_tol Tolerance for convergence of point search 00127 * \param inside_tol Tolerance for inside element calculation 00128 * \param dists_out If non-NULL, will contain distsances to leaves 00129 * \param params_out If non-NULL, will contain parameters of the point in the ents in leaves_out 00130 * \param start_node Start from this tree node (non-NULL) instead of tree root (NULL) 00131 */ 00132 virtual ErrorCode distance_search( const double* point, 00133 const double distance, 00134 std::vector< EntityHandle >& leaves_out, 00135 const double iter_tol = 1.0e-10, 00136 const double inside_tol = 1.0e-6, 00137 std::vector< double >* dists_out = NULL, 00138 std::vector< CartVect >* params_out = NULL, 00139 EntityHandle* start_node = NULL ) = 0; 00140 00141 /** \brief Return the MOAB interface associated with this tree 00142 */ 00143 Interface* moab() 00144 { 00145 return mbImpl; 00146 } 00147 00148 /** \brief Return the MOAB interface associated with this tree 00149 */ 00150 const Interface* moab() const 00151 { 00152 return mbImpl; 00153 } 00154 00155 /** \brief Get max depth set on tree */ 00156 double get_max_depth() 00157 { 00158 return maxDepth; 00159 } 00160 00161 /** \brief Get max entities per leaf set on tree */ 00162 double get_max_per_leaf() 00163 { 00164 return maxPerLeaf; 00165 } 00166 00167 /** \brief Get tree traversal stats object */ 00168 TreeStats& tree_stats() 00169 { 00170 return treeStats; 00171 } 00172 00173 /** \brief Get tree traversal stats object */ 00174 const TreeStats& tree_stats() const 00175 { 00176 return treeStats; 00177 } 00178 00179 /** \brief Create tree root and tag with bounding box 00180 */ 00181 ErrorCode create_root( const double box_min[3], const double box_max[3], EntityHandle& root_handle ); 00182 00183 //! print various things about this tree 00184 virtual ErrorCode print() = 0; 00185 00186 //! get/set the ElemEvaluator 00187 inline ElemEvaluator* get_eval() 00188 { 00189 return myEval; 00190 } 00191 00192 //! get/set the ElemEvaluator 00193 inline void set_eval( ElemEvaluator* eval ) 00194 { 00195 myEval = eval; 00196 } 00197 00198 /** \brief Parse options for this tree, including common options for all trees 00199 * \param opts Options 00200 */ 00201 virtual ErrorCode parse_options( FileOptions& opts ) = 0; 00202 00203 protected: 00204 /** \brief Parse options common to all trees 00205 * \param options Options for representing tree; see Tree::build_tree() and subclass 00206 * build_tree() functions for allowed options \return Non-success returned from base class 00207 * function only under catastrophic circumstances; derived classes also can recognize 00208 * subclass-specific options 00209 */ 00210 ErrorCode parse_common_options( FileOptions& options ); 00211 00212 /** \brief Get the box tag, possibly constructing it first 00213 * \param create_if_missing If true and it has not been made yet, make it 00214 */ 00215 Tag get_box_tag( bool create_if_missing = true ); 00216 00217 // moab instance 00218 Interface* mbImpl; 00219 00220 // bounding box for entire tree 00221 BoundBox boundBox; 00222 00223 // max entities per leaf 00224 int maxPerLeaf; 00225 00226 // max depth of tree 00227 int maxDepth; 00228 00229 // tree depth, set by build_tree 00230 int treeDepth; 00231 00232 // min width of box, handled like tolerance 00233 double minWidth; 00234 00235 // meshset creation flags 00236 unsigned int meshsetFlags; 00237 00238 // clean up flag 00239 bool cleanUp; 00240 00241 // tree root 00242 EntityHandle myRoot; 00243 00244 // tag used to mark bounding box of nodes 00245 Tag boxTag; 00246 00247 // tag name used for boxTag 00248 std::string boxTagName; 00249 00250 // tree traversal stats 00251 TreeStats treeStats; 00252 00253 // element evaluator 00254 ElemEvaluator* myEval; 00255 }; 00256 00257 inline Tree::Tree( Interface* iface ) 00258 : mbImpl( iface ), maxPerLeaf( 6 ), maxDepth( 30 ), treeDepth( -1 ), minWidth( 1.0e-10 ), meshsetFlags( 0 ), 00259 cleanUp( true ), myRoot( 0 ), boxTag( 0 ), myEval( 0 ) 00260 { 00261 } 00262 00263 inline Tree::~Tree() {} 00264 00265 inline ErrorCode Tree::get_bounding_box( BoundBox& box, EntityHandle* tree_node ) const 00266 { 00267 if( ( tree_node && *tree_node == myRoot ) || !tree_node ) 00268 { 00269 box = boundBox; 00270 return MB_SUCCESS; 00271 } 00272 else 00273 return MB_FAILURE; 00274 } 00275 00276 inline ErrorCode Tree::get_info( EntityHandle /* root */, 00277 double* /*min[3]*/, 00278 double* /* max[3]*/, 00279 unsigned int& /*dep*/ ) 00280 { 00281 return MB_NOT_IMPLEMENTED; 00282 } 00283 00284 inline Tag Tree::get_box_tag( bool create_if_missing ) 00285 { 00286 if( !boxTag && create_if_missing ) 00287 { 00288 assert( boxTagName.length() > 0 ); 00289 ErrorCode rval = 00290 moab()->tag_get_handle( boxTagName.c_str(), 6, MB_TYPE_DOUBLE, boxTag, MB_TAG_CREAT | MB_TAG_SPARSE ); 00291 if( MB_INVALID_SIZE == rval ) 00292 { 00293 // delete the tag and get it again, legacy file... 00294 rval = moab()->tag_delete( boxTag ); 00295 if( MB_SUCCESS != rval ) return 0; 00296 boxTag = 0; 00297 return get_box_tag( true ); 00298 } 00299 00300 if( MB_SUCCESS != rval ) return 0; 00301 } 00302 00303 return boxTag; 00304 } 00305 00306 } // namespace moab 00307 00308 #endif