Mesh Oriented datABase  (version 5.5.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.

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 1950 of file GeomTopoTool.cpp.

1951 {
1952  ErrorCode rval;
1953 
1954  Range child_surfaces, triangles, vertices;
1955  double coord[3]; // coord[0] = x, etc.
1956  int result; // point in vol result; 0=F, 1=T
1957 
1958  // find coordinates of any point on surface of A
1959  // get surface corresponding to volume, then get the triangles
1960  child_surfaces = get_ct_children_by_dimension( volume_A, 2 );
1961  rval = mdbImpl->get_entities_by_type( *child_surfaces.begin(), MBTRI, triangles );MB_CHK_ERR( rval );
1962 
1963  // now get 1st triangle vertices
1964  rval = mdbImpl->get_connectivity( &( *triangles.begin() ), 1, vertices );MB_CHK_ERR( rval );
1965 
1966  // now get coordinates of first vertex
1967  rval = mdbImpl->get_coords( &( *vertices.begin() ), 1, &( coord[0] ) );MB_CHK_ERR( rval );
1968 
1969  // if point on A is inside vol B, return T; o.w. return F
1970  rval = GQT->point_in_volume( volume_B, coord, result );MB_CHK_SET_ERR( rval, "Failed to complete point in volume query." );
1971 
1972  return ( result != 0 );
1973 }

References moab::Range::begin(), ErrorCode, 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 1180 of file GeomTopoTool.cpp.

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

1168 {
1169  ErrorCode rval;
1170  unsigned flags = MB_TAG_VARLEN | MB_TAG_SPARSE;
1171  if( create ) flags |= MB_TAG_CREAT;
1172  if( !senseNEntsTag )
1173  {
1174  rval = mdbImpl->tag_get_handle( GEOM_SENSE_N_ENTS_TAG_NAME, 0, MB_TYPE_HANDLE, senseNEntsTag, flags );MB_CHK_SET_ERR( rval, "Failed to get the curve to surface entity tag handle" );
1175  rval = mdbImpl->tag_get_handle( GEOM_SENSE_N_SENSES_TAG_NAME, 0, MB_TYPE_INTEGER, senseNSensesTag, flags );MB_CHK_SET_ERR( rval, "Failed to get the curve to surface sense tag handle" );
1176  }
1177  return MB_SUCCESS;
1178 }

References ErrorCode, 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 1154 of file GeomTopoTool.cpp.

1155 {
1156  ErrorCode rval;
1157  unsigned flags = create ? MB_TAG_SPARSE | MB_TAG_CREAT | MB_TAG_ANY : MB_TAG_SPARSE | MB_TAG_ANY;
1158  if( !sense2Tag )
1159  {
1160  EntityHandle def_val[2] = { 0, 0 };
1161  rval = mdbImpl->tag_get_handle( GEOM_SENSE_2_TAG_NAME, 2, MB_TYPE_HANDLE, sense2Tag, flags, def_val );MB_CHK_SET_ERR( rval, "Could not get/create the sense2Tag" );
1162  }
1163  return MB_SUCCESS;
1164 }

References ErrorCode, 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 1128 of file GeomTopoTool.cpp.

1129 {
1130  ErrorCode rval;
1131  unsigned flags = create ? MB_TAG_DENSE | MB_TAG_CREAT : MB_TAG_DENSE;
1132  if( !geomTag )
1133  {
1134  // get any kind of tag that already exists
1135  rval = mdbImpl->tag_get_handle( GEOM_DIMENSION_TAG_NAME, 1, MB_TYPE_INTEGER, geomTag, flags );MB_CHK_SET_ERR( rval, "Could not get/create the geometry dimension tag" );
1136  }
1137  return MB_SUCCESS;
1138 }

References ErrorCode, 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 1140 of file GeomTopoTool.cpp.

1141 {
1142  ErrorCode rval;
1143  unsigned flags = create ? MB_TAG_DENSE | MB_TAG_CREAT : MB_TAG_DENSE;
1144  if( !gidTag )
1145  {
1146  // get any kind of tag that already exists
1147  rval = mdbImpl->tag_get_handle( GLOBAL_ID_TAG_NAME, 1, MB_TYPE_INTEGER, gidTag, flags );MB_CHK_SET_ERR( rval, "Could not get/create the global id tag" );
1148  }
1149  return MB_SUCCESS;
1150 }

References ErrorCode, 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 1733 of file GeomTopoTool.cpp.

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

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 413 of file GeomTopoTool.cpp.

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

References moab::Interface::add_entities(), moab::Range::begin(), moab::OrientedBoxTreeTool::build(), dim, moab::Range::empty(), moab::Range::end(), ErrorCode, geomTag, moab::Interface::get_child_meshsets(), moab::Interface::get_entities_by_dimension(), get_root(), 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 566 of file GeomTopoTool.cpp.

567 {
568  ErrorCode rval;
569  EntityHandle root;
570 
571  // get all surfaces and volumes
572  Range surfs, vols, vol_trees;
573  rval = get_gsets_by_dimension( 2, surfs );MB_CHK_SET_ERR( rval, "Could not get surface sets" );
574  rval = get_gsets_by_dimension( 3, vols );MB_CHK_SET_ERR( rval, "Could not get volume sets" );
575 
576  // for surface
577  Range one_vol_trees;
578  for( Range::iterator i = surfs.begin(); i != surfs.end(); ++i )
579  {
580  rval = construct_obb_tree( *i );MB_CHK_SET_ERR( rval, "Failed to construct obb tree for surface" );
581  // get the root set of this volume
582  rval = get_root( *i, root );MB_CHK_SET_ERR( rval, "Failed to get obb tree root for surface" );
583  // add to the Range of volume root sets
584  one_vol_trees.insert( root );
585  }
586 
587  // for volumes
588  for( Range::iterator i = vols.begin(); i != vols.end(); ++i )
589  {
590  // create tree for this volume
591  rval = construct_obb_tree( *i );MB_CHK_SET_ERR( rval, "Failed to construct obb tree for volume" );
592  }
593 
594  // build OBB tree for volume
595  if( make_one_vol )
596  {
597  rval = obbTree->join_trees( one_vol_trees, root );MB_CHK_SET_ERR( rval, "Failed to join surface trees into one volume" );
598  oneVolRootSet = root;
599  }
600 
601  return rval;
602 }

References moab::Range::begin(), construct_obb_tree(), moab::Range::end(), ErrorCode, get_gsets_by_dimension(), get_root(), moab::Range::insert(), moab::OrientedBoxTreeTool::join_trees(), MB_CHK_SET_ERR, 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 764 of file GeomTopoTool.cpp.

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

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 395 of file GeomTopoTool.cpp.

396 {
397 
398  ErrorCode rval;
399 
400  for( Range::iterator rit = geomRanges[3].begin(); rit != geomRanges[3].end(); ++rit )
401  {
402  EntityHandle root;
403  rval = mdbImpl->tag_get_data( obbRootTag, &( *rit ), 1, &root );
404  if( MB_SUCCESS == rval )
405  {
406  rval = delete_obb_tree( *rit, false );MB_CHK_SET_ERR( rval, "Failed to delete obb tree" );
407  }
408  }
409 
410  return MB_SUCCESS;
411 }

References delete_obb_tree(), moab::Range::end(), ErrorCode, geomRanges, 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 318 of file GeomTopoTool.cpp.

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

References moab::Range::begin(), child, moab::Interface::delete_entities(), dim, 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  {
101  result = mdbImpl->tag_get_handle( GEOM_DIMENSION_TAG_NAME, 1, MB_TYPE_INTEGER, geomTag );MB_CHK_SET_ERR( result, "Failed to get the geometry dimension tag" );
102  }
103 
104  // check if the geo set belongs to this model
105  if( modelSet )
106  {
107  if( !mdbImpl->contains_entities( modelSet, &this_set, 1 ) )
108  {
109  // this g set does not belong to the current model
110  return -1;
111  }
112  }
113  // get the data for those tags
114  int dim;
115  result = mdbImpl->tag_get_data( geomTag, &this_set, 1, &dim );
116  if( MB_SUCCESS != result )
117  return -1;
118  else
119  return dim;
120 }

References moab::Interface::contains_entities(), dim, 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 1460 of file GeomTopoTool.cpp.

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

References moab::Interface::add_entities(), moab::Interface::add_parent_child(), check_edge_sense_tags(), check_face_sense_tag(), children, moab::Interface::create_meshset(), dim, moab::Range::end(), ErrorCode, 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 149 of file GeomTopoTool.cpp.

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

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  ErrorCode rval;
233  // get all sets with this tag
234  Range geom_sets;
235 
236  if( 0 == geomTag )
237  {
238  rval = mdbImpl->tag_get_handle( GEOM_DIMENSION_TAG_NAME, 1, MB_TYPE_INTEGER, geomTag );MB_CHK_SET_ERR( rval, "Failed to get geom dimension tag handle" );
239  }
240 
241  rval = mdbImpl->get_entities_by_type_and_tag( modelSet, MBENTITYSET, &geomTag, NULL, 1, geom_sets );MB_CHK_SET_ERR( rval, "Failed to get the geometry entities" );
242 
243  rval = separate_by_dimension( geom_sets );MB_CHK_SET_ERR( rval, "Failed to separate geometry sets by dimension" );
244 
245  if( ranges )
246  {
247  for( int i = 0; i < 5; i++ )
248  {
249  ranges[i] = geomRanges[i];
250  }
251  }
252 
253  return MB_SUCCESS;
254 }

References ErrorCode, 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 1673 of file GeomTopoTool.cpp.

1674 {
1675 
1676  ErrorCode rval;
1677  rval = mdbImpl->create_meshset( MESHSET_SET, implicit_complement_set );MB_CHK_SET_ERR( rval, "Failed to create mesh set for implicit complement" );
1678 
1679  // make sure the sense2Tag is set
1680  if( !sense2Tag )
1681  {
1682  check_face_sense_tag( true );
1683  }
1684 
1685  // get all geometric surface sets
1686  Range surfs;
1687  rval = get_gsets_by_dimension( 2, surfs );MB_CHK_SET_ERR( rval, "Could not get surface sets" );
1688 
1689  // search through all surfaces
1690  std::vector< EntityHandle > parent_vols;
1691  for( Range::iterator surf_i = surfs.begin(); surf_i != surfs.end(); ++surf_i )
1692  {
1693 
1694  parent_vols.clear();
1695  // get parents of each surface
1696  rval = mdbImpl->get_parent_meshsets( *surf_i, parent_vols );MB_CHK_SET_ERR( rval, "Failed to get volume meshsets" );
1697 
1698  // if only one parent, get the OBB root for this surface
1699  if( parent_vols.size() == 1 )
1700  {
1701 
1702  // add this surf to the topology of the implicit complement volume
1703  rval = mdbImpl->add_parent_child( implicit_complement_set, *surf_i );MB_CHK_SET_ERR( rval, "Could not add surface to implicit complement set" );
1704 
1705  // get the surface sense wrt original volume
1706  EntityHandle sense_data[2] = { 0, 0 };
1707  rval = get_surface_senses( *surf_i, sense_data[0], sense_data[1] );MB_CHK_SET_ERR( rval, "Could not get surface sense data" );
1708 
1709  // set the surface sense wrt implicit complement volume
1710  if( 0 == sense_data[0] && 0 == sense_data[1] )
1711  MB_SET_ERR( MB_FAILURE, "No sense data for current surface" );
1712  if( 0 == sense_data[0] )
1713  sense_data[0] = implicit_complement_set;
1714  else if( 0 == sense_data[1] )
1715  sense_data[1] = implicit_complement_set;
1716  else
1717  MB_SET_ERR( MB_FAILURE, "Could not insert implicit complement into surface sense data" );
1718 
1719  // set the new sense data for this surface
1720  rval = set_surface_senses( *surf_i, sense_data[0], sense_data[1] );MB_CHK_SET_ERR( rval, "Failed to set sense tag data" );
1721  }
1722  } // end surface loop
1723 
1724  return MB_SUCCESS;
1725 }

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

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(), ErrorCode, 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 1898 of file GeomTopoTool.cpp.

1899 {
1900  double center[3], axis1[3], axis2[3], axis3[3];
1901 
1902  // get center point and vectors to OBB faces
1903  ErrorCode rval = get_obb( volume, center, axis1, axis2, axis3 );MB_CHK_SET_ERR( rval, "Failed to get the oriented bounding box of the volume" );
1904 
1905  // compute min and max vertices
1906  for( int i = 0; i < 3; i++ )
1907  {
1908  double sum = fabs( axis1[i] ) + fabs( axis2[i] ) + fabs( axis3[i] );
1909  minPt[i] = center[i] - sum;
1910  maxPt[i] = center[i] + sum;
1911  }
1912  return MB_SUCCESS;
1913 }

References center(), ErrorCode, 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 1929 of file GeomTopoTool.cpp.

1930 {
1931  Range all_children, desired_children;
1932  Range::iterator it;
1933  int actual_dimension;
1934 
1935  desired_children.clear();
1936  all_children.clear();
1937  mdbImpl->get_child_meshsets( parent, all_children );
1938 
1939  for( it = all_children.begin(); it != all_children.end(); ++it )
1940  {
1941  mdbImpl->tag_get_data( geomTag, &( *it ), 1, &actual_dimension );
1942  if( actual_dimension == desired_dimension ) desired_children.insert( *it );
1943  }
1944 
1945  return desired_children;
1946 }

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 256 of file GeomTopoTool.cpp.

257 {
258  ErrorCode rval;
259 
260  const int val = dim;
261  const void* const dim_val[] = { &val };
262  rval = mdbImpl->get_entities_by_type_and_tag( modelSet, MBENTITYSET, &geomTag, dim_val, 1, gset );MB_CHK_SET_ERR( rval, "Failed to get entity set by type and tag" );
263 
264  return MB_SUCCESS;
265 }

References dim, ErrorCode, 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 1606 of file GeomTopoTool.cpp.

1607 {
1608  if( impl_compl_handle )
1609  {
1610  implicit_complement = impl_compl_handle;
1611  return MB_SUCCESS;
1612  }
1613  else
1614  {
1615  return MB_ENTITY_NOT_FOUND;
1616  }
1617 }

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 1915 of file GeomTopoTool.cpp.

1920 {
1921  // find EntityHandle node_set for use in box
1922  EntityHandle root;
1923  ErrorCode rval = get_root( volume, root );MB_CHK_SET_ERR( rval, "Failed to get volume's obb tree root" );
1924 
1925  // call box to get center and vectors to faces
1926  return obbTree->box( root, center, axis1, axis2, axis3 );
1927 }

References moab::OrientedBoxTreeTool::box(), center(), ErrorCode, 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 905 of file GeomTopoTool.cpp.

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

References check_edge_sense_tags(), check_face_sense_tag(), dimension(), ErrorCode, get_senses(), 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 1017 of file GeomTopoTool.cpp.

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

References check_edge_sense_tags(), check_face_sense_tag(), moab::Interface::contains_entities(), dimension(), ErrorCode, 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 950 of file GeomTopoTool.cpp.

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

References dimension(), ErrorCode, 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 997 of file GeomTopoTool.cpp.

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

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 122 of file GeomTopoTool.cpp.

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

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

Referenced by 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 1890 of file GeomTopoTool.cpp.

1891 {
1892  return rootSets.size() != 0 || mapRootSets.size() != 0;
1893 }

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 1975 of file GeomTopoTool.cpp.

1976 {
1977  ErrorCode rval;
1978 
1979  bool inserted = false;
1980  EntityHandle current_volume = volume; // volume to be inserted
1981  EntityHandle tree_volume = ct_root; // volume already existing in the tree
1982  EntityHandle parent = ct_root;
1983  Range child_volumes;
1984 
1985  // while not inserted in tree
1986  while( !inserted )
1987  {
1988  // if current volume is insde of tree volume-- always true if tree volume
1989  // is the root of the tree
1990  if( tree_volume == ct_root || ( tree_volume != ct_root && A_is_in_B( current_volume, tree_volume, GQT ) ) )
1991  {
1992 
1993  parent = tree_volume;
1994 
1995  // if tree_volume has children then we must test them,
1996  // (tree_volume will change)
1997  child_volumes = get_ct_children_by_dimension( tree_volume, 3 );
1998  if( child_volumes.size() > 0 ) tree_volume = child_volumes.pop_front();
1999  // otherwise current_volume is the only child of the tree volume
2000  else
2001  {
2002  rval = mdbImpl->add_parent_child( parent, current_volume );MB_CHK_SET_ERR( rval, "Failed to add parent-child relationship." );
2003 
2004  inserted = true;
2005  }
2006  // if current volume is not in the tree volume, the converse may be true
2007  }
2008  else
2009  {
2010  // if the tree volume is inside the current volume
2011  if( A_is_in_B( tree_volume, current_volume, GQT ) )
2012  {
2013  // reverse their parentage
2014  rval = mdbImpl->remove_parent_child( parent, tree_volume );MB_CHK_SET_ERR( rval, "Failed to remove parent-child relationship." );
2015  rval = mdbImpl->add_parent_child( current_volume, tree_volume );MB_CHK_SET_ERR( rval, "Failed to add parent-child relationship." );
2016  }
2017 
2018  if( child_volumes.size() == 0 )
2019  {
2020  rval = mdbImpl->add_parent_child( parent, current_volume );MB_CHK_SET_ERR( rval, "Failed to add parent-child relationship." );
2021  inserted = true;
2022  }
2023  else
2024  tree_volume = child_volumes.pop_front();
2025  }
2026  }
2027  return MB_SUCCESS;
2028 }

References A_is_in_B(), moab::Interface::add_parent_child(), ErrorCode, 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 306 of file GeomTopoTool.cpp.

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

References moab::Range::end(), ErrorCode, 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 1108 of file GeomTopoTool.cpp.

1109 {
1110  std::vector< EntityHandle > parents;
1111  ErrorCode rval = mdbImpl->get_parent_meshsets( surface, parents );
1112 
1113  if( MB_SUCCESS == rval )
1114  {
1115  if( parents.size() != 2 )
1116  rval = MB_FAILURE;
1117  else if( parents.front() == old_volume )
1118  new_volume = parents.back();
1119  else if( parents.back() == old_volume )
1120  new_volume = parents.front();
1121  else
1122  rval = MB_FAILURE;
1123  }
1124 
1125  return rval;
1126 }

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 dim, 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 168 of file GeomTopoTool.cpp.

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

References moab::Range::begin(), ErrorCode, 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 523 of file GeomTopoTool.cpp.

524 {
525 
526  // Find the root of the vol or surf
527  ErrorCode rval;
528  EntityHandle root;
529  rval = mdbImpl->tag_get_data( obbRootTag, &( vol_or_surf ), 1, &root );MB_CHK_SET_ERR( rval, "Failed to get obb root tag" );
530 
531  // If the ent is a vol, remove its root from obbtreetool
532  int dim;
533  rval = mdbImpl->tag_get_data( geomTag, &vol_or_surf, 1, &dim );MB_CHK_SET_ERR( rval, "Failed to get dimension" );
534  if( dim == 3 )
535  {
536  rval = obbTree->remove_root( root );MB_CHK_SET_ERR( rval, "Failed to remove root from obbTreeTool" );
537  }
538 
539  // Delete the obbGsetTag data from the root
540  rval = mdbImpl->tag_delete_data( obbGsetTag, &root, 1 );MB_CHK_SET_ERR( rval, "Failed to delete obb root tag" );
541 
542  // Delete the obbRootTag data from the vol or surf
543  rval = mdbImpl->tag_delete_data( obbRootTag, &vol_or_surf, 1 );MB_CHK_SET_ERR( rval, "Failed to delete obb root tag" );
544 
545  // Remove the root from set of all roots
546  if( m_rootSets_vector )
547  {
548  unsigned int index = vol_or_surf - setOffset;
549  if( index < rootSets.size() )
550  {
551  rootSets[index] = 0;
552  }
553  else
554  {
555  return MB_INDEX_OUT_OF_RANGE;
556  }
557  }
558  else
559  {
560  mapRootSets[vol_or_surf] = 0;
561  }
562 
563  return MB_SUCCESS;
564 }

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

References moab::Range::back(), ErrorCode, 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 206 of file GeomTopoTool.cpp.

207 {
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 dim, 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 605 of file GeomTopoTool.cpp.

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

References moab::Interface::add_parent_child(), moab::Range::begin(), moab::Range::clear(), dim, 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 2030 of file GeomTopoTool.cpp.

2031 {
2032 
2033  ErrorCode rval;
2034  // local var will go out of scope if errors appear, no need to free it also
2035  GeomQueryTool GQT( this );
2036  std::map< EntityHandle, EntityHandle > volume_surface; // map of volume
2037  // to its surface
2038 
2039  EntityHandle ct_root;
2040  // create root meshset-- this will be top of tree
2041  std::string meshset_name = "build_hierarchy_root";
2042  rval = mdbImpl->create_meshset( MESHSET_SET, ct_root );MB_CHK_ERR( rval );
2043  rval = mdbImpl->tag_set_data( nameTag, &ct_root, 1, meshset_name.c_str() );MB_CHK_ERR( rval );
2044 
2045  for( Range::iterator vol = flat_volumes.begin(); vol != flat_volumes.end(); vol++ )
2046  {
2047  // get the surface corresponding to each volume
2048  // at this point, each volume meshset only has one 'child' surface
2049  // which exactly corresponds to that volume
2050  Range child_surfaces = get_ct_children_by_dimension( *vol, 2 );
2051  volume_surface[*vol] = *child_surfaces.begin();
2052 
2053  rval = insert_in_tree( ct_root, *vol, &GQT );MB_CHK_SET_ERR( rval, "Failed to insert volume into tree." );
2054  }
2055 
2056  // for each original volume, get its child volumes
2057  for( Range::iterator parent_it = flat_volumes.begin(); parent_it != flat_volumes.end(); parent_it++ )
2058  {
2059  Range volume_children = get_ct_children_by_dimension( *parent_it, 3 );
2060 
2061  if( volume_children.size() != 0 )
2062  {
2063  // loop over all of original volume's child volumes
2064  for( Range::iterator child_it = volume_children.begin(); child_it != volume_children.end(); ++child_it )
2065  {
2066  // set the sense of the surface mapped to the child volume to REVERSE
2067  // wrt the parent volume
2068  rval = set_sense( volume_surface[*child_it], *parent_it, SENSE_REVERSE );MB_CHK_SET_ERR( rval, "Failed to set sense." );
2069 
2070  // add the child volume's surface as a child of the original volume
2071  // and delete the child volume as a child of original volume
2072  rval = mdbImpl->add_parent_child( *parent_it, volume_surface[*child_it] );MB_CHK_SET_ERR( rval, "Failed to add parent-child relationship." );
2073  rval = mdbImpl->remove_parent_child( *parent_it, *child_it );MB_CHK_SET_ERR( rval, "Failed to remove parent-child relationship." );
2074  }
2075  }
2076  }
2077 
2078  return MB_SUCCESS;
2079 }

References moab::Interface::add_parent_child(), moab::Range::begin(), moab::Interface::create_meshset(), moab::Range::end(), ErrorCode, 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 712 of file GeomTopoTool.cpp.

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

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 504 of file GeomTopoTool.cpp.

505 {
506 
507  // Tag the vol or surf with its obb root (obbRootTag)
508  ErrorCode rval;
509  rval = mdbImpl->tag_set_data( obbRootTag, &vol_or_surf, 1, &root );MB_CHK_SET_ERR( rval, "Failed to set the obb root tag" );
510 
511  // Tag obb root with corresponding gset (obbGsetTag)
512  rval = mdbImpl->tag_set_data( obbGsetTag, &root, 1, &vol_or_surf );MB_CHK_SET_ERR( rval, "Failed to set the obb gset tag" );
513 
514  // Add to the set of all roots
515  if( m_rootSets_vector )
516  rootSets[vol_or_surf - setOffset] = root;
517  else
518  mapRootSets[vol_or_surf] = root;
519 
520  return MB_SUCCESS;
521 }

References ErrorCode, 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 810 of file GeomTopoTool.cpp.

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

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::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(), moab::ReadCGM::store_surface_senses(), 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 1095 of file GeomTopoTool.cpp.

1098 {
1099  // not efficient, and maybe wrong
1100  for( unsigned int i = 0; i < wrt_entities.size(); i++ )
1101  {
1102  ErrorCode rval = set_sense( entity, wrt_entities[i], senses[i] );MB_CHK_SET_ERR( rval, "Failed to set the sense" );
1103  }
1104 
1105  return MB_SUCCESS;
1106 }

References ErrorCode, MB_CHK_SET_ERR, MB_SUCCESS, and set_sense().

Referenced by duplicate_model(), and moab::ReadCGM::store_curve_senses().

◆ 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 975 of file GeomTopoTool.cpp.

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

References dimension(), ErrorCode, 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 1619 of file GeomTopoTool.cpp.

1620 {
1621 
1622  // if the implicit complement is already setup,
1623  // we're done
1624  if( impl_compl_handle != 0 )
1625  {
1626  std::cout << "IPC already exists!" << std::endl;
1627  return MB_SUCCESS;
1628  }
1629 
1630  // if not, then query for a set with it's name
1631  Range entities;
1632  const void* const tagdata[] = { IMPLICIT_COMPLEMENT_NAME };
1634  // query error
1635  MB_CHK_SET_ERR( rval, "Unable to query for implicit complement" );
1636 
1637  // if we found exactly one, set it as the implicit complement
1638  if( entities.size() == 1 )
1639  {
1640  impl_compl_handle = entities.front();
1641  return MB_SUCCESS;
1642  }
1643 
1644  // found too many
1645  if( entities.size() > 1 ) MB_CHK_SET_ERR( MB_MULTIPLE_ENTITIES_FOUND, "Too many implicit complement sets" );
1646 
1647  // found none
1648  if( entities.empty() )
1649  {
1650  // create implicit complement if requested
1651  rval = generate_implicit_complement( impl_compl_handle );MB_CHK_SET_ERR( rval, "Could not create implicit complement" );
1652 
1653  rval = mdbImpl->tag_set_data( nameTag, &impl_compl_handle, 1, &IMPLICIT_COMPLEMENT_NAME );MB_CHK_SET_ERR( rval, "Could not set the name tag for the implicit complement" );
1654 
1655  rval = add_geo_set( impl_compl_handle, 3 );MB_CHK_SET_ERR( rval, "Failed to add implicit complement to model" );
1656 
1657  // assign category tag - this is presumably for consistency so that the
1658  // implicit complement has all the appearance of being the same as any
1659  // other volume
1660  Tag category_tag;
1662  MB_TAG_SPARSE | MB_TAG_CREAT );MB_CHK_SET_ERR( rval, "Could not get the category tag" );
1663 
1664  static const char volume_category[CATEGORY_TAG_SIZE] = "Volume\0";
1665  rval = mdbImpl->tag_set_data( category_tag, &impl_compl_handle, 1, volume_category );MB_CHK_SET_ERR( rval, "Could not set the category tag for the implicit complement" );
1666 
1667  return MB_SUCCESS;
1668  }
1669 
1670  return MB_FAILURE;
1671 }

References add_geo_set(), CATEGORY_TAG_NAME, CATEGORY_TAG_SIZE, entities, ErrorCode, 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::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: