Loading [MathJax]/extensions/tex2jax.js
Mesh Oriented datABase  (version 5.5.1)
An array-based unstructured mesh library
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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 63  gidTag = mdbImpl->globalId_tag(); 64  65  rval = 66  mdbImpl->tag_get_handle( NAME_TAG_NAME, NAME_TAG_SIZE, MB_TYPE_OPAQUE, nameTag, MB_TAG_CREAT | MB_TAG_SPARSE );MB_CHK_SET_ERR_CONT( rval, "Error: Failed to create name tag" ); 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 73  impl_compl_handle = 0; 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  { 1199  gidTag = mdbImpl->globalId_tag(); 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 id " << global_id(eh) << " (handle: " << eh << ")" << "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(), global_id(), moab::Range::insert(), is_owned_set(), moab::OrientedBoxTreeTool::join_trees(), m_rootSets_vector, MB_CHK_SET_ERR, MB_INDEX_OUT_OF_RANGE, MB_SET_ERR, MB_SUCCESS, MBENTITYSET, mdbImpl, obbTree, resize_rootSets(), rootSets, set_root_set(), setOffset, moab::Interface::tag_get_data(), and moab::Interface::type_from_handle().

Referenced by construct_obb_trees().

◆ construct_obb_trees()

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

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

Definition at line 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  { 1472  gidTag = mdbImpl->globalId_tag(); 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  1406  EntityHandle edge; 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 1415  EntityHandle vertex; 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()

ErrorCode moab::GeomTopoTool::get_root ( EntityHandle  vol_or_surf,
EntityHandle root 
)
inline

Get the root of the obbtree for a given entity.

Definition at line 359 of file GeomTopoTool.hpp.

360 { 361  if( m_rootSets_vector ) 362  { 363  unsigned int index = vol_or_surf - setOffset; 364  root = ( index < rootSets.size() ? rootSets[index] : 0 ); 365  } 366  else 367  root = mapRootSets[vol_or_surf]; 368  return ( root ? MB_SUCCESS : MB_INDEX_OUT_OF_RANGE ); 369 }

References m_rootSets_vector, mapRootSets, MB_INDEX_OUT_OF_RANGE, MB_SUCCESS, rootSets, and setOffset.

Referenced by moab::GeomQueryTool::closest_to_location(), construct_obb_tree(), construct_obb_trees(), delete_obb_tree(), moab::GeomQueryTool::get_normal(), get_obb(), moab::FBEngine::getEntBoundBox(), moab::FBEngine::getEntClosestPt(), moab::FBEngine::getEntNrmlXYZ(), moab::FBEngine::getPntRayIntsct(), obbstat_write(), obbvis_create(), moab::GeomQueryTool::point_in_volume(), moab::GeomQueryTool::ray_fire(), moab::SmoothFace::SmoothFace(), moab::FBEngine::split_surface_with_direction(), and moab::GeomQueryTool::test_volume_boundary().

◆ 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  { 127  gidTag = mdbImpl->globalId_tag(); 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 construct_obb_tree(), moab::FBEngine::create_new_gedge(), obbstat_write(), moab::FBEngine::split_bedge_at_new_mesh_node(), and moab::FBEngine::split_edge_at_mesh_node().

◆ have_obb_tree()

bool moab::GeomTopoTool::have_obb_tree ( )

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

Definition at line 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  209  if( m_rootSets_vector ) resize_rootSets(); 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  { 742  gidTag = mdbImpl->globalId_tag(); 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(), 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().

◆ 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 }; 1633  ErrorCode rval = mdbImpl->get_entities_by_type_and_tag( modelSet, MBENTITYSET, &nameTag, tagdata, 1, entities ); 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; 1661  rval = mdbImpl->tag_get_handle( CATEGORY_TAG_NAME, CATEGORY_TAG_SIZE, MB_TYPE_OPAQUE, 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: