#include <ReorderTool.hpp>
Public Member Functions | |
ReorderTool (Core *moab) | |
ErrorCode | handle_order_from_int_tag (Tag ordering_tag, int ordering_tag_skip_value, Tag &new_handle_tag_out) |
Calculate new handle order by tag value. More... | |
ErrorCode | handle_order_from_int_tag (EntityType type, int vals_per_ent, Tag ordering_tag, int ordering_tag_skip_value, Tag new_handle_tag) |
Calculate new handle order by tag value. More... | |
ErrorCode | handle_order_from_sets_and_adj (const Range &sets, Tag &new_handle_tag_out) |
Calculate new handle order by set containment. More... | |
ErrorCode | reorder_entities (Tag new_handle_tag) |
Do the re-ordering indicated by the passed handle tag. More... | |
Private Member Functions | |
ErrorCode | reorder_tag_data (EntityType type, Tag new_handles, Tag reorder_tag) |
helper function for reorder_entities More... | |
ErrorCode | update_set_contents (Tag new_handles) |
helper function for reorder_entities More... | |
void | get_entities (EntityType t, int vals_per_ent, Range &result) |
Get all entities of specified type and size. More... | |
ErrorCode | get_reordered_handles (Tag tag, const Range &old_handles, std::vector< EntityHandle > &new_handles) |
Get new handles corresponding to old handles. More... | |
ErrorCode | get_reordered_handles (Tag tag, const std::vector< EntityHandle > &old_handles, std::vector< EntityHandle > &new_handles) |
Get new handles corresponding to old handles. More... | |
ErrorCode | get_reordered_handles (Tag tag, const EntityHandle *old_handles, EntityHandle *new_handles, size_t num_handles) |
Get new handles corresponding to old handles. More... | |
ErrorCode | get_new_handles (Tag tag, Range &old_handles, std::vector< EntityHandle > &newhandles) |
Remove any non-ordered handles and return new handles for remaining. More... | |
ErrorCode | int_order_from_sets_and_adj (const Range &sets, Tag order_tag, int skip_val, std::vector< std::vector< EntityHandle > * > &data) |
convert from input for handle_order_from_sets_and_adj to input for handle_order_from_int_tag More... | |
Private Attributes | |
Core * | mMB |
Definition at line 18 of file ReorderTool.hpp.
|
inline |
Definition at line 21 of file ReorderTool.hpp.
21 : mMB( moab ) {}
|
private |
Get all entities of specified type and size.
t | the type of entity to retreive |
vals_per_ent | entity size (connectivity length for elements, dimension for vertices) |
Definition at line 101 of file ReorderTool.cpp.
102 {
103 Range::iterator hint = entities.begin();
104 ;
105 TypeSequenceManager& seqs = mMB->sequence_manager()->entity_map( t );
106 TypeSequenceManager::iterator s;
107 for( s = seqs.begin(); s != seqs.end(); ++s )
108 {
109 EntitySequence* seq = *s;
110 if( seq->values_per_entity() == vals_per_ent )
111 hint = entities.insert( hint, seq->start_handle(), seq->end_handle() );
112 }
113 }
References moab::TypeSequenceManager::begin(), moab::TypeSequenceManager::end(), moab::EntitySequence::end_handle(), entities, moab::SequenceManager::entity_map(), mMB, moab::Core::sequence_manager(), moab::EntitySequence::start_handle(), and moab::EntitySequence::values_per_entity().
Referenced by handle_order_from_int_tag(), and reorder_entities().
|
private |
Remove any non-ordered handles and return new handles for remaining.
tag | Tag containing old->new mapping |
Definition at line 372 of file ReorderTool.cpp.
373 {
374 // get new handles for tagged entities
375 newhandles.resize( old_handles.size() );
376 ErrorCode rval = mMB->tag_get_data( tag, old_handles, ( newhandles.empty() ) ? NULL : &newhandles[0] );CHKERR;
377
378 // remove entities that were not reordered
379 Range::iterator i = old_handles.begin();
380 size_t w = 0;
381 for( size_t r = 0; r < newhandles.size(); ++r )
382 {
383 if( 0 != newhandles[r] )
384 {
385 newhandles[w] = newhandles[r];
386 ++w;
387 ++i;
388 }
389 else
390 {
391 i = old_handles.erase( i );
392 }
393 }
394 newhandles.resize( w );
395 assert( newhandles.size() == old_handles.size() );
396 return MB_SUCCESS;
397 }
References moab::Range::begin(), CHKERR, moab::Range::erase(), ErrorCode, MB_SUCCESS, mMB, moab::Range::size(), and moab::Core::tag_get_data().
Referenced by reorder_tag_data(), and update_set_contents().
|
private |
Get new handles corresponding to old handles.
tag | Tag containing old->new mapping |
Definition at line 359 of file ReorderTool.cpp.
363 {
364 ErrorCode rval = mMB->tag_get_data( tag, old_handles, num_handles, new_handles );CHKERR;
365
366 for( size_t i = 0; i < num_handles; ++i )
367 if( 0 == new_handles[i] ) new_handles[i] = old_handles[i];
368
369 return MB_SUCCESS;
370 }
References CHKERR, ErrorCode, MB_SUCCESS, mMB, and moab::Core::tag_get_data().
|
private |
Get new handles corresponding to old handles.
tag | Tag containing old->new mapping |
Definition at line 336 of file ReorderTool.cpp.
339 {
340 new_handles.resize( old_handles.size() );
341 ErrorCode rval = mMB->tag_get_data( tag, old_handles, ( new_handles.empty() ) ? NULL : &new_handles[0] );CHKERR;
342
343 Range::const_iterator it1 = old_handles.begin();
344 std::vector< EntityHandle >::iterator it2 = new_handles.begin();
345 for( ; it1 != old_handles.end(); ++it1, ++it2 )
346 if( 0 == *it2 ) *it2 = *it1;
347
348 return MB_SUCCESS;
349 }
References moab::Range::begin(), CHKERR, moab::Range::end(), ErrorCode, MB_SUCCESS, mMB, moab::Range::size(), and moab::Core::tag_get_data().
Referenced by get_reordered_handles(), reorder_entities(), reorder_tag_data(), and update_set_contents().
|
private |
Get new handles corresponding to old handles.
tag | Tag containing old->new mapping |
Definition at line 351 of file ReorderTool.cpp.
354 {
355 new_handles.resize( old_handles.size() );
356 return get_reordered_handles( tag, &old_handles[0], &new_handles[0], old_handles.size() );
357 }
References get_reordered_handles().
ErrorCode moab::ReorderTool::handle_order_from_int_tag | ( | EntityType | type, |
int | vals_per_ent, | ||
Tag | ordering_tag, | ||
int | ordering_tag_skip_value, | ||
Tag | new_handle_tag | ||
) |
Calculate new handle order by tag value.
Given a tag containing integer values, calculate new order for entities in the database (except entity sets) such that all entities with tag value A occur before all entities with tag value B in the handle space where A < B. Ordering will be stable for entities with the same tag value.
type | Entity type for which to calculate re-ordering. |
vals_per_ent | Zero for vertices. Connectivity length for elements. |
ordering_tag | Sinlge integer tag, where value on each entity determines the new position in the handle ordering. Entities may have duplicate values. |
ordering_tag_skip_value | Do not reorder entities with this tag value. This is typically the default value of ordering_tag. Specifying this limits the re-ordering to only those entities for which ordering_tag has been set. |
new_handle_tag | Tag into which to store new handle for each entity. Tag must be defined to store a single entity handle and must have a default value of zero. |
Definition at line 115 of file ReorderTool.cpp.
120 {
121 ErrorCode rval;
122
123 // check that input tag handles are what we expect
124 rval = check_tag_type( mMB, tag, MB_TYPE_INTEGER, sizeof( int ) );CHKERR;
125 rval = check_tag_type( mMB, new_handles, MB_TYPE_HANDLE, sizeof( EntityHandle ) );CHKERR;
126
127 // get entities to re-order
128 Range entities;
129 get_entities( t, vals_per_ent, entities );
130
131 // get entity order values
132 std::vector< int > sortvals( entities.size() );
133 rval = mMB->tag_get_data( tag, entities, &sortvals[0] );CHKERR;
134
135 // remove any entities for which value is skip_value
136 size_t r = 0, w = 0;
137 for( Range::iterator i = entities.begin(); i != entities.end(); ++r )
138 {
139 if( sortvals[r] == skip_value )
140 i = entities.erase( i );
141 else
142 {
143 sortvals[w++] = sortvals[r];
144 ++i;
145 }
146 }
147 sortvals.resize( w );
148
149 // sort
150 std::sort( sortvals.begin(), sortvals.end() );
151 // Convert to unique list and offsets for each value
152 // When done, sortvals will contain unique, sortvals and
153 // offsets will contain, for each unique value in sortvals,
154 // the number of values that occured in the non-unique list
155 // before the first instance of that value.
156 std::vector< size_t > offsets;
157 offsets.push_back( 0 );
158 offsets.push_back( 1 );
159 for( w = 0, r = 1; r < sortvals.size(); ++r )
160 {
161 if( sortvals[r] == sortvals[w] )
162 {
163 ++offsets.back();
164 }
165 else
166 {
167 ++w;
168 sortvals[w] = sortvals[r];
169 offsets.push_back( offsets.back() + 1 );
170 }
171 }
172 ++w;
173 assert( w + 1 == offsets.size() );
174 sortvals.resize( w );
175
176 // Tag each entity with its new handle
177 for( Range::iterator i = entities.begin(); i != entities.end(); ++i )
178 {
179 int val;
180 rval = mMB->tag_get_data( tag, &*i, 1, &val );CHKERR;
181 w = std::lower_bound( sortvals.begin(), sortvals.end(), val ) - sortvals.begin();
182 assert( w < sortvals.size() );
183 size_t offset = offsets[w];
184 ++offsets[w];
185 // should maybe copy range into array to avoid possibly n^2 behavior here
186 EntityHandle h = *( entities.begin() + offset );
187 rval = mMB->tag_set_data( new_handles, &*i, 1, &h );CHKERR;
188 }
189
190 return MB_SUCCESS;
191 }
References moab::check_tag_type(), CHKERR, entities, ErrorCode, get_entities(), MB_SUCCESS, MB_TYPE_HANDLE, MB_TYPE_INTEGER, mMB, moab::Core::tag_get_data(), and moab::Core::tag_set_data().
ErrorCode moab::ReorderTool::handle_order_from_int_tag | ( | Tag | ordering_tag, |
int | ordering_tag_skip_value, | ||
Tag & | new_handle_tag_out | ||
) |
Calculate new handle order by tag value.
Given a tag containing integer values, calculate new order for entities in the database (except entity sets) such that all entities with tag value A occur before all entities with tag value B in the handle space where A < B. Ordering will be stable for entities with the same tag value.
ordering_tag | Sinlge integer tag, where value on each entity determines the new position in the handle ordering. Entities may have duplicate values. |
ordering_tag_skip_value | Do not reorder entities with this tag value. This is typically the default value of ordering_tag. Specifying this limits the re-ordering to only those entities for which ordering_tag has been set. |
new_handle_tag_out | Passed back new tag handle containing the entity mapping. The returned tag will be anonymous. The caller is responsible for releasing the tag. The value of this tag on each handle is the new handle that the entity will will be moved to. The tag value will be zero for entities that were not re-ordered. |
Definition at line 59 of file ReorderTool.cpp.
60 {
61 ErrorCode rval;
62
63 // check that input tag handles are what we expect
64 rval = check_tag_type( mMB, tag, MB_TYPE_INTEGER, sizeof( int ) );CHKERR;
65 EntityHandle zero = 0;
66 rval = mMB->tag_get_handle( 0, 1, MB_TYPE_HANDLE, new_handles, MB_TAG_DENSE | MB_TAG_CREAT | MB_TAG_EXCL, &zero );CHKERR;
67
68 // Can only reorder within same type/connectivity (or vertex/num_coords)
69 // groupings. Call helper function for each such grouping.
70 for( EntityType t = MBVERTEX; t < MBENTITYSET; ++t )
71 {
72 // Get list of all connectivity lengths (or vertex dimensions)
73 // that exist for type t.
74 TypeSequenceManager& seqs = mMB->sequence_manager()->entity_map( t );
75 TypeSequenceManager::iterator i;
76 std::set< int > values;
77 for( i = seqs.begin(); i != seqs.end(); ++i )
78 {
79 EntitySequence* seq = *i;
80 // 0 values per entity implies structured data, which
81 // we cannot reorder. Skip those.
82 if( t == MBVERTEX || 0 < seq->values_per_entity() ) values.insert( seq->values_per_entity() );
83 }
84
85 // Call helper function for each (type,size) tuple.
86 std::set< int >::iterator j;
87 for( j = values.begin(); j != values.end(); ++j )
88 {
89 rval = handle_order_from_int_tag( t, *j, tag, skip_value, new_handles );
90 if( MB_SUCCESS != rval )
91 {
92 mMB->tag_delete( new_handles );
93 return error( rval );
94 }
95 }
96 }
97
98 return MB_SUCCESS;
99 }
References moab::TypeSequenceManager::begin(), moab::check_tag_type(), CHKERR, moab::TypeSequenceManager::end(), moab::SequenceManager::entity_map(), moab::error(), ErrorCode, MB_SUCCESS, MB_TAG_CREAT, MB_TAG_DENSE, MB_TAG_EXCL, MB_TYPE_HANDLE, MB_TYPE_INTEGER, MBENTITYSET, MBVERTEX, mMB, moab::Core::sequence_manager(), moab::Core::tag_delete(), moab::Core::tag_get_handle(), and moab::EntitySequence::values_per_entity().
Referenced by handle_order_from_sets_and_adj(), and main().
ErrorCode moab::ReorderTool::handle_order_from_sets_and_adj | ( | const Range & | sets, |
Tag & | new_handle_tag_out | ||
) |
Calculate new handle order by set containment.
Given a list of sets, re-order entities such that handles are grouped contiguously by set. Will also group all adjacent mesh entities, such that entities that are are adjacent to members of two or more of the input sets will ge grouped by the combined list of sets (e.g. if the input sets contain elements then all vertices that are adjacent to only elements in the first two sets will be grouped together).
sets | Entity sets by which to group entities. |
new_handle_tag_out | Passed back new tag handle containing the entity mapping. The returned tag will be anonymous. The caller is responsible for releasing the tag. The value of this tag on each handle is the new handle that the entity will will be moved to. The tag value will be zero for entities that were not re-ordered. |
Definition at line 193 of file ReorderTool.cpp.
194 {
195 ErrorCode rval;
196
197 if( !sets.all_of_type( MBENTITYSET ) ) return MB_TYPE_OUT_OF_RANGE;
198
199 Tag order_tag;
200 const int negone = -1;
201 rval = mMB->tag_get_handle( 0, 1, MB_TYPE_INTEGER, order_tag, MB_TAG_DENSE | MB_TAG_CREAT | MB_TAG_EXCL, &negone );
202 if( MB_SUCCESS != rval )
203 {
204 mMB->tag_delete( handle_tag );
205 handle_tag = 0;
206 return error( rval );
207 }
208
209 std::vector< std::vector< EntityHandle >* > data;
210 rval = int_order_from_sets_and_adj( sets, order_tag, negone, data );
211 for( size_t i = 0; i < data.size(); ++i )
212 delete data[i];
213 if( MB_SUCCESS != rval )
214 {
215 mMB->tag_delete( order_tag );
216 return error( rval );
217 }
218
219 rval = handle_order_from_int_tag( order_tag, negone, handle_tag );
220 if( MB_SUCCESS != rval )
221 {
222 mMB->tag_delete( order_tag );
223 return error( rval );
224 }
225
226 rval = mMB->tag_delete( order_tag );
227 if( MB_SUCCESS != rval ) return error( rval );
228
229 return MB_SUCCESS;
230 }
References moab::Range::all_of_type(), moab::error(), ErrorCode, handle_order_from_int_tag(), int_order_from_sets_and_adj(), MB_SUCCESS, MB_TAG_CREAT, MB_TAG_DENSE, MB_TAG_EXCL, MB_TYPE_INTEGER, MB_TYPE_OUT_OF_RANGE, MBENTITYSET, mMB, moab::Core::tag_delete(), and moab::Core::tag_get_handle().
Referenced by main().
|
private |
convert from input for handle_order_from_sets_and_adj
to input
for handle_order_from_int_tag
Definition at line 249 of file ReorderTool.cpp.
253 {
254 ErrorCode rval;
255
256 if( !sets.all_of_type( MBENTITYSET ) ) return MB_TYPE_OUT_OF_RANGE;
257
258 rval = check_tag_type( mMB, order_tag, MB_TYPE_INTEGER, sizeof( int ) );CHKERR;
259
260 // Compare function to use for a map keyed on pointers to sorted vectors
261 CompSortedVect lessthan;
262 // Map from sorted list of handles to index
263 std::map< std::vector< EntityHandle >*, int, CompSortedVect > forMap;
264 std::map< std::vector< EntityHandle >*, int, CompSortedVect >::iterator fiter, fiter2;
265 std::vector< EntityHandle > sharing; // tmp storage for entity
266
267 // for each set
268 for( Range::iterator s = sets.begin(); s != sets.end(); ++s )
269 {
270
271 // gather up all entities and adjacencies
272 Range tmp, ents, adj[4]; // indexed by dimension
273 for( int dim = 0; dim < 4; ++dim )
274 {
275 rval = mMB->get_entities_by_dimension( *s, dim, tmp );CHKERR;
276 for( int ldim = 0; ldim < dim; ++ldim )
277 {
278 rval = mMB->get_adjacencies( tmp, ldim, false, adj[ldim], Interface::UNION );CHKERR;
279 }
280 for( int udim = dim + 1; udim <= 3; ++udim )
281 {
282 rval = mMB->get_adjacencies( tmp, udim, false, adj[udim], Interface::UNION );CHKERR;
283 }
284 ents.merge( tmp );
285 tmp.clear();
286 }
287 for( int dim = 0; dim < 4; ++dim )
288 {
289 ents.merge( adj[dim] );
290 adj[dim].clear();
291 }
292
293 // process each entity
294 for( Range::iterator e = ents.begin(); e != ents.end(); ++e )
295 {
296 int val;
297 rval = mMB->tag_get_data( order_tag, &*e, 1, &val );CHKERR;
298
299 // If this entity is already in one or more of the sets (either
300 // directly or through adjacency) then get the existing list of
301 // sets and append this set handle (we are iterating over sets
302 // in sorted order, so appending should aways maintain a sorted
303 // list.)
304 sharing.clear();
305 if( val != skip_val )
306 {
307 sharing = *revMap[val];
308 assert( std::lower_bound( sharing.begin(), sharing.end(), *s ) == sharing.end() );
309 }
310 sharing.push_back( *s );
311
312 // Check if new sharing list already exists in forward map
313 fiter = forMap.lower_bound( &sharing );
314 if( fiter == forMap.end() || lessthan( fiter->first, &sharing ) )
315 {
316 // Add new sharing list to forward and reverse maps.
317 std::vector< EntityHandle >* newvec = new std::vector< EntityHandle >;
318 newvec->swap( sharing );
319 if( (int)revMap.size() == skip_val ) revMap.push_back( 0 );
320 fiter2 =
321 forMap.insert( fiter, std::pair< std::vector< EntityHandle >*, int >( newvec, revMap.size() ) );
322 assert( fiter2 != fiter );
323 fiter = fiter2;
324 revMap.push_back( newvec );
325 }
326
327 // Update index on entity
328 val = fiter->second;
329 rval = mMB->tag_set_data( order_tag, &*e, 1, &val );CHKERR;
330 }
331 }
332
333 return MB_SUCCESS;
334 }
References moab::Range::all_of_type(), moab::Range::begin(), moab::check_tag_type(), CHKERR, moab::Range::clear(), dim, moab::Range::end(), ErrorCode, moab::Core::get_adjacencies(), moab::Core::get_entities_by_dimension(), MB_SUCCESS, MB_TYPE_INTEGER, MB_TYPE_OUT_OF_RANGE, MBENTITYSET, moab::Range::merge(), mMB, moab::Core::tag_get_data(), moab::Core::tag_set_data(), and moab::Interface::UNION.
Referenced by handle_order_from_sets_and_adj().
Do the re-ordering indicated by the passed handle tag.
The specified re-ordering must be a permutation. Each existing entity must be moved to a new, existing handle such that no two entities are moved to the same new handle.
Given a tag storing handles that define a permution, apply the described re-ordering. The passed tag must contain one entity handle per entity. The value of the tag must be zero for all entities that are not to be re-ordered. For entities to be re-ordered, the tag must contain the new handle that the entity is to be moved to. No two entities may have the same value for this tag (other than a value of zero.)
new_handle_tag | Tag containing new handles for entities to reorder. Typically the output of handle_order_from_int_tag or similar. |
Definition at line 399 of file ReorderTool.cpp.
400 {
401 ErrorCode rval;
402
403 rval = check_tag_type( mMB, new_handles, MB_TYPE_HANDLE, sizeof( EntityHandle ) );CHKERR;
404 EntityHandle defval;
405 rval = mMB->tag_get_default_value( new_handles, &defval );CHKERR;
406 if( 0 != defval ) return error( MB_INDEX_OUT_OF_RANGE );
407
408 // Can only reorder within same type/connectivity (or vertex/num_coords)
409 // groupings.
410 for( EntityType t = MBVERTEX; t < MBENTITYSET; ++t )
411 {
412 // Get list of all connectivity lengths (or vertex dimensions)
413 // that exist for type t.
414 TypeSequenceManager& seqs = mMB->sequence_manager()->entity_map( t );
415 TypeSequenceManager::iterator i;
416 std::set< int > values;
417 for( i = seqs.begin(); i != seqs.end(); ++i )
418 {
419 EntitySequence* seq = *i;
420 // 0 values per entity implies structured data, which
421 // we cannot reorder. Skip those.
422 if( t == MBVERTEX || 0 < seq->values_per_entity() ) values.insert( seq->values_per_entity() );
423 }
424
425 // reorder primary data for each (type,size) tuple.
426 std::set< int >::iterator j;
427 for( j = values.begin(); j != values.end(); ++j )
428 {
429 Range entities;
430 get_entities( t, *j, entities );
431 std::vector< EntityHandle > handles;
432 rval = get_reordered_handles( new_handles, entities, handles );
433 UNRECOVERABLE( rval );
434
435 if( t == MBVERTEX )
436 {
437 std::vector< double > coords( entities.size() * 3 );
438 rval = mMB->get_coords( entities, &coords[0] );
439 UNRECOVERABLE( rval );
440 rval = mMB->set_coords( &handles[0], handles.size(), &coords[0] );
441 UNRECOVERABLE( rval );
442 }
443 else
444 {
445 std::vector< EntityHandle > conn;
446 conn.reserve( entities.size() * *j );
447 std::vector< EntityHandle > old_handles;
448 old_handles.resize( entities.size() );
449 std::copy( entities.begin(), entities.end(), old_handles.begin() );
450 rval = mMB->get_connectivity( &old_handles[0], old_handles.size(), conn, false );
451 UNRECOVERABLE( rval );
452 old_handles.clear();
453 old_handles = conn;
454 rval = get_reordered_handles( new_handles, old_handles, conn );
455 UNRECOVERABLE( rval );
456 for( unsigned int h = 0; h < handles.size(); ++h )
457 {
458 rval = mMB->set_connectivity( handles[h], &conn[h * *j], *j );
459 UNRECOVERABLE( rval );
460 }
461 }
462 }
463 }
464
465 // now update tag data
466 std::vector< Tag > tag_handles;
467 mMB->tag_get_tags( tag_handles );
468 for( size_t i = 0; i < tag_handles.size(); ++i )
469 {
470 Tag tag = tag_handles[i];
471 if( tag == new_handles ) // don't mess up mapping from old to new handles
472 continue;
473
474 for( EntityType t = MBVERTEX; t <= MBENTITYSET; ++t )
475 {
476 rval = reorder_tag_data( t, new_handles, tag );
477 UNRECOVERABLE( rval );
478 }
479 }
480
481 rval = update_set_contents( new_handles );
482 UNRECOVERABLE( rval );
483
484 return MB_SUCCESS;
485 }
References moab::TypeSequenceManager::begin(), moab::check_tag_type(), CHKERR, moab::TypeSequenceManager::end(), entities, moab::SequenceManager::entity_map(), moab::error(), ErrorCode, moab::Core::get_connectivity(), moab::Core::get_coords(), get_entities(), get_reordered_handles(), MB_INDEX_OUT_OF_RANGE, MB_SUCCESS, MB_TYPE_HANDLE, MBENTITYSET, MBVERTEX, mMB, reorder_tag_data(), moab::Core::sequence_manager(), moab::Core::set_connectivity(), moab::Core::set_coords(), moab::Core::tag_get_default_value(), moab::Core::tag_get_tags(), UNRECOVERABLE, update_set_contents(), and moab::EntitySequence::values_per_entity().
Referenced by main().
|
private |
helper function for reorder_entities
Reorder tag data for all entities of specified type.
Also updates tag values for MB_TYPE_HANDLE tags.
type | Entity type to reorder |
new_handles | Tag containing old->new handle mapping |
reorder_tag | The tag data to reorder |
Definition at line 487 of file ReorderTool.cpp.
488 {
489 ErrorCode rval;
490
491 int tagsize;
492 DataType tagtype;
493 rval = mMB->tag_get_data_type( tag, tagtype );
494 if( MB_SUCCESS != rval ) return error( rval );
495 if( MB_TYPE_BIT == tagtype )
496 tagsize = 1;
497 else
498 {
499 rval = mMB->tag_get_bytes( tag, tagsize );
500 if( MB_VARIABLE_DATA_LENGTH == rval )
501 tagsize = -1;
502 else if( MB_SUCCESS != rval )
503 return error( rval );
504 }
505
506 // we don't re-order set handles, so we don't care about sets
507 // unless the tag contains handles that need to be updated
508 if( MBENTITYSET == etype && MB_TYPE_HANDLE != tagtype ) return MB_SUCCESS;
509
510 // get tagged entities
511 Range old_tagged;
512 rval = mMB->get_entities_by_type_and_tag( 0, etype, &tag, 0, 1, old_tagged );
513 if( MB_SUCCESS != rval && old_tagged.empty() ) return error( rval );
514
515 // remove entities that were not reordered, unless the tag
516 // is handle type in which case we need to update the data
517 // for all entities, regardless of reordering.
518 std::vector< EntityHandle > newhandles;
519 if( MB_TYPE_HANDLE == tagtype )
520 rval = get_reordered_handles( new_handles, old_tagged, newhandles );
521 else
522 rval = get_new_handles( new_handles, old_tagged, newhandles );CHKERR;
523
524 if( old_tagged.empty() ) return MB_SUCCESS;
525
526 // get copy of all tag data
527 std::vector< unsigned char > buffer;
528 std::vector< const void* > pointers;
529 std::vector< int > sizes;
530 // if variable-length tag
531 if( -1 == tagsize )
532 {
533 pointers.resize( old_tagged.size() );
534 sizes.resize( pointers.size() );
535 rval = mMB->tag_get_by_ptr( tag, old_tagged, &pointers[0], &sizes[0] );CHKERR;
536 int total = std::accumulate( sizes.begin(), sizes.end(), 0 );
537 DataType dtype;
538 mMB->tag_get_data_type( tag, dtype );
539 int type_size;
540 switch( dtype )
541 {
542 case MB_TYPE_INTEGER:
543 type_size = sizeof( int );
544 break;
545 case MB_TYPE_DOUBLE:
546 type_size = sizeof( double );
547 break;
548 case MB_TYPE_HANDLE:
549 type_size = sizeof( EntityHandle );
550 break;
551 case MB_TYPE_BIT:
552 type_size = 1;
553 break;
554 case MB_TYPE_OPAQUE:
555 type_size = 1;
556 break;
557 default:
558 return MB_TYPE_OUT_OF_RANGE;
559 }
560 buffer.resize( total * type_size );
561 size_t off = 0;
562 for( size_t j = 0; j < pointers.size(); ++j )
563 {
564 memcpy( &buffer[off], pointers[j], type_size * sizes[j] );
565 pointers[j] = &buffer[off];
566 off += sizes[j] * type_size;
567 }
568 }
569 // if fixed-length tag
570 else
571 {
572 buffer.resize( old_tagged.size() * tagsize );
573 rval = mMB->tag_get_data( tag, old_tagged, &buffer[0] );CHKERR;
574 }
575
576 // if handle tag, update tag values for reordered handles
577 if( MB_TYPE_HANDLE == tagtype )
578 {
579 assert( !( buffer.size() % sizeof( EntityHandle ) ) );
580 std::vector< unsigned char > buffer2( buffer.size() );
581 rval = get_reordered_handles( new_handles, reinterpret_cast< const EntityHandle* >( &buffer[0] ),
582 reinterpret_cast< EntityHandle* >( &buffer2[0] ),
583 buffer.size() / sizeof( EntityHandle ) );CHKERR;
584 // if var-length tag then do not do swap because pointers[] contains pointers
585 // into old buffer
586 if( -1 == tagsize )
587 memcpy( &buffer[0], &buffer2[0], buffer.size() );
588 else
589 buffer.swap( buffer2 );
590 }
591
592 // store re-ordered tag data
593 if( -1 == tagsize )
594 {
595 rval = mMB->tag_set_by_ptr( tag, &newhandles[0], newhandles.size(), &pointers[0], &sizes[0] );
596 pointers.clear();
597 sizes.clear();
598 buffer.clear();
599 }
600 else
601 {
602 rval = mMB->tag_set_data( tag, &newhandles[0], newhandles.size(), &buffer[0] );
603 buffer.clear();
604 }
605 CHKERR;
606
607 // all permutations should be cyclical, but not all permuted
608 // entities necessarily had tag values, so we might need to delete
609 // tags for some entities
610 std::sort( newhandles.begin(), newhandles.end() );
611 std::vector< EntityHandle >::iterator k = newhandles.begin();
612 Range::iterator i = old_tagged.begin();
613 while( i != old_tagged.end() )
614 {
615 while( k != newhandles.end() && *k < *i )
616 ++k;
617 if( k == newhandles.end() ) break;
618
619 if( *i == *k ) // what old_tagged -= newhandles
620 i = old_tagged.erase( i );
621 else
622 ++i;
623 }
624
625 if( !old_tagged.empty() )
626 {
627 rval = mMB->tag_delete_data( tag, old_tagged );CHKERR;
628 }
629
630 return MB_SUCCESS;
631 }
References moab::Range::begin(), buffer, CHKERR, moab::Range::empty(), moab::Range::end(), moab::Range::erase(), moab::error(), ErrorCode, moab::Core::get_entities_by_type_and_tag(), get_new_handles(), get_reordered_handles(), MB_SUCCESS, MB_TYPE_BIT, MB_TYPE_DOUBLE, MB_TYPE_HANDLE, MB_TYPE_INTEGER, MB_TYPE_OPAQUE, MB_TYPE_OUT_OF_RANGE, MB_VARIABLE_DATA_LENGTH, MBENTITYSET, mMB, moab::Range::size(), sizes, moab::Core::tag_delete_data(), moab::Core::tag_get_by_ptr(), moab::Core::tag_get_bytes(), moab::Core::tag_get_data(), moab::Core::tag_get_data_type(), moab::Core::tag_set_by_ptr(), and moab::Core::tag_set_data().
Referenced by reorder_entities().
helper function for reorder_entities
Update set contents for changed handles.
new_handles | Tag containing old->new handle mapping |
Definition at line 633 of file ReorderTool.cpp.
634 {
635 Range sets;
636 ErrorCode rval = mMB->get_entities_by_type( 0, MBENTITYSET, sets );CHKERR;
637
638 std::vector< EntityHandle > old_handles, new_handles;
639 for( Range::iterator i = sets.begin(); i != sets.end(); ++i )
640 {
641 // If set is un-ordered...
642 unsigned opts = 0;
643 mMB->get_meshset_options( *i, opts );
644 if( !( opts & MESHSET_ORDERED ) )
645 {
646 Range contents;
647 rval = mMB->get_entities_by_handle( *i, contents );CHKERR;
648
649 rval = get_new_handles( nh_tag, contents, new_handles );CHKERR;
650
651 Range replace;
652 std::sort( new_handles.begin(), new_handles.end() );
653 Range::iterator hint = replace.begin();
654 for( size_t j = 0; j < new_handles.size(); ++j )
655 hint = replace.insert( hint, new_handles[j] );
656 Range common = intersect( contents, replace );
657 contents -= common;
658 replace -= common;
659 assert( contents.size() == replace.size() );
660 if( !contents.empty() )
661 {
662 rval = mMB->remove_entities( *i, contents );CHKERR;
663 rval = mMB->add_entities( *i, replace );
664 }
665 }
666
667 // If set is ordered...
668 else
669 {
670 // get set contents
671 old_handles.clear();
672 rval = mMB->get_entities_by_handle( *i, old_handles );CHKERR;
673
674 // get new handles from old contained handles
675 rval = get_reordered_handles( nh_tag, old_handles, new_handles );CHKERR;
676
677 rval = mMB->clear_meshset( &*i, 1 );CHKERR;
678
679 rval = mMB->add_entities( *i, &new_handles[0], new_handles.size() );CHKERR;
680 }
681 } // for each set
682
683 return MB_SUCCESS;
684 }
References moab::Core::add_entities(), moab::Range::begin(), CHKERR, moab::Core::clear_meshset(), moab::Range::empty(), moab::Range::end(), ErrorCode, moab::Core::get_entities_by_handle(), moab::Core::get_entities_by_type(), moab::Core::get_meshset_options(), get_new_handles(), get_reordered_handles(), moab::Range::insert(), moab::intersect(), MB_SUCCESS, MBENTITYSET, mMB, moab::Core::remove_entities(), and moab::Range::size().
Referenced by reorder_entities().
|
private |
Definition at line 178 of file ReorderTool.hpp.
Referenced by get_entities(), get_new_handles(), get_reordered_handles(), handle_order_from_int_tag(), handle_order_from_sets_and_adj(), int_order_from_sets_and_adj(), reorder_entities(), reorder_tag_data(), and update_set_contents().