LCOV - code coverage report
Current view: top level - src/moab - GeomTopoTool.hpp (source / functions) Hit Total Coverage
Test: coverage_sk.info Lines: 30 30 100.0 %
Date: 2020-12-16 07:07:30 Functions: 11 11 100.0 %
Branches: 6 8 75.0 %

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

Generated by: LCOV version 1.11