MOAB: Mesh Oriented datABase  (version 5.4.0)
ReorderTool.cpp
Go to the documentation of this file.
00001 /** \file   ReorderTool.cpp
00002  *  \author Jason Kraftcheck
00003  *  \date   2011-05-23
00004  */
00005 
00006 #include "moab/ReorderTool.hpp"
00007 #include "moab/Core.hpp"
00008 #include "moab/Range.hpp"
00009 
00010 #include "SequenceManager.hpp"
00011 #include "TypeSequenceManager.hpp"
00012 #include "EntitySequence.hpp"
00013 
00014 #include <algorithm>
00015 #include <numeric>
00016 #include <set>
00017 #include <iostream>
00018 
00019 namespace moab
00020 {
00021 
00022 // no-op function as a convenient spot to set a breakpoint
00023 static inline ErrorCode error( ErrorCode val )
00024 {
00025     return val;
00026 }
00027 
00028 #define CHKERR \
00029     if( MB_SUCCESS != rval ) return error( rval )
00030 
00031 #define UNRECOVERABLE( ERRCODE )                                                                             \
00032     do                                                                                                       \
00033     {                                                                                                        \
00034         if( MB_SUCCESS != ( ERRCODE ) )                                                                      \
00035         {                                                                                                    \
00036             error( ( ERRCODE ) );                                                                            \
00037             std::cerr << "Unreconverable error during mesh reorder." << std::endl                            \
00038                       << "Error Code " << ( ERRCODE ) << " at " << __FILE__ << ":" << __LINE__ << std::endl; \
00039             std::cerr.flush();                                                                               \
00040             abort();                                                                                         \
00041         }                                                                                                    \
00042     } while( false )
00043 
00044 static ErrorCode check_tag_type( Interface* moab, Tag tag, DataType exp_type, int exp_size )
00045 {
00046     ErrorCode rval;
00047     DataType act_type;
00048     int act_size;
00049 
00050     rval = moab->tag_get_data_type( tag, act_type );CHKERR;
00051 
00052     rval = moab->tag_get_bytes( tag, act_size );CHKERR;
00053 
00054     if( act_type != exp_type || act_size != exp_size ) return MB_TYPE_OUT_OF_RANGE;
00055 
00056     return MB_SUCCESS;
00057 }
00058 
00059 ErrorCode ReorderTool::handle_order_from_int_tag( Tag tag, int skip_value, Tag& new_handles )
00060 {
00061     ErrorCode rval;
00062 
00063     // check that input tag handles are what we expect
00064     rval = check_tag_type( mMB, tag, MB_TYPE_INTEGER, sizeof( int ) );CHKERR;
00065     EntityHandle zero = 0;
00066     rval = mMB->tag_get_handle( 0, 1, MB_TYPE_HANDLE, new_handles, MB_TAG_DENSE | MB_TAG_CREAT | MB_TAG_EXCL, &zero );CHKERR;
00067 
00068     // Can only reorder within same type/connectivity (or vertex/num_coords)
00069     // groupings.  Call helper function for each such grouping.
00070     for( EntityType t = MBVERTEX; t < MBENTITYSET; ++t )
00071     {
00072         // Get list of all connectivity lengths (or vertex dimensions)
00073         // that exist for type t.
00074         TypeSequenceManager& seqs = mMB->sequence_manager()->entity_map( t );
00075         TypeSequenceManager::iterator i;
00076         std::set< int > values;
00077         for( i = seqs.begin(); i != seqs.end(); ++i )
00078         {
00079             EntitySequence* seq = *i;
00080             // 0 values per entity implies structured data, which
00081             // we cannot reorder.  Skip those.
00082             if( t == MBVERTEX || 0 < seq->values_per_entity() ) values.insert( seq->values_per_entity() );
00083         }
00084 
00085         // Call helper function for each (type,size) tuple.
00086         std::set< int >::iterator j;
00087         for( j = values.begin(); j != values.end(); ++j )
00088         {
00089             rval = handle_order_from_int_tag( t, *j, tag, skip_value, new_handles );
00090             if( MB_SUCCESS != rval )
00091             {
00092                 mMB->tag_delete( new_handles );
00093                 return error( rval );
00094             }
00095         }
00096     }
00097 
00098     return MB_SUCCESS;
00099 }
00100 
00101 void ReorderTool::get_entities( EntityType t, int vals_per_ent, Range& entities )
00102 {
00103     Range::iterator hint = entities.begin();
00104     ;
00105     TypeSequenceManager& seqs = mMB->sequence_manager()->entity_map( t );
00106     TypeSequenceManager::iterator s;
00107     for( s = seqs.begin(); s != seqs.end(); ++s )
00108     {
00109         EntitySequence* seq = *s;
00110         if( seq->values_per_entity() == vals_per_ent )
00111             hint = entities.insert( hint, seq->start_handle(), seq->end_handle() );
00112     }
00113 }
00114 
00115 ErrorCode ReorderTool::handle_order_from_int_tag( EntityType t,
00116                                                   int vals_per_ent,
00117                                                   Tag tag,
00118                                                   int skip_value,
00119                                                   Tag new_handles )
00120 {
00121     ErrorCode rval;
00122 
00123     // check that input tag handles are what we expect
00124     rval = check_tag_type( mMB, tag, MB_TYPE_INTEGER, sizeof( int ) );CHKERR;
00125     rval = check_tag_type( mMB, new_handles, MB_TYPE_HANDLE, sizeof( EntityHandle ) );CHKERR;
00126 
00127     // get entities to re-order
00128     Range entities;
00129     get_entities( t, vals_per_ent, entities );
00130 
00131     // get entity order values
00132     std::vector< int > sortvals( entities.size() );
00133     rval = mMB->tag_get_data( tag, entities, &sortvals[0] );CHKERR;
00134 
00135     // remove any entities for which value is skip_value
00136     size_t r = 0, w = 0;
00137     for( Range::iterator i = entities.begin(); i != entities.end(); ++r )
00138     {
00139         if( sortvals[r] == skip_value )
00140             i = entities.erase( i );
00141         else
00142         {
00143             sortvals[w++] = sortvals[r];
00144             ++i;
00145         }
00146     }
00147     sortvals.resize( w );
00148 
00149     // sort
00150     std::sort( sortvals.begin(), sortvals.end() );
00151     // Convert to unique list and offsets for each value
00152     // When done, sortvals will contain unique, sortvals and
00153     // offsets will contain, for each unique value in sortvals,
00154     // the number of values that occured in the non-unique list
00155     // before the first instance of that value.
00156     std::vector< size_t > offsets;
00157     offsets.push_back( 0 );
00158     offsets.push_back( 1 );
00159     for( w = 0, r = 1; r < sortvals.size(); ++r )
00160     {
00161         if( sortvals[r] == sortvals[w] )
00162         {
00163             ++offsets.back();
00164         }
00165         else
00166         {
00167             ++w;
00168             sortvals[w] = sortvals[r];
00169             offsets.push_back( offsets.back() + 1 );
00170         }
00171     }
00172     ++w;
00173     assert( w + 1 == offsets.size() );
00174     sortvals.resize( w );
00175 
00176     // Tag each entity with its new handle
00177     for( Range::iterator i = entities.begin(); i != entities.end(); ++i )
00178     {
00179         int val;
00180         rval = mMB->tag_get_data( tag, &*i, 1, &val );CHKERR;
00181         w = std::lower_bound( sortvals.begin(), sortvals.end(), val ) - sortvals.begin();
00182         assert( w < sortvals.size() );
00183         size_t offset = offsets[w];
00184         ++offsets[w];
00185         // should maybe copy range into array to avoid possibly n^2 behavior here
00186         EntityHandle h = *( entities.begin() + offset );
00187         rval           = mMB->tag_set_data( new_handles, &*i, 1, &h );CHKERR;
00188     }
00189 
00190     return MB_SUCCESS;
00191 }
00192 
00193 ErrorCode ReorderTool::handle_order_from_sets_and_adj( const Range& sets, Tag& handle_tag )
00194 {
00195     ErrorCode rval;
00196 
00197     if( !sets.all_of_type( MBENTITYSET ) ) return MB_TYPE_OUT_OF_RANGE;
00198 
00199     Tag order_tag;
00200     const int negone = -1;
00201     rval = mMB->tag_get_handle( 0, 1, MB_TYPE_INTEGER, order_tag, MB_TAG_DENSE | MB_TAG_CREAT | MB_TAG_EXCL, &negone );
00202     if( MB_SUCCESS != rval )
00203     {
00204         mMB->tag_delete( handle_tag );
00205         handle_tag = 0;
00206         return error( rval );
00207     }
00208 
00209     std::vector< std::vector< EntityHandle >* > data;
00210     rval = int_order_from_sets_and_adj( sets, order_tag, negone, data );
00211     for( size_t i = 0; i < data.size(); ++i )
00212         delete data[i];
00213     if( MB_SUCCESS != rval )
00214     {
00215         mMB->tag_delete( order_tag );
00216         return error( rval );
00217     }
00218 
00219     rval = handle_order_from_int_tag( order_tag, negone, handle_tag );
00220     if( MB_SUCCESS != rval )
00221     {
00222         mMB->tag_delete( order_tag );
00223         return error( rval );
00224     }
00225 
00226     rval = mMB->tag_delete( order_tag );
00227     if( MB_SUCCESS != rval ) return error( rval );
00228 
00229     return MB_SUCCESS;
00230 }
00231 
00232 // Compare function to use for a map keyed on pointers to sorted vectors
00233 struct CompSortedVect
00234 {
00235     bool operator()( const std::vector< EntityHandle >* v1, const std::vector< EntityHandle >* v2 ) const
00236     {
00237         std::vector< EntityHandle >::const_iterator i1, i2;
00238         for( i1 = v1->begin(), i2 = v2->begin(); i1 != v1->end(); ++i1, ++i2 )
00239         {
00240             if( i2 == v2->end() || *i1 > *i2 )
00241                 return false;
00242             else if( *i1 < *i2 )
00243                 return true;
00244         }
00245         return i2 != v2->end();
00246     }
00247 };
00248 
00249 ErrorCode ReorderTool::int_order_from_sets_and_adj( const Range& sets,
00250                                                     Tag order_tag,
00251                                                     int skip_val,
00252                                                     std::vector< std::vector< EntityHandle >* >& revMap )
00253 {
00254     ErrorCode rval;
00255 
00256     if( !sets.all_of_type( MBENTITYSET ) ) return MB_TYPE_OUT_OF_RANGE;
00257 
00258     rval = check_tag_type( mMB, order_tag, MB_TYPE_INTEGER, sizeof( int ) );CHKERR;
00259 
00260     // Compare function to use for a map keyed on pointers to sorted vectors
00261     CompSortedVect lessthan;
00262     // Map from sorted list of handles to index
00263     std::map< std::vector< EntityHandle >*, int, CompSortedVect > forMap;
00264     std::map< std::vector< EntityHandle >*, int, CompSortedVect >::iterator fiter, fiter2;
00265     std::vector< EntityHandle > sharing;  // tmp storage for entity
00266 
00267     // for each set
00268     for( Range::iterator s = sets.begin(); s != sets.end(); ++s )
00269     {
00270 
00271         // gather up all entities and adjacencies
00272         Range tmp, ents, adj[4];  // indexed by dimension
00273         for( int dim = 0; dim < 4; ++dim )
00274         {
00275             rval = mMB->get_entities_by_dimension( *s, dim, tmp );CHKERR;
00276             for( int ldim = 0; ldim < dim; ++ldim )
00277             {
00278                 rval = mMB->get_adjacencies( tmp, ldim, false, adj[ldim], Interface::UNION );CHKERR;
00279             }
00280             for( int udim = dim + 1; udim <= 3; ++udim )
00281             {
00282                 rval = mMB->get_adjacencies( tmp, udim, false, adj[udim], Interface::UNION );CHKERR;
00283             }
00284             ents.merge( tmp );
00285             tmp.clear();
00286         }
00287         for( int dim = 0; dim < 4; ++dim )
00288         {
00289             ents.merge( adj[dim] );
00290             adj[dim].clear();
00291         }
00292 
00293         // process each entity
00294         for( Range::iterator e = ents.begin(); e != ents.end(); ++e )
00295         {
00296             int val;
00297             rval = mMB->tag_get_data( order_tag, &*e, 1, &val );CHKERR;
00298 
00299             // If this entity is already in one or more of the sets (either
00300             // directly or through adjacency) then get the existing list of
00301             // sets and append this set handle (we are iterating over sets
00302             // in sorted order, so appending should aways maintain a sorted
00303             // list.)
00304             sharing.clear();
00305             if( val != skip_val )
00306             {
00307                 sharing = *revMap[val];
00308                 assert( std::lower_bound( sharing.begin(), sharing.end(), *s ) == sharing.end() );
00309             }
00310             sharing.push_back( *s );
00311 
00312             // Check if new sharing list already exists in forward map
00313             fiter = forMap.lower_bound( &sharing );
00314             if( fiter == forMap.end() || lessthan( fiter->first, &sharing ) )
00315             {
00316                 // Add new sharing list to forward and reverse maps.
00317                 std::vector< EntityHandle >* newvec = new std::vector< EntityHandle >;
00318                 newvec->swap( sharing );
00319                 if( (int)revMap.size() == skip_val ) revMap.push_back( 0 );
00320                 fiter2 =
00321                     forMap.insert( fiter, std::pair< std::vector< EntityHandle >*, int >( newvec, revMap.size() ) );
00322                 assert( fiter2 != fiter );
00323                 fiter = fiter2;
00324                 revMap.push_back( newvec );
00325             }
00326 
00327             // Update index on entity
00328             val  = fiter->second;
00329             rval = mMB->tag_set_data( order_tag, &*e, 1, &val );CHKERR;
00330         }
00331     }
00332 
00333     return MB_SUCCESS;
00334 }
00335 
00336 ErrorCode ReorderTool::get_reordered_handles( Tag tag,
00337                                               const Range& old_handles,
00338                                               std::vector< EntityHandle >& new_handles )
00339 {
00340     new_handles.resize( old_handles.size() );
00341     ErrorCode rval = mMB->tag_get_data( tag, old_handles, ( new_handles.empty() ) ? NULL : &new_handles[0] );CHKERR;
00342 
00343     Range::const_iterator it1                 = old_handles.begin();
00344     std::vector< EntityHandle >::iterator it2 = new_handles.begin();
00345     for( ; it1 != old_handles.end(); ++it1, ++it2 )
00346         if( 0 == *it2 ) *it2 = *it1;
00347 
00348     return MB_SUCCESS;
00349 }
00350 
00351 ErrorCode ReorderTool::get_reordered_handles( Tag tag,
00352                                               const std::vector< EntityHandle >& old_handles,
00353                                               std::vector< EntityHandle >& new_handles )
00354 {
00355     new_handles.resize( old_handles.size() );
00356     return get_reordered_handles( tag, &old_handles[0], &new_handles[0], old_handles.size() );
00357 }
00358 
00359 ErrorCode ReorderTool::get_reordered_handles( Tag tag,
00360                                               const EntityHandle* old_handles,
00361                                               EntityHandle* new_handles,
00362                                               size_t num_handles )
00363 {
00364     ErrorCode rval = mMB->tag_get_data( tag, old_handles, num_handles, new_handles );CHKERR;
00365 
00366     for( size_t i = 0; i < num_handles; ++i )
00367         if( 0 == new_handles[i] ) new_handles[i] = old_handles[i];
00368 
00369     return MB_SUCCESS;
00370 }
00371 
00372 ErrorCode ReorderTool::get_new_handles( Tag tag, Range& old_handles, std::vector< EntityHandle >& newhandles )
00373 {
00374     // get new handles for tagged entities
00375     newhandles.resize( old_handles.size() );
00376     ErrorCode rval = mMB->tag_get_data( tag, old_handles, ( newhandles.empty() ) ? NULL : &newhandles[0] );CHKERR;
00377 
00378     // remove entities that were not reordered
00379     Range::iterator i = old_handles.begin();
00380     size_t w          = 0;
00381     for( size_t r = 0; r < newhandles.size(); ++r )
00382     {
00383         if( 0 != newhandles[r] )
00384         {
00385             newhandles[w] = newhandles[r];
00386             ++w;
00387             ++i;
00388         }
00389         else
00390         {
00391             i = old_handles.erase( i );
00392         }
00393     }
00394     newhandles.resize( w );
00395     assert( newhandles.size() == old_handles.size() );
00396     return MB_SUCCESS;
00397 }
00398 
00399 ErrorCode ReorderTool::reorder_entities( Tag new_handles )
00400 {
00401     ErrorCode rval;
00402 
00403     rval = check_tag_type( mMB, new_handles, MB_TYPE_HANDLE, sizeof( EntityHandle ) );CHKERR;
00404     EntityHandle defval;
00405     rval = mMB->tag_get_default_value( new_handles, &defval );CHKERR;
00406     if( 0 != defval ) return error( MB_INDEX_OUT_OF_RANGE );
00407 
00408     // Can only reorder within same type/connectivity (or vertex/num_coords)
00409     // groupings.
00410     for( EntityType t = MBVERTEX; t < MBENTITYSET; ++t )
00411     {
00412         // Get list of all connectivity lengths (or vertex dimensions)
00413         // that exist for type t.
00414         TypeSequenceManager& seqs = mMB->sequence_manager()->entity_map( t );
00415         TypeSequenceManager::iterator i;
00416         std::set< int > values;
00417         for( i = seqs.begin(); i != seqs.end(); ++i )
00418         {
00419             EntitySequence* seq = *i;
00420             // 0 values per entity implies structured data, which
00421             // we cannot reorder.  Skip those.
00422             if( t == MBVERTEX || 0 < seq->values_per_entity() ) values.insert( seq->values_per_entity() );
00423         }
00424 
00425         // reorder primary data for each (type,size) tuple.
00426         std::set< int >::iterator j;
00427         for( j = values.begin(); j != values.end(); ++j )
00428         {
00429             Range entities;
00430             get_entities( t, *j, entities );
00431             std::vector< EntityHandle > handles;
00432             rval = get_reordered_handles( new_handles, entities, handles );
00433             UNRECOVERABLE( rval );
00434 
00435             if( t == MBVERTEX )
00436             {
00437                 std::vector< double > coords( entities.size() * 3 );
00438                 rval = mMB->get_coords( entities, &coords[0] );
00439                 UNRECOVERABLE( rval );
00440                 rval = mMB->set_coords( &handles[0], handles.size(), &coords[0] );
00441                 UNRECOVERABLE( rval );
00442             }
00443             else
00444             {
00445                 std::vector< EntityHandle > conn;
00446                 conn.reserve( entities.size() * *j );
00447                 std::vector< EntityHandle > old_handles;
00448                 old_handles.resize( entities.size() );
00449                 std::copy( entities.begin(), entities.end(), old_handles.begin() );
00450                 rval = mMB->get_connectivity( &old_handles[0], old_handles.size(), conn, false );
00451                 UNRECOVERABLE( rval );
00452                 old_handles.clear();
00453                 old_handles = conn;
00454                 rval        = get_reordered_handles( new_handles, old_handles, conn );
00455                 UNRECOVERABLE( rval );
00456                 for( unsigned int h = 0; h < handles.size(); ++h )
00457                 {
00458                     rval = mMB->set_connectivity( handles[h], &conn[h * *j], *j );
00459                     UNRECOVERABLE( rval );
00460                 }
00461             }
00462         }
00463     }
00464 
00465     // now update tag data
00466     std::vector< Tag > tag_handles;
00467     mMB->tag_get_tags( tag_handles );
00468     for( size_t i = 0; i < tag_handles.size(); ++i )
00469     {
00470         Tag tag = tag_handles[i];
00471         if( tag == new_handles )  // don't mess up mapping from old to new handles
00472             continue;
00473 
00474         for( EntityType t = MBVERTEX; t <= MBENTITYSET; ++t )
00475         {
00476             rval = reorder_tag_data( t, new_handles, tag );
00477             UNRECOVERABLE( rval );
00478         }
00479     }
00480 
00481     rval = update_set_contents( new_handles );
00482     UNRECOVERABLE( rval );
00483 
00484     return MB_SUCCESS;
00485 }
00486 
00487 ErrorCode ReorderTool::reorder_tag_data( EntityType etype, Tag new_handles, Tag tag )
00488 {
00489     ErrorCode rval;
00490 
00491     int tagsize;
00492     DataType tagtype;
00493     rval = mMB->tag_get_data_type( tag, tagtype );
00494     if( MB_SUCCESS != rval ) return error( rval );
00495     if( MB_TYPE_BIT == tagtype )
00496         tagsize = 1;
00497     else
00498     {
00499         rval = mMB->tag_get_bytes( tag, tagsize );
00500         if( MB_VARIABLE_DATA_LENGTH == rval )
00501             tagsize = -1;
00502         else if( MB_SUCCESS != rval )
00503             return error( rval );
00504     }
00505 
00506     // we don't re-order set handles, so we don't care about sets
00507     // unless the tag contains handles that need to be updated
00508     if( MBENTITYSET == etype && MB_TYPE_HANDLE != tagtype ) return MB_SUCCESS;
00509 
00510     // get tagged entities
00511     Range old_tagged;
00512     rval = mMB->get_entities_by_type_and_tag( 0, etype, &tag, 0, 1, old_tagged );
00513     if( MB_SUCCESS != rval && old_tagged.empty() ) return error( rval );
00514 
00515     // remove entities that were not reordered, unless the tag
00516     // is handle type in which case we need to update the data
00517     // for all entities, regardless of reordering.
00518     std::vector< EntityHandle > newhandles;
00519     if( MB_TYPE_HANDLE == tagtype )
00520         rval = get_reordered_handles( new_handles, old_tagged, newhandles );
00521     else
00522         rval = get_new_handles( new_handles, old_tagged, newhandles );CHKERR;
00523 
00524     if( old_tagged.empty() ) return MB_SUCCESS;
00525 
00526     // get copy of all tag data
00527     std::vector< unsigned char > buffer;
00528     std::vector< const void* > pointers;
00529     std::vector< int > sizes;
00530     // if variable-length tag
00531     if( -1 == tagsize )
00532     {
00533         pointers.resize( old_tagged.size() );
00534         sizes.resize( pointers.size() );
00535         rval = mMB->tag_get_by_ptr( tag, old_tagged, &pointers[0], &sizes[0] );CHKERR;
00536         int total = std::accumulate( sizes.begin(), sizes.end(), 0 );
00537         DataType dtype;
00538         mMB->tag_get_data_type( tag, dtype );
00539         int type_size;
00540         switch( dtype )
00541         {
00542             case MB_TYPE_INTEGER:
00543                 type_size = sizeof( int );
00544                 break;
00545             case MB_TYPE_DOUBLE:
00546                 type_size = sizeof( double );
00547                 break;
00548             case MB_TYPE_HANDLE:
00549                 type_size = sizeof( EntityHandle );
00550                 break;
00551             case MB_TYPE_BIT:
00552                 type_size = 1;
00553                 break;
00554             case MB_TYPE_OPAQUE:
00555                 type_size = 1;
00556                 break;
00557             default:
00558                 return MB_TYPE_OUT_OF_RANGE;
00559         }
00560         buffer.resize( total * type_size );
00561         size_t off = 0;
00562         for( size_t j = 0; j < pointers.size(); ++j )
00563         {
00564             memcpy( &buffer[off], pointers[j], type_size * sizes[j] );
00565             pointers[j] = &buffer[off];
00566             off += sizes[j] * type_size;
00567         }
00568     }
00569     // if fixed-length tag
00570     else
00571     {
00572         buffer.resize( old_tagged.size() * tagsize );
00573         rval = mMB->tag_get_data( tag, old_tagged, &buffer[0] );CHKERR;
00574     }
00575 
00576     // if handle tag, update tag values for reordered handles
00577     if( MB_TYPE_HANDLE == tagtype )
00578     {
00579         assert( !( buffer.size() % sizeof( EntityHandle ) ) );
00580         std::vector< unsigned char > buffer2( buffer.size() );
00581         rval = get_reordered_handles( new_handles, reinterpret_cast< const EntityHandle* >( &buffer[0] ),
00582                                       reinterpret_cast< EntityHandle* >( &buffer2[0] ),
00583                                       buffer.size() / sizeof( EntityHandle ) );CHKERR;
00584         // if var-length tag then do not do swap because pointers[] contains pointers
00585         // into old buffer
00586         if( -1 == tagsize )
00587             memcpy( &buffer[0], &buffer2[0], buffer.size() );
00588         else
00589             buffer.swap( buffer2 );
00590     }
00591 
00592     // store re-ordered tag data
00593     if( -1 == tagsize )
00594     {
00595         rval = mMB->tag_set_by_ptr( tag, &newhandles[0], newhandles.size(), &pointers[0], &sizes[0] );
00596         pointers.clear();
00597         sizes.clear();
00598         buffer.clear();
00599     }
00600     else
00601     {
00602         rval = mMB->tag_set_data( tag, &newhandles[0], newhandles.size(), &buffer[0] );
00603         buffer.clear();
00604     }
00605     CHKERR;
00606 
00607     // all permutations should be cyclical, but not all permuted
00608     // entities necessarily had tag values, so we might need to delete
00609     // tags for some entities
00610     std::sort( newhandles.begin(), newhandles.end() );
00611     std::vector< EntityHandle >::iterator k = newhandles.begin();
00612     Range::iterator i                       = old_tagged.begin();
00613     while( i != old_tagged.end() )
00614     {
00615         while( k != newhandles.end() && *k < *i )
00616             ++k;
00617         if( k == newhandles.end() ) break;
00618 
00619         if( *i == *k )  // what old_tagged -= newhandles
00620             i = old_tagged.erase( i );
00621         else
00622             ++i;
00623     }
00624 
00625     if( !old_tagged.empty() )
00626     {
00627         rval = mMB->tag_delete_data( tag, old_tagged );CHKERR;
00628     }
00629 
00630     return MB_SUCCESS;
00631 }
00632 
00633 ErrorCode ReorderTool::update_set_contents( Tag nh_tag )
00634 {
00635     Range sets;
00636     ErrorCode rval = mMB->get_entities_by_type( 0, MBENTITYSET, sets );CHKERR;
00637 
00638     std::vector< EntityHandle > old_handles, new_handles;
00639     for( Range::iterator i = sets.begin(); i != sets.end(); ++i )
00640     {
00641         // If set is un-ordered...
00642         unsigned opts = 0;
00643         mMB->get_meshset_options( *i, opts );
00644         if( !( opts & MESHSET_ORDERED ) )
00645         {
00646             Range contents;
00647             rval = mMB->get_entities_by_handle( *i, contents );CHKERR;
00648 
00649             rval = get_new_handles( nh_tag, contents, new_handles );CHKERR;
00650 
00651             Range replace;
00652             std::sort( new_handles.begin(), new_handles.end() );
00653             Range::iterator hint = replace.begin();
00654             for( size_t j = 0; j < new_handles.size(); ++j )
00655                 hint = replace.insert( hint, new_handles[j] );
00656             Range common = intersect( contents, replace );
00657             contents -= common;
00658             replace -= common;
00659             assert( contents.size() == replace.size() );
00660             if( !contents.empty() )
00661             {
00662                 rval = mMB->remove_entities( *i, contents );CHKERR;
00663                 rval = mMB->add_entities( *i, replace );
00664             }
00665         }
00666 
00667         // If set is ordered...
00668         else
00669         {
00670             // get set contents
00671             old_handles.clear();
00672             rval = mMB->get_entities_by_handle( *i, old_handles );CHKERR;
00673 
00674             // get new handles from old contained handles
00675             rval = get_reordered_handles( nh_tag, old_handles, new_handles );CHKERR;
00676 
00677             rval = mMB->clear_meshset( &*i, 1 );CHKERR;
00678 
00679             rval = mMB->add_entities( *i, &new_handles[0], new_handles.size() );CHKERR;
00680         }
00681     }  // for each set
00682 
00683     return MB_SUCCESS;
00684 }
00685 
00686 }  // namespace moab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines