MOAB: Mesh Oriented datABase  (version 5.2.1)
Tree.hpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines