MOAB: Mesh Oriented datABase
(version 5.2.1)
|
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