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>
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 | |
Interface * | mbImpl |
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 |
Tools for constructing and working with mesh duals (both tet- and hex-based, though some functions may not make sense for tet duals)
Definition at line 33 of file DualTool.hpp.
|
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 };
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
73 result = mbImpl->tag_get_handle( DUAL_SURFACE_TAG_NAME, 1, MB_TYPE_HANDLE, dualSurfaceTag,
74 MB_TAG_SPARSE | MB_TAG_CREAT, &dum_handle );
75 assert( MB_SUCCESS == result );
76
77 result = mbImpl->tag_get_handle( DUAL_CURVE_TAG_NAME, 1, MB_TYPE_HANDLE, dualCurveTag, MB_TAG_SPARSE | MB_TAG_CREAT,
78 &dum_handle );
79 assert( MB_SUCCESS == result );
80
81 unsigned int dummy = 0;
82 result = mbImpl->tag_get_handle( IS_DUAL_CELL_TAG_NAME, 1, MB_TYPE_INTEGER, isDualCellTag,
83 MB_TAG_SPARSE | MB_TAG_CREAT, &dummy );
84 assert( MB_SUCCESS == result );
85
86 result = mbImpl->tag_get_handle( DUAL_ENTITY_TAG_NAME, 1, MB_TYPE_HANDLE, dualEntityTag,
87 MB_TAG_DENSE | MB_TAG_CREAT, &dum_handle );
88 assert( MB_SUCCESS == result );
89
90 result = mbImpl->tag_get_handle( EXTRA_DUAL_ENTITY_TAG_NAME, 1, MB_TYPE_HANDLE, extraDualEntityTag,
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 };
95 result = mbImpl->tag_get_handle( CATEGORY_TAG_NAME, CATEGORY_TAG_SIZE, MB_TYPE_OPAQUE, categoryTag,
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,
101 dualGraphicsPointTag, MB_TAG_DENSE | MB_TAG_CREAT | MB_TAG_BYTES, &dum_pt );
102 assert( MB_SUCCESS == result );
103
104 globalIdTag = mbImpl->globalId_tag();
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().
moab::DualTool::~DualTool | ( | ) |
Definition at line 113 of file DualTool.cpp.
113 {}
|
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().
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.
|
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().
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().
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().
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().
|
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().
|
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().
|
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().
|
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().
|
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().
|
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().
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 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.
|
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().
|
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().
|
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 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().
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 =
3195 mbImpl->get_entities_by_type_and_tag( 0, MBPOLYHEDRON, &isDualCellTag, NULL, 1, dual_ents, Interface::UNION );RR;
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().
|
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().
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.
|
inline |
get/set the tag for dual entities
Definition at line 405 of file DualTool.hpp.
406 {
407 return dualEntityTag;
408 }
References dualEntityTag.
Referenced by check_1d_loop_edge(), check_dual_equiv_edges(), construct_dual_cells(), construct_dual_edges(), construct_dual_faces(), construct_dual_vertex(), construct_dual_vertices(), delete_dual_entities(), get_dual_entities(), get_dual_entity(), get_radial_dverts(), rev_atomic_pillow(), and traverse_hyperplane().
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.
|
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().
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.
|
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().
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.
|
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().
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.
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().
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.
|
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().
|
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().
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().
|
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().
|
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().
|
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().
|
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().
|
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().
|
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().
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.
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().
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().
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().
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().
|
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().
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().
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.
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().
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().
|
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().
|
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().
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.
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().
|
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().
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.
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.
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().
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().
|
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().
|
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().
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.
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.
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().
|
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().
|
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().
|
private |
Definition at line 384 of file DualTool.hpp.
Referenced by construct_new_hyperplane(), and DualTool().
|
static |
tag name for dual curves
Definition at line 40 of file DualTool.hpp.
Referenced by DualTool(), and get_dual_hyperplanes().
|
static |
tag name for dual entitys
tag name for dual entities
Definition at line 46 of file DualTool.hpp.
Referenced by DualTool().
|
static |
tag name for dual entitys
tag name for graphics point
Definition at line 52 of file DualTool.hpp.
Referenced by DualTool().
|
static |
tag name for dual surfaces
Definition at line 37 of file DualTool.hpp.
Referenced by DualTool(), and get_dual_hyperplanes().
|
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().
|
private |
Definition at line 381 of file DualTool.hpp.
Referenced by delete_whole_dual(), dualEntity_tag(), DualTool(), and print_cell().
|
private |
Definition at line 383 of file DualTool.hpp.
Referenced by delete_whole_dual(), dualGraphicsPoint_tag(), DualTool(), and get_graphics_points().
|
private |
Definition at line 379 of file DualTool.hpp.
Referenced by delete_whole_dual(), dualSurface_tag(), and DualTool().
|
static |
tag name for dual entitys
tag name for extra dual entities
Definition at line 49 of file DualTool.hpp.
Referenced by DualTool().
|
private |
Definition at line 382 of file DualTool.hpp.
Referenced by delete_whole_dual(), DualTool(), and extraDualEntity_tag().
|
private |
Definition at line 385 of file DualTool.hpp.
Referenced by construct_new_hyperplane(), DualTool(), globalId_tag(), and print_cell().
|
static |
|
private |
Definition at line 380 of file DualTool.hpp.
Referenced by delete_whole_dual(), DualTool(), get_dual_entities(), and isDualCell_tag().
|
private |
Definition at line 387 of file DualTool.hpp.
Referenced by atomic_pillow(), construct_dual(), DualTool(), and face_shrink().
|
private |
private copy of interface *
Definition at line 369 of file DualTool.hpp.
Referenced by add_graphics_point(), atomic_pillow(), check_1d_loop_edge(), check_dual_adjs(), check_dual_equiv_edges(), construct_dual(), construct_dual_cells(), construct_dual_edges(), construct_dual_faces(), construct_dual_hyperplanes(), construct_dual_vertex(), construct_dual_vertices(), construct_hp_parent_child(), construct_new_hyperplane(), delete_dual_entities(), delete_whole_dual(), DualTool(), face_open_collapse(), face_shrink(), foc_delete_dual(), foc_get_addl_ents(), foc_get_ents(), foc_get_stars(), fs_check_quad_sense(), fs_get_quad_loops(), fs_get_quads(), fsr_get_fourth_quad(), get_cell_points(), get_dual_entities(), get_dual_entity(), get_dual_hyperplane(), get_extra_dual_entity(), get_graphics_points(), get_opposite_verts(), get_radial_dverts(), is_blind(), list_entities(), next_loop_vertex(), order_chord(), print_cell(), rev_atomic_pillow(), rev_face_shrink(), set_dual_surface_or_curve(), split_pair_nonmanifold(), and traverse_hyperplane().