LCOV - code coverage report
Current view: top level - src - ReorderTool.cpp (source / functions) Hit Total Coverage
Test: coverage_sk.info Lines: 305 331 92.1 %
Date: 2020-12-16 07:07:30 Functions: 16 17 94.1 %
Branches: 519 1126 46.1 %

           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

Generated by: LCOV version 1.11