Branch data Line data Source code
1 : : /** \file ReorderTool.cpp
2 : : * \author Jason Kraftcheck
3 : : * \date 2011-05-23
4 : : */
5 : :
6 : : #include "moab/ReorderTool.hpp"
7 : : #include "moab/Core.hpp"
8 : : #include "moab/Range.hpp"
9 : :
10 : : #include "SequenceManager.hpp"
11 : : #include "TypeSequenceManager.hpp"
12 : : #include "EntitySequence.hpp"
13 : :
14 : : #include <algorithm>
15 : : #include <numeric>
16 : : #include <set>
17 : : #include <iostream>
18 : :
19 : : namespace moab
20 : : {
21 : :
22 : : // no-op function as a convenient spot to set a breakpoint
23 : 0 : static inline ErrorCode error( ErrorCode val )
24 : : {
25 : 0 : return val;
26 : : }
27 : :
28 : : #define CHKERR \
29 : : if( MB_SUCCESS != rval ) return error( rval )
30 : :
31 : : #define UNRECOVERABLE( ERRCODE ) \
32 : : do \
33 : : { \
34 : : if( MB_SUCCESS != ( ERRCODE ) ) \
35 : : { \
36 : : error( ( ERRCODE ) ); \
37 : : std::cerr << "Unreconverable error during mesh reorder." << std::endl \
38 : : << "Error Code " << ( ERRCODE ) << " at " << __FILE__ << ":" << __LINE__ << std::endl; \
39 : : std::cerr.flush(); \
40 : : abort(); \
41 : : } \
42 : : } while( false )
43 : :
44 : 12 : static ErrorCode check_tag_type( Interface* moab, Tag tag, DataType exp_type, int exp_size )
45 : : {
46 : : ErrorCode rval;
47 : : DataType act_type;
48 : : int act_size;
49 : :
50 [ + - ][ - + ]: 12 : rval = moab->tag_get_data_type( tag, act_type );CHKERR;
51 : :
52 [ + - ][ - + ]: 12 : rval = moab->tag_get_bytes( tag, act_size );CHKERR;
53 : :
54 [ + - ][ - + ]: 12 : if( act_type != exp_type || act_size != exp_size ) return MB_TYPE_OUT_OF_RANGE;
55 : :
56 : 12 : return MB_SUCCESS;
57 : : }
58 : :
59 : 2 : ErrorCode ReorderTool::handle_order_from_int_tag( Tag tag, int skip_value, Tag& new_handles )
60 : : {
61 : : ErrorCode rval;
62 : :
63 : : // check that input tag handles are what we expect
64 [ + - ][ - + ]: 2 : rval = check_tag_type( mMB, tag, MB_TYPE_INTEGER, sizeof( int ) );CHKERR;
65 : 2 : EntityHandle zero = 0;
66 [ + - ][ - + ]: 2 : 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 [ + - ][ + + ]: 24 : 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 [ + - ][ + - ]: 22 : TypeSequenceManager& seqs = mMB->sequence_manager()->entity_map( t );
75 [ + - ]: 22 : TypeSequenceManager::iterator i;
76 [ + - ]: 22 : std::set< int > values;
77 [ + - ][ + - ]: 26 : for( i = seqs.begin(); i != seqs.end(); ++i )
[ + - ][ + - ]
[ + + ]
78 : : {
79 [ + - ]: 4 : EntitySequence* seq = *i;
80 : : // 0 values per entity implies structured data, which
81 : : // we cannot reorder. Skip those.
82 [ + + ][ + - ]: 4 : 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 [ + - ]: 22 : std::set< int >::iterator j;
87 [ + - ][ + - ]: 26 : for( j = values.begin(); j != values.end(); ++j )
[ + + ][ + - ]
88 : : {
89 [ + - ][ + - ]: 4 : rval = handle_order_from_int_tag( t, *j, tag, skip_value, new_handles );
90 [ - + ]: 4 : if( MB_SUCCESS != rval )
91 : : {
92 [ # # ]: 0 : mMB->tag_delete( new_handles );
93 : 0 : return error( rval );
94 : : }
95 : : }
96 : 22 : }
97 : :
98 : 2 : return MB_SUCCESS;
99 : : }
100 : :
101 : 6 : void ReorderTool::get_entities( EntityType t, int vals_per_ent, Range& entities )
102 : : {
103 [ + - ]: 6 : Range::iterator hint = entities.begin();
104 : : ;
105 [ + - ][ + - ]: 6 : TypeSequenceManager& seqs = mMB->sequence_manager()->entity_map( t );
106 [ + - ]: 6 : TypeSequenceManager::iterator s;
107 [ + - ][ + - ]: 12 : for( s = seqs.begin(); s != seqs.end(); ++s )
[ + - ][ + - ]
[ + + ]
108 : : {
109 [ + - ]: 6 : EntitySequence* seq = *s;
110 [ + - ][ + - ]: 6 : if( seq->values_per_entity() == vals_per_ent )
111 [ + - ][ + - ]: 6 : hint = entities.insert( hint, seq->start_handle(), seq->end_handle() );
[ + - ]
112 : : }
113 : 6 : }
114 : :
115 : 4 : ErrorCode ReorderTool::handle_order_from_int_tag( EntityType t, int vals_per_ent, Tag tag, int skip_value,
116 : : Tag new_handles )
117 : : {
118 : : ErrorCode rval;
119 : :
120 : : // check that input tag handles are what we expect
121 [ + - ][ - + ]: 4 : rval = check_tag_type( mMB, tag, MB_TYPE_INTEGER, sizeof( int ) );CHKERR;
122 [ + - ][ - + ]: 4 : rval = check_tag_type( mMB, new_handles, MB_TYPE_HANDLE, sizeof( EntityHandle ) );CHKERR;
123 : :
124 : : // get entities to re-order
125 [ + - ]: 4 : Range entities;
126 [ + - ]: 4 : get_entities( t, vals_per_ent, entities );
127 : :
128 : : // get entity order values
129 [ + - ][ + - ]: 8 : std::vector< int > sortvals( entities.size() );
130 [ + - ][ + - ]: 4 : rval = mMB->tag_get_data( tag, entities, &sortvals[0] );CHKERR;
[ - + ]
131 : :
132 : : // remove any entities for which value is skip_value
133 : 4 : size_t r = 0, w = 0;
134 [ + - ][ + - ]: 174 : for( Range::iterator i = entities.begin(); i != entities.end(); ++r )
[ + - ][ + + ]
135 : : {
136 [ + - ][ - + ]: 170 : if( sortvals[r] == skip_value )
137 [ # # ]: 0 : i = entities.erase( i );
138 : : else
139 : : {
140 [ + - ][ + - ]: 170 : sortvals[w++] = sortvals[r];
141 [ + - ]: 170 : ++i;
142 : : }
143 : : }
144 [ + - ]: 4 : sortvals.resize( w );
145 : :
146 : : // sort
147 [ + - ]: 4 : std::sort( sortvals.begin(), sortvals.end() );
148 : : // Convert to unique list and offsets for each value
149 : : // When done, sortvals will contain unique, sortvals and
150 : : // offsets will contain, for each unique value in sortvals,
151 : : // the number of values that occured in the non-unique list
152 : : // before the first instance of that value.
153 [ + - ]: 8 : std::vector< size_t > offsets;
154 [ + - ]: 4 : offsets.push_back( 0 );
155 [ + - ]: 4 : offsets.push_back( 1 );
156 [ + + ]: 170 : for( w = 0, r = 1; r < sortvals.size(); ++r )
157 : : {
158 [ + - ][ + - ]: 166 : if( sortvals[r] == sortvals[w] ) { ++offsets.back(); }
[ + + ][ + - ]
159 : : else
160 : : {
161 : 10 : ++w;
162 [ + - ][ + - ]: 10 : sortvals[w] = sortvals[r];
163 [ + - ][ + - ]: 10 : offsets.push_back( offsets.back() + 1 );
164 : : }
165 : : }
166 : 4 : ++w;
167 [ - + ]: 4 : assert( w + 1 == offsets.size() );
168 [ + - ]: 4 : sortvals.resize( w );
169 : :
170 : : // Tag each entity with its new handle
171 [ + - ][ + - ]: 174 : for( Range::iterator i = entities.begin(); i != entities.end(); ++i )
[ + - ][ + - ]
[ + + ]
172 : : {
173 : : int val;
174 [ + - ][ + - ]: 170 : rval = mMB->tag_get_data( tag, &*i, 1, &val );CHKERR;
[ - + ]
175 [ + - ][ + - ]: 170 : w = std::lower_bound( sortvals.begin(), sortvals.end(), val ) - sortvals.begin();
176 [ - + ]: 170 : assert( w < sortvals.size() );
177 [ + - ]: 170 : size_t offset = offsets[w];
178 [ + - ]: 170 : ++offsets[w];
179 : : // should maybe copy range into array to avoid possibly n^2 behavior here
180 [ + - ][ + - ]: 170 : EntityHandle h = *( entities.begin() + offset );
[ + - ]
181 [ + - ][ + - ]: 170 : rval = mMB->tag_set_data( new_handles, &*i, 1, &h );CHKERR;
[ - + ]
182 : : }
183 : :
184 : 8 : return MB_SUCCESS;
185 : : }
186 : :
187 : 1 : ErrorCode ReorderTool::handle_order_from_sets_and_adj( const Range& sets, Tag& handle_tag )
188 : : {
189 : : ErrorCode rval;
190 : :
191 [ + - ][ - + ]: 1 : if( !sets.all_of_type( MBENTITYSET ) ) return MB_TYPE_OUT_OF_RANGE;
192 : :
193 : : Tag order_tag;
194 : 1 : const int negone = -1;
195 [ + - ]: 1 : rval = mMB->tag_get_handle( 0, 1, MB_TYPE_INTEGER, order_tag, MB_TAG_DENSE | MB_TAG_CREAT | MB_TAG_EXCL, &negone );
196 [ - + ]: 1 : if( MB_SUCCESS != rval )
197 : : {
198 [ # # ]: 0 : mMB->tag_delete( handle_tag );
199 : 0 : handle_tag = 0;
200 : 0 : return error( rval );
201 : : }
202 : :
203 [ + - ]: 1 : std::vector< std::vector< EntityHandle >* > data;
204 [ + - ]: 1 : rval = int_order_from_sets_and_adj( sets, order_tag, negone, data );
205 [ + + ]: 6 : for( size_t i = 0; i < data.size(); ++i )
206 [ + - ][ + - ]: 5 : delete data[i];
207 [ - + ]: 1 : if( MB_SUCCESS != rval )
208 : : {
209 [ # # ]: 0 : mMB->tag_delete( order_tag );
210 : 0 : return error( rval );
211 : : }
212 : :
213 [ + - ]: 1 : rval = handle_order_from_int_tag( order_tag, negone, handle_tag );
214 [ - + ]: 1 : if( MB_SUCCESS != rval )
215 : : {
216 [ # # ]: 0 : mMB->tag_delete( order_tag );
217 : 0 : return error( rval );
218 : : }
219 : :
220 [ + - ]: 1 : rval = mMB->tag_delete( order_tag );
221 [ - + ]: 1 : if( MB_SUCCESS != rval ) return error( rval );
222 : :
223 : 1 : return MB_SUCCESS;
224 : : }
225 : :
226 : : // Compare function to use for a map keyed on pointers to sorted vectors
227 : : struct CompSortedVect
228 : : {
229 : 359 : bool operator()( const std::vector< EntityHandle >* v1, const std::vector< EntityHandle >* v2 ) const
230 : : {
231 : 359 : std::vector< EntityHandle >::const_iterator i1, i2;
232 [ + - ][ + - ]: 666 : for( i1 = v1->begin(), i2 = v2->begin(); i1 != v1->end(); ++i1, ++i2 )
[ + - ][ + + ]
233 : : {
234 [ + - ][ + + ]: 420 : if( i2 == v2->end() || *i1 > *i2 )
[ + - ][ + - ]
[ + + ][ + - ]
[ + + # # ]
235 : 24 : return false;
236 [ + - ][ + - ]: 396 : else if( *i1 < *i2 )
[ + + ]
237 : 89 : return true;
238 : : }
239 [ + - ]: 359 : return i2 != v2->end();
240 : : }
241 : : };
242 : :
243 : 1 : ErrorCode ReorderTool::int_order_from_sets_and_adj( const Range& sets, Tag order_tag, int skip_val,
244 : : std::vector< std::vector< EntityHandle >* >& revMap )
245 : : {
246 : : ErrorCode rval;
247 : :
248 [ + - ][ - + ]: 1 : if( !sets.all_of_type( MBENTITYSET ) ) return MB_TYPE_OUT_OF_RANGE;
249 : :
250 [ + - ][ - + ]: 1 : rval = check_tag_type( mMB, order_tag, MB_TYPE_INTEGER, sizeof( int ) );CHKERR;
251 : :
252 : : // Compare function to use for a map keyed on pointers to sorted vectors
253 : : CompSortedVect lessthan;
254 : : // Map from sorted list of handles to index
255 [ + - ]: 1 : std::map< std::vector< EntityHandle >*, int, CompSortedVect > forMap;
256 [ + - ][ + - ]: 1 : std::map< std::vector< EntityHandle >*, int, CompSortedVect >::iterator fiter, fiter2;
257 [ + - ]: 2 : std::vector< EntityHandle > sharing; // tmp storage for entity
258 : :
259 : : // for each set
260 [ + - ][ + - ]: 4 : for( Range::iterator s = sets.begin(); s != sets.end(); ++s )
[ + - ][ + - ]
[ + + ]
261 : : {
262 : :
263 : : // gather up all entities and adjacencies
264 [ + - ][ + - ]: 30 : Range tmp, ents, adj[4]; // indexed by dimension
[ + - ][ + + ]
[ + - ][ + - ]
[ + - # #
# # ]
265 [ + + ]: 15 : for( int dim = 0; dim < 4; ++dim )
266 : : {
267 [ + - ][ + - ]: 12 : rval = mMB->get_entities_by_dimension( *s, dim, tmp );CHKERR;
[ - + ]
268 [ + + ]: 30 : for( int ldim = 0; ldim < dim; ++ldim )
269 : : {
270 [ + - ][ - + ]: 18 : rval = mMB->get_adjacencies( tmp, ldim, false, adj[ldim], Interface::UNION );CHKERR;
271 : : }
272 [ + + ]: 30 : for( int udim = dim + 1; udim <= 3; ++udim )
273 : : {
274 [ + - ][ - + ]: 18 : rval = mMB->get_adjacencies( tmp, udim, false, adj[udim], Interface::UNION );CHKERR;
275 : : }
276 [ + - ]: 12 : ents.merge( tmp );
277 [ + - ]: 12 : tmp.clear();
278 : : }
279 [ + + ]: 15 : for( int dim = 0; dim < 4; ++dim )
280 : : {
281 [ + - ]: 12 : ents.merge( adj[dim] );
282 [ + - ]: 12 : adj[dim].clear();
283 : : }
284 : :
285 : : // process each entity
286 [ + - ][ + - ]: 135 : for( Range::iterator e = ents.begin(); e != ents.end(); ++e )
[ + - ][ + - ]
[ + + ][ + + ]
287 : : {
288 : : int val;
289 [ + - ][ + - ]: 120 : rval = mMB->tag_get_data( order_tag, &*e, 1, &val );CHKERR;
[ - + ]
290 : :
291 : : // If this entity is already in one or more of the sets (either
292 : : // directly or through adjacency) then get the existing list of
293 : : // sets and append this set handle (we are iterating over sets
294 : : // in sorted order, so appending should aways maintain a sorted
295 : : // list.)
296 : 120 : sharing.clear();
297 [ + + ]: 120 : if( val != skip_val )
298 : : {
299 [ + - ][ + - ]: 35 : sharing = *revMap[val];
300 [ + - ][ + - ]: 35 : assert( std::lower_bound( sharing.begin(), sharing.end(), *s ) == sharing.end() );
[ + - ][ - + ]
301 : : }
302 [ + - ][ + - ]: 120 : sharing.push_back( *s );
303 : :
304 : : // Check if new sharing list already exists in forward map
305 [ + - ]: 120 : fiter = forMap.lower_bound( &sharing );
306 [ + - ][ + + ]: 120 : if( fiter == forMap.end() || lessthan( fiter->first, &sharing ) )
[ + - ][ + - ]
[ - + ][ + - ]
[ + + # # ]
307 : : {
308 : : // Add new sharing list to forward and reverse maps.
309 [ + - ][ + - ]: 5 : std::vector< EntityHandle >* newvec = new std::vector< EntityHandle >;
310 : 5 : newvec->swap( sharing );
311 [ - + ][ # # ]: 5 : if( (int)revMap.size() == skip_val ) revMap.push_back( 0 );
312 : : fiter2 =
313 [ + - ][ + - ]: 5 : forMap.insert( fiter, std::pair< std::vector< EntityHandle >*, int >( newvec, revMap.size() ) );
[ + - ]
314 [ + - ][ - + ]: 5 : assert( fiter2 != fiter );
315 : 5 : fiter = fiter2;
316 [ + - ]: 5 : revMap.push_back( newvec );
317 : : }
318 : :
319 : : // Update index on entity
320 [ + - ]: 120 : val = fiter->second;
321 [ + - ][ + - ]: 120 : rval = mMB->tag_set_data( order_tag, &*e, 1, &val );CHKERR;
[ - + ]
322 : : }
323 : 3 : }
324 : :
325 [ # # ]: 2 : return MB_SUCCESS;
326 : : }
327 : :
328 : 38 : ErrorCode ReorderTool::get_reordered_handles( Tag tag, const Range& old_handles,
329 : : std::vector< EntityHandle >& new_handles )
330 : : {
331 [ + - ][ + - ]: 38 : new_handles.resize( old_handles.size() );
332 [ + + ][ + - ]: 38 : ErrorCode rval = mMB->tag_get_data( tag, old_handles, ( new_handles.empty() ) ? NULL : &new_handles[0] );CHKERR;
[ + - ][ - + ]
333 : :
334 [ + - ]: 38 : Range::const_iterator it1 = old_handles.begin();
335 : 38 : std::vector< EntityHandle >::iterator it2 = new_handles.begin();
336 [ + - ][ + - ]: 246 : for( ; it1 != old_handles.end(); ++it1, ++it2 )
[ + - ][ + - ]
[ + + ]
337 [ + - ][ + + ]: 208 : if( 0 == *it2 ) *it2 = *it1;
[ + - ][ + - ]
338 : :
339 : 38 : return MB_SUCCESS;
340 : : }
341 : :
342 : 2 : ErrorCode ReorderTool::get_reordered_handles( Tag tag, const std::vector< EntityHandle >& old_handles,
343 : : std::vector< EntityHandle >& new_handles )
344 : : {
345 : 2 : new_handles.resize( old_handles.size() );
346 : 2 : return get_reordered_handles( tag, &old_handles[0], &new_handles[0], old_handles.size() );
347 : : }
348 : :
349 : 6 : ErrorCode ReorderTool::get_reordered_handles( Tag tag, const EntityHandle* old_handles, EntityHandle* new_handles,
350 : : size_t num_handles )
351 : : {
352 [ - + ]: 6 : ErrorCode rval = mMB->tag_get_data( tag, old_handles, num_handles, new_handles );CHKERR;
353 : :
354 [ + + ]: 397 : for( size_t i = 0; i < num_handles; ++i )
355 [ - + ]: 391 : if( 0 == new_handles[i] ) new_handles[i] = old_handles[i];
356 : :
357 : 6 : return MB_SUCCESS;
358 : : }
359 : :
360 : 115 : ErrorCode ReorderTool::get_new_handles( Tag tag, Range& old_handles, std::vector< EntityHandle >& newhandles )
361 : : {
362 : : // get new handles for tagged entities
363 [ + - ][ + - ]: 115 : newhandles.resize( old_handles.size() );
364 [ + + ][ + - ]: 115 : ErrorCode rval = mMB->tag_get_data( tag, old_handles, ( newhandles.empty() ) ? NULL : &newhandles[0] );CHKERR;
[ + - ][ - + ]
365 : :
366 : : // remove entities that were not reordered
367 [ + - ]: 115 : Range::iterator i = old_handles.begin();
368 : 115 : size_t w = 0;
369 [ + + ]: 510 : for( size_t r = 0; r < newhandles.size(); ++r )
370 : : {
371 [ + - ][ + - ]: 395 : if( 0 != newhandles[r] )
372 : : {
373 [ + - ][ + - ]: 395 : newhandles[w] = newhandles[r];
374 : 395 : ++w;
375 [ + - ]: 395 : ++i;
376 : : }
377 : : else
378 : : {
379 [ # # ]: 0 : i = old_handles.erase( i );
380 : : }
381 : : }
382 [ + - ]: 115 : newhandles.resize( w );
383 [ + - ][ - + ]: 115 : assert( newhandles.size() == old_handles.size() );
384 : 115 : return MB_SUCCESS;
385 : : }
386 : :
387 : 1 : ErrorCode ReorderTool::reorder_entities( Tag new_handles )
388 : : {
389 : : ErrorCode rval;
390 : :
391 [ + - ][ - + ]: 1 : rval = check_tag_type( mMB, new_handles, MB_TYPE_HANDLE, sizeof( EntityHandle ) );CHKERR;
392 : : EntityHandle defval;
393 [ + - ][ - + ]: 1 : rval = mMB->tag_get_default_value( new_handles, &defval );CHKERR;
394 [ - + ]: 1 : if( 0 != defval ) return error( MB_INDEX_OUT_OF_RANGE );
395 : :
396 : : // Can only reorder within same type/connectivity (or vertex/num_coords)
397 : : // groupings.
398 [ + - ][ + + ]: 12 : for( EntityType t = MBVERTEX; t < MBENTITYSET; ++t )
399 : : {
400 : : // Get list of all connectivity lengths (or vertex dimensions)
401 : : // that exist for type t.
402 [ + - ][ + - ]: 11 : TypeSequenceManager& seqs = mMB->sequence_manager()->entity_map( t );
403 [ + - ]: 11 : TypeSequenceManager::iterator i;
404 [ + - ]: 11 : std::set< int > values;
405 [ + - ][ + - ]: 13 : for( i = seqs.begin(); i != seqs.end(); ++i )
[ + - ][ + - ]
[ + + ]
406 : : {
407 [ + - ]: 2 : EntitySequence* seq = *i;
408 : : // 0 values per entity implies structured data, which
409 : : // we cannot reorder. Skip those.
410 [ + + ][ + - ]: 2 : if( t == MBVERTEX || 0 < seq->values_per_entity() ) values.insert( seq->values_per_entity() );
[ + - ][ + - ]
[ + - ][ + - ]
411 : : }
412 : :
413 : : // reorder primary data for each (type,size) tuple.
414 [ + - ]: 11 : std::set< int >::iterator j;
415 [ + - ][ + - ]: 13 : for( j = values.begin(); j != values.end(); ++j )
[ + + ]
416 : : {
417 [ + - ]: 2 : Range entities;
418 [ + - ][ + - ]: 2 : get_entities( t, *j, entities );
419 [ + - ]: 4 : std::vector< EntityHandle > handles;
420 [ + - ]: 2 : rval = get_reordered_handles( new_handles, entities, handles );
421 [ - + ][ # # ]: 2 : UNRECOVERABLE( rval );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
422 : :
423 [ + + ]: 2 : if( t == MBVERTEX )
424 : : {
425 [ + - ][ + - ]: 1 : std::vector< double > coords( entities.size() * 3 );
426 [ + - ][ + - ]: 1 : rval = mMB->get_coords( entities, &coords[0] );
427 [ - + ][ # # ]: 1 : UNRECOVERABLE( rval );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
428 [ + - ][ + - ]: 1 : rval = mMB->set_coords( &handles[0], handles.size(), &coords[0] );
[ + - ]
429 [ - + ][ # # ]: 1 : UNRECOVERABLE( rval );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
430 : : }
431 : : else
432 : : {
433 [ + - ]: 1 : std::vector< EntityHandle > conn;
434 [ + - ][ + - ]: 1 : conn.reserve( entities.size() * *j );
[ + - ]
435 [ + - ]: 2 : std::vector< EntityHandle > old_handles;
436 [ + - ][ + - ]: 1 : old_handles.resize( entities.size() );
437 [ + - ][ + - ]: 1 : std::copy( entities.begin(), entities.end(), old_handles.begin() );
[ + - ]
438 [ + - ][ + - ]: 1 : rval = mMB->get_connectivity( &old_handles[0], old_handles.size(), conn, false );
439 [ - + ][ # # ]: 1 : UNRECOVERABLE( rval );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
440 : 1 : old_handles.clear();
441 [ + - ]: 1 : old_handles = conn;
442 [ + - ]: 1 : rval = get_reordered_handles( new_handles, old_handles, conn );
443 [ - + ][ # # ]: 1 : UNRECOVERABLE( rval );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
444 [ + + ]: 37 : for( unsigned int h = 0; h < handles.size(); ++h )
445 : : {
446 [ + - ][ + - ]: 36 : rval = mMB->set_connectivity( handles[h], &conn[h * *j], *j );
[ + - ][ + - ]
[ + - ]
447 [ - + ][ # # ]: 36 : UNRECOVERABLE( rval );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
448 : 1 : }
449 : : }
450 : 2 : }
451 : 11 : }
452 : :
453 : : // now update tag data
454 [ + - ]: 1 : std::vector< Tag > tag_handles;
455 [ + - ]: 1 : mMB->tag_get_tags( tag_handles );
456 [ + + ]: 15 : for( size_t i = 0; i < tag_handles.size(); ++i )
457 : : {
458 [ + - ]: 14 : Tag tag = tag_handles[i];
459 [ + + ]: 14 : if( tag == new_handles ) // don't mess up mapping from old to new handles
460 : 1 : continue;
461 : :
462 [ + - ][ + + ]: 169 : for( EntityType t = MBVERTEX; t <= MBENTITYSET; ++t )
463 : : {
464 [ + - ]: 156 : rval = reorder_tag_data( t, new_handles, tag );
465 [ - + ][ # # ]: 156 : UNRECOVERABLE( rval );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
466 : : }
467 : : }
468 : :
469 [ + - ]: 1 : rval = update_set_contents( new_handles );
470 [ - + ][ # # ]: 1 : UNRECOVERABLE( rval );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
471 : :
472 : 1 : return MB_SUCCESS;
473 : : }
474 : :
475 : 156 : ErrorCode ReorderTool::reorder_tag_data( EntityType etype, Tag new_handles, Tag tag )
476 : : {
477 : : ErrorCode rval;
478 : :
479 : : int tagsize;
480 : : DataType tagtype;
481 [ + - ]: 156 : rval = mMB->tag_get_data_type( tag, tagtype );
482 [ - + ]: 156 : if( MB_SUCCESS != rval ) return error( rval );
483 [ + + ]: 156 : if( MB_TYPE_BIT == tagtype )
484 : 12 : tagsize = 1;
485 : : else
486 : : {
487 [ + - ]: 144 : rval = mMB->tag_get_bytes( tag, tagsize );
488 [ + + ]: 144 : if( MB_VARIABLE_DATA_LENGTH == rval )
489 : 12 : tagsize = -1;
490 [ - + ]: 132 : else if( MB_SUCCESS != rval )
491 : 0 : return error( rval );
492 : : }
493 : :
494 : : // we don't re-order set handles, so we don't care about sets
495 : : // unless the tag contains handles that need to be updated
496 [ + + ][ + + ]: 156 : if( MBENTITYSET == etype && MB_TYPE_HANDLE != tagtype ) return MB_SUCCESS;
497 : :
498 : : // get tagged entities
499 [ + - ]: 146 : Range old_tagged;
500 [ + - ]: 146 : rval = mMB->get_entities_by_type_and_tag( 0, etype, &tag, 0, 1, old_tagged );
501 [ - + ][ # # ]: 146 : if( MB_SUCCESS != rval && old_tagged.empty() ) return error( rval );
[ # # ][ - + ]
502 : :
503 : : // remove entities that were not reordered, unless the tag
504 : : // is handle type in which case we need to update the data
505 : : // for all entities, regardless of reordering.
506 [ + - ]: 292 : std::vector< EntityHandle > newhandles;
507 [ + + ]: 146 : if( MB_TYPE_HANDLE == tagtype )
508 [ + - ]: 36 : rval = get_reordered_handles( new_handles, old_tagged, newhandles );
509 : : else
510 [ + - ][ - + ]: 146 : rval = get_new_handles( new_handles, old_tagged, newhandles );CHKERR;
511 : :
512 [ + - ][ + + ]: 146 : if( old_tagged.empty() ) return MB_SUCCESS;
513 : :
514 : : // get copy of all tag data
515 [ + - ]: 22 : std::vector< unsigned char > buffer;
516 [ + - ]: 22 : std::vector< const void* > pointers;
517 [ + - ]: 22 : std::vector< int > sizes;
518 : : // if variable-length tag
519 [ + + ]: 11 : if( -1 == tagsize )
520 : : {
521 [ + - ][ + - ]: 1 : pointers.resize( old_tagged.size() );
522 [ + - ]: 1 : sizes.resize( pointers.size() );
523 [ + - ][ + - ]: 1 : rval = mMB->tag_get_by_ptr( tag, old_tagged, &pointers[0], &sizes[0] );CHKERR;
[ + - ][ - + ]
524 [ + - ]: 1 : int total = std::accumulate( sizes.begin(), sizes.end(), 0 );
525 : : DataType dtype;
526 [ + - ]: 1 : mMB->tag_get_data_type( tag, dtype );
527 : : int type_size;
528 [ + - - - : 1 : switch( dtype )
- - ]
529 : : {
530 : : case MB_TYPE_INTEGER:
531 : 1 : type_size = sizeof( int );
532 : 1 : break;
533 : : case MB_TYPE_DOUBLE:
534 : 0 : type_size = sizeof( double );
535 : 0 : break;
536 : : case MB_TYPE_HANDLE:
537 : 0 : type_size = sizeof( EntityHandle );
538 : 0 : break;
539 : : case MB_TYPE_BIT:
540 : 0 : type_size = 1;
541 : 0 : break;
542 : : case MB_TYPE_OPAQUE:
543 : 0 : type_size = 1;
544 : 0 : break;
545 : : default:
546 : 0 : return MB_TYPE_OUT_OF_RANGE;
547 : : }
548 [ + - ]: 1 : buffer.resize( total * type_size );
549 : 1 : size_t off = 0;
550 [ + + ]: 50 : for( size_t j = 0; j < pointers.size(); ++j )
551 : : {
552 [ + - ][ + - ]: 49 : memcpy( &buffer[off], pointers[j], type_size * sizes[j] );
[ + - ]
553 [ + - ][ + - ]: 49 : pointers[j] = &buffer[off];
554 [ + - ]: 49 : off += sizes[j] * type_size;
555 : : }
556 : : }
557 : : // if fixed-length tag
558 : : else
559 : : {
560 [ + - ][ + - ]: 10 : buffer.resize( old_tagged.size() * tagsize );
561 [ + - ][ + - ]: 10 : rval = mMB->tag_get_data( tag, old_tagged, &buffer[0] );CHKERR;
[ - + ]
562 : : }
563 : :
564 : : // if handle tag, update tag values for reordered handles
565 [ + + ]: 11 : if( MB_TYPE_HANDLE == tagtype )
566 : : {
567 [ - + ]: 4 : assert( !( buffer.size() % sizeof( EntityHandle ) ) );
568 [ + - ]: 4 : std::vector< unsigned char > buffer2( buffer.size() );
569 [ + - ]: 4 : rval = get_reordered_handles( new_handles, reinterpret_cast< const EntityHandle* >( &buffer[0] ),
570 [ + - ]: 4 : reinterpret_cast< EntityHandle* >( &buffer2[0] ),
571 [ + - ][ - + ]: 8 : buffer.size() / sizeof( EntityHandle ) );CHKERR;
572 : : // if var-length tag then do not do swap because pointers[] contains pointers
573 : : // into old buffer
574 [ - + ]: 4 : if( -1 == tagsize )
575 [ # # ][ # # ]: 0 : memcpy( &buffer[0], &buffer2[0], buffer.size() );
576 : : else
577 [ + - ]: 4 : buffer.swap( buffer2 );
578 : : }
579 : :
580 : : // store re-ordered tag data
581 [ + + ]: 11 : if( -1 == tagsize )
582 : : {
583 [ + - ][ + - ]: 1 : rval = mMB->tag_set_by_ptr( tag, &newhandles[0], newhandles.size(), &pointers[0], &sizes[0] );
[ + - ][ + - ]
584 : 1 : pointers.clear();
585 : 1 : sizes.clear();
586 : 1 : buffer.clear();
587 : : }
588 : : else
589 : : {
590 [ + - ][ + - ]: 10 : rval = mMB->tag_set_data( tag, &newhandles[0], newhandles.size(), &buffer[0] );
[ + - ]
591 : 10 : buffer.clear();
592 : : }
593 [ - + ]: 11 : CHKERR;
594 : :
595 : : // all permutations should be cyclical, but not all permuted
596 : : // entities necessarily had tag values, so we might need to delete
597 : : // tags for some entities
598 [ + - ]: 11 : std::sort( newhandles.begin(), newhandles.end() );
599 : 11 : std::vector< EntityHandle >::iterator k = newhandles.begin();
600 [ + - ]: 11 : Range::iterator i = old_tagged.begin();
601 [ + - ][ + - ]: 438 : while( i != old_tagged.end() )
[ + + ]
602 : : {
603 [ + - ][ + - ]: 843 : while( k != newhandles.end() && *k < *i )
[ + - ][ + - ]
[ + + ][ + - ]
[ + + # # ]
604 [ + - ]: 416 : ++k;
605 [ + - ][ - + ]: 427 : if( k == newhandles.end() ) break;
606 : :
607 [ + - ][ + - ]: 427 : if( *i == *k ) // what old_tagged -= newhandles
[ + - ]
608 [ + - ]: 427 : i = old_tagged.erase( i );
609 : : else
610 [ # # ]: 0 : ++i;
611 : : }
612 : :
613 [ + - ][ - + ]: 11 : if( !old_tagged.empty() )
614 : : {
615 [ # # ][ # # ]: 0 : rval = mMB->tag_delete_data( tag, old_tagged );CHKERR;
616 : : }
617 : :
618 : 167 : return MB_SUCCESS;
619 : : }
620 : :
621 : 1 : ErrorCode ReorderTool::update_set_contents( Tag nh_tag )
622 : : {
623 [ + - ]: 1 : Range sets;
624 [ + - ][ - + ]: 1 : ErrorCode rval = mMB->get_entities_by_type( 0, MBENTITYSET, sets );CHKERR;
625 : :
626 [ + - ][ + - ]: 2 : std::vector< EntityHandle > old_handles, new_handles;
627 [ + - ][ + - ]: 7 : for( Range::iterator i = sets.begin(); i != sets.end(); ++i )
[ + - ][ + - ]
[ + + ]
628 : : {
629 : : // If set is un-ordered...
630 : 6 : unsigned opts = 0;
631 [ + - ][ + - ]: 6 : mMB->get_meshset_options( *i, opts );
632 [ + + ]: 6 : if( !( opts & MESHSET_ORDERED ) )
633 : : {
634 [ + - ]: 5 : Range contents;
635 [ + - ][ + - ]: 5 : rval = mMB->get_entities_by_handle( *i, contents );CHKERR;
[ - + ]
636 : :
637 [ + - ][ - + ]: 5 : rval = get_new_handles( nh_tag, contents, new_handles );CHKERR;
638 : :
639 [ + - ][ + - ]: 10 : Range replace;
640 [ + - ]: 5 : std::sort( new_handles.begin(), new_handles.end() );
641 [ + - ]: 5 : Range::iterator hint = replace.begin();
642 [ + + ]: 96 : for( size_t j = 0; j < new_handles.size(); ++j )
643 [ + - ][ + - ]: 91 : hint = replace.insert( hint, new_handles[j] );
644 [ + - ][ + - ]: 10 : Range common = intersect( contents, replace );
645 [ + - ]: 5 : contents -= common;
646 [ + - ]: 5 : replace -= common;
647 [ + - ][ + - ]: 5 : assert( contents.size() == replace.size() );
[ - + ]
648 [ + - ][ + + ]: 5 : if( !contents.empty() )
649 : : {
650 [ + - ][ + - ]: 4 : rval = mMB->remove_entities( *i, contents );CHKERR;
[ - + ]
651 [ + - ][ + - ]: 5 : rval = mMB->add_entities( *i, replace );
[ + - ]
652 : 5 : }
653 : : }
654 : :
655 : : // If set is ordered...
656 : : else
657 : : {
658 : : // get set contents
659 : 1 : old_handles.clear();
660 [ + - ][ + - ]: 1 : rval = mMB->get_entities_by_handle( *i, old_handles );CHKERR;
[ - + ]
661 : :
662 : : // get new handles from old contained handles
663 [ + - ][ - + ]: 1 : rval = get_reordered_handles( nh_tag, old_handles, new_handles );CHKERR;
664 : :
665 [ + - ][ + - ]: 1 : rval = mMB->clear_meshset( &*i, 1 );CHKERR;
[ - + ]
666 : :
667 [ + - ][ + - ]: 1 : rval = mMB->add_entities( *i, &new_handles[0], new_handles.size() );CHKERR;
[ + - ][ - + ]
668 : : }
669 : : } // for each set
670 : :
671 : 2 : return MB_SUCCESS;
672 : : }
673 : :
674 [ + - ][ + - ]: 4 : } // namespace moab
|