Loading [MathJax]/extensions/tex2jax.js
Mesh Oriented datABase  (version 5.5.1)
An array-based unstructured mesh library
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
GeomTopoTool.hpp
Go to the documentation of this file.
1 /** 2  * MOAB, a Mesh-Oriented datABase, is a software component for creating, 3  * storing and accessing finite element mesh data. 4  * 5  * Copyright 2004 Sandia Corporation. Under the terms of Contract 6  * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government 7  * retains certain rights in this software. 8  * 9  * This library is free software; you can redistribute it and/or 10  * modify it under the terms of the GNU Lesser General Public 11  * License as published by the Free Software Foundation; either 12  * version 2.1 of the License, or (at your option) any later version. 13  * 14  */ 15  16 #ifndef MOAB_GEOM_TOPO_TOOL_HPP 17 #define MOAB_GEOM_TOPO_TOOL_HPP 18  19 #include "moab/Forward.hpp" 20 #include "moab/Range.hpp" 21  22 #include <map> 23 #include <cassert> 24  25 namespace moab 26 { 27  28 // forward declare this class to avoid the header leaking in here 29 class OrientedBoxTreeTool; 30 class GeomQueryTool; 31  32 /** \class GeomTopoTool 33  * \brief Tool for interpreting geometric topology sets in MOAB database 34  * Tool for interpreting geometric topology sets in MOAB database; see MOAB metadata_info 35  * document for information on how geometric topology sets are read and represented. 36  */ 37 class GeomTopoTool 38 { 39  public: 40  /** \brief Constructor (creates a GTT object) \ 41  * Construct a GeomTopoTool object and search for geometric EntitySets if they 42  * exist in the provided moab instance. 43  * \param impl MOAB instance the GeomTopoTool will operate on. 44  * \param find_geoments if specified as True, geometric objects in the provided MOAB instance 45  will be searched for and added to the GTT. 46  \param modelRootSet the GTT will operate only on geometric EntitySets contained by this 47  EntitySet. If unprovided, the default value for the modelRootSet is the MOAB instance's root 48  set, which contains everything in the instance. \param p_rootSets_vector determines the storage 49  datastructure used to relate geometric EntitySets to their OrientedBoundingBox (OBB) Tree 50  roots. If set to true (default) a vector will be used to store the root sets along with an 51  EntityHandle offset for fast lookup of the root sets. If set to false, then a map will be used 52  to link geometric EntitySets (keys) to the OBB Tree root sets (values). \param restore_rootSets 53  determines whether or not to restore the internal index that links geomSets to their 54  corresponding OBB Root. Only relevant if find_geoments is true. (default = true) 55  */ 56  GeomTopoTool( Interface* impl, 57  bool find_geoments = false, 58  EntityHandle modelRootSet = 0, 59  bool p_rootSets_vector = true, 60  bool restore_rootSets = true ); 61  62  ~GeomTopoTool(); 63  64  //! Restore parent/child links between GEOM_TOPO mesh sets 65  ErrorCode restore_topology_from_adjacency(); 66  //! Store sense of entity relative to wrt_entity. 67  //!\return MB_MULTIPLE_ENTITIES_FOUND if surface already has a forward volume. 68  //! MB_SUCCESS if successful 69  //! otherwise whatever internal error code occured. 70  ErrorCode set_sense( EntityHandle entity, EntityHandle wrt_entity, int sense ); 71  //! Get the sense of entity with respect to wrt_entity 72  //! Returns MB_ENTITY_NOT_FOUND if no relationship found 73  ErrorCode get_sense( EntityHandle entity, EntityHandle wrt_entity, int& sense ); 74  //! Get the sense of the surface(s) with respect to the volume 75  ErrorCode get_surface_senses( EntityHandle volume, int num_surfs, const EntityHandle* surfs, int* senses_out ); 76  //! Get the senses of a surface with respect to its volumes 77  ErrorCode get_surface_senses( EntityHandle surface_ent, EntityHandle& forward_vol, EntityHandle& reverse_vol ); 78  79  //! Set the senses of a surface with respect to its volumes 80  ErrorCode set_surface_senses( EntityHandle surface_ent, EntityHandle forward_vol, EntityHandle reverse_vol ); 81  //! Get the senses of the lower dimension entity handle wrt the higher dimension entities 82  ErrorCode get_senses( EntityHandle entity, std::vector< EntityHandle >& wrt_entities, std::vector< int >& senses ); 83  //! Set the senses of the entity wrt multiple higher dimension entities 84  ErrorCode set_senses( EntityHandle entity, std::vector< EntityHandle >& wrt_entities, std::vector< int >& senses ); 85  86  /** \brief Get the volume on the other side of a surface 87  * 88  * @param A surface to query 89  * @param old_volume A volume on one side of surface 90  * @param new_volume Output parameter for volume on the other side of surface 91  * @return MB_SUCCESS if new_volume was set successfully, error if not. 92  */ 93  ErrorCode next_vol( EntityHandle surface, EntityHandle old_volume, EntityHandle& new_volume ); 94  95  //! Retrieve geometry sets of desired dimension from model set 96  // 0 = verts, 1 = curves, 2 = surfs, 3 = vols 97  ErrorCode get_gsets_by_dimension( int dim, Range& gset ); 98  99  /** \brief Build obb tree for the entity set given; entity can be surface or volume 100  * 101  * @param eh EntityHandle of the volume or surface to construct the OBB tree around 102  */ 103  ErrorCode construct_obb_tree( EntityHandle eh ); 104  105  /** \brief Get the bouding points from a bounding box 106  * 107  * @param volume The volume for which the bounding coordinates are requested 108  * @param minPt Location of the min xyz corner of the volume's axis-aligned bounding box 109  * @param maxPt Location of the max xyz corner of the volume's axis-aligned bounding box 110  */ 111  ErrorCode get_bounding_coords( EntityHandle volume, double minPt[3], double maxPt[3] ); 112  113  /** \brief Get the center point and three vectors for the OBB of a given volume 114  * 115  * @param volume The volume for which the OBB axes will be returned 116  * @param center coordinates of the oriented bounding box's center point 117  * @param axis1 scaled axis one of the oriented bounding box 118  * @param axis2 scaled axis two of the oriented bounding box 119  * @param axis3 scaled axis three of the oriented bounding box 120  */ 121  ErrorCode get_obb( EntityHandle volume, double center[3], double axis1[3], double axis2[3], double axis3[3] ); 122  123  /** \brief Get the other (d-1)-dimensional entity bounding a set across a (d-2)-dimensional 124  * entity 125  * 126  * Given a d-dimensional entity and one (d-1)-dimensional entity, return the (d-1) dimensional 127  * entity across a specified (d-2)-dimensional entity. For example, given a surface, edge, and 128  * vertex, returns the other edge bounding the surface sharing the vertex. In the case of 129  * degenerate results, e.g. two loops bounding a surface and sharing a vertex, tries to step in 130  * positively-oriented direction. This won't always work; in those cases, will return 131  * MB_MULTIPLE_ENTITIES_FOUND. 132  * 133  * In the special case where bounded is a curve, then not_this can be a vertex and across zero. 134  * This function returns the other vertex on the curve. 135  */ 136  ErrorCode other_entity( EntityHandle bounded, EntityHandle not_this, EntityHandle across, EntityHandle& other ); 137  138  /** \brief Return the dimension of the set, or -1 if it's not a geom_dimension set 139  */ 140  int dimension( EntityHandle this_set ); 141  142  /** \brief Return the global ID of a given entity set 143  * 144  * @param this_set EntitySet for which the global ID will be returned 145  */ 146  int global_id( EntityHandle this_set ); 147  148  //! Map from dimension & global ID to EntityHandle 149  EntityHandle entity_by_id( int dimension, int id ); 150  151  ErrorCode find_geomsets( Range* ranges = NULL ); 152  153  //! Restore the internal cross-referencing of geometry sets and OBB roots 154  // The EntityHandle of an OBB Root can be tagged onto the geoemtry EntitySet 155  // that it represents so that this relationship can be recovered across 156  // write to/read from file. Since finding the OBB Root for a given geomset 157  // is frequent, a faster lookup capability is enabled through data structures 158  // in GeomTopoTool (i.e. rootSets or mapRootSets). This data structure 159  // needs to be populated upon file read. 160  ErrorCode restore_obb_index(); 161  162  //! Build obb trees for all surfaces and volumes in model set. 163  // If make_one_vol true, joins trees from all surfaces in model into single 164  // volume obb tree. 165  ErrorCode construct_obb_trees( bool make_one_vol = false ); 166  167  //! Delete the OBB tree of a volume or surface. 168  // If the passed entity is a volume, and the bool 'vol_only' 169  // is True, function will delete the volume OBB tree, but 170  // OBB trees of the surfaces that compose (are children of) 171  // the volume will remain in tact. If the entity is a volume and 172  // 'vol_only' is False, function will delete the volume OBB tree 173  // along with all child surface OBB trees. 174  ErrorCode delete_obb_tree( EntityHandle gset, bool vol_only = false ); 175  176  ErrorCode delete_all_obb_trees(); 177  178  //! Delete the root of the obb tree from the set of all roots 179  ErrorCode remove_root( EntityHandle vol_or_surf ); 180  181  //! Get the root of the obbtree for a given entity 182  ErrorCode get_root( EntityHandle vol_or_surf, EntityHandle& root ); 183  184  //! If constructing one volume obb tree by joining all surface trees, 185  // get the root of that tree 186  EntityHandle get_one_vol_root(); 187  188  //! Pointer to Oriented Box Tree Tool class 189  OrientedBoxTreeTool* obb_tree() 190  { 191  return obbTree; 192  } 193  194  //! Adds a geometry set to the range of all geometry sets, the model set, and root set 195  // Make sure the set has the proper geometry dimension tag 196  // This could make the obb tree out of date 197  ErrorCode add_geo_set( EntityHandle set, int dimension, int global_id = 0 ); 198  199  //! Will assume no geo sets are defined for this surface 200  // Will output a mesh_set that contains everything (all sets of interest), for proper output 201  ErrorCode geometrize_surface_set( EntityHandle surface, EntityHandle& output ); 202  203  //! Checks to see if the entity is part of the model set 204  ErrorCode is_owned_set( EntityHandle eh ); 205  206  //! This would be a deep copy, into a new geom topo tool 207  // sets will be duplicated, but entities not 208  // modelSet will be a new one; 209  // will take as input a pointer to a std::vector of gents (surfaces and volumes, usually), 210  // which will serve to filter the gents from modelSet (only dependents will be part of the new 211  // gtt) if the pointer is null, all gsets in the original modelSet are duplicated 212  ErrorCode duplicate_model( GeomTopoTool*& duplicate, std::vector< EntityHandle >* pvGEnts = NULL ); 213  214  //! Return the model set handle (this is the full geometry) 215  EntityHandle get_root_model_set() 216  { 217  return modelSet; 218  } 219  220  //! Checks that all geometric entities were created properly 221  bool check_model(); 222  223  //! Should be used instead of keeping multiple ranges, for example in FBEngine 224  const Range* geoRanges() 225  { 226  return geomRanges; 227  } 228  229  //! Return pointer to moab instance 230  Interface* get_moab_instance() 231  { 232  return mdbImpl; 233  } 234  235  //! Returns the sense tag (sense2Tag) from check_face_sense_tag 236  Tag get_sense_tag(); 237  238  //! Returns the global ID tag (gidTag) from check_gid_tag 239  Tag get_gid_tag(); 240  241  //! Returns the geometry dimension tag (geomTag) from check_geom_tag 242  Tag get_geom_tag(); 243  244  //! Returns true if obb trees have been added to the rootset 245  bool have_obb_tree(); 246  247  //! returns the number of entities in the modelSet with specified geometric dimension 248  int num_ents_of_dim( int dim ); 249  250  //! sets the implicit complement handle for this tool 251  ErrorCode setup_implicit_complement(); 252  253  //! Get (or optionally, create) the implicit complement handle 254  ErrorCode get_implicit_complement( EntityHandle& implicit_complement ); 255  256  //! detection method for the implicit complement 257  bool is_implicit_complement( EntityHandle volume ); 258  259  /** \brief Discover and store the topological relationships among a set of volumes 260  * This method may be used to discover the hierarchy that exists in a range of 261  * volumes, that have no previous sense of hierarchy, and store it according 262  * to the conventions of GeomTopoTool. 263  * The following requirements about the range of flat_volumes must be met: 264  * 1. Each volume must be represented by a single, closed surface 265  * a. The surface meshsets have triangles and vertices as members. 266  * b. For each "flat volume", there must be two meshsets: one for the 267  * volume and another for the surface that encloses it. These must be 268  * linked by a parent-child relationship. 269  * c. The SENSE_FORWARD tag on the surface meshset must be set to be 270  * the volume meshset it encloses. 271  * 2. The surfaces must not touch or overlap 272  * 273  * After the hierarchy is established, the topological relationships between 274  * surfaces and the volumes that enclose them are set. This involves: 275  * 1. Setting parent-child relationship between surfaces and the volumes that 276  * enclose them. 277  * 2. Setting the SENSE_REVERSE tag on the surfaces to be the volume that 278  * encloses them. 279  * 280  */ 281  ErrorCode restore_topology_from_geometric_inclusion( const Range& flat_volumes ); 282  283  private: 284  Interface* mdbImpl; 285  Tag sense2Tag; 286  Tag senseNEntsTag, senseNSensesTag; 287  Tag geomTag; 288  Tag gidTag; 289  Tag nameTag; 290  Tag obbRootTag; 291  Tag obbGsetTag; 292  // the model set encompasses a full topological model 293  EntityHandle modelSet; 294  // implicit complement handle cache 295  EntityHandle impl_compl_handle; 296  297  Range geomRanges[5]; // add one more dimension, for set of gentities; by default, they will 298  // have geom_dimension 4 299  int maxGlobalId[5]; // one max global id for each dimension 300  bool updated; 301  302  OrientedBoxTreeTool* obbTree; 303  EntityHandle setOffset; 304  std::vector< EntityHandle > rootSets; 305  306  bool m_rootSets_vector; 307  std::map< EntityHandle, EntityHandle > mapRootSets; 308  EntityHandle oneVolRootSet; 309  310  //! Creates a volume for undefined space in the model 311  // The implicit complement is composed of all surfaces that only 312  // have one parent volume, i.e. surfaces that are in contact with the outside 313  // world 314  ErrorCode generate_implicit_complement( EntityHandle& implicit_complement_set ); 315  316  //! Compute vertices inclusive and put on tag on sets in geom_sets 317  ErrorCode construct_vertex_ranges( const Range& geom_sets, const Tag verts_tag ); 318  319  //! Given a range of geom topology sets, separate by dimension 320  ErrorCode separate_by_dimension( const Range& geom_sets ); 321  322  //! Verify global id tag 323  ErrorCode check_gid_tag( bool create = false ); 324  325  //! Verify geometry tag 326  ErrorCode check_geom_tag( bool create = false ); 327  328  //! Verify sense face tag 329  ErrorCode check_face_sense_tag( bool create = false ); 330  331  //! Verify sense edge tags 332  ErrorCode check_edge_sense_tags( bool create = false ); 333  334  ErrorCode resize_rootSets(); 335  336  ErrorCode set_root_set( EntityHandle vol_or_surf, EntityHandle root ); 337  338  //! Return a range of children of a desired geometric dimension 339  Range get_ct_children_by_dimension( const EntityHandle parent, const int desired_dimension ); 340  341  //! Test if volume A is enclosed by volume B 342  // This will only produce the correct result if the conventions about 343  // volumes listed in the restore_topology_from_geometric_inclusion are 344  // upheld 345  bool A_is_in_B( const EntityHandle volume_A, const EntityHandle volume_B, GeomQueryTool* GQT ); 346  347  //! Used by restore_topology_from_geometric_inclusion to generate the 348  // hierarchical tree of volumes 349  ErrorCode insert_in_tree( const EntityHandle ct_root, const EntityHandle volume, GeomQueryTool* GQT ); 350 }; 351  352 inline int GeomTopoTool::num_ents_of_dim( int dim ) 353 { 354  assert( 0 <= dim && 3 >= dim ); 355  return geomRanges[dim].size(); 356 } 357  358 // get the root of the obbtree for a given entity 359 inline ErrorCode GeomTopoTool::get_root( EntityHandle vol_or_surf, EntityHandle& root ) 360 { 361  if( m_rootSets_vector ) 362  { 363  unsigned int index = vol_or_surf - setOffset; 364  root = ( index < rootSets.size() ? rootSets[index] : 0 ); 365  } 366  else 367  root = mapRootSets[vol_or_surf]; 368  return ( root ? MB_SUCCESS : MB_INDEX_OUT_OF_RANGE ); 369 } 370  371 inline EntityHandle GeomTopoTool::get_one_vol_root() 372 { 373  return oneVolRootSet; 374 } 375  376 inline Tag GeomTopoTool::get_sense_tag() 377 { 378  check_face_sense_tag( true ); 379  return sense2Tag; 380 } 381  382 inline Tag GeomTopoTool::get_gid_tag() 383 { 384  check_gid_tag( true ); 385  return gidTag; 386 } 387  388 inline Tag GeomTopoTool::get_geom_tag() 389 { 390  check_geom_tag( true ); 391  return geomTag; 392 } 393  394 inline bool GeomTopoTool::is_implicit_complement( EntityHandle volume ) 395 { 396  return volume == impl_compl_handle; 397 } 398  399 } // namespace moab 400  401 #endif