MOAB: Mesh Oriented datABase
(version 5.4.1)
|
#include <ReorderTool.hpp>
Public Member Functions | |
ReorderTool (Core *moab) | |
ErrorCode | handle_order_from_int_tag (Tag ordering_tag, int ordering_tag_skip_value, Tag &new_handle_tag_out) |
Calculate new handle order by tag value. | |
ErrorCode | handle_order_from_int_tag (EntityType type, int vals_per_ent, Tag ordering_tag, int ordering_tag_skip_value, Tag new_handle_tag) |
Calculate new handle order by tag value. | |
ErrorCode | handle_order_from_sets_and_adj (const Range &sets, Tag &new_handle_tag_out) |
Calculate new handle order by set containment. | |
ErrorCode | reorder_entities (Tag new_handle_tag) |
Do the re-ordering indicated by the passed handle tag. | |
Private Member Functions | |
ErrorCode | reorder_tag_data (EntityType type, Tag new_handles, Tag reorder_tag) |
helper function for reorder_entities | |
ErrorCode | update_set_contents (Tag new_handles) |
helper function for reorder_entities | |
void | get_entities (EntityType t, int vals_per_ent, Range &result) |
Get all entities of specified type and size. | |
ErrorCode | get_reordered_handles (Tag tag, const Range &old_handles, std::vector< EntityHandle > &new_handles) |
Get new handles corresponding to old handles. | |
ErrorCode | get_reordered_handles (Tag tag, const std::vector< EntityHandle > &old_handles, std::vector< EntityHandle > &new_handles) |
Get new handles corresponding to old handles. | |
ErrorCode | get_reordered_handles (Tag tag, const EntityHandle *old_handles, EntityHandle *new_handles, size_t num_handles) |
Get new handles corresponding to old handles. | |
ErrorCode | get_new_handles (Tag tag, Range &old_handles, std::vector< EntityHandle > &newhandles) |
Remove any non-ordered handles and return new handles for remaining. | |
ErrorCode | int_order_from_sets_and_adj (const Range &sets, Tag order_tag, int skip_val, std::vector< std::vector< EntityHandle > * > &data) |
convert from input for handle_order_from_sets_and_adj to input for handle_order_from_int_tag | |
Private Attributes | |
Core * | mMB |
Definition at line 18 of file ReorderTool.hpp.
moab::ReorderTool::ReorderTool | ( | Core * | moab | ) | [inline] |
Definition at line 21 of file ReorderTool.hpp.
: mMB( moab ) {}
void moab::ReorderTool::get_entities | ( | EntityType | t, |
int | vals_per_ent, | ||
Range & | result | ||
) | [private] |
Get all entities of specified type and size.
t | the type of entity to retreive |
vals_per_ent | entity size (connectivity length for elements, dimension for vertices) |
Definition at line 101 of file ReorderTool.cpp.
References moab::TypeSequenceManager::begin(), moab::Range::begin(), moab::TypeSequenceManager::end(), moab::EntitySequence::end_handle(), moab::SequenceManager::entity_map(), moab::Range::insert(), mMB, moab::Core::sequence_manager(), moab::EntitySequence::start_handle(), and moab::EntitySequence::values_per_entity().
Referenced by handle_order_from_int_tag(), and reorder_entities().
{ Range::iterator hint = entities.begin(); ; TypeSequenceManager& seqs = mMB->sequence_manager()->entity_map( t ); TypeSequenceManager::iterator s; for( s = seqs.begin(); s != seqs.end(); ++s ) { EntitySequence* seq = *s; if( seq->values_per_entity() == vals_per_ent ) hint = entities.insert( hint, seq->start_handle(), seq->end_handle() ); } }
ErrorCode moab::ReorderTool::get_new_handles | ( | Tag | tag, |
Range & | old_handles, | ||
std::vector< EntityHandle > & | newhandles | ||
) | [private] |
Remove any non-ordered handles and return new handles for remaining.
tag | Tag containing old->new mapping |
Definition at line 372 of file ReorderTool.cpp.
References moab::Range::begin(), CHKERR, moab::Range::erase(), ErrorCode, MB_SUCCESS, mMB, moab::Range::size(), and moab::Core::tag_get_data().
Referenced by reorder_tag_data(), and update_set_contents().
{ // get new handles for tagged entities newhandles.resize( old_handles.size() ); ErrorCode rval = mMB->tag_get_data( tag, old_handles, ( newhandles.empty() ) ? NULL : &newhandles[0] );CHKERR; // remove entities that were not reordered Range::iterator i = old_handles.begin(); size_t w = 0; for( size_t r = 0; r < newhandles.size(); ++r ) { if( 0 != newhandles[r] ) { newhandles[w] = newhandles[r]; ++w; ++i; } else { i = old_handles.erase( i ); } } newhandles.resize( w ); assert( newhandles.size() == old_handles.size() ); return MB_SUCCESS; }
ErrorCode moab::ReorderTool::get_reordered_handles | ( | Tag | tag, |
const Range & | old_handles, | ||
std::vector< EntityHandle > & | new_handles | ||
) | [private] |
Get new handles corresponding to old handles.
tag | Tag containing old->new mapping |
Definition at line 336 of file ReorderTool.cpp.
References moab::Range::begin(), CHKERR, moab::Range::end(), ErrorCode, MB_SUCCESS, mMB, moab::Range::size(), and moab::Core::tag_get_data().
Referenced by get_reordered_handles(), reorder_entities(), reorder_tag_data(), and update_set_contents().
{ new_handles.resize( old_handles.size() ); ErrorCode rval = mMB->tag_get_data( tag, old_handles, ( new_handles.empty() ) ? NULL : &new_handles[0] );CHKERR; Range::const_iterator it1 = old_handles.begin(); std::vector< EntityHandle >::iterator it2 = new_handles.begin(); for( ; it1 != old_handles.end(); ++it1, ++it2 ) if( 0 == *it2 ) *it2 = *it1; return MB_SUCCESS; }
ErrorCode moab::ReorderTool::get_reordered_handles | ( | Tag | tag, |
const std::vector< EntityHandle > & | old_handles, | ||
std::vector< EntityHandle > & | new_handles | ||
) | [private] |
Get new handles corresponding to old handles.
tag | Tag containing old->new mapping |
Definition at line 351 of file ReorderTool.cpp.
References get_reordered_handles().
{ new_handles.resize( old_handles.size() ); return get_reordered_handles( tag, &old_handles[0], &new_handles[0], old_handles.size() ); }
ErrorCode moab::ReorderTool::get_reordered_handles | ( | Tag | tag, |
const EntityHandle * | old_handles, | ||
EntityHandle * | new_handles, | ||
size_t | num_handles | ||
) | [private] |
Get new handles corresponding to old handles.
tag | Tag containing old->new mapping |
Definition at line 359 of file ReorderTool.cpp.
References CHKERR, ErrorCode, MB_SUCCESS, mMB, and moab::Core::tag_get_data().
{ ErrorCode rval = mMB->tag_get_data( tag, old_handles, num_handles, new_handles );CHKERR; for( size_t i = 0; i < num_handles; ++i ) if( 0 == new_handles[i] ) new_handles[i] = old_handles[i]; return MB_SUCCESS; }
ErrorCode moab::ReorderTool::handle_order_from_int_tag | ( | Tag | ordering_tag, |
int | ordering_tag_skip_value, | ||
Tag & | new_handle_tag_out | ||
) |
Calculate new handle order by tag value.
Given a tag containing integer values, calculate new order for entities in the database (except entity sets) such that all entities with tag value A occur before all entities with tag value B in the handle space where A < B. Ordering will be stable for entities with the same tag value.
ordering_tag | Sinlge integer tag, where value on each entity determines the new position in the handle ordering. Entities may have duplicate values. |
ordering_tag_skip_value | Do not reorder entities with this tag value. This is typically the default value of ordering_tag. Specifying this limits the re-ordering to only those entities for which ordering_tag has been set. |
new_handle_tag_out | Passed back new tag handle containing the entity mapping. The returned tag will be anonymous. The caller is responsible for releasing the tag. The value of this tag on each handle is the new handle that the entity will will be moved to. The tag value will be zero for entities that were not re-ordered. |
Definition at line 59 of file ReorderTool.cpp.
References moab::TypeSequenceManager::begin(), moab::check_tag_type(), CHKERR, moab::TypeSequenceManager::end(), moab::SequenceManager::entity_map(), moab::error(), ErrorCode, MB_SUCCESS, MB_TAG_CREAT, MB_TAG_DENSE, MB_TAG_EXCL, MB_TYPE_HANDLE, MB_TYPE_INTEGER, MBENTITYSET, MBVERTEX, mMB, moab::Core::sequence_manager(), t, moab::Core::tag_delete(), moab::Core::tag_get_handle(), and moab::EntitySequence::values_per_entity().
Referenced by call_reorder(), handle_order_from_sets_and_adj(), and main().
{ ErrorCode rval; // check that input tag handles are what we expect rval = check_tag_type( mMB, tag, MB_TYPE_INTEGER, sizeof( int ) );CHKERR; EntityHandle zero = 0; rval = mMB->tag_get_handle( 0, 1, MB_TYPE_HANDLE, new_handles, MB_TAG_DENSE | MB_TAG_CREAT | MB_TAG_EXCL, &zero );CHKERR; // Can only reorder within same type/connectivity (or vertex/num_coords) // groupings. Call helper function for each such grouping. for( EntityType t = MBVERTEX; t < MBENTITYSET; ++t ) { // Get list of all connectivity lengths (or vertex dimensions) // that exist for type t. TypeSequenceManager& seqs = mMB->sequence_manager()->entity_map( t ); TypeSequenceManager::iterator i; std::set< int > values; for( i = seqs.begin(); i != seqs.end(); ++i ) { EntitySequence* seq = *i; // 0 values per entity implies structured data, which // we cannot reorder. Skip those. if( t == MBVERTEX || 0 < seq->values_per_entity() ) values.insert( seq->values_per_entity() ); } // Call helper function for each (type,size) tuple. std::set< int >::iterator j; for( j = values.begin(); j != values.end(); ++j ) { rval = handle_order_from_int_tag( t, *j, tag, skip_value, new_handles ); if( MB_SUCCESS != rval ) { mMB->tag_delete( new_handles ); return error( rval ); } } } return MB_SUCCESS; }
ErrorCode moab::ReorderTool::handle_order_from_int_tag | ( | EntityType | type, |
int | vals_per_ent, | ||
Tag | ordering_tag, | ||
int | ordering_tag_skip_value, | ||
Tag | new_handle_tag | ||
) |
Calculate new handle order by tag value.
Given a tag containing integer values, calculate new order for entities in the database (except entity sets) such that all entities with tag value A occur before all entities with tag value B in the handle space where A < B. Ordering will be stable for entities with the same tag value.
type | Entity type for which to calculate re-ordering. |
vals_per_ent | Zero for vertices. Connectivity length for elements. |
ordering_tag | Sinlge integer tag, where value on each entity determines the new position in the handle ordering. Entities may have duplicate values. |
ordering_tag_skip_value | Do not reorder entities with this tag value. This is typically the default value of ordering_tag. Specifying this limits the re-ordering to only those entities for which ordering_tag has been set. |
new_handle_tag | Tag into which to store new handle for each entity. Tag must be defined to store a single entity handle and must have a default value of zero. |
Definition at line 115 of file ReorderTool.cpp.
References moab::Range::begin(), moab::check_tag_type(), CHKERR, moab::Range::end(), entities, moab::Range::erase(), ErrorCode, get_entities(), MB_SUCCESS, MB_TYPE_HANDLE, MB_TYPE_INTEGER, mMB, moab::Range::size(), moab::Core::tag_get_data(), and moab::Core::tag_set_data().
{ ErrorCode rval; // check that input tag handles are what we expect rval = check_tag_type( mMB, tag, MB_TYPE_INTEGER, sizeof( int ) );CHKERR; rval = check_tag_type( mMB, new_handles, MB_TYPE_HANDLE, sizeof( EntityHandle ) );CHKERR; // get entities to re-order Range entities; get_entities( t, vals_per_ent, entities ); // get entity order values std::vector< int > sortvals( entities.size() ); rval = mMB->tag_get_data( tag, entities, &sortvals[0] );CHKERR; // remove any entities for which value is skip_value size_t r = 0, w = 0; for( Range::iterator i = entities.begin(); i != entities.end(); ++r ) { if( sortvals[r] == skip_value ) i = entities.erase( i ); else { sortvals[w++] = sortvals[r]; ++i; } } sortvals.resize( w ); // sort std::sort( sortvals.begin(), sortvals.end() ); // Convert to unique list and offsets for each value // When done, sortvals will contain unique, sortvals and // offsets will contain, for each unique value in sortvals, // the number of values that occured in the non-unique list // before the first instance of that value. std::vector< size_t > offsets; offsets.push_back( 0 ); offsets.push_back( 1 ); for( w = 0, r = 1; r < sortvals.size(); ++r ) { if( sortvals[r] == sortvals[w] ) { ++offsets.back(); } else { ++w; sortvals[w] = sortvals[r]; offsets.push_back( offsets.back() + 1 ); } } ++w; assert( w + 1 == offsets.size() ); sortvals.resize( w ); // Tag each entity with its new handle for( Range::iterator i = entities.begin(); i != entities.end(); ++i ) { int val; rval = mMB->tag_get_data( tag, &*i, 1, &val );CHKERR; w = std::lower_bound( sortvals.begin(), sortvals.end(), val ) - sortvals.begin(); assert( w < sortvals.size() ); size_t offset = offsets[w]; ++offsets[w]; // should maybe copy range into array to avoid possibly n^2 behavior here EntityHandle h = *( entities.begin() + offset ); rval = mMB->tag_set_data( new_handles, &*i, 1, &h );CHKERR; } return MB_SUCCESS; }
ErrorCode moab::ReorderTool::handle_order_from_sets_and_adj | ( | const Range & | sets, |
Tag & | new_handle_tag_out | ||
) |
Calculate new handle order by set containment.
Given a list of sets, re-order entities such that handles are grouped contiguously by set. Will also group all adjacent mesh entities, such that entities that are are adjacent to members of two or more of the input sets will ge grouped by the combined list of sets (e.g. if the input sets contain elements then all vertices that are adjacent to only elements in the first two sets will be grouped together).
sets | Entity sets by which to group entities. |
new_handle_tag_out | Passed back new tag handle containing the entity mapping. The returned tag will be anonymous. The caller is responsible for releasing the tag. The value of this tag on each handle is the new handle that the entity will will be moved to. The tag value will be zero for entities that were not re-ordered. |
Definition at line 193 of file ReorderTool.cpp.
References moab::Range::all_of_type(), moab::error(), ErrorCode, handle_order_from_int_tag(), int_order_from_sets_and_adj(), MB_SUCCESS, MB_TAG_CREAT, MB_TAG_DENSE, MB_TAG_EXCL, MB_TYPE_INTEGER, MB_TYPE_OUT_OF_RANGE, MBENTITYSET, mMB, order_tag, moab::Core::tag_delete(), and moab::Core::tag_get_handle().
Referenced by check_order_by_sets_and_adj(), and main().
{ ErrorCode rval; if( !sets.all_of_type( MBENTITYSET ) ) return MB_TYPE_OUT_OF_RANGE; Tag order_tag; const int negone = -1; rval = mMB->tag_get_handle( 0, 1, MB_TYPE_INTEGER, order_tag, MB_TAG_DENSE | MB_TAG_CREAT | MB_TAG_EXCL, &negone ); if( MB_SUCCESS != rval ) { mMB->tag_delete( handle_tag ); handle_tag = 0; return error( rval ); } std::vector< std::vector< EntityHandle >* > data; rval = int_order_from_sets_and_adj( sets, order_tag, negone, data ); for( size_t i = 0; i < data.size(); ++i ) delete data[i]; if( MB_SUCCESS != rval ) { mMB->tag_delete( order_tag ); return error( rval ); } rval = handle_order_from_int_tag( order_tag, negone, handle_tag ); if( MB_SUCCESS != rval ) { mMB->tag_delete( order_tag ); return error( rval ); } rval = mMB->tag_delete( order_tag ); if( MB_SUCCESS != rval ) return error( rval ); return MB_SUCCESS; }
ErrorCode moab::ReorderTool::int_order_from_sets_and_adj | ( | const Range & | sets, |
Tag | order_tag, | ||
int | skip_val, | ||
std::vector< std::vector< EntityHandle > * > & | data | ||
) | [private] |
convert from input for handle_order_from_sets_and_adj
to input
for handle_order_from_int_tag
Definition at line 249 of file ReorderTool.cpp.
References moab::Range::all_of_type(), moab::Range::begin(), moab::check_tag_type(), CHKERR, moab::Range::clear(), dim, moab::Range::end(), ErrorCode, moab::Core::get_adjacencies(), moab::Core::get_entities_by_dimension(), MB_SUCCESS, MB_TYPE_INTEGER, MB_TYPE_OUT_OF_RANGE, MBENTITYSET, moab::Range::merge(), mMB, moab::Core::tag_get_data(), moab::Core::tag_set_data(), and moab::Interface::UNION.
Referenced by handle_order_from_sets_and_adj().
{ ErrorCode rval; if( !sets.all_of_type( MBENTITYSET ) ) return MB_TYPE_OUT_OF_RANGE; rval = check_tag_type( mMB, order_tag, MB_TYPE_INTEGER, sizeof( int ) );CHKERR; // Compare function to use for a map keyed on pointers to sorted vectors CompSortedVect lessthan; // Map from sorted list of handles to index std::map< std::vector< EntityHandle >*, int, CompSortedVect > forMap; std::map< std::vector< EntityHandle >*, int, CompSortedVect >::iterator fiter, fiter2; std::vector< EntityHandle > sharing; // tmp storage for entity // for each set for( Range::iterator s = sets.begin(); s != sets.end(); ++s ) { // gather up all entities and adjacencies Range tmp, ents, adj[4]; // indexed by dimension for( int dim = 0; dim < 4; ++dim ) { rval = mMB->get_entities_by_dimension( *s, dim, tmp );CHKERR; for( int ldim = 0; ldim < dim; ++ldim ) { rval = mMB->get_adjacencies( tmp, ldim, false, adj[ldim], Interface::UNION );CHKERR; } for( int udim = dim + 1; udim <= 3; ++udim ) { rval = mMB->get_adjacencies( tmp, udim, false, adj[udim], Interface::UNION );CHKERR; } ents.merge( tmp ); tmp.clear(); } for( int dim = 0; dim < 4; ++dim ) { ents.merge( adj[dim] ); adj[dim].clear(); } // process each entity for( Range::iterator e = ents.begin(); e != ents.end(); ++e ) { int val; rval = mMB->tag_get_data( order_tag, &*e, 1, &val );CHKERR; // If this entity is already in one or more of the sets (either // directly or through adjacency) then get the existing list of // sets and append this set handle (we are iterating over sets // in sorted order, so appending should aways maintain a sorted // list.) sharing.clear(); if( val != skip_val ) { sharing = *revMap[val]; assert( std::lower_bound( sharing.begin(), sharing.end(), *s ) == sharing.end() ); } sharing.push_back( *s ); // Check if new sharing list already exists in forward map fiter = forMap.lower_bound( &sharing ); if( fiter == forMap.end() || lessthan( fiter->first, &sharing ) ) { // Add new sharing list to forward and reverse maps. std::vector< EntityHandle >* newvec = new std::vector< EntityHandle >; newvec->swap( sharing ); if( (int)revMap.size() == skip_val ) revMap.push_back( 0 ); fiter2 = forMap.insert( fiter, std::pair< std::vector< EntityHandle >*, int >( newvec, revMap.size() ) ); assert( fiter2 != fiter ); fiter = fiter2; revMap.push_back( newvec ); } // Update index on entity val = fiter->second; rval = mMB->tag_set_data( order_tag, &*e, 1, &val );CHKERR; } } return MB_SUCCESS; }
ErrorCode moab::ReorderTool::reorder_entities | ( | Tag | new_handle_tag | ) |
Do the re-ordering indicated by the passed handle tag.
The specified re-ordering must be a permutation. Each existing entity must be moved to a new, existing handle such that no two entities are moved to the same new handle.
Given a tag storing handles that define a permution, apply the described re-ordering. The passed tag must contain one entity handle per entity. The value of the tag must be zero for all entities that are not to be re-ordered. For entities to be re-ordered, the tag must contain the new handle that the entity is to be moved to. No two entities may have the same value for this tag (other than a value of zero.)
new_handle_tag | Tag containing new handles for entities to reorder. Typically the output of handle_order_from_int_tag or similar. |
Definition at line 399 of file ReorderTool.cpp.
References moab::TypeSequenceManager::begin(), moab::Range::begin(), moab::check_tag_type(), CHKERR, moab::TypeSequenceManager::end(), moab::Range::end(), entities, moab::SequenceManager::entity_map(), moab::error(), ErrorCode, moab::Core::get_connectivity(), moab::Core::get_coords(), get_entities(), get_reordered_handles(), MB_INDEX_OUT_OF_RANGE, MB_SUCCESS, MB_TYPE_HANDLE, MBENTITYSET, MBVERTEX, mMB, reorder_tag_data(), moab::Core::sequence_manager(), moab::Core::set_connectivity(), moab::Core::set_coords(), moab::Range::size(), t, moab::Core::tag_get_default_value(), moab::Core::tag_get_tags(), UNRECOVERABLE, update_set_contents(), and moab::EntitySequence::values_per_entity().
Referenced by call_reorder(), and main().
{ ErrorCode rval; rval = check_tag_type( mMB, new_handles, MB_TYPE_HANDLE, sizeof( EntityHandle ) );CHKERR; EntityHandle defval; rval = mMB->tag_get_default_value( new_handles, &defval );CHKERR; if( 0 != defval ) return error( MB_INDEX_OUT_OF_RANGE ); // Can only reorder within same type/connectivity (or vertex/num_coords) // groupings. for( EntityType t = MBVERTEX; t < MBENTITYSET; ++t ) { // Get list of all connectivity lengths (or vertex dimensions) // that exist for type t. TypeSequenceManager& seqs = mMB->sequence_manager()->entity_map( t ); TypeSequenceManager::iterator i; std::set< int > values; for( i = seqs.begin(); i != seqs.end(); ++i ) { EntitySequence* seq = *i; // 0 values per entity implies structured data, which // we cannot reorder. Skip those. if( t == MBVERTEX || 0 < seq->values_per_entity() ) values.insert( seq->values_per_entity() ); } // reorder primary data for each (type,size) tuple. std::set< int >::iterator j; for( j = values.begin(); j != values.end(); ++j ) { Range entities; get_entities( t, *j, entities ); std::vector< EntityHandle > handles; rval = get_reordered_handles( new_handles, entities, handles ); UNRECOVERABLE( rval ); if( t == MBVERTEX ) { std::vector< double > coords( entities.size() * 3 ); rval = mMB->get_coords( entities, &coords[0] ); UNRECOVERABLE( rval ); rval = mMB->set_coords( &handles[0], handles.size(), &coords[0] ); UNRECOVERABLE( rval ); } else { std::vector< EntityHandle > conn; conn.reserve( entities.size() * *j ); std::vector< EntityHandle > old_handles; old_handles.resize( entities.size() ); std::copy( entities.begin(), entities.end(), old_handles.begin() ); rval = mMB->get_connectivity( &old_handles[0], old_handles.size(), conn, false ); UNRECOVERABLE( rval ); old_handles.clear(); old_handles = conn; rval = get_reordered_handles( new_handles, old_handles, conn ); UNRECOVERABLE( rval ); for( unsigned int h = 0; h < handles.size(); ++h ) { rval = mMB->set_connectivity( handles[h], &conn[h * *j], *j ); UNRECOVERABLE( rval ); } } } } // now update tag data std::vector< Tag > tag_handles; mMB->tag_get_tags( tag_handles ); for( size_t i = 0; i < tag_handles.size(); ++i ) { Tag tag = tag_handles[i]; if( tag == new_handles ) // don't mess up mapping from old to new handles continue; for( EntityType t = MBVERTEX; t <= MBENTITYSET; ++t ) { rval = reorder_tag_data( t, new_handles, tag ); UNRECOVERABLE( rval ); } } rval = update_set_contents( new_handles ); UNRECOVERABLE( rval ); return MB_SUCCESS; }
ErrorCode moab::ReorderTool::reorder_tag_data | ( | EntityType | type, |
Tag | new_handles, | ||
Tag | reorder_tag | ||
) | [private] |
helper function for reorder_entities
Reorder tag data for all entities of specified type.
Also updates tag values for MB_TYPE_HANDLE tags.
type | Entity type to reorder |
new_handles | Tag containing old->new handle mapping |
reorder_tag | The tag data to reorder |
Definition at line 487 of file ReorderTool.cpp.
References moab::Range::begin(), buffer, CHKERR, moab::Range::empty(), moab::Range::end(), moab::Range::erase(), moab::error(), ErrorCode, moab::Core::get_entities_by_type_and_tag(), get_new_handles(), get_reordered_handles(), MB_SUCCESS, MB_TYPE_BIT, MB_TYPE_DOUBLE, MB_TYPE_HANDLE, MB_TYPE_INTEGER, MB_TYPE_OPAQUE, MB_TYPE_OUT_OF_RANGE, MB_VARIABLE_DATA_LENGTH, MBENTITYSET, mMB, moab::Range::size(), sizes, moab::Core::tag_delete_data(), moab::Core::tag_get_by_ptr(), moab::Core::tag_get_bytes(), moab::Core::tag_get_data(), moab::Core::tag_get_data_type(), moab::Core::tag_set_by_ptr(), and moab::Core::tag_set_data().
Referenced by reorder_entities().
{ ErrorCode rval; int tagsize; DataType tagtype; rval = mMB->tag_get_data_type( tag, tagtype ); if( MB_SUCCESS != rval ) return error( rval ); if( MB_TYPE_BIT == tagtype ) tagsize = 1; else { rval = mMB->tag_get_bytes( tag, tagsize ); if( MB_VARIABLE_DATA_LENGTH == rval ) tagsize = -1; else if( MB_SUCCESS != rval ) return error( rval ); } // we don't re-order set handles, so we don't care about sets // unless the tag contains handles that need to be updated if( MBENTITYSET == etype && MB_TYPE_HANDLE != tagtype ) return MB_SUCCESS; // get tagged entities Range old_tagged; rval = mMB->get_entities_by_type_and_tag( 0, etype, &tag, 0, 1, old_tagged ); if( MB_SUCCESS != rval && old_tagged.empty() ) return error( rval ); // remove entities that were not reordered, unless the tag // is handle type in which case we need to update the data // for all entities, regardless of reordering. std::vector< EntityHandle > newhandles; if( MB_TYPE_HANDLE == tagtype ) rval = get_reordered_handles( new_handles, old_tagged, newhandles ); else rval = get_new_handles( new_handles, old_tagged, newhandles );CHKERR; if( old_tagged.empty() ) return MB_SUCCESS; // get copy of all tag data std::vector< unsigned char > buffer; std::vector< const void* > pointers; std::vector< int > sizes; // if variable-length tag if( -1 == tagsize ) { pointers.resize( old_tagged.size() ); sizes.resize( pointers.size() ); rval = mMB->tag_get_by_ptr( tag, old_tagged, &pointers[0], &sizes[0] );CHKERR; int total = std::accumulate( sizes.begin(), sizes.end(), 0 ); DataType dtype; mMB->tag_get_data_type( tag, dtype ); int type_size; switch( dtype ) { case MB_TYPE_INTEGER: type_size = sizeof( int ); break; case MB_TYPE_DOUBLE: type_size = sizeof( double ); break; case MB_TYPE_HANDLE: type_size = sizeof( EntityHandle ); break; case MB_TYPE_BIT: type_size = 1; break; case MB_TYPE_OPAQUE: type_size = 1; break; default: return MB_TYPE_OUT_OF_RANGE; } buffer.resize( total * type_size ); size_t off = 0; for( size_t j = 0; j < pointers.size(); ++j ) { memcpy( &buffer[off], pointers[j], type_size * sizes[j] ); pointers[j] = &buffer[off]; off += sizes[j] * type_size; } } // if fixed-length tag else { buffer.resize( old_tagged.size() * tagsize ); rval = mMB->tag_get_data( tag, old_tagged, &buffer[0] );CHKERR; } // if handle tag, update tag values for reordered handles if( MB_TYPE_HANDLE == tagtype ) { assert( !( buffer.size() % sizeof( EntityHandle ) ) ); std::vector< unsigned char > buffer2( buffer.size() ); rval = get_reordered_handles( new_handles, reinterpret_cast< const EntityHandle* >( &buffer[0] ), reinterpret_cast< EntityHandle* >( &buffer2[0] ), buffer.size() / sizeof( EntityHandle ) );CHKERR; // if var-length tag then do not do swap because pointers[] contains pointers // into old buffer if( -1 == tagsize ) memcpy( &buffer[0], &buffer2[0], buffer.size() ); else buffer.swap( buffer2 ); } // store re-ordered tag data if( -1 == tagsize ) { rval = mMB->tag_set_by_ptr( tag, &newhandles[0], newhandles.size(), &pointers[0], &sizes[0] ); pointers.clear(); sizes.clear(); buffer.clear(); } else { rval = mMB->tag_set_data( tag, &newhandles[0], newhandles.size(), &buffer[0] ); buffer.clear(); } CHKERR; // all permutations should be cyclical, but not all permuted // entities necessarily had tag values, so we might need to delete // tags for some entities std::sort( newhandles.begin(), newhandles.end() ); std::vector< EntityHandle >::iterator k = newhandles.begin(); Range::iterator i = old_tagged.begin(); while( i != old_tagged.end() ) { while( k != newhandles.end() && *k < *i ) ++k; if( k == newhandles.end() ) break; if( *i == *k ) // what old_tagged -= newhandles i = old_tagged.erase( i ); else ++i; } if( !old_tagged.empty() ) { rval = mMB->tag_delete_data( tag, old_tagged );CHKERR; } return MB_SUCCESS; }
ErrorCode moab::ReorderTool::update_set_contents | ( | Tag | new_handles | ) | [private] |
helper function for reorder_entities
Update set contents for changed handles.
new_handles | Tag containing old->new handle mapping |
Definition at line 633 of file ReorderTool.cpp.
References moab::Core::add_entities(), moab::Range::begin(), CHKERR, moab::Core::clear_meshset(), moab::Range::empty(), moab::Range::end(), ErrorCode, moab::Core::get_entities_by_handle(), moab::Core::get_entities_by_type(), moab::Core::get_meshset_options(), get_new_handles(), get_reordered_handles(), moab::Range::insert(), moab::intersect(), MB_SUCCESS, MBENTITYSET, mMB, moab::Core::remove_entities(), and moab::Range::size().
Referenced by reorder_entities().
{ Range sets; ErrorCode rval = mMB->get_entities_by_type( 0, MBENTITYSET, sets );CHKERR; std::vector< EntityHandle > old_handles, new_handles; for( Range::iterator i = sets.begin(); i != sets.end(); ++i ) { // If set is un-ordered... unsigned opts = 0; mMB->get_meshset_options( *i, opts ); if( !( opts & MESHSET_ORDERED ) ) { Range contents; rval = mMB->get_entities_by_handle( *i, contents );CHKERR; rval = get_new_handles( nh_tag, contents, new_handles );CHKERR; Range replace; std::sort( new_handles.begin(), new_handles.end() ); Range::iterator hint = replace.begin(); for( size_t j = 0; j < new_handles.size(); ++j ) hint = replace.insert( hint, new_handles[j] ); Range common = intersect( contents, replace ); contents -= common; replace -= common; assert( contents.size() == replace.size() ); if( !contents.empty() ) { rval = mMB->remove_entities( *i, contents );CHKERR; rval = mMB->add_entities( *i, replace ); } } // If set is ordered... else { // get set contents old_handles.clear(); rval = mMB->get_entities_by_handle( *i, old_handles );CHKERR; // get new handles from old contained handles rval = get_reordered_handles( nh_tag, old_handles, new_handles );CHKERR; rval = mMB->clear_meshset( &*i, 1 );CHKERR; rval = mMB->add_entities( *i, &new_handles[0], new_handles.size() );CHKERR; } } // for each set return MB_SUCCESS; }
Core* moab::ReorderTool::mMB [private] |
Definition at line 178 of file ReorderTool.hpp.
Referenced by get_entities(), get_new_handles(), get_reordered_handles(), handle_order_from_int_tag(), handle_order_from_sets_and_adj(), int_order_from_sets_and_adj(), reorder_entities(), reorder_tag_data(), and update_set_contents().