Branch data Line data Source code
1 : : /**\file Tree.hpp
2 : : * \class moab::Tree
3 : : * \brief Parent class of various tree types in MOAB
4 : : */
5 : :
6 : : #ifndef MOAB_TREE_HPP
7 : : #define MOAB_TREE_HPP
8 : :
9 : : #include "moab/Interface.hpp"
10 : : #include "moab/BoundBox.hpp"
11 : : #include "moab/CartVect.hpp"
12 : : #include "moab/FileOptions.hpp"
13 : : #include "moab/TreeStats.hpp"
14 : :
15 : : #include <string>
16 : : #include <vector>
17 : : #include <math.h>
18 : : #include <assert.h>
19 : :
20 : : namespace moab
21 : : {
22 : :
23 : : class Interface;
24 : : class Range;
25 : : class ElemEvaluator;
26 : :
27 : : class Tree
28 : : {
29 : : public:
30 : : /** \brief Constructor (bare)
31 : : * \param iface MOAB instance
32 : : */
33 : : Tree( Interface* iface );
34 : :
35 : : /** \brief Destructor
36 : : */
37 : : virtual ~Tree();
38 : :
39 : : /** \brief Destroy the tree maintained by this object, optionally checking we have the right
40 : : * root. \param root If non-NULL, check that this is the root, return failure if not
41 : : */
42 : : virtual ErrorCode reset_tree() = 0;
43 : :
44 : : /** \brief Delete the entity sets associated with the tree, starting with the root and
45 : : * traversing children
46 : : */
47 : : ErrorCode delete_tree_sets();
48 : :
49 : : /** Build the tree
50 : : * Build a tree with the entities input. If a non-NULL tree_root_set pointer is input,
51 : : * use the pointed-to set as the root of this tree (*tree_root_set!=0) otherwise construct
52 : : * a new root set and pass its handle back in *tree_root_set. Options vary by tree type,
53 : : * with a few common to all types of trees. Common options:
54 : : * MAX_PER_LEAF: max entities per leaf; default = 6
55 : : * MAX_DEPTH: max depth of the tree; default = 30
56 : : * MIN_WIDTH: minimum width of box, used like a tolerance; default = 1.0e-10
57 : : * MESHSET_FLAGS: flags passed into meshset creation for tree nodes; should be a value from
58 : : * ENTITY_SET_PROPERTY (see Types.hpp); default = MESHSET_SET
59 : : * CLEAN_UP: if false, do not delete tree sets upon tree class destruction; default = true
60 : : * TAG_NAME: tag name to store tree information on tree nodes; default determined by tree type
61 : : * \param entities Entities with which to build the tree
62 : : * \param tree_root Root set for tree (see function description)
63 : : * \param opts Options for tree (see function description)
64 : : * \return Error is returned only on build failure
65 : : */
66 : : virtual ErrorCode build_tree( const Range& entities, EntityHandle* tree_root_set = NULL,
67 : : FileOptions* options = NULL ) = 0;
68 : :
69 : : /** \brief Get bounding box for tree below tree_node, or entire tree
70 : : * If no tree has been built yet, returns +/- DBL_MAX for all dimensions. Note for some tree
71 : : * types, boxes are not available for non-root nodes, and this function will return failure if
72 : : * non-root is passed in \param box The box for this tree \param tree_node If non-NULL, node for
73 : : * which box is requested, tree root if NULL \return Only returns error on fatal condition
74 : : */
75 : : virtual ErrorCode get_bounding_box( BoundBox& box, EntityHandle* tree_node = NULL ) const;
76 : :
77 : : /** \brief Return some basic information about the tree
78 : : * Stats are returned for tree starting from input node or tree root (root = 0)
79 : : * \param root If non-0, give stats below and including root
80 : : * \param min Minimum corner of bounding box
81 : : * \param max Maximum corner of bounding box
82 : : * \param max_dep Maximum depth of tree below root
83 : : */
84 : : virtual ErrorCode get_info( EntityHandle root, double min[3], double max[3], unsigned int& max_dep );
85 : :
86 : : /** \brief Find all trees, by bounding box tag
87 : : */
88 : : ErrorCode find_all_trees( Range& results );
89 : :
90 : : /** \brief Get leaf containing input position.
91 : : *
92 : : * Does not take into account global bounding box of tree.
93 : : * - Therefore there is always one leaf containing the point.
94 : : * - If caller wants to account for global bounding box, then
95 : : * caller can test against that box and not call this method
96 : : * at all if the point is outside the box, as there is no leaf
97 : : * containing the point in that case.
98 : : * \param point Point to be located in tree
99 : : * \param leaf_out Leaf containing point
100 : : * \param iter_tol Tolerance for convergence of point search
101 : : * \param inside_tol Tolerance for inside element calculation
102 : : * \param multiple_leaves Some tree types can have multiple leaves containing a point;
103 : : * if non-NULL, this parameter is returned true if multiple leaves contain
104 : : * the input point
105 : : * \param start_node Start from this tree node (non-NULL) instead of tree root (NULL)
106 : : * \return Non-success returned only in case of failure; not-found indicated by leaf_out=0
107 : : */
108 : : virtual ErrorCode point_search( const double* point, EntityHandle& leaf_out, const double iter_tol = 1.0e-10,
109 : : const double inside_tol = 1.0e-6, bool* multiple_leaves = NULL,
110 : : EntityHandle* start_node = NULL, CartVect* params = NULL ) = 0;
111 : :
112 : : /** \brief Find all leaves within a given distance from point
113 : : * If dists_out input non-NULL, also returns distances from each leaf; if
114 : : * point i is inside leaf, 0 is given as dists_out[i].
115 : : * If params_out is non-NULL and myEval is non-NULL, will evaluate individual entities
116 : : * in tree nodes and return containing entities in leaves_out. In those cases, if params_out
117 : : * is also non-NULL, will return parameters in those elements in that vector.
118 : : * \param point Point to be located in tree
119 : : * \param distance Distance within which to query
120 : : * \param leaves_out Leaves within distance or containing point
121 : : * \param iter_tol Tolerance for convergence of point search
122 : : * \param inside_tol Tolerance for inside element calculation
123 : : * \param dists_out If non-NULL, will contain distsances to leaves
124 : : * \param params_out If non-NULL, will contain parameters of the point in the ents in leaves_out
125 : : * \param start_node Start from this tree node (non-NULL) instead of tree root (NULL)
126 : : */
127 : : virtual ErrorCode distance_search( const double* point, const double distance,
128 : : std::vector< EntityHandle >& leaves_out, const double iter_tol = 1.0e-10,
129 : : const double inside_tol = 1.0e-6, std::vector< double >* dists_out = NULL,
130 : : std::vector< CartVect >* params_out = NULL,
131 : : EntityHandle* start_node = NULL ) = 0;
132 : :
133 : : /** \brief Return the MOAB interface associated with this tree
134 : : */
135 : 1270258 : Interface* moab()
136 : : {
137 : 1270258 : return mbImpl;
138 : : }
139 : :
140 : : /** \brief Return the MOAB interface associated with this tree
141 : : */
142 : : const Interface* moab() const
143 : : {
144 : : return mbImpl;
145 : : }
146 : :
147 : : /** \brief Get max depth set on tree */
148 : 2 : double get_max_depth()
149 : : {
150 : 2 : return maxDepth;
151 : : }
152 : :
153 : : /** \brief Get max entities per leaf set on tree */
154 : : double get_max_per_leaf()
155 : : {
156 : : return maxPerLeaf;
157 : : }
158 : :
159 : : /** \brief Get tree traversal stats object */
160 : 746718 : TreeStats& tree_stats()
161 : : {
162 : 746718 : return treeStats;
163 : : }
164 : :
165 : : /** \brief Get tree traversal stats object */
166 : : const TreeStats& tree_stats() const
167 : : {
168 : : return treeStats;
169 : : }
170 : :
171 : : /** \brief Create tree root and tag with bounding box
172 : : */
173 : : ErrorCode create_root( const double box_min[3], const double box_max[3], EntityHandle& root_handle );
174 : :
175 : : //! print various things about this tree
176 : : virtual ErrorCode print() = 0;
177 : :
178 : : //! get/set the ElemEvaluator
179 : 0 : inline ElemEvaluator* get_eval()
180 : : {
181 : 0 : return myEval;
182 : : }
183 : :
184 : : //! get/set the ElemEvaluator
185 : 2 : inline void set_eval( ElemEvaluator* eval )
186 : : {
187 : 2 : myEval = eval;
188 : 2 : }
189 : :
190 : : /** \brief Parse options for this tree, including common options for all trees
191 : : * \param opts Options
192 : : */
193 : : virtual ErrorCode parse_options( FileOptions& opts ) = 0;
194 : :
195 : : protected:
196 : : /** \brief Parse options common to all trees
197 : : * \param options Options for representing tree; see Tree::build_tree() and subclass
198 : : * build_tree() functions for allowed options \return Non-success returned from base class
199 : : * function only under catastrophic circumstances; derived classes also can recognize
200 : : * subclass-specific options
201 : : */
202 : : ErrorCode parse_common_options( FileOptions& options );
203 : :
204 : : /** \brief Get the box tag, possibly constructing it first
205 : : * \param create_if_missing If true and it has not been made yet, make it
206 : : */
207 : : Tag get_box_tag( bool create_if_missing = true );
208 : :
209 : : // moab instance
210 : : Interface* mbImpl;
211 : :
212 : : // bounding box for entire tree
213 : : BoundBox boundBox;
214 : :
215 : : // max entities per leaf
216 : : int maxPerLeaf;
217 : :
218 : : // max depth of tree
219 : : int maxDepth;
220 : :
221 : : // tree depth, set by build_tree
222 : : int treeDepth;
223 : :
224 : : // min width of box, handled like tolerance
225 : : double minWidth;
226 : :
227 : : // meshset creation flags
228 : : unsigned int meshsetFlags;
229 : :
230 : : // clean up flag
231 : : bool cleanUp;
232 : :
233 : : // tree root
234 : : EntityHandle myRoot;
235 : :
236 : : // tag used to mark bounding box of nodes
237 : : Tag boxTag;
238 : :
239 : : // tag name used for boxTag
240 : : std::string boxTagName;
241 : :
242 : : // tree traversal stats
243 : : TreeStats treeStats;
244 : :
245 : : // element evaluator
246 : : ElemEvaluator* myEval;
247 : : };
248 : :
249 : 24 : inline Tree::Tree( Interface* iface )
250 : : : mbImpl( iface ), maxPerLeaf( 6 ), maxDepth( 30 ), treeDepth( -1 ), minWidth( 1.0e-10 ), meshsetFlags( 0 ),
251 [ + - ][ + - ]: 24 : cleanUp( true ), myRoot( 0 ), boxTag( 0 ), myEval( 0 )
252 : : {
253 : 24 : }
254 : :
255 [ - + ]: 48 : inline Tree::~Tree() {}
256 : :
257 : 4298 : inline ErrorCode Tree::get_bounding_box( BoundBox& box, EntityHandle* tree_node ) const
258 : : {
259 [ + + ][ - + ]: 4298 : if( ( tree_node && *tree_node == myRoot ) || !tree_node )
[ + - ]
260 : : {
261 : 4298 : box = boundBox;
262 : 4298 : return MB_SUCCESS;
263 : : }
264 : : else
265 : 0 : return MB_FAILURE;
266 : : }
267 : :
268 : 0 : inline ErrorCode Tree::get_info( EntityHandle /* root */, double* /*min[3]*/, double* /* max[3]*/,
269 : : unsigned int& /*dep*/ )
270 : : {
271 : 0 : return MB_NOT_IMPLEMENTED;
272 : : }
273 : :
274 : 31 : inline Tag Tree::get_box_tag( bool create_if_missing )
275 : : {
276 [ + + ][ + - ]: 31 : if( !boxTag && create_if_missing )
277 : : {
278 [ - + ]: 24 : assert( boxTagName.length() > 0 );
279 : : ErrorCode rval =
280 : 24 : moab()->tag_get_handle( boxTagName.c_str(), 6, MB_TYPE_DOUBLE, boxTag, MB_TAG_CREAT | MB_TAG_SPARSE );
281 [ - + ]: 24 : if( MB_INVALID_SIZE == rval )
282 : : {
283 : : // delete the tag and get it again, legacy file...
284 : 0 : rval = moab()->tag_delete( boxTag );
285 [ # # ]: 0 : if( MB_SUCCESS != rval ) return 0;
286 : 0 : boxTag = 0;
287 : 0 : return get_box_tag( true );
288 : : }
289 : :
290 [ - + ]: 24 : if( MB_SUCCESS != rval ) return 0;
291 : : }
292 : :
293 : 31 : return boxTag;
294 : : }
295 : :
296 : : } // namespace moab
297 : :
298 : : #endif
|