MOAB: Mesh Oriented datABase
(version 5.4.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, 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