MOAB: Mesh Oriented datABase
(version 5.4.1)
|
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 | |
ErrorCode | construct_hex_dual (EntityHandle *entities, const int num_entities) |
construct the dual entities for a hex mesh, including dual surfaces & curves | |
ErrorCode | construct_hex_dual (Range &entities) |
construct the dual entities for a hex mesh, including dual surfaces & curves | |
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 | |
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 | |
EntityHandle | get_dual_entity (const EntityHandle this_ent) const |
return the corresponding dual entity | |
EntityHandle | get_extra_dual_entity (const EntityHandle this_ent) |
return the corresponding extra dual entity | |
ErrorCode | get_graphics_points (EntityHandle dual_ent, std::vector< int > &npts, std::vector< GraphicsPoint > &gpoints) |
ErrorCode | get_graphics_points (const Range &in_range, std::vector< GraphicsPoint > &gpoints, const bool assign_ids=false, const int start_id=0) |
EntityHandle | next_loop_vertex (const EntityHandle last_v, const EntityHandle this_v, const EntityHandle dual_surf) |
Tag | dualSurface_tag () const |
get/set the tag for dual surfaces | |
ErrorCode | dualSurface_tag (const Tag tag) |
get/set the tag for dual surfaces | |
Tag | dualCurve_tag () const |
get/set the tag for dual curves | |
ErrorCode | dualCurve_tag (const Tag tag) |
get/set the tag for dual curves | |
Tag | isDualCell_tag () const |
get/set the tag for dual cells | |
ErrorCode | isDualCell_tag (const Tag tag) |
get/set the tag for dual cells | |
Tag | dualEntity_tag () const |
get/set the tag for dual entities | |
ErrorCode | dualEntity_tag (const Tag tag) |
get/set the tag for dual entities | |
Tag | extraDualEntity_tag () const |
get/set the tag for dual entities | |
ErrorCode | extraDualEntity_tag (const Tag tag) |
get/set the tag for dual entities | |
Tag | dualGraphicsPoint_tag () const |
get/set the tag for dual entities | |
ErrorCode | dualGraphicsPoint_tag (const Tag tag) |
get/set the tag for dual entities | |
Tag | globalId_tag () const |
get/set the global id tag | |
ErrorCode | globalId_tag (const Tag tag) |
get/set the tag for dual entities | |
EntityHandle | get_dual_hyperplane (const EntityHandle ncell) |
given an entity, return any dual surface or curve it's in | |
bool | is_blind (const EntityHandle chord) |
returns true if first & last vertices are dual to hexes (not faces) | |
ErrorCode | set_dual_surface_or_curve (EntityHandle entity, const EntityHandle dual_hyperplane, const int dimension) |
set the dual surface or curve for an entity | |
ErrorCode | atomic_pillow (EntityHandle odedge, EntityHandle &quad1, EntityHandle &quad2) |
effect atomic pillow operation | |
ErrorCode | rev_atomic_pillow (EntityHandle pillow, Range &chords) |
effect reverse atomic pillow operation | |
ErrorCode | face_shrink (EntityHandle odedge) |
effect face shrink operation | |
ErrorCode | rev_face_shrink (EntityHandle edge) |
effect reverse atomic pillow operation | |
ErrorCode | face_open_collapse (EntityHandle ocl, EntityHandle ocr) |
effect a face open-collapse operation | |
ErrorCode | foc_get_ents (EntityHandle ocl, EntityHandle ocr, EntityHandle *quads, EntityHandle *split_edges, EntityHandle *split_nodes, Range &hexes, EntityHandle *other_edges, EntityHandle *other_nodes) |
ErrorCode | get_opposite_verts (const EntityHandle middle_edge, const EntityHandle chord, EntityHandle *verts) |
ErrorCode | get_dual_entities (const EntityHandle dual_ent, Range *dcells, Range *dedges, Range *dverts, Range *dverts_loop, Range *dedges_loop) |
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 | |
ErrorCode | check_dual_adjs () |
check dual-primal adjacencies | |
Static Public Member Functions | |
static ErrorCode | get_dual_hyperplanes (const Interface *impl, const int dim, Range &dual_ents) |
Static Public Attributes | |
static MOAB_EXPORT const char * | DUAL_SURFACE_TAG_NAME = "DUAL_SURFACE" |
tag name for dual surfaces | |
static MOAB_EXPORT const char * | DUAL_CURVE_TAG_NAME = "DUAL_CURVE" |
tag name for dual curves | |
static const char * | IS_DUAL_CELL_TAG_NAME = "__IS_DUAL_CELL" |
tag name for dual cells | |
static const char * | DUAL_ENTITY_TAG_NAME = "__DUAL_ENTITY" |
tag name for dual entitys | |
static const char * | EXTRA_DUAL_ENTITY_TAG_NAME = "__EXTRA_DUAL_ENTITY" |
tag name for dual entitys | |
static const char * | DUAL_GRAPHICS_POINT_TAG_NAME = "__DUAL_GRAPHICS_POINT" |
tag name for dual entitys | |
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 | |
ErrorCode | construct_dual_edges (const Range &all_faces, Range &new_dual_ents) |
construct dual edges for specified faces | |
ErrorCode | construct_dual_faces (const Range &all_edges, Range &new_dual_ents) |
construct dual faces for specified edges | |
ErrorCode | construct_dual_cells (const Range &all_verts, Range &new_dual_ents) |
construct dual cells for specified vertices | |
ErrorCode | construct_dual_hyperplanes (const int dim, EntityHandle *entities, const int num_entities) |
ErrorCode | order_chord (EntityHandle chord_set) |
order 1cells on a chord | |
ErrorCode | construct_new_hyperplane (const int dim, EntityHandle &new_hyperplane, int &id) |
ErrorCode | traverse_hyperplane (const Tag hp_tag, EntityHandle &this_hp, EntityHandle this_ent) |
ErrorCode | construct_hp_parent_child () |
connect dual surfaces with dual curves using parent/child connections | |
ErrorCode | get_radial_dverts (const EntityHandle edge, std::vector< EntityHandle > &rad_verts, bool &bdy_edge) |
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) | |
ErrorCode | get_cell_points (EntityHandle dual_ent, std::vector< int > &npts, std::vector< GraphicsPoint > &points) |
get points defining facets of a 2cell | |
bool | check_1d_loop_edge (EntityHandle this_ent) |
ErrorCode | check_dual_equiv_edges (Range &dual_edges) |
ErrorCode | delete_dual_entities (EntityHandle *entities, const int num_entities) |
delete a dual entity; updates primal to no longer point to it | |
ErrorCode | delete_dual_entities (Range &entities) |
delete a range of dual entities; updates primal to no longer point to them | |
ErrorCode | fs_check_quad_sense (EntityHandle hex0, EntityHandle quad0, std::vector< EntityHandle > *connects) |
check sense of connect arrays, and reverse/rotate if necessary | |
ErrorCode | fs_get_quads (EntityHandle odedge, EntityHandle *quads, EntityHandle *hexes, std::vector< EntityHandle > *connects) |
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 | |
ErrorCode | fsr_get_fourth_quad (std::vector< EntityHandle > *connects, std::vector< EntityHandle > *side_quads) |
ErrorCode | foc_delete_dual (EntityHandle *split_quads, EntityHandle *split_edges, Range &hexes) |
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 | |
ErrorCode | foc_get_addl_ents (std::vector< EntityHandle > *star_dp1, std::vector< EntityHandle > *star_dp2, EntityHandle *split_edges, EntityHandle split_node, Range *addl_ents) |
ErrorCode | foc_get_stars (EntityHandle *split_quads, EntityHandle *split_edges, std::vector< EntityHandle > *star_dp1, std::vector< EntityHandle > *star_dp2) |
void | print_cell (EntityHandle cell) |
Private Attributes | |
Interface * | mbImpl |
private copy of interface * | |
Tag | dualCurveTag |
tags used for dual surfaces, curves, cells, entities | |
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.
anonymous enum [private] |
static constant number of points bounding any cell
Definition at line 372 of file DualTool.hpp.
{ GP_SIZE = 20 };
moab::DualTool::DualTool | ( | Interface * | impl | ) |
Definition at line 68 of file DualTool.cpp.
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().
: mbImpl( impl ) { EntityHandle dum_handle = 0; ErrorCode result; result = mbImpl->tag_get_handle( DUAL_SURFACE_TAG_NAME, 1, MB_TYPE_HANDLE, dualSurfaceTag, MB_TAG_SPARSE | MB_TAG_CREAT, &dum_handle ); assert( MB_SUCCESS == result ); result = mbImpl->tag_get_handle( DUAL_CURVE_TAG_NAME, 1, MB_TYPE_HANDLE, dualCurveTag, MB_TAG_SPARSE | MB_TAG_CREAT, &dum_handle ); assert( MB_SUCCESS == result ); unsigned int dummy = 0; result = mbImpl->tag_get_handle( IS_DUAL_CELL_TAG_NAME, 1, MB_TYPE_INTEGER, isDualCellTag, MB_TAG_SPARSE | MB_TAG_CREAT, &dummy ); assert( MB_SUCCESS == result ); result = mbImpl->tag_get_handle( DUAL_ENTITY_TAG_NAME, 1, MB_TYPE_HANDLE, dualEntityTag, MB_TAG_DENSE | MB_TAG_CREAT, &dum_handle ); assert( MB_SUCCESS == result ); result = mbImpl->tag_get_handle( EXTRA_DUAL_ENTITY_TAG_NAME, 1, MB_TYPE_HANDLE, extraDualEntityTag, MB_TAG_SPARSE | MB_TAG_CREAT, &dum_handle ); assert( MB_SUCCESS == result ); static const char dum_name[CATEGORY_TAG_SIZE] = { 0 }; result = mbImpl->tag_get_handle( CATEGORY_TAG_NAME, CATEGORY_TAG_SIZE, MB_TYPE_OPAQUE, categoryTag, MB_TAG_SPARSE | MB_TAG_CREAT, dum_name ); assert( MB_SUCCESS == result ); DualTool::GraphicsPoint dum_pt( 0.0, 0.0, 0.0, -1 ); result = mbImpl->tag_get_handle( DUAL_GRAPHICS_POINT_TAG_NAME, sizeof( DualTool::GraphicsPoint ), MB_TYPE_DOUBLE, dualGraphicsPointTag, MB_TAG_DENSE | MB_TAG_CREAT | MB_TAG_BYTES, &dum_pt ); assert( MB_SUCCESS == result ); globalIdTag = mbImpl->globalId_tag(); if( MB_SUCCESS == result ) { } // empty statement to get rid of warning. maxHexId = -1; }
Definition at line 113 of file DualTool.cpp.
{}
ErrorCode moab::DualTool::add_graphics_point | ( | EntityHandle | entity, |
double * | avg_pos = NULL |
||
) | [private] |
add a graphics point to an entity (on a tag)
Definition at line 269 of file DualTool.cpp.
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().
{ // add a graphics pt, placed at the same position as the vertex double my_pos[3]; ErrorCode result; if( NULL == avg_pos ) { result = MeshTopoUtil( mbImpl ).get_average_position( entity, my_pos ); if( MB_SUCCESS != result ) return result; } else for( int i = 0; i < 3; i++ ) my_pos[i] = avg_pos[i]; DualTool::GraphicsPoint dum_pt( my_pos, -1 ); result = mbImpl->tag_set_data( dualGraphicsPoint_tag(), &entity, 1, &dum_pt ); return result; }
ErrorCode moab::DualTool::atomic_pillow | ( | EntityHandle | odedge, |
EntityHandle & | quad1, | ||
EntityHandle & | quad2 | ||
) |
effect atomic pillow operation
Definition at line 1435 of file DualTool.cpp.
References moab::Range::begin(), construct_hex_dual(), moab::debug_ap, delete_dual_entities(), ErrorCode, get_dual_entity(), globalId_tag(), moab::Range::insert(), maxHexId, MB_SUCCESS, MB_TYPE_INTEGER, MBENTITYSET, MBHEX, mbImpl, MBQUAD, moab::Range::merge(), print_cell(), moab::Range::rbegin(), RR, moab::Range::size(), and moab::Interface::UNION.
{ if( debug_ap ) ( (Core*)mbImpl )->check_adjacencies(); if( debug_ap ) { Range sets; Tag ms_tag; ErrorCode result = mbImpl->tag_get_handle( "MATERIAL_SET", 1, MB_TYPE_INTEGER, ms_tag ); if( MB_SUCCESS == result ) { result = mbImpl->get_entities_by_type_and_tag( 0, MBENTITYSET, &ms_tag, NULL, 1, sets ); if( MB_SUCCESS == result ) result = mbImpl->delete_entities( sets ); } } std::cout << "-AP("; print_cell( odedge ); std::cout << ")" << std::endl; // perform an atomic pillow operation around dedge // grab the quad before deleting the odedge quad1 = get_dual_entity( odedge ); assert( 0 != quad1 ); // 0. get star 2cells around odedge (before odedge changes) and 3cells around // those 2cells (going to delete the 2cells, therefore need to delete the 3cells // that depend on those too) MeshTopoUtil mtu( mbImpl ); Range star_cells, tmp_cells; ErrorCode result = mbImpl->get_adjacencies( &odedge, 1, 2, false, star_cells );RR; result = mbImpl->get_adjacencies( star_cells, 3, false, tmp_cells, Interface::UNION );RR; star_cells.merge( tmp_cells ); star_cells.insert( odedge ); // tear down the dual entities which will be modified by the ap first result = delete_dual_entities( star_cells );RR; // now change the quad to an ap std::vector< EntityHandle > verts; result = mbImpl->get_connectivity( &quad1, 1, verts );RR; // get average position of vertices double coords[12], avg[3] = { 0.0, 0.0, 0.0 }; result = mbImpl->get_coords( &verts[0], verts.size(), coords );RR; for( int i = 0; i < 4; i++ ) { avg[0] += coords[3 * i]; avg[1] += coords[3 * i + 1]; avg[2] += coords[3 * i + 2]; } for( int i = 0; i < 3; i++ ) avg[i] *= 0.25; // for each position, get a corresponding position 1/2 way to avg double new_coords[12]; for( int i = 0; i < 4; i++ ) { new_coords[3 * i] = avg[0] + .5 * ( coords[3 * i] - avg[0] ); new_coords[3 * i + 1] = avg[1] + .5 * ( coords[3 * i + 1] - avg[1] ); new_coords[3 * i + 2] = avg[2] + .5 * ( coords[3 * i + 2] - avg[2] ); } // make the 4 new vertices; store in vector long enough for hex connectivity for( int i = 0; i < 4; i++ ) { verts.push_back( 0 ); result = mbImpl->create_vertex( &new_coords[3 * i], verts[4 + i] );RR; } // get the hexes connected to the quad Range hexes; result = mbImpl->get_adjacencies( &quad1, 1, 3, false, hexes );RR; assert( hexes.size() <= 2 ); // remove any explicit adjacency from the first hex, since that'll get connected // to the new quad; add adjacency between quad and second hex, if there is a 2nd result = mbImpl->remove_adjacencies( quad1, &( *hexes.begin() ), 1 );RR; if( hexes.size() == 2 ) { result = mbImpl->add_adjacencies( quad1, &( *hexes.rbegin() ), 1, false );RR; } // create the new, inner quad, and make it explicitly adjacent to 1st hex; // make the connectivity of this quad same as the original one std::vector< EntityHandle > tmp_verts; std::copy( verts.begin(), verts.end(), std::back_inserter( tmp_verts ) ); result = mbImpl->create_element( MBQUAD, &tmp_verts[0], 4, quad2 );RR; result = mbImpl->add_adjacencies( quad2, &( *hexes.begin() ), 1, false );RR; // reverse the connectivity of the 1st hex std::reverse( verts.begin(), verts.begin() + 4 ); std::reverse( verts.begin() + 4, verts.end() ); // now make two inner hexes; note connectivity array is flipped for the two hexes EntityHandle new_hexes[2]; result = mbImpl->create_element( MBHEX, &verts[0], 8, new_hexes[0] );RR; result = mbImpl->create_element( MBHEX, &tmp_verts[0], 8, new_hexes[1] );RR; // set the global id tag on the new hexes int new_hex_ids[2] = { maxHexId + 1, maxHexId + 2 }; maxHexId += 2; result = mbImpl->tag_set_data( globalId_tag(), new_hexes, 2, new_hex_ids ); if( MB_SUCCESS != result ) return result; // by definition, quad1 is adj to new_hexes[0] result = mbImpl->add_adjacencies( quad1, &new_hexes[0], 1, false );RR; result = mbImpl->add_adjacencies( quad2, &new_hexes[1], 1, false );RR; if( debug_ap ) ( (Core*)mbImpl )->check_adjacencies(); // now update the dual result = construct_hex_dual( &new_hexes[0], 2 );RR; // get the new dual surface, by getting one of the edges between the center // and outer vertex rings Range new_edge; verts[1] = verts[4]; result = mbImpl->get_adjacencies( &verts[0], 2, 1, false, new_edge ); if( MB_SUCCESS != result || new_edge.size() != 1 ) return result; return MB_SUCCESS; }
bool moab::DualTool::check_1d_loop_edge | ( | EntityHandle | this_ent | ) | [private] |
if this_ent is an edge, is a dual entity, and has quads as its vertices' dual entities, return true, otherwise false
Definition at line 1116 of file DualTool.cpp.
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().
{ // make sure it's an edge if( MBEDGE != mbImpl->type_from_handle( this_ent ) ) return false; // also has to be a dual entity unsigned int dum; ErrorCode result = mbImpl->tag_get_data( isDualCell_tag(), &this_ent, 1, &dum ); if( MB_SUCCESS != result || dum != 0x1 ) return false; const EntityHandle* verts; EntityHandle vert_tags[2]; int num_verts; result = mbImpl->get_connectivity( this_ent, verts, num_verts ); if( MB_SUCCESS != result ) return false; result = mbImpl->tag_get_data( dualEntity_tag(), verts, 2, vert_tags ); if( MB_SUCCESS != result || mbImpl->type_from_handle( vert_tags[0] ) != MBQUAD || mbImpl->type_from_handle( vert_tags[1] ) != MBQUAD ) return false; else return true; }
check dual-primal adjacencies
Definition at line 3236 of file DualTool.cpp.
References moab::Range::begin(), moab::Range::end(), ErrorCode, moab::Range::find(), moab::Interface::get_adjacencies(), get_dual_entity(), moab::Interface::get_entities_by_type(), MB_SUCCESS, MBHEX, mbImpl, PRENT, RR, moab::Range::size(), and moab::Interface::UNION.
Referenced by face_open_collapse().
{ // check primal-dual correspondence // get the primal entities Range pents[4]; ErrorCode result = mbImpl->get_entities_by_type( 0, MBHEX, pents[3] );RR; for( int i = 2; i >= 0; i-- ) { result = mbImpl->get_adjacencies( pents[3], 2, false, pents[2], Interface::UNION );RR; } // for each primal entity of dimension pd #define PRENT( ent ) CN::EntityTypeName( TYPE_FROM_HANDLE( ent ) ) << " " << ID_FROM_HANDLE( ent ) ErrorCode overall_result = MB_SUCCESS; for( int pd = 1; pd <= 3; pd++ ) { for( Range::iterator prit = pents[pd].begin(); prit != pents[pd].end(); ++prit ) { // get corresponding dual entity of dimension dd = 3-pd EntityHandle dual_ent = get_dual_entity( *prit ); if( 0 == dual_ent ) std::cerr << "Problem getting dual entity for " << PRENT( *prit ) << std::endl; // for each sub dimension sd = 0..pd-1 for( int sd = 0; sd < pd; sd++ ) { Range R1, R2, R3; // R1 = entities bounding primal entity of dim sd result = mbImpl->get_adjacencies( &( *prit ), 1, sd, false, R1 );RR; // R2 = entities bounded by dual entity, of dim 3-sd result = mbImpl->get_adjacencies( &dual_ent, 1, 3 - sd, false, R2 );RR; if( R1.size() != R2.size() ) { std::cerr << PRENT( *prit ) << ": number of adj ents in " << "primal/dual don't agree for dimension " << sd << "." << std::endl; overall_result = MB_FAILURE; } // for each entity in R1, get its dual and look for it in R2 for( Range::iterator r1it = R1.begin(); r1it != R1.end(); ++r1it ) { EntityHandle tmp_dual = get_dual_entity( *r1it ); if( R2.find( tmp_dual ) == R2.end() ) { std::cerr << PRENT( *prit ) << ": adj entity " << PRENT( *r1it ) << " isn't adjacent in dual." << std::endl; overall_result = MB_FAILURE; } } // ditto for R2 for( Range::iterator r2it = R2.begin(); r2it != R2.end(); ++r2it ) { EntityHandle tmp_prim = get_dual_entity( *r2it ); if( R1.find( tmp_prim ) == R1.end() ) { std::cerr << PRENT( *prit ) << ": adj entity " << PRENT( *r2it ) << " isn't adjacent in primal." << std::endl; overall_result = MB_FAILURE; } } } } } return overall_result; }
ErrorCode moab::DualTool::check_dual_equiv_edges | ( | Range & | dual_edges | ) | [private] |
go through potential dual equivalent edges (edges whose nodes define multiple edges), and add explicit adjacencies to corrent 2cells
Definition at line 468 of file DualTool.cpp.
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().
{ // fix equivalent dual edges (i.e. edges whose vertices define multiple edges) // by explicitly adding adjacencies to containing polygons; adjacent polygons // found by going through primal ErrorCode tmp_result, result = MB_SUCCESS; Range all_dedges( dual_edges ); // first, go through all dual edges and find equivalent edges (by looking for // up-adjacent edges on the vertices of each edge) for( Range::iterator rit = dual_edges.begin(); rit != dual_edges.end(); ++rit ) { Range connect, dum_range( *rit, *rit ); tmp_result = mbImpl->get_adjacencies( dum_range, 0, false, connect ); if( MB_SUCCESS != tmp_result ) continue; tmp_result = mbImpl->get_adjacencies( connect, 1, false, all_dedges, Interface::UNION ); if( MB_SUCCESS != tmp_result ) continue; } // save a copy for checking later Range save_all_2cells; // go through each edge while( !all_dedges.empty() ) { EntityHandle this_edge = *all_dedges.begin(); all_dedges.erase( all_dedges.begin() ); const EntityHandle* connect; int num_connect; result = mbImpl->get_connectivity( this_edge, connect, num_connect ); if( MB_SUCCESS != result ) continue; Range dum_edges, verts; verts.insert( connect[0] ); verts.insert( connect[1] ); tmp_result = mbImpl->get_adjacencies( verts, 1, false, dum_edges ); if( MB_SUCCESS != tmp_result ) { result = tmp_result; continue; } if( dum_edges.size() == 1 ) { // not an equiv edge - already removed from list, so just continue continue; } // ok, have an equiv entity - fix by looking through primal // pre-get the primal of these EntityHandle dedge_quad; tmp_result = mbImpl->tag_get_data( dualEntity_tag(), &this_edge, 1, &dedge_quad ); if( MB_SUCCESS != tmp_result ) { result = tmp_result; continue; } if( MBQUAD == mbImpl->type_from_handle( dedge_quad ) ) { // get the primal edges adj to quad Range dum_quad_range( dedge_quad, dedge_quad ), adj_pedges; tmp_result = mbImpl->get_adjacencies( dum_quad_range, 1, false, adj_pedges ); if( MB_SUCCESS != tmp_result ) { result = tmp_result; continue; } // get the dual 2cells corresponding to those pedges std::vector< EntityHandle > dcells; dcells.resize( adj_pedges.size() ); tmp_result = mbImpl->tag_get_data( dualEntity_tag(), adj_pedges, &dcells[0] ); if( MB_SUCCESS != tmp_result ) { result = tmp_result; continue; } // now add explicit adjacencies from the dedge to those dcells std::vector< EntityHandle >::iterator vit; for( vit = dcells.begin(); vit != dcells.end(); ++vit ) { save_all_2cells.insert( *vit ); assert( MBPOLYGON == mbImpl->type_from_handle( *vit ) ); tmp_result = mbImpl->add_adjacencies( this_edge, &( *vit ), 1, false ); if( MB_SUCCESS != tmp_result ) { result = tmp_result; continue; } // check that there are really adjacencies and *vit is in them const EntityHandle* adjs; int num_adjs; tmp_result = reinterpret_cast< Core* >( mbImpl )->a_entity_factory()->get_adjacencies( this_edge, adjs, num_adjs ); if( NULL == adjs || std::find( adjs, adjs + num_adjs, *vit ) == adjs + num_adjs ) std::cout << "Add_adjacencies failed in construct_dual_faces." << std::endl; } } else { // else, have a dual edge representing a bdy edge - tie directly to // dual entity if its dual entity EntityHandle bdy_dcell; tmp_result = mbImpl->tag_get_data( dualEntity_tag(), &dedge_quad, 1, &bdy_dcell ); TRC assert( MBPOLYGON == mbImpl->type_from_handle( bdy_dcell ) ); tmp_result = mbImpl->add_adjacencies( this_edge, &bdy_dcell, 1, false ); if( MB_SUCCESS != tmp_result ) { result = tmp_result; continue; } } } // sanity check - look for adj edges again, and check for equiv entities for( Range::iterator vit = save_all_2cells.begin(); vit != save_all_2cells.end(); ++vit ) { Range adj_edges, dum_quad_range; dum_quad_range.insert( *vit ); assert( MBPOLYGON == mbImpl->type_from_handle( *vit ) ); tmp_result = mbImpl->get_adjacencies( dum_quad_range, 1, false, adj_edges ); if( MB_MULTIPLE_ENTITIES_FOUND == tmp_result ) { std::cout << "Multiple entities returned for polygon " << mbImpl->id_from_handle( *vit ) << "." << std::endl; continue; } } // success! return result; }
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.
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(), 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(), and main().
{ // allocate a dual entity for each primal entity in the mesh, starting // with highest dimension and working downward; do each dimension in a separate code // block, since they're all handled slightly differently Range regions, faces, edges, vertices; ErrorCode result; if( NULL == entities || 0 == num_entities ) { // first, construct all the aentities, since they're currently needed to // compute the dual result = mbImpl->get_entities_by_dimension( 0, 0, vertices ); if( MB_SUCCESS != result ) return result; result = MeshTopoUtil( mbImpl ).construct_aentities( vertices ); if( MB_SUCCESS != result ) return result; // get all edges, faces and regions now, so we don't need to filter out dual // entities later result = mbImpl->get_entities_by_dimension( 0, 1, edges ); if( MB_SUCCESS != result ) return result; result = mbImpl->get_entities_by_dimension( 0, 2, faces ); if( MB_SUCCESS != result ) return result; result = mbImpl->get_entities_by_dimension( 0, 3, regions ); if( MB_SUCCESS != result ) return result; // get the max global id for hexes, we'll need for modification ops std::vector< int > gid_vec( regions.size() ); result = mbImpl->tag_get_data( globalId_tag(), regions, &gid_vec[0] ); if( MB_SUCCESS != result ) return result; maxHexId = -1; Range::iterator rit; unsigned int i; for( rit = regions.begin(), i = 0; rit != regions.end(); ++rit, i++ ) { if( gid_vec[i] > maxHexId && mbImpl->type_from_handle( *rit ) == MBHEX ) maxHexId = gid_vec[i]; } } else { // get entities of various dimensions adjacent to these result = mbImpl->get_adjacencies( entities, num_entities, 0, true, vertices, Interface::UNION ); if( MB_SUCCESS != result ) return result; result = mbImpl->get_adjacencies( entities, num_entities, 1, true, edges, Interface::UNION ); if( MB_SUCCESS != result ) return result; result = mbImpl->get_adjacencies( entities, num_entities, 2, true, faces, Interface::UNION ); if( MB_SUCCESS != result ) return result; result = mbImpl->get_adjacencies( entities, num_entities, 3, true, regions, Interface::UNION ); if( MB_SUCCESS != result ) return result; } Range dual_verts; result = construct_dual_vertices( regions, dual_verts ); if( MB_SUCCESS != result || dual_verts.size() != regions.size() ) return result; if( debug ) std::cout << "Constructed " << dual_verts.size() << " dual vertices." << std::endl; // don't really need dual edges, but construct 'em anyway Range dual_edges; result = construct_dual_edges( faces, dual_edges ); if( MB_SUCCESS != result || dual_edges.size() != faces.size() ) return result; if( debug ) std::cout << "Constructed " << dual_edges.size() << " dual edges." << std::endl; // construct dual faces Range dual_faces; result = construct_dual_faces( edges, dual_faces ); if( MB_SUCCESS != result || dual_faces.size() != edges.size() ) return result; if( debug ) std::cout << "Constructed " << dual_faces.size() << " dual faces." << std::endl; // construct dual cells Range dual_cells; result = construct_dual_cells( vertices, dual_cells ); if( MB_SUCCESS != result || dual_cells.size() != vertices.size() ) return result; if( debug ) std::cout << "Constructed " << dual_cells.size() << " dual cells." << std::endl; return MB_SUCCESS; }
ErrorCode moab::DualTool::construct_dual_cells | ( | const Range & | all_verts, |
Range & | new_dual_ents | ||
) | [private] |
construct dual cells for specified vertices
Definition at line 603 of file DualTool.cpp.
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().
{ if( all_verts.empty() ) return MB_SUCCESS; // make sure they're all edges assert( 0 == CN::Dimension( TYPE_FROM_HANDLE( *all_verts.begin() ) ) && 0 == CN::Dimension( TYPE_FROM_HANDLE( *all_verts.rbegin() ) ) ); Range::const_iterator rit; EntityHandle dual_ent; unsigned int is_dual = 0x1; ErrorCode tmp_result = MB_SUCCESS; ErrorCode result = MB_SUCCESS; std::vector< EntityHandle > edges, dfaces; for( rit = all_verts.begin(); rit != all_verts.end(); ++rit ) { if( tmp_result != MB_SUCCESS ) result = tmp_result; tmp_result = mbImpl->tag_get_data( dualEntity_tag(), &( *rit ), 1, &dual_ent ); if( MB_SUCCESS == tmp_result && 0 != dual_ent ) { dual_ents.insert( dual_ent ); continue; } // no dual entity; construct one; get the edges bounding the vertex edges.clear(); dfaces.clear(); tmp_result = mbImpl->get_adjacencies( &( *rit ), 1, 1, false, edges ); if( MB_SUCCESS != tmp_result ) continue; // get the dual faces corresponding to the edges dfaces.resize( edges.size() ); tmp_result = mbImpl->tag_get_data( dualEntity_tag(), &edges[0], edges.size(), &dfaces[0] ); if( MB_SUCCESS != tmp_result ) continue; // create the dual cell from those faces tmp_result = mbImpl->create_element( MBPOLYHEDRON, &dfaces[0], dfaces.size(), dual_ent ); if( MB_SUCCESS != tmp_result || 0 == dual_ent ) continue; // save it in the list of new dual ents dual_ents.insert( dual_ent ); // tag it indicating it's a dual entity tmp_result = mbImpl->tag_set_data( isDualCell_tag(), &dual_ent, 1, &is_dual ); if( MB_SUCCESS != tmp_result ) continue; // tag the primal entity with its dual entity and vica versa tmp_result = mbImpl->tag_set_data( dualEntity_tag(), &( *rit ), 1, &dual_ent ); if( MB_SUCCESS != tmp_result ) continue; tmp_result = mbImpl->tag_set_data( dualEntity_tag(), &dual_ent, 1, &( *rit ) ); if( MB_SUCCESS != tmp_result ) continue; } return result; }
ErrorCode moab::DualTool::construct_dual_edges | ( | const Range & | all_faces, |
Range & | new_dual_ents | ||
) | [private] |
construct dual edges for specified faces
Definition at line 289 of file DualTool.cpp.
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().
{ if( all_faces.empty() ) return MB_SUCCESS; // make sure they're all faces assert( 2 == CN::Dimension( TYPE_FROM_HANDLE( *all_faces.begin() ) ) && 2 == CN::Dimension( TYPE_FROM_HANDLE( *all_faces.rbegin() ) ) ); Range::const_iterator rit; EntityHandle dual_ent; unsigned int is_dual = 0x1; ErrorCode tmp_result = MB_SUCCESS; ErrorCode result = MB_SUCCESS; for( rit = all_faces.begin(); rit != all_faces.end(); ++rit ) { if( tmp_result != MB_SUCCESS ) result = tmp_result; tmp_result = mbImpl->tag_get_data( dualEntity_tag(), &( *rit ), 1, &dual_ent ); if( MB_SUCCESS == tmp_result && 0 != dual_ent ) { dual_ents.insert( dual_ent ); continue; } // no dual entity; construct one; get the bounding regions std::vector< EntityHandle > out_ents; tmp_result = mbImpl->get_adjacencies( &( *rit ), 1, 3, false, out_ents ); if( MB_SUCCESS != tmp_result || out_ents.empty() ) continue; // get the dual vertices std::vector< EntityHandle > dual_verts( out_ents.size() ); tmp_result = mbImpl->tag_get_data( dualEntity_tag(), &out_ents[0], out_ents.size(), &dual_verts[0] ); if( MB_SUCCESS != tmp_result ) continue; assert( dual_verts.size() <= 2 ); double avg_pos[3]; bool bdy_face = ( dual_verts.size() == 1 ? true : false ); if( bdy_face ) { // boundary face - make a dual vertex at the face center and put in list tmp_result = construct_dual_vertex( *rit, dual_ent, true, true ); // put it on vertex list dual_verts.push_back( dual_ent ); } assert( dual_verts.size() == 2 ); // now create the dual edge tmp_result = mbImpl->create_element( MBEDGE, &dual_verts[0], 2, dual_ent ); if( MB_SUCCESS != tmp_result || 0 == dual_ent ) continue; // save it in the list of new dual ents dual_ents.insert( dual_ent ); // tag the primal entity with its dual entity and vica versa tmp_result = mbImpl->tag_set_data( dualEntity_tag(), &( *rit ), 1, &dual_ent ); if( MB_SUCCESS != tmp_result ) continue; tmp_result = mbImpl->tag_set_data( dualEntity_tag(), &dual_ent, 1, &( *rit ) ); if( MB_SUCCESS != tmp_result ) continue; // tag the edge indicating it's a dual entity tmp_result = mbImpl->tag_set_data( isDualCell_tag(), &dual_ent, 1, &is_dual ); if( MB_SUCCESS != tmp_result ) continue; // add a graphics point to the edge; position depends on whether it's a // bdy face (mid-pt of dual edge) or not (mid-pt of primal face) if( bdy_face ) tmp_result = add_graphics_point( dual_ent ); else { // get the face's position tmp_result = MeshTopoUtil( mbImpl ).get_average_position( *rit, avg_pos ); if( MB_SUCCESS != tmp_result ) continue; tmp_result = add_graphics_point( dual_ent, avg_pos ); } if( MB_SUCCESS != tmp_result ) continue; } return result; }
ErrorCode moab::DualTool::construct_dual_faces | ( | const Range & | all_edges, |
Range & | new_dual_ents | ||
) | [private] |
construct dual faces for specified edges
Definition at line 373 of file DualTool.cpp.
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().
{ if( all_edges.empty() ) return MB_SUCCESS; // make sure they're all edges assert( 1 == CN::Dimension( TYPE_FROM_HANDLE( *all_edges.begin() ) ) && 1 == CN::Dimension( TYPE_FROM_HANDLE( *all_edges.rbegin() ) ) ); Range::const_iterator rit; EntityHandle dual_ent; unsigned int is_dual = 0x1; ErrorCode tmp_result = MB_SUCCESS; ErrorCode result = MB_SUCCESS; Range equiv_edges; #define TRC \ if( MB_SUCCESS != tmp_result ) \ { \ result = tmp_result; \ continue; \ } for( rit = all_edges.begin(); rit != all_edges.end(); ++rit ) { tmp_result = mbImpl->tag_get_data( dualEntity_tag(), &( *rit ), 1, &dual_ent ); if( MB_SUCCESS == tmp_result && 0 != dual_ent ) { dual_ents.insert( dual_ent ); continue; } // no dual entity; construct one; get the dual vertices bounding the edge in radial order, // then construct the dual face std::vector< EntityHandle > rad_dverts; bool bdy_edge; tmp_result = get_radial_dverts( *rit, rad_dverts, bdy_edge ); TRC if( rad_dverts.empty() ) continue; tmp_result = mbImpl->create_element( MBPOLYGON, &rad_dverts[0], rad_dverts.size(), dual_ent ); TRC // tag it indicating it's a dual entity, and tag primal/dual with dual/primal tmp_result = mbImpl->tag_set_data( isDualCell_tag(), &dual_ent, 1, &is_dual ); TRC tmp_result = mbImpl->tag_set_data( dualEntity_tag(), &( *rit ), 1, &dual_ent ); TRC tmp_result = mbImpl->tag_set_data( dualEntity_tag(), &dual_ent, 1, &( *rit ) ); TRC // save it in the list of new dual ents dual_ents.insert( dual_ent ); // add a graphics point to the cell; position depends on whether it's a // bdy cell (mid-pt of cell's vertices) or not (mid-pt of primal edge) double avg_pos[3]; tmp_result = MeshTopoUtil( mbImpl ).get_average_position( *rit, avg_pos ); TRC if( bdy_edge ) { // add a new dual edge betw last 2 verts EntityHandle new_edge; tmp_result = mbImpl->create_element( MBEDGE, &rad_dverts[rad_dverts.size() - 2], 2, new_edge ); TRC tmp_result = mbImpl->tag_set_data( isDualCell_tag(), &new_edge, 1, &is_dual ); TRC // tag the new dual edge with the primal edge as it's dual entity; primal // edge IS NOT likewise tagged, since it's already tagged with the 2cell tmp_result = mbImpl->tag_set_data( dualEntity_tag(), &new_edge, 1, &( *rit ) ); TRC // add a graphics pt, position is center of primal edge tmp_result = add_graphics_point( dual_ent ); TRC tmp_result = add_graphics_point( new_edge, avg_pos ); TRC } else { // if inside, point goes on the 2cell, at primal edge mid-pt tmp_result = add_graphics_point( dual_ent, avg_pos ); TRC } // check to see whether we have equiv entities; if we find any, save for later fixup Range dum_edges, dum_poly( dual_ent, dual_ent ); tmp_result = mbImpl->get_adjacencies( dum_poly, 1, false, dum_edges ); if( MB_MULTIPLE_ENTITIES_FOUND == tmp_result ) { // we do - need to add adjacencies to disambiguate; use the primal equiv_edges.merge( dum_edges ); } } if( !equiv_edges.empty() ) result = check_dual_equiv_edges( equiv_edges ); return result; }
ErrorCode moab::DualTool::construct_dual_hyperplanes | ( | const int | dim, |
EntityHandle * | entities, | ||
const int | num_entities | ||
) | [private] |
traverse dual faces of input dimension, constructing dual hyperplanes of them in sets as it goes
Definition at line 825 of file DualTool.cpp.
References check_1d_loop_edge(), moab::debug, dualCurve_tag(), dualSurface_tag(), 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().
{ // this function traverses dual faces of input dimension, constructing // dual hyperplanes of them in sets as it goes // check various inputs int num_quads, num_hexes; if( // this function only makes sense for dim == 1 or dim == 2 ( dim != 1 && dim != 2 ) || // should either be quads or hexes around mbImpl->get_number_entities_by_type( 0, MBQUAD, num_quads ) != MB_SUCCESS || mbImpl->get_number_entities_by_type( 0, MBHEX, num_hexes ) != MB_SUCCESS || // if we're asking for 1d dual ents, should be quads around ( num_quads == 0 && dim == 1 ) || // if we're asking for 2d dual ents, should be hexes around ( num_hexes == 0 && dim == 2 ) ) return MB_FAILURE; Tag hp_tag = ( 1 == dim ? dualCurve_tag() : dualSurface_tag() ); // two stacks: one completely untreated entities, and the other untreated // entities on the current dual hyperplane std::vector< EntityHandle > tot_untreated; // put dual entities of this dimension on the untreated list ErrorCode result = get_dual_entities( dim, entities, num_entities, tot_untreated ); if( MB_SUCCESS != result ) return result; // main part of traversal loop EntityHandle this_ent; EntityHandle this_hp; while( !tot_untreated.empty() ) { if( debug && dim == 2 /*(tot_untreated.size()%report == 0)*/ ) std::cout << "Untreated list size " << tot_untreated.size() << "." << std::endl; this_ent = tot_untreated.back(); tot_untreated.pop_back(); result = mbImpl->tag_get_data( hp_tag, &this_ent, 1, &this_hp ); if( MB_SUCCESS != result && MB_TAG_NOT_FOUND != result ) return result; // d for this entity having a hyperplane assignment already else if( this_hp != 0 ) continue; if( 1 == dim && check_1d_loop_edge( this_ent ) ) continue; // inner loop: traverse the hyperplane 'till we don't have any more result = traverse_hyperplane( hp_tag, this_hp, this_ent ); if( MB_SUCCESS != result ) { std::cout << "Failed to traverse hyperplane "; if( this_hp ) std::cout << mbImpl->id_from_handle( this_hp ) << "." << std::endl; else std::cout << "0." << std::endl; return result; } // ok, now order the edges if it's a chord if( 1 == dim ) order_chord( this_hp ); } return MB_SUCCESS; }
ErrorCode moab::DualTool::construct_dual_vertex | ( | EntityHandle | entity, |
EntityHandle & | dual_ent, | ||
const bool | extra = false , |
||
const bool | add_graphics_pt = true |
||
) | [private] |
Definition at line 233 of file DualTool.cpp.
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().
{ // no dual entity; construct one; first need the avg coordinates unsigned int is_dual = 0x1; double avg_pos[3]; ErrorCode result = MeshTopoUtil( mbImpl ).get_average_position( entity, avg_pos ); if( MB_SUCCESS != result ) return result; // now construct the new dual entity result = mbImpl->create_vertex( avg_pos, dual_ent ); if( MB_SUCCESS != result ) return result; // tag it indicating it's a dual entity result = mbImpl->tag_set_data( isDualCell_tag(), &dual_ent, 1, &is_dual ); if( MB_SUCCESS != result ) return result; // tag the primal entity with its dual entity and vica versa if( extra ) result = mbImpl->tag_set_data( extraDualEntity_tag(), &( entity ), 1, &dual_ent ); else result = mbImpl->tag_set_data( dualEntity_tag(), &( entity ), 1, &dual_ent ); if( MB_SUCCESS != result ) return result; result = mbImpl->tag_set_data( dualEntity_tag(), &dual_ent, 1, &( entity ) ); if( MB_SUCCESS != result ) return result; if( add_graphics_pt ) // put a graphics point on that vertex too result = add_graphics_point( dual_ent, avg_pos ); return result; }
ErrorCode moab::DualTool::construct_dual_vertices | ( | const Range & | all_regions, |
Range & | new_dual_ents | ||
) | [private] |
construct dual vertices for specified regions
Definition at line 197 of file DualTool.cpp.
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().
{ if( all_regions.empty() ) return MB_SUCCESS; // make sure they're all regions assert( 3 == CN::Dimension( TYPE_FROM_HANDLE( *all_regions.begin() ) ) && 3 == CN::Dimension( TYPE_FROM_HANDLE( *all_regions.rbegin() ) ) ); Range::const_iterator rit; EntityHandle dual_ent; ErrorCode tmp_result = MB_SUCCESS; ErrorCode result = MB_SUCCESS; for( rit = all_regions.begin(); rit != all_regions.end(); ++rit ) { if( tmp_result != MB_SUCCESS ) result = tmp_result; tmp_result = mbImpl->tag_get_data( dualEntity_tag(), &( *rit ), 1, &dual_ent ); if( MB_SUCCESS == tmp_result && 0 != dual_ent ) { dual_ents.insert( dual_ent ); continue; } else if( MB_SUCCESS != tmp_result ) continue; tmp_result = construct_dual_vertex( *rit, dual_ent, false, true ); if( MB_SUCCESS != tmp_result ) continue; // save it in the list of new dual ents dual_ents.insert( dual_ent ); } return result; }
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.
References construct_dual(), construct_dual_hyperplanes(), construct_hp_parent_child(), ErrorCode, and MB_SUCCESS.
Referenced by atomic_pillow(), construct_hex_dual(), face_open_collapse(), face_shrink(), main(), rev_atomic_pillow(), and rev_face_shrink().
{ // really quite simple: // construct the dual... ErrorCode result = construct_dual( entities, num_entities ); if( MB_SUCCESS != result ) { std::cerr << "Error constructing dual entities for primal entities." << std::endl; return result; } // now traverse to build 1d and 2d hyperplanes result = construct_dual_hyperplanes( 1, entities, num_entities ); if( MB_SUCCESS != result ) { std::cerr << "Problem traversing 1d hyperplanes." << std::endl; return result; } result = construct_dual_hyperplanes( 2, entities, num_entities ); if( MB_SUCCESS != result ) { std::cerr << "Problem traversing 2d hyperplanes." << std::endl; return result; } result = construct_hp_parent_child(); if( MB_SUCCESS != result ) { std::cerr << "Problem constructing parent/child relations between hyperplanes." << std::endl; return result; } // see? simple, just like I said return MB_SUCCESS; }
ErrorCode moab::DualTool::construct_hex_dual | ( | Range & | entities | ) |
construct the dual entities for a hex mesh, including dual surfaces & curves
Definition at line 709 of file DualTool.cpp.
References moab::Range::begin(), construct_hex_dual(), and moab::Range::end().
{ std::vector< EntityHandle > evec; std::copy( entities.begin(), entities.end(), std::back_inserter( evec ) ); return construct_hex_dual( &evec[0], evec.size() ); }
ErrorCode moab::DualTool::construct_hp_parent_child | ( | ) | [private] |
connect dual surfaces with dual curves using parent/child connections
Definition at line 1141 of file DualTool.cpp.
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().
{ Range dual_surfs, dual_cells, dual_edges; ErrorCode result = this->get_dual_hyperplanes( mbImpl, 2, dual_surfs ); if( MB_SUCCESS != result || dual_surfs.empty() ) return result; std::vector< EntityHandle > dual_curve_sets; for( Range::iterator surf_it = dual_surfs.begin(); surf_it != dual_surfs.end(); ++surf_it ) { // get all the cells, edges in those cells, and chords for those edges dual_cells.clear(); result = mbImpl->get_entities_by_handle( *surf_it, dual_cells ); if( MB_SUCCESS != result ) return result; dual_edges.clear(); result = mbImpl->get_adjacencies( dual_cells, 1, false, dual_edges, Interface::UNION ); if( MB_SUCCESS != result ) return result; dual_curve_sets.resize( dual_edges.size() ); result = mbImpl->tag_get_data( dualCurve_tag(), dual_edges, &dual_curve_sets[0] ); if( MB_SUCCESS != result ) return result; // reuse dual_cells to get unique list of chord sets dual_cells.clear(); for( unsigned int i = 0; i < dual_edges.size(); i++ ) if( dual_curve_sets[i] != 0 ) dual_cells.insert( dual_curve_sets[i] ); // now connect up this dual surf with all the 1d ones for( Range::iterator rit = dual_cells.begin(); rit != dual_cells.end(); ++rit ) { result = mbImpl->add_parent_child( *surf_it, *rit ); if( MB_SUCCESS != result ) return result; } } return MB_SUCCESS; }
ErrorCode moab::DualTool::construct_new_hyperplane | ( | const int | dim, |
EntityHandle & | new_hyperplane, | ||
int & | id | ||
) | [private] |
make a new dual hyperplane with the specified id; if the id specified is -1, set the new one's id to the max found
Definition at line 1083 of file DualTool.cpp.
References CATEGORY_TAG_SIZE, categoryTag, moab::Interface::create_meshset(), 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().
{ ErrorCode result; if( 1 == dim ) result = mbImpl->create_meshset( ( MESHSET_ORDERED | MESHSET_TRACK_OWNER ), new_hyperplane ); else result = mbImpl->create_meshset( ( MESHSET_SET | MESHSET_TRACK_OWNER ), new_hyperplane ); if( MB_SUCCESS != result ) return result; if( -1 == id ) { Range all_hyperplanes; result = get_dual_hyperplanes( mbImpl, dim, all_hyperplanes );RR; std::vector< int > gids( all_hyperplanes.size() ); result = mbImpl->tag_get_data( globalIdTag, all_hyperplanes, ( gids.empty() ) ? NULL : &gids[0] );RR; for( unsigned int i = 0; i < gids.size(); i++ ) if( gids[i] > id ) id = gids[i]; id++; if( 0 == id ) id++; } result = mbImpl->tag_set_data( globalId_tag(), &new_hyperplane, 1, &id );RR; Tag hp_tag = ( 1 == dim ? dualCurve_tag() : dualSurface_tag() ); result = mbImpl->tag_set_data( hp_tag, &new_hyperplane, 1, &new_hyperplane );RR; // assign a category name to these sets static const char dual_category_names[2][CATEGORY_TAG_SIZE] = { "Chord\0", "Sheet\0" }; result = mbImpl->tag_set_data( categoryTag, &new_hyperplane, 1, dual_category_names[dim - 1] ); return result; }
ErrorCode moab::DualTool::delete_dual_entities | ( | EntityHandle * | entities, |
const int | num_entities | ||
) | [private] |
delete a dual entity; updates primal to no longer point to it
Definition at line 1639 of file DualTool.cpp.
Referenced by atomic_pillow(), face_shrink(), foc_delete_dual(), rev_atomic_pillow(), and rev_face_shrink().
{ Range tmp_ents; std::copy( entities, entities + num_entities, range_inserter( tmp_ents ) ); return delete_dual_entities( tmp_ents ); }
ErrorCode moab::DualTool::delete_dual_entities | ( | Range & | entities | ) | [private] |
delete a range of dual entities; updates primal to no longer point to them
Definition at line 1646 of file DualTool.cpp.
References moab::Range::begin(), check_1d_loop_edge(), moab::Interface::delete_entities(), delete_whole_dual(), dualEntity_tag(), moab::Range::empty(), moab::Range::end(), ErrorCode, extraDualEntity_tag(), moab::Interface::get_adjacencies(), get_dual_entity(), get_extra_dual_entity(), moab::Range::insert(), mbImpl, MBPOLYGON, moab::Range::pop_back(), RR, moab::Interface::tag_set_data(), and moab::Interface::type_from_handle().
{ if( entities.empty() ) return delete_whole_dual(); EntityHandle null_entity = 0; ErrorCode result; Range ents_to_delete; while( !entities.empty() ) { EntityHandle this_entity = entities.pop_back(); // reset the primal's dual entity EntityHandle primal = get_dual_entity( this_entity ); if( get_dual_entity( primal ) == this_entity ) { result = mbImpl->tag_set_data( dualEntity_tag(), &primal, 1, &null_entity );RR; } EntityHandle extra = get_extra_dual_entity( primal ); if( 0 != extra ) { result = mbImpl->tag_set_data( extraDualEntity_tag(), &primal, 1, &null_entity );RR; } ents_to_delete.insert( this_entity ); // check for extra dual entities if( mbImpl->type_from_handle( this_entity ) == MBPOLYGON ) { // for 2cell, might be a loop edge Range loop_edges; result = mbImpl->get_adjacencies( &this_entity, 1, 1, false, loop_edges ); for( Range::iterator rit = loop_edges.begin(); rit != loop_edges.end(); ++rit ) if( check_1d_loop_edge( *rit ) ) entities.insert( *rit ); } else if( extra && extra != this_entity ) // just put it on the list; primal for which we're extra has already been // reset to not point to extra entity ents_to_delete.insert( extra ); } // now delete the entities (sheets and chords will be updated automatically) return mbImpl->delete_entities( ents_to_delete ); }
delete all the dual data
Definition at line 3180 of file DualTool.cpp.
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().
{ // delete dual hyperplanes Range dual_surfs, dual_curves; ErrorCode result = this->get_dual_hyperplanes( mbImpl, 2, dual_surfs );RR; result = mbImpl->delete_entities( dual_surfs );RR; result = this->get_dual_hyperplanes( mbImpl, 1, dual_curves );RR; result = mbImpl->delete_entities( dual_curves );RR; // gather up all dual entities Range dual_ents; result = mbImpl->get_entities_by_type_and_tag( 0, MBVERTEX, &isDualCellTag, NULL, 1, dual_ents, Interface::UNION );RR; result = mbImpl->get_entities_by_type_and_tag( 0, MBEDGE, &isDualCellTag, NULL, 1, dual_ents, Interface::UNION );RR; result = mbImpl->get_entities_by_type_and_tag( 0, MBPOLYGON, &isDualCellTag, NULL, 1, dual_ents, Interface::UNION );RR; result = mbImpl->get_entities_by_type_and_tag( 0, MBPOLYHEDRON, &isDualCellTag, NULL, 1, dual_ents, Interface::UNION );RR; // delete them, in reverse order of dimension ErrorCode tmp_result; for( Range::reverse_iterator rit = dual_ents.rbegin(); rit != dual_ents.rend(); ++rit ) { tmp_result = mbImpl->delete_entities( &( *rit ), 1 ); if( MB_SUCCESS != tmp_result ) result = tmp_result; } RR; // delete dual-related tags if( 0 != dualSurfaceTag ) { tmp_result = mbImpl->tag_delete( dualSurfaceTag ); if( MB_SUCCESS != tmp_result && MB_TAG_NOT_FOUND != tmp_result ) result = tmp_result; } if( 0 != dualCurveTag ) { tmp_result = mbImpl->tag_delete( dualCurveTag ); if( MB_SUCCESS != tmp_result && MB_TAG_NOT_FOUND != tmp_result ) result = tmp_result; } if( 0 != dualEntityTag ) { tmp_result = mbImpl->tag_delete( dualEntityTag ); if( MB_SUCCESS != tmp_result && MB_TAG_NOT_FOUND != tmp_result ) result = tmp_result; } if( 0 != extraDualEntityTag ) { tmp_result = mbImpl->tag_delete( extraDualEntityTag ); if( MB_SUCCESS != tmp_result && MB_TAG_NOT_FOUND != tmp_result ) result = tmp_result; } if( 0 != dualGraphicsPointTag ) { tmp_result = mbImpl->tag_delete( dualGraphicsPointTag ); if( MB_SUCCESS != tmp_result && MB_TAG_NOT_FOUND != tmp_result ) result = tmp_result; } return MB_SUCCESS; }
Tag moab::DualTool::dualCurve_tag | ( | ) | const [inline] |
get/set the tag for dual curves
Definition at line 395 of file DualTool.hpp.
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().
{ return dualCurveTag; }
ErrorCode moab::DualTool::dualCurve_tag | ( | const Tag | tag | ) | [inline] |
get/set the tag for dual curves
Definition at line 439 of file DualTool.hpp.
References dualCurveTag, ErrorCode, and MB_SUCCESS.
{ ErrorCode result = MB_FAILURE; if( ( 0 == dualCurveTag && tag ) || dualCurveTag != tag ) { dualCurveTag = tag; result = MB_SUCCESS; } return result; }
Tag moab::DualTool::dualEntity_tag | ( | ) | const [inline] |
get/set the tag for dual entities
Definition at line 405 of file DualTool.hpp.
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().
{ return dualEntityTag; }
ErrorCode moab::DualTool::dualEntity_tag | ( | const Tag | tag | ) | [inline] |
get/set the tag for dual entities
Definition at line 465 of file DualTool.hpp.
References dualEntityTag, ErrorCode, and MB_SUCCESS.
{ ErrorCode result = MB_FAILURE; if( ( 0 == dualEntityTag && tag ) || dualEntityTag != tag ) { dualEntityTag = tag; result = MB_SUCCESS; } return result; }
Tag moab::DualTool::dualGraphicsPoint_tag | ( | ) | const [inline] |
get/set the tag for dual entities
Definition at line 415 of file DualTool.hpp.
References dualGraphicsPointTag.
Referenced by add_graphics_point(), get_cell_points(), and get_graphics_points().
{ return dualGraphicsPointTag; }
ErrorCode moab::DualTool::dualGraphicsPoint_tag | ( | const Tag | tag | ) | [inline] |
get/set the tag for dual entities
Definition at line 491 of file DualTool.hpp.
References dualGraphicsPointTag, ErrorCode, and MB_SUCCESS.
{ ErrorCode result = MB_FAILURE; if( ( 0 == dualGraphicsPointTag && tag ) || dualGraphicsPointTag != tag ) { dualGraphicsPointTag = tag; result = MB_SUCCESS; } return result; }
Tag moab::DualTool::dualSurface_tag | ( | ) | const [inline] |
get/set the tag for dual surfaces
Definition at line 390 of file DualTool.hpp.
References dualSurfaceTag.
Referenced by construct_dual_hyperplanes(), construct_new_hyperplane(), get_dual_hyperplane(), list_entities(), and set_dual_surface_or_curve().
{ return dualSurfaceTag; }
ErrorCode moab::DualTool::dualSurface_tag | ( | const Tag | tag | ) | [inline] |
get/set the tag for dual surfaces
Definition at line 426 of file DualTool.hpp.
References dualSurfaceTag, ErrorCode, and MB_SUCCESS.
{ ErrorCode result = MB_FAILURE; if( ( 0 == dualSurfaceTag && tag ) || dualSurfaceTag != tag ) { dualSurfaceTag = tag; result = MB_SUCCESS; } return result; }
Tag moab::DualTool::extraDualEntity_tag | ( | ) | const [inline] |
get/set the tag for dual entities
Definition at line 410 of file DualTool.hpp.
References extraDualEntityTag.
Referenced by construct_dual_vertex(), delete_dual_entities(), and get_extra_dual_entity().
{ return extraDualEntityTag; }
ErrorCode moab::DualTool::extraDualEntity_tag | ( | const Tag | tag | ) | [inline] |
get/set the tag for dual entities
Definition at line 478 of file DualTool.hpp.
References ErrorCode, extraDualEntityTag, and MB_SUCCESS.
{ ErrorCode result = MB_FAILURE; if( ( 0 == extraDualEntityTag && tag ) || extraDualEntityTag != tag ) { extraDualEntityTag = tag; result = MB_SUCCESS; } return result; }
effect a face open-collapse operation
Definition at line 1727 of file DualTool.cpp.
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, print_cell(), RR, and split_pair_nonmanifold().
{ if( debug_ap ) ( (Core*)mbImpl )->check_adjacencies(); MeshTopoUtil mtu( mbImpl ); std::cout << "OC("; print_cell( ocl ); std::cout << ")-("; print_cell( ocr ); std::cout << ")" << std::endl; // get the primal entities we're dealing with EntityHandle split_quads[2] = { 0 }, split_edges[3] = { 0 }, split_nodes[2] = { 0 }, other_edges[6] = { 0 }, other_nodes[6] = { 0 }; Range hexes; ErrorCode result = foc_get_ents( ocl, ocr, split_quads, split_edges, split_nodes, hexes, other_edges, other_nodes );RR; // get star entities around edges, separated into halves std::vector< EntityHandle > star_dp1[2], star_dp2[2]; result = foc_get_stars( split_quads, split_edges, star_dp1, star_dp2 );RR; if( MBQUAD != mbImpl->type_from_handle( split_quads[0] ) || MBQUAD != mbImpl->type_from_handle( split_quads[1] ) ) return MB_TYPE_OUT_OF_RANGE; result = foc_delete_dual( split_quads, split_edges, hexes ); if( MB_SUCCESS != result ) return result; EntityHandle new_quads[2], new_edges[3], new_nodes[2]; result = split_pair_nonmanifold( split_quads, split_edges, split_nodes, star_dp1, star_dp2, other_edges, other_nodes, new_quads, new_edges, new_nodes ); if( MB_SUCCESS != result ) return result; // now merge entities, the C of foc EntityHandle keepit, deleteit; #define MIN( a, b ) ( ( a ) < ( b ) ? ( a ) : ( b ) ) #define MAX( a, b ) ( ( a ) > ( b ) ? ( a ) : ( b ) ) #define KEEP_DELETE( a, b, c, d ) \ { \ ( c ) = MIN( a, b ); \ ( d ) = MAX( a, b ); \ } // find how many shared edges there were int num_shared_edges = ( split_edges[2] ? 3 : ( split_edges[1] ? 2 : 1 ) ); // first the node(s) for( int i = 0; i < 3 - num_shared_edges; i++ ) { KEEP_DELETE( other_nodes[2 + 2 * i], other_nodes[3 + 2 * i], keepit, deleteit ); result = mbImpl->merge_entities( keepit, deleteit, false, true );RR; } // now the edges for( int i = 0; i < 4 - num_shared_edges; i++ ) { KEEP_DELETE( other_edges[2 * i], other_edges[2 * i + 1], keepit, deleteit ); result = mbImpl->merge_entities( keepit, deleteit, false, true );RR; } // now the faces KEEP_DELETE( split_quads[0], split_quads[1], keepit, deleteit ); result = mbImpl->merge_entities( keepit, deleteit, false, true );RR; result = mbImpl->merge_entities( new_quads[0], new_quads[1], false, true );RR; if( debug_ap ) ( (Core*)mbImpl )->check_adjacencies(); // reconstruct dual result = construct_hex_dual( hexes ); if( MB_SUCCESS != result ) return result; return check_dual_adjs(); }
ErrorCode moab::DualTool::face_shrink | ( | EntityHandle | odedge | ) |
effect face shrink operation
Definition at line 2630 of file DualTool.cpp.
References moab::Range::begin(), construct_hex_dual(), moab::debug_ap, delete_dual_entities(), dim, moab::Range::empty(), moab::Range::end(), moab::MeshTopoUtil::equivalent_entities(), ErrorCode, fs_check_quad_sense(), fs_get_quad_loops(), fs_get_quads(), moab::MeshTopoUtil::get_bridge_adjacencies(), get_dual_hyperplane(), globalId_tag(), moab::Range::insert(), maxHexId, MB_SUCCESS, MB_TYPE_OUT_OF_RANGE, MBEDGE, MBHEX, mbImpl, print_cell(), moab::Interface::type_from_handle(), and moab::Interface::UNION.
{ // some preliminary checking if( mbImpl->type_from_handle( odedge ) != MBEDGE ) return MB_TYPE_OUT_OF_RANGE; if( debug_ap ) ( (Core*)mbImpl )->check_adjacencies(); std::cout << "FS("; print_cell( odedge ); std::cout << ")" << std::endl; EntityHandle quads[4], hexes[2]; std::vector< EntityHandle > connects[4], side_quads[2]; // get the quads along the chord through the 2 hexes, and the vertices // for those quads ErrorCode result = fs_get_quads( odedge, quads, hexes, connects ); if( MB_SUCCESS != result ) return result; // flip/rotate connect arrays so they align & are same sense result = fs_check_quad_sense( hexes[0], quads[0], connects ); if( MB_SUCCESS != result ) return result; // get the quad loops along the "side" surfaces result = fs_get_quad_loops( hexes, connects, side_quads ); if( MB_SUCCESS != result ) return result; // ok, done with setup; now delete dual entities affected by this operation, // which is all the entities adjacent to vertices of dual edge Range adj_verts, adj_edges, dual_ents, cells1or2; MeshTopoUtil mtu( mbImpl ); result = mtu.get_bridge_adjacencies( odedge, 0, 1, adj_edges ); if( MB_SUCCESS != result ) return result; result = mbImpl->get_adjacencies( adj_edges, 0, false, adj_verts, Interface::UNION ); if( MB_SUCCESS != result ) return result; for( int i = 1; i <= 3; i++ ) { result = mbImpl->get_adjacencies( adj_verts, i, false, dual_ents, Interface::UNION ); if( MB_SUCCESS != result ) return result; } // before deleting dual, grab the 1- and 2-cells for( Range::iterator rit = dual_ents.begin(); rit != dual_ents.end(); ++rit ) { int dim = mbImpl->dimension_from_handle( *rit ); if( 1 == dim || 2 == dim ) cells1or2.insert( *rit ); } Range dual_hps; for( Range::iterator rit = cells1or2.begin(); rit != cells1or2.end(); ++rit ) dual_hps.insert( get_dual_hyperplane( *rit ) ); dual_ents.insert( odedge ); result = delete_dual_entities( dual_ents ); if( MB_SUCCESS != result ) return result; // after deleting cells, check for empty chords & sheets, and delete those too for( Range::iterator rit = dual_hps.begin(); rit != dual_hps.end(); ++rit ) { Range tmp_ents; result = mbImpl->get_entities_by_handle( *rit, tmp_ents ); if( MB_SUCCESS != result ) return result; if( tmp_ents.empty() ) { result = mbImpl->delete_entities( &( *rit ), 1 ); if( MB_SUCCESS != result ) return result; } } // remove any explicit adjacencies between side quads and hexes; don't check // for error, since there might not be adjacencies for( int i = 0; i < 4; i++ ) { for( int j = 0; j < 2; j++ ) { result = mbImpl->remove_adjacencies( side_quads[j][i], &hexes[j], 1 ); } } // make inner ring of vertices // get centroid of quad2 double q2coords[12], avg[3] = { 0.0, 0.0, 0.0 }; result = mbImpl->get_coords( &connects[1][0], 4, q2coords ); if( MB_SUCCESS != result ) return result; for( int i = 0; i < 4; i++ ) { avg[0] += q2coords[3 * i]; avg[1] += q2coords[3 * i + 1]; avg[2] += q2coords[3 * i + 2]; } avg[0] *= .25; avg[1] *= .25; avg[2] *= .25; // position new vertices connects[3].resize( 4 ); for( int i = 0; i < 4; i++ ) { q2coords[3 * i] = avg[0] + .25 * ( q2coords[3 * i] - avg[0] ); q2coords[3 * i + 1] = avg[1] + .25 * ( q2coords[3 * i + 1] - avg[1] ); q2coords[3 * i + 2] = avg[2] + .25 * ( q2coords[3 * i + 2] - avg[2] ); result = mbImpl->create_vertex( &q2coords[3 * i], connects[3][i] ); if( MB_SUCCESS != result ) return result; } // ok, now have the 4 connectivity arrays for 4 quads; construct hexes EntityHandle hconnect[8], new_hexes[4]; int new_hex_ids[4]; for( int i = 0; i < 4; i++ ) { int i1 = i, i2 = ( i + 1 ) % 4; hconnect[0] = connects[0][i1]; hconnect[1] = connects[0][i2]; hconnect[2] = connects[3][i2]; hconnect[3] = connects[3][i1]; hconnect[4] = connects[1][i1]; hconnect[5] = connects[1][i2]; hconnect[6] = connects[2][i2]; hconnect[7] = connects[2][i1]; result = mbImpl->create_element( MBHEX, hconnect, 8, new_hexes[i] ); if( MB_SUCCESS != result ) return result; // test for equiv entities from the side quads, and make explicit adjacencies // if there are any for( int j = 0; j < 2; j++ ) { if( mtu.equivalent_entities( side_quads[j][i] ) ) { result = mbImpl->add_adjacencies( side_quads[j][i], &new_hexes[i], 1, false ); if( MB_SUCCESS != result ) return result; } } new_hex_ids[i] = ++maxHexId; } // set the global id tag on the new hexes result = mbImpl->tag_set_data( globalId_tag(), new_hexes, 4, new_hex_ids ); if( MB_SUCCESS != result ) return result; // now fixup other two hexes; start by getting hex through quads 0, 1 // make this first hex switch to the other side, to make the dual look like // a hex push int tmp_ids[2]; result = mbImpl->tag_get_data( globalId_tag(), hexes, 2, tmp_ids ); if( MB_SUCCESS != result ) return result; result = mbImpl->delete_entities( hexes, 2 ); if( MB_SUCCESS != result ) return result; result = mbImpl->delete_entities( &quads[1], 1 ); if( MB_SUCCESS != result ) return result; for( int i = 0; i < 4; i++ ) { hconnect[i] = connects[3][i]; hconnect[4 + i] = connects[2][i]; } result = mbImpl->create_element( MBHEX, hconnect, 8, hexes[0] ); if( MB_SUCCESS != result ) return result; for( int i = 0; i < 4; i++ ) { hconnect[i] = connects[0][i]; hconnect[4 + i] = connects[3][i]; } result = mbImpl->create_element( MBHEX, hconnect, 8, hexes[1] ); if( MB_SUCCESS != result ) return result; // check for and fix any explicit adjacencies on either end quad if( mtu.equivalent_entities( quads[0] ) ) mbImpl->add_adjacencies( quads[0], &hexes[1], 1, false ); if( mtu.equivalent_entities( quads[2] ) ) mbImpl->add_adjacencies( quads[2], &hexes[0], 1, false ); // re-set the global ids for the hexes to what they were result = mbImpl->tag_set_data( globalId_tag(), hexes, 2, tmp_ids ); if( MB_SUCCESS != result ) return result; if( debug_ap ) ( (Core*)mbImpl )->check_adjacencies(); // now update the dual Range tmph; result = mtu.get_bridge_adjacencies( hexes[0], 0, 3, tmph ); if( MB_SUCCESS != result ) return result; result = mtu.get_bridge_adjacencies( hexes[1], 0, 3, tmph ); if( MB_SUCCESS != result ) return result; tmph.insert( hexes[1] ); result = construct_hex_dual( tmph ); if( MB_SUCCESS != result ) return result; return result; }
ErrorCode moab::DualTool::foc_delete_dual | ( | EntityHandle * | split_quads, |
EntityHandle * | split_edges, | ||
Range & | hexes | ||
) | [private] |
function for deleting dual prior to foc operation; special because in many cases need to delete a sheet in preparation for merging onto another
Definition at line 2289 of file DualTool.cpp.
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().
{ // special delete dual procedure, because in some cases we need to delete // a sheet too since it'll get merged into another // figure out whether we'll need to delete a sheet EntityHandle sheet1 = get_dual_hyperplane( get_dual_entity( split_edges[0] ) ); if( split_edges[1] ) sheet1 = get_dual_hyperplane( get_dual_entity( split_edges[1] ) ); EntityHandle chordl = get_dual_hyperplane( get_dual_entity( split_quads[0] ) ); EntityHandle chordr = get_dual_hyperplane( get_dual_entity( split_quads[1] ) ); assert( 0 != sheet1 && 0 != chordl && 0 != chordr ); Range parentsl, parentsr; ErrorCode result = mbImpl->get_parent_meshsets( chordl, parentsl ); if( MB_SUCCESS != result ) return result; result = mbImpl->get_parent_meshsets( chordr, parentsr ); if( MB_SUCCESS != result ) return result; parentsl.erase( sheet1 ); parentsr.erase( sheet1 ); // before deciding which one to delete, collect the other cells which must // be deleted, and all the chords/sheets they're on Range adj_ents, dual_ents, cells1or2; for( int i = 0; i < 3; i++ ) { result = mbImpl->get_adjacencies( hexes, i, false, adj_ents, Interface::UNION ); if( MB_SUCCESS != result ) return result; } // cache any adjacent hexes, for rebuilding the dual later result = mbImpl->get_adjacencies( adj_ents, 3, false, hexes, Interface::UNION ); if( MB_SUCCESS != result ) return result; for( Range::iterator rit = adj_ents.begin(); rit != adj_ents.end(); ++rit ) { EntityHandle this_ent = get_dual_entity( *rit ); dual_ents.insert( this_ent ); int dim = mbImpl->dimension_from_handle( this_ent ); if( 1 == dim || 2 == dim ) cells1or2.insert( this_ent ); } Range dual_hps; for( Range::iterator rit = cells1or2.begin(); rit != cells1or2.end(); ++rit ) dual_hps.insert( get_dual_hyperplane( *rit ) ); result = delete_dual_entities( dual_ents ); if( MB_SUCCESS != result ) return result; // now decide which sheet to delete (to be merged into the other) EntityHandle sheet_delete = 0; if( is_blind( *parentsl.begin() ) ) sheet_delete = *parentsl.begin(); else if( is_blind( *parentsr.begin() ) ) sheet_delete = *parentsr.begin(); else { // neither is blind, take the one with fewer cells Range tmp_ents; int numl, numr; result = mbImpl->get_number_entities_by_handle( *parentsl.begin(), numl ); if( MB_SUCCESS != result ) return result; result = mbImpl->get_number_entities_by_handle( *parentsr.begin(), numr ); if( MB_SUCCESS != result ) return result; sheet_delete = ( numl > numr ? *parentsr.begin() : *parentsl.begin() ); } assert( 0 != sheet_delete ); // after deleting cells, check for empty chords & sheets, and delete those too for( Range::iterator rit = dual_hps.begin(); rit != dual_hps.end(); ++rit ) { Range tmp_ents; result = mbImpl->get_entities_by_handle( *rit, tmp_ents ); if( MB_SUCCESS != result ) return result; if( tmp_ents.empty() ) { result = mbImpl->delete_entities( &( *rit ), 1 ); if( MB_SUCCESS != result ) return result; } else if( *rit == sheet_delete ) { // delete the sheet result = mbImpl->delete_entities( &( *rit ), 1 ); if( MB_SUCCESS != result ) return result; } } // now just to be safe, add the hexes bridge-adjacent across vertices // to the hexes we already have Range tmp_hexes; MeshTopoUtil mtu( mbImpl ); for( Range::iterator rit = hexes.begin(); rit != hexes.end(); ++rit ) { result = mtu.get_bridge_adjacencies( *rit, 0, 3, tmp_hexes ); if( MB_SUCCESS != result ) return result; } hexes.merge( tmp_hexes ); return MB_SUCCESS; }
ErrorCode moab::DualTool::foc_get_addl_ents | ( | std::vector< EntityHandle > * | star_dp1, |
std::vector< EntityHandle > * | star_dp2, | ||
EntityHandle * | split_edges, | ||
EntityHandle | split_node, | ||
Range * | addl_ents | ||
) | [private] |
for foc's splitting two shared edges, there might be additional entities connected to the split node that also have to be updated
Definition at line 2098 of file DualTool.cpp.
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().
{ // if we're splitting 2 edges, there might be other edges that have the split // node; also need to know which side they're on // algorithm: for a given star_dp1 (faces) on a side: // - get all edges adj to all faces -> R1 // - get all edges adj to split_node -> R2 // - R3 = R1 & R2 (edges connected to split_node & adj to a star face) // - R3 -= split_edges (take split edges off addl_ents) Range R2; MeshTopoUtil mtu( mbImpl ); ErrorCode result = mbImpl->get_adjacencies( &split_node, 1, 1, false, R2 );RR; Range::iterator rit; for( int i = 0; i < 2; i++ ) { Range R1, R3; result = mbImpl->get_adjacencies( &star_dp1[i][0], star_dp1[i].size(), 1, false, R1, Interface::UNION );RR; R3 = intersect( R1, R2 ); for( int j = 0; j < 3; j++ ) if( split_edges[j] ) R3.erase( split_edges[j] ); addl_ents[i].merge( R3 ); } return MB_SUCCESS; }
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.
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 smoab::UNION.
Referenced by face_open_collapse().
{ // get the entities used for foc; ocl and ocr are dual 1-cells // representing quads to be split; returned from this function: // quads[2] - 2 quads to be split // split_edges[2] - edge(s) to be split (2nd is 0 if only one) // split_node - node to be split, if any (otherwise 0) // hexes - connected hexes to split_edges // other_edges[0], [1] - edges in quads[0] and [1] sharing node with // one end of split_edges[0] // other_edges[2], [3] - other end of split_edges[0] (or [1] if 2 // split_edges) // other_edges[4], [5] - edges in quads[0], [1] opposite to split_edges[0] // other_nodes[0], [1] - nodes on other_edges[0], [1] not shared with // split_edges[0] // other_nodes[2], [3] - nodes on other_edges[2], [3] not shared with // split_edges[0] (if 2 split_edges, there's only 1 opposite node // in each split quad) // (for diagram, see Tim's notes from 11/12/07) split_quads[0] = get_dual_entity( ocl ); split_quads[1] = get_dual_entity( ocr ); if( MBQUAD != mbImpl->type_from_handle( split_quads[0] ) || MBQUAD != mbImpl->type_from_handle( split_quads[1] ) ) return MB_TYPE_OUT_OF_RANGE; Range common_edges; ErrorCode result = mbImpl->get_adjacencies( split_quads, 2, 1, false, common_edges ); if( MB_SUCCESS != result ) return result; if( common_edges.empty() ) return MB_FAILURE; for( unsigned int i = 0; i < common_edges.size(); i++ ) split_edges[i] = common_edges[i]; MeshTopoUtil mtu( mbImpl ); if( common_edges.size() == 3 ) { // find other (non-shared) edges for( int i = 0; i < 2; i++ ) { Range tmp_edges; result = mbImpl->get_adjacencies( &split_quads[i], 1, 1, false, tmp_edges ); if( MB_SUCCESS != result ) return result; tmp_edges = subtract( tmp_edges, common_edges ); assert( tmp_edges.size() == 1 ); other_edges[i] = *tmp_edges.begin(); } assert( other_edges[0] && other_edges[1] && other_edges[0] != other_edges[1] ); // arrange common edges so middle is in middle result = mtu.opposite_entity( split_quads[0], other_edges[0], split_edges[1] );RR; common_edges.erase( split_edges[1] ); split_edges[0] = *common_edges.begin(); split_edges[2] = *common_edges.rbegin(); common_edges.insert( split_edges[1] ); // get split nodes and other nodes split_nodes[0] = mtu.common_entity( split_edges[0], split_edges[1], 0 ); split_nodes[1] = mtu.common_entity( split_edges[2], split_edges[1], 0 ); other_nodes[0] = mtu.common_entity( split_edges[0], other_edges[0], 0 ); other_nodes[1] = mtu.common_entity( split_edges[2], other_edges[1], 0 ); assert( other_nodes[0] && other_nodes[1] && split_nodes[0] && split_nodes[1] ); assert( split_edges[0] && split_edges[1] && split_edges[2] && split_edges[0] != split_edges[1] && split_edges[1] != split_edges[2] && split_edges[0] != split_edges[2] ); } else if( common_edges.size() == 2 ) { // split node is shared by split edges split_nodes[0] = mtu.common_entity( split_edges[0], split_edges[1], 0 ); if( 0 == split_nodes[0] ) return MB_FAILURE; // first two other nodes are on split edges opposite split node result = mtu.opposite_entity( split_edges[0], split_nodes[0], other_nodes[0] );RR; result = mtu.opposite_entity( split_edges[1], split_nodes[0], other_nodes[1] );RR; // over split quads: for( int i = 0; i < 2; i++ ) { // 1st other edge is opposite second split edge result = mtu.opposite_entity( split_quads[i], split_edges[1], other_edges[i] );RR; // 2nd other edge is opposite first split edge result = mtu.opposite_entity( split_quads[i], split_edges[0], other_edges[2 + i] );RR; // last other node is opposite split node on split quad result = mtu.opposite_entity( split_quads[i], split_nodes[0], other_nodes[2 + i] );RR; } } else { const EntityHandle* connect; int num_connect; result = mbImpl->get_connectivity( split_edges[0], connect, num_connect ); if( MB_SUCCESS != result ) return result; // other_nodes[0], [1] are on split edge other_nodes[0] = connect[0]; other_nodes[1] = connect[1]; // for each of the split quads for( int i = 0; i < 2; i++ ) { // get the other edge on the split quad adj to node 0 on the split edge, by getting // edges adj to split quad and node and removing split edge; that's other_edge[i] Range tmp_range1, tmp_range2; tmp_range1.insert( connect[0] ); tmp_range1.insert( split_quads[i] ); result = mbImpl->get_adjacencies( tmp_range1, 1, false, tmp_range2 ); if( MB_SUCCESS != result ) return result; tmp_range2.erase( split_edges[0] ); assert( tmp_range2.size() == 1 ); other_edges[i] = *tmp_range2.begin(); // get edge connected to other node on split edge & split quad; that's // opposite prev other_edges on the split quad; that's other_edges[4+i] result = mtu.opposite_entity( split_quads[i], other_edges[i], other_edges[4 + i] );RR; // get the edge on the split quad opposite the split edge; that's other_edges[2+i] result = mtu.opposite_entity( split_quads[i], split_edges[0], other_edges[2 + i] );RR; // get nodes on other side of split quad from split edge, by getting common // node between top/bottom edge and opposite edge other_nodes[2 + i] = mtu.common_entity( other_edges[i], other_edges[2 + i], 0 ); other_nodes[4 + i] = mtu.common_entity( other_edges[4 + i], other_edges[2 + i], 0 ); if( 0 == other_nodes[2 + i] || 0 == other_nodes[4 + i] ) return MB_FAILURE; } } result = mbImpl->get_adjacencies( split_edges, common_edges.size(), 3, false, hexes, Interface::UNION ); if( MB_SUCCESS != result ) return result; assert( "split node not in other_nodes" && other_nodes[0] != split_nodes[0] && other_nodes[0] != split_nodes[1] && other_nodes[1] != split_nodes[0] && other_nodes[1] != split_nodes[1] ); assert( "each split node on an end of a split edge" && mtu.common_entity( other_nodes[0], split_edges[0], 0 ) && ( ( ( split_edges[2] && mtu.common_entity( other_nodes[1], split_edges[2], 0 ) ) || ( split_edges[1] && mtu.common_entity( other_nodes[1], split_edges[1], 0 ) ) || mtu.common_entity( other_nodes[1], split_edges[0], 0 ) ) ) ); assert( "opposite other edges meet at an other node" && ( mtu.common_entity( other_edges[0], other_edges[1], 0 ) == other_nodes[0] || ( split_edges[2] && mtu.common_entity( other_edges[0], other_edges[1], 0 ) == other_nodes[1] ) ) && ( split_edges[2] || ( split_edges[1] && mtu.common_entity( other_edges[2], other_edges[3], 0 ) == other_nodes[1] ) || mtu.common_entity( other_edges[4], other_edges[5], 0 ) == other_nodes[1] ) ); return MB_SUCCESS; }
ErrorCode moab::DualTool::foc_get_stars | ( | EntityHandle * | split_quads, |
EntityHandle * | split_edges, | ||
std::vector< EntityHandle > * | star_dp1, | ||
std::vector< EntityHandle > * | star_dp2 | ||
) | [private] |
given the split quads and edges, get the face and hex stars around the edge(s), separated into halves, each of which goes with the new or old entities after the split
Definition at line 2131 of file DualTool.cpp.
References ErrorCode, MB_SUCCESS, mbImpl, RR, and moab::MeshTopoUtil::star_entities().
Referenced by face_open_collapse().
{ bool on_bdy = false, on_bdy_tmp; ErrorCode result; MeshTopoUtil mtu( mbImpl ); // get the star around the split_edge std::vector< EntityHandle > qstar, hstar; unsigned int qpos = 0; for( int i = 0; i < 3; i++ ) { if( !split_edges[i] ) break; // get the star around this split edge unsigned int qpos_tmp = 0; std::vector< EntityHandle > qstar_tmp, hstar_tmp; result = mtu.star_entities( split_edges[i], qstar_tmp, on_bdy_tmp, 0, &hstar_tmp );RR; // if we're on the bdy, add a null to the hex star too if( on_bdy_tmp ) { assert( hstar_tmp.size() == qstar_tmp.size() - 1 ); hstar_tmp.push_back( 0 ); on_bdy = true; } // get the position of first split quad in star while( qpos_tmp < qstar_tmp.size() && qstar_tmp[qpos_tmp] != split_quads[0] ) qpos_tmp++; if( qpos_tmp == qstar_tmp.size() ) return MB_FAILURE; bool forward; // 1st iteration is forward by definition if( 0 == i ) forward = true; // need to be careful about direction on later iters else if( hstar[qpos] == hstar_tmp[qpos_tmp] ) forward = true; else if( hstar[qpos] == hstar_tmp[( qpos_tmp + qstar_tmp.size() - 1 ) % qstar_tmp.size()] && hstar_tmp[qpos_tmp] == hstar[( qpos + qstar.size() - 1 ) % qstar.size()] ) forward = false; else return MB_FAILURE; if( forward ) { // 1st half of star // save hex right after split_quad[0] first star_dp2[0].push_back( hstar_tmp[qpos_tmp] ); qpos_tmp = ( qpos_tmp + 1 ) % qstar_tmp.size(); while( qstar_tmp[qpos_tmp] != split_quads[1] ) { star_dp1[0].push_back( qstar_tmp[qpos_tmp] ); star_dp2[0].push_back( hstar_tmp[qpos_tmp] ); qpos_tmp = ( qpos_tmp + 1 ) % qstar_tmp.size(); } // 2nd half of star // save hex right after split_quad[1] first star_dp2[1].push_back( hstar_tmp[qpos_tmp] ); qpos_tmp = ( qpos_tmp + 1 ) % qstar_tmp.size(); while( qstar_tmp[qpos_tmp] != split_quads[0] ) { star_dp1[1].push_back( qstar_tmp[qpos_tmp] ); star_dp2[1].push_back( hstar_tmp[qpos_tmp] ); qpos_tmp = ( qpos_tmp + 1 ) % qstar_tmp.size(); } } else { // go in reverse - take prev hex instead of current // one, and step in reverse // save hex right after split_quad[0] first qpos_tmp = ( qpos_tmp + qstar_tmp.size() - 1 ) % qstar_tmp.size(); star_dp2[0].push_back( hstar_tmp[qpos_tmp] ); while( qstar_tmp[qpos_tmp] != split_quads[1] ) { star_dp1[0].push_back( qstar_tmp[qpos_tmp] ); qpos_tmp = ( qpos_tmp + qstar_tmp.size() - 1 ) % qstar_tmp.size(); star_dp2[0].push_back( hstar_tmp[qpos_tmp] ); } // 2nd half of star // save hex right after split_quad[1] first qpos_tmp = ( qpos_tmp + qstar_tmp.size() - 1 ) % qstar_tmp.size(); star_dp2[1].push_back( hstar_tmp[qpos_tmp] ); while( qstar_tmp[qpos_tmp] != split_quads[0] ) { star_dp1[1].push_back( qstar_tmp[qpos_tmp] ); qpos_tmp = ( qpos_tmp + qstar_tmp.size() - 1 ) % qstar_tmp.size(); star_dp2[1].push_back( hstar_tmp[qpos_tmp] ); } } if( 0 == i ) { // if we're on the first iteration, save results and continue, other iters // get compared to this one qstar.swap( qstar_tmp ); hstar.swap( hstar_tmp ); on_bdy = on_bdy_tmp; qpos = qpos_tmp; } } // split quads go on list with NULLs, if any, otherwise on 2nd if( on_bdy ) { if( std::find( star_dp2[0].begin(), star_dp2[0].end(), 0 ) != star_dp2[0].end() ) { // remove *all* the zeros star_dp2[0].erase( std::remove( star_dp2[0].begin(), star_dp2[0].end(), 0 ), star_dp2[0].end() ); // put the split quads on this half star_dp1[0].push_back( split_quads[0] ); star_dp1[0].push_back( split_quads[1] ); } else { star_dp2[1].erase( std::remove( star_dp2[1].begin(), star_dp2[1].end(), 0 ), star_dp2[1].end() ); // put the split quads on this half star_dp1[1].push_back( split_quads[0] ); star_dp1[1].push_back( split_quads[1] ); } } else { star_dp1[1].push_back( split_quads[0] ); star_dp1[1].push_back( split_quads[1] ); } // some error checking if( !( ( ( std::find( star_dp1[0].begin(), star_dp1[0].end(), split_quads[0] ) == star_dp1[0].end() && std::find( star_dp1[0].begin(), star_dp1[0].end(), split_quads[1] ) == star_dp1[0].end() && std::find( star_dp1[1].begin(), star_dp1[1].end(), split_quads[0] ) != star_dp1[1].end() && std::find( star_dp1[1].begin(), star_dp1[1].end(), split_quads[1] ) != star_dp1[1].end() ) || ( std::find( star_dp1[1].begin(), star_dp1[1].end(), split_quads[0] ) == star_dp1[1].end() && std::find( star_dp1[1].begin(), star_dp1[1].end(), split_quads[1] ) == star_dp1[1].end() && std::find( star_dp1[0].begin(), star_dp1[0].end(), split_quads[0] ) != star_dp1[0].end() && std::find( star_dp1[0].begin(), star_dp1[0].end(), split_quads[1] ) != star_dp1[0].end() ) ) ) ) { std::cerr << "foc_get_stars: both split quads should be on the same star list half and not " << "on the other, failed" << std::endl; return MB_FAILURE; } if( !( std::find( star_dp2[0].begin(), star_dp2[0].end(), 0 ) == star_dp2[0].end() && std::find( star_dp2[1].begin(), star_dp2[1].end(), 0 ) == star_dp2[1].end() ) ) { std::cerr << "foc_get_stars: no NULLs on the hstar lists, failed"; return MB_FAILURE; } return MB_SUCCESS; }
ErrorCode moab::DualTool::fs_check_quad_sense | ( | EntityHandle | hex0, |
EntityHandle | quad0, | ||
std::vector< EntityHandle > * | connects | ||
) | [private] |
check sense of connect arrays, and reverse/rotate if necessary
Definition at line 2846 of file DualTool.cpp.
References moab::MeshTopoUtil::common_entity(), moab::dum, ErrorCode, MB_SUCCESS, mbImpl, and moab::Interface::side_number().
Referenced by face_shrink(), and rev_face_shrink().
{ // check sense of 0th quad wrt hex; since sense is out of element, // switch if quad is NOT reversed wrt hex int dum1, dum2, sense = 0; ErrorCode result = mbImpl->side_number( hex0, quad0, dum1, sense, dum2 ); if( MB_SUCCESS != result ) return result; assert( 0 != sense ); if( 1 == sense ) { // just switch sense of this one; others will get switched next EntityHandle dum = connects[0][0]; connects[0][0] = connects[0][2]; connects[0][2] = dum; } // check sense of 1st, 2nd quads, rotate if necessary to align connect arrays int index0 = -1, index2 = -1, sense0 = 0, sense2 = 0; MeshTopoUtil mtu( mbImpl ); for( int i = 0; i < 4; i++ ) { if( 0 != mtu.common_entity( connects[0][0], connects[1][i], 1 ) ) { index0 = i; if( 0 != mtu.common_entity( connects[0][1], connects[1][( i + 1 ) % 4], 1 ) ) sense0 = 1; else if( 0 != mtu.common_entity( connects[0][1], connects[1][( i + 4 - 1 ) % 4], 1 ) ) sense0 = -1; break; } } assert( index0 != -1 && sense0 != 0 ); if( sense0 == -1 ) { EntityHandle dumh = connects[1][0]; connects[1][0] = connects[1][2]; connects[1][2] = dumh; if( index0 % 2 == 0 ) index0 = ( index0 + 2 ) % 4; } if( index0 != 0 ) { std::vector< EntityHandle > tmpc; for( int i = 0; i < 4; i++ ) tmpc.push_back( connects[1][( index0 + i ) % 4] ); connects[1].swap( tmpc ); } for( int i = 0; i < 4; i++ ) { if( 0 != mtu.common_entity( connects[1][0], connects[2][i], 1 ) ) { index2 = i; if( 0 != mtu.common_entity( connects[1][1], connects[2][( i + 1 ) % 4], 1 ) ) sense2 = 1; else if( 0 != mtu.common_entity( connects[1][1], connects[2][( i + 4 - 1 ) % 4], 1 ) ) sense2 = -1; break; } } assert( index2 != -1 && sense2 != 0 ); if( sense2 == -1 ) { EntityHandle dumh = connects[2][0]; connects[2][0] = connects[2][2]; connects[2][2] = dumh; if( index2 % 2 == 0 ) index2 = ( index2 + 2 ) % 4; } if( index2 != 0 ) { std::vector< EntityHandle > tmpc; for( int i = 0; i < 4; i++ ) tmpc.push_back( connects[2][( index2 + i ) % 4] ); connects[2].swap( tmpc ); } return MB_SUCCESS; }
ErrorCode moab::DualTool::fs_get_quad_loops | ( | EntityHandle * | hexes, |
std::vector< EntityHandle > * | connects, | ||
std::vector< EntityHandle > * | side_quads | ||
) | [private] |
get loops of quads around 2 hexes, ordered similarly to vertex loops
Definition at line 2821 of file DualTool.cpp.
References moab::Range::begin(), ErrorCode, moab::Interface::get_adjacencies(), moab::Range::insert(), MB_SUCCESS, mbImpl, and moab::Range::size().
Referenced by face_shrink().
{ for( int i = 0; i < 4; i++ ) { for( int j = 0; j < 2; j++ ) { Range adj_ents, dum_quads; adj_ents.insert( hexes[j] ); adj_ents.insert( connects[j][i] ); adj_ents.insert( connects[j][( i + 1 ) % 4] ); adj_ents.insert( connects[j + 1][i] ); adj_ents.insert( connects[j + 1][( i + 1 ) % 4] ); ErrorCode result = mbImpl->get_adjacencies( adj_ents, 2, false, dum_quads ); if( MB_SUCCESS != result ) return result; assert( 1 == dum_quads.size() ); side_quads[j].push_back( *dum_quads.begin() ); } } return MB_SUCCESS; }
ErrorCode moab::DualTool::fs_get_quads | ( | EntityHandle | odedge, |
EntityHandle * | quads, | ||
EntityHandle * | hexes, | ||
std::vector< EntityHandle > * | connects | ||
) | [private] |
get the three quads for a face shrink, the two hexes, and the connectivity of the three quads
Definition at line 3138 of file DualTool.cpp.
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().
{ // need to get the three quads along the chord EntityHandle chord = get_dual_hyperplane( odedge ); if( 0 == chord ) return MB_FAILURE; std::vector< EntityHandle > edges; ErrorCode result = mbImpl->get_entities_by_handle( chord, edges ); if( MB_FAILURE == result ) return result; std::vector< EntityHandle >::iterator vit = std::find( edges.begin(), edges.end(), odedge ); // shouldn't be first or last edge on chord if( vit == edges.end() || *edges.begin() == *vit || *edges.rbegin() == *vit ) return MB_FAILURE; // get quads/connectivity for first 3 quads quads[0] = get_dual_entity( *( vit - 1 ) ); quads[1] = get_dual_entity( *vit ); quads[2] = get_dual_entity( *( vit + 1 ) ); for( int i = 0; i < 3; i++ ) { result = mbImpl->get_connectivity( &quads[i], 1, connects[i], true ); if( MB_SUCCESS != result ) return result; } Range tmph; result = mbImpl->get_adjacencies( quads, 2, 3, false, tmph ); if( MB_SUCCESS != result ) return result; assert( tmph.size() == 1 ); hexes[0] = *tmph.begin(); tmph.clear(); result = mbImpl->get_adjacencies( &quads[1], 2, 3, false, tmph ); if( MB_SUCCESS != result ) return result; assert( tmph.size() == 1 ); hexes[1] = *tmph.begin(); return MB_SUCCESS; }
ErrorCode moab::DualTool::fsr_get_fourth_quad | ( | std::vector< EntityHandle > * | connects, |
std::vector< EntityHandle > * | side_quads | ||
) | [private] |
given connectivity of first 3 quads for reverse face shrink, get fourth (outer 4 verts to be shared by two inner hexes) and quads around the side of the structure
Definition at line 3082 of file DualTool.cpp.
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().
{ // given the first three quad connectivities in ordered vectors, get the fourth, // where the fourth is really the 4 vertices originally shared by the 2 hexes // before the face shrink on them // vertex on 4th quad is in quad adj to other 3 verts for( int i = 0; i < 4; i++ ) { Range start_verts, tmp_verts, quads; for( int j = 0; j < 3; j++ ) start_verts.insert( connects[j][i] ); ErrorCode result = mbImpl->get_adjacencies( start_verts, 2, false, quads ); if( MB_SUCCESS != result ) return result; assert( quads.size() == 1 ); result = mbImpl->get_adjacencies( &( *quads.begin() ), 1, 0, false, tmp_verts );RR; tmp_verts = subtract( tmp_verts, start_verts ); assert( 1 == tmp_verts.size() ); connects[3].push_back( *tmp_verts.begin() ); } // now get the side quads for( int i = 0; i < 4; i++ ) { Range dum_ents, hexes; dum_ents.insert( connects[1][i] ); dum_ents.insert( connects[1][( i + 1 ) % 4] ); dum_ents.insert( connects[3][i] ); ErrorCode result = mbImpl->get_adjacencies( dum_ents, 3, false, hexes ); if( MB_SUCCESS != result ) return result; assert( 1 == hexes.size() ); hexes.insert( connects[0][i] ); hexes.insert( connects[0][( i + 1 ) % 4] ); hexes.insert( connects[3][i] ); hexes.insert( connects[3][( i + 1 ) % 4] ); dum_ents.clear(); result = mbImpl->get_adjacencies( hexes, 2, false, dum_ents ); if( MB_SUCCESS != result ) return result; assert( dum_ents.size() == 1 ); side_quads[0].push_back( *dum_ents.begin() ); hexes.erase( connects[0][i] ); hexes.erase( connects[0][( i + 1 ) % 4] ); hexes.insert( connects[2][i] ); hexes.insert( connects[2][( i + 1 ) % 4] ); dum_ents.clear(); result = mbImpl->get_adjacencies( hexes, 2, false, dum_ents ); if( MB_SUCCESS != result ) return result; side_quads[1].push_back( *dum_ents.begin() ); } return MB_SUCCESS; }
ErrorCode moab::DualTool::get_cell_points | ( | EntityHandle | dual_ent, |
std::vector< int > & | npts, | ||
std::vector< GraphicsPoint > & | points | ||
) | [private] |
get points defining facets of a 2cell
Definition at line 1228 of file DualTool.cpp.
References dualGraphicsPoint_tag(), ErrorCode, moab::Interface::get_adjacencies(), moab::Interface::get_connectivity(), moab::Range::insert(), mbImpl, MBPOLYGON, RR, moab::Interface::tag_get_data(), moab::Interface::type_from_handle(), and moab::Interface::UNION.
Referenced by get_graphics_points().
{ assert( MBPOLYGON == mbImpl->type_from_handle( dual_ent ) ); // get the 1cells in this 2cell Range one_cells; Range tc_range; tc_range.insert( dual_ent ); ErrorCode result = mbImpl->get_adjacencies( tc_range, 1, false, one_cells, Interface::UNION );RR; int num_edges = one_cells.size(); std::vector< GraphicsPoint > dum_gps( num_edges + 1 ); // get graphics points for 0cells and for this cell result = mbImpl->tag_get_data( dualGraphicsPoint_tag(), one_cells, &dum_gps[0] );RR; result = mbImpl->tag_get_data( dualGraphicsPoint_tag(), &dual_ent, 1, &( dum_gps[num_edges] ) );RR; Range::iterator eit; const EntityHandle* connect; int num_connect; GraphicsPoint vert_gps[2]; int i; for( i = 0, eit = one_cells.begin(); i < num_edges; i++, ++eit ) { // get the vertices and the graphics points for them result = mbImpl->get_connectivity( *eit, connect, num_connect );RR; result = mbImpl->tag_get_data( dualGraphicsPoint_tag(), connect, 2, vert_gps );RR; // make the 2 tris corresponding to this edge; don't worry about order // for now npts.push_back( 3 ); points.push_back( dum_gps[num_edges] ); points.push_back( vert_gps[0] ); points.push_back( dum_gps[i] ); npts.push_back( 3 ); points.push_back( dum_gps[num_edges] ); points.push_back( dum_gps[i] ); points.push_back( vert_gps[1] ); } return result; }
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.
References dualEntity_tag(), moab::dum, 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(), main(), and rev_atomic_pillow().
{ if( 0 == isDualCell_tag() ) return MB_SUCCESS; if( 0 > dim || 3 < dim ) return MB_INDEX_OUT_OF_RANGE; unsigned int dum = 0x1; const void* dum_ptr = &dum; static EntityType dual_type[] = { MBVERTEX, MBEDGE, MBPOLYGON, MBPOLYHEDRON }; Range dim_ents; ErrorCode result; if( 0 == entities || 0 == num_entities ) { // just get all the dual entities of this dimension result = mbImpl->get_entities_by_type_and_tag( 0, dual_type[dim], &isDualCellTag, &dum_ptr, 1, dual_ents ); } else { // else look for specific dual entities result = mbImpl->get_adjacencies( entities, num_entities, 3 - dim, false, dim_ents, Interface::UNION ); if( MB_SUCCESS != result ) return result; std::vector< EntityHandle > dual_ents_vec( dim_ents.size() ); result = mbImpl->tag_get_data( dualEntity_tag(), dim_ents, &dual_ents_vec[0] ); if( MB_SUCCESS != result ) return result; std::copy( dual_ents_vec.begin(), dual_ents_vec.end(), range_inserter( dual_ents ) ); } return result; }
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.
References moab::Range::begin(), moab::Range::end(), ErrorCode, get_dual_entities(), MB_SUCCESS, and moab::Range::size().
{ Range tmp_range; ErrorCode result = get_dual_entities( dim, entities, num_entities, tmp_range ); if( MB_SUCCESS != result ) return result; // dual_ents.insert(dual_ents.end(), tmp_range.begin(), tmp_range.end()); dual_ents.reserve( dual_ents.size() + tmp_range.size() ); for( Range::const_iterator it = tmp_range.begin(); it != tmp_range.end(); ++it ) { dual_ents.push_back( *it ); } return MB_SUCCESS; }
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.
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 result = MB_SUCCESS; if( NULL != dcells ) { result = mbImpl->get_entities_by_type( dual_ent, MBPOLYGON, *dcells ); if( MB_SUCCESS != result ) return result; } if( NULL != dedges ) { if( NULL != dcells ) result = mbImpl->get_adjacencies( *dcells, 1, false, *dedges, Interface::UNION ); else result = mbImpl->get_entities_by_type( dual_ent, MBEDGE, *dedges ); if( MB_SUCCESS != result ) return result; } if( NULL != dverts ) { if( NULL != dcells ) result = mbImpl->get_adjacencies( *dcells, 0, false, *dverts, Interface::UNION ); else if( NULL != dedges ) result = mbImpl->get_adjacencies( *dedges, 0, false, *dverts, Interface::UNION ); else { Range all_ents; result = mbImpl->get_entities_by_handle( dual_ent, all_ents );RR; result = mbImpl->get_adjacencies( all_ents, 0, false, *dverts, Interface::UNION ); } if( MB_SUCCESS != result ) return result; } if( NULL != dverts_loop && NULL != dverts ) { static std::vector< EntityHandle > dual_ents; dual_ents.resize( dverts->size() ); result = mbImpl->tag_get_data( dualEntity_tag(), *dverts, &dual_ents[0] ); if( MB_SUCCESS != result ) return result; Range::iterator rit; unsigned int i; for( rit = dverts->begin(), i = 0; rit != dverts->end(); ++rit, i++ ) if( 0 != dual_ents[i] && mbImpl->type_from_handle( dual_ents[i] ) == MBQUAD ) dverts_loop->insert( *rit ); } if( NULL != dedges_loop && NULL != dedges ) { static std::vector< EntityHandle > dual_ents; dual_ents.resize( dedges->size() ); result = mbImpl->tag_get_data( dualEntity_tag(), *dedges, &dual_ents[0] ); if( MB_SUCCESS != result ) return result; Range::iterator rit; unsigned int i; for( rit = dedges->begin(), i = 0; rit != dedges->end(); ++rit, i++ ) if( 0 != dual_ents[i] && mbImpl->type_from_handle( dual_ents[i] ) == MBEDGE ) dedges_loop->insert( *rit ); } return result; }
EntityHandle moab::DualTool::get_dual_entity | ( | const EntityHandle | this_ent | ) | const |
return the corresponding dual entity
Definition at line 1414 of file DualTool.cpp.
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 dual_ent; ErrorCode result = mbImpl->tag_get_data( dualEntity_tag(), &this_ent, 1, &dual_ent ); if( MB_SUCCESS != result || MB_TAG_NOT_FOUND == result ) return 0; else return dual_ent; }
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.
References dualCurve_tag(), dualSurface_tag(), ErrorCode, moab::Interface::get_adjacencies(), MB_SUCCESS, MB_TAG_NOT_FOUND, mbImpl, and moab::Interface::tag_get_data().
Referenced by face_shrink(), foc_delete_dual(), fs_get_quads(), rev_face_shrink(), and traverse_hyperplane().
{ // get the sheet or chord it's in std::vector< EntityHandle > adj_sets; ErrorCode result = mbImpl->get_adjacencies( &ncell, 1, 4, false, adj_sets ); if( MB_SUCCESS != result ) return 0; EntityHandle dum_set; for( std::vector< EntityHandle >::iterator vit = adj_sets.begin(); vit != adj_sets.end(); ++vit ) { if( mbImpl->tag_get_data( dualCurve_tag(), &( *vit ), 1, &dum_set ) != MB_TAG_NOT_FOUND || mbImpl->tag_get_data( dualSurface_tag(), &( *vit ), 1, &dum_set ) != MB_TAG_NOT_FOUND ) return *vit; } return 0; }
ErrorCode moab::DualTool::get_dual_hyperplanes | ( | const Interface * | impl, |
const int | dim, | ||
Range & | dual_ents | ||
) | [static] |
get the d-dimensional hyperplane sets; static 'cuz it's easy to do without an active dualtool
Definition at line 807 of file DualTool.cpp.
References 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().
{ if( dim != 1 && dim != 2 ) return MB_INDEX_OUT_OF_RANGE; Tag dual_tag; ErrorCode result; if( dim == 1 ) result = impl->tag_get_handle( DUAL_CURVE_TAG_NAME, 1, MB_TYPE_HANDLE, dual_tag ); else result = impl->tag_get_handle( DUAL_SURFACE_TAG_NAME, 1, MB_TYPE_HANDLE, dual_tag ); if( MB_SUCCESS == result ) result = impl->get_entities_by_type_and_tag( 0, MBENTITYSET, &dual_tag, NULL, 1, dual_ents, Interface::UNION ); return result; }
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.
References ErrorCode, extraDualEntity_tag(), MB_SUCCESS, MB_TAG_NOT_FOUND, mbImpl, and moab::Interface::tag_get_data().
Referenced by delete_dual_entities().
{ EntityHandle dual_ent; ErrorCode result = mbImpl->tag_get_data( extraDualEntity_tag(), &this_ent, 1, &dual_ent ); if( MB_SUCCESS != result || MB_TAG_NOT_FOUND == result ) return 0; else return dual_ent; }
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.
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().
{ // shouldn't be a set assert( MBENTITYSET != mbImpl->type_from_handle( dual_ent ) ); // get the graphics points comprising the given entity GraphicsPoint gp_array[DualTool::GP_SIZE]; ErrorCode result = MB_SUCCESS; // switch based on topological dimension switch( mbImpl->dimension_from_handle( dual_ent ) ) { case 0: // just return the vertex point result = mbImpl->tag_get_data( dualGraphicsPoint_tag(), &dual_ent, 1, gp_array ); if( MB_SUCCESS == result ) points.push_back( gp_array[0] ); break; case 1: // get my graphics point then those of my vertices const EntityHandle* connect; int num_connect; result = mbImpl->get_connectivity( dual_ent, connect, num_connect ); if( MB_SUCCESS != result ) break; result = mbImpl->tag_get_data( dualGraphicsPoint_tag(), connect, 2, gp_array ); if( MB_SUCCESS == result ) { points.push_back( gp_array[0] ); points.push_back( gp_array[0] ); points.push_back( gp_array[1] ); result = mbImpl->tag_get_data( dualGraphicsPoint_tag(), &dual_ent, 1, gp_array ); if( MB_SUCCESS == result ) points[1] = gp_array[0]; } npts.push_back( 3 ); break; case 2: result = get_cell_points( dual_ent, npts, points ); break; } return result; }
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.
References moab::Range::begin(), moab::Range::clear(), dualGraphicsPoint_tag(), dualGraphicsPointTag, moab::Range::end(), ErrorCode, moab::Interface::get_adjacencies(), moab::Interface::get_entities_by_handle(), 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.
{ // return graphics points on dual entities in in_range or in entities // in sets in in_range ErrorCode result; // for each dual hyperplane set: Range::const_iterator rit; Range two_cells, all_cells; for( rit = in_range.begin(); rit != in_range.end(); ++rit ) { // for each entity: two_cells.clear(); EntityType this_type = mbImpl->type_from_handle( *rit ); if( MBENTITYSET == this_type ) { result = mbImpl->get_entities_by_handle( *rit, two_cells );RR; std::copy( two_cells.begin(), two_cells.end(), range_inserter( all_cells ) ); } else { two_cells.insert( *rit ); assert( this_type == MBVERTEX || this_type == MBEDGE || this_type == MBPOLYGON || this_type == MBPOLYHEDRON ); } result = mbImpl->get_adjacencies( two_cells, 0, false, all_cells, Interface::UNION );RR; result = mbImpl->get_adjacencies( two_cells, 1, false, all_cells, Interface::UNION );RR; } // get graphics points points.resize( all_cells.size() ); result = mbImpl->tag_get_data( dualGraphicsPointTag, all_cells, &points[0] );RR; if( assign_ids ) { int i = start_id; for( std::vector< GraphicsPoint >::iterator vit = points.begin(); vit != points.end(); ++vit ) vit->id = i++; result = mbImpl->tag_set_data( dualGraphicsPoint_tag(), all_cells, &points[0] );RR; } return result; }
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.
References moab::Range::begin(), moab::Range::clear(), moab::MeshTopoUtil::common_entity(), ErrorCode, moab::Interface::get_connectivity(), moab::Interface::get_entities_by_handle(), is_blind(), MB_SUCCESS, mbImpl, RR, moab::Range::size(), and moab::subtract().
{ // get the edges on the chord, in order, and move to middle_edge std::vector< EntityHandle > chord_edges; const EntityHandle* connect; int num_connect; ErrorCode result = mbImpl->get_entities_by_handle( chord, chord_edges );RR; std::vector< EntityHandle >::iterator vit = std::find( chord_edges.begin(), chord_edges.end(), middle_edge ); result = mbImpl->get_connectivity( middle_edge, connect, num_connect );RR; if( // middle_edge isn't on this chord vit == chord_edges.end() || // chord only has 1 edge chord_edges.size() == 1 || // middle_edge is at beginning or end and chord isn't blind ( ( vit == chord_edges.begin() || vit == chord_edges.end() - 1 ) && !is_blind( chord ) ) ) return MB_FAILURE; else if( chord_edges.size() == 2 ) { // easier if it's a 2-edge blind chord, just get vertices in opposite order verts[0] = connect[1]; verts[1] = connect[0]; return MB_SUCCESS; } // get vertices with the prev edge & subtract vertices of 1-cell if( vit == chord_edges.begin() ) vit = chord_edges.end() - 1; else --vit; Range dum_connect, middle_connect; result = mbImpl->get_connectivity( &middle_edge, 1, middle_connect );RR; result = mbImpl->get_connectivity( &( *vit ), 1, dum_connect );RR; dum_connect = subtract( dum_connect, middle_connect ); if( dum_connect.size() != 1 ) { std::cerr << "Trouble traversing chord." << std::endl; return MB_FAILURE; } // put in verts[0] verts[0] = *dum_connect.begin(); // same with prev edge ++vit; if( vit == chord_edges.end() ) vit = chord_edges.begin(); ++vit; dum_connect.clear(); result = mbImpl->get_connectivity( &( *vit ), 1, dum_connect );RR; dum_connect = subtract( dum_connect, middle_connect ); if( dum_connect.size() != 1 ) { std::cerr << "Trouble traversing chord." << std::endl; return MB_FAILURE; } // put in verts[1] verts[1] = *dum_connect.begin(); // if verts[0] and 1st vertex of 1cell don't have common edge, switch verts MeshTopoUtil mtu( mbImpl ); if( 0 == mtu.common_entity( verts[0], connect[0], 1 ) ) { EntityHandle dum_h = verts[0]; verts[0] = verts[1]; verts[1] = dum_h; } if( 0 == mtu.common_entity( verts[0], connect[0], 1 ) ) { std::cerr << "Trouble traversing chord." << std::endl; return MB_FAILURE; } return MB_SUCCESS; }
ErrorCode moab::DualTool::get_radial_dverts | ( | const EntityHandle | edge, |
std::vector< EntityHandle > & | rad_dverts, | ||
bool & | bdy_edge | ||
) | [private] |
given an edge handle, return a list of dual vertices in radial order around the edge; also returns whether this edge is on the boundary
given an edge handle, return a list of dual vertices in radial order around the edge
Definition at line 663 of file DualTool.cpp.
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().
{ rad_dverts.clear(); std::vector< EntityHandle > rad_faces, rad_ents; ErrorCode result = MeshTopoUtil( mbImpl ).star_entities( edge, rad_faces, bdy_edge, 0, &rad_ents ); if( MB_SUCCESS != result ) return result; if( bdy_edge ) { // if we're a bdy edge, change the order back to what DualTool expects rad_ents.push_back( *rad_faces.rbegin() ); rad_ents.push_back( *rad_faces.begin() ); } rad_dverts.resize( rad_ents.size() ); for( unsigned int i = 0; i < rad_ents.size(); i++ ) { EntityHandle dual_ent; result = mbImpl->tag_get_data( dualEntity_tag(), &rad_ents[i], 1, &dual_ent ); if( !bdy_edge || i < rad_ents.size() - 2 ) rad_dverts[i] = dual_ent; else { // fix up this entry assert( mbImpl->type_from_handle( dual_ent ) == MBEDGE ); // get connectivity of that edge const EntityHandle* connect; int num_connect; result = mbImpl->get_connectivity( dual_ent, connect, num_connect ); if( MB_SUCCESS != result ) return result; // we want the one that's not already on the list; reuse last_face int last_hex = ( i == rad_ents.size() - 1 ? 0 : i - 1 ); EntityHandle last_face = ( connect[0] == rad_dverts[last_hex] ? connect[1] : connect[0] ); rad_dverts[i] = last_face; } } return result; }
Tag moab::DualTool::globalId_tag | ( | ) | const [inline] |
get/set the global id tag
Definition at line 420 of file DualTool.hpp.
References globalIdTag.
Referenced by atomic_pillow(), construct_dual(), construct_new_hyperplane(), face_shrink(), list_entities(), and traverse_hyperplane().
{ return globalIdTag; }
ErrorCode moab::DualTool::globalId_tag | ( | const Tag | tag | ) | [inline] |
get/set the tag for dual entities
Definition at line 504 of file DualTool.hpp.
References ErrorCode, globalIdTag, and MB_SUCCESS.
{ ErrorCode result = MB_FAILURE; if( ( 0 == globalIdTag && tag ) || globalIdTag != tag ) { globalIdTag = tag; result = MB_SUCCESS; } return result; }
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.
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().
{ // must be an entity set if( TYPE_FROM_HANDLE( chord_or_sheet ) != MBENTITYSET ) return false; // get the vertices Range verts, ents; ErrorCode result = mbImpl->get_entities_by_handle( chord_or_sheet, ents ); if( MB_SUCCESS != result || ents.empty() ) return false; result = mbImpl->get_adjacencies( ents, 0, false, verts, Interface::UNION ); if( MB_SUCCESS != result || verts.empty() ) return false; for( Range::iterator rit = verts.begin(); rit != verts.end(); ++rit ) { // get dual entity for this vertex EntityHandle dual_ent = get_dual_entity( *rit ); if( 0 == dual_ent ) continue; if( TYPE_FROM_HANDLE( dual_ent ) == MBQUAD ) return false; } // if none of the vertices' duals were quads, chord_or_sheet must be blind return true; }
Tag moab::DualTool::isDualCell_tag | ( | ) | const [inline] |
get/set the tag for dual cells
Definition at line 400 of file DualTool.hpp.
References isDualCellTag.
Referenced by check_1d_loop_edge(), construct_dual_cells(), construct_dual_edges(), construct_dual_faces(), construct_dual_vertex(), and get_dual_entities().
{ return isDualCellTag; }
ErrorCode moab::DualTool::isDualCell_tag | ( | const Tag | tag | ) | [inline] |
get/set the tag for dual cells
Definition at line 452 of file DualTool.hpp.
References ErrorCode, isDualCellTag, and MB_SUCCESS.
{ ErrorCode result = MB_FAILURE; if( ( 0 == isDualCellTag && tag ) || isDualCellTag != tag ) { isDualCellTag = tag; result = MB_SUCCESS; } return result; }
ErrorCode moab::DualTool::list_entities | ( | const Range & | entities | ) | const |
Definition at line 2591 of file DualTool.cpp.
References moab::Range::begin(), dualCurve_tag(), dualSurface_tag(), moab::Range::end(), moab::CN::EntityTypeName(), ErrorCode, get_dual_entity(), globalId_tag(), moab::ID_FROM_HANDLE(), moab::Interface::id_from_handle(), moab::Interface::list_entity(), MB_SUCCESS, MBENTITYSET, mbImpl, moab::Interface::tag_get_data(), moab::TYPE_FROM_HANDLE(), and moab::Interface::type_from_handle().
Referenced by list_entities().
{ // now print each entity, listing the dual information first then calling Interface to do // the rest ErrorCode result = MB_SUCCESS, tmp_result; for( Range::const_iterator iter = entities.begin(); iter != entities.end(); ++iter ) { EntityType this_type = TYPE_FROM_HANDLE( *iter ); std::cout << CN::EntityTypeName( this_type ) << " " << ID_FROM_HANDLE( *iter ) << ":" << std::endl; EntityHandle dual_ent = get_dual_entity( *iter ); if( 0 != dual_ent ) { std::cout << "Dual to " << CN::EntityTypeName( mbImpl->type_from_handle( dual_ent ) ) << " " << mbImpl->id_from_handle( dual_ent ) << std::endl; } if( TYPE_FROM_HANDLE( *iter ) == MBENTITYSET ) { EntityHandle chord = 0, sheet = 0; int id; result = mbImpl->tag_get_data( dualCurve_tag(), &( *iter ), 1, &chord ); if( MB_SUCCESS != result ) return result; result = mbImpl->tag_get_data( dualSurface_tag(), &( *iter ), 1, &sheet ); if( MB_SUCCESS != result ) return result; result = mbImpl->tag_get_data( globalId_tag(), &( *iter ), 1, &id ); if( MB_SUCCESS != result ) return result; if( 0 != chord ) std::cout << "(Dual chord " << id << ")" << std::endl; if( 0 != sheet ) std::cout << "(Dual sheet " << id << ")" << std::endl; } tmp_result = mbImpl->list_entity( *iter ); if( MB_SUCCESS != tmp_result ) result = tmp_result; } return result; }
ErrorCode moab::DualTool::list_entities | ( | const EntityHandle * | entities, |
const int | num_entities | ||
) | const |
Definition at line 2564 of file DualTool.cpp.
References ErrorCode, moab::Interface::get_entities_by_type(), list_entities(), moab::Interface::list_entities(), MB_SUCCESS, mbImpl, MBMAXTYPE, and MBVERTEX.
{ Range temp_range; ErrorCode result; if( NULL == entities && 0 == num_entities ) return mbImpl->list_entities( entities, num_entities ); else if( NULL == entities && 0 < num_entities ) { // list all entities of all types std::cout << std::endl; for( EntityType this_type = MBVERTEX; this_type < MBMAXTYPE; this_type++ ) { result = mbImpl->get_entities_by_type( 0, this_type, temp_range ); if( MB_SUCCESS != result ) return result; } } else { std::copy( entities, entities + num_entities, range_inserter( temp_range ) ); } return list_entities( temp_range ); }
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.
References moab::Range::begin(), moab::Range::clear(), moab::Range::empty(), moab::Range::erase(), ErrorCode, moab::Interface::get_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().
{ // given two vertices, find the next one on the loop; if one is a dual // surface, then just choose either one for that surface assert( ( 0 == last_v || mbImpl->type_from_handle( last_v ) == MBVERTEX ) && mbImpl->type_from_handle( this_v ) == MBVERTEX && mbImpl->type_from_handle( dual_surf ) == MBENTITYSET ); // get the connected vertices MeshTopoUtil tpu( mbImpl ); Range other_verts; ErrorCode result = tpu.get_bridge_adjacencies( this_v, 1, 0, other_verts ); if( MB_SUCCESS != result || other_verts.empty() ) return 0; // if (mbImpl->type_from_handle(last_v) == MBENTITYSET) { // dual surface, choose either; first get a 2cell on this surface Range tcells, tcells2, verts; result = mbImpl->get_entities_by_type( dual_surf, MBPOLYGON, tcells ); if( MB_SUCCESS != result || tcells.empty() ) return 0; // ok, pay attention here: first get 2cells common to dual surface and this_v verts.insert( this_v ); result = mbImpl->get_adjacencies( verts, 2, false, tcells ); if( MB_SUCCESS != result || tcells.empty() ) return 0; // next get vertices common to both 2cells and subtract from other_verts; also // remove last_v if it's non-zero verts.clear(); result = mbImpl->get_adjacencies( tcells, 0, false, verts ); if( MB_SUCCESS != result || verts.empty() ) return 0; Range tmp_verts = subtract( other_verts, verts ); other_verts.swap( tmp_verts ); if( 0 != last_v ) other_verts.erase( last_v ); // now get intersection of remaining vertices and 2 2cells vertices // look at each one successively; should find one, maybe not on both tmp_verts = other_verts; Range tmp_faces( *tcells.begin(), *tcells.begin() ); result = mbImpl->get_adjacencies( tmp_faces, 0, false, tmp_verts ); if( MB_SUCCESS == result && !tmp_verts.empty() ) return *tmp_verts.begin(); tmp_faces.clear(); tmp_faces.insert( *tcells.rbegin() ); result = mbImpl->get_adjacencies( tmp_faces, 0, false, other_verts ); if( MB_SUCCESS == result && !other_verts.empty() ) return *other_verts.begin(); // if we got here, there isn't any return 0; }
ErrorCode moab::DualTool::order_chord | ( | EntityHandle | chord_set | ) | [private] |
order 1cells on a chord
Definition at line 1022 of file DualTool.cpp.
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().
{ // re-order the 1cells in the set so they are in order along the chord // start by finding the vertex dual to a quad Range verts, one_cells; ErrorCode result = mbImpl->get_entities_by_dimension( chord_set, 1, one_cells ); if( MB_SUCCESS != result || one_cells.empty() ) return MB_FAILURE; result = mbImpl->get_adjacencies( one_cells, 0, false, verts, Interface::UNION ); if( MB_SUCCESS != result || verts.empty() ) return MB_FAILURE; EntityHandle last_vert = 0; for( Range::iterator rit = verts.begin(); rit != verts.end(); ++rit ) { if( TYPE_FROM_HANDLE( get_dual_entity( *rit ) ) == MBQUAD ) { last_vert = *rit; break; } } // if there's no vertex owned by a quad, just start with 1st one if( 0 == last_vert ) last_vert = *verts.begin(); // now, skip from vertex to vertex, building a list of 1cells std::vector< EntityHandle > ordered_1cells; EntityHandle last_1cell = 0; Range dum1, dum2; const EntityHandle* connect; int num_connect; ErrorCode tmp_result = MB_SUCCESS; while( ordered_1cells.size() != one_cells.size() ) { dum1 = one_cells; result = mbImpl->get_adjacencies( &last_vert, 1, 1, false, dum1 ); if( 0 != last_1cell ) dum1.erase( last_1cell ); // assert(1 == dum1.size()); if( 0 != last_1cell && 1 != dum1.size() ) { std::cerr << "unexpected size traversing chord." << std::endl; tmp_result = MB_FAILURE; } last_1cell = *dum1.begin(); ordered_1cells.push_back( last_1cell ); result = mbImpl->get_connectivity( last_1cell, connect, num_connect );RR; if( last_vert == connect[0] ) last_vert = connect[1]; else last_vert = connect[0]; } // now have the 1cells in order, replace them in the set if( MB_SUCCESS == tmp_result ) { result = mbImpl->remove_entities( chord_set, one_cells );RR; result = mbImpl->add_entities( chord_set, &ordered_1cells[0], ordered_1cells.size() );RR; } return MB_SUCCESS; }
void moab::DualTool::print_cell | ( | EntityHandle | cell | ) | [private] |
Definition at line 1691 of file DualTool.cpp.
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().
{ const EntityHandle* connect; int num_connect; ErrorCode result = mbImpl->get_connectivity( cell, connect, num_connect ); if( MB_SUCCESS != result ) return; bool first = true; EntityHandle primals[20]; std::vector< int > ids; assert( num_connect < 20 ); result = mbImpl->tag_get_data( dualEntityTag, connect, num_connect, primals ); if( MB_SUCCESS != result ) return; ids.resize( num_connect ); result = mbImpl->tag_get_data( globalIdTag, primals, num_connect, &ids[0] ); if( MB_SUCCESS != result ) return; for( int i = 0; i < num_connect; i++ ) { if( !first ) std::cout << "-"; EntityType this_type = mbImpl->type_from_handle( primals[i] ); if( this_type == MBHEX ) std::cout << "h"; else if( this_type == MBQUAD ) std::cout << "f"; else std::cout << "u"; if( ids[i] != 0 ) std::cout << ids[i]; else std::cout << mbImpl->id_from_handle( primals[i] ); first = false; } }
ErrorCode moab::DualTool::rev_atomic_pillow | ( | EntityHandle | pillow, |
Range & | chords | ||
) |
effect reverse atomic pillow operation
Definition at line 1563 of file DualTool.cpp.
References moab::Range::begin(), construct_hex_dual(), moab::debug_ap, delete_dual_entities(), dim, dualEntity_tag(), moab::Range::end(), ErrorCode, get_dual_entities(), moab::Range::insert(), MB_SUCCESS, mbImpl, print_cell(), moab::Range::rbegin(), RR, size, moab::Range::size(), moab::subtract(), and moab::Interface::UNION.
{ // get the dual entities associated with elements in the pillow; go through // the elements instead of the pillow sheet so you get all of them, not just // the ones on the sheet if( debug_ap ) ( (Core*)mbImpl )->check_adjacencies(); std::cout << "-AP("; print_cell( pillow ); std::cout << ")" << std::endl; Range dverts; ErrorCode result = get_dual_entities( pillow, NULL, NULL, &dverts, NULL, NULL ); if( MB_SUCCESS != result ) return result; assert( 2 == dverts.size() ); EntityHandle hexes[2]; result = mbImpl->tag_get_data( dualEntity_tag(), dverts, hexes );RR; assert( hexes[0] != 0 && hexes[1] != 0 ); std::vector< EntityHandle > dcells[4]; Range pcells[4]; std::copy( hexes, hexes + 2, range_inserter( pcells[3] ) ); std::copy( dverts.begin(), dverts.end(), std::back_inserter( dcells[0] ) ); for( int dim = 0; dim <= 2; dim++ ) { result = mbImpl->get_adjacencies( hexes, 2, dim, false, pcells[dim], Interface::UNION );RR; dcells[3 - dim].resize( pcells[dim].size() ); result = mbImpl->tag_get_data( dualEntity_tag(), pcells[dim], &dcells[3 - dim][0] );RR; } // delete the dual entities which are part of the original pillow result = mbImpl->delete_entities( &pillow, 1 ); if( MB_SUCCESS != result ) return result; result = mbImpl->delete_entities( chords ); if( MB_SUCCESS != result ) return result; for( int i = 3; i >= 0; i-- ) { result = delete_dual_entities( &dcells[i][0], dcells[i].size() );RR; } // delete the primal entities inserted by the ap; be careful to get the right // faces, edges and vertices Range del_faces, del_edges, del_verts, tmp_faces, tmp_verts; // faces are the shared 5 and the 1 other one with greater handle (which // we know will be later in the range) result = mbImpl->get_adjacencies( hexes, 2, 2, false, del_faces );RR; assert( 5 == del_faces.size() ); std::copy( pcells[2].begin(), pcells[2].end(), range_inserter( tmp_faces ) ); tmp_faces = subtract( tmp_faces, del_faces ); del_faces.insert( *tmp_faces.rbegin() ); result = mbImpl->get_adjacencies( tmp_faces, 0, false, tmp_verts );RR; std::copy( pcells[0].begin(), pcells[0].end(), range_inserter( del_verts ) ); del_verts = subtract( del_verts, tmp_verts ); assert( 4 == del_verts.size() ); result = mbImpl->get_adjacencies( del_verts, 1, false, del_edges, Interface::UNION );RR; assert( 8 == del_edges.size() ); result = mbImpl->delete_entities( hexes, 2 );RR; result = mbImpl->delete_entities( del_faces );RR; result = mbImpl->delete_entities( del_edges );RR; result = mbImpl->delete_entities( del_verts );RR; if( debug_ap ) ( (Core*)mbImpl )->check_adjacencies(); // recompute the dual for the hexes on either side of the quad affected // by the ap removal Range tmp_hexes; result = mbImpl->get_adjacencies( tmp_verts, 3, false, tmp_hexes, Interface::UNION );RR; result = construct_hex_dual( tmp_hexes );RR; return MB_SUCCESS; }
effect reverse atomic pillow operation
effect reverse face shrink operation
Definition at line 2931 of file DualTool.cpp.
References moab::Range::begin(), construct_hex_dual(), moab::debug_ap, delete_dual_entities(), dim, 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(), get_dual_entity(), get_dual_hyperplane(), moab::Range::insert(), MB_MULTIPLE_ENTITIES_FOUND, MB_SUCCESS, MB_TYPE_OUT_OF_RANGE, MBEDGE, mbImpl, MBQUAD, print_cell(), RR, and moab::Interface::UNION.
{ if( debug_ap ) ( (Core*)mbImpl )->check_adjacencies(); // some preliminary checking if( mbImpl->type_from_handle( odedge ) != MBEDGE ) return MB_TYPE_OUT_OF_RANGE; std::cout << "-FS("; print_cell( odedge ); std::cout << ")" << std::endl; EntityHandle quads[4], hexes[2]; std::vector< EntityHandle > connects[4], side_quads[2]; // get three quads (shared quad & 2 end quads), hexes, and quad // connects ErrorCode result = fs_get_quads( odedge, quads, hexes, connects ); if( MB_SUCCESS != result ) return result; // adjust sense & rotation so they're aligned, together & wrt first // hex result = fs_check_quad_sense( hexes[0], quads[0], connects ); if( MB_SUCCESS != result ) return result; result = fsr_get_fourth_quad( connects, side_quads ); if( MB_SUCCESS != result ) { std::cout << "Can't do -FS here, two hexes must be adjacent to ring of 4 hexes." << std::endl; return result; } Range adj_ents, outer_hexes, all_adjs; // first get the entities connected to interior 4 verts for( int i = 1; i <= 3; i++ ) { result = mbImpl->get_adjacencies( &connects[1][0], 4, i, false, adj_ents, Interface::UNION ); if( MB_SUCCESS != result ) return result; } // next get all entities adjacent to those; these will have their dual // entities deleted for( int i = 0; i < 3; i++ ) { result = mbImpl->get_adjacencies( adj_ents, i, false, all_adjs, Interface::UNION ); if( MB_SUCCESS != result ) return result; } // get the dual entities and delete them Range dual_ents, dual_hps; for( Range::iterator rit = all_adjs.begin(); rit != all_adjs.end(); ++rit ) { EntityHandle this_ent = get_dual_entity( *rit ); dual_ents.insert( this_ent ); } // before deleting dual, grab the 1- and 2-cells for( Range::iterator rit = dual_ents.begin(); rit != dual_ents.end(); ++rit ) { int dim = mbImpl->dimension_from_handle( *rit ); if( 1 == dim || 2 == dim ) dual_hps.insert( get_dual_hyperplane( *rit ) ); } result = delete_dual_entities( dual_ents ); if( MB_SUCCESS != result ) return result; // after deleting cells, check for empty chords & sheets, and delete those too for( Range::iterator rit = dual_hps.begin(); rit != dual_hps.end(); ++rit ) { Range tmp_ents; result = mbImpl->get_entities_by_handle( *rit, tmp_ents ); if( MB_SUCCESS != result ) return result; if( tmp_ents.empty() ) { result = mbImpl->delete_entities( &( *rit ), 1 ); if( MB_SUCCESS != result ) return result; } } // before re-connecting two hexes, check for existing quad on 4th quad vertices; // if there is a quad there, need to add explicit adjs to any adj hexes, since // by definition there'll be another quad on those vertices bool need_explicit = false; Range adj_quads; result = mbImpl->get_adjacencies( &connects[3][0], 4, 2, false, adj_quads ); if( MB_MULTIPLE_ENTITIES_FOUND == result || !adj_quads.empty() ) { // there's already a quad for these 4 vertices; by definition, // we'll be creating equivalent entities, so that original quad // needs explicit adj's to its bounding elements need_explicit = true; for( Range::iterator rit = adj_quads.begin(); rit != adj_quads.end(); ++rit ) { Range adj_hexes; result = mbImpl->get_adjacencies( &( *rit ), 1, 3, false, adj_hexes );RR; result = mbImpl->add_adjacencies( *rit, adj_hexes, false );RR; } } // re-connect the two hexes std::vector< EntityHandle > new_connect; std::copy( connects[3].begin(), connects[3].end(), std::back_inserter( new_connect ) ); std::copy( connects[2].begin(), connects[2].end(), std::back_inserter( new_connect ) ); result = mbImpl->set_connectivity( hexes[0], &new_connect[0], 8 ); if( MB_SUCCESS != result ) return result; new_connect.clear(); std::copy( connects[0].begin(), connects[0].end(), std::back_inserter( new_connect ) ); std::copy( connects[3].begin(), connects[3].end(), std::back_inserter( new_connect ) ); result = mbImpl->set_connectivity( hexes[1], &new_connect[0], 8 ); if( MB_SUCCESS != result ) return result; // test for equiv entities from the side quads, and make explicit // adjacencies if there are any MeshTopoUtil mtu( mbImpl ); for( int j = 0; j < 2; j++ ) { for( int i = 0; i < 4; i++ ) { if( mtu.equivalent_entities( side_quads[j][i] ) ) { result = mbImpl->add_adjacencies( side_quads[j][i], &hexes[j], 1, false ); if( MB_SUCCESS != result ) return result; } } } // remove hexes we want to keep adj_ents.erase( hexes[0] ); adj_ents.erase( hexes[1] ); // delete the other interior entities result = mbImpl->delete_entities( adj_ents ); if( MB_SUCCESS != result ) return result; EntityHandle new_quad; result = mbImpl->create_element( MBQUAD, &connects[3][0], 4, new_quad );RR; if( need_explicit ) { result = mbImpl->add_adjacencies( new_quad, hexes, 2, false );RR; } if( debug_ap ) ( (Core*)mbImpl )->check_adjacencies(); // now update the dual result = construct_hex_dual( hexes, 2 ); if( MB_SUCCESS != result ) return result; return MB_SUCCESS; }
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.
References dualCurve_tag(), dualSurface_tag(), MB_INDEX_OUT_OF_RANGE, MB_SUCCESS, mbImpl, and moab::Interface::tag_set_data().
{ if( 1 == dual_entity_dimension ) mbImpl->tag_set_data( dualCurve_tag(), &entity, 1, &dual_hyperplane ); else if( 2 == dual_entity_dimension ) mbImpl->tag_set_data( dualSurface_tag(), &entity, 1, &dual_hyperplane ); else return MB_INDEX_OUT_OF_RANGE; return MB_SUCCESS; }
ErrorCode moab::DualTool::split_pair_nonmanifold | ( | EntityHandle * | split_quads, |
EntityHandle * | split_edges, | ||
EntityHandle * | split_nodes, | ||
std::vector< EntityHandle > * | star_dp1, | ||
std::vector< EntityHandle > * | star_dp2, | ||
EntityHandle * | other_edges, | ||
EntityHandle * | other_nodes, | ||
EntityHandle * | new_quads, | ||
EntityHandle * | new_edges, | ||
EntityHandle * | new_nodes | ||
) | [private] |
split a pair of quads and the edge(s) shared by them
Definition at line 1949 of file DualTool.cpp.
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().
{ // if there's a bdy in the star around the shared edge(s), get the quads on that // bdy so we know which edges to merge after the split-nonmanifold MeshTopoUtil mtu( mbImpl ); ErrorCode result; // get which star the split faces are in, and choose the other one int new_side = -1; if( std::find( star_dp1[0].begin(), star_dp1[0].end(), split_quads[0] ) != star_dp1[0].end() ) new_side = 1; else if( std::find( star_dp1[1].begin(), star_dp1[1].end(), split_quads[0] ) != star_dp1[1].end() ) new_side = 0; assert( -1 != new_side ); if( -1 == new_side ) return MB_FAILURE; //=============== split faces for( int i = 0; i < 2; i++ ) { // get a hex in star_dp2[new_side] that's adj to this split quad, to tell // mtu which one the new quad should go with; there should be at least one, // if we have any hexes connected to the split quad EntityHandle gowith_hex = 0; for( std::vector< EntityHandle >::iterator vit = star_dp2[new_side].begin(); vit != star_dp2[new_side].end(); ++vit ) { if( mtu.common_entity( *vit, split_quads[i], 2 ) ) { gowith_hex = *vit; break; } } assert( 0 != gowith_hex ); // split manifold each of the split_quads, and put the results on the merge list result = mtu.split_entities_manifold( split_quads + i, 1, new_quads + i, NULL, ( gowith_hex ? &gowith_hex : NULL ) );RR; } // make ranges of faces which need to be explicitly adj to old, new // edge; faces come from stars and new_quads (which weren't in the stars); // new_quads go with side j, which does not have split quads Range tmp_addl_faces[2], addl_faces[2]; for( int i = 0; i < 2; i++ ) { std::copy( star_dp1[i].begin(), star_dp1[i].end(), range_inserter( tmp_addl_faces[i] ) ); tmp_addl_faces[new_side].insert( new_quads[i] ); } #ifndef NDEBUG bool cond1 = ( "split_quads on 1, new_quads on 0" && tmp_addl_faces[0].find( split_quads[0] ) == tmp_addl_faces[0].end() && tmp_addl_faces[0].find( split_quads[1] ) == tmp_addl_faces[0].end() && tmp_addl_faces[1].find( split_quads[0] ) != tmp_addl_faces[1].end() && tmp_addl_faces[1].find( split_quads[1] ) != tmp_addl_faces[1].end() && tmp_addl_faces[0].find( new_quads[0] ) != tmp_addl_faces[0].end() && tmp_addl_faces[0].find( new_quads[1] ) != tmp_addl_faces[0].end() && tmp_addl_faces[1].find( new_quads[0] ) == tmp_addl_faces[1].end() && tmp_addl_faces[1].find( new_quads[1] ) == tmp_addl_faces[1].end() ), cond2 = ( "split_quads on 0, new_quads on 1" && tmp_addl_faces[0].find( split_quads[0] ) != tmp_addl_faces[0].end() && tmp_addl_faces[0].find( split_quads[1] ) != tmp_addl_faces[0].end() && tmp_addl_faces[1].find( split_quads[0] ) == tmp_addl_faces[1].end() && tmp_addl_faces[1].find( split_quads[1] ) == tmp_addl_faces[1].end() && tmp_addl_faces[0].find( new_quads[0] ) == tmp_addl_faces[0].end() && tmp_addl_faces[0].find( new_quads[1] ) == tmp_addl_faces[0].end() && tmp_addl_faces[1].find( new_quads[0] ) != tmp_addl_faces[1].end() && tmp_addl_faces[1].find( new_quads[1] ) != tmp_addl_faces[1].end() ); assert( cond1 || cond2 ); #endif //=============== split edge(s) for( int j = 0; j < 3; j++ ) { if( !split_edges[j] ) break; // filter add'l faces to only those adj to split_edges[j] addl_faces[0] = tmp_addl_faces[0]; addl_faces[1] = tmp_addl_faces[1]; for( int i = 0; i < 2; i++ ) { result = mbImpl->get_adjacencies( &split_edges[j], 1, 2, false, addl_faces[i] );RR; } // split edge result = mtu.split_entity_nonmanifold( split_edges[j], addl_faces[1 - new_side], addl_faces[new_side], new_edges[j] );RR; } //=============== split node(s) for( int j = 0; j < 2; j++ ) { if( !split_nodes[j] ) break; // if we're splitting multiple edges, there might be other edges that have the split // node; also need to know which side they're on Range tmp_addl_edges[2]; result = foc_get_addl_ents( star_dp1, star_dp2, split_edges, split_nodes[j], tmp_addl_edges );RR; // also, we need to know which of the split/new edges go // with the split/new node; new edges go with side 0, split with 1 for( int i = 0; i < 3; i++ ) { if( !split_edges[i] ) break; tmp_addl_edges[new_side].insert( new_edges[i] ); tmp_addl_edges[1 - new_side].insert( split_edges[i] ); } // same for star faces and hexes for( int i = 0; i < 2; i++ ) { std::copy( star_dp1[i].begin(), star_dp1[i].end(), range_inserter( tmp_addl_edges[i] ) ); std::copy( star_dp2[i].begin(), star_dp2[i].end(), range_inserter( tmp_addl_edges[i] ) ); } // finally, new quads for( int i = 0; i < 2; i++ ) tmp_addl_edges[new_side].insert( new_quads[i] ); // filter the entities, keeping only the ones adjacent to this node Range addl_edges[2]; for( int i = 0; i < 2; i++ ) { for( Range::reverse_iterator rit = tmp_addl_edges[i].rbegin(); rit != tmp_addl_edges[i].rend(); ++rit ) { if( mtu.common_entity( *rit, split_nodes[j], 0 ) ) addl_edges[i].insert( *rit ); } } // now split the node too result = mtu.split_entity_nonmanifold( split_nodes[j], addl_edges[1 - new_side], addl_edges[new_side], new_nodes[j] );RR; } return MB_SUCCESS; }
ErrorCode moab::DualTool::traverse_hyperplane | ( | const Tag | hp_tag, |
EntityHandle & | this_hp, | ||
EntityHandle | this_ent | ||
) | [private] |
traverse the cells of a dual hyperplane, starting with this_ent (dimension of this_ent determines hyperplane dimension) simpler method for traversing hyperplane, using same basic algorithm but using MeshTopoUtil::get_bridge_adjacencies
Definition at line 893 of file DualTool.cpp.
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().
{ Range tmp_star, star, tmp_range, new_hyperplane_ents; std::vector< EntityHandle > hp_untreated; int dim = mbImpl->dimension_from_handle( this_ent ); MeshTopoUtil mtu( mbImpl ); this_hp = 0; ErrorCode result; unsigned short mark_val = 0x0; Tag mark_tag; result = mbImpl->tag_get_handle( "__hyperplane_mark", 1, MB_TYPE_BIT, mark_tag, MB_TAG_CREAT | MB_TAG_BIT ); if( MB_SUCCESS != result ) return result; mark_val = 0x1; while( 0 != this_ent ) { EntityHandle tmp_hp = get_dual_hyperplane( this_ent ); if( 0 == this_hp && 0 != tmp_hp ) this_hp = tmp_hp; if( 0 == tmp_hp ) new_hyperplane_ents.insert( this_ent ); if( debug && hp_untreated.size() % 10 == 0 ) std::cout << "Dual surface " << this_hp << ", hp_untreated list size = " << hp_untreated.size() << "." << std::endl; // get the 2nd order adjacencies through lower dimension tmp_range.clear(); tmp_star.clear(); star.clear(); result = mtu.get_bridge_adjacencies( this_ent, dim - 1, dim, star );RR; // get the bridge adjacencies through higher dimension result = mtu.get_bridge_adjacencies( this_ent, dim + 1, dim, tmp_star );RR; tmp_range = subtract( star, tmp_star ); for( Range::iterator rit = tmp_range.begin(); rit != tmp_range.end(); ++rit ) { if( new_hyperplane_ents.find( *rit ) != new_hyperplane_ents.end() ) continue; // check for tag first, 'cuz it's probably faster than checking adjacencies // assign to avoid valgrind warning unsigned short tmp_mark = 0x0; result = mbImpl->tag_get_data( mark_tag, &( *rit ), 1, &tmp_mark ); if( MB_SUCCESS == result && mark_val == tmp_mark ) continue; // if it's on the loop, it's not eligible if( 1 == dim && check_1d_loop_edge( *rit ) ) continue; // have one on this hp; just put it on the hp_untreated list for now, // will get tagged and put in the hp set later hp_untreated.push_back( *rit ); result = mbImpl->tag_set_data( mark_tag, &( *rit ), 1, &mark_val ); if( MB_SUCCESS != result ) return result; } // end of inner loop; get the next this_ent, or set to zero if( hp_untreated.empty() ) this_ent = 0; else { this_ent = hp_untreated.back(); hp_untreated.pop_back(); } } if( debug_ap ) { std::string hp_name; if( 2 == dim ) hp_name = "sheet"; else hp_name = "chord"; if( 0 == this_hp ) std::cout << "Constructed new " << hp_name << " with "; else { int this_id; result = mbImpl->tag_get_data( globalId_tag(), &this_hp, 1, &this_id );RR; std::cout << "Added to " << hp_name << " " << this_id << " "; } if( dim == 2 ) std::cout << "edges:" << std::endl; else std::cout << "quads:" << std::endl; std::vector< EntityHandle > pents( new_hyperplane_ents.size() ); result = mbImpl->tag_get_data( dualEntity_tag(), new_hyperplane_ents, &pents[0] );RR; for( std::vector< EntityHandle >::iterator vit = pents.begin(); vit != pents.end(); ++vit ) { if( vit != pents.begin() ) std::cout << ", "; std::cout << mbImpl->id_from_handle( *vit ); } std::cout << std::endl; } if( 0 == this_hp ) { // ok, doesn't have one; make a new hyperplane int new_id = -1; result = construct_new_hyperplane( dim, this_hp, new_id ); if( MB_SUCCESS != result ) return result; if( debug_ap ) { std::cout << "New "; if( 2 == dim ) std::cout << " sheet "; else std::cout << " chord "; std::cout << new_id << " constructed." << std::endl; } } // set the hp_val for entities which didn't have one before std::vector< EntityHandle > hp_tags( new_hyperplane_ents.size() ); std::fill( hp_tags.begin(), hp_tags.end(), this_hp ); result = mbImpl->tag_set_data( hp_tag, new_hyperplane_ents, &hp_tags[0] ); if( MB_SUCCESS != result ) return result; result = mbImpl->add_entities( this_hp, new_hyperplane_ents ); if( MB_SUCCESS != result ) return result; // unmark the entities by removing the tag result = mbImpl->tag_delete( mark_tag ); if( MB_SUCCESS != result ) return result; return MB_SUCCESS; }
Tag moab::DualTool::categoryTag [private] |
Definition at line 384 of file DualTool.hpp.
Referenced by construct_new_hyperplane(), and DualTool().
const char * moab::DualTool::DUAL_CURVE_TAG_NAME = "DUAL_CURVE" [static] |
tag name for dual curves
Definition at line 40 of file DualTool.hpp.
Referenced by DualTool(), get_dual_hyperplanes(), and main().
const char * moab::DualTool::DUAL_ENTITY_TAG_NAME = "__DUAL_ENTITY" [static] |
tag name for dual entitys
tag name for dual entities
Definition at line 46 of file DualTool.hpp.
Referenced by DualTool().
const char * moab::DualTool::DUAL_GRAPHICS_POINT_TAG_NAME = "__DUAL_GRAPHICS_POINT" [static] |
tag name for dual entitys
tag name for graphics point
Definition at line 52 of file DualTool.hpp.
Referenced by DualTool().
const char * moab::DualTool::DUAL_SURFACE_TAG_NAME = "DUAL_SURFACE" [static] |
tag name for dual surfaces
Definition at line 37 of file DualTool.hpp.
Referenced by DualTool(), get_dual_hyperplanes(), and main().
Tag moab::DualTool::dualCurveTag [private] |
tags used for dual surfaces, curves, cells, entities
Definition at line 378 of file DualTool.hpp.
Referenced by delete_whole_dual(), dualCurve_tag(), and DualTool().
Tag moab::DualTool::dualEntityTag [private] |
Definition at line 381 of file DualTool.hpp.
Referenced by delete_whole_dual(), dualEntity_tag(), DualTool(), and print_cell().
Tag moab::DualTool::dualGraphicsPointTag [private] |
Definition at line 383 of file DualTool.hpp.
Referenced by delete_whole_dual(), dualGraphicsPoint_tag(), DualTool(), and get_graphics_points().
Tag moab::DualTool::dualSurfaceTag [private] |
Definition at line 379 of file DualTool.hpp.
Referenced by delete_whole_dual(), dualSurface_tag(), and DualTool().
const char * moab::DualTool::EXTRA_DUAL_ENTITY_TAG_NAME = "__EXTRA_DUAL_ENTITY" [static] |
tag name for dual entitys
tag name for extra dual entities
Definition at line 49 of file DualTool.hpp.
Referenced by DualTool().
Tag moab::DualTool::extraDualEntityTag [private] |
Definition at line 382 of file DualTool.hpp.
Referenced by delete_whole_dual(), DualTool(), and extraDualEntity_tag().
Tag moab::DualTool::globalIdTag [private] |
Definition at line 385 of file DualTool.hpp.
Referenced by construct_new_hyperplane(), DualTool(), globalId_tag(), and print_cell().
const char * moab::DualTool::IS_DUAL_CELL_TAG_NAME = "__IS_DUAL_CELL" [static] |
Tag moab::DualTool::isDualCellTag [private] |
Definition at line 380 of file DualTool.hpp.
Referenced by delete_whole_dual(), DualTool(), get_dual_entities(), and isDualCell_tag().
int moab::DualTool::maxHexId [private] |
Definition at line 387 of file DualTool.hpp.
Referenced by atomic_pillow(), construct_dual(), DualTool(), and face_shrink().
Interface* moab::DualTool::mbImpl [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().