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

#include <WriteUtil.hpp>

+ Inheritance diagram for moab::WriteUtil:
+ Collaboration diagram for moab::WriteUtil:

Public Member Functions

 WriteUtil (Core *mdb)
 Constructor takes Core pointer.
 ~WriteUtil ()
 Destructor.
virtual ErrorCode check_doesnt_exist (const char *file_name)
 Check if the specified file already exists. Returns MB_SUCCESS if file does not exist, MB_ALREADY_ALLOCATED if file does exist, or MB_FAILURE for some other error condition.
virtual ErrorCode gather_entities (Range &all_ents, const EntityHandle *ent_sets=NULL, const int num_sets=0)
 Gather all entities in the mesh, or in the sets specified.
ErrorCode get_node_coords (const int num_arrays, const int num_nodes, const Range &entities, Tag node_id_tag, const int start_node_id, std::vector< double * > &arrays)
 Gets arrays for coordinate data from the MB.
ErrorCode get_node_coords (const int which_array, Range::const_iterator begin, const Range::const_iterator &end, const size_t output_size, double *const output_array)
ErrorCode get_element_connect (const int num_elements, const int verts_per_element, Tag node_id_tag, const Range &entities, Tag element_id_tag, int start_element_id, int *array, bool add_sizes=false)
ErrorCode get_element_connect (Range::const_iterator begin, const Range::const_iterator &end, const int vertices_per_elem, Tag node_id_tag, const size_t array_size, int *const element_array, bool add_sizes=false)
virtual ErrorCode get_element_connect (Range::const_iterator begin, const Range::const_iterator &end, const int vertices_per_elem, const size_t array_size, EntityHandle *const element_array)
virtual ErrorCode get_poly_connect_size (Range::const_iterator begin, const Range::const_iterator &end, int &connectivity_size)
virtual ErrorCode get_poly_connect (Range::const_iterator &iter, const Range::const_iterator &end, const Tag node_id_tag, size_t &handle_array_len, int *const handle_array, size_t &index_array_len, int *const index_array, int &index_offset)
ErrorCode gather_nodes_from_elements (const Range &elements, const Tag node_bit_mark_tag, Range &nodes)
 Get a set of nodes that represent a set of elements.
ErrorCode assign_ids (Range &elements, Tag id_tag, const int start_id)
 Assign ids to input elements starting with start_id, written to id_tag if zero, assigns to GLOBAL_ID_TAG_NAME.
ErrorCode get_adjacencies (EntityHandle entity, Tag id_tag, std::vector< int > &adj)
ErrorCode get_adjacencies (EntityHandle entity, const EntityHandle *&adj_array, int &num_adj)
virtual ErrorCode get_tag_list (std::vector< Tag > &result_list, const Tag *user_tag_list=0, int user_tag_list_length=0, bool include_variable_length_tags=true)
 Get list of tags to write.
virtual ErrorCode get_entity_list_pointers (Range::const_iterator query_begin, Range::const_iterator query_end, EntityHandle const **output_pointer_array, EntityListType relation=CONTENTS, int *lengths=0, unsigned char *flags=0)
virtual ErrorCode get_entity_list_pointers (EntityHandle const *entities, int num_entities, EntityHandle const **output_pointer_array, EntityListType relation=CONTENTS, int *lengths=0, unsigned char *flags=0)

Private Attributes

CoremMB
 Pointer to the Core.

Detailed Description

Definition at line 30 of file WriteUtil.hpp.


Constructor & Destructor Documentation

Constructor takes Core pointer.

Definition at line 46 of file WriteUtil.cpp.

: WriteUtilIface(), mMB( mdb ) {}

Destructor.

Definition at line 41 of file WriteUtil.hpp.

{}

Member Function Documentation

ErrorCode moab::WriteUtil::assign_ids ( Range elements,
Tag  id_tag,
const int  start_id 
) [virtual]

Assign ids to input elements starting with start_id, written to id_tag if zero, assigns to GLOBAL_ID_TAG_NAME.

Implements moab::WriteUtilIface.

Definition at line 654 of file WriteUtil.cpp.

References moab::Range::begin(), moab::Range::end(), ErrorCode, moab::Core::globalId_tag(), MB_SUCCESS, mMB, and moab::Core::tag_set_data().

{
    ErrorCode result;
    if( 0 == id_tag )
    {
        // Get the global id tag
        id_tag = mMB->globalId_tag();
    }

    // Now assign the ids
    int i;
    Range::iterator rit;
    ErrorCode tmp_result;
    result = MB_SUCCESS;
    for( i = start_id, rit = elements.begin(); rit != elements.end(); ++rit, i++ )
    {
        tmp_result = mMB->tag_set_data( id_tag, &( *rit ), 1, &i );
        if( MB_SUCCESS != tmp_result ) result = tmp_result;
    }

    return result;
}
ErrorCode moab::WriteUtil::check_doesnt_exist ( const char *  file_name) [virtual]

Check if the specified file already exists. Returns MB_SUCCESS if file does not exist, MB_ALREADY_ALLOCATED if file does exist, or MB_FAILURE for some other error condition.

Implements moab::WriteUtilIface.

Definition at line 51 of file WriteUtil.cpp.

References MB_ALREADY_ALLOCATED, MB_SET_ERR, and MB_SUCCESS.

{
    struct stat s;
    if( 0 == stat( file_name, &s ) )
    {
        MB_SET_ERR( MB_ALREADY_ALLOCATED, file_name << ": file already exists" );
    }
    else if( errno == ENOENT )
        return MB_SUCCESS;
    else
        return MB_FAILURE;
}
ErrorCode moab::WriteUtil::gather_entities ( Range all_ents,
const EntityHandle ent_sets = NULL,
const int  num_sets = 0 
) [virtual]

Gather all entities in the mesh, or in the sets specified.

Parameters:
all_entsrange in which entities are returned
ent_setsentity sets whose contents are to be gathered
num_setsnumber of sets in list

Implements moab::WriteUtilIface.

Definition at line 65 of file WriteUtil.cpp.

References ErrorCode, moab::Core::get_entities_by_handle(), MB_SUCCESS, and mMB.

{
    ErrorCode rval = MB_SUCCESS;
    if( !ent_sets || num_sets == 0 )
    {
        rval = mMB->get_entities_by_handle( 0, all_ents );
    }
    else
    {
        for( int i = 0; i < num_sets; i++ )
        {
            ErrorCode tmp_rval = mMB->get_entities_by_handle( ent_sets[i], all_ents );
            if( MB_SUCCESS != tmp_rval ) rval = tmp_rval;
        }
    }

    return rval;
}
ErrorCode moab::WriteUtil::gather_nodes_from_elements ( const Range elements,
const Tag  node_bit_mark_tag,
Range nodes 
) [virtual]

Get a set of nodes that represent a set of elements.

Implements moab::WriteUtilIface.

Definition at line 515 of file WriteUtil.cpp.

References moab::Range::back(), moab::Range::begin(), moab::Range::empty(), moab::Range::end(), moab::EntitySequence::end_handle(), ErrorCode, moab::Range::front(), moab::ElementSequence::get_connectivity(), moab::Core::get_connectivity(), moab::ElementSequence::get_connectivity_array(), moab::Range::insert(), MB_ENTITY_NOT_FOUND, MB_SUCCESS, MB_TAG_CREAT, MB_TYPE_BIT, MB_TYPE_OUT_OF_RANGE, MBENTITYSET, MBPOLYHEDRON, MBVERTEX, mMB, moab::ElementSequence::nodes_per_element(), moab::Core::sequence_manager(), moab::EntitySequence::start_handle(), moab::Core::tag_delete(), moab::Core::tag_get_data(), moab::Core::tag_get_handle(), moab::Core::tag_set_data(), moab::Core::type_from_handle(), and moab::TYPE_FROM_HANDLE().

{
    bool printed_warning = false;

    if( elements.empty() ) return MB_SUCCESS;

    if( TYPE_FROM_HANDLE( elements.front() ) <= MBVERTEX || TYPE_FROM_HANDLE( elements.back() ) >= MBENTITYSET )
        return MB_TYPE_OUT_OF_RANGE;

    // See if we need to use our own marking tag
    Tag exporting_nodes_tag = 0;
    if( node_bit_mark_tag )
        exporting_nodes_tag = node_bit_mark_tag;
    else
    {
        mMB->tag_get_handle( "__MBWriteUtil::exporting_nodes", 1, MB_TYPE_BIT, exporting_nodes_tag, MB_TAG_CREAT );
    }

    // The x,y,z tag handles we need
    EntityHandle lower_bound = ~0, upper_bound = 0;

    std::vector< EntityHandle > tmp_conn;

    RangeSeqIntersectIter iter( mMB->sequence_manager() );
    for( ErrorCode rval = iter.init( elements.begin(), elements.end() ); MB_FAILURE != rval; rval = iter.step() )
    {
        if( MB_ENTITY_NOT_FOUND == rval )
        {
            if( !printed_warning )
            {
                std::cerr << "Warning: ignoring invalid element handle(s) in gather_nodes_from_elements" << std::endl;
                printed_warning = true;
            }
            continue;
        }

        ElementSequence* seq = static_cast< ElementSequence* >( iter.get_sequence() );

        // Get the connectivity array
        const EntityHandle* conn_array = seq->get_connectivity_array();

        // If unstructured mesh
        if( conn_array && mMB->type_from_handle( iter.get_start_handle() ) != MBPOLYHEDRON )
        {
            assert( iter.get_start_handle() >= seq->start_handle() );
            assert( iter.get_end_handle() <= seq->end_handle() );
            const EntityHandle offset   = iter.get_start_handle() - seq->start_handle();
            const EntityHandle num_elem = iter.get_end_handle() - iter.get_start_handle() + 1;

            conn_array += offset * seq->nodes_per_element();
            const EntityHandle num_node = num_elem * seq->nodes_per_element();

            // For each node
            for( EntityHandle j = 0; j < num_node; j++ )
            {
                EntityHandle node = conn_array[j];
                if( node < lower_bound ) lower_bound = node;
                if( node > upper_bound ) upper_bound = node;
                unsigned char bit = 0x1;
                rval              = mMB->tag_set_data( exporting_nodes_tag, &node, 1, &bit );
                assert( MB_SUCCESS == rval );
                if( MB_SUCCESS != rval ) return rval;
            }
        }
        // Polyhedra
        else if( conn_array && mMB->type_from_handle( iter.get_start_handle() ) == MBPOLYHEDRON )
        {
            assert( iter.get_start_handle() >= seq->start_handle() );
            assert( iter.get_end_handle() <= seq->end_handle() );
            const EntityHandle offset   = iter.get_start_handle() - seq->start_handle();
            const EntityHandle num_elem = iter.get_end_handle() - iter.get_start_handle() + 1;

            conn_array += offset * seq->nodes_per_element();
            int num_face = num_elem * seq->nodes_per_element();

            // For each node
            for( int j = 0; j < num_face; j++ )
            {
                const EntityHandle* face_conn = NULL;
                int face_num_conn             = 0;
                rval                          = mMB->get_connectivity( conn_array[j], face_conn, face_num_conn, false );
                if( MB_SUCCESS != rval ) return rval;
                for( int k = 0; k < face_num_conn; k++ )
                {
                    EntityHandle node = face_conn[k];
                    if( node < lower_bound ) lower_bound = node;
                    if( node > upper_bound ) upper_bound = node;
                    unsigned char bit = 0x1;
                    rval              = mMB->tag_set_data( exporting_nodes_tag, &node, 1, &bit );
                    assert( MB_SUCCESS == rval );
                    if( MB_SUCCESS != rval ) return rval;
                }
            }
        }
        // Structured mesh
        else
        {
            EntityHandle end_h = iter.get_end_handle() + 1;
            for( EntityHandle h = iter.get_start_handle(); h < end_h; ++h )
            {
                tmp_conn.clear();
                rval = seq->get_connectivity( h, tmp_conn, false );
                if( MB_SUCCESS != rval )
                {
                    if( node_bit_mark_tag == 0 ) mMB->tag_delete( exporting_nodes_tag );
                    return rval;
                }

                // For each node
                for( size_t j = 0; j < tmp_conn.size(); j++ )
                {
                    EntityHandle node = tmp_conn[j];
                    if( node < lower_bound ) lower_bound = node;
                    if( node > upper_bound ) upper_bound = node;
                    unsigned char bit = 0x1;
                    mMB->tag_set_data( exporting_nodes_tag, &node, 1, &bit );
                }
            }
        }
    }

    // We can get a REALLY long loop if lower_bound is zero
    assert( lower_bound != 0 );
    // Gather up all the nodes
    for( ; upper_bound >= lower_bound; --upper_bound )
    {
        unsigned char node_marked = 0;
        mMB->tag_get_data( exporting_nodes_tag, &upper_bound, 1, &node_marked );
        if( node_marked == 0x1 ) nodes.insert( upper_bound );
    }

    // Clean up our own marking tag
    if( node_bit_mark_tag == 0 ) mMB->tag_delete( exporting_nodes_tag );

    return MB_SUCCESS;
}
ErrorCode moab::WriteUtil::get_adjacencies ( EntityHandle  entity,
Tag  id_tag,
std::vector< int > &  adj 
) [virtual]

Get explicit adjacencies

Get explicit adjacences stored in database. Does not create any explicit adjacencies or search for implicit ones.

Parameters:
entityThe entity to retrieve adjacencies for.
id_tagThe global ID tag
adjThe output list of global IDs of adjacent entities.

Implements moab::WriteUtilIface.

Definition at line 677 of file WriteUtil.cpp.

References moab::Core::a_entity_factory(), ErrorCode, moab::AEntityFactory::get_adjacencies(), MB_SUCCESS, MBENTITYSET, mMB, moab::Core::tag_get_data(), and moab::TYPE_FROM_HANDLE().

{
    ErrorCode rval;
    const EntityHandle* adj_array;
    int num_adj, id;

    // Get handles of adjacent entities
    rval = mMB->a_entity_factory()->get_adjacencies( entity, adj_array, num_adj );
    if( MB_SUCCESS != rval )
    {
        adj.clear();
        return rval;
    }

    // Append IDs of adjacent entities -- skip meshsets
    adj.resize( num_adj );  // Pre-allocate space
    adj.clear();            // Clear used space

    const EntityHandle* const end = adj_array + num_adj;
    for( const EntityHandle* iter = adj_array; iter != end; ++iter )
    {
        if( TYPE_FROM_HANDLE( *iter ) != MBENTITYSET )
        {
            rval = mMB->tag_get_data( id_tag, iter, 1, &id );
            if( MB_SUCCESS != rval ) return rval;
            adj.push_back( id );
        }
    }

    return MB_SUCCESS;
}
ErrorCode moab::WriteUtil::get_adjacencies ( EntityHandle  entity,
const EntityHandle *&  adj_array,
int &  num_adj 
) [virtual]

Implements moab::WriteUtilIface.

Definition at line 709 of file WriteUtil.cpp.

References moab::Core::a_entity_factory(), moab::AEntityFactory::get_adjacencies(), and mMB.

{
    return mMB->a_entity_factory()->get_adjacencies( entity, adj_array, num_adj );
}
ErrorCode moab::WriteUtil::get_element_connect ( const int  num_elements,
const int  verts_per_element,
Tag  node_id_tag,
const Range entities,
Tag  element_id_tag,
int  start_element_id,
int *  array,
bool  add_sizes = false 
) [virtual]

Get connectivity for elements

Get the connectivity list for a range of elements.

Parameters:
num_elementsNumber of elements for which connectivity is needed
vertices_per_elemNumber of vertices to retrieve for each element.
node_id_tagA tag with integer values.
entitiesEntities being queried
element_id_tagIf non-zero, elements are tagged with an id starting at start_element_id
start_element_idStarting id value for element_id_tag
add_sizesIf true, writes size of connect array before connectivity in array

Implements moab::WriteUtilIface.

Definition at line 215 of file WriteUtil.cpp.

References moab::TypeSequenceManager::begin(), moab::Range::begin(), moab::Range::empty(), moab::TypeSequenceManager::end(), moab::Range::end(), moab::SequenceManager::entity_map(), moab::ElementSequence::get_connectivity_array(), MB_SUCCESS, mMB, moab::ElementSequence::nodes_per_element(), moab::Core::sequence_manager(), moab::Core::tag_get_data(), moab::Core::tag_set_data(), and moab::TYPE_FROM_HANDLE().

{
    // Check the data we got
    if( num_elements < 1 ) return MB_FAILURE;
    if( verts_per_element < 1 ) return MB_FAILURE;
    if( elements.empty() ) return MB_FAILURE;
    if( !element_array ) return MB_FAILURE;

    Range::const_iterator range_iter     = elements.begin();
    Range::const_iterator range_iter_end = elements.end();

    TypeSequenceManager::iterator seq_iter, seq_iter_end;
    EntityType current_type = TYPE_FROM_HANDLE( *range_iter );

    seq_iter     = mMB->sequence_manager()->entity_map( current_type ).begin();
    seq_iter_end = mMB->sequence_manager()->entity_map( current_type ).end();

    // Let's find the entity sequence which holds the first entity
    TypeSequenceManager::iterator seq_iter_lookahead = seq_iter;
    ++seq_iter_lookahead;
    for( ; seq_iter_lookahead != seq_iter_end && ( *seq_iter_lookahead )->start_handle() < *range_iter; )
    {
        ++seq_iter;
        ++seq_iter_lookahead;
    }

    // A look ahead iterator
    Range::const_iterator range_iter_lookahead = range_iter;

    // Our main loop
    for( ; range_iter != range_iter_end && seq_iter != seq_iter_end; /* ++ is handled in loop*/ )
    {
        // Find a range that fits in the current entity sequence
        for( ; range_iter_lookahead != range_iter_end && *range_iter_lookahead <= ( *seq_iter )->end_handle();
             ++range_iter_lookahead )
        {
        }

        if( current_type != TYPE_FROM_HANDLE( *range_iter ) )
        {
            current_type = TYPE_FROM_HANDLE( *range_iter );
            seq_iter     = mMB->sequence_manager()->entity_map( current_type ).begin();
            seq_iter_end = mMB->sequence_manager()->entity_map( current_type ).end();

            // Let's find the entity sequence which holds the first entity of this type
            TypeSequenceManager::const_iterator seq_iter_lookahead2 = seq_iter;
            ++seq_iter_lookahead2;
            for( ; seq_iter_lookahead2 != seq_iter_end && ( *seq_iter_lookahead2 )->start_handle() < *range_iter; )
            {
                ++seq_iter;
                ++seq_iter_lookahead2;
            }
        }

        int i = static_cast< ElementSequence* >( *seq_iter )->nodes_per_element();

        // Get the connectivity array
        EntityHandle* conn_array = static_cast< ElementSequence* >( *seq_iter )->get_connectivity_array();

        EntityHandle start_handle = ( *seq_iter )->start_handle();

        for( Range::const_iterator tmp_iter = range_iter; tmp_iter != range_iter_lookahead; ++tmp_iter )
        {
            // Set the element id tag
            mMB->tag_set_data( element_id_tag, &*tmp_iter, 1, &start_element_id );
            ++start_element_id;

            if( add_sizes ) *element_array++ = i;

            // For each node
            for( int j = 0; j < i; j++ )
            {
                EntityHandle node = *( conn_array + j + i * ( *tmp_iter - start_handle ) );
                mMB->tag_get_data( node_id_tag, &node, 1, element_array );
                element_array++;
            }
        }

        // Go to the next entity sequence
        ++seq_iter;
        // Start with the next entities
        range_iter = range_iter_lookahead;
    }

    return MB_SUCCESS;
}
ErrorCode moab::WriteUtil::get_element_connect ( Range::const_iterator  begin,
const Range::const_iterator end,
const int  vertices_per_elem,
Tag  node_id_tag,
const size_t  array_size,
int *const  element_array,
bool  add_sizes = false 
) [virtual]

Get connectivity for elements

Get the connectivity list for a range of elements.

Failure cases:

  • Passed range is empty (begin == end).
  • vertices_per_elem is less than one
  • element_array is null.
  • The range contains invalid handles (non-existent entities, not an element, etc.)
  • Retrieving ID tag for an entity failed.
  • Insufficient space in passed array.
Parameters:
beginThe first element handle
endOne past the last element handle
vertices_per_elemNumber of vertices to retrieve for each element. If the element has more vertices, the element connectivity will be truncated. If vertices_per_elem is greater than the number of nodes for an element, the data will be padded with zeros.
node_id_tagA tag with integer values.
array_sizeThe length of element_array
element_arrayThe memory location at which to store the connectivity list.
add_sizesIf true, writes size of connect array before connectivity in array
Author:
Jason Kraftcheck

Implements moab::WriteUtilIface.

Definition at line 309 of file WriteUtil.cpp.

References moab::TypeSequenceManager::begin(), moab::TypeSequenceManager::end(), moab::SequenceManager::entity_map(), ErrorCode, moab::ElementSequence::get_connectivity_array(), MB_SUCCESS, MBEDGE, MBENTITYSET, MBMAXTYPE, mMB, moab::ElementSequence::nodes_per_element(), moab::Core::sequence_manager(), moab::Core::tag_get_data(), and moab::TYPE_FROM_HANDLE().

{
    // Check the data we got
    if( iter == end ) return MB_FAILURE;
    if( vertices_per_elem < 1 ) return MB_FAILURE;
    if( !element_array || elem_array_size < (unsigned)vertices_per_elem ) return MB_FAILURE;

    // Sequence iterators
    TypeSequenceManager::const_iterator seq_iter, seq_end;

    // loop over range, getting coordinate value
    EntityType current_type = MBMAXTYPE;
    int* output_iter        = element_array;
    int* const output_end   = element_array + elem_array_size;
    while( iter != end )
    {
        // Make sure we have the right sequence list (and get the sequence
        // list for the first iteration.)
        EntityType type = TYPE_FROM_HANDLE( *iter );
        if( type != current_type )
        {
            if( type >= MBENTITYSET || type < MBEDGE ) return MB_FAILURE;
            seq_iter     = mMB->sequence_manager()->entity_map( type ).begin();
            seq_end      = mMB->sequence_manager()->entity_map( type ).end();
            current_type = type;
        }

        // Find the sequence containing the current handle
        while( seq_iter != seq_end && ( *seq_iter )->end_handle() < *iter )
            ++seq_iter;
        if( seq_iter == seq_end || *iter < ( *seq_iter )->start_handle() ) return MB_FAILURE;

        // Get the connectivity array
        EntityHandle* conn_array = NULL;
        int conn_size            = static_cast< ElementSequence* >( *seq_iter )->nodes_per_element();
        conn_array               = static_cast< ElementSequence* >( *seq_iter )->get_connectivity_array();

        // Determine how much of the sequence we want.
        Range::pair_iterator pair( iter );
        Range::const_iterator prev( end );
        --prev;
        EntityHandle range_end    = pair->second;
        EntityHandle sequence_end = ( *seq_iter )->end_handle();
        EntityHandle end_handle   = range_end > sequence_end ? sequence_end : range_end;
        if( end_handle > *prev ) end_handle = *prev;
        EntityHandle count = end_handle - *iter + 1;

        // Get offset in sequence to start at
        assert( *iter >= ( *seq_iter )->start_handle() );
        EntityHandle offset = *iter - ( *seq_iter )->start_handle();

        // Make sure sufficient space in output array
        if( ( !add_sizes && output_iter + ( count * conn_size ) > output_end ) ||
            ( add_sizes && output_iter + ( count * ( conn_size + 1 ) ) > output_end ) )
            return MB_FAILURE;

        // If the nodes per element match, do in one call
        conn_array += ( conn_size * offset );
        if( vertices_per_elem == conn_size && !add_sizes )
        {
            ErrorCode rval = mMB->tag_get_data( node_id_tag, conn_array, count * conn_size, output_iter );
            if( MB_SUCCESS != rval ) return rval;

            output_iter += count * conn_size;
        }
        // Otherwise need to do one at a time
        else
        {
            int min = vertices_per_elem > conn_size ? conn_size : vertices_per_elem;
            for( EntityHandle i = 0; i < count; ++i )
            {
                *output_iter++ = min;
                ErrorCode rval = mMB->tag_get_data( node_id_tag, conn_array, min, output_iter );
                if( MB_SUCCESS != rval ) return rval;

                output_iter += min;
                conn_array += conn_size;

                if( vertices_per_elem > conn_size )
                {  // Need to pad
                    memset( output_iter, 0, sizeof( int ) * ( vertices_per_elem - conn_size ) );
                    output_iter += ( vertices_per_elem - conn_size );
                }
            }
        }

        iter += count;
    }

    return MB_SUCCESS;
}
ErrorCode moab::WriteUtil::get_element_connect ( Range::const_iterator  begin,
const Range::const_iterator end,
const int  vertices_per_elem,
const size_t  array_size,
EntityHandle *const  element_array 
) [virtual]

Get connectivity for elements

Get the connectivity list for a range of elements.

Failure cases:

  • Passed range is empty (begin == end).
  • vertices_per_elem is less than one
  • element_array is null.
  • The range contains invalid handles (non-existent entities, not an element, etc.)
  • Insufficient space in passed array.
Parameters:
beginThe first element handle
endOne past the last element handle
vertices_per_elemNumber of vertices to retrieve for each element. If the element has more vertices, the element connectivity will be truncated. If vertices_per_elem is greater than the number of nodes for an element, the data will be padded with zeros.
array_sizeThe length of element_array
element_arrayThe memory location at which to store the connectivity list.
Author:
Jason Kraftcheck

Implements moab::WriteUtilIface.

Definition at line 407 of file WriteUtil.cpp.

References moab::TypeSequenceManager::begin(), moab::TypeSequenceManager::end(), moab::SequenceManager::entity_map(), ErrorCode, moab::ElementSequence::get_connectivity(), moab::ElementSequence::get_connectivity_array(), MB_SUCCESS, MBEDGE, MBENTITYSET, MBMAXTYPE, mMB, moab::ElementSequence::nodes_per_element(), moab::Core::sequence_manager(), and moab::TYPE_FROM_HANDLE().

{
    // Check the data we got
    if( iter == end ) return MB_FAILURE;
    if( vertices_per_elem < 1 ) return MB_FAILURE;
    if( !element_array || elem_array_size < (unsigned)vertices_per_elem ) return MB_FAILURE;

    // Sequence iterators
    TypeSequenceManager::const_iterator seq_iter, seq_end;

    // Loop over range, getting coordinate value
    EntityType current_type        = MBMAXTYPE;
    EntityHandle* output_iter      = element_array;
    EntityHandle* const output_end = element_array + elem_array_size;
    while( iter != end )
    {
        // Make sure we have the right sequence list (and get the sequence
        // list for the first iteration.)
        EntityType type = TYPE_FROM_HANDLE( *iter );
        if( type != current_type )
        {
            if( type >= MBENTITYSET || type < MBEDGE ) return MB_FAILURE;
            seq_iter     = mMB->sequence_manager()->entity_map( type ).begin();
            seq_end      = mMB->sequence_manager()->entity_map( type ).end();
            current_type = type;
        }

        // Find the sequence containing the current handle
        while( seq_iter != seq_end && ( *seq_iter )->end_handle() < *iter )
            ++seq_iter;
        if( seq_iter == seq_end || *iter < ( *seq_iter )->start_handle() ) return MB_FAILURE;

        // Get the connectivity array
        EntityHandle* conn_array = NULL;
        int conn_size            = static_cast< ElementSequence* >( *seq_iter )->nodes_per_element();
        if( conn_size != vertices_per_elem ) return MB_FAILURE;
        conn_array = static_cast< ElementSequence* >( *seq_iter )->get_connectivity_array();

        // Determine how much of the sequence we want.
        Range::pair_iterator pair( iter );
        Range::const_iterator prev( end );
        --prev;
        EntityHandle range_end    = pair->second;
        EntityHandle sequence_end = ( *seq_iter )->end_handle();
        EntityHandle end_handle   = range_end > sequence_end ? sequence_end : range_end;
        if( end_handle > *prev ) end_handle = *prev;
        EntityHandle count = end_handle - *iter + 1;

        // Get offset in sequence to start at
        assert( *iter >= ( *seq_iter )->start_handle() );
        EntityHandle offset = *iter - ( *seq_iter )->start_handle();

        // Make sure sufficient space in output array
        if( output_iter + ( count * conn_size ) > output_end ) return MB_FAILURE;

        if( conn_array == NULL )
        {  // If it is structured mesh
            ErrorCode rval;
            int temp_buff_size = conn_size * sizeof( EntityHandle );
            for( unsigned i = 0; i < count; i++ )
            {  // Copy connectivity element by element
                std::vector< EntityHandle > connect;
                rval = static_cast< ElementSequence* >( *seq_iter )->get_connectivity( *iter, connect );
                if( MB_SUCCESS != rval )
                {
                    return rval;
                }
                memcpy( output_iter, &connect[0], temp_buff_size );
                output_iter += conn_size;
                ++iter;
            }
        }
        else
        {
            // Copy connectivity into output array
            conn_array += ( conn_size * offset );
            memcpy( output_iter, conn_array, count * conn_size * sizeof( EntityHandle ) );
            output_iter += count * conn_size;
            iter += count;
        }
    }

    return MB_SUCCESS;
}
ErrorCode moab::WriteUtil::get_entity_list_pointers ( Range::const_iterator  query_begin,
Range::const_iterator  query_end,
EntityHandle const **  output_pointer_array,
EntityListType  relation = CONTENTS,
int *  lengths = 0,
unsigned char *  flags = 0 
) [virtual]

Implements moab::WriteUtilIface.

Definition at line 776 of file WriteUtil.cpp.

References moab::WriteUtilIface::CHILDREN, moab::WriteUtilIface::CONTENTS, ErrorCode, moab::ElementSequence::get_connectivity(), moab::MeshSetSequence::get_set(), MB_SUCCESS, MB_TYPE_OUT_OF_RANGE, MBENTITYSET, MBVERTEX, mMB, moab::WriteUtilIface::PARENTS, moab::Core::sequence_manager(), moab::WriteUtilIface::TOPOLOGICAL, and moab::TYPE_FROM_HANDLE().

{
    RangeSeqIntersectIter iter( mMB->sequence_manager() );
    ErrorCode rval = iter.init( begin, end );
    while( MB_SUCCESS == rval )
    {
        EntityType type = TYPE_FROM_HANDLE( iter.get_start_handle() );

        if( MBENTITYSET == type )
        {
            const MeshSetSequence* seq = reinterpret_cast< MeshSetSequence* >( iter.get_sequence() );
            const MeshSet* set;
            int len = 0;
            size_t clen;
            for( EntityHandle h = iter.get_start_handle(); h <= iter.get_end_handle(); ++h )
            {
                set = seq->get_set( h );
                switch( relation )
                {
                    case CONTENTS:
                        *pointers = set->get_contents( clen );
                        len       = clen;
                        break;
                    case CHILDREN:
                        *pointers = set->get_children( len );
                        break;
                    case PARENTS:
                        *pointers = set->get_parents( len );
                        break;
                }
                if( lengths )
                {
                    *lengths = len;
                    ++lengths;
                }
                if( flags )
                {
                    *flags = (unsigned char)set->flags();
                    ++flags;
                }
                ++pointers;
            }
        }

        else if( MBVERTEX != type )
        {
            const bool topological = ( relation == TOPOLOGICAL );
            int len;
            const ElementSequence* seq = reinterpret_cast< ElementSequence* >( iter.get_sequence() );
            for( EntityHandle h = iter.get_start_handle(); h <= iter.get_end_handle(); ++h )
            {
                rval = seq->get_connectivity( h, *pointers, len, topological );
                if( MB_SUCCESS != rval ) return rval;
                if( lengths )
                {
                    *lengths = len;
                    ++lengths;
                }
                if( flags )
                {
                    *flags = 0;
                    ++flags;
                }
                ++pointers;
            }
        }
        else
        {
            return MB_TYPE_OUT_OF_RANGE;
        }

        rval = iter.step();
    }
    if( MB_FAILURE == rval )
        return MB_SUCCESS;  // At end of list
    else
        return rval;
}
ErrorCode moab::WriteUtil::get_entity_list_pointers ( EntityHandle const *  entities,
int  num_entities,
EntityHandle const **  output_pointer_array,
EntityListType  relation = CONTENTS,
int *  lengths = 0,
unsigned char *  flags = 0 
) [virtual]

Implements moab::WriteUtilIface.

Definition at line 860 of file WriteUtil.cpp.

References moab::WriteUtilIface::CHILDREN, moab::WriteUtilIface::CONTENTS, ErrorCode, moab::SequenceManager::find(), moab::ElementSequence::get_connectivity(), moab::MeshSetSequence::get_set(), MB_SUCCESS, MB_TYPE_OUT_OF_RANGE, MBENTITYSET, MBVERTEX, mMB, moab::WriteUtilIface::PARENTS, moab::Core::sequence_manager(), moab::WriteUtilIface::TOPOLOGICAL, and moab::TYPE_FROM_HANDLE().

{
    SequenceManager* sm = mMB->sequence_manager();
    const EntitySequence* tmp_seq;
    ErrorCode rval = MB_SUCCESS;
    for( int i = 0; i < num_entities; i++ )
    {
        rval = sm->find( entities[i], tmp_seq );
        if( MB_SUCCESS != rval ) return rval;

        EntityType type = TYPE_FROM_HANDLE( entities[i] );

        if( MBENTITYSET == type )
        {
            const MeshSetSequence* seq = reinterpret_cast< const MeshSetSequence* >( tmp_seq );
            const MeshSet* set;
            int len = 0;
            size_t clen;
            set = seq->get_set( entities[i] );
            switch( relation )
            {
                case CONTENTS:
                    *pointers = set->get_contents( clen );
                    len       = clen;
                    break;
                case CHILDREN:
                    *pointers = set->get_children( len );
                    break;
                case PARENTS:
                    *pointers = set->get_parents( len );
                    break;
            }
            if( lengths )
            {
                *lengths = len;
                ++lengths;
            }
            if( flags )
            {
                *flags = (unsigned char)set->flags();
                ++flags;
            }
            ++pointers;
        }
        else if( MBVERTEX != type )
        {
            const bool topological = ( relation == TOPOLOGICAL );
            int len;
            const ElementSequence* seq = reinterpret_cast< const ElementSequence* >( tmp_seq );
            rval                       = seq->get_connectivity( entities[i], *pointers, len, topological );
            if( MB_SUCCESS != rval ) return rval;
            if( lengths )
            {
                *lengths = len;
                ++lengths;
            }
            if( flags )
            {
                *flags = 0;
                ++flags;
            }
            ++pointers;
        }
        else
        {
            return MB_TYPE_OUT_OF_RANGE;
        }
    }

    return MB_SUCCESS;
}
ErrorCode moab::WriteUtil::get_node_coords ( const int  num_arrays,
const int  num_nodes,
const Range entities,
Tag  node_id_tag,
const int  start_node_id,
std::vector< double * > &  arrays 
) [virtual]

Gets arrays for coordinate data from the MB.

Implements moab::WriteUtilIface.

Definition at line 90 of file WriteUtil.cpp.

References moab::Range::empty(), ErrorCode, moab::Core::get_coords(), MB_SUCCESS, mMB, and moab::Core::tag_set_data().

{
    // Check the data coming into the function
    // Dimension should be proper
    if( num_arrays < 1 || num_arrays > 3 ) return MB_FAILURE;

    // There should be some entities
    // if (entities.empty())
    //  return MB_FAILURE;
    // The above necessitates annoying special cases for files
    // w/out vertices (e.g. a kD-tree).  Return NULL array
    // pointers instead. - kraftcheck, 3-14-08
    if( entities.empty() )
    {
        arrays.clear();
        arrays.resize( num_arrays, NULL );
        return MB_SUCCESS;
    }

    // Memory should already be allocated for us
    int tmp_num_arrays = 0;
    for( unsigned int i = 0; i < 3; i++ )
        if( i + 1 <= arrays.size() && NULL != arrays[i] ) tmp_num_arrays++;
    if( 0 == tmp_num_arrays ) return MB_FAILURE;

    // Get coordinate data
    ErrorCode result = mMB->get_coords( entities, num_arrays < 1 || arrays.size() < 1 ? NULL : arrays[0],
                                        num_arrays < 2 || arrays.size() < 2 ? NULL : arrays[1],
                                        num_arrays < 3 || arrays.size() < 3 ? NULL : arrays[2] );

    if( 0 == node_id_tag || MB_SUCCESS != result ) return result;

    // Now assign tags
    std::vector< int > ids( num_nodes );
    int node_id = start_node_id;
    for( int i = 0; i < num_nodes; i++ )
        ids[i] = node_id++;
    result = mMB->tag_set_data( node_id_tag, entities, &ids[0] );

    return result;
}
ErrorCode moab::WriteUtil::get_node_coords ( const int  which_array,
Range::const_iterator  begin,
const Range::const_iterator end,
const size_t  output_size,
double *const  output_array 
) [virtual]

Get an array of coordinate values for nodes

Given a range of node handles, retrieve a single or multiple coordinate value(s) for each.

Failure conditions:

  • invalid entity handles (not vertices, non-existent entity, etc.)
  • range is empty (iter == end)
  • output_array is null
  • insufficient space in output_array
Parameters:
which_arrayThe coordinate to retrieve (0->X, 1->Y, 2->Z, -1->all)
beginThe first node handle.
endOne past the last node handle.
output_sizeThe size of output_array.
output_arrayThe memory in which to write the node coordinates.
Author:
Jason Kraftcheck

Implements moab::WriteUtilIface.

Definition at line 137 of file WriteUtil.cpp.

References moab::TypeSequenceManager::begin(), moab::TypeSequenceManager::end(), moab::SequenceManager::entity_map(), moab::VertexSequence::get_coordinate_arrays(), MB_SUCCESS, MBVERTEX, mMB, and moab::Core::sequence_manager().

{
    // Check the data coming into the function
    // Dimension should be proper
    if( which_array < -1 || which_array > 2 ) return MB_FAILURE;

    // There should be some entities
    if( iter == end ) return MB_FAILURE;

    // Memory should already be allocated for us
    if( NULL == output_array || 0 == output_array_len ) return MB_FAILURE;

    // Sequence iterators
    TypeSequenceManager::iterator seq_iter, seq_end;
    seq_iter = mMB->sequence_manager()->entity_map( MBVERTEX ).begin();
    seq_end  = mMB->sequence_manager()->entity_map( MBVERTEX ).end();

    // Loop over range, getting coordinate value
    double* output_iter      = output_array;
    double* const output_end = output_array + output_array_len;
    while( iter != end )
    {
        // Find the sequence containing the current handle
        while( seq_iter != seq_end && ( *seq_iter )->end_handle() < *iter )
            ++seq_iter;
        if( seq_iter == seq_end || *iter < ( *seq_iter )->start_handle() ) return MB_FAILURE;

        // Determine how much of the sequence we want.
        Range::pair_iterator pair( iter );
        Range::const_iterator prev( end );
        --prev;
        EntityHandle range_end    = pair->second;
        EntityHandle sequence_end = ( *seq_iter )->end_handle();
        EntityHandle end_handle   = range_end > sequence_end ? sequence_end : range_end;
        if( end_handle > *prev ) end_handle = *prev;
        EntityHandle count = end_handle - *iter + 1;

        // Get offset in sequence to start at
        assert( *iter >= ( *seq_iter )->start_handle() );
        EntityHandle offset = *iter - ( *seq_iter )->start_handle();

        // Get coordinate arrays from sequence
        double* coord_array[3];
        static_cast< VertexSequence* >( *seq_iter )
            ->get_coordinate_arrays( coord_array[0], coord_array[1], coord_array[2] );

        // Copy data to output buffer
        if( -1 != which_array )
        {
            if( output_iter + count > output_end ) return MB_FAILURE;
            memcpy( output_iter, coord_array[which_array] + offset, count * sizeof( double ) );
            output_iter += count;
        }
        else
        {
            if( output_iter + 3 * count > output_end ) return MB_FAILURE;
            for( unsigned int i = 0; i < count; i++ )
            {
                *output_iter = coord_array[0][i + offset];
                output_iter++;
                *output_iter = coord_array[1][i + offset];
                output_iter++;
                *output_iter = coord_array[2][i + offset];
                output_iter++;
            }
        }

        // Iterate
        iter += count;
    }

    return MB_SUCCESS;
}
ErrorCode moab::WriteUtil::get_poly_connect ( Range::const_iterator iter,
const Range::const_iterator end,
const Tag  node_id_tag,
size_t &  handle_array_len,
int *const  handle_array,
size_t &  index_array_len,
int *const  index_array,
int &  index_offset 
) [virtual]

Get poly (polygon or polyhedron) connectivity.

This function will add as many polys as possible to the passed arrays given the sizes of those arrays. It will then pass back position at which it stopped and the sizes of the data written to the arrays.

Parameters:
iterAs input, the first element handle. As output, one past the last element handle for which data was written to the arrays.
endThe iterator at which to stop.
node_id_tagA tag with integer values.
element_array_lenAs input, length of element_array. As output, the number of entries written in that array.
element_arrayThe memory location at which to store the connectivity list.
index_array_lenAs input, the length of index_array. As output, the number of entries written in that array.
index_arrayThe memory location at which to store offsets.
index_offsetValue to offset (add to) index values. As output the input value plus the amount of data written to the element array. (The value you presumably want to pass to the next call.)
Author:
Jason Kraftcheck

Implements moab::WriteUtilIface.

Definition at line 503 of file WriteUtil.cpp.

References MB_NOT_IMPLEMENTED.

{
    return MB_NOT_IMPLEMENTED;
}
ErrorCode moab::WriteUtil::get_poly_connect_size ( Range::const_iterator  begin,
const Range::const_iterator end,
int &  connectivity_size 
) [virtual]

Get poly (polygon or polyhedron) connectivity size

Parameters:
beginFirst iterator in range of poly
endOne past last in range of poly.
connectivity_sizeThe length of the connectivity list For the specified range of polyhedra.
Author:
Jason Kraftcheck

Implements moab::WriteUtilIface.

Definition at line 496 of file WriteUtil.cpp.

References MB_NOT_IMPLEMENTED.

{
    return MB_NOT_IMPLEMENTED;
}
ErrorCode moab::WriteUtil::get_tag_list ( std::vector< Tag > &  result_list,
const Tag user_tag_list = 0,
int  user_tag_list_length = 0,
bool  include_variable_length_tags = true 
) [virtual]

Get list of tags to write.

Get the list of tags to write to the file, possibly using an optional user-specified tag list. This function consolidates some common code for file writers to use to figure out what tag data to write to the file. It provides the following features: o filter list based on user-specified array of tag handles o filter internal tags (those for which the name is prefixed with two underscore characters) o filter anonymous tags o optionally filter variable-length tags.

Author:
Jason Kraftcheck
Parameters:
result_listList of tag handles for which to write data
user_tag_listOptional array of tag handles passed by user to write to file.
include_variable_length_tagsIf false, return only fixed-length tags.

Implements moab::WriteUtilIface.

Definition at line 714 of file WriteUtil.cpp.

References ErrorCode, MB_CHK_SET_ERR, MB_SET_ERR, MB_SUCCESS, MB_TAG_NOT_FOUND, MB_TYPE_OUT_OF_RANGE, MB_VARIABLE_DATA_LENGTH, mMB, size, moab::Core::tag_get_length(), moab::Core::tag_get_name(), and moab::Core::tag_get_tags().

{
    ErrorCode rval;

    if( user_tag_list )
    {
        result_list.clear();
        result_list.reserve( user_tag_list_length );
        for( int i = 0; i < user_tag_list_length; ++i )
        {
            std::string name;
            rval = mMB->tag_get_name( user_tag_list[i], name );MB_CHK_SET_ERR( rval, "Error " << (int)rval << " getting name for tag (Invalid input tag handle?)" );

            if( name.empty() )
            {
                MB_SET_ERR( MB_TAG_NOT_FOUND, "Explicit request to save anonymous tag" );
            }

            int size;
            if( !include_variable_length_tags &&
                MB_VARIABLE_DATA_LENGTH == mMB->tag_get_length( user_tag_list[i], size ) )
            {
                MB_SET_ERR( MB_TYPE_OUT_OF_RANGE, "File format cannot store variable-length tag: \"" << name << "\"" );
            }

            result_list.push_back( user_tag_list[i] );
        }
    }
    else
    {
        std::vector< Tag > temp_list;
        rval = mMB->tag_get_tags( temp_list );MB_CHK_SET_ERR( rval, "Interface::tag_get_tags failed" );

        result_list.clear();
        result_list.reserve( temp_list.size() );

        std::vector< Tag >::iterator i;
        for( i = temp_list.begin(); i != temp_list.end(); ++i )
        {
            std::string name;
            rval = mMB->tag_get_name( *i, name );MB_CHK_SET_ERR( rval, "Error " << (int)rval << " getting name for tag (Stale tag handle?)" );

            // Skip anonymous tags
            if( name.empty() ) continue;

            // Skip private/internal tags
            if( name.size() >= 2 && name[0] == '_' && name[1] == '_' ) continue;

            // If requested, skip variable-length tags
            int size;
            if( !include_variable_length_tags && MB_VARIABLE_DATA_LENGTH == mMB->tag_get_length( *i, size ) ) continue;

            result_list.push_back( *i );
        }
    }

    return MB_SUCCESS;
}

Member Data Documentation

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