![]() |
Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
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) |
get the graphics points for single entity (dual_ent CAN'T be a set); returns multiple facets, each with npts[i] points | |
ErrorCode | get_graphics_points (const Range &in_range, std::vector< GraphicsPoint > &gpoints, const bool assign_ids=false, const int start_id=0) |
get the graphics points for a range of entities or sets (if set, the entities in those sets); optionally reset ids on points | |
EntityHandle | next_loop_vertex (const EntityHandle last_v, const EntityHandle this_v, const EntityHandle dual_surf) |
given a last_v (possibly zero) and this_v, find the next loop vertex on this dual surface | |
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) |
given the two 1-cells involved in the foc, get entities associated with the quads being opened/collapsed; see implementation for more details | |
ErrorCode | get_opposite_verts (const EntityHandle middle_edge, const EntityHandle chord, EntityHandle *verts) |
given a 1-cell and a chord, return the neighboring vertices on the chord, in the same order as the 1-cell's vertices | |
ErrorCode | get_dual_entities (const EntityHandle dual_ent, Range *dcells, Range *dedges, Range *dverts, Range *dverts_loop, Range *dedges_loop) |
given a dual surface or curve, return the 2-cells, 1-cells, 0-cells, and loop 0/1-cells, if requested; any of those range pointers can be NULL, in which case that range isn't returned | |
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) |
get the d-dimensional hyperplane sets; static 'cuz it's easy to do without an active dualtool | |
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) |
traverse dual faces of input dimension, constructing dual hyperplanes of them in sets as it goes | |
ErrorCode | order_chord (EntityHandle chord_set) |
order 1cells on a chord | |
ErrorCode | construct_new_hyperplane (const int dim, EntityHandle &new_hyperplane, int &id) |
make a new dual hyperplane with the specified id; if the id specified is -1, set the new one's id to the max found | |
ErrorCode | traverse_hyperplane (const Tag hp_tag, EntityHandle &this_hp, EntityHandle this_ent) |
traverse the cells of a dual hyperplane, starting with this_ent (dimension of this_ent determines hyperplane dimension) simpler method for traversing hyperplane, using same basic algorithm but using MeshTopoUtil::get_bridge_adjacencies | |
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) |
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 | |
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) |
if this_ent is an edge, is a dual entity, and has quads as its vertices' dual entities, return true, otherwise false | |
ErrorCode | check_dual_equiv_edges (Range &dual_edges) |
go through potential dual equivalent edges (edges whose nodes define multiple edges), and add explicit adjacencies to corrent 2cells | |
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) |
get the three quads for a face shrink, the two hexes, and the connectivity of the three quads | |
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) |
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 | |
ErrorCode | foc_delete_dual (EntityHandle *split_quads, EntityHandle *split_edges, Range &hexes) |
function for deleting dual prior to foc operation; special because in many cases need to delete a sheet in preparation for merging onto another | |
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) |
for foc's splitting two shared edges, there might be additional entities connected to the split node that also have to be updated | |
ErrorCode | foc_get_stars (EntityHandle *split_quads, EntityHandle *split_edges, std::vector< EntityHandle > *star_dp1, std::vector< EntityHandle > *star_dp2) |
given the split quads and edges, get the face and hex stars around the edge(s), separated into halves, each of which goes with the new or old entities after the split | |
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().
{
// 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(), 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(), 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_verts, | ||
bool & | bdy_edge | ||
) | [private] |
given an edge handle, return a list of dual vertices in radial order around the edge; also returns whether this edge is on the boundary
given an edge handle, return a list of dual vertices in radial order around the edge
Definition at line 663 of file DualTool.cpp.
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(), and get_dual_hyperplanes().
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(), and get_dual_hyperplanes().
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().