Mesh Oriented datABase  (version 5.6.0)
An array-based unstructured mesh library
moab::GeomTopoTool Class Reference

Tool for interpreting geometric topology sets in MOAB database Tool for interpreting geometric topology sets in MOAB database; see MOAB metadata_info document for information on how geometric topology sets are read and represented. More...

#include <GeomTopoTool.hpp>

+ Collaboration diagram for moab::GeomTopoTool:

Public Member Functions

 GeomTopoTool (Interface *impl, bool find_geoments=false, EntityHandle modelRootSet=0, bool p_rootSets_vector=true, bool restore_rootSets=true)
 Constructor (creates a GTT object) \ Construct a GeomTopoTool object and search for geometric EntitySets if they exist in the provided moab instance. More...
 
 ~GeomTopoTool ()
 
ErrorCode restore_topology_from_adjacency ()
 Restore parent/child links between GEOM_TOPO mesh sets. More...
 
ErrorCode set_sense (EntityHandle entity, EntityHandle wrt_entity, int sense)
 Store sense of entity relative to wrt_entity. More...
 
ErrorCode get_sense (EntityHandle entity, EntityHandle wrt_entity, int &sense)
 Get the sense of entity with respect to wrt_entity Returns MB_ENTITY_NOT_FOUND if no relationship found. More...
 
ErrorCode get_surface_senses (EntityHandle volume, int num_surfs, const EntityHandle *surfs, int *senses_out)
 Get the sense of the surface(s) with respect to the volume. More...
 
ErrorCode get_surface_senses (EntityHandle surface_ent, EntityHandle &forward_vol, EntityHandle &reverse_vol)
 Get the senses of a surface with respect to its volumes. More...
 
ErrorCode set_surface_senses (EntityHandle surface_ent, EntityHandle forward_vol, EntityHandle reverse_vol)
 Set the senses of a surface with respect to its volumes. More...
 
ErrorCode get_senses (EntityHandle entity, std::vector< EntityHandle > &wrt_entities, std::vector< int > &senses)
 Get the senses of the lower dimension entity handle wrt the higher dimension entities. More...
 
ErrorCode set_senses (EntityHandle entity, std::vector< EntityHandle > &wrt_entities, std::vector< int > &senses)
 Set the senses of the entity wrt multiple higher dimension entities. More...
 
ErrorCode next_vol (EntityHandle surface, EntityHandle old_volume, EntityHandle &new_volume)
 Get the volume on the other side of a surface. More...
 
ErrorCode get_gsets_by_dimension (int dim, Range &gset)
 Retrieve geometry sets of desired dimension from model set. More...
 
ErrorCode construct_obb_tree (EntityHandle eh)
 Build obb tree for the entity set given; entity can be surface or volume. More...
 
ErrorCode get_bounding_coords (EntityHandle volume, double minPt[3], double maxPt[3])
 Get the bouding points from a bounding box. More...
 
ErrorCode get_obb (EntityHandle volume, double center[3], double axis1[3], double axis2[3], double axis3[3])
 Get the center point and three vectors for the OBB of a given volume. More...
 
ErrorCode other_entity (EntityHandle bounded, EntityHandle not_this, EntityHandle across, EntityHandle &other)
 Get the other (d-1)-dimensional entity bounding a set across a (d-2)-dimensional entity. More...
 
int dimension (EntityHandle this_set)
 Return the dimension of the set, or -1 if it's not a geom_dimension set. More...
 
int global_id (EntityHandle this_set)
 Return the global ID of a given entity set. More...
 
EntityHandle entity_by_id (int dimension, int id)
 Map from dimension & global ID to EntityHandle. More...
 
ErrorCode find_geomsets (Range *ranges=NULL)
 
ErrorCode restore_obb_index ()
 Restore the internal cross-referencing of geometry sets and OBB roots. More...
 
ErrorCode construct_obb_trees (bool make_one_vol=false)
 Build obb trees for all surfaces and volumes in model set. More...
 
ErrorCode delete_obb_tree (EntityHandle gset, bool vol_only=false)
 Delete the OBB tree of a volume or surface. More...
 
ErrorCode delete_all_obb_trees ()
 
ErrorCode remove_root (EntityHandle vol_or_surf)
 Delete the root of the obb tree from the set of all roots. More...
 
ErrorCode get_root (EntityHandle vol_or_surf, EntityHandle &root)
 Get the root of the obbtree for a given entity. More...
 
EntityHandle get_one_vol_root ()
 If constructing one volume obb tree by joining all surface trees,. More...
 
OrientedBoxTreeToolobb_tree ()
 Pointer to Oriented Box Tree Tool class. More...
 
ErrorCode add_geo_set (EntityHandle set, int dimension, int global_id=0)
 Adds a geometry set to the range of all geometry sets, the model set, and root set. More...
 
ErrorCode geometrize_surface_set (EntityHandle surface, EntityHandle &output)
 Will assume no geo sets are defined for this surface. More...
 
ErrorCode is_owned_set (EntityHandle eh)
 Checks to see if the entity is part of the model set. More...
 
ErrorCode duplicate_model (GeomTopoTool *&duplicate, std::vector< EntityHandle > *pvGEnts=NULL)
 This would be a deep copy, into a new geom topo tool. More...
 
EntityHandle get_root_model_set ()
 Return the model set handle (this is the full geometry) More...
 
bool check_model ()
 Checks that all geometric entities were created properly. More...
 
const RangegeoRanges ()
 Should be used instead of keeping multiple ranges, for example in FBEngine. More...
 
Interfaceget_moab_instance ()
 Return pointer to moab instance. More...
 
Tag get_sense_tag ()
 Returns the sense tag (sense2Tag) from check_face_sense_tag. More...
 
Tag get_gid_tag ()
 Returns the global ID tag (gidTag) from check_gid_tag. More...
 
Tag get_geom_tag ()
 Returns the geometry dimension tag (geomTag) from check_geom_tag. More...
 
bool have_obb_tree ()
 Returns true if obb trees have been added to the rootset. More...
 
int num_ents_of_dim (int dim)
 returns the number of entities in the modelSet with specified geometric dimension More...
 
ErrorCode setup_implicit_complement ()
 sets the implicit complement handle for this tool More...
 
ErrorCode get_implicit_complement (EntityHandle &implicit_complement)
 Get (or optionally, create) the implicit complement handle. More...
 
bool is_implicit_complement (EntityHandle volume)
 detection method for the implicit complement More...
 
ErrorCode restore_topology_from_geometric_inclusion (const Range &flat_volumes)
 Discover and store the topological relationships among a set of volumes This method may be used to discover the hierarchy that exists in a range of volumes, that have no previous sense of hierarchy, and store it according to the conventions of GeomTopoTool. The following requirements about the range of flat_volumes must be met: More...
 

Private Member Functions

ErrorCode generate_implicit_complement (EntityHandle &implicit_complement_set)
 Creates a volume for undefined space in the model. More...
 
ErrorCode construct_vertex_ranges (const Range &geom_sets, const Tag verts_tag)
 Compute vertices inclusive and put on tag on sets in geom_sets. More...
 
ErrorCode separate_by_dimension (const Range &geom_sets)
 Given a range of geom topology sets, separate by dimension. More...
 
ErrorCode check_gid_tag (bool create=false)
 Verify global id tag. More...
 
ErrorCode check_geom_tag (bool create=false)
 Verify geometry tag. More...
 
ErrorCode check_face_sense_tag (bool create=false)
 Verify sense face tag. More...
 
ErrorCode check_edge_sense_tags (bool create=false)
 Verify sense edge tags. More...
 
ErrorCode resize_rootSets ()
 
ErrorCode set_root_set (EntityHandle vol_or_surf, EntityHandle root)
 
Range get_ct_children_by_dimension (const EntityHandle parent, const int desired_dimension)
 Return a range of children of a desired geometric dimension. More...
 
bool A_is_in_B (const EntityHandle volume_A, const EntityHandle volume_B, GeomQueryTool *GQT)
 Test if volume A is enclosed by volume B. More...
 
ErrorCode insert_in_tree (const EntityHandle ct_root, const EntityHandle volume, GeomQueryTool *GQT)
 Used by restore_topology_from_geometric_inclusion to generate the. More...
 

Private Attributes

InterfacemdbImpl
 
Tag sense2Tag
 
Tag senseNEntsTag
 
Tag senseNSensesTag
 
Tag geomTag
 
Tag gidTag
 
Tag nameTag
 
Tag obbRootTag
 
Tag obbGsetTag
 
EntityHandle modelSet
 
EntityHandle impl_compl_handle
 
Range geomRanges [5]
 
int maxGlobalId [5]
 
bool updated
 
OrientedBoxTreeToolobbTree
 
EntityHandle setOffset
 
std::vector< EntityHandlerootSets
 
bool m_rootSets_vector
 
std::map< EntityHandle, EntityHandlemapRootSets
 
EntityHandle oneVolRootSet
 

Detailed Description

Tool for interpreting geometric topology sets in MOAB database Tool for interpreting geometric topology sets in MOAB database; see MOAB metadata_info document for information on how geometric topology sets are read and represented.

Examples
GeomSetHierarchy.cpp.

Definition at line 37 of file GeomTopoTool.hpp.

Constructor & Destructor Documentation

◆ GeomTopoTool()

moab::GeomTopoTool::GeomTopoTool ( Interface impl,
bool  find_geoments = false,
EntityHandle  modelRootSet = 0,
bool  p_rootSets_vector = true,
bool  restore_rootSets = true 
)

Constructor (creates a GTT object) \ Construct a GeomTopoTool object and search for geometric EntitySets if they exist in the provided moab instance.

Parameters
implMOAB instance the GeomTopoTool will operate on.
find_geomentsif specified as True, geometric objects in the provided MOAB instance will be searched for and added to the GTT.
modelRootSetthe GTT will operate only on geometric EntitySets contained by this EntitySet. If unprovided, the default value for the modelRootSet is the MOAB instance's root set, which contains everything in the instance.
p_rootSets_vectordetermines the storage datastructure used to relate geometric EntitySets to their OrientedBoundingBox (OBB) Tree roots. If set to true (default) a vector will be used to store the root sets along with an EntityHandle offset for fast lookup of the root sets. If set to false, then a map will be used to link geometric EntitySets (keys) to the OBB Tree root sets (values).
restore_rootSetsdetermines whether or not to restore the internal index that links geomSets to their corresponding OBB Root. Only relevant if find_geoments is true. (default = true)

Definition at line 46 of file GeomTopoTool.cpp.

51  : mdbImpl( impl ), sense2Tag( 0 ), senseNEntsTag( 0 ), senseNSensesTag( 0 ), geomTag( 0 ), gidTag( 0 ),
52  obbRootTag( 0 ), obbGsetTag( 0 ), modelSet( modelRootSet ), updated( false ), setOffset( 0 ),
53  m_rootSets_vector( p_rootSets_vector ), oneVolRootSet( 0 )
54 {
55 
56  obbTree = new OrientedBoxTreeTool( impl, NULL, true );
57 
58  ErrorCode rval =
59  mdbImpl->tag_get_handle( GEOM_DIMENSION_TAG_NAME, 1, MB_TYPE_INTEGER, geomTag, MB_TAG_CREAT | MB_TAG_SPARSE );MB_CHK_SET_ERR_CONT( rval, "Error: Failed to create geometry dimension tag" );
60 
61  // global id tag is not really needed, but mbsize complains if we do not set it for
62  // geometry entities
64 
65  rval =
67 
68  rval = mdbImpl->tag_get_handle( OBB_ROOT_TAG_NAME, 1, MB_TYPE_HANDLE, obbRootTag, MB_TAG_CREAT | MB_TAG_SPARSE );MB_CHK_SET_ERR_CONT( rval, "Error: Failed to create obb root tag" );
69 
70  rval = mdbImpl->tag_get_handle( OBB_GSET_TAG_NAME, 1, MB_TYPE_HANDLE, obbGsetTag, MB_TAG_CREAT | MB_TAG_SPARSE );MB_CHK_SET_ERR_CONT( rval, "Error: Failed to create obb gset tag" );
71 
72  // set this value to zero for comparisons
74 
75  maxGlobalId[0] = maxGlobalId[1] = maxGlobalId[2] = maxGlobalId[3] = maxGlobalId[4] = 0;
76  if( find_geoments )
77  {
78  find_geomsets();
79  if( restore_rootSets )
80  {
81  rval = restore_obb_index();
82  if( MB_SUCCESS != rval )
83  {
84  rval = delete_all_obb_trees();MB_CHK_SET_ERR_CONT( rval, "Error: Failed to delete existing obb trees" );
85  rval = construct_obb_trees();MB_CHK_SET_ERR_CONT( rval, "Error: Failed to rebuild obb trees" );
86  }
87  }
88  }
89 }

References construct_obb_trees(), delete_all_obb_trees(), ErrorCode, find_geomsets(), GEOM_DIMENSION_TAG_NAME, geomTag, gidTag, moab::Interface::globalId_tag(), impl_compl_handle, maxGlobalId, MB_CHK_SET_ERR_CONT, MB_SUCCESS, MB_TAG_CREAT, MB_TAG_SPARSE, MB_TYPE_HANDLE, MB_TYPE_INTEGER, MB_TYPE_OPAQUE, mdbImpl, NAME_TAG_NAME, NAME_TAG_SIZE, nameTag, moab::OBB_GSET_TAG_NAME, moab::OBB_ROOT_TAG_NAME, obbGsetTag, obbRootTag, obbTree, restore_obb_index(), and moab::Interface::tag_get_handle().

Referenced by duplicate_model().

◆ ~GeomTopoTool()

moab::GeomTopoTool::~GeomTopoTool ( )

Definition at line 91 of file GeomTopoTool.cpp.

92 {
93  delete obbTree;
94 }

References obbTree.

Member Function Documentation

◆ A_is_in_B()

bool moab::GeomTopoTool::A_is_in_B ( const EntityHandle  volume_A,
const EntityHandle  volume_B,
GeomQueryTool GQT 
)
private

Test if volume A is enclosed by volume B.

Definition at line 1981 of file GeomTopoTool.cpp.

1982 {
1983  Range child_surfaces, triangles, vertices;
1984  double coord[3]; // coord[0] = x, etc.
1985  int result; // point in vol result; 0=F, 1=T
1986 
1987  // find coordinates of any point on surface of A
1988  // get surface corresponding to volume, then get the triangles
1989  child_surfaces = get_ct_children_by_dimension( volume_A, 2 );
1990  MB_CHK_ERR( mdbImpl->get_entities_by_type( *child_surfaces.begin(), MBTRI, triangles ) );
1991 
1992  // now get 1st triangle vertices
1993  MB_CHK_ERR( mdbImpl->get_connectivity( &( *triangles.begin() ), 1, vertices ) );
1994 
1995  // now get coordinates of first vertex
1996  MB_CHK_ERR( mdbImpl->get_coords( &( *vertices.begin() ), 1, &( coord[0] ) ) );
1997 
1998  // if point on A is inside vol B, return T; o.w. return F
1999  MB_CHK_SET_ERR( GQT->point_in_volume( volume_B, coord, result ), "Failed to complete point in volume query." );
2000 
2001  return ( result != 0 );
2002 }

References moab::Range::begin(), moab::Interface::get_connectivity(), moab::Interface::get_coords(), get_ct_children_by_dimension(), moab::Interface::get_entities_by_type(), MB_CHK_ERR, MB_CHK_SET_ERR, MBTRI, mdbImpl, and moab::GeomQueryTool::point_in_volume().

Referenced by insert_in_tree().

◆ add_geo_set()

ErrorCode moab::GeomTopoTool::add_geo_set ( EntityHandle  set,
int  dimension,
int  global_id = 0 
)

Adds a geometry set to the range of all geometry sets, the model set, and root set.

Definition at line 1176 of file GeomTopoTool.cpp.

1177 {
1178  if( dim < 0 || dim > 4 ) MB_SET_ERR( MB_FAILURE, "Invalid geometric dimension provided" );
1179 
1180  // see if it is not already set
1181  if( geomRanges[dim].find( set ) != geomRanges[dim].end() )
1182  {
1183  return MB_SUCCESS; // nothing to do, we already have it as a geo set of proper dimension
1184  }
1185  updated = false; // this should trigger at least an obb recomputation
1186  // get the geom topology tag
1187  ErrorCode result;
1188  if( 0 == geomTag )
1189  {
1191  MB_CHK_SET_ERR( result, "Failed to get the geometry dimension tag handle" );
1192  }
1193 
1194  if( 0 == gidTag )
1195  {
1197  }
1198 
1199  // make sure the added set has the geom tag properly set
1200  result = mdbImpl->tag_set_data( geomTag, &set, 1, &dim );
1201  MB_CHK_SET_ERR( result, "Failed set the geometry dimension tag value" );
1202 
1203  geomRanges[dim].insert( set );
1204  // not only that, but also add it to the root model set
1205  if( modelSet )
1206  {
1207  result = mdbImpl->add_entities( modelSet, &set, 1 );
1208  MB_CHK_SET_ERR( result, "Failed to add new geometry set to the tool's modelSet" );
1209  }
1210 
1211  // set the global ID value
1212  // if passed 0, just increase the max id for the dimension
1213  if( 0 == gid )
1214  {
1215  gid = ++maxGlobalId[dim];
1216  }
1217 
1218  result = mdbImpl->tag_set_data( gidTag, &set, 1, &gid );
1219  MB_CHK_SET_ERR( result, "Failed to get the global id tag value for the geom entity" );
1220 
1221  return MB_SUCCESS;
1222 }

References moab::Interface::add_entities(), ErrorCode, GEOM_DIMENSION_TAG_NAME, geomRanges, geomTag, gidTag, moab::Interface::globalId_tag(), moab::Range::insert(), maxGlobalId, MB_CHK_SET_ERR, MB_SET_ERR, MB_SUCCESS, MB_TYPE_INTEGER, mdbImpl, modelSet, moab::Interface::tag_get_handle(), moab::Interface::tag_set_data(), and updated.

Referenced by moab::FBEngine::create_new_gedge(), moab::FBEngine::create_volume_with_direction(), geometrize_surface_set(), setup_implicit_complement(), moab::FBEngine::split_bedge_at_new_mesh_node(), moab::FBEngine::split_edge_at_mesh_node(), moab::FBEngine::split_surface(), and moab::FBEngine::weave_lateral_face_from_edges().

◆ check_edge_sense_tags()

ErrorCode moab::GeomTopoTool::check_edge_sense_tags ( bool  create = false)
private

Verify sense edge tags.

Definition at line 1161 of file GeomTopoTool.cpp.

1162 {
1163  unsigned flags = MB_TAG_VARLEN | MB_TAG_SPARSE;
1164  if( create ) flags |= MB_TAG_CREAT;
1165  if( !senseNEntsTag )
1166  {
1168  "Failed to get the curve to surface entity tag handle" );
1170  flags ),
1171  "Failed to get the curve to surface sense tag handle" );
1172  }
1173  return MB_SUCCESS;
1174 }

References moab::GEOM_SENSE_N_ENTS_TAG_NAME, moab::GEOM_SENSE_N_SENSES_TAG_NAME, MB_CHK_SET_ERR, MB_SUCCESS, MB_TAG_CREAT, MB_TAG_SPARSE, MB_TAG_VARLEN, MB_TYPE_HANDLE, MB_TYPE_INTEGER, mdbImpl, senseNEntsTag, senseNSensesTag, and moab::Interface::tag_get_handle().

Referenced by duplicate_model(), get_sense(), get_senses(), and set_sense().

◆ check_face_sense_tag()

ErrorCode moab::GeomTopoTool::check_face_sense_tag ( bool  create = false)
private

Verify sense face tag.

Definition at line 1148 of file GeomTopoTool.cpp.

1149 {
1150  unsigned flags = create ? MB_TAG_SPARSE | MB_TAG_CREAT | MB_TAG_ANY : MB_TAG_SPARSE | MB_TAG_ANY;
1151  if( !sense2Tag )
1152  {
1153  EntityHandle def_val[2] = { 0, 0 };
1155  "Could not get/create the sense2Tag" );
1156  }
1157  return MB_SUCCESS;
1158 }

References moab::GEOM_SENSE_2_TAG_NAME, MB_CHK_SET_ERR, MB_SUCCESS, MB_TAG_ANY, MB_TAG_CREAT, MB_TAG_SPARSE, MB_TYPE_HANDLE, mdbImpl, sense2Tag, and moab::Interface::tag_get_handle().

Referenced by duplicate_model(), generate_implicit_complement(), get_sense(), get_sense_tag(), get_senses(), and set_sense().

◆ check_geom_tag()

ErrorCode moab::GeomTopoTool::check_geom_tag ( bool  create = false)
private

Verify geometry tag.

Definition at line 1122 of file GeomTopoTool.cpp.

1123 {
1124  unsigned flags = create ? MB_TAG_DENSE | MB_TAG_CREAT : MB_TAG_DENSE;
1125  if( !geomTag )
1126  {
1127  // get any kind of tag that already exists
1129  "Could not get/create the geometry dimension tag" );
1130  }
1131  return MB_SUCCESS;
1132 }

References GEOM_DIMENSION_TAG_NAME, geomTag, MB_CHK_SET_ERR, MB_SUCCESS, MB_TAG_CREAT, MB_TAG_DENSE, MB_TYPE_INTEGER, mdbImpl, and moab::Interface::tag_get_handle().

Referenced by get_geom_tag(), and separate_by_dimension().

◆ check_gid_tag()

ErrorCode moab::GeomTopoTool::check_gid_tag ( bool  create = false)
private

Verify global id tag.

Definition at line 1134 of file GeomTopoTool.cpp.

1135 {
1136  unsigned flags = create ? MB_TAG_DENSE | MB_TAG_CREAT : MB_TAG_DENSE;
1137  if( !gidTag )
1138  {
1139  // get any kind of tag that already exists
1141  "Could not get/create the global id tag" );
1142  }
1143  return MB_SUCCESS;
1144 }

References gidTag, GLOBAL_ID_TAG_NAME, MB_CHK_SET_ERR, MB_SUCCESS, MB_TAG_CREAT, MB_TAG_DENSE, MB_TYPE_INTEGER, mdbImpl, and moab::Interface::tag_get_handle().

Referenced by get_gid_tag().

◆ check_model()

bool moab::GeomTopoTool::check_model ( )

Checks that all geometric entities were created properly.

Definition at line 1763 of file GeomTopoTool.cpp.

1764 {
1765  // vertex sets should have one node
1766  Range::iterator rit;
1767  ErrorCode rval;
1768  for( rit = geomRanges[0].begin(); rit != geomRanges[0].end(); ++rit )
1769  {
1770  EntityHandle vSet = *rit;
1771  Range nodes;
1772  rval = mdbImpl->get_entities_by_handle( vSet, nodes );
1773  if( MB_SUCCESS != rval ) RETFALSE( " failed to get nodes from vertex set ", vSet );
1774  if( nodes.size() != 1 ) RETFALSE( " number of nodes is different from 1 ", vSet )
1775  EntityType type = mdbImpl->type_from_handle( nodes[0] );
1776  if( type != MBVERTEX ) RETFALSE( " entity in vertex set is not a node ", nodes[0] )
1777  // get all parents, and see if they belong to geomRanges[1]
1778  Range edges;
1779  rval = mdbImpl->get_parent_meshsets( vSet, edges );
1780  if( MB_SUCCESS != rval ) RETFALSE( " can't get parent edges for a node set ", vSet )
1781  Range notEdges = subtract( edges, geomRanges[1] );
1782  if( !notEdges.empty() ) RETFALSE( " some parents of a node set are not geo edges ", notEdges[0] )
1783  }
1784 
1785  // edges to be formed by continuous chain of mesh edges, oriented correctly
1786  for( rit = geomRanges[1].begin(); rit != geomRanges[1].end(); ++rit )
1787  {
1788  EntityHandle edge = *rit;
1789  std::vector< EntityHandle > mesh_edges;
1790  rval = mdbImpl->get_entities_by_type( edge, MBEDGE, mesh_edges );
1791  if( MB_SUCCESS != rval ) RETFALSE( " can't get mesh edges from edge set", edge )
1792  int num_edges = (int)mesh_edges.size();
1793  if( num_edges == 0 ) RETFALSE( " no mesh edges in edge set ", edge )
1794  EntityHandle firstNode;
1795  EntityHandle currentNode; // will also hold the last node in chain of edges
1796  const EntityHandle* conn2;
1797  int nnodes2;
1798  // get all parents, and see if they belong to geomRanges[1]
1799  for( int i = 0; i < num_edges; i++ )
1800  {
1801  rval = mdbImpl->get_connectivity( mesh_edges[i], conn2, nnodes2 );
1802  if( MB_SUCCESS != rval || nnodes2 != 2 ) RETFALSE( " mesh edge connectivity is wrong ", mesh_edges[i] )
1803  if( i == 0 )
1804  {
1805  firstNode = conn2[0];
1806  currentNode = conn2[1];
1807  }
1808 
1809  else // if ( (i>0) )
1810  {
1811  // check the current node is conn[0]
1812  if( conn2[0] != currentNode )
1813  {
1814  std::cout << "i=" << i << " conn2:" << conn2[0] << " " << conn2[1] << " currentNode:" << currentNode
1815  << "\n";
1816  mdbImpl->list_entity( mesh_edges[i] );
1817  RETFALSE( " edges are not contiguous in edge set ", edge )
1818  }
1819  currentNode = conn2[1];
1820  }
1821  }
1822  // check the children of the edge set; do they have the first and last node?
1823  Range vertSets;
1824  rval = mdbImpl->get_child_meshsets( edge, vertSets );
1825  if( MB_SUCCESS != rval ) RETFALSE( " can't get vertex children ", edge )
1826  Range notVertices = subtract( vertSets, geomRanges[0] );
1827  if( !notVertices.empty() ) RETFALSE( " children sets that are not vertices ", notVertices[0] )
1828  for( Range::iterator it = vertSets.begin(); it != vertSets.end(); ++it )
1829  {
1830  if( !mdbImpl->contains_entities( *it, &firstNode, 1 ) &&
1831  !mdbImpl->contains_entities( *it, &currentNode, 1 ) )
1832  RETFALSE( " a vertex set is not containing the first and last nodes ", *it )
1833  }
1834  // check now the faces / parents
1835  Range faceSets;
1836  rval = mdbImpl->get_parent_meshsets( edge, faceSets );
1837  if( MB_SUCCESS != rval ) RETFALSE( " can't get edge parents ", edge )
1838  Range notFaces = subtract( faceSets, geomRanges[2] );
1839  if( !notFaces.empty() ) RETFALSE( " parent sets that are not faces ", notFaces[0] )
1840 
1841  // for a geo edge, check the sense tags with respect to the adjacent faces
1842  // in general, it is sufficient to check one mesh edge (the first one)
1843  // edge/face senses
1844  EntityHandle firstMeshEdge = mesh_edges[0];
1845  // get all entities/elements adjacent to it
1846  Range adjElem;
1847  rval = mdbImpl->get_adjacencies( &firstMeshEdge, 1, 2, false, adjElem );
1848  if( MB_SUCCESS != rval ) RETFALSE( " can't get adjacent elements to the edge ", firstMeshEdge )
1849  for( Range::iterator it2 = adjElem.begin(); it2 != adjElem.end(); ++it2 )
1850  {
1851  EntityHandle elem = *it2;
1852  // find the geo face it belongs to
1853  EntityHandle gFace = 0;
1854  for( Range::iterator fit = faceSets.begin(); fit != faceSets.end(); ++fit )
1855  {
1856  EntityHandle possibleFace = *fit;
1857  if( mdbImpl->contains_entities( possibleFace, &elem, 1 ) )
1858  {
1859  gFace = possibleFace;
1860  break;
1861  }
1862  }
1863  if( 0 == gFace )
1864  RETFALSE( " can't find adjacent surface that contains the adjacent element to the edge ",
1865  firstMeshEdge )
1866 
1867  // now, check the sense of mesh_edge in element, and the sense of gedge in gface
1868  // side_number
1869  int side_n, sense, offset;
1870  rval = mdbImpl->side_number( elem, firstMeshEdge, side_n, sense, offset );
1871  if( MB_SUCCESS != rval ) RETFALSE( " can't get sense and side number of an element ", elem )
1872  // now get the sense
1873  int topoSense;
1874  rval = this->get_sense( edge, gFace, topoSense );
1875  if( topoSense != sense ) RETFALSE( " geometric topo sense and element sense do not agree ", edge )
1876  }
1877  }
1878  // surfaces to be true meshes
1879  // for surfaces, check that the skinner will find the correct boundary
1880 
1881  // use the skinner for boundary check
1882  Skinner tool( mdbImpl );
1883 
1884  for( rit = geomRanges[2].begin(); rit != geomRanges[2].end(); ++rit )
1885  {
1886  EntityHandle faceSet = *rit;
1887  // get all boundary edges (adjacent edges)
1888 
1889  Range edges;
1890  rval = mdbImpl->get_child_meshsets( faceSet, edges );
1891  if( MB_SUCCESS != rval ) RETFALSE( " can't get children edges for a face set ", faceSet )
1892  Range notEdges = subtract( edges, geomRanges[1] );
1893  if( !notEdges.empty() ) RETFALSE( " some children of a face set are not geo edges ", notEdges[0] )
1894 
1895  Range boundary_mesh_edges;
1896  for( Range::iterator it = edges.begin(); it != edges.end(); ++it )
1897  {
1898  rval = mdbImpl->get_entities_by_type( *it, MBEDGE, boundary_mesh_edges );
1899  if( MB_SUCCESS != rval ) RETFALSE( " can't get edge elements from the edge set ", *it )
1900  }
1901  // skin the elements of the surface
1902  // most of these should be triangles and quads
1903  Range surface_ents, edge_ents;
1904  rval = mdbImpl->get_entities_by_dimension( faceSet, 2, surface_ents );
1905  if( MB_SUCCESS != rval ) RETFALSE( " can't get surface elements from the face set ", faceSet )
1906 
1907  rval = tool.find_skin( 0, surface_ents, 1, edge_ents );
1908  if( MB_SUCCESS != rval ) RETFALSE( "can't skin a surface ", surface_ents[0] )
1909 
1910  // those 2 ranges for boundary edges now must be equal
1911  if( boundary_mesh_edges != edge_ents ) RETFALSE( "boundary ranges are different", boundary_mesh_edges[0] )
1912  }
1913 
1914  // solids to be filled correctly, maybe a skin procedure too.
1915  // (maybe the solids are empty)
1916 
1917  return true;
1918 }

References moab::Range::begin(), moab::Interface::contains_entities(), moab::Range::empty(), moab::Range::end(), ErrorCode, moab::Skinner::find_skin(), geomRanges, moab::Interface::get_adjacencies(), moab::Interface::get_child_meshsets(), moab::Interface::get_connectivity(), moab::Interface::get_entities_by_dimension(), moab::Interface::get_entities_by_handle(), moab::Interface::get_entities_by_type(), moab::Interface::get_parent_meshsets(), get_sense(), moab::Interface::list_entity(), MB_SUCCESS, MBEDGE, MBVERTEX, mdbImpl, RETFALSE, moab::Interface::side_number(), moab::Range::size(), moab::subtract(), and moab::Interface::type_from_handle().

◆ construct_obb_tree()

ErrorCode moab::GeomTopoTool::construct_obb_tree ( EntityHandle  eh)

Build obb tree for the entity set given; entity can be surface or volume.

Parameters
ehEntityHandle of the volume or surface to construct the OBB tree around

Definition at line 403 of file GeomTopoTool.cpp.

404 {
405  MB_CHK_SET_ERR( is_owned_set( eh ), "Entity set is not part of this model" );
406 
407  // get the type
408  EntityType type = mdbImpl->type_from_handle( eh );
409 
410  // find the dimension of the entity
411  int dim;
412  MB_CHK_SET_ERR( mdbImpl->tag_get_data( geomTag, &eh, 1, &dim ), "Failed to get dimension" );
413 
414  // ensure that the rootSets vector is of the correct size
415  if( m_rootSets_vector && ( eh < setOffset || eh >= setOffset + rootSets.size() ) )
416  {
417  MB_CHK_SET_ERR( resize_rootSets(), "Error setting offset and sizing rootSets vector." );
418  }
419 
420  EntityHandle root;
421  // if it's a surface
422  if( dim == 2 && type == MBENTITYSET )
423  {
424  ErrorCode rval = get_root( eh, root );
425  if( MB_SUCCESS == rval )
426  {
427  std::cerr << "Surface obb tree already exists" << std::endl;
428  return MB_SUCCESS;
429  }
430  else if( MB_INDEX_OUT_OF_RANGE != rval )
431  {
432  MB_CHK_SET_ERR( rval, "Failed to get surface obb tree root" );
433  }
434 
435  Range tris;
436  MB_CHK_SET_ERR( mdbImpl->get_entities_by_dimension( eh, 2, tris ), "Failed to get entities by dimension" );
437 
438  if( tris.empty() )
439  {
440  std::cerr << "WARNING: Surface id " << global_id( eh ) << " (handle: " << eh << ")" << "has no facets"
441  << std::endl;
442  }
443 
444  MB_CHK_SET_ERR( obbTree->build( tris, root ), "Failed to build obb Tree for surface" );
445 
446  MB_CHK_SET_ERR( mdbImpl->add_entities( root, &eh, 1 ), "Failed to add entities to root set" );
447 
448  // add this root to the GeomTopoTool tree root indexing
449  set_root_set( eh, root );
450 
451  // if just building tree for surface, return here
452  return MB_SUCCESS;
453  }
454  // if it's a volume
455  else if( dim == 3 && type == MBENTITYSET )
456  {
457  // get its surfaces
458  Range tmp_surfs, surf_trees;
459  MB_CHK_SET_ERR( mdbImpl->get_child_meshsets( eh, tmp_surfs ), "Failed to get surface meshsets" );
460 
461  // get OBB trees or create for each surface
462  for( Range::iterator j = tmp_surfs.begin(); j != tmp_surfs.end(); ++j )
463  {
464  ErrorCode rval = get_root( *j, root );
465  // if root doesn't exist, create obb tree
466  if( MB_INDEX_OUT_OF_RANGE == rval )
467  {
468  MB_CHK_SET_ERR( construct_obb_tree( *j ), "Failed to get create surface obb tree" );
469  MB_CHK_SET_ERR( get_root( *j, root ), "Failed to get surface obb tree root" );
470  }
471  else
472  {
473  MB_CHK_SET_ERR( rval, "Failed to get surface obb tree root" );
474  }
475 
476  surf_trees.insert( root );
477  }
478 
479  // build OBB tree for volume
480  MB_CHK_SET_ERR( obbTree->join_trees( surf_trees, root ), "Failed to join the obb trees" );
481 
482  // add this root to the GeomTopoTool tree root indexing
483  set_root_set( eh, root );
484 
485  return MB_SUCCESS;
486  }
487  else
488  {
489  MB_SET_ERR( MB_FAILURE, "Improper dimension or type for constructing obb tree" );
490  }
491 }

References moab::Interface::add_entities(), moab::Range::begin(), moab::OrientedBoxTreeTool::build(), moab::Range::empty(), moab::Range::end(), ErrorCode, geomTag, moab::Interface::get_child_meshsets(), moab::Interface::get_entities_by_dimension(), get_root(), global_id(), moab::Range::insert(), is_owned_set(), moab::OrientedBoxTreeTool::join_trees(), m_rootSets_vector, MB_CHK_SET_ERR, MB_INDEX_OUT_OF_RANGE, MB_SET_ERR, MB_SUCCESS, MBENTITYSET, mdbImpl, obbTree, resize_rootSets(), rootSets, set_root_set(), setOffset, moab::Interface::tag_get_data(), and moab::Interface::type_from_handle().

Referenced by construct_obb_trees().

◆ construct_obb_trees()

ErrorCode moab::GeomTopoTool::construct_obb_trees ( bool  make_one_vol = false)

Build obb trees for all surfaces and volumes in model set.

Definition at line 552 of file GeomTopoTool.cpp.

553 {
554  EntityHandle root;
555 
556  // get all surfaces and volumes
557  Range surfs, vols, vol_trees;
558  MB_CHK_SET_ERR( get_gsets_by_dimension( 2, surfs ), "Could not get surface sets" );
559  MB_CHK_SET_ERR( get_gsets_by_dimension( 3, vols ), "Could not get volume sets" );
560 
561  // for surface
562  Range one_vol_trees;
563  for( Range::iterator i = surfs.begin(); i != surfs.end(); ++i )
564  {
565  MB_CHK_SET_ERR( construct_obb_tree( *i ), "Failed to construct obb tree for surface" );
566  // get the root set of this volume
567  MB_CHK_SET_ERR( get_root( *i, root ), "Failed to get obb tree root for surface" );
568  // add to the Range of volume root sets
569  one_vol_trees.insert( root );
570  }
571 
572  // for volumes
573  for( Range::iterator i = vols.begin(); i != vols.end(); ++i )
574  {
575  // create tree for this volume
576  MB_CHK_SET_ERR( construct_obb_tree( *i ), "Failed to construct obb tree for volume" );
577  }
578 
579  // build OBB tree for volume
580  if( make_one_vol )
581  {
582  MB_CHK_SET_ERR( obbTree->join_trees( one_vol_trees, root ), "Failed to join surface trees into one volume" );
583  oneVolRootSet = root;
584  }
585 
586  return moab::MB_SUCCESS;
587 }

References moab::Range::begin(), construct_obb_tree(), moab::Range::end(), get_gsets_by_dimension(), get_root(), moab::Range::insert(), moab::OrientedBoxTreeTool::join_trees(), MB_CHK_SET_ERR, MB_SUCCESS, obbTree, and oneVolRootSet.

Referenced by GeomTopoTool(), moab::FBEngine::Init(), moab::GeomQueryTool::initialize(), and main().

◆ construct_vertex_ranges()

ErrorCode moab::GeomTopoTool::construct_vertex_ranges ( const Range geom_sets,
const Tag  verts_tag 
)
private

Compute vertices inclusive and put on tag on sets in geom_sets.

Definition at line 755 of file GeomTopoTool.cpp.

756 {
757  // construct the vertex range for each entity and put on that tag
758  Range *temp_verts, temp_elems;
759  ErrorCode result = MB_SUCCESS;
760  for( Range::const_iterator it = geom_sets.begin(); it != geom_sets.end(); ++it )
761  {
762  temp_elems.clear();
763 
764  // get all the elements in the set, recursively
765  result = mdbImpl->get_entities_by_handle( *it, temp_elems, true );
766  MB_CHK_SET_ERR( result, "Failed to get the geometry set entities" );
767 
768  // make the new range
769  temp_verts = new( std::nothrow ) Range();
770  if( NULL == temp_verts )
771  {
772  MB_SET_ERR( MB_FAILURE, "Could not construct Range object" );
773  }
774 
775  // get all the verts of those elements; use get_adjacencies 'cuz it handles ranges better
776  result = mdbImpl->get_adjacencies( temp_elems, 0, false, *temp_verts, Interface::UNION );
777  if( MB_SUCCESS != result )
778  {
779  delete temp_verts;
780  }
781  MB_CHK_SET_ERR( result, "Failed to get the element's adjacent vertices" );
782 
783  // store this range as a tag on the entity
784  result = mdbImpl->tag_set_data( verts_tag, &( *it ), 1, &temp_verts );
785  if( MB_SUCCESS != result )
786  {
787  delete temp_verts;
788  }
789  MB_CHK_SET_ERR( result, "Failed to get the adjacent vertex data" );
790 
791  delete temp_verts;
792  temp_verts = NULL;
793  }
794 
795  return result;
796 }

References moab::Range::begin(), moab::Range::clear(), moab::Range::end(), ErrorCode, moab::Interface::get_adjacencies(), moab::Interface::get_entities_by_handle(), MB_CHK_SET_ERR, MB_SET_ERR, MB_SUCCESS, mdbImpl, moab::Interface::tag_set_data(), and moab::Interface::UNION.

◆ delete_all_obb_trees()

ErrorCode moab::GeomTopoTool::delete_all_obb_trees ( )

Definition at line 390 of file GeomTopoTool.cpp.

391 {
392  for( Range::iterator rit = geomRanges[3].begin(); rit != geomRanges[3].end(); ++rit )
393  {
394  EntityHandle root;
395  MB_CHK_ERR( mdbImpl->tag_get_data( obbRootTag, &( *rit ), 1, &root ) );
396 
397  MB_CHK_SET_ERR( delete_obb_tree( *rit, false ), "Failed to delete obb tree" );
398  }
399 
400  return MB_SUCCESS;
401 }

References delete_obb_tree(), moab::Range::end(), geomRanges, MB_CHK_ERR, MB_CHK_SET_ERR, MB_SUCCESS, mdbImpl, obbRootTag, and moab::Interface::tag_get_data().

Referenced by GeomTopoTool().

◆ delete_obb_tree()

ErrorCode moab::GeomTopoTool::delete_obb_tree ( EntityHandle  gset,
bool  vol_only = false 
)

Delete the OBB tree of a volume or surface.

Definition at line 315 of file GeomTopoTool.cpp.

316 {
317  // Make sure this set is part of the model
318  MB_CHK_SET_ERR( is_owned_set( gset ), "Entity set is not part of this model" );
319 
320  // Find the dimension of the entity
321  int dim;
322  MB_CHK_SET_ERR( mdbImpl->tag_get_data( geomTag, &gset, 1, &dim ), "Failed to get dimension" );
323 
324  // Attempt to find a root for this set
325  EntityHandle root;
326  MB_CHK_SET_ERR( get_root( gset, root ), "Failed to find an obb tree root for the entity set" );
327 
328  // Create range of tree nodes to delete
329  Range nodes_to_delete;
330  nodes_to_delete.insert( root );
331 
332  // If passed ent is a vol and 'vol_only' is true, delete vol root and all nodes between vol and
333  // surf root
334  if( dim == 3 && vol_only )
335  {
336  // Range of child nodes to check before adding to delete list
337  Range child_tree_nodes;
338  MB_CHK_SET_ERR( mdbImpl->get_child_meshsets( root, child_tree_nodes ), "Problem getting child tree nodes" );
339 
340  // Traverse the tree, checking each child node until
341  // a surface root node is reached
342  while( child_tree_nodes.size() != 0 )
343  {
344  EntityHandle child = *child_tree_nodes.begin();
345  EntityHandle surf;
346  ErrorCode rval = mdbImpl->tag_get_data( obbGsetTag, &child, 1, &surf );
347  // If the node has a gset tag, it is a surf root. Stop here.
348  // If not, it is a tree node that needs to 1) have its children checked and
349  // 2) be added to delete range
350  if( MB_TAG_NOT_FOUND == rval )
351  {
352  Range new_child_tree_nodes;
353  MB_CHK_SET_ERR( mdbImpl->get_child_meshsets( child, new_child_tree_nodes ),
354  "Problem getting child nodes" );
355  child_tree_nodes.insert_list( new_child_tree_nodes.begin(), new_child_tree_nodes.end() );
356  nodes_to_delete.insert( child );
357  }
358  // We're done checking this node, so can erase from child list
359  child_tree_nodes.erase( child );
360  }
361  }
362  // If passed ent is a surf or a vol and 'vol_only' is false, recursively gather all child nodes
363  // and add them to delete list
364  else
365  {
366  Range all_tree_nodes;
367  MB_CHK_SET_ERR( mdbImpl->get_child_meshsets( root, all_tree_nodes, 0 ), "Failed to get child tree node sets" );
368  nodes_to_delete.insert_list( all_tree_nodes.begin(), all_tree_nodes.end() );
369  }
370 
371  // Remove the root nodes from the GTT data structures
372  for( Range::iterator it = nodes_to_delete.begin(); it != nodes_to_delete.end(); ++it )
373  {
374  // Check to see if node is a root
375  EntityHandle vol_or_surf;
376  ErrorCode rval = mdbImpl->tag_get_data( obbGsetTag, &( *it ), 1, &vol_or_surf );
377  if( MB_SUCCESS == rval )
378  {
379  // Remove from set of all roots
380  MB_CHK_SET_ERR( remove_root( vol_or_surf ), "Failed to remove node from GTT data structure" );
381  }
382  }
383 
384  // Delete the tree nodes from the database
385  MB_CHK_SET_ERR( mdbImpl->delete_entities( nodes_to_delete ), "Failed to delete node set" );
386 
387  return MB_SUCCESS;
388 }

References moab::Range::begin(), moab::Interface::delete_entities(), moab::Range::end(), moab::Range::erase(), ErrorCode, geomTag, moab::Interface::get_child_meshsets(), get_root(), moab::Range::insert(), moab::Range::insert_list(), is_owned_set(), MB_CHK_SET_ERR, MB_SUCCESS, MB_TAG_NOT_FOUND, mdbImpl, obbGsetTag, remove_root(), moab::Range::size(), and moab::Interface::tag_get_data().

Referenced by delete_all_obb_trees().

◆ dimension()

int moab::GeomTopoTool::dimension ( EntityHandle  this_set)

Return the dimension of the set, or -1 if it's not a geom_dimension set.

Definition at line 96 of file GeomTopoTool.cpp.

97 {
98  ErrorCode result;
99  if( 0 == geomTag )
100  {
102  MB_CHK_SET_ERR( result, "Failed to get the geometry dimension tag" );
103  }
104 
105  // check if the geo set belongs to this model
106  if( modelSet )
107  {
108  if( !mdbImpl->contains_entities( modelSet, &this_set, 1 ) )
109  {
110  // this g set does not belong to the current model
111  return -1;
112  }
113  }
114  // get the data for those tags
115  int dim;
116  result = mdbImpl->tag_get_data( geomTag, &this_set, 1, &dim );
117  if( MB_SUCCESS != result )
118  return -1;
119  else
120  return dim;
121 }

References moab::Interface::contains_entities(), ErrorCode, GEOM_DIMENSION_TAG_NAME, geomTag, MB_CHK_SET_ERR, MB_SUCCESS, MB_TYPE_INTEGER, mdbImpl, modelSet, moab::Interface::tag_get_data(), and moab::Interface::tag_get_handle().

Referenced by get_sense(), get_senses(), get_surface_senses(), moab::FBEngine::redistribute_boundary_edges_to_faces(), set_sense(), set_surface_senses(), moab::FBEngine::split_bedge_at_new_mesh_node(), moab::FBEngine::split_edge_at_mesh_node(), and moab::FBEngine::split_edge_at_point().

◆ duplicate_model()

ErrorCode moab::GeomTopoTool::duplicate_model ( GeomTopoTool *&  duplicate,
std::vector< EntityHandle > *  pvGEnts = NULL 
)

This would be a deep copy, into a new geom topo tool.

Definition at line 1471 of file GeomTopoTool.cpp.

1472 {
1473  // will
1474  EntityHandle rootModelSet;
1475  MB_CHK_SET_ERR( mdbImpl->create_meshset( MESHSET_SET, rootModelSet ), "Failed to create the rootModelSet" );
1476 
1477  if( 0 == geomTag )
1478  {
1480  "Failed to get the geometry dimension tag handle" );
1481  }
1482  if( 0 == gidTag )
1483  {
1485  }
1486  // extract from the geomSet the dimension, children, and grand-children
1487  Range depSets; // dependents of the geomSet, including the geomSet
1488  // add in this range all the dependents of this, to filter the ones that need to be deep copied
1489 
1490  if( pvGEnts != NULL )
1491  {
1492  unsigned int numGents = pvGEnts->size();
1493  for( unsigned int k = 0; k < numGents; k++ )
1494  {
1495  EntityHandle geomSet = ( *pvGEnts )[k];
1496  // will keep accumulating to the depSets range
1497  // dependents are returned, not only the direct children.
1498  // 0 for numHops means that all
1499  MB_CHK_SET_ERR( mdbImpl->get_child_meshsets( geomSet, depSets, 0 ),
1500  "Failed to get the geometry set's child meshsets" );
1501 
1502  depSets.insert( geomSet );
1503  }
1504  }
1505 
1506  // add to the root model set copies of the gsets, with correct sets
1507  // keep a map between sets to help in copying parent/child relations
1508  std::map< EntityHandle, EntityHandle > relate;
1509  // each set will get the same entities as the original
1510  for( int dim = 0; dim < 5; dim++ )
1511  {
1512  int gid = 0;
1513  unsigned int set_options = ( ( 1 != dim ) ? MESHSET_SET : MESHSET_ORDERED );
1514  for( Range::iterator it = geomRanges[dim].begin(); it != geomRanges[dim].end(); ++it )
1515  {
1516  EntityHandle set = *it;
1517  if( pvGEnts != NULL && depSets.find( set ) == depSets.end() )
1518  continue; // this means that this set is not of interest, skip it
1519  EntityHandle newSet;
1520  MB_CHK_SET_ERR( mdbImpl->create_meshset( set_options, newSet ), "Failed to create new meshset" );
1521 
1522  relate[set] = newSet;
1523  MB_CHK_SET_ERR( mdbImpl->add_entities( rootModelSet, &newSet, 1 ),
1524  "Failed to add the new meshset to the tool's modelSet" );
1525 
1526  // make it a geo set, and give also global id in order
1527  MB_CHK_SET_ERR( mdbImpl->tag_set_data( geomTag, &newSet, 1, &dim ),
1528  "Failed to set the new meshset's geometry dimension data" );
1529 
1530  gid++; // increment global id, everything starts with 1 in the new model!
1531  MB_CHK_SET_ERR( mdbImpl->tag_set_data( gidTag, &newSet, 1, &gid ),
1532  "Failed to get the new meshset's global id data" );
1533 
1534  if( dim == 1 )
1535  {
1536  // the entities are ordered, we need to retrieve them ordered, and set them ordered
1537  std::vector< EntityHandle > mesh_edges;
1538  MB_CHK_SET_ERR( mdbImpl->get_entities_by_handle( set, mesh_edges ),
1539  "Failed to get the meshset entities by handle" );
1540 
1541  MB_CHK_SET_ERR( mdbImpl->add_entities( newSet, &( mesh_edges[0] ), (int)mesh_edges.size() ),
1542  "Failed to add the new entities to the new meshset" );
1543  }
1544  else
1545  {
1546  Range ents;
1548  "Failed to add the entities to the existing meshset" );
1549 
1550  MB_CHK_SET_ERR( mdbImpl->add_entities( newSet, ents ),
1551  "Failed to add the entities to the new meshset" );
1552  }
1553  // set parent/child relations if dim>=1
1554  if( dim >= 1 )
1555  {
1556  Range children;
1557  // the children of geo sets are only g sets
1558  // num_hops = 1 by default
1559  MB_CHK_SET_ERR( mdbImpl->get_child_meshsets( set, children ),
1560  "Failed to get the child meshsets of the existing set" );
1561 
1562  for( Range::iterator it2 = children.begin(); it2 != children.end(); ++it2 )
1563  {
1564  EntityHandle newChildSet = relate[*it2];
1565  MB_CHK_SET_ERR( mdbImpl->add_parent_child( newSet, newChildSet ),
1566  "Failed to create parent child relationship to the new meshset" );
1567  }
1568  }
1569  }
1570  }
1571 
1572  duplicate = new GeomTopoTool( mdbImpl, true, rootModelSet ); // will retrieve the
1573  // sets and put them in ranges
1574 
1575  // this is the lazy way to it:
1576  // newgtt->restore_topology_from_adjacency(); // will reset the sense entities, and with this,
1577  // the model represented by this new gtt will be complete set senses by peeking at the old model
1578  // make sure we have the sense tags defined
1579  MB_CHK_SET_ERR( check_face_sense_tag( true ), "Failed to check the face to volume sense tag handle" );
1580 
1581  MB_CHK_SET_ERR( check_edge_sense_tags( true ), "Failed to check the curve to surface sense tag handles" );
1582 
1583  for( int dd = 1; dd <= 2; dd++ ) // do it for surfaces and edges
1584  {
1585  for( Range::iterator it = geomRanges[dd].begin(); it != geomRanges[dd].end(); ++it )
1586  {
1587  EntityHandle surf = *it;
1588  if( pvGEnts != NULL && depSets.find( surf ) == depSets.end() )
1589  continue; // this means that this set is not of interest, skip it
1590  EntityHandle newSurf = relate[surf];
1591  // we can actually look at the tag data, to be more efficient
1592  // or use the
1593  std::vector< EntityHandle > solids;
1594  std::vector< int > senses;
1595  MB_CHK_SET_ERR( this->get_senses( surf, solids, senses ),
1596  "Failed to get the sense data for the surface with respect to its volumes" );
1597 
1598  std::vector< EntityHandle > newSolids;
1599  std::vector< int > newSenses;
1600  for( unsigned int i = 0; i < solids.size(); i++ )
1601  {
1602  if( pvGEnts != NULL && depSets.find( solids[i] ) == depSets.end() )
1603  continue; // this means that this set is not of interest, skip it
1604  EntityHandle newSolid = relate[solids[i]];
1605  // see which "solids" are in the new model
1606  newSolids.push_back( newSolid );
1607  newSenses.push_back( senses[i] );
1608  }
1609  MB_CHK_SET_ERR( duplicate->set_senses( newSurf, newSolids, newSenses ),
1610  "Failed to set the sense data for the surface with respect to the new volumes" );
1611  }
1612  }
1613  // if the original root model set for this model is 0 (root set), then create
1614  // a new set and put all the old sets in the new model set
1615  // in this way, the existing gtt remains valid (otherwise, the modelSet would contain all the
1616  // gsets, the old ones and the new ones; the root set contains everything)
1617  if( modelSet == 0 )
1618  {
1619  MB_CHK_SET_ERR( mdbImpl->create_meshset( MESHSET_SET, modelSet ), "Failed to create the modelSet meshset" );
1620 
1621  // add to this new set all previous sets (which are still in ranges)
1622  for( int dim = 0; dim < 5; dim++ )
1623  {
1625  "Failed to add the geometric meshsets to the tool's modelSet" );
1626  }
1627  }
1628  return MB_SUCCESS;
1629 }

References moab::Interface::add_entities(), moab::Interface::add_parent_child(), moab::Range::begin(), check_edge_sense_tags(), check_face_sense_tag(), moab::Interface::create_meshset(), moab::Range::end(), moab::Range::find(), GEOM_DIMENSION_TAG_NAME, geomRanges, geomTag, GeomTopoTool(), moab::Interface::get_child_meshsets(), moab::Interface::get_entities_by_handle(), get_senses(), gidTag, moab::Interface::globalId_tag(), moab::Range::insert(), MB_CHK_SET_ERR, MB_SUCCESS, MB_TYPE_INTEGER, mdbImpl, MESHSET_SET, modelSet, set_senses(), moab::Range::size(), moab::Interface::tag_get_handle(), and moab::Interface::tag_set_data().

Referenced by moab::FBEngine::split_quads().

◆ entity_by_id()

EntityHandle moab::GeomTopoTool::entity_by_id ( int  dimension,
int  id 
)

Map from dimension & global ID to EntityHandle.

Definition at line 150 of file GeomTopoTool.cpp.

151 {
152  if( 0 > dimension1 || 3 < dimension1 )
153  {
154  MB_CHK_SET_ERR_CONT( MB_FAILURE, "Incorrect dimension provided" );
155  }
156  const Tag tags[] = { gidTag, geomTag };
157  const void* const vals[] = { &id, &dimension1 };
158  ErrorCode rval;
159 
160  Range results;
161  rval = mdbImpl->get_entities_by_type_and_tag( 0, MBENTITYSET, tags, vals, 2, results );
162 
163  if( MB_SUCCESS != rval )
164  return 0;
165  else
166  return results.front();
167 }

References ErrorCode, moab::Range::front(), geomTag, moab::Interface::get_entities_by_type_and_tag(), gidTag, MB_CHK_SET_ERR_CONT, MB_SUCCESS, MBENTITYSET, and mdbImpl.

Referenced by obbstat_write(), and obbvis_create().

◆ find_geomsets()

ErrorCode moab::GeomTopoTool::find_geomsets ( Range ranges = NULL)

Definition at line 230 of file GeomTopoTool.cpp.

231 {
232  // get all sets with this tag
233  Range geom_sets;
234 
235  if( 0 == geomTag )
236  {
238  "Failed to get geom dimension tag handle" );
239  }
240 
242  "Failed to get the geometry entities" );
243 
244  MB_CHK_SET_ERR( separate_by_dimension( geom_sets ), "Failed to separate geometry sets by dimension" );
245 
246  if( ranges )
247  {
248  for( int i = 0; i < 5; i++ )
249  {
250  ranges[i] = geomRanges[i];
251  }
252  }
253 
254  return MB_SUCCESS;
255 }

References GEOM_DIMENSION_TAG_NAME, geomRanges, geomTag, moab::Interface::get_entities_by_type_and_tag(), MB_CHK_SET_ERR, MB_SUCCESS, MB_TYPE_INTEGER, MBENTITYSET, mdbImpl, modelSet, separate_by_dimension(), and moab::Interface::tag_get_handle().

Referenced by moab::FBEngine::chain_edges(), GeomTopoTool(), moab::FBEngine::Init(), moab::GeomQueryTool::initialize(), main(), moab::FBEngine::set_default_neumann_tags(), and moab::FBEngine::split_quads().

◆ generate_implicit_complement()

ErrorCode moab::GeomTopoTool::generate_implicit_complement ( EntityHandle implicit_complement_set)
private

Creates a volume for undefined space in the model.

Definition at line 1701 of file GeomTopoTool.cpp.

1702 {
1703  MB_CHK_SET_ERR( mdbImpl->create_meshset( MESHSET_SET, implicit_complement_set ),
1704  "Failed to create mesh set for implicit complement" );
1705 
1706  // make sure the sense2Tag is set
1707  if( !sense2Tag )
1708  {
1709  check_face_sense_tag( true );
1710  }
1711 
1712  // get all geometric surface sets
1713  Range surfs;
1714  MB_CHK_SET_ERR( get_gsets_by_dimension( 2, surfs ), "Could not get surface sets" );
1715 
1716  // search through all surfaces
1717  std::vector< EntityHandle > parent_vols;
1718  for( Range::iterator surf_i = surfs.begin(); surf_i != surfs.end(); ++surf_i )
1719  {
1720 
1721  parent_vols.clear();
1722  // get parents of each surface
1723  MB_CHK_SET_ERR( mdbImpl->get_parent_meshsets( *surf_i, parent_vols ), "Failed to get volume meshsets" );
1724 
1725  // if only one parent, get the OBB root for this surface
1726  if( parent_vols.size() == 1 )
1727  {
1728 
1729  // add this surf to the topology of the implicit complement volume
1730  MB_CHK_SET_ERR( mdbImpl->add_parent_child( implicit_complement_set, *surf_i ),
1731  "Could not add surface to implicit complement set" );
1732 
1733  // get the surface sense wrt original volume
1734  EntityHandle sense_data[2] = { 0, 0 };
1735  MB_CHK_SET_ERR( get_surface_senses( *surf_i, sense_data[0], sense_data[1] ),
1736  "Could not get surface sense data" );
1737 
1738  // set the surface sense wrt implicit complement volume
1739  if( 0 == sense_data[0] && 0 == sense_data[1] )
1740  MB_SET_ERR( MB_FAILURE, "No sense data for current surface" );
1741  if( 0 == sense_data[0] )
1742  sense_data[0] = implicit_complement_set;
1743  else if( 0 == sense_data[1] )
1744  sense_data[1] = implicit_complement_set;
1745  else
1746  MB_SET_ERR( MB_FAILURE, "Could not insert implicit complement into surface sense data" );
1747 
1748  // set the new sense data for this surface
1749  MB_CHK_SET_ERR( set_surface_senses( *surf_i, sense_data[0], sense_data[1] ),
1750  "Failed to set sense tag data" );
1751  }
1752  } // end surface loop
1753 
1754  return MB_SUCCESS;
1755 }

References moab::Interface::add_parent_child(), moab::Range::begin(), check_face_sense_tag(), moab::Interface::create_meshset(), moab::Range::end(), get_gsets_by_dimension(), moab::Interface::get_parent_meshsets(), get_surface_senses(), MB_CHK_SET_ERR, MB_SET_ERR, MB_SUCCESS, mdbImpl, MESHSET_SET, sense2Tag, and set_surface_senses().

Referenced by setup_implicit_complement().

◆ geometrize_surface_set()

ErrorCode moab::GeomTopoTool::geometrize_surface_set ( EntityHandle  surface,
EntityHandle output 
)

Will assume no geo sets are defined for this surface.

Definition at line 1226 of file GeomTopoTool.cpp.

1227 {
1228  // usual scenario is to read a surface smf file, and "geometrize" it, and output it as a
1229  // h5m file with proper sets, tags defined for mesh-based geometry
1230 
1231  // get all triangles/quads from the surface, then build loops
1232  // we may even have to
1233  // proper care has to be given to the orientation, material to the left!!!
1234  // at some point we may have to reorient triangles, not only edges, for proper definition
1235  bool debugFlag = false;
1236 
1237  Range surface_ents, edge_ents, loop_range;
1238 
1239  // most of these should be triangles and quads
1240  MB_CHK_SET_ERR( mdbImpl->get_entities_by_dimension( surface, 2, surface_ents ),
1241  "Failed to get the surface entities" );
1242 
1243  EntityHandle face = surface;
1244  if( !surface ) // in the case it is root set, create another set
1245  {
1246  MB_CHK_SET_ERR( mdbImpl->create_meshset( MESHSET_SET, face ), "Failed to create a the new surface meshset" );
1247  }
1248  // set the geo tag
1249  MB_CHK_SET_ERR( add_geo_set( face, 2 ), "Failed to add the geometry set to the tool" );
1250 
1251  // this will be our output set, will contain all our new geo sets
1252  MB_CHK_SET_ERR( mdbImpl->create_meshset( MESHSET_SET, output ), "Failed to create the output meshset" );
1253 
1254  // add first geo set (face) to the output set
1255  MB_CHK_SET_ERR( mdbImpl->add_entities( output, &face, 1 ), "Failed to add the new meshset to the output meshset" );
1256 
1257  // how many edges do we need to create?
1258  // depends on how many loops we have
1259  // also, we should avoid non-manifold topology
1260  if( !surface )
1261  { // in this case, surface is root, so we have to add entities
1262  MB_CHK_SET_ERR( mdbImpl->add_entities( face, surface_ents ),
1263  "Failed to add surface entities to the surface meshset" );
1264  }
1265 
1266  Skinner tool( mdbImpl );
1267  MB_CHK_SET_ERR( tool.find_skin( 0, surface_ents, 1, edge_ents ), "Failed to skin the surface entities" );
1268  if( debugFlag )
1269  {
1270  std::cout << "skinning edges: " << edge_ents.size() << "\n";
1271  for( Range::iterator it = edge_ents.begin(); it != edge_ents.end(); ++it )
1272  {
1273  EntityHandle ed = *it;
1274  std::cout << "edge: " << mdbImpl->id_from_handle( ed ) << " type:" << mdbImpl->type_from_handle( ed )
1275  << "\n";
1276  std::cout << mdbImpl->list_entity( ed );
1277  }
1278  }
1279 
1280  std::vector< EntityHandle > edges_loop;
1281 
1282  Range pool_of_edges = edge_ents;
1283  Range used_edges; // these edges are already used for some loops
1284  // get a new one
1285 
1286  while( !pool_of_edges.empty() )
1287  {
1288  // get the first edge, and start a loop with it
1289  EntityHandle current_edge = pool_of_edges[0];
1290  if( debugFlag )
1291  {
1292  std::cout << "Start current edge: " << mdbImpl->id_from_handle( current_edge ) << "\n ";
1293  std::cout << mdbImpl->list_entity( current_edge );
1294  }
1295  // get its triangle / quad and see its orientation
1296  std::vector< EntityHandle > tris;
1297  MB_CHK_SET_ERR( mdbImpl->get_adjacencies( &current_edge, 1, 2, false, tris ),
1298  "Failed to get the adjacent triangles to the current edge" );
1299  if( tris.size() != 1 ) MB_SET_ERR( MB_FAILURE, "Edge not on boundary" );
1300 
1301  int side_n, sense, offset;
1302  MB_CHK_SET_ERR( mdbImpl->side_number( tris[0], current_edge, side_n, sense, offset ),
1303  "Failed to get the current edge's side number" );
1304 
1305  const EntityHandle* conn2;
1306  int nnodes2;
1307  MB_CHK_SET_ERR( mdbImpl->get_connectivity( current_edge, conn2, nnodes2 ),
1308  "Failed to get the current edge's connectivity" );
1309 
1310  if( nnodes2 != 2 ) MB_SET_ERR( MB_FAILURE, "Incorrect number of nodes found." );
1311 
1312  EntityHandle start_node = conn2[0];
1313  EntityHandle next_node = conn2[1];
1314 
1315  if( sense == -1 )
1316  {
1317  // revert the edge, and start well
1318  EntityHandle nn2[2] = { conn2[1], conn2[0] };
1319  MB_CHK_SET_ERR( mdbImpl->set_connectivity( current_edge, nn2, 2 ),
1320  "Failed to set the connectivity of the current edge" );
1321 
1322  start_node = nn2[0]; // or conn2[0] !!! beware: conn2 is modified
1323  next_node = nn2[1]; // or conn2[1] !!!
1324  // reset connectivity of edge
1325  if( debugFlag ) std::cout << " current edge needs reversed\n";
1326  }
1327  // start a new loop of edges
1328  edges_loop.clear(); // every edge loop starts fresh
1329  edges_loop.push_back( current_edge );
1330  used_edges.insert( current_edge );
1331  pool_of_edges.erase( current_edge );
1332 
1333  if( debugFlag )
1334  {
1335  std::cout << " start node: " << start_node << "\n";
1336  std::cout << mdbImpl->list_entity( start_node );
1337  std::cout << " next node: " << next_node << "\n";
1338  std::cout << mdbImpl->list_entity( next_node );
1339  }
1340  while( next_node != start_node )
1341  {
1342  // find the next edge in the skin
1343  std::vector< EntityHandle > candidate_edges;
1344  MB_CHK_SET_ERR( mdbImpl->get_adjacencies( &next_node, 1, 1, false, candidate_edges ),
1345  "Failed to get the adjacent edges to the next node" );
1346  // filter the edges that are used, or the edges not in the skin
1347  std::vector< EntityHandle > good_edges;
1348  for( int k = 0; k < (int)candidate_edges.size(); k++ )
1349  {
1350  EntityHandle edg = candidate_edges[k];
1351  if( used_edges.find( edg ) != used_edges.end() ) continue;
1352  if( pool_of_edges.find( edg ) != pool_of_edges.end() ) good_edges.push_back( edg );
1353  }
1354  if( good_edges.size() != 1 )
1355  {
1356  std::cout << " good_edges.size()=" << good_edges.size() << " STOP\n";
1357  MB_SET_ERR( MB_FAILURE, "Number of good edges is not one. Could not complete the loop" );
1358  }
1359  // see if the orientation is good; if not, revert it
1360 
1361  current_edge = good_edges[0];
1362  MB_CHK_SET_ERR( mdbImpl->get_connectivity( current_edge, conn2, nnodes2 ),
1363  "Failed to get the connectivity of the current edge" );
1364  if( nnodes2 != 2 ) MB_SET_ERR( MB_FAILURE, "Incorrect number of nodes found" );
1365 
1366  if( conn2[0] != next_node )
1367  {
1368  if( conn2[1] != next_node )
1369  {
1370  // the edge is not connected then to current edge
1371  // bail out
1372  std::cout << "edge " << mdbImpl->id_from_handle( current_edge ) << " not connected to node "
1373  << next_node << "\n";
1374  MB_SET_ERR( MB_FAILURE, "Current edge is not connected to node" );
1375  ;
1376  }
1377  if( debugFlag )
1378  {
1379  std::cout << " revert edge " << mdbImpl->id_from_handle( current_edge ) << "\n";
1380  std::cout << mdbImpl->list_entity( current_edge );
1381  }
1382  // orientation should be reversed
1383  EntityHandle nn2[2] = { conn2[1], conn2[0] };
1384  MB_CHK_SET_ERR( mdbImpl->set_connectivity( current_edge, nn2, 2 ),
1385  "Failed to set the connectivity of the current edge" );
1386 
1387  {
1388  std::cout << "after revert edge " << mdbImpl->id_from_handle( current_edge ) << "\n";
1389  std::cout << mdbImpl->list_entity( current_edge );
1390  std::cout << " conn2: " << conn2[0] << " " << conn2[1] << "\n";
1391  }
1392  }
1393  // before reversion, conn2 was something { n1, next_node}
1394  // after reversion, conn2 became {next_node, n1}, so the
1395  // new next node will be still conn2[1]; big surprise, as
1396  // I didn't expect the conn2 to change.
1397  // it seems that const EntityHandle * conn2 means conn2 cannot be
1398  // changed, but what is pointed to by it will change when we reset connectivity for edge
1399  next_node = conn2[1];
1400 
1401  if( debugFlag )
1402  {
1403  std::cout << " current edge: " << mdbImpl->id_from_handle( current_edge ) << "\n ";
1404  std::cout << mdbImpl->list_entity( current_edge );
1405  std::cout << "next node: " << next_node << "\n ";
1406  std::cout << mdbImpl->list_entity( next_node );
1407  }
1408  edges_loop.push_back( current_edge );
1409  used_edges.insert( current_edge );
1410  pool_of_edges.erase( current_edge );
1411  }
1412  // at this point, we have a loop formed;
1413  // create a geo edge, a vertex set, and add it to our sets
1414 
1416  MB_CHK_SET_ERR( mdbImpl->create_meshset( MESHSET_ORDERED, edge ), "Failed to create the edge meshset" );
1417 
1418  MB_CHK_SET_ERR( add_geo_set( edge, 1 ), "Failed to add the edge meshset to the tool's model set" );
1419  // add the mesh edges:
1420  // add loops edges to the edge set
1421  MB_CHK_SET_ERR( mdbImpl->add_entities( edge, &edges_loop[0], edges_loop.size() ),
1422  "Failed to add entities to the edge meshset" );
1423  // create a vertex set
1425  MB_CHK_SET_ERR( mdbImpl->create_meshset( MESHSET_SET, vertex ), "Failed to create the vertex meshset" );
1426  MB_CHK_SET_ERR( add_geo_set( vertex, 0 ), "Failed to add the vertex meshset to the tool's model set" );
1427  // add one node to the vertex set
1428 
1429  MB_CHK_SET_ERR( mdbImpl->add_entities( vertex, &start_node, 1 ),
1430  "Failed to add entities to the vertex meshset" );
1431 
1433  "Failed to create the edge to face parent child relationship" );
1434 
1436  "Failed to create the vertex to edge parent child relationship" );
1437 
1438  // the sense of the edge in face is for sure positive (forward)
1439  MB_CHK_SET_ERR( set_sense( edge, face, 1 ), "Failed to set the edge to face sense" );
1440  // also add our sets to the output set, to be sure to be exported
1441 
1442  MB_CHK_SET_ERR( mdbImpl->add_entities( output, &edge, 1 ), "Failed to add the edge meshset to the output set" );
1444  "Failed to add the vertex meshset to the output set" );
1445 
1446  if( debugFlag )
1447  {
1448  std::cout << "add edge with start node " << start_node << " with " << edges_loop.size() << " edges\n";
1449  }
1450  }
1451 
1452  return MB_SUCCESS;
1453 }

References moab::Interface::add_entities(), add_geo_set(), moab::Interface::add_parent_child(), moab::Range::begin(), moab::Interface::create_meshset(), moab::Range::empty(), moab::Range::end(), moab::Range::erase(), moab::Range::find(), moab::Skinner::find_skin(), moab::Interface::get_adjacencies(), moab::Interface::get_connectivity(), moab::Interface::get_entities_by_dimension(), moab::Interface::id_from_handle(), moab::Range::insert(), moab::Interface::list_entity(), MB_CHK_SET_ERR, MB_SET_ERR, MB_SUCCESS, mdbImpl, MESHSET_SET, output, moab::Interface::set_connectivity(), set_sense(), moab::Interface::side_number(), moab::Range::size(), and moab::Interface::type_from_handle().

◆ geoRanges()

const Range* moab::GeomTopoTool::geoRanges ( )
inline

Should be used instead of keeping multiple ranges, for example in FBEngine.

Definition at line 224 of file GeomTopoTool.hpp.

225  {
226  return geomRanges;
227  }

References geomRanges.

Referenced by moab::FBEngine::getAdjacentEntities(), moab::FBEngine::getEntities(), moab::FBEngine::getEntType(), and moab::FBEngine::getNumOfType().

◆ get_bounding_coords()

ErrorCode moab::GeomTopoTool::get_bounding_coords ( EntityHandle  volume,
double  minPt[3],
double  maxPt[3] 
)

Get the bouding points from a bounding box.

Parameters
volumeThe volume for which the bounding coordinates are requested
minPtLocation of the min xyz corner of the volume's axis-aligned bounding box
maxPtLocation of the max xyz corner of the volume's axis-aligned bounding box

Definition at line 1928 of file GeomTopoTool.cpp.

1929 {
1930  double center[3], axis1[3], axis2[3], axis3[3];
1931 
1932  // get center point and vectors to OBB faces
1933  MB_CHK_SET_ERR( get_obb( volume, center, axis1, axis2, axis3 ),
1934  "Failed to get the oriented bounding box of the volume" );
1935 
1936  // compute min and max vertices
1937  for( int i = 0; i < 3; i++ )
1938  {
1939  double sum = fabs( axis1[i] ) + fabs( axis2[i] ) + fabs( axis3[i] );
1940  minPt[i] = center[i] - sum;
1941  maxPt[i] = center[i] + sum;
1942  }
1943  return MB_SUCCESS;
1944 }

References center(), get_obb(), MB_CHK_SET_ERR, MB_SUCCESS, and moab::sum().

Referenced by moab::GeomQueryTool::point_in_box().

◆ get_ct_children_by_dimension()

Range moab::GeomTopoTool::get_ct_children_by_dimension ( const EntityHandle  parent,
const int  desired_dimension 
)
private

Return a range of children of a desired geometric dimension.

Definition at line 1960 of file GeomTopoTool.cpp.

1961 {
1962  Range all_children, desired_children;
1963  Range::iterator it;
1964  int actual_dimension;
1965 
1966  desired_children.clear();
1967  all_children.clear();
1968  mdbImpl->get_child_meshsets( parent, all_children );
1969 
1970  for( it = all_children.begin(); it != all_children.end(); ++it )
1971  {
1972  mdbImpl->tag_get_data( geomTag, &( *it ), 1, &actual_dimension );
1973  if( actual_dimension == desired_dimension ) desired_children.insert( *it );
1974  }
1975 
1976  return desired_children;
1977 }

References moab::Range::begin(), moab::Range::clear(), moab::Range::end(), geomTag, moab::Interface::get_child_meshsets(), moab::Range::insert(), mdbImpl, and moab::Interface::tag_get_data().

Referenced by A_is_in_B(), insert_in_tree(), and restore_topology_from_geometric_inclusion().

◆ get_geom_tag()

Tag moab::GeomTopoTool::get_geom_tag ( )
inline

Returns the geometry dimension tag (geomTag) from check_geom_tag.

Definition at line 388 of file GeomTopoTool.hpp.

389 {
390  check_geom_tag( true );
391  return geomTag;
392 }

References check_geom_tag(), and geomTag.

◆ get_gid_tag()

Tag moab::GeomTopoTool::get_gid_tag ( )
inline

Returns the global ID tag (gidTag) from check_gid_tag.

Definition at line 382 of file GeomTopoTool.hpp.

383 {
384  check_gid_tag( true );
385  return gidTag;
386 }

References check_gid_tag(), and gidTag.

◆ get_gsets_by_dimension()

ErrorCode moab::GeomTopoTool::get_gsets_by_dimension ( int  dim,
Range gset 
)

Retrieve geometry sets of desired dimension from model set.

Definition at line 257 of file GeomTopoTool.cpp.

258 {
259  const int val = dim;
260  const void* const dim_val[] = { &val };
262  "Failed to get entity set by type and tag" );
263 
264  return MB_SUCCESS;
265 }

References geomTag, moab::Interface::get_entities_by_type_and_tag(), MB_CHK_SET_ERR, MB_SUCCESS, MBENTITYSET, mdbImpl, and modelSet.

Referenced by construct_obb_trees(), moab::GeomQueryTool::find_volume_slow(), generate_implicit_complement(), and resize_rootSets().

◆ get_implicit_complement()

ErrorCode moab::GeomTopoTool::get_implicit_complement ( EntityHandle implicit_complement)

Get (or optionally, create) the implicit complement handle.

Definition at line 1631 of file GeomTopoTool.cpp.

1632 {
1633  if( impl_compl_handle )
1634  {
1635  implicit_complement = impl_compl_handle;
1636  return MB_SUCCESS;
1637  }
1638  else
1639  {
1640  return MB_ENTITY_NOT_FOUND;
1641  }
1642 }

References impl_compl_handle, MB_ENTITY_NOT_FOUND, and MB_SUCCESS.

Referenced by moab::GeomQueryTool::find_volume().

◆ get_moab_instance()

Interface* moab::GeomTopoTool::get_moab_instance ( )
inline

Return pointer to moab instance.

Definition at line 230 of file GeomTopoTool.hpp.

231  {
232  return mdbImpl;
233  }

References mdbImpl.

Referenced by chkerr(), moab::GeomQueryTool::GeomQueryTool(), obbstat_write(), and obbvis_create().

◆ get_obb()

ErrorCode moab::GeomTopoTool::get_obb ( EntityHandle  volume,
double  center[3],
double  axis1[3],
double  axis2[3],
double  axis3[3] 
)

Get the center point and three vectors for the OBB of a given volume.

Parameters
volumeThe volume for which the OBB axes will be returned
centercoordinates of the oriented bounding box's center point
axis1scaled axis one of the oriented bounding box
axis2scaled axis two of the oriented bounding box
axis3scaled axis three of the oriented bounding box

Definition at line 1946 of file GeomTopoTool.cpp.

1951 {
1952  // find EntityHandle node_set for use in box
1953  EntityHandle root;
1954  MB_CHK_SET_ERR( get_root( volume, root ), "Failed to get volume's obb tree root" );
1955 
1956  // call box to get center and vectors to faces
1957  return obbTree->box( root, center, axis1, axis2, axis3 );
1958 }

References moab::OrientedBoxTreeTool::box(), center(), get_root(), MB_CHK_SET_ERR, and obbTree.

Referenced by get_bounding_coords(), and obbvis_create().

◆ get_one_vol_root()

EntityHandle moab::GeomTopoTool::get_one_vol_root ( )
inline

If constructing one volume obb tree by joining all surface trees,.

Definition at line 371 of file GeomTopoTool.hpp.

372 {
373  return oneVolRootSet;
374 }

References oneVolRootSet.

Referenced by moab::GeomQueryTool::find_volume().

◆ get_root()

◆ get_root_model_set()

EntityHandle moab::GeomTopoTool::get_root_model_set ( )
inline

Return the model set handle (this is the full geometry)

Definition at line 215 of file GeomTopoTool.hpp.

216  {
217  return modelSet;
218  }

References modelSet.

Referenced by moab::FBEngine::getRootSet().

◆ get_sense()

ErrorCode moab::GeomTopoTool::get_sense ( EntityHandle  entity,
EntityHandle  wrt_entity,
int &  sense 
)

Get the sense of entity with respect to wrt_entity Returns MB_ENTITY_NOT_FOUND if no relationship found.

Definition at line 899 of file GeomTopoTool.cpp.

900 {
901  // entity is lower dim (edge or face), wrt_entity is face or volume
902  int edim = dimension( entity );
903  int wrtdim = dimension( wrt_entity );
904  if( -1 == edim || -1 == wrtdim ) MB_SET_ERR( MB_FAILURE, "Non-geometric entity provided" );
905  if( wrtdim - edim != 1 ) MB_SET_ERR( MB_FAILURE, "Entity dimension mismatch" );
906 
907  ErrorCode rval;
908 
909  if( 1 == edim )
910  {
911  // edge in face
912  MB_CHK_SET_ERR( check_edge_sense_tags( false ), "Failed to check the curve to surface sense tag handles" );
913 
914  std::vector< EntityHandle > faces;
915  std::vector< int > senses;
916  rval = get_senses( entity, faces, senses ); // the tags should be defined here
917  MB_CHK_SET_ERR( rval, "Failed to get the curve to surface sense data" );
918 
919  std::vector< EntityHandle >::iterator it = std::find( faces.begin(), faces.end(), wrt_entity );
920  if( it == faces.end() ) return MB_ENTITY_NOT_FOUND;
921  unsigned int index = it - faces.begin();
922  sense = senses[index];
923  }
924  else
925  {
926  // face in volume
927  MB_CHK_SET_ERR( check_face_sense_tag( false ), "Failed to check the surface to volume sense tag handle" );
928  EntityHandle sense_data[2] = { 0, 0 };
929  rval = mdbImpl->tag_get_data( sense2Tag, &entity, 1, sense_data );
930  if( MB_TAG_NOT_FOUND != rval && MB_SUCCESS != rval )
931  MB_CHK_SET_ERR( rval, "Failed to get the surface to volume sense data" );
932  if( ( wrt_entity == sense_data[0] ) && ( wrt_entity == sense_data[1] ) )
933  sense = 0;
934  else if( wrt_entity == sense_data[0] )
935  sense = 1;
936  else if( wrt_entity == sense_data[1] )
937  sense = -1;
938  else
939  return MB_ENTITY_NOT_FOUND;
940  }
941  return MB_SUCCESS;
942 }

References check_edge_sense_tags(), check_face_sense_tag(), dimension(), ErrorCode, get_senses(), moab::index, MB_CHK_SET_ERR, MB_ENTITY_NOT_FOUND, MB_SET_ERR, MB_SUCCESS, MB_TAG_NOT_FOUND, mdbImpl, sense2Tag, and moab::Interface::tag_get_data().

Referenced by moab::GeomQueryTool::boundary_case(), check_model(), get_surface_senses(), main(), moab::FBEngine::split_bedge_at_new_mesh_node(), and moab::FBEngine::split_edge_at_mesh_node().

◆ get_sense_tag()

Tag moab::GeomTopoTool::get_sense_tag ( )
inline

Returns the sense tag (sense2Tag) from check_face_sense_tag.

Definition at line 376 of file GeomTopoTool.hpp.

377 {
378  check_face_sense_tag( true );
379  return sense2Tag;
380 }

References check_face_sense_tag(), and sense2Tag.

Referenced by moab::GeomQueryTool::GeomQueryTool().

◆ get_senses()

ErrorCode moab::GeomTopoTool::get_senses ( EntityHandle  entity,
std::vector< EntityHandle > &  wrt_entities,
std::vector< int > &  senses 
)

Get the senses of the lower dimension entity handle wrt the higher dimension entities.

Definition at line 1011 of file GeomTopoTool.cpp.

1014 {
1015  // the question here is: the wrt_entities is supplied or not?
1016  // I assume not, we will obtain it !!
1017  int edim = dimension( entity );
1018 
1019  if( -1 == edim ) MB_SET_ERR( MB_FAILURE, "Non-geometric entity provided" );
1020 
1021  wrt_entities.clear();
1022  senses.clear();
1023 
1024  if( 1 == edim ) // edge
1025  {
1026  MB_CHK_SET_ERR( check_edge_sense_tags( false ), "Failed to check the curve to surface sense tag handles" );
1027  const void* dum_ptr;
1028  int num_ents;
1029  MB_CHK_ERR( mdbImpl->tag_get_by_ptr( senseNEntsTag, &entity, 1, &dum_ptr, &num_ents ) );
1030 
1031  const EntityHandle* ents_data = static_cast< const EntityHandle* >( dum_ptr );
1032  std::copy( ents_data, ents_data + num_ents, std::back_inserter( wrt_entities ) );
1033 
1034  MB_CHK_ERR( mdbImpl->tag_get_by_ptr( senseNSensesTag, &entity, 1, &dum_ptr, &num_ents ) );
1035 
1036  const int* senses_data = static_cast< const int* >( dum_ptr );
1037  std::copy( senses_data, senses_data + num_ents, std::back_inserter( senses ) );
1038  }
1039  else // face in volume, edim == 2
1040  {
1041  MB_CHK_SET_ERR( check_face_sense_tag( false ), "Failed to check the surface to volume sense tag handle" );
1042  EntityHandle sense_data[2] = { 0, 0 };
1043  MB_CHK_SET_ERR( mdbImpl->tag_get_data( sense2Tag, &entity, 1, sense_data ),
1044  "Failed to get the surface to volume sense data" );
1045  if( sense_data[0] != 0 && sense_data[1] == sense_data[0] )
1046  {
1047  wrt_entities.push_back( sense_data[0] );
1048  senses.push_back( 0 ); // both
1049  }
1050  else
1051  {
1052  if( sense_data[0] != 0 )
1053  {
1054  wrt_entities.push_back( sense_data[0] );
1055  senses.push_back( 1 );
1056  }
1057  if( sense_data[1] != 0 )
1058  {
1059  wrt_entities.push_back( sense_data[1] );
1060  senses.push_back( -1 );
1061  }
1062  }
1063  }
1064  // filter the results with the sets that are in the model at this time
1065  // this was introduced because extracting some sets (e.g. neumann set, with mbconvert)
1066  // from a model would leave some sense tags not defined correctly
1067  // also, the geom ent set really needs to be part of the current model set
1068  unsigned int currentSize = 0;
1069 
1070  for( unsigned int index = 0; index < wrt_entities.size(); index++ )
1071  {
1072  EntityHandle wrt_ent = wrt_entities[index];
1073  if( wrt_ent )
1074  {
1075  if( mdbImpl->contains_entities( modelSet, &wrt_ent, 1 ) )
1076  {
1077  wrt_entities[currentSize] = wrt_entities[index];
1078  senses[currentSize] = senses[index];
1079  currentSize++;
1080  }
1081  }
1082  }
1083  wrt_entities.resize( currentSize );
1084  senses.resize( currentSize );
1085  //
1086  return MB_SUCCESS;
1087 }

References check_edge_sense_tags(), check_face_sense_tag(), moab::Interface::contains_entities(), dimension(), moab::index, MB_CHK_ERR, MB_CHK_SET_ERR, MB_SET_ERR, MB_SUCCESS, mdbImpl, modelSet, sense2Tag, senseNEntsTag, senseNSensesTag, moab::Interface::tag_get_by_ptr(), and moab::Interface::tag_get_data().

Referenced by moab::SmoothCurve::compute_control_points_on_boundary_edges(), duplicate_model(), get_sense(), moab::FBEngine::getEgFcSense(), main(), and set_sense().

◆ get_surface_senses() [1/2]

ErrorCode moab::GeomTopoTool::get_surface_senses ( EntityHandle  surface_ent,
EntityHandle forward_vol,
EntityHandle reverse_vol 
)

Get the senses of a surface with respect to its volumes.

Definition at line 944 of file GeomTopoTool.cpp.

947 {
948  // this method should only be called to retrieve surface to volume
949  // sense relationships
950  int ent_dim = dimension( surface_ent );
951  // verify the incoming entity dimensions for this call
952  if( ent_dim != 2 )
953  {
954  MB_SET_ERR( MB_FAILURE, "Entity dimension is incorrect for surface meshset" );
955  }
956 
957  // get the sense information for this surface
958  EntityHandle parent_vols[2] = { 0, 0 };
959  MB_CHK_SET_ERR( mdbImpl->tag_get_data( sense2Tag, &surface_ent, 1, parent_vols ),
960  "Failed to get surface sense data" );
961 
962  // set the outgoing values
963  forward_vol = parent_vols[0];
964  reverse_vol = parent_vols[1];
965 
966  return MB_SUCCESS;
967 }

References dimension(), MB_CHK_SET_ERR, MB_SET_ERR, MB_SUCCESS, mdbImpl, sense2Tag, and moab::Interface::tag_get_data().

◆ get_surface_senses() [2/2]

ErrorCode moab::GeomTopoTool::get_surface_senses ( EntityHandle  volume,
int  num_surfs,
const EntityHandle surfs,
int *  senses_out 
)

Get the sense of the surface(s) with respect to the volume.

Definition at line 991 of file GeomTopoTool.cpp.

995 {
996 
997  /* The sense tags do not reference the implicit complement handle.
998  All surfaces that interact with the implicit complement should have
999  a null handle in the direction of the implicit complement. */
1000  // if (volume == impl_compl_handle)
1001  // volume = (EntityHandle) 0;
1002 
1003  for( int surf_num = 0; surf_num < num_surfaces; surf_num++ )
1004  {
1005  get_sense( surfaces[surf_num], volume, senses_out[surf_num] );
1006  }
1007 
1008  return MB_SUCCESS;
1009 }

References get_sense(), and MB_SUCCESS.

Referenced by moab::GeomQueryTool::find_volume(), generate_implicit_complement(), moab::GeomQueryTool::measure_volume(), and moab::GeomQueryTool::point_in_volume_slow().

◆ global_id()

int moab::GeomTopoTool::global_id ( EntityHandle  this_set)

Return the global ID of a given entity set.

Parameters
this_setEntitySet for which the global ID will be returned

Definition at line 123 of file GeomTopoTool.cpp.

124 {
125  ErrorCode result;
126  if( 0 == gidTag )
127  {
129  }
130 
131  // check if the geo set belongs to this model
132  if( modelSet )
133  {
134  if( !mdbImpl->contains_entities( modelSet, &this_set, 1 ) )
135  {
136  // this g set does not belong to the current model
137  return -1;
138  }
139  }
140 
141  // get the data for those tags
142  int id;
143  result = mdbImpl->tag_get_data( gidTag, &this_set, 1, &id );
144  if( MB_SUCCESS != result )
145  return -1;
146  else
147  return id;
148 }

References moab::Interface::contains_entities(), ErrorCode, gidTag, moab::Interface::globalId_tag(), MB_SUCCESS, mdbImpl, modelSet, and moab::Interface::tag_get_data().

Referenced by construct_obb_tree(), moab::FBEngine::create_new_gedge(), obbstat_write(), moab::FBEngine::split_bedge_at_new_mesh_node(), and moab::FBEngine::split_edge_at_mesh_node().

◆ have_obb_tree()

bool moab::GeomTopoTool::have_obb_tree ( )

Returns true if obb trees have been added to the rootset.

Definition at line 1920 of file GeomTopoTool.cpp.

1921 {
1922  return rootSets.size() != 0 || mapRootSets.size() != 0;
1923 }

References mapRootSets, and rootSets.

◆ insert_in_tree()

ErrorCode moab::GeomTopoTool::insert_in_tree ( const EntityHandle  ct_root,
const EntityHandle  volume,
GeomQueryTool GQT 
)
private

Used by restore_topology_from_geometric_inclusion to generate the.

Definition at line 2004 of file GeomTopoTool.cpp.

2005 {
2006  bool inserted = false;
2007  EntityHandle current_volume = volume; // volume to be inserted
2008  EntityHandle tree_volume = ct_root; // volume already existing in the tree
2009  EntityHandle parent = ct_root;
2010  Range child_volumes;
2011 
2012  // while not inserted in tree
2013  while( !inserted )
2014  {
2015  // if current volume is insde of tree volume-- always true if tree volume
2016  // is the root of the tree
2017  if( tree_volume == ct_root || ( tree_volume != ct_root && A_is_in_B( current_volume, tree_volume, GQT ) ) )
2018  {
2019 
2020  parent = tree_volume;
2021 
2022  // if tree_volume has children then we must test them,
2023  // (tree_volume will change)
2024  child_volumes = get_ct_children_by_dimension( tree_volume, 3 );
2025  if( child_volumes.size() > 0 ) tree_volume = child_volumes.pop_front();
2026  // otherwise current_volume is the only child of the tree volume
2027  else
2028  {
2029  MB_CHK_SET_ERR( mdbImpl->add_parent_child( parent, current_volume ),
2030  "Failed to add parent-child relationship." );
2031 
2032  inserted = true;
2033  }
2034  // if current volume is not in the tree volume, the converse may be true
2035  }
2036  else
2037  {
2038  // if the tree volume is inside the current volume
2039  if( A_is_in_B( tree_volume, current_volume, GQT ) )
2040  {
2041  // reverse their parentage
2042  MB_CHK_SET_ERR( mdbImpl->remove_parent_child( parent, tree_volume ),
2043  "Failed to remove parent-child relationship." );
2044  MB_CHK_SET_ERR( mdbImpl->add_parent_child( current_volume, tree_volume ),
2045  "Failed to add parent-child relationship." );
2046  }
2047 
2048  if( child_volumes.size() == 0 )
2049  {
2050  MB_CHK_SET_ERR( mdbImpl->add_parent_child( parent, current_volume ),
2051  "Failed to add parent-child relationship." );
2052  inserted = true;
2053  }
2054  else
2055  tree_volume = child_volumes.pop_front();
2056  }
2057  }
2058  return MB_SUCCESS;
2059 }

References A_is_in_B(), moab::Interface::add_parent_child(), get_ct_children_by_dimension(), MB_CHK_SET_ERR, MB_SUCCESS, mdbImpl, moab::Range::pop_front(), moab::Interface::remove_parent_child(), and moab::Range::size().

Referenced by restore_topology_from_geometric_inclusion().

◆ is_implicit_complement()

bool moab::GeomTopoTool::is_implicit_complement ( EntityHandle  volume)
inline

detection method for the implicit complement

Definition at line 394 of file GeomTopoTool.hpp.

395 {
396  return volume == impl_compl_handle;
397 }

References impl_compl_handle.

Referenced by moab::GeomQueryTool::measure_volume(), obbstat_write(), and moab::GeomQueryTool::point_in_volume().

◆ is_owned_set()

ErrorCode moab::GeomTopoTool::is_owned_set ( EntityHandle  eh)

Checks to see if the entity is part of the model set.

Definition at line 303 of file GeomTopoTool.cpp.

304 {
305  // make sure entity set is part of the model
306  Range model_ents;
307  MB_CHK_SET_ERR( mdbImpl->get_entities_by_handle( modelSet, model_ents ), "Failed to get entities" );
308  if( model_ents.find( eh ) == model_ents.end() )
309  {
310  MB_SET_ERR( MB_FAILURE, "Entity handle not in model set" );
311  }
312  return MB_SUCCESS;
313 }

References moab::Range::end(), moab::Range::find(), moab::Interface::get_entities_by_handle(), MB_CHK_SET_ERR, MB_SET_ERR, MB_SUCCESS, mdbImpl, and modelSet.

Referenced by construct_obb_tree(), and delete_obb_tree().

◆ next_vol()

ErrorCode moab::GeomTopoTool::next_vol ( EntityHandle  surface,
EntityHandle  old_volume,
EntityHandle new_volume 
)

Get the volume on the other side of a surface.

Parameters
Asurface to query
old_volumeA volume on one side of surface
new_volumeOutput parameter for volume on the other side of surface
Returns
MB_SUCCESS if new_volume was set successfully, error if not.

Definition at line 1102 of file GeomTopoTool.cpp.

1103 {
1104  std::vector< EntityHandle > parents;
1105  ErrorCode rval = mdbImpl->get_parent_meshsets( surface, parents );
1106 
1107  if( MB_SUCCESS == rval )
1108  {
1109  if( parents.size() != 2 )
1110  rval = MB_FAILURE;
1111  else if( parents.front() == old_volume )
1112  new_volume = parents.back();
1113  else if( parents.back() == old_volume )
1114  new_volume = parents.front();
1115  else
1116  rval = MB_FAILURE;
1117  }
1118 
1119  return rval;
1120 }

References ErrorCode, moab::Interface::get_parent_meshsets(), MB_SUCCESS, and mdbImpl.

◆ num_ents_of_dim()

int moab::GeomTopoTool::num_ents_of_dim ( int  dim)
inline

returns the number of entities in the modelSet with specified geometric dimension

Definition at line 352 of file GeomTopoTool.hpp.

353 {
354  assert( 0 <= dim && 3 >= dim );
355  return geomRanges[dim].size();
356 }

References geomRanges, and moab::Range::size().

◆ obb_tree()

◆ other_entity()

ErrorCode moab::GeomTopoTool::other_entity ( EntityHandle  bounded,
EntityHandle  not_this,
EntityHandle  across,
EntityHandle other 
)

Get the other (d-1)-dimensional entity bounding a set across a (d-2)-dimensional entity.

Given a d-dimensional entity and one (d-1)-dimensional entity, return the (d-1) dimensional entity across a specified (d-2)-dimensional entity. For example, given a surface, edge, and vertex, returns the other edge bounding the surface sharing the vertex. In the case of degenerate results, e.g. two loops bounding a surface and sharing a vertex, tries to step in positively-oriented direction. This won't always work; in those cases, will return MB_MULTIPLE_ENTITIES_FOUND.

In the special case where bounded is a curve, then not_this can be a vertex and across zero. This function returns the other vertex on the curve.

Definition at line 169 of file GeomTopoTool.cpp.

173 {
174  other = 0;
175 
176  // get all children of bounded
177  Range bdy, tmpr;
178  MB_CHK_SET_ERR( mdbImpl->get_child_meshsets( bounded, bdy ), "Failed to get the bounded entity's child meshsets" );
179 
180  // get all the parents of across
181  MB_CHK_SET_ERR( mdbImpl->get_parent_meshsets( across, tmpr ), "failed to get parent meshsets" );
182 
183  // possible candidates is the intersection
184  bdy = intersect( bdy, tmpr );
185 
186  // if only two, choose the other
187  if( 1 == bdy.size() && *bdy.begin() == not_this )
188  {
189  return MB_SUCCESS;
190  }
191  else if( 2 == bdy.size() )
192  {
193  if( *bdy.begin() == not_this ) other = *bdy.rbegin();
194  if( *bdy.rbegin() == not_this )
195  other = *bdy.begin();
196  else
197  return MB_FAILURE;
198  }
199  else
200  {
201  return MB_FAILURE;
202  }
203 
204  return MB_SUCCESS;
205 }

References moab::Range::begin(), moab::Interface::get_child_meshsets(), moab::Interface::get_parent_meshsets(), moab::intersect(), MB_CHK_SET_ERR, MB_SUCCESS, mdbImpl, moab::Range::rbegin(), and moab::Range::size().

◆ remove_root()

ErrorCode moab::GeomTopoTool::remove_root ( EntityHandle  vol_or_surf)

Delete the root of the obb tree from the set of all roots.

Definition at line 511 of file GeomTopoTool.cpp.

512 {
513  // Find the root of the vol or surf
514  EntityHandle root;
515  MB_CHK_SET_ERR( mdbImpl->tag_get_data( obbRootTag, &( vol_or_surf ), 1, &root ), "Failed to get obb root tag" );
516 
517  // If the ent is a vol, remove its root from obbtreetool
518  int dim;
519  MB_CHK_SET_ERR( mdbImpl->tag_get_data( geomTag, &vol_or_surf, 1, &dim ), "Failed to get dimension" );
520  if( dim == 3 )
521  {
522  MB_CHK_SET_ERR( obbTree->remove_root( root ), "Failed to remove root from obbTreeTool" );
523  }
524 
525  // Delete the obbGsetTag data from the root
526  MB_CHK_SET_ERR( mdbImpl->tag_delete_data( obbGsetTag, &root, 1 ), "Failed to delete obb root tag" );
527 
528  // Delete the obbRootTag data from the vol or surf
529  MB_CHK_SET_ERR( mdbImpl->tag_delete_data( obbRootTag, &vol_or_surf, 1 ), "Failed to delete obb root tag" );
530 
531  // Remove the root from set of all roots
532  if( m_rootSets_vector )
533  {
534  unsigned int index = vol_or_surf - setOffset;
535  if( index < rootSets.size() )
536  {
537  rootSets[index] = 0;
538  }
539  else
540  {
541  return MB_INDEX_OUT_OF_RANGE;
542  }
543  }
544  else
545  {
546  mapRootSets[vol_or_surf] = 0;
547  }
548 
549  return MB_SUCCESS;
550 }

References geomTag, moab::index, m_rootSets_vector, mapRootSets, MB_CHK_SET_ERR, MB_INDEX_OUT_OF_RANGE, MB_SUCCESS, mdbImpl, obbGsetTag, obbRootTag, obbTree, moab::OrientedBoxTreeTool::remove_root(), rootSets, setOffset, moab::Interface::tag_delete_data(), and moab::Interface::tag_get_data().

Referenced by delete_obb_tree().

◆ resize_rootSets()

ErrorCode moab::GeomTopoTool::resize_rootSets ( )
private

Definition at line 267 of file GeomTopoTool.cpp.

268 {
269  // store original offset for later
270  EntityHandle orig_offset = setOffset;
271 
272  // get all surfaces and volumes
273  Range surfs, vols;
274  MB_CHK_SET_ERR( get_gsets_by_dimension( 2, surfs ), "Could not get surface sets" );
275  MB_CHK_SET_ERR( get_gsets_by_dimension( 3, vols ), "Could not get volume sets" );
276 
277  // check the vector size
278  Range surfs_and_vols;
279  surfs_and_vols = vols;
280  surfs_and_vols.merge( surfs );
281 
282  // update the setOffset
283  setOffset = surfs_and_vols.front();
284 
285  EntityHandle exp_size = surfs_and_vols.back() - setOffset + 1;
286 
287  // if new EnitytHandle(s) are lower than the original offset
288  if( setOffset < orig_offset )
289  {
290  // insert empty values at the beginning of the vector
291  rootSets.insert( rootSets.begin(), orig_offset - setOffset, 0 );
292  }
293 
294  if( exp_size != rootSets.size() )
295  {
296  // resize rootSets vector if necessary (new space will be added at the back)
297  rootSets.resize( exp_size );
298  }
299 
300  return MB_SUCCESS;
301 }

References moab::Range::back(), moab::Range::front(), get_gsets_by_dimension(), MB_CHK_SET_ERR, MB_SUCCESS, moab::Range::merge(), rootSets, and setOffset.

Referenced by construct_obb_tree(), and restore_obb_index().

◆ restore_obb_index()

ErrorCode moab::GeomTopoTool::restore_obb_index ( )

Restore the internal cross-referencing of geometry sets and OBB roots.

Definition at line 207 of file GeomTopoTool.cpp.

208 {
210 
211  ErrorCode rval;
212  EntityHandle root;
213 
214  for( int dim = 2; dim <= 3; dim++ )
215  for( Range::iterator rit = geomRanges[dim].begin(); rit != geomRanges[dim].end(); ++rit )
216  {
217  rval = mdbImpl->tag_get_data( obbRootTag, &( *rit ), 1, &root );
218 
219  if( MB_SUCCESS == rval )
220  set_root_set( *rit, root );
221  else
222  {
223  return MB_TAG_NOT_FOUND;
224  }
225  }
226 
227  return MB_SUCCESS;
228 }

References moab::Range::end(), ErrorCode, geomRanges, m_rootSets_vector, MB_SUCCESS, MB_TAG_NOT_FOUND, mdbImpl, obbRootTag, resize_rootSets(), set_root_set(), and moab::Interface::tag_get_data().

Referenced by GeomTopoTool().

◆ restore_topology_from_adjacency()

ErrorCode moab::GeomTopoTool::restore_topology_from_adjacency ( )

Restore parent/child links between GEOM_TOPO mesh sets.

Definition at line 590 of file GeomTopoTool.cpp.

591 {
592 
593  // look for geometric topology sets and restore parent/child links between them
594  // algorithm:
595  // - for each entity of dimension d=D-1..0:
596  // . get d-dimensional entity in entity
597  // . get all (d+1)-dim adjs to that entity
598  // . for each geom entity if dim d+1, if it contains any of the ents,
599  // add it to list of parents
600  // . make parent/child links with parents
601 
602  // the geomRanges are already known, separated by dimension
603 
604  std::vector< EntityHandle > parents;
605  Range tmp_parents;
606  ErrorCode result;
607 
608  // loop over dimensions
609  for( int dim = 2; dim >= 0; dim-- )
610  {
611  // mark entities of next higher dimension with their owners; regenerate tag
612  // each dimension so prev dim's tag data goes away
613  Tag owner_tag;
614  EntityHandle dum_val = 0;
615  result = mdbImpl->tag_get_handle( "__owner_tag", 1, MB_TYPE_HANDLE, owner_tag, MB_TAG_DENSE | MB_TAG_CREAT,
616  &dum_val );
617  if( MB_SUCCESS != result ) continue;
618  Range dp1ents;
619  std::vector< EntityHandle > owners;
620  for( Range::iterator rit = geomRanges[dim + 1].begin(); rit != geomRanges[dim + 1].end(); ++rit )
621  {
622  dp1ents.clear();
623  result = mdbImpl->get_entities_by_dimension( *rit, dim + 1, dp1ents );
624  if( MB_SUCCESS != result ) continue;
625  owners.resize( dp1ents.size() );
626  std::fill( owners.begin(), owners.end(), *rit );
627  result = mdbImpl->tag_set_data( owner_tag, dp1ents, &owners[0] );
628  if( MB_SUCCESS != result ) continue;
629  }
630 
631  for( Range::iterator d_it = geomRanges[dim].begin(); d_it != geomRanges[dim].end(); ++d_it )
632  {
633  Range dents;
634  result = mdbImpl->get_entities_by_dimension( *d_it, dim, dents );
635  if( MB_SUCCESS != result ) continue;
636  if( dents.empty() ) continue;
637 
638  // get (d+1)-dimensional adjs
639  dp1ents.clear();
640  result = mdbImpl->get_adjacencies( &( *dents.begin() ), 1, dim + 1, false, dp1ents );
641  if( MB_SUCCESS != result || dp1ents.empty() ) continue;
642 
643  // get owner tags
644  parents.resize( dp1ents.size() );
645  result = mdbImpl->tag_get_data( owner_tag, dp1ents, &parents[0] );
646  if( MB_TAG_NOT_FOUND == result )
647  {
648  MB_CHK_SET_ERR( result, "Could not find owner tag" );
649  }
650  if( MB_SUCCESS != result ) continue;
651 
652  // compress to a range to remove duplicates
653  tmp_parents.clear();
654  std::copy( parents.begin(), parents.end(), range_inserter( tmp_parents ) );
655  for( Range::iterator pit = tmp_parents.begin(); pit != tmp_parents.end(); ++pit )
656  {
657  result = mdbImpl->add_parent_child( *pit, *d_it );
658  MB_CHK_SET_ERR( result, "Failed to create parent child relationship" );
659  }
660 
661  // store surface senses within regions, and edge senses within surfaces
662  if( dim == 0 ) continue;
663  const EntityHandle *conn3 = NULL, *conn2 = NULL;
664  int len3 = 0, len2 = 0, err = 0, num = 0, sense = 0, offset = 0;
665  for( size_t i = 0; i < parents.size(); ++i )
666  {
667  result = mdbImpl->get_connectivity( dp1ents[i], conn3, len3, true );
668  MB_CHK_SET_ERR( result, "Failed to get the connectivity of the element" );
669  result = mdbImpl->get_connectivity( dents.front(), conn2, len2, true );
670  MB_CHK_SET_ERR( result, "Failed to get the connectivity of the first element" );
671  if( len2 > 4 )
672  {
673  MB_SET_ERR( MB_FAILURE, "Connectivity of incorrect length" );
674  }
675  err = CN::SideNumber( TYPE_FROM_HANDLE( dp1ents[i] ), conn3, conn2, len2, dim, num, sense, offset );
676  if( err ) return MB_FAILURE;
677 
678  result = set_sense( *d_it, parents[i], sense );
679  if( MB_MULTIPLE_ENTITIES_FOUND == result )
680  {
681  if( 2 == dim )
682  std::cerr << "Warning: Multiple volumes use surface with same sense." << std::endl
683  << " Some geometric sense data lost." << std::endl;
684  }
685  else if( MB_SUCCESS != result )
686  {
687  return result;
688  }
689  }
690  }
691 
692  // now delete owner tag on this dimension, automatically removes tag data
693  result = mdbImpl->tag_delete( owner_tag );
694  MB_CHK_SET_ERR( result, "Failed to delete the owner tag" );
695 
696  } // dim
697 
698  return result;
699 }

References moab::Interface::add_parent_child(), moab::Range::begin(), moab::Range::clear(), moab::Range::empty(), moab::Range::end(), ErrorCode, moab::Range::front(), geomRanges, moab::Interface::get_adjacencies(), moab::Interface::get_connectivity(), moab::Interface::get_entities_by_dimension(), MB_CHK_SET_ERR, MB_MULTIPLE_ENTITIES_FOUND, MB_SET_ERR, MB_SUCCESS, MB_TAG_CREAT, MB_TAG_DENSE, MB_TAG_NOT_FOUND, MB_TYPE_HANDLE, mdbImpl, set_sense(), moab::CN::SideNumber(), moab::Range::size(), moab::Interface::tag_delete(), moab::Interface::tag_get_data(), moab::Interface::tag_get_handle(), moab::Interface::tag_set_data(), and moab::TYPE_FROM_HANDLE().

Referenced by moab::Tqdcfr::load_file().

◆ restore_topology_from_geometric_inclusion()

ErrorCode moab::GeomTopoTool::restore_topology_from_geometric_inclusion ( const Range flat_volumes)

Discover and store the topological relationships among a set of volumes This method may be used to discover the hierarchy that exists in a range of volumes, that have no previous sense of hierarchy, and store it according to the conventions of GeomTopoTool. The following requirements about the range of flat_volumes must be met:

  1. Each volume must be represented by a single, closed surface a. The surface meshsets have triangles and vertices as members. b. For each "flat volume", there must be two meshsets: one for the volume and another for the surface that encloses it. These must be linked by a parent-child relationship. c. The SENSE_FORWARD tag on the surface meshset must be set to be the volume meshset it encloses.
  2. The surfaces must not touch or overlap

After the hierarchy is established, the topological relationships between surfaces and the volumes that enclose them are set. This involves:

  1. Setting parent-child relationship between surfaces and the volumes that enclose them.
  2. Setting the SENSE_REVERSE tag on the surfaces to be the volume that encloses them.

Definition at line 2061 of file GeomTopoTool.cpp.

2062 {
2063  // local var will go out of scope if errors appear, no need to free it also
2064  GeomQueryTool GQT( this );
2065  std::map< EntityHandle, EntityHandle > volume_surface; // map of volume
2066  // to its surface
2067 
2068  EntityHandle ct_root;
2069  // create root meshset-- this will be top of tree
2070  std::string meshset_name = "build_hierarchy_root";
2071  MB_CHK_ERR( mdbImpl->create_meshset( MESHSET_SET, ct_root ) );
2072  MB_CHK_ERR( mdbImpl->tag_set_data( nameTag, &ct_root, 1, meshset_name.c_str() ) );
2073 
2074  for( Range::iterator vol = flat_volumes.begin(); vol != flat_volumes.end(); vol++ )
2075  {
2076  // get the surface corresponding to each volume
2077  // at this point, each volume meshset only has one 'child' surface
2078  // which exactly corresponds to that volume
2079  Range child_surfaces = get_ct_children_by_dimension( *vol, 2 );
2080  volume_surface[*vol] = *child_surfaces.begin();
2081 
2082  MB_CHK_SET_ERR( insert_in_tree( ct_root, *vol, &GQT ), "Failed to insert volume into tree." );
2083  }
2084 
2085  // for each original volume, get its child volumes
2086  for( Range::iterator parent_it = flat_volumes.begin(); parent_it != flat_volumes.end(); parent_it++ )
2087  {
2088  Range volume_children = get_ct_children_by_dimension( *parent_it, 3 );
2089 
2090  if( volume_children.size() != 0 )
2091  {
2092  // loop over all of original volume's child volumes
2093  for( Range::iterator child_it = volume_children.begin(); child_it != volume_children.end(); ++child_it )
2094  {
2095  // set the sense of the surface mapped to the child volume to REVERSE
2096  // wrt the parent volume
2097  MB_CHK_SET_ERR( set_sense( volume_surface[*child_it], *parent_it, SENSE_REVERSE ),
2098  "Failed to set sense." );
2099 
2100  // add the child volume's surface as a child of the original volume
2101  // and delete the child volume as a child of original volume
2102  MB_CHK_SET_ERR( mdbImpl->add_parent_child( *parent_it, volume_surface[*child_it] ),
2103  "Failed to add parent-child relationship." );
2104  MB_CHK_SET_ERR( mdbImpl->remove_parent_child( *parent_it, *child_it ),
2105  "Failed to remove parent-child relationship." );
2106  }
2107  }
2108  }
2109 
2110  return MB_SUCCESS;
2111 }

References moab::Interface::add_parent_child(), moab::Range::begin(), moab::Interface::create_meshset(), moab::Range::end(), get_ct_children_by_dimension(), insert_in_tree(), MB_CHK_ERR, MB_CHK_SET_ERR, MB_SUCCESS, mdbImpl, MESHSET_SET, nameTag, moab::Interface::remove_parent_child(), SENSE_REVERSE, set_sense(), moab::Range::size(), and moab::Interface::tag_set_data().

◆ separate_by_dimension()

ErrorCode moab::GeomTopoTool::separate_by_dimension ( const Range geom_sets)
private

Given a range of geom topology sets, separate by dimension.

Definition at line 701 of file GeomTopoTool.cpp.

702 {
703  ErrorCode result;
704 
705  result = check_geom_tag();
706  MB_CHK_SET_ERR( result, "Could not verify geometry dimension tag" );
707 
708  // get the data for those tags
709  std::vector< int > tag_vals( geom_sets.size() );
710  result = mdbImpl->tag_get_data( geomTag, geom_sets, &tag_vals[0] );
711  MB_CHK_SET_ERR( result, "Failed to get the geometry dimension tag" );
712 
713  Range::const_iterator git;
714  std::vector< int >::iterator iit;
715 
716  for( int i = 0; i < 5; i++ )
717  this->geomRanges[i].clear();
718 
719  for( git = geom_sets.begin(), iit = tag_vals.begin(); git != geom_sets.end(); ++git, ++iit )
720  {
721  if( 0 <= *iit && 4 >= *iit )
722  geomRanges[*iit].insert( *git );
723  else
724  {
725  // assert(false);
726  // do nothing for now
727  }
728  }
729 
730  // establish the max global ids so far, per dimension
731  if( 0 == gidTag )
732  {
734  }
735 
736  for( int i = 0; i <= 4; i++ )
737  {
738  maxGlobalId[i] = 0;
739  for( Range::iterator it = geomRanges[i].begin(); it != geomRanges[i].end(); ++it )
740  {
741  EntityHandle set = *it;
742  int gid;
743 
744  result = mdbImpl->tag_get_data( gidTag, &set, 1, &gid );
745  if( MB_SUCCESS == result )
746  {
747  if( gid > maxGlobalId[i] ) maxGlobalId[i] = gid;
748  }
749  }
750  }
751 
752  return MB_SUCCESS;
753 }

References moab::Range::begin(), check_geom_tag(), moab::Range::end(), ErrorCode, geomRanges, geomTag, gidTag, moab::Interface::globalId_tag(), moab::Range::insert(), maxGlobalId, MB_CHK_SET_ERR, MB_SUCCESS, mdbImpl, moab::Range::size(), and moab::Interface::tag_get_data().

Referenced by find_geomsets().

◆ set_root_set()

ErrorCode moab::GeomTopoTool::set_root_set ( EntityHandle  vol_or_surf,
EntityHandle  root 
)
private

Definition at line 493 of file GeomTopoTool.cpp.

494 {
495 
496  // Tag the vol or surf with its obb root (obbRootTag)
497  MB_CHK_SET_ERR( mdbImpl->tag_set_data( obbRootTag, &vol_or_surf, 1, &root ), "Failed to set the obb root tag" );
498 
499  // Tag obb root with corresponding gset (obbGsetTag)
500  MB_CHK_SET_ERR( mdbImpl->tag_set_data( obbGsetTag, &root, 1, &vol_or_surf ), "Failed to set the obb gset tag" );
501 
502  // Add to the set of all roots
503  if( m_rootSets_vector )
504  rootSets[vol_or_surf - setOffset] = root;
505  else
506  mapRootSets[vol_or_surf] = root;
507 
508  return MB_SUCCESS;
509 }

References m_rootSets_vector, mapRootSets, MB_CHK_SET_ERR, MB_SUCCESS, mdbImpl, obbGsetTag, obbRootTag, rootSets, setOffset, and moab::Interface::tag_set_data().

Referenced by construct_obb_tree(), and restore_obb_index().

◆ set_sense()

ErrorCode moab::GeomTopoTool::set_sense ( EntityHandle  entity,
EntityHandle  wrt_entity,
int  sense 
)

Store sense of entity relative to wrt_entity.

Returns
MB_MULTIPLE_ENTITIES_FOUND if surface already has a forward volume. MB_SUCCESS if successful otherwise whatever internal error code occured.
MB_MULTIPLE_ENTITIES_FOUND if surface already has a forward volume. MB_SUCCESS if successful otherwise whatever internal error code occurred.

Definition at line 802 of file GeomTopoTool.cpp.

803 {
804  // entity is lower dim (edge or face), wrt_entity is face or volume
805  int edim = dimension( entity );
806  int wrtdim = dimension( wrt_entity );
807  if( -1 == edim || -1 == wrtdim ) MB_SET_ERR( MB_FAILURE, "Non-geometric entity provided" );
808  if( wrtdim - edim != 1 ) MB_SET_ERR( MB_FAILURE, "Entity dimension mismatch" );
809  if( sense < -1 || sense > 1 ) MB_SET_ERR( MB_FAILURE, "Invalid sense data provided" );
810 
811  ErrorCode rval;
812 
813  if( 1 == edim )
814  {
815  // this case is about setting the sense of an edge in a face
816  // it could be -1, 0 (rare, non manifold), or 1
817  MB_CHK_SET_ERR( check_edge_sense_tags( true ), "Failed to check the curve to surface sense tag handles" );
818  std::vector< EntityHandle > higher_ents;
819  std::vector< int > senses;
820  rval = get_senses( entity, higher_ents, senses ); // the tags should be defined here
821  // if there are no higher_ents, we are fine, we will just set them
822  // if wrt_entity is not among higher_ents, we will add it to the list
823  // it is possible the entity (edge set) has no prior faces adjancent; in that case, the
824  // tag would not be set, and rval could be MB_TAG_NOT_FOUND; it is not a fatal error
825  if( MB_SUCCESS != rval && MB_TAG_NOT_FOUND != rval )
826  MB_CHK_SET_ERR( rval, "cannot determine sense tags for edge" );
827  bool append = true;
828  if( !higher_ents.empty() )
829  {
830  std::vector< EntityHandle >::iterator it = std::find( higher_ents.begin(), higher_ents.end(), wrt_entity );
831  if( it != higher_ents.end() )
832  {
833  // we should not reset the sense, if the sense is the same
834  // if the sense is different, put BOTH
835  unsigned int idx = it - higher_ents.begin();
836  int oldSense = senses[idx];
837  if( oldSense == sense ) return MB_SUCCESS; // sense already set fine, do not reset
838  if( 0 != oldSense && oldSense + sense != 0 ) return MB_MULTIPLE_ENTITIES_FOUND;
839  senses[idx] = SENSE_BOTH; // allow double senses
840  // do not need to add a new sense, but still need to reset the tag
841  // because of a new value
842  append = false;
843  }
844  }
845  if( append )
846  {
847  // what happens if a var tag data was already set before, and now it is
848  // reset with a different size??
849  higher_ents.push_back( wrt_entity );
850  senses.push_back( sense );
851  }
852  // finally, set the senses :
853  int dum_size = higher_ents.size();
854  void* dum_ptr = &higher_ents[0];
855  MB_CHK_SET_ERR( mdbImpl->tag_set_by_ptr( senseNEntsTag, &entity, 1, &dum_ptr, &dum_size ),
856  "Failed to set the sense data" );
857 
858  dum_ptr = &senses[0];
859  dum_size = higher_ents.size();
860  MB_CHK_SET_ERR( mdbImpl->tag_set_by_ptr( senseNSensesTag, &entity, 1, &dum_ptr, &dum_size ),
861  "Failed to set the sense data by pointer" );
862  }
863  else
864  {
865  // this case is about a face in the volume
866  // there could be only 2 volumes
867 
868  MB_CHK_SET_ERR( check_face_sense_tag( true ), "Failed to verify the face sense tag" );
869 
870  EntityHandle sense_data[2] = { 0, 0 };
871  rval = mdbImpl->tag_get_data( sense2Tag, &entity, 1, sense_data );
872  if( MB_TAG_NOT_FOUND != rval && MB_SUCCESS != rval ) MB_CHK_SET_ERR( rval, "Failed to get the sense2Tag data" );
873 
874  if( 0 == sense )
875  {
876  if( 0 != sense_data[0] && wrt_entity != sense_data[0] ) return MB_MULTIPLE_ENTITIES_FOUND;
877  if( 0 != sense_data[1] && wrt_entity != sense_data[1] ) return MB_MULTIPLE_ENTITIES_FOUND;
878  sense_data[0] = sense_data[1] = wrt_entity;
879  }
880  else if( -1 == sense )
881  {
882  if( 0 != sense_data[1] && wrt_entity != sense_data[1] ) return MB_MULTIPLE_ENTITIES_FOUND;
883  if( sense_data[1] == wrt_entity ) return MB_SUCCESS; // already set as we want
884  sense_data[1] = wrt_entity;
885  }
886  else if( 1 == sense )
887  {
888  if( 0 != sense_data[0] && wrt_entity != sense_data[0] ) return MB_MULTIPLE_ENTITIES_FOUND;
889  if( sense_data[0] == wrt_entity ) return MB_SUCCESS; // already set as we want
890  sense_data[0] = wrt_entity;
891  }
892  return mdbImpl->tag_set_data( sense2Tag, &entity, 1, sense_data );
893  }
894  return MB_SUCCESS;
895 }

References check_edge_sense_tags(), check_face_sense_tag(), dimension(), ErrorCode, get_senses(), MB_CHK_SET_ERR, MB_MULTIPLE_ENTITIES_FOUND, MB_SET_ERR, MB_SUCCESS, MB_TAG_NOT_FOUND, mdbImpl, sense2Tag, SENSE_BOTH, senseNEntsTag, senseNSensesTag, moab::Interface::tag_get_data(), moab::Interface::tag_set_by_ptr(), and moab::Interface::tag_set_data().

Referenced by moab::ReadRTT::build_moab(), moab::ReadOBJ::create_new_object(), moab::FBEngine::create_volume_with_direction(), geometrize_surface_set(), moab::FBEngine::redistribute_boundary_edges_to_faces(), restore_topology_from_adjacency(), restore_topology_from_geometric_inclusion(), set_senses(), moab::ReadRTT::set_surface_senses(), moab::FBEngine::split_bedge_at_new_mesh_node(), moab::FBEngine::split_edge_at_mesh_node(), moab::FBEngine::split_surface(), and moab::FBEngine::weave_lateral_face_from_edges().

◆ set_senses()

ErrorCode moab::GeomTopoTool::set_senses ( EntityHandle  entity,
std::vector< EntityHandle > &  wrt_entities,
std::vector< int > &  senses 
)

Set the senses of the entity wrt multiple higher dimension entities.

Definition at line 1089 of file GeomTopoTool.cpp.

1092 {
1093  // not efficient, and maybe wrong
1094  for( unsigned int i = 0; i < wrt_entities.size(); i++ )
1095  {
1096  MB_CHK_SET_ERR( set_sense( entity, wrt_entities[i], senses[i] ), "Failed to set the sense" );
1097  }
1098 
1099  return MB_SUCCESS;
1100 }

References MB_CHK_SET_ERR, MB_SUCCESS, and set_sense().

Referenced by duplicate_model().

◆ set_surface_senses()

ErrorCode moab::GeomTopoTool::set_surface_senses ( EntityHandle  surface_ent,
EntityHandle  forward_vol,
EntityHandle  reverse_vol 
)

Set the senses of a surface with respect to its volumes.

Definition at line 969 of file GeomTopoTool.cpp.

972 {
973  // this mthod should only be called to retrieve surface to volume
974  // sense relationships
975  int ent_dim = dimension( surface_ent );
976  // verify the incoming entity dimensions for this call
977  if( ent_dim != 2 )
978  {
979  MB_SET_ERR( MB_FAILURE, "Entity dimension is incorrect for surface meshset" );
980  }
981 
982  // set the sense information for this surface
983  EntityHandle parent_vols[2] = { forward_vol, reverse_vol };
984  MB_CHK_SET_ERR( mdbImpl->tag_set_data( sense2Tag, &surface_ent, 1, parent_vols ),
985  "Failed to set surface sense data" );
986 
987  return MB_SUCCESS;
988 }

References dimension(), MB_CHK_SET_ERR, MB_SET_ERR, MB_SUCCESS, mdbImpl, sense2Tag, and moab::Interface::tag_set_data().

Referenced by generate_implicit_complement().

◆ setup_implicit_complement()

ErrorCode moab::GeomTopoTool::setup_implicit_complement ( )

sets the implicit complement handle for this tool

Definition at line 1644 of file GeomTopoTool.cpp.

1645 {
1646 
1647  // if the implicit complement is already setup,
1648  // we're done
1649  if( impl_compl_handle != 0 )
1650  {
1651  std::cout << "IPC already exists!" << std::endl;
1652  return MB_SUCCESS;
1653  }
1654 
1655  // if not, then query for a set with it's name
1656  Range entities;
1657  const void* const tagdata[] = { IMPLICIT_COMPLEMENT_NAME };
1658  ErrorCode rval = mdbImpl->get_entities_by_type_and_tag( modelSet, MBENTITYSET, &nameTag, tagdata, 1, entities );
1659  // query error
1660  MB_CHK_SET_ERR( rval, "Unable to query for implicit complement" );
1661 
1662  // if we found exactly one, set it as the implicit complement
1663  if( entities.size() == 1 )
1664  {
1665  impl_compl_handle = entities.front();
1666  return MB_SUCCESS;
1667  }
1668 
1669  // found too many
1670  if( entities.size() > 1 ) MB_CHK_SET_ERR( MB_MULTIPLE_ENTITIES_FOUND, "Too many implicit complement sets" );
1671 
1672  // found none
1673  if( entities.empty() )
1674  {
1675  // create implicit complement if requested
1676  MB_CHK_SET_ERR( generate_implicit_complement( impl_compl_handle ), "Could not create implicit complement" );
1677 
1679  "Could not set the name tag for the implicit complement" );
1680 
1681  MB_CHK_SET_ERR( add_geo_set( impl_compl_handle, 3 ), "Failed to add implicit complement to model" );
1682 
1683  // assign category tag - this is presumably for consistency so that the
1684  // implicit complement has all the appearance of being the same as any
1685  // other volume
1686  Tag category_tag;
1689  "Could not get the category tag" );
1690 
1691  static const char volume_category[CATEGORY_TAG_SIZE] = "Volume\0";
1692  MB_CHK_SET_ERR( mdbImpl->tag_set_data( category_tag, &impl_compl_handle, 1, volume_category ),
1693  "Could not set the category tag for the implicit complement" );
1694 
1695  return MB_SUCCESS;
1696  }
1697 
1698  return MB_FAILURE;
1699 }

References add_geo_set(), CATEGORY_TAG_NAME, CATEGORY_TAG_SIZE, moab::Range::empty(), ErrorCode, moab::Range::front(), generate_implicit_complement(), moab::Interface::get_entities_by_type_and_tag(), impl_compl_handle, moab::IMPLICIT_COMPLEMENT_NAME, MB_CHK_SET_ERR, MB_MULTIPLE_ENTITIES_FOUND, MB_SUCCESS, MB_TAG_CREAT, MB_TAG_SPARSE, MB_TYPE_OPAQUE, MBENTITYSET, mdbImpl, modelSet, nameTag, moab::Range::size(), moab::Interface::tag_get_handle(), and moab::Interface::tag_set_data().

Referenced by moab::GeomQueryTool::initialize().

Member Data Documentation

◆ geomRanges

◆ geomTag

◆ gidTag

Tag moab::GeomTopoTool::gidTag
private

◆ impl_compl_handle

EntityHandle moab::GeomTopoTool::impl_compl_handle
private

◆ m_rootSets_vector

bool moab::GeomTopoTool::m_rootSets_vector
private

◆ mapRootSets

std::map< EntityHandle, EntityHandle > moab::GeomTopoTool::mapRootSets
private

Definition at line 307 of file GeomTopoTool.hpp.

Referenced by get_root(), have_obb_tree(), remove_root(), and set_root_set().

◆ maxGlobalId

int moab::GeomTopoTool::maxGlobalId[5]
private

Definition at line 299 of file GeomTopoTool.hpp.

Referenced by add_geo_set(), GeomTopoTool(), and separate_by_dimension().

◆ mdbImpl

◆ modelSet

◆ nameTag

Tag moab::GeomTopoTool::nameTag
private

◆ obbGsetTag

Tag moab::GeomTopoTool::obbGsetTag
private

Definition at line 291 of file GeomTopoTool.hpp.

Referenced by delete_obb_tree(), GeomTopoTool(), remove_root(), and set_root_set().

◆ obbRootTag

Tag moab::GeomTopoTool::obbRootTag
private

◆ obbTree

OrientedBoxTreeTool* moab::GeomTopoTool::obbTree
private

◆ oneVolRootSet

EntityHandle moab::GeomTopoTool::oneVolRootSet
private

Definition at line 308 of file GeomTopoTool.hpp.

Referenced by construct_obb_trees(), and get_one_vol_root().

◆ rootSets

std::vector< EntityHandle > moab::GeomTopoTool::rootSets
private

◆ sense2Tag

◆ senseNEntsTag

Tag moab::GeomTopoTool::senseNEntsTag
private

Definition at line 286 of file GeomTopoTool.hpp.

Referenced by check_edge_sense_tags(), get_senses(), and set_sense().

◆ senseNSensesTag

Tag moab::GeomTopoTool::senseNSensesTag
private

Definition at line 286 of file GeomTopoTool.hpp.

Referenced by check_edge_sense_tags(), get_senses(), and set_sense().

◆ setOffset

EntityHandle moab::GeomTopoTool::setOffset
private

◆ updated

bool moab::GeomTopoTool::updated
private

Definition at line 300 of file GeomTopoTool.hpp.

Referenced by add_geo_set().


The documentation for this class was generated from the following files: