Mesh Oriented datABase  (version 5.4.1)
Array-based unstructured mesh datastructure
moab::DualTool Class Reference

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

#include <DualTool.hpp>

+ Collaboration diagram for moab::DualTool:

Classes

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

Public Member Functions

 DualTool (Interface *impl)
 ~DualTool ()
ErrorCode construct_dual (EntityHandle *entities, const int num_entities)
 construct the dual entities for the entire mesh
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

InterfacembImpl
 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

Detailed Description

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

Authors:
Tim Tautges
Date:
2/04

Definition at line 33 of file DualTool.hpp.


Member Enumeration Documentation

anonymous enum [private]

static constant number of points bounding any cell

Enumerator:
GP_SIZE 

Definition at line 372 of file DualTool.hpp.

    {
        GP_SIZE = 20
    };

Constructor & Destructor Documentation

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.

{}

Member Function Documentation

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;
}

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;
}

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;
}

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() );
}

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 );
}

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;
}
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;
}
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;
}

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().

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;
}

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;
}

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;
}

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;
}

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();
}

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;
}

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;
}

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;
}

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;
}

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;
    }
}

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;
}

Member Data Documentation

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().

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().

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().

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

tag name for dual cells

Definition at line 43 of file DualTool.hpp.

Referenced by DualTool().

int moab::DualTool::maxHexId [private]

Definition at line 387 of file DualTool.hpp.

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

List of all members.


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines