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