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

Tools for constructing and working with mesh duals (both tet- and hex-based, though some functions may not make sense for tet duals) More...

#include <DualTool.hpp>

+ Collaboration diagram for moab::DualTool:

Classes

class  GraphicsPoint
 struct for storing a graphics pt More...
 

Public Member Functions

 DualTool (Interface *impl)
 
 ~DualTool ()
 
ErrorCode construct_dual (EntityHandle *entities, const int num_entities)
 construct the dual entities for the entire mesh More...
 
ErrorCode construct_hex_dual (EntityHandle *entities, const int num_entities)
 construct the dual entities for a hex mesh, including dual surfaces & curves More...
 
ErrorCode construct_hex_dual (Range &entities)
 construct the dual entities for a hex mesh, including dual surfaces & curves More...
 
ErrorCode get_dual_entities (const int dim, EntityHandle *entities, const int num_entities, Range &dual_ents)
 get the dual entities; if non-null, only dual of entities passed in are returned More...
 
ErrorCode get_dual_entities (const int dim, EntityHandle *entities, const int num_entities, std::vector< EntityHandle > &dual_ents)
 get the dual entities; if non-null, only dual of entities passed in are returned More...
 
EntityHandle get_dual_entity (const EntityHandle this_ent) const
 return the corresponding dual entity More...
 
EntityHandle get_extra_dual_entity (const EntityHandle this_ent)
 return the corresponding extra dual entity More...
 
ErrorCode get_graphics_points (EntityHandle dual_ent, std::vector< int > &npts, std::vector< GraphicsPoint > &gpoints)
 get the graphics points for single entity (dual_ent CAN'T be a set); returns multiple facets, each with npts[i] points More...
 
ErrorCode get_graphics_points (const Range &in_range, std::vector< GraphicsPoint > &gpoints, const bool assign_ids=false, const int start_id=0)
 get the graphics points for a range of entities or sets (if set, the entities in those sets); optionally reset ids on points More...
 
EntityHandle next_loop_vertex (const EntityHandle last_v, const EntityHandle this_v, const EntityHandle dual_surf)
 given a last_v (possibly zero) and this_v, find the next loop vertex on this dual surface More...
 
Tag dualSurface_tag () const
 get/set the tag for dual surfaces More...
 
ErrorCode dualSurface_tag (const Tag tag)
 get/set the tag for dual surfaces More...
 
Tag dualCurve_tag () const
 get/set the tag for dual curves More...
 
ErrorCode dualCurve_tag (const Tag tag)
 get/set the tag for dual curves More...
 
Tag isDualCell_tag () const
 get/set the tag for dual cells More...
 
ErrorCode isDualCell_tag (const Tag tag)
 get/set the tag for dual cells More...
 
Tag dualEntity_tag () const
 get/set the tag for dual entities More...
 
ErrorCode dualEntity_tag (const Tag tag)
 get/set the tag for dual entities More...
 
Tag extraDualEntity_tag () const
 get/set the tag for dual entities More...
 
ErrorCode extraDualEntity_tag (const Tag tag)
 get/set the tag for dual entities More...
 
Tag dualGraphicsPoint_tag () const
 get/set the tag for dual entities More...
 
ErrorCode dualGraphicsPoint_tag (const Tag tag)
 get/set the tag for dual entities More...
 
Tag globalId_tag () const
 get/set the global id tag More...
 
ErrorCode globalId_tag (const Tag tag)
 get/set the tag for dual entities More...
 
EntityHandle get_dual_hyperplane (const EntityHandle ncell)
 given an entity, return any dual surface or curve it's in More...
 
bool is_blind (const EntityHandle chord)
 returns true if first & last vertices are dual to hexes (not faces) More...
 
ErrorCode set_dual_surface_or_curve (EntityHandle entity, const EntityHandle dual_hyperplane, const int dimension)
 set the dual surface or curve for an entity More...
 
ErrorCode atomic_pillow (EntityHandle odedge, EntityHandle &quad1, EntityHandle &quad2)
 effect atomic pillow operation More...
 
ErrorCode rev_atomic_pillow (EntityHandle pillow, Range &chords)
 effect reverse atomic pillow operation More...
 
ErrorCode face_shrink (EntityHandle odedge)
 effect face shrink operation More...
 
ErrorCode rev_face_shrink (EntityHandle edge)
 effect reverse atomic pillow operation More...
 
ErrorCode face_open_collapse (EntityHandle ocl, EntityHandle ocr)
 effect a face open-collapse operation More...
 
ErrorCode foc_get_ents (EntityHandle ocl, EntityHandle ocr, EntityHandle *quads, EntityHandle *split_edges, EntityHandle *split_nodes, Range &hexes, EntityHandle *other_edges, EntityHandle *other_nodes)
 given the two 1-cells involved in the foc, get entities associated with the quads being opened/collapsed; see implementation for more details More...
 
ErrorCode get_opposite_verts (const EntityHandle middle_edge, const EntityHandle chord, EntityHandle *verts)
 given a 1-cell and a chord, return the neighboring vertices on the chord, in the same order as the 1-cell's vertices More...
 
ErrorCode get_dual_entities (const EntityHandle dual_ent, Range *dcells, Range *dedges, Range *dverts, Range *dverts_loop, Range *dedges_loop)
 given a dual surface or curve, return the 2-cells, 1-cells, 0-cells, and loop 0/1-cells, if requested; any of those range pointers can be NULL, in which case that range isn't returned More...
 
ErrorCode list_entities (const Range &entities) const
 
ErrorCode list_entities (const EntityHandle *entities, const int num_entities) const
 
ErrorCode delete_whole_dual ()
 delete all the dual data More...
 
ErrorCode check_dual_adjs ()
 check dual-primal adjacencies More...
 

Static Public Member Functions

static ErrorCode get_dual_hyperplanes (const Interface *impl, const int dim, Range &dual_ents)
 get the d-dimensional hyperplane sets; static 'cuz it's easy to do without an active dualtool More...
 

Static Public Attributes

static MOAB_EXPORT const char * DUAL_SURFACE_TAG_NAME = "DUAL_SURFACE"
 tag name for dual surfaces More...
 
static MOAB_EXPORT const char * DUAL_CURVE_TAG_NAME = "DUAL_CURVE"
 tag name for dual curves More...
 
static const char * IS_DUAL_CELL_TAG_NAME = "__IS_DUAL_CELL"
 tag name for dual cells More...
 
static const char * DUAL_ENTITY_TAG_NAME = "__DUAL_ENTITY"
 tag name for dual entitys More...
 
static const char * EXTRA_DUAL_ENTITY_TAG_NAME = "__EXTRA_DUAL_ENTITY"
 tag name for dual entitys More...
 
static const char * DUAL_GRAPHICS_POINT_TAG_NAME = "__DUAL_GRAPHICS_POINT"
 tag name for dual entitys More...
 

Private Types

enum  { GP_SIZE = 20 }
 static constant number of points bounding any cell More...
 

Private Member Functions

ErrorCode construct_dual_vertices (const Range &all_regions, Range &new_dual_ents)
 construct dual vertices for specified regions More...
 
ErrorCode construct_dual_edges (const Range &all_faces, Range &new_dual_ents)
 construct dual edges for specified faces More...
 
ErrorCode construct_dual_faces (const Range &all_edges, Range &new_dual_ents)
 construct dual faces for specified edges More...
 
ErrorCode construct_dual_cells (const Range &all_verts, Range &new_dual_ents)
 construct dual cells for specified vertices More...
 
ErrorCode construct_dual_hyperplanes (const int dim, EntityHandle *entities, const int num_entities)
 traverse dual faces of input dimension, constructing dual hyperplanes of them in sets as it goes More...
 
ErrorCode order_chord (EntityHandle chord_set)
 order 1cells on a chord More...
 
ErrorCode construct_new_hyperplane (const int dim, EntityHandle &new_hyperplane, int &id)
 make a new dual hyperplane with the specified id; if the id specified is -1, set the new one's id to the max found More...
 
ErrorCode traverse_hyperplane (const Tag hp_tag, EntityHandle &this_hp, EntityHandle this_ent)
 traverse the cells of a dual hyperplane, starting with this_ent (dimension of this_ent determines hyperplane dimension) simpler method for traversing hyperplane, using same basic algorithm but using MeshTopoUtil::get_bridge_adjacencies More...
 
ErrorCode construct_hp_parent_child ()
 connect dual surfaces with dual curves using parent/child connections More...
 
ErrorCode get_radial_dverts (const EntityHandle edge, std::vector< EntityHandle > &rad_verts, bool &bdy_edge)
 given an edge handle, return a list of dual vertices in radial order around the edge; also returns whether this edge is on the boundary More...
 
ErrorCode construct_dual_vertex (EntityHandle entity, EntityHandle &dual_ent, const bool extra=false, const bool add_graphics_pt=true)
 
ErrorCode add_graphics_point (EntityHandle entity, double *avg_pos=NULL)
 add a graphics point to an entity (on a tag) More...
 
ErrorCode get_cell_points (EntityHandle dual_ent, std::vector< int > &npts, std::vector< GraphicsPoint > &points)
 get points defining facets of a 2cell More...
 
bool check_1d_loop_edge (EntityHandle this_ent)
 if this_ent is an edge, is a dual entity, and has quads as its vertices' dual entities, return true, otherwise false More...
 
ErrorCode check_dual_equiv_edges (Range &dual_edges)
 go through potential dual equivalent edges (edges whose nodes define multiple edges), and add explicit adjacencies to corrent 2cells More...
 
ErrorCode delete_dual_entities (EntityHandle *entities, const int num_entities)
 delete a dual entity; updates primal to no longer point to it More...
 
ErrorCode delete_dual_entities (Range &entities)
 delete a range of dual entities; updates primal to no longer point to them More...
 
ErrorCode fs_check_quad_sense (EntityHandle hex0, EntityHandle quad0, std::vector< EntityHandle > *connects)
 check sense of connect arrays, and reverse/rotate if necessary More...
 
ErrorCode fs_get_quads (EntityHandle odedge, EntityHandle *quads, EntityHandle *hexes, std::vector< EntityHandle > *connects)
 get the three quads for a face shrink, the two hexes, and the connectivity of the three quads More...
 
ErrorCode fs_get_quad_loops (EntityHandle *hexes, std::vector< EntityHandle > *connects, std::vector< EntityHandle > *side_quads)
 get loops of quads around 2 hexes, ordered similarly to vertex loops More...
 
ErrorCode fsr_get_fourth_quad (std::vector< EntityHandle > *connects, std::vector< EntityHandle > *side_quads)
 given connectivity of first 3 quads for reverse face shrink, get fourth (outer 4 verts to be shared by two inner hexes) and quads around the side of the structure More...
 
ErrorCode foc_delete_dual (EntityHandle *split_quads, EntityHandle *split_edges, Range &hexes)
 function for deleting dual prior to foc operation; special because in many cases need to delete a sheet in preparation for merging onto another More...
 
ErrorCode split_pair_nonmanifold (EntityHandle *split_quads, EntityHandle *split_edges, EntityHandle *split_nodes, std::vector< EntityHandle > *star_dp1, std::vector< EntityHandle > *star_dp2, EntityHandle *other_edges, EntityHandle *other_nodes, EntityHandle *new_quads, EntityHandle *new_edges, EntityHandle *new_nodes)
 split a pair of quads and the edge(s) shared by them More...
 
ErrorCode foc_get_addl_ents (std::vector< EntityHandle > *star_dp1, std::vector< EntityHandle > *star_dp2, EntityHandle *split_edges, EntityHandle split_node, Range *addl_ents)
 for foc's splitting two shared edges, there might be additional entities connected to the split node that also have to be updated More...
 
ErrorCode foc_get_stars (EntityHandle *split_quads, EntityHandle *split_edges, std::vector< EntityHandle > *star_dp1, std::vector< EntityHandle > *star_dp2)
 given the split quads and edges, get the face and hex stars around the edge(s), separated into halves, each of which goes with the new or old entities after the split More...
 
void print_cell (EntityHandle cell)
 

Private Attributes

InterfacembImpl
 private copy of interface * More...
 
Tag dualCurveTag
 tags used for dual surfaces, curves, cells, entities More...
 
Tag dualSurfaceTag
 
Tag isDualCellTag
 
Tag dualEntityTag
 
Tag extraDualEntityTag
 
Tag dualGraphicsPointTag
 
Tag categoryTag
 
Tag globalIdTag
 
int maxHexId
 

Detailed Description

Tools for constructing and working with mesh duals (both tet- and hex-based, though some functions may not make sense for tet duals)

Authors
Tim Tautges
Date
2/04

Definition at line 33 of file DualTool.hpp.

Member Enumeration Documentation

◆ anonymous enum

anonymous enum
private

static constant number of points bounding any cell

Enumerator
GP_SIZE 

Definition at line 372 of file DualTool.hpp.

373  {
374  GP_SIZE = 20
375  };

Constructor & Destructor Documentation

◆ DualTool()

moab::DualTool::DualTool ( Interface impl)

Definition at line 68 of file DualTool.cpp.

68  : mbImpl( impl )
69 {
70  EntityHandle dum_handle = 0;
71  ErrorCode result;
72 
74  MB_TAG_SPARSE | MB_TAG_CREAT, &dum_handle );
75  assert( MB_SUCCESS == result );
76 
78  &dum_handle );
79  assert( MB_SUCCESS == result );
80 
81  unsigned int dummy = 0;
83  MB_TAG_SPARSE | MB_TAG_CREAT, &dummy );
84  assert( MB_SUCCESS == result );
85 
87  MB_TAG_DENSE | MB_TAG_CREAT, &dum_handle );
88  assert( MB_SUCCESS == result );
89 
91  MB_TAG_SPARSE | MB_TAG_CREAT, &dum_handle );
92  assert( MB_SUCCESS == result );
93 
94  static const char dum_name[CATEGORY_TAG_SIZE] = { 0 };
96  MB_TAG_SPARSE | MB_TAG_CREAT, dum_name );
97  assert( MB_SUCCESS == result );
98 
99  DualTool::GraphicsPoint dum_pt( 0.0, 0.0, 0.0, -1 );
100  result = mbImpl->tag_get_handle( DUAL_GRAPHICS_POINT_TAG_NAME, sizeof( DualTool::GraphicsPoint ), MB_TYPE_DOUBLE,
102  assert( MB_SUCCESS == result );
103 
105 
106  if( MB_SUCCESS == result )
107  {
108  } // empty statement to get rid of warning.
109 
110  maxHexId = -1;
111 }

References CATEGORY_TAG_NAME, CATEGORY_TAG_SIZE, categoryTag, DUAL_CURVE_TAG_NAME, DUAL_ENTITY_TAG_NAME, DUAL_GRAPHICS_POINT_TAG_NAME, DUAL_SURFACE_TAG_NAME, dualCurveTag, dualEntityTag, dualGraphicsPointTag, dualSurfaceTag, ErrorCode, EXTRA_DUAL_ENTITY_TAG_NAME, extraDualEntityTag, moab::Interface::globalId_tag(), globalIdTag, IS_DUAL_CELL_TAG_NAME, isDualCellTag, maxHexId, MB_SUCCESS, MB_TAG_BYTES, MB_TAG_CREAT, MB_TAG_DENSE, MB_TAG_SPARSE, MB_TYPE_DOUBLE, MB_TYPE_HANDLE, MB_TYPE_INTEGER, MB_TYPE_OPAQUE, mbImpl, and moab::Interface::tag_get_handle().

◆ ~DualTool()

moab::DualTool::~DualTool ( )

Definition at line 113 of file DualTool.cpp.

113 {}

Member Function Documentation

◆ add_graphics_point()

ErrorCode moab::DualTool::add_graphics_point ( EntityHandle  entity,
double *  avg_pos = NULL 
)
private

add a graphics point to an entity (on a tag)

Definition at line 269 of file DualTool.cpp.

270 {
271  // add a graphics pt, placed at the same position as the vertex
272  double my_pos[3];
273  ErrorCode result;
274 
275  if( NULL == avg_pos )
276  {
277  result = MeshTopoUtil( mbImpl ).get_average_position( entity, my_pos );
278  if( MB_SUCCESS != result ) return result;
279  }
280  else
281  for( int i = 0; i < 3; i++ )
282  my_pos[i] = avg_pos[i];
283 
284  DualTool::GraphicsPoint dum_pt( my_pos, -1 );
285  result = mbImpl->tag_set_data( dualGraphicsPoint_tag(), &entity, 1, &dum_pt );
286  return result;
287 }

References dualGraphicsPoint_tag(), ErrorCode, moab::MeshTopoUtil::get_average_position(), MB_SUCCESS, mbImpl, and moab::Interface::tag_set_data().

Referenced by construct_dual_edges(), construct_dual_faces(), and construct_dual_vertex().

◆ atomic_pillow()

ErrorCode moab::DualTool::atomic_pillow ( EntityHandle  odedge,
EntityHandle quad1,
EntityHandle quad2 
)

effect atomic pillow operation

Definition at line 1435 of file DualTool.cpp.

1436 {
1437  if( debug_ap ) ( (Core*)mbImpl )->check_adjacencies();
1438 
1439  if( debug_ap )
1440  {
1441  Range sets;
1442  Tag ms_tag;
1443 
1444  ErrorCode result = mbImpl->tag_get_handle( "MATERIAL_SET", 1, MB_TYPE_INTEGER, ms_tag );
1445  if( MB_SUCCESS == result )
1446  {
1447  result = mbImpl->get_entities_by_type_and_tag( 0, MBENTITYSET, &ms_tag, NULL, 1, sets );
1448  if( MB_SUCCESS == result ) result = mbImpl->delete_entities( sets );
1449  }
1450  }
1451 
1452  std::cout << "-AP(";
1453  print_cell( odedge );
1454  std::cout << ")" << std::endl;
1455 
1456  // perform an atomic pillow operation around dedge
1457 
1458  // grab the quad before deleting the odedge
1459  quad1 = get_dual_entity( odedge );
1460  assert( 0 != quad1 );
1461 
1462  // 0. get star 2cells around odedge (before odedge changes) and 3cells around
1463  // those 2cells (going to delete the 2cells, therefore need to delete the 3cells
1464  // that depend on those too)
1465  MeshTopoUtil mtu( mbImpl );
1466  Range star_cells, tmp_cells;
1467  ErrorCode result = mbImpl->get_adjacencies( &odedge, 1, 2, false, star_cells );RR;
1468  result = mbImpl->get_adjacencies( star_cells, 3, false, tmp_cells, Interface::UNION );RR;
1469  star_cells.merge( tmp_cells );
1470  star_cells.insert( odedge );
1471 
1472  // tear down the dual entities which will be modified by the ap first
1473  result = delete_dual_entities( star_cells );RR;
1474 
1475  // now change the quad to an ap
1476  std::vector< EntityHandle > verts;
1477  result = mbImpl->get_connectivity( &quad1, 1, verts );RR;
1478 
1479  // get average position of vertices
1480  double coords[12], avg[3] = { 0.0, 0.0, 0.0 };
1481  result = mbImpl->get_coords( &verts[0], verts.size(), coords );RR;
1482  for( int i = 0; i < 4; i++ )
1483  {
1484  avg[0] += coords[3 * i];
1485  avg[1] += coords[3 * i + 1];
1486  avg[2] += coords[3 * i + 2];
1487  }
1488  for( int i = 0; i < 3; i++ )
1489  avg[i] *= 0.25;
1490 
1491  // for each position, get a corresponding position 1/2 way to avg
1492  double new_coords[12];
1493  for( int i = 0; i < 4; i++ )
1494  {
1495  new_coords[3 * i] = avg[0] + .5 * ( coords[3 * i] - avg[0] );
1496  new_coords[3 * i + 1] = avg[1] + .5 * ( coords[3 * i + 1] - avg[1] );
1497  new_coords[3 * i + 2] = avg[2] + .5 * ( coords[3 * i + 2] - avg[2] );
1498  }
1499 
1500  // make the 4 new vertices; store in vector long enough for hex connectivity
1501  for( int i = 0; i < 4; i++ )
1502  {
1503  verts.push_back( 0 );
1504  result = mbImpl->create_vertex( &new_coords[3 * i], verts[4 + i] );RR;
1505  }
1506 
1507  // get the hexes connected to the quad
1508  Range hexes;
1509  result = mbImpl->get_adjacencies( &quad1, 1, 3, false, hexes );RR;
1510  assert( hexes.size() <= 2 );
1511 
1512  // remove any explicit adjacency from the first hex, since that'll get connected
1513  // to the new quad; add adjacency between quad and second hex, if there is a 2nd
1514  result = mbImpl->remove_adjacencies( quad1, &( *hexes.begin() ), 1 );RR;
1515  if( hexes.size() == 2 )
1516  {
1517  result = mbImpl->add_adjacencies( quad1, &( *hexes.rbegin() ), 1, false );RR;
1518  }
1519 
1520  // create the new, inner quad, and make it explicitly adjacent to 1st hex;
1521  // make the connectivity of this quad same as the original one
1522  std::vector< EntityHandle > tmp_verts;
1523  std::copy( verts.begin(), verts.end(), std::back_inserter( tmp_verts ) );
1524 
1525  result = mbImpl->create_element( MBQUAD, &tmp_verts[0], 4, quad2 );RR;
1526  result = mbImpl->add_adjacencies( quad2, &( *hexes.begin() ), 1, false );RR;
1527 
1528  // reverse the connectivity of the 1st hex
1529  std::reverse( verts.begin(), verts.begin() + 4 );
1530  std::reverse( verts.begin() + 4, verts.end() );
1531 
1532  // now make two inner hexes; note connectivity array is flipped for the two hexes
1533  EntityHandle new_hexes[2];
1534  result = mbImpl->create_element( MBHEX, &verts[0], 8, new_hexes[0] );RR;
1535  result = mbImpl->create_element( MBHEX, &tmp_verts[0], 8, new_hexes[1] );RR;
1536 
1537  // set the global id tag on the new hexes
1538  int new_hex_ids[2] = { maxHexId + 1, maxHexId + 2 };
1539  maxHexId += 2;
1540  result = mbImpl->tag_set_data( globalId_tag(), new_hexes, 2, new_hex_ids );
1541  if( MB_SUCCESS != result ) return result;
1542 
1543  // by definition, quad1 is adj to new_hexes[0]
1544  result = mbImpl->add_adjacencies( quad1, &new_hexes[0], 1, false );RR;
1545  result = mbImpl->add_adjacencies( quad2, &new_hexes[1], 1, false );RR;
1546 
1547  if( debug_ap ) ( (Core*)mbImpl )->check_adjacencies();
1548 
1549  // now update the dual
1550  result = construct_hex_dual( &new_hexes[0], 2 );RR;
1551 
1552  // get the new dual surface, by getting one of the edges between the center
1553  // and outer vertex rings
1554  Range new_edge;
1555  verts[1] = verts[4];
1556  result = mbImpl->get_adjacencies( &verts[0], 2, 1, false, new_edge );
1557  if( MB_SUCCESS != result || new_edge.size() != 1 ) return result;
1558 
1559  return MB_SUCCESS;
1560 }

References moab::Interface::add_adjacencies(), moab::Range::begin(), construct_hex_dual(), moab::Interface::create_element(), moab::Interface::create_vertex(), moab::debug_ap, delete_dual_entities(), moab::Interface::delete_entities(), ErrorCode, moab::Interface::get_adjacencies(), moab::Interface::get_connectivity(), moab::Interface::get_coords(), get_dual_entity(), moab::Interface::get_entities_by_type_and_tag(), globalId_tag(), moab::Range::insert(), maxHexId, MB_SUCCESS, MB_TYPE_INTEGER, MBENTITYSET, MBHEX, mbImpl, MBQUAD, moab::Range::merge(), print_cell(), moab::Range::rbegin(), moab::Interface::remove_adjacencies(), RR, moab::Range::size(), moab::Interface::tag_get_handle(), moab::Interface::tag_set_data(), and moab::Interface::UNION.

◆ check_1d_loop_edge()

bool moab::DualTool::check_1d_loop_edge ( EntityHandle  this_ent)
private

if this_ent is an edge, is a dual entity, and has quads as its vertices' dual entities, return true, otherwise false

Definition at line 1116 of file DualTool.cpp.

1117 {
1118  // make sure it's an edge
1119  if( MBEDGE != mbImpl->type_from_handle( this_ent ) ) return false;
1120 
1121  // also has to be a dual entity
1122  unsigned int dum;
1123  ErrorCode result = mbImpl->tag_get_data( isDualCell_tag(), &this_ent, 1, &dum );
1124  if( MB_SUCCESS != result || dum != 0x1 ) return false;
1125 
1126  const EntityHandle* verts;
1127  EntityHandle vert_tags[2];
1128  int num_verts;
1129  result = mbImpl->get_connectivity( this_ent, verts, num_verts );
1130  if( MB_SUCCESS != result ) return false;
1131 
1132  result = mbImpl->tag_get_data( dualEntity_tag(), verts, 2, vert_tags );
1133  if( MB_SUCCESS != result || mbImpl->type_from_handle( vert_tags[0] ) != MBQUAD ||
1134  mbImpl->type_from_handle( vert_tags[1] ) != MBQUAD )
1135  return false;
1136 
1137  else
1138  return true;
1139 }

References dualEntity_tag(), moab::dum, ErrorCode, moab::Interface::get_connectivity(), isDualCell_tag(), MB_SUCCESS, MBEDGE, mbImpl, MBQUAD, moab::Interface::tag_get_data(), and moab::Interface::type_from_handle().

Referenced by construct_dual_hyperplanes(), delete_dual_entities(), and traverse_hyperplane().

◆ check_dual_adjs()

ErrorCode moab::DualTool::check_dual_adjs ( )

check dual-primal adjacencies

Definition at line 3236 of file DualTool.cpp.

3237 {
3238  // check primal-dual correspondence
3239 
3240  // get the primal entities
3241  Range pents[4];
3242  ErrorCode result = mbImpl->get_entities_by_type( 0, MBHEX, pents[3] );RR;
3243  for( int i = 2; i >= 0; i-- )
3244  {
3245  result = mbImpl->get_adjacencies( pents[3], 2, false, pents[2], Interface::UNION );RR;
3246  }
3247 
3248  // for each primal entity of dimension pd
3249 #define PRENT( ent ) CN::EntityTypeName( TYPE_FROM_HANDLE( ent ) ) << " " << ID_FROM_HANDLE( ent )
3250  ErrorCode overall_result = MB_SUCCESS;
3251  for( int pd = 1; pd <= 3; pd++ )
3252  {
3253  for( Range::iterator prit = pents[pd].begin(); prit != pents[pd].end(); ++prit )
3254  {
3255  // get corresponding dual entity of dimension dd = 3-pd
3256  EntityHandle dual_ent = get_dual_entity( *prit );
3257  if( 0 == dual_ent ) std::cerr << "Problem getting dual entity for " << PRENT( *prit ) << std::endl;
3258 
3259  // for each sub dimension sd = 0..pd-1
3260  for( int sd = 0; sd < pd; sd++ )
3261  {
3262  Range R1, R2, R3;
3263  // R1 = entities bounding primal entity of dim sd
3264  result = mbImpl->get_adjacencies( &( *prit ), 1, sd, false, R1 );RR;
3265 
3266  // R2 = entities bounded by dual entity, of dim 3-sd
3267  result = mbImpl->get_adjacencies( &dual_ent, 1, 3 - sd, false, R2 );RR;
3268 
3269  if( R1.size() != R2.size() )
3270  {
3271  std::cerr << PRENT( *prit ) << ": number of adj ents in "
3272  << "primal/dual don't agree for dimension " << sd << "." << std::endl;
3273  overall_result = MB_FAILURE;
3274  }
3275 
3276  // for each entity in R1, get its dual and look for it in R2
3277  for( Range::iterator r1it = R1.begin(); r1it != R1.end(); ++r1it )
3278  {
3279  EntityHandle tmp_dual = get_dual_entity( *r1it );
3280  if( R2.find( tmp_dual ) == R2.end() )
3281  {
3282  std::cerr << PRENT( *prit ) << ": adj entity " << PRENT( *r1it ) << " isn't adjacent in dual."
3283  << std::endl;
3284  overall_result = MB_FAILURE;
3285  }
3286  }
3287  // ditto for R2
3288  for( Range::iterator r2it = R2.begin(); r2it != R2.end(); ++r2it )
3289  {
3290  EntityHandle tmp_prim = get_dual_entity( *r2it );
3291  if( R1.find( tmp_prim ) == R1.end() )
3292  {
3293  std::cerr << PRENT( *prit ) << ": adj entity " << PRENT( *r2it ) << " isn't adjacent in primal."
3294  << std::endl;
3295  overall_result = MB_FAILURE;
3296  }
3297  }
3298  }
3299  }
3300  }
3301 
3302  return overall_result;
3303 }

References moab::Range::begin(), moab::Range::end(), ErrorCode, moab::Range::find(), moab::Interface::get_adjacencies(), get_dual_entity(), moab::Interface::get_entities_by_type(), MB_SUCCESS, MBHEX, mbImpl, PRENT, RR, moab::Range::size(), and moab::Interface::UNION.

Referenced by face_open_collapse().

◆ check_dual_equiv_edges()

ErrorCode moab::DualTool::check_dual_equiv_edges ( Range dual_edges)
private

go through potential dual equivalent edges (edges whose nodes define multiple edges), and add explicit adjacencies to corrent 2cells

Definition at line 468 of file DualTool.cpp.

469 {
470  // fix equivalent dual edges (i.e. edges whose vertices define multiple edges)
471  // by explicitly adding adjacencies to containing polygons; adjacent polygons
472  // found by going through primal
473  ErrorCode tmp_result, result = MB_SUCCESS;
474 
475  Range all_dedges( dual_edges );
476  // first, go through all dual edges and find equivalent edges (by looking for
477  // up-adjacent edges on the vertices of each edge)
478  for( Range::iterator rit = dual_edges.begin(); rit != dual_edges.end(); ++rit )
479  {
480  Range connect, dum_range( *rit, *rit );
481  tmp_result = mbImpl->get_adjacencies( dum_range, 0, false, connect );
482  if( MB_SUCCESS != tmp_result ) continue;
483  tmp_result = mbImpl->get_adjacencies( connect, 1, false, all_dedges, Interface::UNION );
484  if( MB_SUCCESS != tmp_result ) continue;
485  }
486 
487  // save a copy for checking later
488  Range save_all_2cells;
489 
490  // go through each edge
491  while( !all_dedges.empty() )
492  {
493  EntityHandle this_edge = *all_dedges.begin();
494  all_dedges.erase( all_dedges.begin() );
495 
496  const EntityHandle* connect;
497  int num_connect;
498  result = mbImpl->get_connectivity( this_edge, connect, num_connect );
499  if( MB_SUCCESS != result ) continue;
500 
501  Range dum_edges, verts;
502  verts.insert( connect[0] );
503  verts.insert( connect[1] );
504  tmp_result = mbImpl->get_adjacencies( verts, 1, false, dum_edges );
505  if( MB_SUCCESS != tmp_result )
506  {
507  result = tmp_result;
508  continue;
509  }
510  if( dum_edges.size() == 1 )
511  {
512  // not an equiv edge - already removed from list, so just continue
513  continue;
514  }
515 
516  // ok, have an equiv entity - fix by looking through primal
517  // pre-get the primal of these
518  EntityHandle dedge_quad;
519  tmp_result = mbImpl->tag_get_data( dualEntity_tag(), &this_edge, 1, &dedge_quad );
520  if( MB_SUCCESS != tmp_result )
521  {
522  result = tmp_result;
523  continue;
524  }
525 
526  if( MBQUAD == mbImpl->type_from_handle( dedge_quad ) )
527  {
528 
529  // get the primal edges adj to quad
530  Range dum_quad_range( dedge_quad, dedge_quad ), adj_pedges;
531  tmp_result = mbImpl->get_adjacencies( dum_quad_range, 1, false, adj_pedges );
532  if( MB_SUCCESS != tmp_result )
533  {
534  result = tmp_result;
535  continue;
536  }
537  // get the dual 2cells corresponding to those pedges
538  std::vector< EntityHandle > dcells;
539  dcells.resize( adj_pedges.size() );
540  tmp_result = mbImpl->tag_get_data( dualEntity_tag(), adj_pedges, &dcells[0] );
541  if( MB_SUCCESS != tmp_result )
542  {
543  result = tmp_result;
544  continue;
545  }
546  // now add explicit adjacencies from the dedge to those dcells
547  std::vector< EntityHandle >::iterator vit;
548  for( vit = dcells.begin(); vit != dcells.end(); ++vit )
549  {
550  save_all_2cells.insert( *vit );
551 
552  assert( MBPOLYGON == mbImpl->type_from_handle( *vit ) );
553  tmp_result = mbImpl->add_adjacencies( this_edge, &( *vit ), 1, false );
554  if( MB_SUCCESS != tmp_result )
555  {
556  result = tmp_result;
557  continue;
558  }
559  // check that there are really adjacencies and *vit is in them
560  const EntityHandle* adjs;
561  int num_adjs;
562  tmp_result = reinterpret_cast< Core* >( mbImpl )->a_entity_factory()->get_adjacencies( this_edge, adjs,
563  num_adjs );
564  if( NULL == adjs || std::find( adjs, adjs + num_adjs, *vit ) == adjs + num_adjs )
565  std::cout << "Add_adjacencies failed in construct_dual_faces." << std::endl;
566  }
567  }
568  else
569  {
570  // else, have a dual edge representing a bdy edge - tie directly to
571  // dual entity if its dual entity
572  EntityHandle bdy_dcell;
573  tmp_result = mbImpl->tag_get_data( dualEntity_tag(), &dedge_quad, 1, &bdy_dcell );
574  TRC assert( MBPOLYGON == mbImpl->type_from_handle( bdy_dcell ) );
575 
576  tmp_result = mbImpl->add_adjacencies( this_edge, &bdy_dcell, 1, false );
577  if( MB_SUCCESS != tmp_result )
578  {
579  result = tmp_result;
580  continue;
581  }
582  }
583  }
584 
585  // sanity check - look for adj edges again, and check for equiv entities
586  for( Range::iterator vit = save_all_2cells.begin(); vit != save_all_2cells.end(); ++vit )
587  {
588  Range adj_edges, dum_quad_range;
589  dum_quad_range.insert( *vit );
590  assert( MBPOLYGON == mbImpl->type_from_handle( *vit ) );
591  tmp_result = mbImpl->get_adjacencies( dum_quad_range, 1, false, adj_edges );
592  if( MB_MULTIPLE_ENTITIES_FOUND == tmp_result )
593  {
594  std::cout << "Multiple entities returned for polygon " << mbImpl->id_from_handle( *vit ) << "."
595  << std::endl;
596  continue;
597  }
598  }
599  // success!
600  return result;
601 }

References moab::Interface::add_adjacencies(), moab::Range::begin(), dualEntity_tag(), moab::Range::empty(), moab::Range::end(), moab::Range::erase(), ErrorCode, moab::Core::get_adjacencies(), moab::Interface::get_adjacencies(), moab::Interface::get_connectivity(), moab::Interface::id_from_handle(), moab::Range::insert(), MB_MULTIPLE_ENTITIES_FOUND, MB_SUCCESS, mbImpl, MBPOLYGON, MBQUAD, moab::Range::size(), moab::Interface::tag_get_data(), TRC, moab::Interface::type_from_handle(), and moab::Interface::UNION.

Referenced by construct_dual_faces().

◆ construct_dual()

ErrorCode moab::DualTool::construct_dual ( EntityHandle entities,
const int  num_entities 
)

construct the dual entities for the entire mesh

Definition at line 116 of file DualTool.cpp.

117 {
118  // allocate a dual entity for each primal entity in the mesh, starting
119  // with highest dimension and working downward; do each dimension in a separate code
120  // block, since they're all handled slightly differently
121 
122  Range regions, faces, edges, vertices;
123  ErrorCode result;
124 
125  if( NULL == entities || 0 == num_entities )
126  {
127 
128  // first, construct all the aentities, since they're currently needed to
129  // compute the dual
130  result = mbImpl->get_entities_by_dimension( 0, 0, vertices );
131  if( MB_SUCCESS != result ) return result;
132 
133  result = MeshTopoUtil( mbImpl ).construct_aentities( vertices );
134  if( MB_SUCCESS != result ) return result;
135 
136  // get all edges, faces and regions now, so we don't need to filter out dual
137  // entities later
138 
139  result = mbImpl->get_entities_by_dimension( 0, 1, edges );
140  if( MB_SUCCESS != result ) return result;
141  result = mbImpl->get_entities_by_dimension( 0, 2, faces );
142  if( MB_SUCCESS != result ) return result;
143  result = mbImpl->get_entities_by_dimension( 0, 3, regions );
144  if( MB_SUCCESS != result ) return result;
145 
146  // get the max global id for hexes, we'll need for modification ops
147  std::vector< int > gid_vec( regions.size() );
148  result = mbImpl->tag_get_data( globalId_tag(), regions, &gid_vec[0] );
149  if( MB_SUCCESS != result ) return result;
150  maxHexId = -1;
151  Range::iterator rit;
152  unsigned int i;
153  for( rit = regions.begin(), i = 0; rit != regions.end(); ++rit, i++ )
154  {
155  if( gid_vec[i] > maxHexId && mbImpl->type_from_handle( *rit ) == MBHEX ) maxHexId = gid_vec[i];
156  }
157  }
158  else
159  {
160  // get entities of various dimensions adjacent to these
161  result = mbImpl->get_adjacencies( entities, num_entities, 0, true, vertices, Interface::UNION );
162  if( MB_SUCCESS != result ) return result;
163  result = mbImpl->get_adjacencies( entities, num_entities, 1, true, edges, Interface::UNION );
164  if( MB_SUCCESS != result ) return result;
165  result = mbImpl->get_adjacencies( entities, num_entities, 2, true, faces, Interface::UNION );
166  if( MB_SUCCESS != result ) return result;
167  result = mbImpl->get_adjacencies( entities, num_entities, 3, true, regions, Interface::UNION );
168  if( MB_SUCCESS != result ) return result;
169  }
170 
171  Range dual_verts;
172  result = construct_dual_vertices( regions, dual_verts );
173  if( MB_SUCCESS != result || dual_verts.size() != regions.size() ) return result;
174  if( debug ) std::cout << "Constructed " << dual_verts.size() << " dual vertices." << std::endl;
175 
176  // don't really need dual edges, but construct 'em anyway
177  Range dual_edges;
178  result = construct_dual_edges( faces, dual_edges );
179  if( MB_SUCCESS != result || dual_edges.size() != faces.size() ) return result;
180  if( debug ) std::cout << "Constructed " << dual_edges.size() << " dual edges." << std::endl;
181 
182  // construct dual faces
183  Range dual_faces;
184  result = construct_dual_faces( edges, dual_faces );
185  if( MB_SUCCESS != result || dual_faces.size() != edges.size() ) return result;
186  if( debug ) std::cout << "Constructed " << dual_faces.size() << " dual faces." << std::endl;
187 
188  // construct dual cells
189  Range dual_cells;
190  result = construct_dual_cells( vertices, dual_cells );
191  if( MB_SUCCESS != result || dual_cells.size() != vertices.size() ) return result;
192  if( debug ) std::cout << "Constructed " << dual_cells.size() << " dual cells." << std::endl;
193 
194  return MB_SUCCESS;
195 }

References moab::Range::begin(), moab::MeshTopoUtil::construct_aentities(), construct_dual_cells(), construct_dual_edges(), construct_dual_faces(), construct_dual_vertices(), moab::debug, moab::Range::end(), entities, ErrorCode, moab::Interface::get_adjacencies(), moab::Interface::get_entities_by_dimension(), globalId_tag(), maxHexId, MB_SUCCESS, MBHEX, mbImpl, moab::Range::size(), moab::Interface::tag_get_data(), moab::Interface::type_from_handle(), and moab::Interface::UNION.

Referenced by construct_hex_dual().

◆ construct_dual_cells()

ErrorCode moab::DualTool::construct_dual_cells ( const Range all_verts,
Range new_dual_ents 
)
private

construct dual cells for specified vertices

Definition at line 603 of file DualTool.cpp.

604 {
605  if( all_verts.empty() ) return MB_SUCCESS;
606 
607  // make sure they're all edges
608  assert( 0 == CN::Dimension( TYPE_FROM_HANDLE( *all_verts.begin() ) ) &&
609  0 == CN::Dimension( TYPE_FROM_HANDLE( *all_verts.rbegin() ) ) );
610 
611  Range::const_iterator rit;
612  EntityHandle dual_ent;
613  unsigned int is_dual = 0x1;
614  ErrorCode tmp_result = MB_SUCCESS;
615  ErrorCode result = MB_SUCCESS;
616  std::vector< EntityHandle > edges, dfaces;
617 
618  for( rit = all_verts.begin(); rit != all_verts.end(); ++rit )
619  {
620  if( tmp_result != MB_SUCCESS ) result = tmp_result;
621 
622  tmp_result = mbImpl->tag_get_data( dualEntity_tag(), &( *rit ), 1, &dual_ent );
623  if( MB_SUCCESS == tmp_result && 0 != dual_ent )
624  {
625  dual_ents.insert( dual_ent );
626  continue;
627  }
628 
629  // no dual entity; construct one; get the edges bounding the vertex
630  edges.clear();
631  dfaces.clear();
632  tmp_result = mbImpl->get_adjacencies( &( *rit ), 1, 1, false, edges );
633  if( MB_SUCCESS != tmp_result ) continue;
634 
635  // get the dual faces corresponding to the edges
636  dfaces.resize( edges.size() );
637  tmp_result = mbImpl->tag_get_data( dualEntity_tag(), &edges[0], edges.size(), &dfaces[0] );
638  if( MB_SUCCESS != tmp_result ) continue;
639 
640  // create the dual cell from those faces
641  tmp_result = mbImpl->create_element( MBPOLYHEDRON, &dfaces[0], dfaces.size(), dual_ent );
642  if( MB_SUCCESS != tmp_result || 0 == dual_ent ) continue;
643 
644  // save it in the list of new dual ents
645  dual_ents.insert( dual_ent );
646 
647  // tag it indicating it's a dual entity
648  tmp_result = mbImpl->tag_set_data( isDualCell_tag(), &dual_ent, 1, &is_dual );
649  if( MB_SUCCESS != tmp_result ) continue;
650 
651  // tag the primal entity with its dual entity and vica versa
652  tmp_result = mbImpl->tag_set_data( dualEntity_tag(), &( *rit ), 1, &dual_ent );
653  if( MB_SUCCESS != tmp_result ) continue;
654  tmp_result = mbImpl->tag_set_data( dualEntity_tag(), &dual_ent, 1, &( *rit ) );
655  if( MB_SUCCESS != tmp_result ) continue;
656  }
657 
658  return result;
659 }

References moab::Range::begin(), moab::Interface::create_element(), moab::CN::Dimension(), dualEntity_tag(), moab::Range::empty(), moab::Range::end(), ErrorCode, moab::Interface::get_adjacencies(), moab::Range::insert(), isDualCell_tag(), MB_SUCCESS, mbImpl, MBPOLYHEDRON, moab::Range::rbegin(), moab::Interface::tag_get_data(), moab::Interface::tag_set_data(), and moab::TYPE_FROM_HANDLE().

Referenced by construct_dual().

◆ construct_dual_edges()

ErrorCode moab::DualTool::construct_dual_edges ( const Range all_faces,
Range new_dual_ents 
)
private

construct dual edges for specified faces

Definition at line 289 of file DualTool.cpp.

290 {
291  if( all_faces.empty() ) return MB_SUCCESS;
292 
293  // make sure they're all faces
294  assert( 2 == CN::Dimension( TYPE_FROM_HANDLE( *all_faces.begin() ) ) &&
295  2 == CN::Dimension( TYPE_FROM_HANDLE( *all_faces.rbegin() ) ) );
296 
297  Range::const_iterator rit;
298  EntityHandle dual_ent;
299  unsigned int is_dual = 0x1;
300  ErrorCode tmp_result = MB_SUCCESS;
301  ErrorCode result = MB_SUCCESS;
302 
303  for( rit = all_faces.begin(); rit != all_faces.end(); ++rit )
304  {
305  if( tmp_result != MB_SUCCESS ) result = tmp_result;
306 
307  tmp_result = mbImpl->tag_get_data( dualEntity_tag(), &( *rit ), 1, &dual_ent );
308  if( MB_SUCCESS == tmp_result && 0 != dual_ent )
309  {
310  dual_ents.insert( dual_ent );
311  continue;
312  }
313 
314  // no dual entity; construct one; get the bounding regions
315  std::vector< EntityHandle > out_ents;
316  tmp_result = mbImpl->get_adjacencies( &( *rit ), 1, 3, false, out_ents );
317  if( MB_SUCCESS != tmp_result || out_ents.empty() ) continue;
318 
319  // get the dual vertices
320  std::vector< EntityHandle > dual_verts( out_ents.size() );
321  tmp_result = mbImpl->tag_get_data( dualEntity_tag(), &out_ents[0], out_ents.size(), &dual_verts[0] );
322  if( MB_SUCCESS != tmp_result ) continue;
323  assert( dual_verts.size() <= 2 );
324 
325  double avg_pos[3];
326  bool bdy_face = ( dual_verts.size() == 1 ? true : false );
327  if( bdy_face )
328  {
329  // boundary face - make a dual vertex at the face center and put in list
330  tmp_result = construct_dual_vertex( *rit, dual_ent, true, true );
331 
332  // put it on vertex list
333  dual_verts.push_back( dual_ent );
334  }
335 
336  assert( dual_verts.size() == 2 );
337 
338  // now create the dual edge
339  tmp_result = mbImpl->create_element( MBEDGE, &dual_verts[0], 2, dual_ent );
340  if( MB_SUCCESS != tmp_result || 0 == dual_ent ) continue;
341 
342  // save it in the list of new dual ents
343  dual_ents.insert( dual_ent );
344 
345  // tag the primal entity with its dual entity and vica versa
346  tmp_result = mbImpl->tag_set_data( dualEntity_tag(), &( *rit ), 1, &dual_ent );
347  if( MB_SUCCESS != tmp_result ) continue;
348 
349  tmp_result = mbImpl->tag_set_data( dualEntity_tag(), &dual_ent, 1, &( *rit ) );
350  if( MB_SUCCESS != tmp_result ) continue;
351 
352  // tag the edge indicating it's a dual entity
353  tmp_result = mbImpl->tag_set_data( isDualCell_tag(), &dual_ent, 1, &is_dual );
354  if( MB_SUCCESS != tmp_result ) continue;
355 
356  // add a graphics point to the edge; position depends on whether it's a
357  // bdy face (mid-pt of dual edge) or not (mid-pt of primal face)
358  if( bdy_face )
359  tmp_result = add_graphics_point( dual_ent );
360  else
361  {
362  // get the face's position
363  tmp_result = MeshTopoUtil( mbImpl ).get_average_position( *rit, avg_pos );
364  if( MB_SUCCESS != tmp_result ) continue;
365  tmp_result = add_graphics_point( dual_ent, avg_pos );
366  }
367  if( MB_SUCCESS != tmp_result ) continue;
368  }
369 
370  return result;
371 }

References add_graphics_point(), moab::Range::begin(), construct_dual_vertex(), moab::Interface::create_element(), moab::CN::Dimension(), dualEntity_tag(), moab::Range::empty(), moab::Range::end(), ErrorCode, moab::Interface::get_adjacencies(), moab::MeshTopoUtil::get_average_position(), moab::Range::insert(), isDualCell_tag(), MB_SUCCESS, MBEDGE, mbImpl, moab::Range::rbegin(), moab::Interface::tag_get_data(), moab::Interface::tag_set_data(), and moab::TYPE_FROM_HANDLE().

Referenced by construct_dual().

◆ construct_dual_faces()

ErrorCode moab::DualTool::construct_dual_faces ( const Range all_edges,
Range new_dual_ents 
)
private

construct dual faces for specified edges

Definition at line 373 of file DualTool.cpp.

374 {
375  if( all_edges.empty() ) return MB_SUCCESS;
376 
377  // make sure they're all edges
378  assert( 1 == CN::Dimension( TYPE_FROM_HANDLE( *all_edges.begin() ) ) &&
379  1 == CN::Dimension( TYPE_FROM_HANDLE( *all_edges.rbegin() ) ) );
380 
381  Range::const_iterator rit;
382  EntityHandle dual_ent;
383  unsigned int is_dual = 0x1;
384  ErrorCode tmp_result = MB_SUCCESS;
385  ErrorCode result = MB_SUCCESS;
386  Range equiv_edges;
387 #define TRC \
388  if( MB_SUCCESS != tmp_result ) \
389  { \
390  result = tmp_result; \
391  continue; \
392  }
393  for( rit = all_edges.begin(); rit != all_edges.end(); ++rit )
394  {
395 
396  tmp_result = mbImpl->tag_get_data( dualEntity_tag(), &( *rit ), 1, &dual_ent );
397  if( MB_SUCCESS == tmp_result && 0 != dual_ent )
398  {
399  dual_ents.insert( dual_ent );
400  continue;
401  }
402 
403  // no dual entity; construct one; get the dual vertices bounding the edge in radial order,
404  // then construct the dual face
405  std::vector< EntityHandle > rad_dverts;
406  bool bdy_edge;
407  tmp_result = get_radial_dverts( *rit, rad_dverts, bdy_edge );
408  TRC if( rad_dverts.empty() ) continue;
409 
410  tmp_result = mbImpl->create_element( MBPOLYGON, &rad_dverts[0], rad_dverts.size(), dual_ent );
411  TRC
412 
413  // tag it indicating it's a dual entity, and tag primal/dual with dual/primal
414  tmp_result = mbImpl->tag_set_data( isDualCell_tag(), &dual_ent, 1, &is_dual );
415  TRC tmp_result = mbImpl->tag_set_data( dualEntity_tag(), &( *rit ), 1, &dual_ent );
416  TRC tmp_result = mbImpl->tag_set_data( dualEntity_tag(), &dual_ent, 1, &( *rit ) );
417  TRC
418 
419  // save it in the list of new dual ents
420  dual_ents.insert( dual_ent );
421 
422  // add a graphics point to the cell; position depends on whether it's a
423  // bdy cell (mid-pt of cell's vertices) or not (mid-pt of primal edge)
424  double avg_pos[3];
425  tmp_result = MeshTopoUtil( mbImpl ).get_average_position( *rit, avg_pos );
426  TRC if( bdy_edge )
427  {
428 
429  // add a new dual edge betw last 2 verts
430  EntityHandle new_edge;
431  tmp_result = mbImpl->create_element( MBEDGE, &rad_dverts[rad_dverts.size() - 2], 2, new_edge );
432  TRC tmp_result = mbImpl->tag_set_data( isDualCell_tag(), &new_edge, 1, &is_dual );
433  TRC
434 
435  // tag the new dual edge with the primal edge as it's dual entity; primal
436  // edge IS NOT likewise tagged, since it's already tagged with the 2cell
437  tmp_result = mbImpl->tag_set_data( dualEntity_tag(), &new_edge, 1, &( *rit ) );
438  TRC
439 
440  // add a graphics pt, position is center of primal edge
441  tmp_result = add_graphics_point( dual_ent );
442  TRC tmp_result = add_graphics_point( new_edge, avg_pos );
443  TRC
444  }
445 
446  else
447  {
448  // if inside, point goes on the 2cell, at primal edge mid-pt
449  tmp_result = add_graphics_point( dual_ent, avg_pos );
450  TRC
451  }
452 
453  // check to see whether we have equiv entities; if we find any, save for later fixup
454  Range dum_edges, dum_poly( dual_ent, dual_ent );
455  tmp_result = mbImpl->get_adjacencies( dum_poly, 1, false, dum_edges );
456  if( MB_MULTIPLE_ENTITIES_FOUND == tmp_result )
457  {
458  // we do - need to add adjacencies to disambiguate; use the primal
459  equiv_edges.merge( dum_edges );
460  }
461  }
462 
463  if( !equiv_edges.empty() ) result = check_dual_equiv_edges( equiv_edges );
464 
465  return result;
466 }

References add_graphics_point(), moab::Range::begin(), check_dual_equiv_edges(), moab::Interface::create_element(), moab::CN::Dimension(), dualEntity_tag(), moab::Range::empty(), moab::Range::end(), ErrorCode, moab::Interface::get_adjacencies(), moab::MeshTopoUtil::get_average_position(), get_radial_dverts(), moab::Range::insert(), isDualCell_tag(), MB_MULTIPLE_ENTITIES_FOUND, MB_SUCCESS, MBEDGE, mbImpl, MBPOLYGON, moab::Range::merge(), moab::Range::rbegin(), moab::Interface::tag_get_data(), moab::Interface::tag_set_data(), TRC, and moab::TYPE_FROM_HANDLE().

Referenced by construct_dual().

◆ construct_dual_hyperplanes()

ErrorCode moab::DualTool::construct_dual_hyperplanes ( const int  dim,
EntityHandle entities,
const int  num_entities 
)
private

traverse dual faces of input dimension, constructing dual hyperplanes of them in sets as it goes

Definition at line 825 of file DualTool.cpp.

826 {
827  // this function traverses dual faces of input dimension, constructing
828  // dual hyperplanes of them in sets as it goes
829 
830  // check various inputs
831  int num_quads, num_hexes;
832  if(
833  // this function only makes sense for dim == 1 or dim == 2
834  ( dim != 1 && dim != 2 ) ||
835  // should either be quads or hexes around
836  mbImpl->get_number_entities_by_type( 0, MBQUAD, num_quads ) != MB_SUCCESS ||
837  mbImpl->get_number_entities_by_type( 0, MBHEX, num_hexes ) != MB_SUCCESS ||
838  // if we're asking for 1d dual ents, should be quads around
839  ( num_quads == 0 && dim == 1 ) ||
840  // if we're asking for 2d dual ents, should be hexes around
841  ( num_hexes == 0 && dim == 2 ) )
842  return MB_FAILURE;
843 
844  Tag hp_tag = ( 1 == dim ? dualCurve_tag() : dualSurface_tag() );
845 
846  // two stacks: one completely untreated entities, and the other untreated
847  // entities on the current dual hyperplane
848  std::vector< EntityHandle > tot_untreated;
849 
850  // put dual entities of this dimension on the untreated list
851  ErrorCode result = get_dual_entities( dim, entities, num_entities, tot_untreated );
852  if( MB_SUCCESS != result ) return result;
853 
854  // main part of traversal loop
855  EntityHandle this_ent;
856  EntityHandle this_hp;
857 
858  while( !tot_untreated.empty() )
859  {
860  if( debug && dim == 2 /*(tot_untreated.size()%report == 0)*/ )
861  std::cout << "Untreated list size " << tot_untreated.size() << "." << std::endl;
862 
863  this_ent = tot_untreated.back();
864  tot_untreated.pop_back();
865  result = mbImpl->tag_get_data( hp_tag, &this_ent, 1, &this_hp );
866  if( MB_SUCCESS != result && MB_TAG_NOT_FOUND != result ) return result;
867 
868  // d for this entity having a hyperplane assignment already
869  else if( this_hp != 0 )
870  continue;
871 
872  if( 1 == dim && check_1d_loop_edge( this_ent ) ) continue;
873 
874  // inner loop: traverse the hyperplane 'till we don't have any more
875  result = traverse_hyperplane( hp_tag, this_hp, this_ent );
876  if( MB_SUCCESS != result )
877  {
878  std::cout << "Failed to traverse hyperplane ";
879  if( this_hp )
880  std::cout << mbImpl->id_from_handle( this_hp ) << "." << std::endl;
881  else
882  std::cout << "0." << std::endl;
883  return result;
884  }
885 
886  // ok, now order the edges if it's a chord
887  if( 1 == dim ) order_chord( this_hp );
888  }
889 
890  return MB_SUCCESS;
891 }

References check_1d_loop_edge(), moab::debug, dim, dualCurve_tag(), dualSurface_tag(), entities, ErrorCode, get_dual_entities(), moab::Interface::get_number_entities_by_type(), moab::Interface::id_from_handle(), MB_SUCCESS, MB_TAG_NOT_FOUND, MBHEX, mbImpl, MBQUAD, order_chord(), moab::Interface::tag_get_data(), and traverse_hyperplane().

Referenced by construct_hex_dual().

◆ construct_dual_vertex()

ErrorCode moab::DualTool::construct_dual_vertex ( EntityHandle  entity,
EntityHandle dual_ent,
const bool  extra = false,
const bool  add_graphics_pt = true 
)
private

Definition at line 233 of file DualTool.cpp.

237 {
238  // no dual entity; construct one; first need the avg coordinates
239  unsigned int is_dual = 0x1;
240  double avg_pos[3];
241  ErrorCode result = MeshTopoUtil( mbImpl ).get_average_position( entity, avg_pos );
242  if( MB_SUCCESS != result ) return result;
243 
244  // now construct the new dual entity
245  result = mbImpl->create_vertex( avg_pos, dual_ent );
246  if( MB_SUCCESS != result ) return result;
247 
248  // tag it indicating it's a dual entity
249  result = mbImpl->tag_set_data( isDualCell_tag(), &dual_ent, 1, &is_dual );
250  if( MB_SUCCESS != result ) return result;
251 
252  // tag the primal entity with its dual entity and vica versa
253  if( extra )
254  result = mbImpl->tag_set_data( extraDualEntity_tag(), &( entity ), 1, &dual_ent );
255  else
256  result = mbImpl->tag_set_data( dualEntity_tag(), &( entity ), 1, &dual_ent );
257  if( MB_SUCCESS != result ) return result;
258 
259  result = mbImpl->tag_set_data( dualEntity_tag(), &dual_ent, 1, &( entity ) );
260  if( MB_SUCCESS != result ) return result;
261 
262  if( add_graphics_pt )
263  // put a graphics point on that vertex too
264  result = add_graphics_point( dual_ent, avg_pos );
265 
266  return result;
267 }

References add_graphics_point(), moab::Interface::create_vertex(), dualEntity_tag(), ErrorCode, extraDualEntity_tag(), moab::MeshTopoUtil::get_average_position(), isDualCell_tag(), MB_SUCCESS, mbImpl, and moab::Interface::tag_set_data().

Referenced by construct_dual_edges(), and construct_dual_vertices().

◆ construct_dual_vertices()

ErrorCode moab::DualTool::construct_dual_vertices ( const Range all_regions,
Range new_dual_ents 
)
private

construct dual vertices for specified regions

Definition at line 197 of file DualTool.cpp.

198 {
199  if( all_regions.empty() ) return MB_SUCCESS;
200 
201  // make sure they're all regions
202  assert( 3 == CN::Dimension( TYPE_FROM_HANDLE( *all_regions.begin() ) ) &&
203  3 == CN::Dimension( TYPE_FROM_HANDLE( *all_regions.rbegin() ) ) );
204 
205  Range::const_iterator rit;
206  EntityHandle dual_ent;
207  ErrorCode tmp_result = MB_SUCCESS;
208  ErrorCode result = MB_SUCCESS;
209 
210  for( rit = all_regions.begin(); rit != all_regions.end(); ++rit )
211  {
212  if( tmp_result != MB_SUCCESS ) result = tmp_result;
213 
214  tmp_result = mbImpl->tag_get_data( dualEntity_tag(), &( *rit ), 1, &dual_ent );
215  if( MB_SUCCESS == tmp_result && 0 != dual_ent )
216  {
217  dual_ents.insert( dual_ent );
218  continue;
219  }
220  else if( MB_SUCCESS != tmp_result )
221  continue;
222 
223  tmp_result = construct_dual_vertex( *rit, dual_ent, false, true );
224  if( MB_SUCCESS != tmp_result ) continue;
225 
226  // save it in the list of new dual ents
227  dual_ents.insert( dual_ent );
228  }
229 
230  return result;
231 }

References moab::Range::begin(), construct_dual_vertex(), moab::CN::Dimension(), dualEntity_tag(), moab::Range::empty(), moab::Range::end(), ErrorCode, moab::Range::insert(), MB_SUCCESS, mbImpl, moab::Range::rbegin(), moab::Interface::tag_get_data(), and moab::TYPE_FROM_HANDLE().

Referenced by construct_dual().

◆ construct_hex_dual() [1/2]

ErrorCode moab::DualTool::construct_hex_dual ( EntityHandle entities,
const int  num_entities 
)

construct the dual entities for a hex mesh, including dual surfaces & curves

Definition at line 717 of file DualTool.cpp.

718 {
719  // really quite simple:
720 
721  // construct the dual...
722  ErrorCode result = construct_dual( entities, num_entities );
723  if( MB_SUCCESS != result )
724  {
725  std::cerr << "Error constructing dual entities for primal entities." << std::endl;
726  return result;
727  }
728 
729  // now traverse to build 1d and 2d hyperplanes
730  result = construct_dual_hyperplanes( 1, entities, num_entities );
731  if( MB_SUCCESS != result )
732  {
733  std::cerr << "Problem traversing 1d hyperplanes." << std::endl;
734  return result;
735  }
736 
737  result = construct_dual_hyperplanes( 2, entities, num_entities );
738  if( MB_SUCCESS != result )
739  {
740  std::cerr << "Problem traversing 2d hyperplanes." << std::endl;
741  return result;
742  }
743 
744  result = construct_hp_parent_child();
745  if( MB_SUCCESS != result )
746  {
747  std::cerr << "Problem constructing parent/child relations between hyperplanes." << std::endl;
748  return result;
749  }
750 
751  // see? simple, just like I said
752  return MB_SUCCESS;
753 }

References construct_dual(), construct_dual_hyperplanes(), construct_hp_parent_child(), entities, ErrorCode, and MB_SUCCESS.

Referenced by atomic_pillow(), construct_hex_dual(), face_open_collapse(), face_shrink(), rev_atomic_pillow(), and rev_face_shrink().

◆ construct_hex_dual() [2/2]

ErrorCode moab::DualTool::construct_hex_dual ( Range entities)

construct the dual entities for a hex mesh, including dual surfaces & curves

Definition at line 709 of file DualTool.cpp.

710 {
711  std::vector< EntityHandle > evec;
712  std::copy( entities.begin(), entities.end(), std::back_inserter( evec ) );
713  return construct_hex_dual( &evec[0], evec.size() );
714 }

References construct_hex_dual(), and entities.

◆ construct_hp_parent_child()

ErrorCode moab::DualTool::construct_hp_parent_child ( )
private

connect dual surfaces with dual curves using parent/child connections

Definition at line 1141 of file DualTool.cpp.

1142 {
1143  Range dual_surfs, dual_cells, dual_edges;
1144  ErrorCode result = this->get_dual_hyperplanes( mbImpl, 2, dual_surfs );
1145  if( MB_SUCCESS != result || dual_surfs.empty() ) return result;
1146  std::vector< EntityHandle > dual_curve_sets;
1147 
1148  for( Range::iterator surf_it = dual_surfs.begin(); surf_it != dual_surfs.end(); ++surf_it )
1149  {
1150  // get all the cells, edges in those cells, and chords for those edges
1151  dual_cells.clear();
1152  result = mbImpl->get_entities_by_handle( *surf_it, dual_cells );
1153  if( MB_SUCCESS != result ) return result;
1154  dual_edges.clear();
1155  result = mbImpl->get_adjacencies( dual_cells, 1, false, dual_edges, Interface::UNION );
1156  if( MB_SUCCESS != result ) return result;
1157  dual_curve_sets.resize( dual_edges.size() );
1158  result = mbImpl->tag_get_data( dualCurve_tag(), dual_edges, &dual_curve_sets[0] );
1159  if( MB_SUCCESS != result ) return result;
1160 
1161  // reuse dual_cells to get unique list of chord sets
1162  dual_cells.clear();
1163  for( unsigned int i = 0; i < dual_edges.size(); i++ )
1164  if( dual_curve_sets[i] != 0 ) dual_cells.insert( dual_curve_sets[i] );
1165 
1166  // now connect up this dual surf with all the 1d ones
1167  for( Range::iterator rit = dual_cells.begin(); rit != dual_cells.end(); ++rit )
1168  {
1169  result = mbImpl->add_parent_child( *surf_it, *rit );
1170  if( MB_SUCCESS != result ) return result;
1171  }
1172  }
1173 
1174  return MB_SUCCESS;
1175 }

References moab::Interface::add_parent_child(), moab::Range::begin(), moab::Range::clear(), dualCurve_tag(), moab::Range::empty(), moab::Range::end(), ErrorCode, moab::Interface::get_adjacencies(), get_dual_hyperplanes(), moab::Interface::get_entities_by_handle(), moab::Range::insert(), MB_SUCCESS, mbImpl, moab::Range::size(), moab::Interface::tag_get_data(), and moab::Interface::UNION.

Referenced by construct_hex_dual().

◆ construct_new_hyperplane()

ErrorCode moab::DualTool::construct_new_hyperplane ( const int  dim,
EntityHandle new_hyperplane,
int &  id 
)
private

make a new dual hyperplane with the specified id; if the id specified is -1, set the new one's id to the max found

Definition at line 1083 of file DualTool.cpp.

1084 {
1085  ErrorCode result;
1086  if( 1 == dim )
1087  result = mbImpl->create_meshset( ( MESHSET_ORDERED | MESHSET_TRACK_OWNER ), new_hyperplane );
1088  else
1089  result = mbImpl->create_meshset( ( MESHSET_SET | MESHSET_TRACK_OWNER ), new_hyperplane );
1090  if( MB_SUCCESS != result ) return result;
1091 
1092  if( -1 == id )
1093  {
1094  Range all_hyperplanes;
1095  result = get_dual_hyperplanes( mbImpl, dim, all_hyperplanes );RR;
1096  std::vector< int > gids( all_hyperplanes.size() );
1097  result = mbImpl->tag_get_data( globalIdTag, all_hyperplanes, ( gids.empty() ) ? NULL : &gids[0] );RR;
1098  for( unsigned int i = 0; i < gids.size(); i++ )
1099  if( gids[i] > id ) id = gids[i];
1100  id++;
1101  if( 0 == id ) id++;
1102  }
1103 
1104  result = mbImpl->tag_set_data( globalId_tag(), &new_hyperplane, 1, &id );RR;
1105  Tag hp_tag = ( 1 == dim ? dualCurve_tag() : dualSurface_tag() );
1106  result = mbImpl->tag_set_data( hp_tag, &new_hyperplane, 1, &new_hyperplane );RR;
1107 
1108  // assign a category name to these sets
1109  static const char dual_category_names[2][CATEGORY_TAG_SIZE] = { "Chord\0", "Sheet\0" };
1110 
1111  result = mbImpl->tag_set_data( categoryTag, &new_hyperplane, 1, dual_category_names[dim - 1] );
1112 
1113  return result;
1114 }

References CATEGORY_TAG_SIZE, categoryTag, moab::Interface::create_meshset(), dim, dualCurve_tag(), dualSurface_tag(), ErrorCode, get_dual_hyperplanes(), globalId_tag(), globalIdTag, MB_SUCCESS, mbImpl, MESHSET_SET, MESHSET_TRACK_OWNER, RR, moab::Range::size(), moab::Interface::tag_get_data(), and moab::Interface::tag_set_data().

Referenced by traverse_hyperplane().

◆ delete_dual_entities() [1/2]

ErrorCode moab::DualTool::delete_dual_entities ( EntityHandle entities,
const int  num_entities 
)
private

delete a dual entity; updates primal to no longer point to it

Definition at line 1639 of file DualTool.cpp.

1640 {
1641  Range tmp_ents;
1642  std::copy( entities, entities + num_entities, range_inserter( tmp_ents ) );
1643  return delete_dual_entities( tmp_ents );
1644 }

References entities.

Referenced by atomic_pillow(), face_shrink(), foc_delete_dual(), rev_atomic_pillow(), and rev_face_shrink().

◆ delete_dual_entities() [2/2]

ErrorCode moab::DualTool::delete_dual_entities ( Range entities)
private

delete a range of dual entities; updates primal to no longer point to them

Definition at line 1646 of file DualTool.cpp.

1647 {
1648  if( entities.empty() ) return delete_whole_dual();
1649 
1650  EntityHandle null_entity = 0;
1651  ErrorCode result;
1652  Range ents_to_delete;
1653 
1654  while( !entities.empty() )
1655  {
1656  EntityHandle this_entity = entities.pop_back();
1657 
1658  // reset the primal's dual entity
1659  EntityHandle primal = get_dual_entity( this_entity );
1660  if( get_dual_entity( primal ) == this_entity )
1661  {
1662  result = mbImpl->tag_set_data( dualEntity_tag(), &primal, 1, &null_entity );RR;
1663  }
1664  EntityHandle extra = get_extra_dual_entity( primal );
1665  if( 0 != extra )
1666  {
1667  result = mbImpl->tag_set_data( extraDualEntity_tag(), &primal, 1, &null_entity );RR;
1668  }
1669 
1670  ents_to_delete.insert( this_entity );
1671 
1672  // check for extra dual entities
1673  if( mbImpl->type_from_handle( this_entity ) == MBPOLYGON )
1674  {
1675  // for 2cell, might be a loop edge
1676  Range loop_edges;
1677  result = mbImpl->get_adjacencies( &this_entity, 1, 1, false, loop_edges );
1678  for( Range::iterator rit = loop_edges.begin(); rit != loop_edges.end(); ++rit )
1679  if( check_1d_loop_edge( *rit ) ) entities.insert( *rit );
1680  }
1681  else if( extra && extra != this_entity )
1682  // just put it on the list; primal for which we're extra has already been
1683  // reset to not point to extra entity
1684  ents_to_delete.insert( extra );
1685  }
1686 
1687  // now delete the entities (sheets and chords will be updated automatically)
1688  return mbImpl->delete_entities( ents_to_delete );
1689 }

References moab::Range::begin(), check_1d_loop_edge(), moab::Interface::delete_entities(), delete_whole_dual(), dualEntity_tag(), moab::Range::end(), entities, ErrorCode, extraDualEntity_tag(), moab::Interface::get_adjacencies(), get_dual_entity(), get_extra_dual_entity(), moab::Range::insert(), mbImpl, MBPOLYGON, RR, moab::Interface::tag_set_data(), and moab::Interface::type_from_handle().

◆ delete_whole_dual()

ErrorCode moab::DualTool::delete_whole_dual ( )

delete all the dual data

Definition at line 3180 of file DualTool.cpp.

3181 {
3182  // delete dual hyperplanes
3183  Range dual_surfs, dual_curves;
3184  ErrorCode result = this->get_dual_hyperplanes( mbImpl, 2, dual_surfs );RR;
3185  result = mbImpl->delete_entities( dual_surfs );RR;
3186  result = this->get_dual_hyperplanes( mbImpl, 1, dual_curves );RR;
3187  result = mbImpl->delete_entities( dual_curves );RR;
3188 
3189  // gather up all dual entities
3190  Range dual_ents;
3191  result = mbImpl->get_entities_by_type_and_tag( 0, MBVERTEX, &isDualCellTag, NULL, 1, dual_ents, Interface::UNION );RR;
3192  result = mbImpl->get_entities_by_type_and_tag( 0, MBEDGE, &isDualCellTag, NULL, 1, dual_ents, Interface::UNION );RR;
3193  result = mbImpl->get_entities_by_type_and_tag( 0, MBPOLYGON, &isDualCellTag, NULL, 1, dual_ents, Interface::UNION );RR;
3194  result =
3196 
3197  // delete them, in reverse order of dimension
3198  ErrorCode tmp_result;
3199  for( Range::reverse_iterator rit = dual_ents.rbegin(); rit != dual_ents.rend(); ++rit )
3200  {
3201  tmp_result = mbImpl->delete_entities( &( *rit ), 1 );
3202  if( MB_SUCCESS != tmp_result ) result = tmp_result;
3203  }
3204  RR;
3205 
3206  // delete dual-related tags
3207  if( 0 != dualSurfaceTag )
3208  {
3209  tmp_result = mbImpl->tag_delete( dualSurfaceTag );
3210  if( MB_SUCCESS != tmp_result && MB_TAG_NOT_FOUND != tmp_result ) result = tmp_result;
3211  }
3212  if( 0 != dualCurveTag )
3213  {
3214  tmp_result = mbImpl->tag_delete( dualCurveTag );
3215  if( MB_SUCCESS != tmp_result && MB_TAG_NOT_FOUND != tmp_result ) result = tmp_result;
3216  }
3217  if( 0 != dualEntityTag )
3218  {
3219  tmp_result = mbImpl->tag_delete( dualEntityTag );
3220  if( MB_SUCCESS != tmp_result && MB_TAG_NOT_FOUND != tmp_result ) result = tmp_result;
3221  }
3222  if( 0 != extraDualEntityTag )
3223  {
3224  tmp_result = mbImpl->tag_delete( extraDualEntityTag );
3225  if( MB_SUCCESS != tmp_result && MB_TAG_NOT_FOUND != tmp_result ) result = tmp_result;
3226  }
3227  if( 0 != dualGraphicsPointTag )
3228  {
3229  tmp_result = mbImpl->tag_delete( dualGraphicsPointTag );
3230  if( MB_SUCCESS != tmp_result && MB_TAG_NOT_FOUND != tmp_result ) result = tmp_result;
3231  }
3232 
3233  return MB_SUCCESS;
3234 }

References moab::Interface::delete_entities(), dualCurveTag, dualEntityTag, dualGraphicsPointTag, dualSurfaceTag, ErrorCode, extraDualEntityTag, get_dual_hyperplanes(), moab::Interface::get_entities_by_type_and_tag(), isDualCellTag, MB_SUCCESS, MB_TAG_NOT_FOUND, MBEDGE, mbImpl, MBPOLYGON, MBPOLYHEDRON, MBVERTEX, moab::Range::rbegin(), moab::Range::rend(), RR, moab::Interface::tag_delete(), and moab::Interface::UNION.

Referenced by delete_dual_entities().

◆ dualCurve_tag() [1/2]

Tag moab::DualTool::dualCurve_tag ( ) const
inline

get/set the tag for dual curves

Definition at line 395 of file DualTool.hpp.

396 {
397  return dualCurveTag;
398 }

References dualCurveTag.

Referenced by construct_dual_hyperplanes(), construct_hp_parent_child(), construct_new_hyperplane(), get_dual_hyperplane(), list_entities(), and set_dual_surface_or_curve().

◆ dualCurve_tag() [2/2]

ErrorCode moab::DualTool::dualCurve_tag ( const Tag  tag)
inline

get/set the tag for dual curves

Definition at line 439 of file DualTool.hpp.

440 {
441  ErrorCode result = MB_FAILURE;
442  if( ( 0 == dualCurveTag && tag ) || dualCurveTag != tag )
443  {
444  dualCurveTag = tag;
445  result = MB_SUCCESS;
446  }
447 
448  return result;
449 }

References dualCurveTag, ErrorCode, and MB_SUCCESS.

◆ dualEntity_tag() [1/2]

◆ dualEntity_tag() [2/2]

ErrorCode moab::DualTool::dualEntity_tag ( const Tag  tag)
inline

get/set the tag for dual entities

Definition at line 465 of file DualTool.hpp.

466 {
467  ErrorCode result = MB_FAILURE;
468  if( ( 0 == dualEntityTag && tag ) || dualEntityTag != tag )
469  {
470  dualEntityTag = tag;
471  result = MB_SUCCESS;
472  }
473 
474  return result;
475 }

References dualEntityTag, ErrorCode, and MB_SUCCESS.

◆ dualGraphicsPoint_tag() [1/2]

Tag moab::DualTool::dualGraphicsPoint_tag ( ) const
inline

get/set the tag for dual entities

Definition at line 415 of file DualTool.hpp.

416 {
417  return dualGraphicsPointTag;
418 }

References dualGraphicsPointTag.

Referenced by add_graphics_point(), get_cell_points(), and get_graphics_points().

◆ dualGraphicsPoint_tag() [2/2]

ErrorCode moab::DualTool::dualGraphicsPoint_tag ( const Tag  tag)
inline

get/set the tag for dual entities

Definition at line 491 of file DualTool.hpp.

492 {
493  ErrorCode result = MB_FAILURE;
494  if( ( 0 == dualGraphicsPointTag && tag ) || dualGraphicsPointTag != tag )
495  {
496  dualGraphicsPointTag = tag;
497  result = MB_SUCCESS;
498  }
499 
500  return result;
501 }

References dualGraphicsPointTag, ErrorCode, and MB_SUCCESS.

◆ dualSurface_tag() [1/2]

Tag moab::DualTool::dualSurface_tag ( ) const
inline

get/set the tag for dual surfaces

Definition at line 390 of file DualTool.hpp.

391 {
392  return dualSurfaceTag;
393 }

References dualSurfaceTag.

Referenced by construct_dual_hyperplanes(), construct_new_hyperplane(), get_dual_hyperplane(), list_entities(), and set_dual_surface_or_curve().

◆ dualSurface_tag() [2/2]

ErrorCode moab::DualTool::dualSurface_tag ( const Tag  tag)
inline

get/set the tag for dual surfaces

Definition at line 426 of file DualTool.hpp.

427 {
428  ErrorCode result = MB_FAILURE;
429  if( ( 0 == dualSurfaceTag && tag ) || dualSurfaceTag != tag )
430  {
431  dualSurfaceTag = tag;
432  result = MB_SUCCESS;
433  }
434 
435  return result;
436 }

References dualSurfaceTag, ErrorCode, and MB_SUCCESS.

◆ extraDualEntity_tag() [1/2]

Tag moab::DualTool::extraDualEntity_tag ( ) const
inline

get/set the tag for dual entities

Definition at line 410 of file DualTool.hpp.

411 {
412  return extraDualEntityTag;
413 }

References extraDualEntityTag.

Referenced by construct_dual_vertex(), delete_dual_entities(), and get_extra_dual_entity().

◆ extraDualEntity_tag() [2/2]

ErrorCode moab::DualTool::extraDualEntity_tag ( const Tag  tag)
inline

get/set the tag for dual entities

Definition at line 478 of file DualTool.hpp.

479 {
480  ErrorCode result = MB_FAILURE;
481  if( ( 0 == extraDualEntityTag && tag ) || extraDualEntityTag != tag )
482  {
483  extraDualEntityTag = tag;
484  result = MB_SUCCESS;
485  }
486 
487  return result;
488 }

References ErrorCode, extraDualEntityTag, and MB_SUCCESS.

◆ face_open_collapse()

ErrorCode moab::DualTool::face_open_collapse ( EntityHandle  ocl,
EntityHandle  ocr 
)

effect a face open-collapse operation

Definition at line 1727 of file DualTool.cpp.

1728 {
1729  if( debug_ap ) ( (Core*)mbImpl )->check_adjacencies();
1730 
1731  MeshTopoUtil mtu( mbImpl );
1732 
1733  std::cout << "OC(";
1734  print_cell( ocl );
1735  std::cout << ")-(";
1736  print_cell( ocr );
1737  std::cout << ")" << std::endl;
1738 
1739  // get the primal entities we're dealing with
1740  EntityHandle split_quads[2] = { 0 }, split_edges[3] = { 0 }, split_nodes[2] = { 0 }, other_edges[6] = { 0 },
1741  other_nodes[6] = { 0 };
1742  Range hexes;
1743  ErrorCode result = foc_get_ents( ocl, ocr, split_quads, split_edges, split_nodes, hexes, other_edges, other_nodes );RR;
1744 
1745  // get star entities around edges, separated into halves
1746  std::vector< EntityHandle > star_dp1[2], star_dp2[2];
1747  result = foc_get_stars( split_quads, split_edges, star_dp1, star_dp2 );RR;
1748 
1749  if( MBQUAD != mbImpl->type_from_handle( split_quads[0] ) || MBQUAD != mbImpl->type_from_handle( split_quads[1] ) )
1750  return MB_TYPE_OUT_OF_RANGE;
1751 
1752  result = foc_delete_dual( split_quads, split_edges, hexes );
1753  if( MB_SUCCESS != result ) return result;
1754 
1755  EntityHandle new_quads[2], new_edges[3], new_nodes[2];
1756  result = split_pair_nonmanifold( split_quads, split_edges, split_nodes, star_dp1, star_dp2, other_edges,
1757  other_nodes, new_quads, new_edges, new_nodes );
1758  if( MB_SUCCESS != result ) return result;
1759 
1760  // now merge entities, the C of foc
1761  EntityHandle keepit, deleteit;
1762 #define MIN( a, b ) ( ( a ) < ( b ) ? ( a ) : ( b ) )
1763 #define MAX( a, b ) ( ( a ) > ( b ) ? ( a ) : ( b ) )
1764 #define KEEP_DELETE( a, b, c, d ) \
1765  { \
1766  ( c ) = MIN( a, b ); \
1767  ( d ) = MAX( a, b ); \
1768  }
1769 
1770  // find how many shared edges there were
1771  int num_shared_edges = ( split_edges[2] ? 3 : ( split_edges[1] ? 2 : 1 ) );
1772 
1773  // first the node(s)
1774  for( int i = 0; i < 3 - num_shared_edges; i++ )
1775  {
1776  KEEP_DELETE( other_nodes[2 + 2 * i], other_nodes[3 + 2 * i], keepit, deleteit );
1777  result = mbImpl->merge_entities( keepit, deleteit, false, true );RR;
1778  }
1779 
1780  // now the edges
1781  for( int i = 0; i < 4 - num_shared_edges; i++ )
1782  {
1783  KEEP_DELETE( other_edges[2 * i], other_edges[2 * i + 1], keepit, deleteit );
1784  result = mbImpl->merge_entities( keepit, deleteit, false, true );RR;
1785  }
1786 
1787  // now the faces
1788  KEEP_DELETE( split_quads[0], split_quads[1], keepit, deleteit );
1789  result = mbImpl->merge_entities( keepit, deleteit, false, true );RR;
1790 
1791  result = mbImpl->merge_entities( new_quads[0], new_quads[1], false, true );RR;
1792 
1793  if( debug_ap ) ( (Core*)mbImpl )->check_adjacencies();
1794 
1795  // reconstruct dual
1796  result = construct_hex_dual( hexes );
1797  if( MB_SUCCESS != result ) return result;
1798 
1799  return check_dual_adjs();
1800 }

References check_dual_adjs(), construct_hex_dual(), moab::debug_ap, ErrorCode, foc_delete_dual(), foc_get_ents(), foc_get_stars(), KEEP_DELETE, MB_SUCCESS, MB_TYPE_OUT_OF_RANGE, mbImpl, MBQUAD, moab::Interface::merge_entities(), print_cell(), RR, split_pair_nonmanifold(), and moab::Interface::type_from_handle().

◆ face_shrink()

ErrorCode moab::DualTool::face_shrink ( EntityHandle  odedge)

effect face shrink operation

Definition at line 2630 of file DualTool.cpp.

2631 {
2632  // some preliminary checking
2633  if( mbImpl->type_from_handle( odedge ) != MBEDGE ) return MB_TYPE_OUT_OF_RANGE;
2634 
2635  if( debug_ap ) ( (Core*)mbImpl )->check_adjacencies();
2636 
2637  std::cout << "FS(";
2638  print_cell( odedge );
2639  std::cout << ")" << std::endl;
2640 
2641  EntityHandle quads[4], hexes[2];
2642  std::vector< EntityHandle > connects[4], side_quads[2];
2643 
2644  // get the quads along the chord through the 2 hexes, and the vertices
2645  // for those quads
2646  ErrorCode result = fs_get_quads( odedge, quads, hexes, connects );
2647  if( MB_SUCCESS != result ) return result;
2648 
2649  // flip/rotate connect arrays so they align & are same sense
2650  result = fs_check_quad_sense( hexes[0], quads[0], connects );
2651  if( MB_SUCCESS != result ) return result;
2652 
2653  // get the quad loops along the "side" surfaces
2654  result = fs_get_quad_loops( hexes, connects, side_quads );
2655  if( MB_SUCCESS != result ) return result;
2656 
2657  // ok, done with setup; now delete dual entities affected by this operation,
2658  // which is all the entities adjacent to vertices of dual edge
2659  Range adj_verts, adj_edges, dual_ents, cells1or2;
2660  MeshTopoUtil mtu( mbImpl );
2661  result = mtu.get_bridge_adjacencies( odedge, 0, 1, adj_edges );
2662  if( MB_SUCCESS != result ) return result;
2663  result = mbImpl->get_adjacencies( adj_edges, 0, false, adj_verts, Interface::UNION );
2664  if( MB_SUCCESS != result ) return result;
2665  for( int i = 1; i <= 3; i++ )
2666  {
2667  result = mbImpl->get_adjacencies( adj_verts, i, false, dual_ents, Interface::UNION );
2668  if( MB_SUCCESS != result ) return result;
2669  }
2670 
2671  // before deleting dual, grab the 1- and 2-cells
2672  for( Range::iterator rit = dual_ents.begin(); rit != dual_ents.end(); ++rit )
2673  {
2674  int dim = mbImpl->dimension_from_handle( *rit );
2675  if( 1 == dim || 2 == dim ) cells1or2.insert( *rit );
2676  }
2677  Range dual_hps;
2678  for( Range::iterator rit = cells1or2.begin(); rit != cells1or2.end(); ++rit )
2679  dual_hps.insert( get_dual_hyperplane( *rit ) );
2680 
2681  dual_ents.insert( odedge );
2682  result = delete_dual_entities( dual_ents );
2683  if( MB_SUCCESS != result ) return result;
2684 
2685  // after deleting cells, check for empty chords & sheets, and delete those too
2686  for( Range::iterator rit = dual_hps.begin(); rit != dual_hps.end(); ++rit )
2687  {
2688  Range tmp_ents;
2689  result = mbImpl->get_entities_by_handle( *rit, tmp_ents );
2690  if( MB_SUCCESS != result ) return result;
2691  if( tmp_ents.empty() )
2692  {
2693  result = mbImpl->delete_entities( &( *rit ), 1 );
2694  if( MB_SUCCESS != result ) return result;
2695  }
2696  }
2697 
2698  // remove any explicit adjacencies between side quads and hexes; don't check
2699  // for error, since there might not be adjacencies
2700  for( int i = 0; i < 4; i++ )
2701  {
2702  for( int j = 0; j < 2; j++ )
2703  {
2704  result = mbImpl->remove_adjacencies( side_quads[j][i], &hexes[j], 1 );
2705  }
2706  }
2707 
2708  // make inner ring of vertices
2709  // get centroid of quad2
2710  double q2coords[12], avg[3] = { 0.0, 0.0, 0.0 };
2711  result = mbImpl->get_coords( &connects[1][0], 4, q2coords );
2712  if( MB_SUCCESS != result ) return result;
2713  for( int i = 0; i < 4; i++ )
2714  {
2715  avg[0] += q2coords[3 * i];
2716  avg[1] += q2coords[3 * i + 1];
2717  avg[2] += q2coords[3 * i + 2];
2718  }
2719  avg[0] *= .25;
2720  avg[1] *= .25;
2721  avg[2] *= .25;
2722  // position new vertices
2723  connects[3].resize( 4 );
2724  for( int i = 0; i < 4; i++ )
2725  {
2726  q2coords[3 * i] = avg[0] + .25 * ( q2coords[3 * i] - avg[0] );
2727  q2coords[3 * i + 1] = avg[1] + .25 * ( q2coords[3 * i + 1] - avg[1] );
2728  q2coords[3 * i + 2] = avg[2] + .25 * ( q2coords[3 * i + 2] - avg[2] );
2729  result = mbImpl->create_vertex( &q2coords[3 * i], connects[3][i] );
2730  if( MB_SUCCESS != result ) return result;
2731  }
2732 
2733  // ok, now have the 4 connectivity arrays for 4 quads; construct hexes
2734  EntityHandle hconnect[8], new_hexes[4];
2735  int new_hex_ids[4];
2736 
2737  for( int i = 0; i < 4; i++ )
2738  {
2739  int i1 = i, i2 = ( i + 1 ) % 4;
2740  hconnect[0] = connects[0][i1];
2741  hconnect[1] = connects[0][i2];
2742  hconnect[2] = connects[3][i2];
2743  hconnect[3] = connects[3][i1];
2744 
2745  hconnect[4] = connects[1][i1];
2746  hconnect[5] = connects[1][i2];
2747  hconnect[6] = connects[2][i2];
2748  hconnect[7] = connects[2][i1];
2749 
2750  result = mbImpl->create_element( MBHEX, hconnect, 8, new_hexes[i] );
2751  if( MB_SUCCESS != result ) return result;
2752 
2753  // test for equiv entities from the side quads, and make explicit adjacencies
2754  // if there are any
2755  for( int j = 0; j < 2; j++ )
2756  {
2757  if( mtu.equivalent_entities( side_quads[j][i] ) )
2758  {
2759  result = mbImpl->add_adjacencies( side_quads[j][i], &new_hexes[i], 1, false );
2760  if( MB_SUCCESS != result ) return result;
2761  }
2762  }
2763 
2764  new_hex_ids[i] = ++maxHexId;
2765  }
2766 
2767  // set the global id tag on the new hexes
2768  result = mbImpl->tag_set_data( globalId_tag(), new_hexes, 4, new_hex_ids );
2769  if( MB_SUCCESS != result ) return result;
2770 
2771  // now fixup other two hexes; start by getting hex through quads 0, 1
2772  // make this first hex switch to the other side, to make the dual look like
2773  // a hex push
2774  int tmp_ids[2];
2775  result = mbImpl->tag_get_data( globalId_tag(), hexes, 2, tmp_ids );
2776  if( MB_SUCCESS != result ) return result;
2777 
2778  result = mbImpl->delete_entities( hexes, 2 );
2779  if( MB_SUCCESS != result ) return result;
2780  result = mbImpl->delete_entities( &quads[1], 1 );
2781  if( MB_SUCCESS != result ) return result;
2782  for( int i = 0; i < 4; i++ )
2783  {
2784  hconnect[i] = connects[3][i];
2785  hconnect[4 + i] = connects[2][i];
2786  }
2787  result = mbImpl->create_element( MBHEX, hconnect, 8, hexes[0] );
2788  if( MB_SUCCESS != result ) return result;
2789 
2790  for( int i = 0; i < 4; i++ )
2791  {
2792  hconnect[i] = connects[0][i];
2793  hconnect[4 + i] = connects[3][i];
2794  }
2795  result = mbImpl->create_element( MBHEX, hconnect, 8, hexes[1] );
2796  if( MB_SUCCESS != result ) return result;
2797 
2798  // check for and fix any explicit adjacencies on either end quad
2799  if( mtu.equivalent_entities( quads[0] ) ) mbImpl->add_adjacencies( quads[0], &hexes[1], 1, false );
2800  if( mtu.equivalent_entities( quads[2] ) ) mbImpl->add_adjacencies( quads[2], &hexes[0], 1, false );
2801 
2802  // re-set the global ids for the hexes to what they were
2803  result = mbImpl->tag_set_data( globalId_tag(), hexes, 2, tmp_ids );
2804  if( MB_SUCCESS != result ) return result;
2805 
2806  if( debug_ap ) ( (Core*)mbImpl )->check_adjacencies();
2807 
2808  // now update the dual
2809  Range tmph;
2810  result = mtu.get_bridge_adjacencies( hexes[0], 0, 3, tmph );
2811  if( MB_SUCCESS != result ) return result;
2812  result = mtu.get_bridge_adjacencies( hexes[1], 0, 3, tmph );
2813  if( MB_SUCCESS != result ) return result;
2814  tmph.insert( hexes[1] );
2815  result = construct_hex_dual( tmph );
2816  if( MB_SUCCESS != result ) return result;
2817 
2818  return result;
2819 }

References moab::Interface::add_adjacencies(), moab::Range::begin(), construct_hex_dual(), moab::Interface::create_element(), moab::Interface::create_vertex(), moab::debug_ap, delete_dual_entities(), moab::Interface::delete_entities(), dim, moab::Interface::dimension_from_handle(), moab::Range::empty(), moab::Range::end(), moab::MeshTopoUtil::equivalent_entities(), ErrorCode, fs_check_quad_sense(), fs_get_quad_loops(), fs_get_quads(), moab::Interface::get_adjacencies(), moab::MeshTopoUtil::get_bridge_adjacencies(), moab::Interface::get_coords(), get_dual_hyperplane(), moab::Interface::get_entities_by_handle(), globalId_tag(), moab::Range::insert(), maxHexId, MB_SUCCESS, MB_TYPE_OUT_OF_RANGE, MBEDGE, MBHEX, mbImpl, print_cell(), moab::Interface::remove_adjacencies(), moab::Interface::tag_get_data(), moab::Interface::tag_set_data(), moab::Interface::type_from_handle(), and moab::Interface::UNION.

◆ foc_delete_dual()

ErrorCode moab::DualTool::foc_delete_dual ( EntityHandle split_quads,
EntityHandle split_edges,
Range hexes 
)
private

function for deleting dual prior to foc operation; special because in many cases need to delete a sheet in preparation for merging onto another

Definition at line 2289 of file DualTool.cpp.

2290 {
2291  // special delete dual procedure, because in some cases we need to delete
2292  // a sheet too since it'll get merged into another
2293 
2294  // figure out whether we'll need to delete a sheet
2295  EntityHandle sheet1 = get_dual_hyperplane( get_dual_entity( split_edges[0] ) );
2296  if( split_edges[1] ) sheet1 = get_dual_hyperplane( get_dual_entity( split_edges[1] ) );
2297  EntityHandle chordl = get_dual_hyperplane( get_dual_entity( split_quads[0] ) );
2298  EntityHandle chordr = get_dual_hyperplane( get_dual_entity( split_quads[1] ) );
2299  assert( 0 != sheet1 && 0 != chordl && 0 != chordr );
2300  Range parentsl, parentsr;
2301  ErrorCode result = mbImpl->get_parent_meshsets( chordl, parentsl );
2302  if( MB_SUCCESS != result ) return result;
2303  result = mbImpl->get_parent_meshsets( chordr, parentsr );
2304  if( MB_SUCCESS != result ) return result;
2305  parentsl.erase( sheet1 );
2306  parentsr.erase( sheet1 );
2307 
2308  // before deciding which one to delete, collect the other cells which must
2309  // be deleted, and all the chords/sheets they're on
2310  Range adj_ents, dual_ents, cells1or2;
2311  for( int i = 0; i < 3; i++ )
2312  {
2313  result = mbImpl->get_adjacencies( hexes, i, false, adj_ents, Interface::UNION );
2314  if( MB_SUCCESS != result ) return result;
2315  }
2316 
2317  // cache any adjacent hexes, for rebuilding the dual later
2318  result = mbImpl->get_adjacencies( adj_ents, 3, false, hexes, Interface::UNION );
2319  if( MB_SUCCESS != result ) return result;
2320 
2321  for( Range::iterator rit = adj_ents.begin(); rit != adj_ents.end(); ++rit )
2322  {
2323  EntityHandle this_ent = get_dual_entity( *rit );
2324  dual_ents.insert( this_ent );
2325  int dim = mbImpl->dimension_from_handle( this_ent );
2326  if( 1 == dim || 2 == dim ) cells1or2.insert( this_ent );
2327  }
2328 
2329  Range dual_hps;
2330  for( Range::iterator rit = cells1or2.begin(); rit != cells1or2.end(); ++rit )
2331  dual_hps.insert( get_dual_hyperplane( *rit ) );
2332 
2333  result = delete_dual_entities( dual_ents );
2334  if( MB_SUCCESS != result ) return result;
2335 
2336  // now decide which sheet to delete (to be merged into the other)
2337  EntityHandle sheet_delete = 0;
2338  if( is_blind( *parentsl.begin() ) )
2339  sheet_delete = *parentsl.begin();
2340  else if( is_blind( *parentsr.begin() ) )
2341  sheet_delete = *parentsr.begin();
2342  else
2343  {
2344  // neither is blind, take the one with fewer cells
2345  Range tmp_ents;
2346  int numl, numr;
2347  result = mbImpl->get_number_entities_by_handle( *parentsl.begin(), numl );
2348  if( MB_SUCCESS != result ) return result;
2349  result = mbImpl->get_number_entities_by_handle( *parentsr.begin(), numr );
2350  if( MB_SUCCESS != result ) return result;
2351  sheet_delete = ( numl > numr ? *parentsr.begin() : *parentsl.begin() );
2352  }
2353  assert( 0 != sheet_delete );
2354 
2355  // after deleting cells, check for empty chords & sheets, and delete those too
2356  for( Range::iterator rit = dual_hps.begin(); rit != dual_hps.end(); ++rit )
2357  {
2358  Range tmp_ents;
2359  result = mbImpl->get_entities_by_handle( *rit, tmp_ents );
2360  if( MB_SUCCESS != result ) return result;
2361  if( tmp_ents.empty() )
2362  {
2363  result = mbImpl->delete_entities( &( *rit ), 1 );
2364  if( MB_SUCCESS != result ) return result;
2365  }
2366  else if( *rit == sheet_delete )
2367  {
2368  // delete the sheet
2369  result = mbImpl->delete_entities( &( *rit ), 1 );
2370  if( MB_SUCCESS != result ) return result;
2371  }
2372  }
2373 
2374  // now just to be safe, add the hexes bridge-adjacent across vertices
2375  // to the hexes we already have
2376  Range tmp_hexes;
2377  MeshTopoUtil mtu( mbImpl );
2378  for( Range::iterator rit = hexes.begin(); rit != hexes.end(); ++rit )
2379  {
2380  result = mtu.get_bridge_adjacencies( *rit, 0, 3, tmp_hexes );
2381  if( MB_SUCCESS != result ) return result;
2382  }
2383  hexes.merge( tmp_hexes );
2384 
2385  return MB_SUCCESS;
2386 }

References moab::Range::begin(), delete_dual_entities(), moab::Interface::delete_entities(), dim, moab::Interface::dimension_from_handle(), moab::Range::empty(), moab::Range::end(), moab::Range::erase(), ErrorCode, moab::Interface::get_adjacencies(), moab::MeshTopoUtil::get_bridge_adjacencies(), get_dual_entity(), get_dual_hyperplane(), moab::Interface::get_entities_by_handle(), moab::Interface::get_number_entities_by_handle(), moab::Interface::get_parent_meshsets(), moab::Range::insert(), is_blind(), MB_SUCCESS, mbImpl, moab::Range::merge(), and moab::Interface::UNION.

Referenced by face_open_collapse().

◆ foc_get_addl_ents()

ErrorCode moab::DualTool::foc_get_addl_ents ( std::vector< EntityHandle > *  star_dp1,
std::vector< EntityHandle > *  star_dp2,
EntityHandle split_edges,
EntityHandle  split_node,
Range addl_ents 
)
private

for foc's splitting two shared edges, there might be additional entities connected to the split node that also have to be updated

Definition at line 2098 of file DualTool.cpp.

2103 {
2104  // if we're splitting 2 edges, there might be other edges that have the split
2105  // node; also need to know which side they're on
2106 
2107  // algorithm: for a given star_dp1 (faces) on a side:
2108  // - get all edges adj to all faces -> R1
2109  // - get all edges adj to split_node -> R2
2110  // - R3 = R1 & R2 (edges connected to split_node & adj to a star face)
2111  // - R3 -= split_edges (take split edges off addl_ents)
2112 
2113  Range R2;
2114  MeshTopoUtil mtu( mbImpl );
2115  ErrorCode result = mbImpl->get_adjacencies( &split_node, 1, 1, false, R2 );RR;
2116  Range::iterator rit;
2117 
2118  for( int i = 0; i < 2; i++ )
2119  {
2120  Range R1, R3;
2121  result = mbImpl->get_adjacencies( &star_dp1[i][0], star_dp1[i].size(), 1, false, R1, Interface::UNION );RR;
2122  R3 = intersect( R1, R2 );
2123  for( int j = 0; j < 3; j++ )
2124  if( split_edges[j] ) R3.erase( split_edges[j] );
2125  addl_ents[i].merge( R3 );
2126  }
2127 
2128  return MB_SUCCESS;
2129 }

References moab::Range::erase(), ErrorCode, moab::Interface::get_adjacencies(), moab::intersect(), MB_SUCCESS, mbImpl, moab::Range::merge(), RR, size, and moab::Interface::UNION.

Referenced by split_pair_nonmanifold().

◆ foc_get_ents()

ErrorCode moab::DualTool::foc_get_ents ( EntityHandle  ocl,
EntityHandle  ocr,
EntityHandle quads,
EntityHandle split_edges,
EntityHandle split_nodes,
Range hexes,
EntityHandle other_edges,
EntityHandle other_nodes 
)

given the two 1-cells involved in the foc, get entities associated with the quads being opened/collapsed; see implementation for more details

Definition at line 1802 of file DualTool.cpp.

1810 {
1811  // get the entities used for foc; ocl and ocr are dual 1-cells
1812  // representing quads to be split; returned from this function:
1813  // quads[2] - 2 quads to be split
1814  // split_edges[2] - edge(s) to be split (2nd is 0 if only one)
1815  // split_node - node to be split, if any (otherwise 0)
1816  // hexes - connected hexes to split_edges
1817  // other_edges[0], [1] - edges in quads[0] and [1] sharing node with
1818  // one end of split_edges[0]
1819  // other_edges[2], [3] - other end of split_edges[0] (or [1] if 2
1820  // split_edges)
1821  // other_edges[4], [5] - edges in quads[0], [1] opposite to split_edges[0]
1822  // other_nodes[0], [1] - nodes on other_edges[0], [1] not shared with
1823  // split_edges[0]
1824  // other_nodes[2], [3] - nodes on other_edges[2], [3] not shared with
1825  // split_edges[0] (if 2 split_edges, there's only 1 opposite node
1826  // in each split quad)
1827  // (for diagram, see Tim's notes from 11/12/07)
1828 
1829  split_quads[0] = get_dual_entity( ocl );
1830  split_quads[1] = get_dual_entity( ocr );
1831  if( MBQUAD != mbImpl->type_from_handle( split_quads[0] ) || MBQUAD != mbImpl->type_from_handle( split_quads[1] ) )
1832  return MB_TYPE_OUT_OF_RANGE;
1833 
1834  Range common_edges;
1835  ErrorCode result = mbImpl->get_adjacencies( split_quads, 2, 1, false, common_edges );
1836  if( MB_SUCCESS != result ) return result;
1837 
1838  if( common_edges.empty() ) return MB_FAILURE;
1839  for( unsigned int i = 0; i < common_edges.size(); i++ )
1840  split_edges[i] = common_edges[i];
1841 
1842  MeshTopoUtil mtu( mbImpl );
1843 
1844  if( common_edges.size() == 3 )
1845  {
1846  // find other (non-shared) edges
1847  for( int i = 0; i < 2; i++ )
1848  {
1849  Range tmp_edges;
1850  result = mbImpl->get_adjacencies( &split_quads[i], 1, 1, false, tmp_edges );
1851  if( MB_SUCCESS != result ) return result;
1852  tmp_edges = subtract( tmp_edges, common_edges );
1853  assert( tmp_edges.size() == 1 );
1854  other_edges[i] = *tmp_edges.begin();
1855  }
1856  assert( other_edges[0] && other_edges[1] && other_edges[0] != other_edges[1] );
1857 
1858  // arrange common edges so middle is in middle
1859  result = mtu.opposite_entity( split_quads[0], other_edges[0], split_edges[1] );RR;
1860  common_edges.erase( split_edges[1] );
1861  split_edges[0] = *common_edges.begin();
1862  split_edges[2] = *common_edges.rbegin();
1863  common_edges.insert( split_edges[1] );
1864 
1865  // get split nodes and other nodes
1866  split_nodes[0] = mtu.common_entity( split_edges[0], split_edges[1], 0 );
1867  split_nodes[1] = mtu.common_entity( split_edges[2], split_edges[1], 0 );
1868  other_nodes[0] = mtu.common_entity( split_edges[0], other_edges[0], 0 );
1869  other_nodes[1] = mtu.common_entity( split_edges[2], other_edges[1], 0 );
1870 
1871  assert( other_nodes[0] && other_nodes[1] && split_nodes[0] && split_nodes[1] );
1872  assert( split_edges[0] && split_edges[1] && split_edges[2] && split_edges[0] != split_edges[1] &&
1873  split_edges[1] != split_edges[2] && split_edges[0] != split_edges[2] );
1874  }
1875  else if( common_edges.size() == 2 )
1876  {
1877  // split node is shared by split edges
1878  split_nodes[0] = mtu.common_entity( split_edges[0], split_edges[1], 0 );
1879  if( 0 == split_nodes[0] ) return MB_FAILURE;
1880  // first two other nodes are on split edges opposite split node
1881  result = mtu.opposite_entity( split_edges[0], split_nodes[0], other_nodes[0] );RR;
1882  result = mtu.opposite_entity( split_edges[1], split_nodes[0], other_nodes[1] );RR;
1883  // over split quads:
1884  for( int i = 0; i < 2; i++ )
1885  {
1886  // 1st other edge is opposite second split edge
1887  result = mtu.opposite_entity( split_quads[i], split_edges[1], other_edges[i] );RR;
1888  // 2nd other edge is opposite first split edge
1889  result = mtu.opposite_entity( split_quads[i], split_edges[0], other_edges[2 + i] );RR;
1890  // last other node is opposite split node on split quad
1891  result = mtu.opposite_entity( split_quads[i], split_nodes[0], other_nodes[2 + i] );RR;
1892  }
1893  }
1894  else
1895  {
1896  const EntityHandle* connect;
1897  int num_connect;
1898  result = mbImpl->get_connectivity( split_edges[0], connect, num_connect );
1899  if( MB_SUCCESS != result ) return result;
1900  // other_nodes[0], [1] are on split edge
1901  other_nodes[0] = connect[0];
1902  other_nodes[1] = connect[1];
1903 
1904  // for each of the split quads
1905  for( int i = 0; i < 2; i++ )
1906  {
1907  // get the other edge on the split quad adj to node 0 on the split edge, by getting
1908  // edges adj to split quad and node and removing split edge; that's other_edge[i]
1909  Range tmp_range1, tmp_range2;
1910  tmp_range1.insert( connect[0] );
1911  tmp_range1.insert( split_quads[i] );
1912  result = mbImpl->get_adjacencies( tmp_range1, 1, false, tmp_range2 );
1913  if( MB_SUCCESS != result ) return result;
1914  tmp_range2.erase( split_edges[0] );
1915  assert( tmp_range2.size() == 1 );
1916  other_edges[i] = *tmp_range2.begin();
1917  // get edge connected to other node on split edge & split quad; that's
1918  // opposite prev other_edges on the split quad; that's other_edges[4+i]
1919  result = mtu.opposite_entity( split_quads[i], other_edges[i], other_edges[4 + i] );RR;
1920  // get the edge on the split quad opposite the split edge; that's other_edges[2+i]
1921  result = mtu.opposite_entity( split_quads[i], split_edges[0], other_edges[2 + i] );RR;
1922  // get nodes on other side of split quad from split edge, by getting common
1923  // node between top/bottom edge and opposite edge
1924  other_nodes[2 + i] = mtu.common_entity( other_edges[i], other_edges[2 + i], 0 );
1925  other_nodes[4 + i] = mtu.common_entity( other_edges[4 + i], other_edges[2 + i], 0 );
1926  if( 0 == other_nodes[2 + i] || 0 == other_nodes[4 + i] ) return MB_FAILURE;
1927  }
1928  }
1929 
1930  result = mbImpl->get_adjacencies( split_edges, common_edges.size(), 3, false, hexes, Interface::UNION );
1931  if( MB_SUCCESS != result ) return result;
1932 
1933  assert( "split node not in other_nodes" && other_nodes[0] != split_nodes[0] && other_nodes[0] != split_nodes[1] &&
1934  other_nodes[1] != split_nodes[0] && other_nodes[1] != split_nodes[1] );
1935  assert( "each split node on an end of a split edge" && mtu.common_entity( other_nodes[0], split_edges[0], 0 ) &&
1936  ( ( ( split_edges[2] && mtu.common_entity( other_nodes[1], split_edges[2], 0 ) ) ||
1937  ( split_edges[1] && mtu.common_entity( other_nodes[1], split_edges[1], 0 ) ) ||
1938  mtu.common_entity( other_nodes[1], split_edges[0], 0 ) ) ) );
1939  assert( "opposite other edges meet at an other node" &&
1940  ( mtu.common_entity( other_edges[0], other_edges[1], 0 ) == other_nodes[0] ||
1941  ( split_edges[2] && mtu.common_entity( other_edges[0], other_edges[1], 0 ) == other_nodes[1] ) ) &&
1942  ( split_edges[2] ||
1943  ( split_edges[1] && mtu.common_entity( other_edges[2], other_edges[3], 0 ) == other_nodes[1] ) ||
1944  mtu.common_entity( other_edges[4], other_edges[5], 0 ) == other_nodes[1] ) );
1945 
1946  return MB_SUCCESS;
1947 }

References moab::Range::begin(), moab::MeshTopoUtil::common_entity(), moab::Range::empty(), moab::Range::erase(), ErrorCode, moab::Interface::get_adjacencies(), moab::Interface::get_connectivity(), get_dual_entity(), moab::Range::insert(), MB_SUCCESS, MB_TYPE_OUT_OF_RANGE, mbImpl, MBQUAD, moab::MeshTopoUtil::opposite_entity(), moab::Range::rbegin(), RR, moab::Range::size(), moab::subtract(), moab::Interface::type_from_handle(), and moab::Interface::UNION.

Referenced by face_open_collapse().

◆ foc_get_stars()

ErrorCode moab::DualTool::foc_get_stars ( EntityHandle split_quads,
EntityHandle split_edges,
std::vector< EntityHandle > *  star_dp1,
std::vector< EntityHandle > *  star_dp2 
)
private

given the split quads and edges, get the face and hex stars around the edge(s), separated into halves, each of which goes with the new or old entities after the split

Definition at line 2131 of file DualTool.cpp.

2135 {
2136  bool on_bdy = false, on_bdy_tmp;
2137  ErrorCode result;
2138  MeshTopoUtil mtu( mbImpl );
2139 
2140  // get the star around the split_edge
2141  std::vector< EntityHandle > qstar, hstar;
2142  unsigned int qpos = 0;
2143 
2144  for( int i = 0; i < 3; i++ )
2145  {
2146  if( !split_edges[i] ) break;
2147 
2148  // get the star around this split edge
2149  unsigned int qpos_tmp = 0;
2150  std::vector< EntityHandle > qstar_tmp, hstar_tmp;
2151  result = mtu.star_entities( split_edges[i], qstar_tmp, on_bdy_tmp, 0, &hstar_tmp );RR;
2152  // if we're on the bdy, add a null to the hex star too
2153  if( on_bdy_tmp )
2154  {
2155  assert( hstar_tmp.size() == qstar_tmp.size() - 1 );
2156  hstar_tmp.push_back( 0 );
2157  on_bdy = true;
2158  }
2159 
2160  // get the position of first split quad in star
2161  while( qpos_tmp < qstar_tmp.size() && qstar_tmp[qpos_tmp] != split_quads[0] )
2162  qpos_tmp++;
2163  if( qpos_tmp == qstar_tmp.size() ) return MB_FAILURE;
2164 
2165  bool forward;
2166  // 1st iteration is forward by definition
2167  if( 0 == i ) forward = true;
2168 
2169  // need to be careful about direction on later iters
2170  else if( hstar[qpos] == hstar_tmp[qpos_tmp] )
2171  forward = true;
2172  else if( hstar[qpos] == hstar_tmp[( qpos_tmp + qstar_tmp.size() - 1 ) % qstar_tmp.size()] &&
2173  hstar_tmp[qpos_tmp] == hstar[( qpos + qstar.size() - 1 ) % qstar.size()] )
2174  forward = false;
2175  else
2176  return MB_FAILURE;
2177 
2178  if( forward )
2179  {
2180  // 1st half of star
2181  // save hex right after split_quad[0] first
2182  star_dp2[0].push_back( hstar_tmp[qpos_tmp] );
2183  qpos_tmp = ( qpos_tmp + 1 ) % qstar_tmp.size();
2184  while( qstar_tmp[qpos_tmp] != split_quads[1] )
2185  {
2186  star_dp1[0].push_back( qstar_tmp[qpos_tmp] );
2187  star_dp2[0].push_back( hstar_tmp[qpos_tmp] );
2188  qpos_tmp = ( qpos_tmp + 1 ) % qstar_tmp.size();
2189  }
2190  // 2nd half of star
2191  // save hex right after split_quad[1] first
2192  star_dp2[1].push_back( hstar_tmp[qpos_tmp] );
2193  qpos_tmp = ( qpos_tmp + 1 ) % qstar_tmp.size();
2194  while( qstar_tmp[qpos_tmp] != split_quads[0] )
2195  {
2196  star_dp1[1].push_back( qstar_tmp[qpos_tmp] );
2197  star_dp2[1].push_back( hstar_tmp[qpos_tmp] );
2198  qpos_tmp = ( qpos_tmp + 1 ) % qstar_tmp.size();
2199  }
2200  }
2201  else
2202  {
2203  // go in reverse - take prev hex instead of current
2204  // one, and step in reverse
2205 
2206  // save hex right after split_quad[0] first
2207  qpos_tmp = ( qpos_tmp + qstar_tmp.size() - 1 ) % qstar_tmp.size();
2208  star_dp2[0].push_back( hstar_tmp[qpos_tmp] );
2209  while( qstar_tmp[qpos_tmp] != split_quads[1] )
2210  {
2211  star_dp1[0].push_back( qstar_tmp[qpos_tmp] );
2212  qpos_tmp = ( qpos_tmp + qstar_tmp.size() - 1 ) % qstar_tmp.size();
2213  star_dp2[0].push_back( hstar_tmp[qpos_tmp] );
2214  }
2215  // 2nd half of star
2216  // save hex right after split_quad[1] first
2217  qpos_tmp = ( qpos_tmp + qstar_tmp.size() - 1 ) % qstar_tmp.size();
2218  star_dp2[1].push_back( hstar_tmp[qpos_tmp] );
2219  while( qstar_tmp[qpos_tmp] != split_quads[0] )
2220  {
2221  star_dp1[1].push_back( qstar_tmp[qpos_tmp] );
2222  qpos_tmp = ( qpos_tmp + qstar_tmp.size() - 1 ) % qstar_tmp.size();
2223  star_dp2[1].push_back( hstar_tmp[qpos_tmp] );
2224  }
2225  }
2226 
2227  if( 0 == i )
2228  {
2229  // if we're on the first iteration, save results and continue, other iters
2230  // get compared to this one
2231  qstar.swap( qstar_tmp );
2232  hstar.swap( hstar_tmp );
2233  on_bdy = on_bdy_tmp;
2234  qpos = qpos_tmp;
2235  }
2236  }
2237 
2238  // split quads go on list with NULLs, if any, otherwise on 2nd
2239  if( on_bdy )
2240  {
2241  if( std::find( star_dp2[0].begin(), star_dp2[0].end(), 0 ) != star_dp2[0].end() )
2242  {
2243  // remove *all* the zeros
2244  star_dp2[0].erase( std::remove( star_dp2[0].begin(), star_dp2[0].end(), 0 ), star_dp2[0].end() );
2245  // put the split quads on this half
2246  star_dp1[0].push_back( split_quads[0] );
2247  star_dp1[0].push_back( split_quads[1] );
2248  }
2249  else
2250  {
2251  star_dp2[1].erase( std::remove( star_dp2[1].begin(), star_dp2[1].end(), 0 ), star_dp2[1].end() );
2252  // put the split quads on this half
2253  star_dp1[1].push_back( split_quads[0] );
2254  star_dp1[1].push_back( split_quads[1] );
2255  }
2256  }
2257  else
2258  {
2259  star_dp1[1].push_back( split_quads[0] );
2260  star_dp1[1].push_back( split_quads[1] );
2261  }
2262 
2263  // some error checking
2264  if( !( ( ( std::find( star_dp1[0].begin(), star_dp1[0].end(), split_quads[0] ) == star_dp1[0].end() &&
2265  std::find( star_dp1[0].begin(), star_dp1[0].end(), split_quads[1] ) == star_dp1[0].end() &&
2266  std::find( star_dp1[1].begin(), star_dp1[1].end(), split_quads[0] ) != star_dp1[1].end() &&
2267  std::find( star_dp1[1].begin(), star_dp1[1].end(), split_quads[1] ) != star_dp1[1].end() ) ||
2268 
2269  ( std::find( star_dp1[1].begin(), star_dp1[1].end(), split_quads[0] ) == star_dp1[1].end() &&
2270  std::find( star_dp1[1].begin(), star_dp1[1].end(), split_quads[1] ) == star_dp1[1].end() &&
2271  std::find( star_dp1[0].begin(), star_dp1[0].end(), split_quads[0] ) != star_dp1[0].end() &&
2272  std::find( star_dp1[0].begin(), star_dp1[0].end(), split_quads[1] ) != star_dp1[0].end() ) ) ) )
2273  {
2274  std::cerr << "foc_get_stars: both split quads should be on the same star list half and not "
2275  << "on the other, failed" << std::endl;
2276  return MB_FAILURE;
2277  }
2278 
2279  if( !( std::find( star_dp2[0].begin(), star_dp2[0].end(), 0 ) == star_dp2[0].end() &&
2280  std::find( star_dp2[1].begin(), star_dp2[1].end(), 0 ) == star_dp2[1].end() ) )
2281  {
2282  std::cerr << "foc_get_stars: no NULLs on the hstar lists, failed";
2283  return MB_FAILURE;
2284  }
2285 
2286  return MB_SUCCESS;
2287 }

References ErrorCode, MB_SUCCESS, mbImpl, RR, and moab::MeshTopoUtil::star_entities().

Referenced by face_open_collapse().

◆ fs_check_quad_sense()

ErrorCode moab::DualTool::fs_check_quad_sense ( EntityHandle  hex0,
EntityHandle  quad0,
std::vector< EntityHandle > *  connects 
)
private

check sense of connect arrays, and reverse/rotate if necessary

Definition at line 2846 of file DualTool.cpp.

2847 {
2848  // check sense of 0th quad wrt hex; since sense is out of element,
2849  // switch if quad is NOT reversed wrt hex
2850  int dum1, dum2, sense = 0;
2851  ErrorCode result = mbImpl->side_number( hex0, quad0, dum1, sense, dum2 );
2852  if( MB_SUCCESS != result ) return result;
2853  assert( 0 != sense );
2854  if( 1 == sense )
2855  {
2856  // just switch sense of this one; others will get switched next
2857  EntityHandle dum = connects[0][0];
2858  connects[0][0] = connects[0][2];
2859  connects[0][2] = dum;
2860  }
2861 
2862  // check sense of 1st, 2nd quads, rotate if necessary to align connect arrays
2863  int index0 = -1, index2 = -1, sense0 = 0, sense2 = 0;
2864  MeshTopoUtil mtu( mbImpl );
2865  for( int i = 0; i < 4; i++ )
2866  {
2867  if( 0 != mtu.common_entity( connects[0][0], connects[1][i], 1 ) )
2868  {
2869  index0 = i;
2870  if( 0 != mtu.common_entity( connects[0][1], connects[1][( i + 1 ) % 4], 1 ) )
2871  sense0 = 1;
2872  else if( 0 != mtu.common_entity( connects[0][1], connects[1][( i + 4 - 1 ) % 4], 1 ) )
2873  sense0 = -1;
2874  break;
2875  }
2876  }
2877 
2878  assert( index0 != -1 && sense0 != 0 );
2879 
2880  if( sense0 == -1 )
2881  {
2882  EntityHandle dumh = connects[1][0];
2883  connects[1][0] = connects[1][2];
2884  connects[1][2] = dumh;
2885  if( index0 % 2 == 0 ) index0 = ( index0 + 2 ) % 4;
2886  }
2887 
2888  if( index0 != 0 )
2889  {
2890  std::vector< EntityHandle > tmpc;
2891  for( int i = 0; i < 4; i++ )
2892  tmpc.push_back( connects[1][( index0 + i ) % 4] );
2893  connects[1].swap( tmpc );
2894  }
2895 
2896  for( int i = 0; i < 4; i++ )
2897  {
2898  if( 0 != mtu.common_entity( connects[1][0], connects[2][i], 1 ) )
2899  {
2900  index2 = i;
2901  if( 0 != mtu.common_entity( connects[1][1], connects[2][( i + 1 ) % 4], 1 ) )
2902  sense2 = 1;
2903  else if( 0 != mtu.common_entity( connects[1][1], connects[2][( i + 4 - 1 ) % 4], 1 ) )
2904  sense2 = -1;
2905  break;
2906  }
2907  }
2908 
2909  assert( index2 != -1 && sense2 != 0 );
2910 
2911  if( sense2 == -1 )
2912  {
2913  EntityHandle dumh = connects[2][0];
2914  connects[2][0] = connects[2][2];
2915  connects[2][2] = dumh;
2916  if( index2 % 2 == 0 ) index2 = ( index2 + 2 ) % 4;
2917  }
2918 
2919  if( index2 != 0 )
2920  {
2921  std::vector< EntityHandle > tmpc;
2922  for( int i = 0; i < 4; i++ )
2923  tmpc.push_back( connects[2][( index2 + i ) % 4] );
2924  connects[2].swap( tmpc );
2925  }
2926 
2927  return MB_SUCCESS;
2928 }

References moab::MeshTopoUtil::common_entity(), moab::dum, ErrorCode, MB_SUCCESS, mbImpl, and moab::Interface::side_number().

Referenced by face_shrink(), and rev_face_shrink().

◆ fs_get_quad_loops()

ErrorCode moab::DualTool::fs_get_quad_loops ( EntityHandle hexes,
std::vector< EntityHandle > *  connects,
std::vector< EntityHandle > *  side_quads 
)
private

get loops of quads around 2 hexes, ordered similarly to vertex loops

Definition at line 2821 of file DualTool.cpp.

2824 {
2825  for( int i = 0; i < 4; i++ )
2826  {
2827  for( int j = 0; j < 2; j++ )
2828  {
2829  Range adj_ents, dum_quads;
2830  adj_ents.insert( hexes[j] );
2831  adj_ents.insert( connects[j][i] );
2832  adj_ents.insert( connects[j][( i + 1 ) % 4] );
2833  adj_ents.insert( connects[j + 1][i] );
2834  adj_ents.insert( connects[j + 1][( i + 1 ) % 4] );
2835 
2836  ErrorCode result = mbImpl->get_adjacencies( adj_ents, 2, false, dum_quads );
2837  if( MB_SUCCESS != result ) return result;
2838  assert( 1 == dum_quads.size() );
2839  side_quads[j].push_back( *dum_quads.begin() );
2840  }
2841  }
2842 
2843  return MB_SUCCESS;
2844 }

References moab::Range::begin(), ErrorCode, moab::Interface::get_adjacencies(), moab::Range::insert(), MB_SUCCESS, mbImpl, and moab::Range::size().

Referenced by face_shrink().

◆ fs_get_quads()

ErrorCode moab::DualTool::fs_get_quads ( EntityHandle  odedge,
EntityHandle quads,
EntityHandle hexes,
std::vector< EntityHandle > *  connects 
)
private

get the three quads for a face shrink, the two hexes, and the connectivity of the three quads

Definition at line 3138 of file DualTool.cpp.

3142 {
3143  // need to get the three quads along the chord
3144  EntityHandle chord = get_dual_hyperplane( odedge );
3145  if( 0 == chord ) return MB_FAILURE;
3146 
3147  std::vector< EntityHandle > edges;
3148  ErrorCode result = mbImpl->get_entities_by_handle( chord, edges );
3149  if( MB_FAILURE == result ) return result;
3150 
3151  std::vector< EntityHandle >::iterator vit = std::find( edges.begin(), edges.end(), odedge );
3152  // shouldn't be first or last edge on chord
3153  if( vit == edges.end() || *edges.begin() == *vit || *edges.rbegin() == *vit ) return MB_FAILURE;
3154 
3155  // get quads/connectivity for first 3 quads
3156  quads[0] = get_dual_entity( *( vit - 1 ) );
3157  quads[1] = get_dual_entity( *vit );
3158  quads[2] = get_dual_entity( *( vit + 1 ) );
3159  for( int i = 0; i < 3; i++ )
3160  {
3161  result = mbImpl->get_connectivity( &quads[i], 1, connects[i], true );
3162  if( MB_SUCCESS != result ) return result;
3163  }
3164 
3165  Range tmph;
3166  result = mbImpl->get_adjacencies( quads, 2, 3, false, tmph );
3167  if( MB_SUCCESS != result ) return result;
3168  assert( tmph.size() == 1 );
3169  hexes[0] = *tmph.begin();
3170 
3171  tmph.clear();
3172  result = mbImpl->get_adjacencies( &quads[1], 2, 3, false, tmph );
3173  if( MB_SUCCESS != result ) return result;
3174  assert( tmph.size() == 1 );
3175  hexes[1] = *tmph.begin();
3176 
3177  return MB_SUCCESS;
3178 }

References moab::Range::begin(), moab::Range::clear(), ErrorCode, moab::Interface::get_adjacencies(), moab::Interface::get_connectivity(), get_dual_entity(), get_dual_hyperplane(), moab::Interface::get_entities_by_handle(), MB_SUCCESS, mbImpl, and moab::Range::size().

Referenced by face_shrink(), and rev_face_shrink().

◆ fsr_get_fourth_quad()

ErrorCode moab::DualTool::fsr_get_fourth_quad ( std::vector< EntityHandle > *  connects,
std::vector< EntityHandle > *  side_quads 
)
private

given connectivity of first 3 quads for reverse face shrink, get fourth (outer 4 verts to be shared by two inner hexes) and quads around the side of the structure

Definition at line 3082 of file DualTool.cpp.

3084 {
3085  // given the first three quad connectivities in ordered vectors, get the fourth,
3086  // where the fourth is really the 4 vertices originally shared by the 2 hexes
3087  // before the face shrink on them
3088 
3089  // vertex on 4th quad is in quad adj to other 3 verts
3090  for( int i = 0; i < 4; i++ )
3091  {
3092  Range start_verts, tmp_verts, quads;
3093  for( int j = 0; j < 3; j++ )
3094  start_verts.insert( connects[j][i] );
3095  ErrorCode result = mbImpl->get_adjacencies( start_verts, 2, false, quads );
3096  if( MB_SUCCESS != result ) return result;
3097  assert( quads.size() == 1 );
3098  result = mbImpl->get_adjacencies( &( *quads.begin() ), 1, 0, false, tmp_verts );RR;
3099  tmp_verts = subtract( tmp_verts, start_verts );
3100  assert( 1 == tmp_verts.size() );
3101  connects[3].push_back( *tmp_verts.begin() );
3102  }
3103 
3104  // now get the side quads
3105  for( int i = 0; i < 4; i++ )
3106  {
3107  Range dum_ents, hexes;
3108  dum_ents.insert( connects[1][i] );
3109  dum_ents.insert( connects[1][( i + 1 ) % 4] );
3110  dum_ents.insert( connects[3][i] );
3111  ErrorCode result = mbImpl->get_adjacencies( dum_ents, 3, false, hexes );
3112  if( MB_SUCCESS != result ) return result;
3113  assert( 1 == hexes.size() );
3114 
3115  hexes.insert( connects[0][i] );
3116  hexes.insert( connects[0][( i + 1 ) % 4] );
3117  hexes.insert( connects[3][i] );
3118  hexes.insert( connects[3][( i + 1 ) % 4] );
3119  dum_ents.clear();
3120  result = mbImpl->get_adjacencies( hexes, 2, false, dum_ents );
3121  if( MB_SUCCESS != result ) return result;
3122  assert( dum_ents.size() == 1 );
3123  side_quads[0].push_back( *dum_ents.begin() );
3124 
3125  hexes.erase( connects[0][i] );
3126  hexes.erase( connects[0][( i + 1 ) % 4] );
3127  hexes.insert( connects[2][i] );
3128  hexes.insert( connects[2][( i + 1 ) % 4] );
3129  dum_ents.clear();
3130  result = mbImpl->get_adjacencies( hexes, 2, false, dum_ents );
3131  if( MB_SUCCESS != result ) return result;
3132  side_quads[1].push_back( *dum_ents.begin() );
3133  }
3134 
3135  return MB_SUCCESS;
3136 }

References moab::Range::begin(), moab::Range::clear(), moab::Range::erase(), ErrorCode, moab::Interface::get_adjacencies(), moab::Range::insert(), MB_SUCCESS, mbImpl, RR, moab::Range::size(), and moab::subtract().

Referenced by rev_face_shrink().

◆ get_cell_points()

ErrorCode moab::DualTool::get_cell_points ( EntityHandle  dual_ent,
std::vector< int > &  npts,
std::vector< GraphicsPoint > &  points 
)
private

get points defining facets of a 2cell

Definition at line 1228 of file DualTool.cpp.

1231 {
1232  assert( MBPOLYGON == mbImpl->type_from_handle( dual_ent ) );
1233 
1234  // get the 1cells in this 2cell
1235  Range one_cells;
1236 
1237  Range tc_range;
1238  tc_range.insert( dual_ent );
1239  ErrorCode result = mbImpl->get_adjacencies( tc_range, 1, false, one_cells, Interface::UNION );RR;
1240 
1241  int num_edges = one_cells.size();
1242  std::vector< GraphicsPoint > dum_gps( num_edges + 1 );
1243 
1244  // get graphics points for 0cells and for this cell
1245  result = mbImpl->tag_get_data( dualGraphicsPoint_tag(), one_cells, &dum_gps[0] );RR;
1246  result = mbImpl->tag_get_data( dualGraphicsPoint_tag(), &dual_ent, 1, &( dum_gps[num_edges] ) );RR;
1247 
1248  Range::iterator eit;
1249  const EntityHandle* connect;
1250  int num_connect;
1251  GraphicsPoint vert_gps[2];
1252  int i;
1253  for( i = 0, eit = one_cells.begin(); i < num_edges; i++, ++eit )
1254  {
1255  // get the vertices and the graphics points for them
1256  result = mbImpl->get_connectivity( *eit, connect, num_connect );RR;
1257  result = mbImpl->tag_get_data( dualGraphicsPoint_tag(), connect, 2, vert_gps );RR;
1258 
1259  // make the 2 tris corresponding to this edge; don't worry about order
1260  // for now
1261  npts.push_back( 3 );
1262  points.push_back( dum_gps[num_edges] );
1263  points.push_back( vert_gps[0] );
1264  points.push_back( dum_gps[i] );
1265 
1266  npts.push_back( 3 );
1267  points.push_back( dum_gps[num_edges] );
1268  points.push_back( dum_gps[i] );
1269  points.push_back( vert_gps[1] );
1270  }
1271 
1272  return result;
1273 }

References moab::Range::begin(), dualGraphicsPoint_tag(), ErrorCode, moab::Interface::get_adjacencies(), moab::Interface::get_connectivity(), moab::Range::insert(), mbImpl, MBPOLYGON, RR, moab::Range::size(), moab::Interface::tag_get_data(), moab::Interface::type_from_handle(), and moab::Interface::UNION.

Referenced by get_graphics_points().

◆ get_dual_entities() [1/3]

ErrorCode moab::DualTool::get_dual_entities ( const EntityHandle  dual_ent,
Range dcells,
Range dedges,
Range dverts,
Range dverts_loop,
Range dedges_loop 
)

given a dual surface or curve, return the 2-cells, 1-cells, 0-cells, and loop 0/1-cells, if requested; any of those range pointers can be NULL, in which case that range isn't returned

Definition at line 2496 of file DualTool.cpp.

2502 {
2503  ErrorCode result = MB_SUCCESS;
2504 
2505  if( NULL != dcells )
2506  {
2507  result = mbImpl->get_entities_by_type( dual_ent, MBPOLYGON, *dcells );
2508  if( MB_SUCCESS != result ) return result;
2509  }
2510 
2511  if( NULL != dedges )
2512  {
2513  if( NULL != dcells )
2514  result = mbImpl->get_adjacencies( *dcells, 1, false, *dedges, Interface::UNION );
2515  else
2516  result = mbImpl->get_entities_by_type( dual_ent, MBEDGE, *dedges );
2517 
2518  if( MB_SUCCESS != result ) return result;
2519  }
2520 
2521  if( NULL != dverts )
2522  {
2523  if( NULL != dcells )
2524  result = mbImpl->get_adjacencies( *dcells, 0, false, *dverts, Interface::UNION );
2525  else if( NULL != dedges )
2526  result = mbImpl->get_adjacencies( *dedges, 0, false, *dverts, Interface::UNION );
2527  else
2528  {
2529  Range all_ents;
2530  result = mbImpl->get_entities_by_handle( dual_ent, all_ents );RR;
2531  result = mbImpl->get_adjacencies( all_ents, 0, false, *dverts, Interface::UNION );
2532  }
2533 
2534  if( MB_SUCCESS != result ) return result;
2535  }
2536 
2537  if( NULL != dverts_loop && NULL != dverts )
2538  {
2539  static std::vector< EntityHandle > dual_ents;
2540  dual_ents.resize( dverts->size() );
2541  result = mbImpl->tag_get_data( dualEntity_tag(), *dverts, &dual_ents[0] );
2542  if( MB_SUCCESS != result ) return result;
2543  Range::iterator rit;
2544  unsigned int i;
2545  for( rit = dverts->begin(), i = 0; rit != dverts->end(); ++rit, i++ )
2546  if( 0 != dual_ents[i] && mbImpl->type_from_handle( dual_ents[i] ) == MBQUAD ) dverts_loop->insert( *rit );
2547  }
2548 
2549  if( NULL != dedges_loop && NULL != dedges )
2550  {
2551  static std::vector< EntityHandle > dual_ents;
2552  dual_ents.resize( dedges->size() );
2553  result = mbImpl->tag_get_data( dualEntity_tag(), *dedges, &dual_ents[0] );
2554  if( MB_SUCCESS != result ) return result;
2555  Range::iterator rit;
2556  unsigned int i;
2557  for( rit = dedges->begin(), i = 0; rit != dedges->end(); ++rit, i++ )
2558  if( 0 != dual_ents[i] && mbImpl->type_from_handle( dual_ents[i] ) == MBEDGE ) dedges_loop->insert( *rit );
2559  }
2560 
2561  return result;
2562 }

References moab::Range::begin(), dualEntity_tag(), moab::Range::end(), ErrorCode, moab::Interface::get_adjacencies(), moab::Interface::get_entities_by_handle(), moab::Interface::get_entities_by_type(), moab::Range::insert(), MB_SUCCESS, MBEDGE, mbImpl, MBPOLYGON, MBQUAD, RR, moab::Range::size(), moab::Interface::tag_get_data(), moab::Interface::type_from_handle(), and moab::Interface::UNION.

◆ get_dual_entities() [2/3]

ErrorCode moab::DualTool::get_dual_entities ( const int  dim,
EntityHandle entities,
const int  num_entities,
Range dual_ents 
)

get the dual entities; if non-null, only dual of entities passed in are returned

get the cells of the dual

Definition at line 756 of file DualTool.cpp.

757 {
758  if( 0 == isDualCell_tag() ) return MB_SUCCESS;
759  if( 0 > dim || 3 < dim ) return MB_INDEX_OUT_OF_RANGE;
760 
761  unsigned int dum = 0x1;
762  const void* dum_ptr = &dum;
763  static EntityType dual_type[] = { MBVERTEX, MBEDGE, MBPOLYGON, MBPOLYHEDRON };
764 
765  Range dim_ents;
766 
767  ErrorCode result;
768 
769  if( 0 == entities || 0 == num_entities )
770  {
771  // just get all the dual entities of this dimension
772  result = mbImpl->get_entities_by_type_and_tag( 0, dual_type[dim], &isDualCellTag, &dum_ptr, 1, dual_ents );
773  }
774  else
775  {
776  // else look for specific dual entities
777  result = mbImpl->get_adjacencies( entities, num_entities, 3 - dim, false, dim_ents, Interface::UNION );
778  if( MB_SUCCESS != result ) return result;
779  std::vector< EntityHandle > dual_ents_vec( dim_ents.size() );
780  result = mbImpl->tag_get_data( dualEntity_tag(), dim_ents, &dual_ents_vec[0] );
781  if( MB_SUCCESS != result ) return result;
782  std::copy( dual_ents_vec.begin(), dual_ents_vec.end(), range_inserter( dual_ents ) );
783  }
784 
785  return result;
786 }

References dim, dualEntity_tag(), moab::dum, entities, ErrorCode, moab::Interface::get_adjacencies(), moab::Interface::get_entities_by_type_and_tag(), isDualCell_tag(), isDualCellTag, MB_INDEX_OUT_OF_RANGE, MB_SUCCESS, MBEDGE, mbImpl, MBPOLYGON, MBPOLYHEDRON, MBVERTEX, moab::Range::size(), moab::Interface::tag_get_data(), and moab::Interface::UNION.

Referenced by construct_dual_hyperplanes(), get_dual_entities(), and rev_atomic_pillow().

◆ get_dual_entities() [3/3]

ErrorCode moab::DualTool::get_dual_entities ( const int  dim,
EntityHandle entities,
const int  num_entities,
std::vector< EntityHandle > &  dual_ents 
)

get the dual entities; if non-null, only dual of entities passed in are returned

get the faces of the dual

Definition at line 789 of file DualTool.cpp.

793 {
794  Range tmp_range;
795  ErrorCode result = get_dual_entities( dim, entities, num_entities, tmp_range );
796  if( MB_SUCCESS != result ) return result;
797 
798  // dual_ents.insert(dual_ents.end(), tmp_range.begin(), tmp_range.end());
799  dual_ents.reserve( dual_ents.size() + tmp_range.size() );
800  for( Range::const_iterator it = tmp_range.begin(); it != tmp_range.end(); ++it )
801  {
802  dual_ents.push_back( *it );
803  }
804  return MB_SUCCESS;
805 }

References moab::Range::begin(), dim, moab::Range::end(), entities, ErrorCode, get_dual_entities(), MB_SUCCESS, and moab::Range::size().

◆ get_dual_entity()

EntityHandle moab::DualTool::get_dual_entity ( const EntityHandle  this_ent) const

return the corresponding dual entity

Definition at line 1414 of file DualTool.cpp.

1415 {
1416  EntityHandle dual_ent;
1417  ErrorCode result = mbImpl->tag_get_data( dualEntity_tag(), &this_ent, 1, &dual_ent );
1418  if( MB_SUCCESS != result || MB_TAG_NOT_FOUND == result )
1419  return 0;
1420  else
1421  return dual_ent;
1422 }

References dualEntity_tag(), ErrorCode, MB_SUCCESS, MB_TAG_NOT_FOUND, mbImpl, and moab::Interface::tag_get_data().

Referenced by atomic_pillow(), check_dual_adjs(), delete_dual_entities(), foc_delete_dual(), foc_get_ents(), fs_get_quads(), is_blind(), list_entities(), order_chord(), and rev_face_shrink().

◆ get_dual_hyperplane()

EntityHandle moab::DualTool::get_dual_hyperplane ( const EntityHandle  ncell)

given an entity, return any dual surface or curve it's in

Definition at line 1380 of file DualTool.cpp.

1381 {
1382  // get the sheet or chord it's in
1383  std::vector< EntityHandle > adj_sets;
1384  ErrorCode result = mbImpl->get_adjacencies( &ncell, 1, 4, false, adj_sets );
1385  if( MB_SUCCESS != result ) return 0;
1386 
1387  EntityHandle dum_set;
1388  for( std::vector< EntityHandle >::iterator vit = adj_sets.begin(); vit != adj_sets.end(); ++vit )
1389  {
1390  if( mbImpl->tag_get_data( dualCurve_tag(), &( *vit ), 1, &dum_set ) != MB_TAG_NOT_FOUND ||
1391  mbImpl->tag_get_data( dualSurface_tag(), &( *vit ), 1, &dum_set ) != MB_TAG_NOT_FOUND )
1392  return *vit;
1393  }
1394 
1395  return 0;
1396 }

References dualCurve_tag(), dualSurface_tag(), ErrorCode, moab::Interface::get_adjacencies(), MB_SUCCESS, MB_TAG_NOT_FOUND, mbImpl, and moab::Interface::tag_get_data().

Referenced by face_shrink(), foc_delete_dual(), fs_get_quads(), rev_face_shrink(), and traverse_hyperplane().

◆ get_dual_hyperplanes()

ErrorCode moab::DualTool::get_dual_hyperplanes ( const Interface impl,
const int  dim,
Range dual_ents 
)
static

get the d-dimensional hyperplane sets; static 'cuz it's easy to do without an active dualtool

Definition at line 807 of file DualTool.cpp.

808 {
809  if( dim != 1 && dim != 2 ) return MB_INDEX_OUT_OF_RANGE;
810 
811  Tag dual_tag;
812  ErrorCode result;
813 
814  if( dim == 1 )
815  result = impl->tag_get_handle( DUAL_CURVE_TAG_NAME, 1, MB_TYPE_HANDLE, dual_tag );
816  else
817  result = impl->tag_get_handle( DUAL_SURFACE_TAG_NAME, 1, MB_TYPE_HANDLE, dual_tag );
818 
819  if( MB_SUCCESS == result )
820  result = impl->get_entities_by_type_and_tag( 0, MBENTITYSET, &dual_tag, NULL, 1, dual_ents, Interface::UNION );
821 
822  return result;
823 }

References dim, DUAL_CURVE_TAG_NAME, DUAL_SURFACE_TAG_NAME, ErrorCode, moab::Interface::get_entities_by_type_and_tag(), MB_INDEX_OUT_OF_RANGE, MB_SUCCESS, MB_TYPE_HANDLE, MBENTITYSET, moab::Interface::tag_get_handle(), and moab::Interface::UNION.

Referenced by construct_hp_parent_child(), construct_new_hyperplane(), and delete_whole_dual().

◆ get_extra_dual_entity()

EntityHandle moab::DualTool::get_extra_dual_entity ( const EntityHandle  this_ent)

return the corresponding extra dual entity

return the corresponding dual entity

Definition at line 1425 of file DualTool.cpp.

1426 {
1427  EntityHandle dual_ent;
1428  ErrorCode result = mbImpl->tag_get_data( extraDualEntity_tag(), &this_ent, 1, &dual_ent );
1429  if( MB_SUCCESS != result || MB_TAG_NOT_FOUND == result )
1430  return 0;
1431  else
1432  return dual_ent;
1433 }

References ErrorCode, extraDualEntity_tag(), MB_SUCCESS, MB_TAG_NOT_FOUND, mbImpl, and moab::Interface::tag_get_data().

Referenced by delete_dual_entities().

◆ get_graphics_points() [1/2]

ErrorCode moab::DualTool::get_graphics_points ( const Range in_range,
std::vector< GraphicsPoint > &  gpoints,
const bool  assign_ids = false,
const int  start_id = 0 
)

get the graphics points for a range of entities or sets (if set, the entities in those sets); optionally reset ids on points

Definition at line 1275 of file DualTool.cpp.

1279 {
1280  // return graphics points on dual entities in in_range or in entities
1281  // in sets in in_range
1282  ErrorCode result;
1283 
1284  // for each dual hyperplane set:
1285  Range::const_iterator rit;
1286 
1287  Range two_cells, all_cells;
1288  for( rit = in_range.begin(); rit != in_range.end(); ++rit )
1289  {
1290  // for each entity:
1291  two_cells.clear();
1292  EntityType this_type = mbImpl->type_from_handle( *rit );
1293  if( MBENTITYSET == this_type )
1294  {
1295  result = mbImpl->get_entities_by_handle( *rit, two_cells );RR;
1296 
1297  std::copy( two_cells.begin(), two_cells.end(), range_inserter( all_cells ) );
1298  }
1299 
1300  else
1301  {
1302  two_cells.insert( *rit );
1303  assert( this_type == MBVERTEX || this_type == MBEDGE || this_type == MBPOLYGON ||
1304  this_type == MBPOLYHEDRON );
1305  }
1306 
1307  result = mbImpl->get_adjacencies( two_cells, 0, false, all_cells, Interface::UNION );RR;
1308  result = mbImpl->get_adjacencies( two_cells, 1, false, all_cells, Interface::UNION );RR;
1309  }
1310 
1311  // get graphics points
1312  points.resize( all_cells.size() );
1313 
1314  result = mbImpl->tag_get_data( dualGraphicsPointTag, all_cells, &points[0] );RR;
1315 
1316  if( assign_ids )
1317  {
1318  int i = start_id;
1319 
1320  for( std::vector< GraphicsPoint >::iterator vit = points.begin(); vit != points.end(); ++vit )
1321  vit->id = i++;
1322 
1323  result = mbImpl->tag_set_data( dualGraphicsPoint_tag(), all_cells, &points[0] );RR;
1324  }
1325 
1326  return result;
1327 }

References moab::Range::begin(), moab::Range::clear(), dualGraphicsPoint_tag(), dualGraphicsPointTag, moab::Range::end(), ErrorCode, moab::Interface::get_adjacencies(), moab::Interface::get_entities_by_handle(), in_range(), moab::Range::insert(), MBEDGE, MBENTITYSET, mbImpl, MBPOLYGON, MBPOLYHEDRON, MBVERTEX, RR, moab::Range::size(), moab::Interface::tag_get_data(), moab::Interface::tag_set_data(), moab::Interface::type_from_handle(), and moab::Interface::UNION.

◆ get_graphics_points() [2/2]

ErrorCode moab::DualTool::get_graphics_points ( EntityHandle  dual_ent,
std::vector< int > &  npts,
std::vector< GraphicsPoint > &  gpoints 
)

get the graphics points for single entity (dual_ent CAN'T be a set); returns multiple facets, each with npts[i] points

Definition at line 1177 of file DualTool.cpp.

1180 {
1181  // shouldn't be a set
1182  assert( MBENTITYSET != mbImpl->type_from_handle( dual_ent ) );
1183 
1184  // get the graphics points comprising the given entity
1185  GraphicsPoint gp_array[DualTool::GP_SIZE];
1186 
1187  ErrorCode result = MB_SUCCESS;
1188 
1189  // switch based on topological dimension
1190  switch( mbImpl->dimension_from_handle( dual_ent ) )
1191  {
1192  case 0:
1193  // just return the vertex point
1194  result = mbImpl->tag_get_data( dualGraphicsPoint_tag(), &dual_ent, 1, gp_array );
1195  if( MB_SUCCESS == result ) points.push_back( gp_array[0] );
1196 
1197  break;
1198 
1199  case 1:
1200  // get my graphics point then those of my vertices
1201  const EntityHandle* connect;
1202  int num_connect;
1203  result = mbImpl->get_connectivity( dual_ent, connect, num_connect );
1204  if( MB_SUCCESS != result ) break;
1205 
1206  result = mbImpl->tag_get_data( dualGraphicsPoint_tag(), connect, 2, gp_array );
1207  if( MB_SUCCESS == result )
1208  {
1209  points.push_back( gp_array[0] );
1210  points.push_back( gp_array[0] );
1211  points.push_back( gp_array[1] );
1212  result = mbImpl->tag_get_data( dualGraphicsPoint_tag(), &dual_ent, 1, gp_array );
1213  if( MB_SUCCESS == result ) points[1] = gp_array[0];
1214  }
1215 
1216  npts.push_back( 3 );
1217 
1218  break;
1219 
1220  case 2:
1221  result = get_cell_points( dual_ent, npts, points );
1222  break;
1223  }
1224 
1225  return result;
1226 }

References moab::Interface::dimension_from_handle(), dualGraphicsPoint_tag(), ErrorCode, get_cell_points(), moab::Interface::get_connectivity(), GP_SIZE, MB_SUCCESS, MBENTITYSET, mbImpl, moab::Interface::tag_get_data(), and moab::Interface::type_from_handle().

◆ get_opposite_verts()

ErrorCode moab::DualTool::get_opposite_verts ( const EntityHandle  middle_edge,
const EntityHandle  chord,
EntityHandle verts 
)

given a 1-cell and a chord, return the neighboring vertices on the chord, in the same order as the 1-cell's vertices

Definition at line 2416 of file DualTool.cpp.

2417 {
2418  // get the edges on the chord, in order, and move to middle_edge
2419  std::vector< EntityHandle > chord_edges;
2420  const EntityHandle* connect;
2421  int num_connect;
2422 
2423  ErrorCode result = mbImpl->get_entities_by_handle( chord, chord_edges );RR;
2424  std::vector< EntityHandle >::iterator vit = std::find( chord_edges.begin(), chord_edges.end(), middle_edge );
2425  result = mbImpl->get_connectivity( middle_edge, connect, num_connect );RR;
2426 
2427  if(
2428  // middle_edge isn't on this chord
2429  vit == chord_edges.end() ||
2430  // chord only has 1 edge
2431  chord_edges.size() == 1 ||
2432  // middle_edge is at beginning or end and chord isn't blind
2433  ( ( vit == chord_edges.begin() || vit == chord_edges.end() - 1 ) && !is_blind( chord ) ) )
2434  return MB_FAILURE;
2435 
2436  else if( chord_edges.size() == 2 )
2437  {
2438  // easier if it's a 2-edge blind chord, just get vertices in opposite order
2439  verts[0] = connect[1];
2440  verts[1] = connect[0];
2441  return MB_SUCCESS;
2442  }
2443 
2444  // get vertices with the prev edge & subtract vertices of 1-cell
2445  if( vit == chord_edges.begin() )
2446  vit = chord_edges.end() - 1;
2447  else
2448  --vit;
2449  Range dum_connect, middle_connect;
2450  result = mbImpl->get_connectivity( &middle_edge, 1, middle_connect );RR;
2451  result = mbImpl->get_connectivity( &( *vit ), 1, dum_connect );RR;
2452  dum_connect = subtract( dum_connect, middle_connect );
2453  if( dum_connect.size() != 1 )
2454  {
2455  std::cerr << "Trouble traversing chord." << std::endl;
2456  return MB_FAILURE;
2457  }
2458 
2459  // put in verts[0]
2460  verts[0] = *dum_connect.begin();
2461 
2462  // same with prev edge
2463  ++vit;
2464  if( vit == chord_edges.end() ) vit = chord_edges.begin();
2465  ++vit;
2466  dum_connect.clear();
2467  result = mbImpl->get_connectivity( &( *vit ), 1, dum_connect );RR;
2468  dum_connect = subtract( dum_connect, middle_connect );
2469  if( dum_connect.size() != 1 )
2470  {
2471  std::cerr << "Trouble traversing chord." << std::endl;
2472  return MB_FAILURE;
2473  }
2474 
2475  // put in verts[1]
2476  verts[1] = *dum_connect.begin();
2477 
2478  // if verts[0] and 1st vertex of 1cell don't have common edge, switch verts
2479  MeshTopoUtil mtu( mbImpl );
2480  if( 0 == mtu.common_entity( verts[0], connect[0], 1 ) )
2481  {
2482  EntityHandle dum_h = verts[0];
2483  verts[0] = verts[1];
2484  verts[1] = dum_h;
2485  }
2486 
2487  if( 0 == mtu.common_entity( verts[0], connect[0], 1 ) )
2488  {
2489  std::cerr << "Trouble traversing chord." << std::endl;
2490  return MB_FAILURE;
2491  }
2492 
2493  return MB_SUCCESS;
2494 }

References moab::Range::begin(), moab::Range::clear(), moab::MeshTopoUtil::common_entity(), ErrorCode, moab::Interface::get_connectivity(), moab::Interface::get_entities_by_handle(), is_blind(), MB_SUCCESS, mbImpl, RR, moab::Range::size(), and moab::subtract().

◆ get_radial_dverts()

ErrorCode moab::DualTool::get_radial_dverts ( const EntityHandle  edge,
std::vector< EntityHandle > &  rad_verts,
bool &  bdy_edge 
)
private

given an edge handle, return a list of dual vertices in radial order around the edge; also returns whether this edge is on the boundary

given an edge handle, return a list of dual vertices in radial order around the edge

Definition at line 663 of file DualTool.cpp.

666 {
667  rad_dverts.clear();
668 
669  std::vector< EntityHandle > rad_faces, rad_ents;
670  ErrorCode result = MeshTopoUtil( mbImpl ).star_entities( edge, rad_faces, bdy_edge, 0, &rad_ents );
671  if( MB_SUCCESS != result ) return result;
672 
673  if( bdy_edge )
674  {
675  // if we're a bdy edge, change the order back to what DualTool expects
676  rad_ents.push_back( *rad_faces.rbegin() );
677  rad_ents.push_back( *rad_faces.begin() );
678  }
679 
680  rad_dverts.resize( rad_ents.size() );
681  for( unsigned int i = 0; i < rad_ents.size(); i++ )
682  {
683  EntityHandle dual_ent;
684  result = mbImpl->tag_get_data( dualEntity_tag(), &rad_ents[i], 1, &dual_ent );
685  if( !bdy_edge || i < rad_ents.size() - 2 )
686  rad_dverts[i] = dual_ent;
687  else
688  {
689  // fix up this entry
690  assert( mbImpl->type_from_handle( dual_ent ) == MBEDGE );
691 
692  // get connectivity of that edge
693  const EntityHandle* connect;
694  int num_connect;
695  result = mbImpl->get_connectivity( dual_ent, connect, num_connect );
696  if( MB_SUCCESS != result ) return result;
697 
698  // we want the one that's not already on the list; reuse last_face
699  int last_hex = ( i == rad_ents.size() - 1 ? 0 : i - 1 );
700  EntityHandle last_face = ( connect[0] == rad_dverts[last_hex] ? connect[1] : connect[0] );
701  rad_dverts[i] = last_face;
702  }
703  }
704 
705  return result;
706 }

References dualEntity_tag(), ErrorCode, moab::Interface::get_connectivity(), MB_SUCCESS, MBEDGE, mbImpl, moab::MeshTopoUtil::star_entities(), moab::Interface::tag_get_data(), and moab::Interface::type_from_handle().

Referenced by construct_dual_faces().

◆ globalId_tag() [1/2]

Tag moab::DualTool::globalId_tag ( ) const
inline

get/set the global id tag

Definition at line 420 of file DualTool.hpp.

421 {
422  return globalIdTag;
423 }

References globalIdTag.

Referenced by atomic_pillow(), construct_dual(), construct_new_hyperplane(), face_shrink(), list_entities(), and traverse_hyperplane().

◆ globalId_tag() [2/2]

ErrorCode moab::DualTool::globalId_tag ( const Tag  tag)
inline

get/set the tag for dual entities

Definition at line 504 of file DualTool.hpp.

505 {
506  ErrorCode result = MB_FAILURE;
507  if( ( 0 == globalIdTag && tag ) || globalIdTag != tag )
508  {
509  globalIdTag = tag;
510  result = MB_SUCCESS;
511  }
512 
513  return result;
514 }

References ErrorCode, globalIdTag, and MB_SUCCESS.

◆ is_blind()

bool moab::DualTool::is_blind ( const EntityHandle  chord)

returns true if first & last vertices are dual to hexes (not faces)

returns true if all vertices are dual to hexes (not faces)

Definition at line 2389 of file DualTool.cpp.

2390 {
2391  // must be an entity set
2392  if( TYPE_FROM_HANDLE( chord_or_sheet ) != MBENTITYSET ) return false;
2393 
2394  // get the vertices
2395  Range verts, ents;
2396  ErrorCode result = mbImpl->get_entities_by_handle( chord_or_sheet, ents );
2397  if( MB_SUCCESS != result || ents.empty() ) return false;
2398 
2399  result = mbImpl->get_adjacencies( ents, 0, false, verts, Interface::UNION );
2400  if( MB_SUCCESS != result || verts.empty() ) return false;
2401 
2402  for( Range::iterator rit = verts.begin(); rit != verts.end(); ++rit )
2403  {
2404  // get dual entity for this vertex
2405  EntityHandle dual_ent = get_dual_entity( *rit );
2406  if( 0 == dual_ent ) continue;
2407  if( TYPE_FROM_HANDLE( dual_ent ) == MBQUAD ) return false;
2408  }
2409 
2410  // if none of the vertices' duals were quads, chord_or_sheet must be blind
2411  return true;
2412 }

References moab::Range::begin(), moab::Range::empty(), moab::Range::end(), ErrorCode, moab::Interface::get_adjacencies(), get_dual_entity(), moab::Interface::get_entities_by_handle(), MB_SUCCESS, MBENTITYSET, mbImpl, MBQUAD, moab::TYPE_FROM_HANDLE(), and moab::Interface::UNION.

Referenced by foc_delete_dual(), and get_opposite_verts().

◆ isDualCell_tag() [1/2]

Tag moab::DualTool::isDualCell_tag ( ) const
inline

get/set the tag for dual cells

Definition at line 400 of file DualTool.hpp.

401 {
402  return isDualCellTag;
403 }

References isDualCellTag.

Referenced by check_1d_loop_edge(), construct_dual_cells(), construct_dual_edges(), construct_dual_faces(), construct_dual_vertex(), and get_dual_entities().

◆ isDualCell_tag() [2/2]

ErrorCode moab::DualTool::isDualCell_tag ( const Tag  tag)
inline

get/set the tag for dual cells

Definition at line 452 of file DualTool.hpp.

453 {
454  ErrorCode result = MB_FAILURE;
455  if( ( 0 == isDualCellTag && tag ) || isDualCellTag != tag )
456  {
457  isDualCellTag = tag;
458  result = MB_SUCCESS;
459  }
460 
461  return result;
462 }

References ErrorCode, isDualCellTag, and MB_SUCCESS.

◆ list_entities() [1/2]

ErrorCode moab::DualTool::list_entities ( const EntityHandle entities,
const int  num_entities 
) const

Definition at line 2564 of file DualTool.cpp.

2565 {
2566  Range temp_range;
2567  ErrorCode result;
2568  if( NULL == entities && 0 == num_entities )
2569  return mbImpl->list_entities( entities, num_entities );
2570 
2571  else if( NULL == entities && 0 < num_entities )
2572  {
2573 
2574  // list all entities of all types
2575  std::cout << std::endl;
2576  for( EntityType this_type = MBVERTEX; this_type < MBMAXTYPE; this_type++ )
2577  {
2578  result = mbImpl->get_entities_by_type( 0, this_type, temp_range );
2579  if( MB_SUCCESS != result ) return result;
2580  }
2581  }
2582 
2583  else
2584  {
2585  std::copy( entities, entities + num_entities, range_inserter( temp_range ) );
2586  }
2587 
2588  return list_entities( temp_range );
2589 }

References entities, ErrorCode, moab::Interface::get_entities_by_type(), list_entities(), moab::Interface::list_entities(), MB_SUCCESS, mbImpl, MBMAXTYPE, and MBVERTEX.

◆ list_entities() [2/2]

ErrorCode moab::DualTool::list_entities ( const Range entities) const

Definition at line 2591 of file DualTool.cpp.

2592 {
2593  // now print each entity, listing the dual information first then calling Interface to do
2594  // the rest
2595  ErrorCode result = MB_SUCCESS, tmp_result;
2596  for( Range::const_iterator iter = entities.begin(); iter != entities.end(); ++iter )
2597  {
2598  EntityType this_type = TYPE_FROM_HANDLE( *iter );
2599  std::cout << CN::EntityTypeName( this_type ) << " " << ID_FROM_HANDLE( *iter ) << ":" << std::endl;
2600 
2601  EntityHandle dual_ent = get_dual_entity( *iter );
2602  if( 0 != dual_ent )
2603  {
2604  std::cout << "Dual to " << CN::EntityTypeName( mbImpl->type_from_handle( dual_ent ) ) << " "
2605  << mbImpl->id_from_handle( dual_ent ) << std::endl;
2606  }
2607 
2608  if( TYPE_FROM_HANDLE( *iter ) == MBENTITYSET )
2609  {
2610  EntityHandle chord = 0, sheet = 0;
2611  int id;
2612  result = mbImpl->tag_get_data( dualCurve_tag(), &( *iter ), 1, &chord );
2613  if( MB_SUCCESS != result ) return result;
2614  result = mbImpl->tag_get_data( dualSurface_tag(), &( *iter ), 1, &sheet );
2615  if( MB_SUCCESS != result ) return result;
2616  result = mbImpl->tag_get_data( globalId_tag(), &( *iter ), 1, &id );
2617  if( MB_SUCCESS != result ) return result;
2618 
2619  if( 0 != chord ) std::cout << "(Dual chord " << id << ")" << std::endl;
2620  if( 0 != sheet ) std::cout << "(Dual sheet " << id << ")" << std::endl;
2621  }
2622 
2623  tmp_result = mbImpl->list_entity( *iter );
2624  if( MB_SUCCESS != tmp_result ) result = tmp_result;
2625  }
2626 
2627  return result;
2628 }

References dualCurve_tag(), dualSurface_tag(), entities, moab::CN::EntityTypeName(), ErrorCode, get_dual_entity(), globalId_tag(), moab::Interface::id_from_handle(), moab::ID_FROM_HANDLE(), moab::Interface::list_entity(), MB_SUCCESS, MBENTITYSET, mbImpl, moab::Interface::tag_get_data(), moab::Interface::type_from_handle(), and moab::TYPE_FROM_HANDLE().

Referenced by list_entities().

◆ next_loop_vertex()

EntityHandle moab::DualTool::next_loop_vertex ( const EntityHandle  last_v,
const EntityHandle  this_v,
const EntityHandle  dual_surf 
)

given a last_v (possibly zero) and this_v, find the next loop vertex on this dual surface

Definition at line 1329 of file DualTool.cpp.

1332 {
1333  // given two vertices, find the next one on the loop; if one is a dual
1334  // surface, then just choose either one for that surface
1335  assert( ( 0 == last_v || mbImpl->type_from_handle( last_v ) == MBVERTEX ) &&
1336  mbImpl->type_from_handle( this_v ) == MBVERTEX && mbImpl->type_from_handle( dual_surf ) == MBENTITYSET );
1337 
1338  // get the connected vertices
1339  MeshTopoUtil tpu( mbImpl );
1340  Range other_verts;
1341  ErrorCode result = tpu.get_bridge_adjacencies( this_v, 1, 0, other_verts );
1342  if( MB_SUCCESS != result || other_verts.empty() ) return 0;
1343 
1344  // if (mbImpl->type_from_handle(last_v) == MBENTITYSET) {
1345  // dual surface, choose either; first get a 2cell on this surface
1346  Range tcells, tcells2, verts;
1347  result = mbImpl->get_entities_by_type( dual_surf, MBPOLYGON, tcells );
1348  if( MB_SUCCESS != result || tcells.empty() ) return 0;
1349 
1350  // ok, pay attention here: first get 2cells common to dual surface and this_v
1351  verts.insert( this_v );
1352  result = mbImpl->get_adjacencies( verts, 2, false, tcells );
1353  if( MB_SUCCESS != result || tcells.empty() ) return 0;
1354 
1355  // next get vertices common to both 2cells and subtract from other_verts; also
1356  // remove last_v if it's non-zero
1357  verts.clear();
1358  result = mbImpl->get_adjacencies( tcells, 0, false, verts );
1359  if( MB_SUCCESS != result || verts.empty() ) return 0;
1360 
1361  Range tmp_verts = subtract( other_verts, verts );
1362  other_verts.swap( tmp_verts );
1363  if( 0 != last_v ) other_verts.erase( last_v );
1364 
1365  // now get intersection of remaining vertices and 2 2cells vertices
1366  // look at each one successively; should find one, maybe not on both
1367  tmp_verts = other_verts;
1368  Range tmp_faces( *tcells.begin(), *tcells.begin() );
1369  result = mbImpl->get_adjacencies( tmp_faces, 0, false, tmp_verts );
1370  if( MB_SUCCESS == result && !tmp_verts.empty() ) return *tmp_verts.begin();
1371  tmp_faces.clear();
1372  tmp_faces.insert( *tcells.rbegin() );
1373  result = mbImpl->get_adjacencies( tmp_faces, 0, false, other_verts );
1374  if( MB_SUCCESS == result && !other_verts.empty() ) return *other_verts.begin();
1375 
1376  // if we got here, there isn't any
1377  return 0;
1378 }

References moab::Range::begin(), moab::Range::clear(), moab::Range::empty(), moab::Range::erase(), ErrorCode, moab::Interface::get_adjacencies(), moab::MeshTopoUtil::get_bridge_adjacencies(), moab::Interface::get_entities_by_type(), moab::Range::insert(), MB_SUCCESS, MBENTITYSET, mbImpl, MBPOLYGON, MBVERTEX, moab::Range::rbegin(), moab::subtract(), moab::Range::swap(), and moab::Interface::type_from_handle().

◆ order_chord()

ErrorCode moab::DualTool::order_chord ( EntityHandle  chord_set)
private

order 1cells on a chord

Definition at line 1022 of file DualTool.cpp.

1023 {
1024  // re-order the 1cells in the set so they are in order along the chord
1025  // start by finding the vertex dual to a quad
1026  Range verts, one_cells;
1027  ErrorCode result = mbImpl->get_entities_by_dimension( chord_set, 1, one_cells );
1028  if( MB_SUCCESS != result || one_cells.empty() ) return MB_FAILURE;
1029 
1030  result = mbImpl->get_adjacencies( one_cells, 0, false, verts, Interface::UNION );
1031  if( MB_SUCCESS != result || verts.empty() ) return MB_FAILURE;
1032 
1033  EntityHandle last_vert = 0;
1034  for( Range::iterator rit = verts.begin(); rit != verts.end(); ++rit )
1035  {
1036  if( TYPE_FROM_HANDLE( get_dual_entity( *rit ) ) == MBQUAD )
1037  {
1038  last_vert = *rit;
1039  break;
1040  }
1041  }
1042  // if there's no vertex owned by a quad, just start with 1st one
1043  if( 0 == last_vert ) last_vert = *verts.begin();
1044 
1045  // now, skip from vertex to vertex, building a list of 1cells
1046  std::vector< EntityHandle > ordered_1cells;
1047  EntityHandle last_1cell = 0;
1048  Range dum1, dum2;
1049  const EntityHandle* connect;
1050  int num_connect;
1051  ErrorCode tmp_result = MB_SUCCESS;
1052  while( ordered_1cells.size() != one_cells.size() )
1053  {
1054  dum1 = one_cells;
1055  result = mbImpl->get_adjacencies( &last_vert, 1, 1, false, dum1 );
1056  if( 0 != last_1cell ) dum1.erase( last_1cell );
1057  // assert(1 == dum1.size());
1058  if( 0 != last_1cell && 1 != dum1.size() )
1059  {
1060  std::cerr << "unexpected size traversing chord." << std::endl;
1061  tmp_result = MB_FAILURE;
1062  }
1063 
1064  last_1cell = *dum1.begin();
1065  ordered_1cells.push_back( last_1cell );
1066  result = mbImpl->get_connectivity( last_1cell, connect, num_connect );RR;
1067  if( last_vert == connect[0] )
1068  last_vert = connect[1];
1069  else
1070  last_vert = connect[0];
1071  }
1072 
1073  // now have the 1cells in order, replace them in the set
1074  if( MB_SUCCESS == tmp_result )
1075  {
1076  result = mbImpl->remove_entities( chord_set, one_cells );RR;
1077  result = mbImpl->add_entities( chord_set, &ordered_1cells[0], ordered_1cells.size() );RR;
1078  }
1079 
1080  return MB_SUCCESS;
1081 }

References moab::Interface::add_entities(), moab::Range::begin(), moab::Range::empty(), moab::Range::end(), moab::Range::erase(), ErrorCode, moab::Interface::get_adjacencies(), moab::Interface::get_connectivity(), get_dual_entity(), moab::Interface::get_entities_by_dimension(), MB_SUCCESS, mbImpl, MBQUAD, moab::Interface::remove_entities(), RR, moab::Range::size(), moab::TYPE_FROM_HANDLE(), and moab::Interface::UNION.

Referenced by construct_dual_hyperplanes().

◆ print_cell()

void moab::DualTool::print_cell ( EntityHandle  cell)
private

Definition at line 1691 of file DualTool.cpp.

1692 {
1693  const EntityHandle* connect;
1694  int num_connect;
1695  ErrorCode result = mbImpl->get_connectivity( cell, connect, num_connect );
1696  if( MB_SUCCESS != result ) return;
1697  bool first = true;
1698  EntityHandle primals[20];
1699  std::vector< int > ids;
1700 
1701  assert( num_connect < 20 );
1702  result = mbImpl->tag_get_data( dualEntityTag, connect, num_connect, primals );
1703  if( MB_SUCCESS != result ) return;
1704  ids.resize( num_connect );
1705  result = mbImpl->tag_get_data( globalIdTag, primals, num_connect, &ids[0] );
1706  if( MB_SUCCESS != result ) return;
1707  for( int i = 0; i < num_connect; i++ )
1708  {
1709  if( !first ) std::cout << "-";
1710  EntityType this_type = mbImpl->type_from_handle( primals[i] );
1711  if( this_type == MBHEX )
1712  std::cout << "h";
1713  else if( this_type == MBQUAD )
1714  std::cout << "f";
1715  else
1716  std::cout << "u";
1717 
1718  if( ids[i] != 0 )
1719  std::cout << ids[i];
1720  else
1721  std::cout << mbImpl->id_from_handle( primals[i] );
1722 
1723  first = false;
1724  }
1725 }

References dualEntityTag, ErrorCode, moab::GeomUtil::first(), moab::Interface::get_connectivity(), globalIdTag, moab::Interface::id_from_handle(), MB_SUCCESS, MBHEX, mbImpl, MBQUAD, moab::Interface::tag_get_data(), and moab::Interface::type_from_handle().

Referenced by atomic_pillow(), face_open_collapse(), face_shrink(), rev_atomic_pillow(), and rev_face_shrink().

◆ rev_atomic_pillow()

ErrorCode moab::DualTool::rev_atomic_pillow ( EntityHandle  pillow,
Range chords 
)

effect reverse atomic pillow operation

Definition at line 1563 of file DualTool.cpp.

1564 {
1565  // get the dual entities associated with elements in the pillow; go through
1566  // the elements instead of the pillow sheet so you get all of them, not just
1567  // the ones on the sheet
1568  if( debug_ap ) ( (Core*)mbImpl )->check_adjacencies();
1569 
1570  std::cout << "-AP(";
1571  print_cell( pillow );
1572  std::cout << ")" << std::endl;
1573 
1574  Range dverts;
1575  ErrorCode result = get_dual_entities( pillow, NULL, NULL, &dverts, NULL, NULL );
1576  if( MB_SUCCESS != result ) return result;
1577  assert( 2 == dverts.size() );
1578 
1579  EntityHandle hexes[2];
1580  result = mbImpl->tag_get_data( dualEntity_tag(), dverts, hexes );RR;
1581  assert( hexes[0] != 0 && hexes[1] != 0 );
1582 
1583  std::vector< EntityHandle > dcells[4];
1584  Range pcells[4];
1585  std::copy( hexes, hexes + 2, range_inserter( pcells[3] ) );
1586  std::copy( dverts.begin(), dverts.end(), std::back_inserter( dcells[0] ) );
1587  for( int dim = 0; dim <= 2; dim++ )
1588  {
1589  result = mbImpl->get_adjacencies( hexes, 2, dim, false, pcells[dim], Interface::UNION );RR;
1590  dcells[3 - dim].resize( pcells[dim].size() );
1591  result = mbImpl->tag_get_data( dualEntity_tag(), pcells[dim], &dcells[3 - dim][0] );RR;
1592  }
1593 
1594  // delete the dual entities which are part of the original pillow
1595  result = mbImpl->delete_entities( &pillow, 1 );
1596  if( MB_SUCCESS != result ) return result;
1597 
1598  result = mbImpl->delete_entities( chords );
1599  if( MB_SUCCESS != result ) return result;
1600 
1601  for( int i = 3; i >= 0; i-- )
1602  {
1603  result = delete_dual_entities( &dcells[i][0], dcells[i].size() );RR;
1604  }
1605 
1606  // delete the primal entities inserted by the ap; be careful to get the right
1607  // faces, edges and vertices
1608  Range del_faces, del_edges, del_verts, tmp_faces, tmp_verts;
1609  // faces are the shared 5 and the 1 other one with greater handle (which
1610  // we know will be later in the range)
1611  result = mbImpl->get_adjacencies( hexes, 2, 2, false, del_faces );RR;
1612  assert( 5 == del_faces.size() );
1613  std::copy( pcells[2].begin(), pcells[2].end(), range_inserter( tmp_faces ) );
1614  tmp_faces = subtract( tmp_faces, del_faces );
1615  del_faces.insert( *tmp_faces.rbegin() );
1616  result = mbImpl->get_adjacencies( tmp_faces, 0, false, tmp_verts );RR;
1617  std::copy( pcells[0].begin(), pcells[0].end(), range_inserter( del_verts ) );
1618  del_verts = subtract( del_verts, tmp_verts );
1619  assert( 4 == del_verts.size() );
1620  result = mbImpl->get_adjacencies( del_verts, 1, false, del_edges, Interface::UNION );RR;
1621  assert( 8 == del_edges.size() );
1622 
1623  result = mbImpl->delete_entities( hexes, 2 );RR;
1624  result = mbImpl->delete_entities( del_faces );RR;
1625  result = mbImpl->delete_entities( del_edges );RR;
1626  result = mbImpl->delete_entities( del_verts );RR;
1627 
1628  if( debug_ap ) ( (Core*)mbImpl )->check_adjacencies();
1629 
1630  // recompute the dual for the hexes on either side of the quad affected
1631  // by the ap removal
1632  Range tmp_hexes;
1633  result = mbImpl->get_adjacencies( tmp_verts, 3, false, tmp_hexes, Interface::UNION );RR;
1634  result = construct_hex_dual( tmp_hexes );RR;
1635 
1636  return MB_SUCCESS;
1637 }

References moab::Range::begin(), construct_hex_dual(), moab::debug_ap, delete_dual_entities(), moab::Interface::delete_entities(), dim, dualEntity_tag(), moab::Range::end(), ErrorCode, moab::Interface::get_adjacencies(), get_dual_entities(), moab::Range::insert(), MB_SUCCESS, mbImpl, print_cell(), moab::Range::rbegin(), RR, size, moab::Range::size(), moab::subtract(), moab::Interface::tag_get_data(), and moab::Interface::UNION.

◆ rev_face_shrink()

ErrorCode moab::DualTool::rev_face_shrink ( EntityHandle  edge)

effect reverse atomic pillow operation

effect reverse face shrink operation

Definition at line 2931 of file DualTool.cpp.

2932 {
2933  if( debug_ap ) ( (Core*)mbImpl )->check_adjacencies();
2934 
2935  // some preliminary checking
2936  if( mbImpl->type_from_handle( odedge ) != MBEDGE ) return MB_TYPE_OUT_OF_RANGE;
2937 
2938  std::cout << "-FS(";
2939  print_cell( odedge );
2940  std::cout << ")" << std::endl;
2941 
2942  EntityHandle quads[4], hexes[2];
2943  std::vector< EntityHandle > connects[4], side_quads[2];
2944 
2945  // get three quads (shared quad & 2 end quads), hexes, and quad
2946  // connects
2947  ErrorCode result = fs_get_quads( odedge, quads, hexes, connects );
2948  if( MB_SUCCESS != result ) return result;
2949 
2950  // adjust sense & rotation so they're aligned, together & wrt first
2951  // hex
2952  result = fs_check_quad_sense( hexes[0], quads[0], connects );
2953  if( MB_SUCCESS != result ) return result;
2954 
2955  result = fsr_get_fourth_quad( connects, side_quads );
2956  if( MB_SUCCESS != result )
2957  {
2958  std::cout << "Can't do -FS here, two hexes must be adjacent to ring of 4 hexes." << std::endl;
2959  return result;
2960  }
2961 
2962  Range adj_ents, outer_hexes, all_adjs;
2963 
2964  // first get the entities connected to interior 4 verts
2965  for( int i = 1; i <= 3; i++ )
2966  {
2967  result = mbImpl->get_adjacencies( &connects[1][0], 4, i, false, adj_ents, Interface::UNION );
2968  if( MB_SUCCESS != result ) return result;
2969  }
2970 
2971  // next get all entities adjacent to those; these will have their dual
2972  // entities deleted
2973  for( int i = 0; i < 3; i++ )
2974  {
2975  result = mbImpl->get_adjacencies( adj_ents, i, false, all_adjs, Interface::UNION );
2976  if( MB_SUCCESS != result ) return result;
2977  }
2978 
2979  // get the dual entities and delete them
2980  Range dual_ents, dual_hps;
2981  for( Range::iterator rit = all_adjs.begin(); rit != all_adjs.end(); ++rit )
2982  {
2983  EntityHandle this_ent = get_dual_entity( *rit );
2984  dual_ents.insert( this_ent );
2985  }
2986 
2987  // before deleting dual, grab the 1- and 2-cells
2988  for( Range::iterator rit = dual_ents.begin(); rit != dual_ents.end(); ++rit )
2989  {
2990  int dim = mbImpl->dimension_from_handle( *rit );
2991  if( 1 == dim || 2 == dim ) dual_hps.insert( get_dual_hyperplane( *rit ) );
2992  }
2993 
2994  result = delete_dual_entities( dual_ents );
2995  if( MB_SUCCESS != result ) return result;
2996 
2997  // after deleting cells, check for empty chords & sheets, and delete those too
2998  for( Range::iterator rit = dual_hps.begin(); rit != dual_hps.end(); ++rit )
2999  {
3000  Range tmp_ents;
3001  result = mbImpl->get_entities_by_handle( *rit, tmp_ents );
3002  if( MB_SUCCESS != result ) return result;
3003  if( tmp_ents.empty() )
3004  {
3005  result = mbImpl->delete_entities( &( *rit ), 1 );
3006  if( MB_SUCCESS != result ) return result;
3007  }
3008  }
3009 
3010  // before re-connecting two hexes, check for existing quad on 4th quad vertices;
3011  // if there is a quad there, need to add explicit adjs to any adj hexes, since
3012  // by definition there'll be another quad on those vertices
3013  bool need_explicit = false;
3014  Range adj_quads;
3015  result = mbImpl->get_adjacencies( &connects[3][0], 4, 2, false, adj_quads );
3016  if( MB_MULTIPLE_ENTITIES_FOUND == result || !adj_quads.empty() )
3017  {
3018  // there's already a quad for these 4 vertices; by definition,
3019  // we'll be creating equivalent entities, so that original quad
3020  // needs explicit adj's to its bounding elements
3021  need_explicit = true;
3022  for( Range::iterator rit = adj_quads.begin(); rit != adj_quads.end(); ++rit )
3023  {
3024  Range adj_hexes;
3025  result = mbImpl->get_adjacencies( &( *rit ), 1, 3, false, adj_hexes );RR;
3026  result = mbImpl->add_adjacencies( *rit, adj_hexes, false );RR;
3027  }
3028  }
3029 
3030  // re-connect the two hexes
3031  std::vector< EntityHandle > new_connect;
3032  std::copy( connects[3].begin(), connects[3].end(), std::back_inserter( new_connect ) );
3033  std::copy( connects[2].begin(), connects[2].end(), std::back_inserter( new_connect ) );
3034  result = mbImpl->set_connectivity( hexes[0], &new_connect[0], 8 );
3035  if( MB_SUCCESS != result ) return result;
3036 
3037  new_connect.clear();
3038  std::copy( connects[0].begin(), connects[0].end(), std::back_inserter( new_connect ) );
3039  std::copy( connects[3].begin(), connects[3].end(), std::back_inserter( new_connect ) );
3040  result = mbImpl->set_connectivity( hexes[1], &new_connect[0], 8 );
3041  if( MB_SUCCESS != result ) return result;
3042 
3043  // test for equiv entities from the side quads, and make explicit
3044  // adjacencies if there are any
3045  MeshTopoUtil mtu( mbImpl );
3046  for( int j = 0; j < 2; j++ )
3047  {
3048  for( int i = 0; i < 4; i++ )
3049  {
3050  if( mtu.equivalent_entities( side_quads[j][i] ) )
3051  {
3052  result = mbImpl->add_adjacencies( side_quads[j][i], &hexes[j], 1, false );
3053  if( MB_SUCCESS != result ) return result;
3054  }
3055  }
3056  }
3057 
3058  // remove hexes we want to keep
3059  adj_ents.erase( hexes[0] );
3060  adj_ents.erase( hexes[1] );
3061 
3062  // delete the other interior entities
3063  result = mbImpl->delete_entities( adj_ents );
3064  if( MB_SUCCESS != result ) return result;
3065 
3066  EntityHandle new_quad;
3067  result = mbImpl->create_element( MBQUAD, &connects[3][0], 4, new_quad );RR;
3068  if( need_explicit )
3069  {
3070  result = mbImpl->add_adjacencies( new_quad, hexes, 2, false );RR;
3071  }
3072 
3073  if( debug_ap ) ( (Core*)mbImpl )->check_adjacencies();
3074 
3075  // now update the dual
3076  result = construct_hex_dual( hexes, 2 );
3077  if( MB_SUCCESS != result ) return result;
3078 
3079  return MB_SUCCESS;
3080 }

References moab::Interface::add_adjacencies(), moab::Range::begin(), construct_hex_dual(), moab::Interface::create_element(), moab::debug_ap, delete_dual_entities(), moab::Interface::delete_entities(), dim, moab::Interface::dimension_from_handle(), moab::Range::empty(), moab::Range::end(), moab::MeshTopoUtil::equivalent_entities(), moab::Range::erase(), ErrorCode, fs_check_quad_sense(), fs_get_quads(), fsr_get_fourth_quad(), moab::Interface::get_adjacencies(), get_dual_entity(), get_dual_hyperplane(), moab::Interface::get_entities_by_handle(), moab::Range::insert(), MB_MULTIPLE_ENTITIES_FOUND, MB_SUCCESS, MB_TYPE_OUT_OF_RANGE, MBEDGE, mbImpl, MBQUAD, print_cell(), RR, moab::Interface::set_connectivity(), moab::Interface::type_from_handle(), and moab::Interface::UNION.

◆ set_dual_surface_or_curve()

ErrorCode moab::DualTool::set_dual_surface_or_curve ( EntityHandle  entity,
const EntityHandle  dual_hyperplane,
const int  dimension 
)

set the dual surface or curve for an entity

Definition at line 1399 of file DualTool.cpp.

1402 {
1403  if( 1 == dual_entity_dimension )
1404  mbImpl->tag_set_data( dualCurve_tag(), &entity, 1, &dual_hyperplane );
1405  else if( 2 == dual_entity_dimension )
1406  mbImpl->tag_set_data( dualSurface_tag(), &entity, 1, &dual_hyperplane );
1407  else
1408  return MB_INDEX_OUT_OF_RANGE;
1409 
1410  return MB_SUCCESS;
1411 }

References dualCurve_tag(), dualSurface_tag(), MB_INDEX_OUT_OF_RANGE, MB_SUCCESS, mbImpl, and moab::Interface::tag_set_data().

◆ split_pair_nonmanifold()

ErrorCode moab::DualTool::split_pair_nonmanifold ( EntityHandle split_quads,
EntityHandle split_edges,
EntityHandle split_nodes,
std::vector< EntityHandle > *  star_dp1,
std::vector< EntityHandle > *  star_dp2,
EntityHandle other_edges,
EntityHandle other_nodes,
EntityHandle new_quads,
EntityHandle new_edges,
EntityHandle new_nodes 
)
private

split a pair of quads and the edge(s) shared by them

Definition at line 1949 of file DualTool.cpp.

1959 {
1960 
1961  // if there's a bdy in the star around the shared edge(s), get the quads on that
1962  // bdy so we know which edges to merge after the split-nonmanifold
1963  MeshTopoUtil mtu( mbImpl );
1964  ErrorCode result;
1965 
1966  // get which star the split faces are in, and choose the other one
1967  int new_side = -1;
1968  if( std::find( star_dp1[0].begin(), star_dp1[0].end(), split_quads[0] ) != star_dp1[0].end() )
1969  new_side = 1;
1970  else if( std::find( star_dp1[1].begin(), star_dp1[1].end(), split_quads[0] ) != star_dp1[1].end() )
1971  new_side = 0;
1972  assert( -1 != new_side );
1973  if( -1 == new_side ) return MB_FAILURE;
1974 
1975  //=============== split faces
1976 
1977  for( int i = 0; i < 2; i++ )
1978  {
1979  // get a hex in star_dp2[new_side] that's adj to this split quad, to tell
1980  // mtu which one the new quad should go with; there should be at least one,
1981  // if we have any hexes connected to the split quad
1982  EntityHandle gowith_hex = 0;
1983  for( std::vector< EntityHandle >::iterator vit = star_dp2[new_side].begin(); vit != star_dp2[new_side].end();
1984  ++vit )
1985  {
1986  if( mtu.common_entity( *vit, split_quads[i], 2 ) )
1987  {
1988  gowith_hex = *vit;
1989  break;
1990  }
1991  }
1992  assert( 0 != gowith_hex );
1993 
1994  // split manifold each of the split_quads, and put the results on the merge list
1995  result =
1996  mtu.split_entities_manifold( split_quads + i, 1, new_quads + i, NULL, ( gowith_hex ? &gowith_hex : NULL ) );RR;
1997  }
1998 
1999  // make ranges of faces which need to be explicitly adj to old, new
2000  // edge; faces come from stars and new_quads (which weren't in the stars);
2001  // new_quads go with side j, which does not have split quads
2002  Range tmp_addl_faces[2], addl_faces[2];
2003  for( int i = 0; i < 2; i++ )
2004  {
2005  std::copy( star_dp1[i].begin(), star_dp1[i].end(), range_inserter( tmp_addl_faces[i] ) );
2006  tmp_addl_faces[new_side].insert( new_quads[i] );
2007  }
2008 #ifndef NDEBUG
2009  bool cond1 = ( "split_quads on 1, new_quads on 0" &&
2010  tmp_addl_faces[0].find( split_quads[0] ) == tmp_addl_faces[0].end() &&
2011  tmp_addl_faces[0].find( split_quads[1] ) == tmp_addl_faces[0].end() &&
2012  tmp_addl_faces[1].find( split_quads[0] ) != tmp_addl_faces[1].end() &&
2013  tmp_addl_faces[1].find( split_quads[1] ) != tmp_addl_faces[1].end() &&
2014  tmp_addl_faces[0].find( new_quads[0] ) != tmp_addl_faces[0].end() &&
2015  tmp_addl_faces[0].find( new_quads[1] ) != tmp_addl_faces[0].end() &&
2016  tmp_addl_faces[1].find( new_quads[0] ) == tmp_addl_faces[1].end() &&
2017  tmp_addl_faces[1].find( new_quads[1] ) == tmp_addl_faces[1].end() ),
2018  cond2 = ( "split_quads on 0, new_quads on 1" &&
2019  tmp_addl_faces[0].find( split_quads[0] ) != tmp_addl_faces[0].end() &&
2020  tmp_addl_faces[0].find( split_quads[1] ) != tmp_addl_faces[0].end() &&
2021  tmp_addl_faces[1].find( split_quads[0] ) == tmp_addl_faces[1].end() &&
2022  tmp_addl_faces[1].find( split_quads[1] ) == tmp_addl_faces[1].end() &&
2023  tmp_addl_faces[0].find( new_quads[0] ) == tmp_addl_faces[0].end() &&
2024  tmp_addl_faces[0].find( new_quads[1] ) == tmp_addl_faces[0].end() &&
2025  tmp_addl_faces[1].find( new_quads[0] ) != tmp_addl_faces[1].end() &&
2026  tmp_addl_faces[1].find( new_quads[1] ) != tmp_addl_faces[1].end() );
2027 
2028  assert( cond1 || cond2 );
2029 #endif
2030 
2031  //=============== split edge(s)
2032  for( int j = 0; j < 3; j++ )
2033  {
2034  if( !split_edges[j] ) break;
2035 
2036  // filter add'l faces to only those adj to split_edges[j]
2037  addl_faces[0] = tmp_addl_faces[0];
2038  addl_faces[1] = tmp_addl_faces[1];
2039  for( int i = 0; i < 2; i++ )
2040  {
2041  result = mbImpl->get_adjacencies( &split_edges[j], 1, 2, false, addl_faces[i] );RR;
2042  }
2043 
2044  // split edge
2045  result = mtu.split_entity_nonmanifold( split_edges[j], addl_faces[1 - new_side], addl_faces[new_side],
2046  new_edges[j] );RR;
2047  }
2048 
2049  //=============== split node(s)
2050 
2051  for( int j = 0; j < 2; j++ )
2052  {
2053  if( !split_nodes[j] ) break;
2054 
2055  // if we're splitting multiple edges, there might be other edges that have the split
2056  // node; also need to know which side they're on
2057  Range tmp_addl_edges[2];
2058  result = foc_get_addl_ents( star_dp1, star_dp2, split_edges, split_nodes[j], tmp_addl_edges );RR;
2059 
2060  // also, we need to know which of the split/new edges go
2061  // with the split/new node; new edges go with side 0, split with 1
2062  for( int i = 0; i < 3; i++ )
2063  {
2064  if( !split_edges[i] ) break;
2065  tmp_addl_edges[new_side].insert( new_edges[i] );
2066  tmp_addl_edges[1 - new_side].insert( split_edges[i] );
2067  }
2068 
2069  // same for star faces and hexes
2070  for( int i = 0; i < 2; i++ )
2071  {
2072  std::copy( star_dp1[i].begin(), star_dp1[i].end(), range_inserter( tmp_addl_edges[i] ) );
2073  std::copy( star_dp2[i].begin(), star_dp2[i].end(), range_inserter( tmp_addl_edges[i] ) );
2074  }
2075 
2076  // finally, new quads
2077  for( int i = 0; i < 2; i++ )
2078  tmp_addl_edges[new_side].insert( new_quads[i] );
2079 
2080  // filter the entities, keeping only the ones adjacent to this node
2081  Range addl_edges[2];
2082  for( int i = 0; i < 2; i++ )
2083  {
2084  for( Range::reverse_iterator rit = tmp_addl_edges[i].rbegin(); rit != tmp_addl_edges[i].rend(); ++rit )
2085  {
2086  if( mtu.common_entity( *rit, split_nodes[j], 0 ) ) addl_edges[i].insert( *rit );
2087  }
2088  }
2089 
2090  // now split the node too
2091  result = mtu.split_entity_nonmanifold( split_nodes[j], addl_edges[1 - new_side], addl_edges[new_side],
2092  new_nodes[j] );RR;
2093  }
2094 
2095  return MB_SUCCESS;
2096 }

References moab::MeshTopoUtil::common_entity(), moab::Range::end(), ErrorCode, moab::Range::find(), foc_get_addl_ents(), moab::Interface::get_adjacencies(), moab::Range::insert(), MB_SUCCESS, mbImpl, moab::Range::rend(), RR, moab::MeshTopoUtil::split_entities_manifold(), and moab::MeshTopoUtil::split_entity_nonmanifold().

Referenced by face_open_collapse().

◆ traverse_hyperplane()

ErrorCode moab::DualTool::traverse_hyperplane ( const Tag  hp_tag,
EntityHandle this_hp,
EntityHandle  this_ent 
)
private

traverse the cells of a dual hyperplane, starting with this_ent (dimension of this_ent determines hyperplane dimension) simpler method for traversing hyperplane, using same basic algorithm but using MeshTopoUtil::get_bridge_adjacencies

Definition at line 893 of file DualTool.cpp.

894 {
895  Range tmp_star, star, tmp_range, new_hyperplane_ents;
896  std::vector< EntityHandle > hp_untreated;
897  int dim = mbImpl->dimension_from_handle( this_ent );
898  MeshTopoUtil mtu( mbImpl );
899  this_hp = 0;
900  ErrorCode result;
901 
902  unsigned short mark_val = 0x0;
903  Tag mark_tag;
904  result = mbImpl->tag_get_handle( "__hyperplane_mark", 1, MB_TYPE_BIT, mark_tag, MB_TAG_CREAT | MB_TAG_BIT );
905  if( MB_SUCCESS != result ) return result;
906  mark_val = 0x1;
907 
908  while( 0 != this_ent )
909  {
910  EntityHandle tmp_hp = get_dual_hyperplane( this_ent );
911  if( 0 == this_hp && 0 != tmp_hp ) this_hp = tmp_hp;
912 
913  if( 0 == tmp_hp ) new_hyperplane_ents.insert( this_ent );
914 
915  if( debug && hp_untreated.size() % 10 == 0 )
916  std::cout << "Dual surface " << this_hp << ", hp_untreated list size = " << hp_untreated.size() << "."
917  << std::endl;
918 
919  // get the 2nd order adjacencies through lower dimension
920  tmp_range.clear();
921  tmp_star.clear();
922  star.clear();
923  result = mtu.get_bridge_adjacencies( this_ent, dim - 1, dim, star );RR;
924 
925  // get the bridge adjacencies through higher dimension
926  result = mtu.get_bridge_adjacencies( this_ent, dim + 1, dim, tmp_star );RR;
927  tmp_range = subtract( star, tmp_star );
928 
929  for( Range::iterator rit = tmp_range.begin(); rit != tmp_range.end(); ++rit )
930  {
931  if( new_hyperplane_ents.find( *rit ) != new_hyperplane_ents.end() ) continue;
932 
933  // check for tag first, 'cuz it's probably faster than checking adjacencies
934  // assign to avoid valgrind warning
935  unsigned short tmp_mark = 0x0;
936  result = mbImpl->tag_get_data( mark_tag, &( *rit ), 1, &tmp_mark );
937  if( MB_SUCCESS == result && mark_val == tmp_mark ) continue;
938 
939  // if it's on the loop, it's not eligible
940  if( 1 == dim && check_1d_loop_edge( *rit ) ) continue;
941 
942  // have one on this hp; just put it on the hp_untreated list for now,
943  // will get tagged and put in the hp set later
944  hp_untreated.push_back( *rit );
945  result = mbImpl->tag_set_data( mark_tag, &( *rit ), 1, &mark_val );
946  if( MB_SUCCESS != result ) return result;
947  }
948 
949  // end of inner loop; get the next this_ent, or set to zero
950  if( hp_untreated.empty() )
951  this_ent = 0;
952  else
953  {
954  this_ent = hp_untreated.back();
955  hp_untreated.pop_back();
956  }
957  }
958 
959  if( debug_ap )
960  {
961  std::string hp_name;
962  if( 2 == dim )
963  hp_name = "sheet";
964  else
965  hp_name = "chord";
966 
967  if( 0 == this_hp )
968  std::cout << "Constructed new " << hp_name << " with ";
969  else
970  {
971  int this_id;
972  result = mbImpl->tag_get_data( globalId_tag(), &this_hp, 1, &this_id );RR;
973  std::cout << "Added to " << hp_name << " " << this_id << " ";
974  }
975  if( dim == 2 )
976  std::cout << "edges:" << std::endl;
977  else
978  std::cout << "quads:" << std::endl;
979  std::vector< EntityHandle > pents( new_hyperplane_ents.size() );
980  result = mbImpl->tag_get_data( dualEntity_tag(), new_hyperplane_ents, &pents[0] );RR;
981  for( std::vector< EntityHandle >::iterator vit = pents.begin(); vit != pents.end(); ++vit )
982  {
983  if( vit != pents.begin() ) std::cout << ", ";
984  std::cout << mbImpl->id_from_handle( *vit );
985  }
986  std::cout << std::endl;
987  }
988 
989  if( 0 == this_hp )
990  {
991  // ok, doesn't have one; make a new hyperplane
992  int new_id = -1;
993  result = construct_new_hyperplane( dim, this_hp, new_id );
994  if( MB_SUCCESS != result ) return result;
995 
996  if( debug_ap )
997  {
998  std::cout << "New ";
999  if( 2 == dim )
1000  std::cout << " sheet ";
1001  else
1002  std::cout << " chord ";
1003  std::cout << new_id << " constructed." << std::endl;
1004  }
1005  }
1006 
1007  // set the hp_val for entities which didn't have one before
1008  std::vector< EntityHandle > hp_tags( new_hyperplane_ents.size() );
1009  std::fill( hp_tags.begin(), hp_tags.end(), this_hp );
1010  result = mbImpl->tag_set_data( hp_tag, new_hyperplane_ents, &hp_tags[0] );
1011  if( MB_SUCCESS != result ) return result;
1012  result = mbImpl->add_entities( this_hp, new_hyperplane_ents );
1013  if( MB_SUCCESS != result ) return result;
1014 
1015  // unmark the entities by removing the tag
1016  result = mbImpl->tag_delete( mark_tag );
1017  if( MB_SUCCESS != result ) return result;
1018 
1019  return MB_SUCCESS;
1020 }

References moab::Interface::add_entities(), moab::Range::begin(), check_1d_loop_edge(), moab::Range::clear(), construct_new_hyperplane(), moab::debug, moab::debug_ap, dim, moab::Interface::dimension_from_handle(), dualEntity_tag(), moab::Range::end(), ErrorCode, moab::Range::find(), moab::MeshTopoUtil::get_bridge_adjacencies(), get_dual_hyperplane(), globalId_tag(), moab::Interface::id_from_handle(), moab::Range::insert(), MB_SUCCESS, MB_TAG_BIT, MB_TAG_CREAT, MB_TYPE_BIT, mbImpl, RR, moab::Range::size(), moab::subtract(), moab::Interface::tag_delete(), moab::Interface::tag_get_data(), moab::Interface::tag_get_handle(), and moab::Interface::tag_set_data().

Referenced by construct_dual_hyperplanes().

Member Data Documentation

◆ categoryTag

Tag moab::DualTool::categoryTag
private

Definition at line 384 of file DualTool.hpp.

Referenced by construct_new_hyperplane(), and DualTool().

◆ DUAL_CURVE_TAG_NAME

const char * moab::DualTool::DUAL_CURVE_TAG_NAME = "DUAL_CURVE"
static

tag name for dual curves

Definition at line 40 of file DualTool.hpp.

Referenced by DualTool(), and get_dual_hyperplanes().

◆ DUAL_ENTITY_TAG_NAME

const char * moab::DualTool::DUAL_ENTITY_TAG_NAME = "__DUAL_ENTITY"
static

tag name for dual entitys

tag name for dual entities

Definition at line 46 of file DualTool.hpp.

Referenced by DualTool().

◆ DUAL_GRAPHICS_POINT_TAG_NAME

const char * moab::DualTool::DUAL_GRAPHICS_POINT_TAG_NAME = "__DUAL_GRAPHICS_POINT"
static

tag name for dual entitys

tag name for graphics point

Definition at line 52 of file DualTool.hpp.

Referenced by DualTool().

◆ DUAL_SURFACE_TAG_NAME

const char * moab::DualTool::DUAL_SURFACE_TAG_NAME = "DUAL_SURFACE"
static

tag name for dual surfaces

Definition at line 37 of file DualTool.hpp.

Referenced by DualTool(), and get_dual_hyperplanes().

◆ dualCurveTag

Tag moab::DualTool::dualCurveTag
private

tags used for dual surfaces, curves, cells, entities

Definition at line 378 of file DualTool.hpp.

Referenced by delete_whole_dual(), dualCurve_tag(), and DualTool().

◆ dualEntityTag

Tag moab::DualTool::dualEntityTag
private

Definition at line 381 of file DualTool.hpp.

Referenced by delete_whole_dual(), dualEntity_tag(), DualTool(), and print_cell().

◆ dualGraphicsPointTag

Tag moab::DualTool::dualGraphicsPointTag
private

◆ dualSurfaceTag

Tag moab::DualTool::dualSurfaceTag
private

Definition at line 379 of file DualTool.hpp.

Referenced by delete_whole_dual(), dualSurface_tag(), and DualTool().

◆ EXTRA_DUAL_ENTITY_TAG_NAME

const char * moab::DualTool::EXTRA_DUAL_ENTITY_TAG_NAME = "__EXTRA_DUAL_ENTITY"
static

tag name for dual entitys

tag name for extra dual entities

Definition at line 49 of file DualTool.hpp.

Referenced by DualTool().

◆ extraDualEntityTag

Tag moab::DualTool::extraDualEntityTag
private

Definition at line 382 of file DualTool.hpp.

Referenced by delete_whole_dual(), DualTool(), and extraDualEntity_tag().

◆ globalIdTag

Tag moab::DualTool::globalIdTag
private

Definition at line 385 of file DualTool.hpp.

Referenced by construct_new_hyperplane(), DualTool(), globalId_tag(), and print_cell().

◆ IS_DUAL_CELL_TAG_NAME

const char * moab::DualTool::IS_DUAL_CELL_TAG_NAME = "__IS_DUAL_CELL"
static

tag name for dual cells

Definition at line 43 of file DualTool.hpp.

Referenced by DualTool().

◆ isDualCellTag

Tag moab::DualTool::isDualCellTag
private

Definition at line 380 of file DualTool.hpp.

Referenced by delete_whole_dual(), DualTool(), get_dual_entities(), and isDualCell_tag().

◆ maxHexId

int moab::DualTool::maxHexId
private

Definition at line 387 of file DualTool.hpp.

Referenced by atomic_pillow(), construct_dual(), DualTool(), and face_shrink().

◆ mbImpl


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