MOAB: Mesh Oriented datABase  (version 5.4.0)
TagTest.cpp
Go to the documentation of this file.
00001 #include "moab/Core.hpp"
00002 #include "moab/Range.hpp"
00003 #include "TestUtil.hpp"
00004 #include <cstdlib>
00005 #include <algorithm>
00006 
00007 using namespace moab;
00008 
00009 void test_create_tag();
00010 void test_get_set_sparse_int();
00011 void test_get_set_dense_int();
00012 void test_get_set_dense_double();
00013 void test_get_set_bit();
00014 void test_get_by_tag();
00015 void test_get_by_tag_value();
00016 void test_get_by_tag_value_dense();
00017 void test_mesh_value();
00018 void test_get_pointers_sparse();
00019 void test_get_pointers_dense();
00020 void test_set_pointers_sparse();
00021 void test_set_pointers_dense();
00022 void test_get_entity_tags();
00023 void test_delete_sparse_tag();
00024 void test_delete_dense_tag();
00025 void test_delete_mesh_tag();
00026 void test_delete_sparse_data();
00027 void test_delete_dense_data();
00028 void test_delete_bit_data();
00029 void test_create_variable_length_tag();
00030 void test_get_set_variable_length_sparse();
00031 void test_get_set_variable_length_dense();
00032 void test_get_set_variable_length_mesh();
00033 void test_get_ents_with_default_value();
00034 void test_bit_tag_big();
00035 void test_clear_dense();
00036 void test_clear_sparse();
00037 void test_clear_bit();
00038 void test_clear_dense_varlen();
00039 void test_clear_sparse_varlen();
00040 void test_tag_iterate_sparse();
00041 void test_tag_iterate_dense();
00042 void test_tag_iterate_sparse_default();
00043 void test_tag_iterate_dense_default();
00044 void test_tag_iterate_invalid();
00045 
00046 void regression_one_entity_by_var_tag();
00047 void regression_tag_on_nonexistent_entity();
00048 
00049 int main()
00050 {
00051     int failures = 0;
00052 
00053     failures += RUN_TEST( test_create_tag );
00054     failures += RUN_TEST( test_get_set_sparse_int );
00055     failures += RUN_TEST( test_get_set_dense_int );
00056     failures += RUN_TEST( test_get_set_dense_double );
00057     failures += RUN_TEST( test_get_set_bit );
00058     failures += RUN_TEST( test_get_by_tag );
00059     failures += RUN_TEST( test_get_by_tag_value );
00060     failures += RUN_TEST( test_get_by_tag_value_dense );
00061     failures += RUN_TEST( test_mesh_value );
00062     failures += RUN_TEST( test_get_pointers_sparse );
00063     failures += RUN_TEST( test_get_pointers_dense );
00064     failures += RUN_TEST( test_set_pointers_sparse );
00065     failures += RUN_TEST( test_set_pointers_dense );
00066     failures += RUN_TEST( test_get_entity_tags );
00067     failures += RUN_TEST( test_delete_sparse_tag );
00068     failures += RUN_TEST( test_delete_dense_tag );
00069     failures += RUN_TEST( test_delete_mesh_tag );
00070     failures += RUN_TEST( test_delete_sparse_data );
00071     failures += RUN_TEST( test_delete_dense_data );
00072     failures += RUN_TEST( test_delete_bit_data );
00073     failures += RUN_TEST( test_create_variable_length_tag );
00074     failures += RUN_TEST( test_get_set_variable_length_sparse );
00075     failures += RUN_TEST( test_get_set_variable_length_dense );
00076     failures += RUN_TEST( test_get_set_variable_length_mesh );
00077     failures += RUN_TEST( test_get_ents_with_default_value );
00078     failures += RUN_TEST( test_bit_tag_big );
00079     failures += RUN_TEST( regression_one_entity_by_var_tag );
00080     failures += RUN_TEST( regression_tag_on_nonexistent_entity );
00081     failures += RUN_TEST( test_clear_dense );
00082     failures += RUN_TEST( test_clear_sparse );
00083     failures += RUN_TEST( test_clear_bit );
00084     failures += RUN_TEST( test_clear_dense_varlen );
00085     failures += RUN_TEST( test_clear_sparse_varlen );
00086     failures += RUN_TEST( test_tag_iterate_sparse );
00087     failures += RUN_TEST( test_tag_iterate_dense );
00088     failures += RUN_TEST( test_tag_iterate_sparse_default );
00089     failures += RUN_TEST( test_tag_iterate_dense_default );
00090     failures += RUN_TEST( test_tag_iterate_invalid );
00091 
00092     if( failures ) std::cerr << "<<<< " << failures << " TESTS FAILED >>>>" << std::endl;
00093 
00094     return failures;
00095 }
00096 
00097 void setup_mesh( Interface& mesh );
00098 
00099 Tag test_create_tag( Interface& mb,
00100                      const char* name,
00101                      int num_vals,
00102                      TagType storage,
00103                      DataType type,
00104                      const void* defval,
00105                      ErrorCode expect = MB_SUCCESS );
00106 
00107 Tag test_create_var_len_tag( Interface& mb,
00108                              const char* name,
00109                              TagType storage,
00110                              DataType type,
00111                              const void* defval,
00112                              int defval_size,
00113                              ErrorCode expect = MB_SUCCESS );
00114 
00115 enum SetMode
00116 {
00117     NORMAL,
00118     POINTER,
00119     ONE_VALUE
00120 };
00121 
00122 void test_get_set( const char* name,
00123                    int vals_per_ent,
00124                    TagType storage,
00125                    DataType type,
00126                    const void* some_values,
00127                    int num_values,
00128                    const void* default_value,
00129                    SetMode set_by_pointer = NORMAL,
00130                    bool get_by_pointer    = false );
00131 
00132 void test_get_set_variable_length( const char* name,
00133                                    TagType storage,
00134                                    DataType type,
00135                                    const void** values,
00136                                    const int* lengths,
00137                                    int num_values,
00138                                    const void* default_value,
00139                                    int default_value_length );
00140 
00141 void test_mesh_value( Interface& mb,
00142                       const char* tag_name,
00143                       unsigned tag_size,
00144                       TagType tag_storage,
00145                       DataType tag_type,
00146                       const void* value );
00147 
00148 Tag test_create_tag( Interface& mb,
00149                      const char* name,
00150                      int num_vals,
00151                      TagType storage,
00152                      DataType type,
00153                      const void* defval,
00154                      ErrorCode expect )
00155 {
00156     ErrorCode rval;
00157     Tag tag;
00158 
00159     rval = mb.tag_get_handle( name, num_vals, type, tag, storage | MB_TAG_EXCL, defval );
00160     if( expect != MB_SUCCESS )
00161     {
00162         CHECK_EQUAL( expect, rval );
00163         return 0;
00164     }
00165     CHECK_ERR( rval );
00166 
00167     std::string n;
00168     rval = mb.tag_get_name( tag, n );CHECK_ERR( rval );
00169     CHECK( n == name );
00170 
00171     Tag tag2;
00172     rval = mb.tag_get_handle( name, num_vals, type, tag2 );CHECK_ERR( rval );
00173     CHECK_EQUAL( tag, tag2 );
00174 
00175     int s;
00176     rval = mb.tag_get_length( tag, s );CHECK_ERR( rval );
00177     CHECK_EQUAL( num_vals, s );
00178 
00179     TagType t;
00180     rval = mb.tag_get_type( tag, t );CHECK_ERR( rval );
00181     CHECK_EQUAL( storage, t );
00182 
00183     DataType d;
00184     rval = mb.tag_get_data_type( tag, d );CHECK_ERR( rval );
00185     CHECK_EQUAL( type, d );
00186 
00187     int bytes;
00188     rval = mb.tag_get_bytes( tag, bytes );CHECK_ERR( rval );
00189     int exp_bytes = 0;
00190     switch( type )
00191     {
00192         case MB_TYPE_INTEGER:
00193             exp_bytes = num_vals * sizeof( int );
00194             break;
00195         case MB_TYPE_DOUBLE:
00196             exp_bytes = num_vals * sizeof( double );
00197             break;
00198         case MB_TYPE_HANDLE:
00199             exp_bytes = num_vals * sizeof( EntityHandle );
00200             break;
00201         case MB_TYPE_BIT:
00202             exp_bytes = 1;
00203             break;
00204         case MB_TYPE_OPAQUE:
00205             exp_bytes = num_vals;
00206             break;
00207     }
00208     CHECK_EQUAL( exp_bytes, bytes );
00209 
00210     std::vector< unsigned char > defv( bytes );
00211     rval = mb.tag_get_default_value( tag, &defv[0] );
00212     if( defval )
00213     {
00214         CHECK_ERR( rval );
00215         CHECK( !memcmp( defval, &defv[0], bytes ) );
00216     }
00217     else
00218     {
00219         CHECK_EQUAL( MB_ENTITY_NOT_FOUND, rval );
00220     }
00221 
00222     // make sure we can't create a second tag w/ the same name
00223     rval = mb.tag_get_handle( name, num_vals, type, tag2, storage | MB_TAG_EXCL, defval );
00224     CHECK_EQUAL( MB_ALREADY_ALLOCATED, rval );
00225     // we should get back the handle of the existing tag
00226     CHECK_EQUAL( tag, tag2 );
00227 
00228     return tag;
00229 }
00230 
00231 Tag test_create_var_len_tag( Interface& mb,
00232                              const char* name,
00233                              TagType storage,
00234                              DataType type,
00235                              const void* defval,
00236                              int defval_size,
00237                              ErrorCode expect )
00238 {
00239     ErrorCode rval;
00240     Tag tag;
00241 
00242     rval = mb.tag_get_handle( name, defval_size, type, tag, storage | MB_TAG_VARLEN | MB_TAG_EXCL, defval );
00243     if( expect != MB_SUCCESS )
00244     {
00245         CHECK_EQUAL( expect, rval );
00246         return 0;
00247     }
00248     CHECK_ERR( rval );
00249 
00250     std::string n;
00251     rval = mb.tag_get_name( tag, n );CHECK_ERR( rval );
00252     CHECK( n == name );
00253 
00254     Tag tag2;
00255     rval = mb.tag_get_handle( name, 0, type, tag2 );CHECK_ERR( rval );
00256     CHECK_EQUAL( tag, tag2 );
00257 
00258     int s;
00259     rval = mb.tag_get_bytes( tag, s );
00260     CHECK_EQUAL( MB_VARIABLE_DATA_LENGTH, rval );
00261     rval = mb.tag_get_length( tag, s );
00262     CHECK_EQUAL( MB_VARIABLE_DATA_LENGTH, rval );
00263     // CHECK_ERR(rval);
00264     // CHECK_EQUAL( MB_VARIABLE_LENGTH, s );
00265 
00266     TagType t;
00267     rval = mb.tag_get_type( tag, t );CHECK_ERR( rval );
00268     CHECK_EQUAL( storage, t );
00269 
00270     DataType d;
00271     rval = mb.tag_get_data_type( tag, d );CHECK_ERR( rval );
00272     CHECK_EQUAL( type, d );
00273 
00274     int size;
00275     const void* defv;
00276     rval = mb.tag_get_default_value( tag, defv, size );
00277     if( defval )
00278     {
00279         CHECK_ERR( rval );
00280         CHECK_EQUAL( defval_size, size );
00281         CHECK( !memcmp( defval, defv, size ) );
00282     }
00283     else
00284     {
00285         CHECK_EQUAL( MB_ENTITY_NOT_FOUND, rval );
00286     }
00287 
00288     // make sure we can't create a second tag w/ the same name
00289     rval = mb.tag_get_handle( name, defval_size, type, tag2, storage | MB_TAG_VARLEN | MB_TAG_EXCL );
00290     CHECK_EQUAL( MB_ALREADY_ALLOCATED, rval );
00291     // we should get back the handle of the existing tag
00292     CHECK_EQUAL( tag, tag2 );
00293 
00294     return tag;
00295 }
00296 
00297 void test_create_tag()
00298 {
00299     Core mb;
00300     unsigned char defval[] = { 1, 2, 3, 4, 0, 0, 0, 0 };
00301 
00302     // opaque tags
00303     test_create_tag( mb, "opaque_tag_sparse", 8, MB_TAG_SPARSE, MB_TYPE_OPAQUE, defval );
00304     test_create_tag( mb, "opaque_tag_dense", 4, MB_TAG_DENSE, MB_TYPE_OPAQUE, defval );
00305     test_create_tag( mb, "opaque_tag_dense2", 1, MB_TAG_DENSE, MB_TYPE_OPAQUE, 0 );
00306 
00307     // integer tags
00308     test_create_tag( mb, "int_tag_sparse", 1, MB_TAG_SPARSE, MB_TYPE_INTEGER, defval );
00309     test_create_tag( mb, "int_tag_dense", 8, MB_TAG_DENSE, MB_TYPE_INTEGER, 0 );
00310 
00311     // double tags
00312     double defval2[] = { 3.14159, 2.71828 };
00313     test_create_tag( mb, "dbl_tag_sparse", 1, MB_TAG_SPARSE, MB_TYPE_DOUBLE, 0 );
00314     test_create_tag( mb, "dbl_tag_dense", 2, MB_TAG_DENSE, MB_TYPE_DOUBLE, defval2 );
00315 
00316     // handle tags
00317     test_create_tag( mb, "h_tag_dense", 1, MB_TAG_DENSE, MB_TYPE_HANDLE, defval );
00318 
00319     // bit tags
00320     unsigned char def_bit_val = 0xBF;
00321     test_create_tag( mb, "bit_tag_1", 2, MB_TAG_BIT, MB_TYPE_BIT, &def_bit_val );
00322 }
00323 
00324 void test_create_variable_length_tag()
00325 {
00326     Core mb;
00327     unsigned char defval[] = { 1, 2, 3, 4, 0, 0, 0, 0 };
00328 
00329     // opaque tags
00330     const void* defptr = defval;
00331     test_create_var_len_tag( mb, "opaque_tag_sparse", MB_TAG_SPARSE, MB_TYPE_OPAQUE, defptr, 8 );
00332     test_create_var_len_tag( mb, "opaque_tag_dense", MB_TAG_DENSE, MB_TYPE_OPAQUE, defptr, 4 );
00333     test_create_var_len_tag( mb, "opaque_tag_dense2", MB_TAG_DENSE, MB_TYPE_OPAQUE, 0, 0 );
00334 
00335     // integer tags
00336     test_create_var_len_tag( mb, "int_tag_sparse", MB_TAG_SPARSE, MB_TYPE_INTEGER, defptr, 1 );
00337     test_create_var_len_tag( mb, "int_tag_dense", MB_TAG_DENSE, MB_TYPE_INTEGER, 0, 0 );
00338 
00339     // double tags
00340     double defval2[] = { 3.14159, 2.71828 };
00341     defptr           = defval2;
00342     test_create_var_len_tag( mb, "dbl_tag_sparse", MB_TAG_SPARSE, MB_TYPE_DOUBLE, 0, 0 );
00343     test_create_var_len_tag( mb, "dbl_tag_dense", MB_TAG_DENSE, MB_TYPE_DOUBLE, defptr, 2 );
00344 
00345     // handle tags
00346     test_create_var_len_tag( mb, "h_tag_dense", MB_TAG_DENSE, MB_TYPE_HANDLE, 0, 0 );
00347 }
00348 
00349 // Given a list of sequential values in memory (pointed to by 'concat'),
00350 // populate a list of pointers to to each value.  The number of values
00351 // is assumed to be the size of 'list'.  Individual values have a size of 'bytes'
00352 static void concat_to_list( const void* concat, std::vector< const void* >& list, size_t bytes )
00353 {
00354     const unsigned char* ptr                  = reinterpret_cast< const unsigned char* >( concat );
00355     std::vector< const void* >::iterator iter = list.begin();
00356     for( ; iter != list.end(); ++iter, ptr += bytes )
00357         *iter = ptr;
00358 }
00359 
00360 // test get/set of tag values
00361 void test_get_set( const char* name,
00362                    int vals_per_ent,
00363                    TagType storage,
00364                    DataType type,
00365                    const void* some_values,
00366                    int num_values,
00367                    const void* default_value,
00368                    SetMode set_mode,
00369                    bool get_by_pointer )
00370 {
00371     std::vector< unsigned char > data;
00372 
00373     // create mesh and tag
00374     Core moab;
00375     Interface& mb = moab;
00376     setup_mesh( mb );
00377     Tag tag = test_create_tag( mb, name, vals_per_ent, storage, type, default_value );
00378 
00379     // get some handles to work with
00380     Range entities;
00381     ErrorCode rval = mb.get_entities_by_handle( 0, entities );CHECK_ERR( rval );
00382     CHECK( !entities.empty() );
00383 
00384     int bytes = 0;
00385     switch( type )
00386     {
00387         case MB_TYPE_INTEGER:
00388             bytes = vals_per_ent * sizeof( int );
00389             break;
00390         case MB_TYPE_DOUBLE:
00391             bytes = vals_per_ent * sizeof( double );
00392             break;
00393         case MB_TYPE_HANDLE:
00394             bytes = vals_per_ent * sizeof( EntityHandle );
00395             break;
00396         case MB_TYPE_BIT:
00397             bytes = 1;
00398             break;
00399         case MB_TYPE_OPAQUE:
00400             bytes = vals_per_ent;
00401             break;
00402     }
00403 
00404     // split handles into four groups
00405     // a) a single handle
00406     // b) some non-consecutive handles in an array
00407     // c) some handles in an Range
00408     // d) remaining handles (remaining in 'entities');
00409     EntityHandle one_handle;
00410     Range::iterator it = entities.begin() += entities.size() / 2;
00411     one_handle         = *it;
00412     entities.erase( it );
00413 
00414     Range handle_range;
00415     std::vector< EntityHandle > handle_list;
00416     for( Range::const_pair_iterator i = entities.const_pair_begin(); i != entities.const_pair_end(); ++i )
00417     {
00418         if( i->first == i->second || i->second - i->first == 1 )
00419         {
00420             EntityHandle h1 = i->first, h2 = i->second;
00421             ++i;
00422             handle_range.insert( h1, h2 );
00423         }
00424         else
00425         {
00426             EntityHandle mid = (EntityHandle)( i->first + ( i->second - i->first + 1 ) / 2 );
00427             handle_list.push_back( mid );
00428             handle_range.insert( mid + 1, i->second );
00429         }
00430     }
00431     entities = subtract( entities, handle_range );
00432     for( unsigned i = 0; i < handle_list.size(); ++i )
00433         entities.erase( handle_list[i] );
00434 
00435     // try getting/setting single handle value
00436 
00437     std::vector< const void* > list( 1 );
00438     if( set_mode == NORMAL )
00439     {
00440         rval = mb.tag_set_data( tag, &one_handle, 1, some_values );
00441     }
00442     else if( set_mode == POINTER )
00443     {
00444         list[0] = some_values;
00445         rval    = mb.tag_set_by_ptr( tag, &one_handle, 1, &list[0] );
00446     }
00447     else
00448     {  // set_mode == ONE_VALUE
00449         rval = mb.tag_clear_data( tag, &one_handle, 1, some_values );
00450     }
00451     CHECK_ERR( rval );
00452     data.resize( bytes );
00453     if( get_by_pointer )
00454     {
00455         // test that correct size is returned
00456         int rsize;
00457         rval = mb.tag_get_by_ptr( tag, &one_handle, 1, &list[0], &rsize );CHECK_ERR( rval );
00458         CHECK_EQUAL( vals_per_ent, rsize );
00459         // try again with NULL size pointer
00460         list[0] = 0;
00461         rval    = mb.tag_get_by_ptr( tag, &one_handle, 1, &list[0] );CHECK_ERR( rval );
00462         CHECK( !memcmp( some_values, list[0], bytes ) );
00463     }
00464     else
00465     {
00466         rval = mb.tag_get_data( tag, &one_handle, 1, &data[0] );CHECK_ERR( rval );
00467         CHECK( !memcmp( some_values, &data[0], bytes ) );
00468     }
00469 
00470     // try getting/setting for arrays of handles
00471 
00472     const int step = std::min( (int)handle_list.size(), num_values );
00473     data.resize( step * bytes );
00474     for( int i = 0; i < (int)handle_list.size(); i += step )
00475     {
00476         const int n = std::min( (int)handle_list.size() - i, step );
00477         list.resize( n );
00478         if( set_mode == NORMAL )
00479         {
00480             rval = mb.tag_set_data( tag, &handle_list[i], n, some_values );
00481         }
00482         else if( set_mode == POINTER )
00483         {
00484             concat_to_list( some_values, list, bytes );
00485             rval = mb.tag_set_by_ptr( tag, &handle_list[i], n, &list[0] );
00486         }
00487         else
00488         {
00489             rval = mb.tag_clear_data( tag, &handle_list[i], n, some_values );
00490         }
00491         CHECK_ERR( rval );
00492 
00493         if( get_by_pointer )
00494         {
00495             // check that valid sizes are returned if requested
00496             std::vector< int > rsizes( n, 0 );
00497             rval = mb.tag_get_by_ptr( tag, &handle_list[i], n, &list[0], &rsizes[0] );CHECK_ERR( rval );
00498             for( int j = 0; j < n; ++j )
00499                 CHECK_EQUAL( vals_per_ent, rsizes[j] );
00500             // query a second time to verify that it works w/ NULL size array
00501             list.clear();
00502             list.resize( n, 0 );
00503             rval = mb.tag_get_by_ptr( tag, &handle_list[i], n, &list[0] );
00504         }
00505         else
00506         {
00507             rval = mb.tag_get_data( tag, &handle_list[i], n, &data[0] );
00508             concat_to_list( &data[0], list, bytes );
00509         }
00510         CHECK_ERR( rval );
00511 
00512         const unsigned char* ptr = reinterpret_cast< const unsigned char* >( some_values );
00513         for( int j = 0; j < n; ++j, ptr += bytes )
00514             CHECK( !memcmp( ptr, list[j], bytes ) );
00515     }
00516 
00517     // try getting/setting for Range of handles
00518 
00519     // set data for range
00520     if( set_mode == NORMAL )
00521     {
00522         std::vector< unsigned char > input_data( handle_range.size() * bytes );
00523         for( int i = 0; i < (int)input_data.size(); i += num_values * bytes )
00524             memcpy( &input_data[i], some_values, std::min( (int)input_data.size() - i, num_values * bytes ) );
00525         rval = mb.tag_set_data( tag, handle_range, &input_data[0] );
00526     }
00527     else if( set_mode == POINTER )
00528     {
00529         list.resize( num_values );
00530         concat_to_list( some_values, list, bytes );
00531         while( list.size() < handle_range.size() )
00532         {
00533             size_t s = list.size();
00534             list.resize( 2 * s );
00535             std::copy( list.begin(), list.begin() + s, list.begin() + s );
00536         }
00537         rval = mb.tag_set_by_ptr( tag, handle_range, &list[0] );
00538     }
00539     else
00540     {
00541         rval = mb.tag_clear_data( tag, handle_range, some_values );
00542     }
00543     CHECK_ERR( rval );
00544 
00545     // get data for range
00546     list.clear();
00547     list.resize( handle_range.size(), 0 );
00548     if( get_by_pointer )
00549     {
00550         // check that valid sizes are returned if requested
00551         std::vector< int > rsizes( handle_range.size(), 0 );
00552         rval = mb.tag_get_by_ptr( tag, handle_range, &list[0], &rsizes[0] );CHECK_ERR( rval );
00553         for( size_t j = 0; j < handle_range.size(); ++j )
00554             CHECK_EQUAL( vals_per_ent, rsizes[j] );
00555         // query w/ NULL size array to make sure that works also
00556         list.clear();
00557         list.resize( handle_range.size(), 0 );
00558         rval = mb.tag_get_by_ptr( tag, handle_range, &list[0] );
00559     }
00560     else
00561     {
00562         data.resize( handle_range.size() * bytes );
00563         concat_to_list( &data[0], list, bytes );
00564         rval = mb.tag_get_data( tag, handle_range, &data[0] );
00565     }
00566     CHECK_ERR( rval );
00567 
00568     // compare values
00569     const bool dstep = ( set_mode != ONE_VALUE );
00570     for( size_t i = 0; i < list.size(); ++i )
00571     {
00572         CHECK( list[i * dstep] != NULL );
00573         const void* ptr = reinterpret_cast< const char* >( some_values ) + ( i % num_values ) * bytes;
00574         CHECK( !memcmp( list[i * dstep], ptr, bytes ) );
00575     }
00576 
00577     // try getting unset values
00578 
00579     list.resize( entities.size() );
00580     if( get_by_pointer )
00581     {
00582         rval = mb.tag_get_by_ptr( tag, entities, &list[0] );
00583     }
00584     else
00585     {
00586         data.clear(), data.resize( entities.size() * bytes, '\001' );
00587         concat_to_list( &data[0], list, bytes );
00588         rval = mb.tag_get_data( tag, entities, &data[0] );
00589     }
00590     // if there was a default value, we should have gotten it for all unset entities
00591     if( default_value )
00592     {
00593         CHECK_ERR( rval );
00594         for( unsigned i = 0; i < entities.size(); ++i )
00595             CHECK( !memcmp( default_value, list[i], bytes ) );
00596     }
00597     // otherwise we should get MB_TAG_NOT_FOUND, *unless* the tag
00598     // is dense, in which case we /might/ get all zero bytes instead.
00599     else if( MB_TAG_NOT_FOUND != rval )
00600     {
00601         CHECK_EQUAL( MB_TAG_DENSE, storage );
00602         std::vector< unsigned char > zeros( bytes, 0 );
00603         for( unsigned i = 0; i < entities.size(); ++i )
00604             CHECK( !memcmp( &zeros[0], list[i], bytes ) );
00605     }
00606 
00607     // Check that handles for other entities didn't change.
00608 
00609     // Ignore get_by_pointer/set_by_pointer flags from here on.
00610     // We've established (hopefully) that both methods work in
00611     // the above code.  Now we just want to verify correct values,
00612     // regardless of the API used to get them.
00613 
00614     // one handle
00615     data.resize( bytes );
00616     rval = mb.tag_get_data( tag, &one_handle, 1, &data[0] );CHECK_ERR( rval );
00617     CHECK( !memcmp( some_values, &data[0], bytes ) );
00618 
00619     // array values
00620     data.resize( step * bytes );
00621     for( int i = 0; i < (int)handle_list.size(); i += step )
00622     {
00623         const int n = std::min( (int)handle_list.size() - i, step );
00624         rval        = mb.tag_get_data( tag, &handle_list[i], n, &data[0] );CHECK_ERR( rval );
00625         CHECK( !memcmp( some_values, &data[0], step * bytes ) );
00626         rval = mb.tag_set_data( tag, &handle_list[i], n, some_values );CHECK_ERR( rval );
00627     }
00628 
00629     // range values
00630     list.clear();
00631     list.resize( handle_range.size(), 0 );
00632     rval = mb.tag_get_by_ptr( tag, handle_range, &list[0] );CHECK_ERR( rval );
00633     for( size_t i = 0; i < handle_range.size(); ++i )
00634     {
00635         const void* ptr = reinterpret_cast< const char* >( some_values ) + ( i % num_values ) * bytes;
00636         CHECK( !memcmp( ptr, list[i], bytes ) );
00637     }
00638 }
00639 
00640 void test_get_set_sparse_int()
00641 {
00642     const int data[]  = { 21, 00, 46, 30, 26, 63, 05, 49, 31, 39, 86, 77, 24, 37, 25, 98,
00643                          26, 20, 01, 54, 16, 28, 55, 49, 96, 18, 28, 18, 53, 00, 80, 48 };
00644     const int num_val = sizeof( data ) / sizeof( data[0] );
00645 
00646     test_get_set( "sparse_int", 2, MB_TAG_SPARSE, MB_TYPE_INTEGER, data, num_val / 2, 0 );
00647 
00648     const int defaultval = 19740508;
00649     test_get_set( "sparse_int_def", 1, MB_TAG_SPARSE, MB_TYPE_INTEGER, data, num_val, &defaultval );
00650 }
00651 
00652 void test_get_set_dense_int()
00653 {
00654     const int data[]  = { 231, 416, 294, 504, 318, 558, 494, 006, 464, 648, 737, 045, 179, 852, 944, 336,
00655                          773, 248, 434, 615, 677, 667, 521, 748, 820, 533, 955, 300, 108, 726, 747, 597 };
00656     const int num_val = sizeof( data ) / sizeof( data[0] );
00657 
00658     test_get_set( "dense_int", 1, MB_TAG_DENSE, MB_TYPE_INTEGER, data, num_val, 0 );
00659 
00660     const int defaultval[] = { 5, 8, 1974 };
00661     test_get_set( "dense_int_def", 3, MB_TAG_DENSE, MB_TYPE_INTEGER, data, num_val / 3, defaultval );
00662 }
00663 
00664 void test_get_set_dense_double()
00665 {
00666     const double pi     = 3.1415926535897931;
00667     const double e      = 2.7182818284590451;
00668     const double data[] = { 1,      1.,     pi,     e,      2,      1. / 2, 2 * pi, e / 2,  3,      1. / 3,
00669                             3 * pi, e / 3,  4,      1. / 4, 4 * pi, e / 4,  5,      1. / 5, 5 * pi, e / 5,
00670                             6,      1. / 6, 6 * pi, e / 6,  0,      100,    1000,   10000 };
00671     const int num_val   = sizeof( data ) / sizeof( data[0] );
00672 
00673     test_get_set( "dense_dbl", 1, MB_TAG_DENSE, MB_TYPE_DOUBLE, data, num_val, 0 );
00674 
00675     const double defaultval[] = { 0.11, 0.22 };
00676     test_get_set( "dense_dbl_def", 2, MB_TAG_DENSE, MB_TYPE_DOUBLE, data, num_val / 2, defaultval );
00677 }
00678 
00679 void test_get_pointers_sparse()
00680 {
00681     const double data[] = { 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16 };
00682     const int num_val   = sizeof( data ) / sizeof( data[0] );
00683 
00684     test_get_set( "sparse_dbl_ptr", 2, MB_TAG_SPARSE, MB_TYPE_DOUBLE, data, num_val / 2, 0, NORMAL, true );
00685 
00686     const double defaultval[] = { -1, -2 };
00687     test_get_set( "sparse_dbl_ptr_def", 2, MB_TAG_SPARSE, MB_TYPE_DOUBLE, data, num_val / 2, defaultval, NORMAL, true );
00688 }
00689 
00690 void test_get_pointers_dense()
00691 {
00692     const unsigned char data[] = "a few aribtrary bytes entered as a string";
00693     const int num_val          = sizeof( data ) / sizeof( data[0] );
00694 
00695     test_get_set( "dense_byte_ptr", 2, MB_TAG_DENSE, MB_TYPE_OPAQUE, data, num_val / 2, 0, NORMAL, true );
00696 
00697     const unsigned char defaultval[] = "XY";
00698     test_get_set( "dense_byte_ptr_def", 2, MB_TAG_DENSE, MB_TYPE_OPAQUE, data, num_val / 2, defaultval, NORMAL, true );
00699 }
00700 
00701 void test_set_pointers_sparse()
00702 {
00703     const double data[] = { 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16 };
00704     const int num_val   = sizeof( data ) / sizeof( data[0] );
00705 
00706     test_get_set( "sparse_dbl_ptr", 2, MB_TAG_SPARSE, MB_TYPE_DOUBLE, data, num_val / 2, 0, POINTER, false );
00707 
00708     const double defaultval[] = { -1, -2 };
00709     test_get_set( "sparse_dbl_ptr_def", 2, MB_TAG_SPARSE, MB_TYPE_DOUBLE, data, num_val / 2, defaultval, POINTER,
00710                   false );
00711 }
00712 
00713 void test_set_pointers_dense()
00714 {
00715     const unsigned char data[] = "a few aribtrary bytes entered as a string";
00716     const int num_val          = sizeof( data ) / sizeof( data[0] );
00717 
00718     test_get_set( "dense_byte_ptr", 2, MB_TAG_DENSE, MB_TYPE_OPAQUE, data, num_val / 2, 0, POINTER, false );
00719 
00720     const unsigned char defaultval[] = "XY";
00721     test_get_set( "dense_byte_ptr_def", 2, MB_TAG_DENSE, MB_TYPE_OPAQUE, data, num_val / 2, defaultval, POINTER,
00722                   false );
00723 
00724     const double dbldata[3] = { 1.0, 2.0, 3.0 };
00725     const int dbl_num_val   = sizeof( dbldata ) / sizeof( double );
00726 
00727     test_get_set( "dense_double_ptr", 3, MB_TAG_DENSE, MB_TYPE_DOUBLE, dbldata, dbl_num_val, 0, POINTER, false );
00728 
00729     const double dbldefaultval[3] = { 0.0, 0.0, 0.0 };
00730     test_get_set( "dense_byte_ptr_def", 3, MB_TAG_DENSE, MB_TYPE_DOUBLE, dbldata, dbl_num_val, dbldefaultval, POINTER,
00731                   false );
00732 }
00733 
00734 void test_clear_dense()
00735 {
00736     const int int_val = 0xcab;
00737     test_get_set( "clear_dense_int", 1, MB_TAG_DENSE, MB_TYPE_INTEGER, &int_val, 1, 0, ONE_VALUE, false );
00738 
00739     const double dbl_val[]     = { 3.14159, -3.14159 };
00740     const double default_val[] = { -2, 5 };
00741     test_get_set( "clear_dense_double", 2, MB_TAG_DENSE, MB_TYPE_DOUBLE, &dbl_val, 1, default_val, ONE_VALUE, false );
00742 }
00743 
00744 void test_clear_sparse()
00745 {
00746     const int int_val = 0xcab;
00747     test_get_set( "clear_sparse_int", 1, MB_TAG_SPARSE, MB_TYPE_INTEGER, &int_val, 1, 0, ONE_VALUE, false );
00748 
00749     const double dbl_val[]     = { 3.14159, -3.14159 };
00750     const double default_val[] = { -2, 5 };
00751     test_get_set( "clear_sparse_double", 2, MB_TAG_SPARSE, MB_TYPE_DOUBLE, &dbl_val, 1, default_val, ONE_VALUE, false );
00752 }
00753 
00754 void test_get_set_bit()
00755 {
00756     // create mesh and tag
00757     Core moab;
00758     Interface& mb = moab;
00759     setup_mesh( mb );
00760     Tag tag = test_create_tag( mb, "bit_val", 2, MB_TAG_BIT, MB_TYPE_BIT, 0 );
00761 
00762     // get some handles to work with
00763     Range entities;
00764     ErrorCode rval = mb.get_entities_by_handle( 0, entities );CHECK_ERR( rval );
00765     CHECK( !entities.empty() );
00766 
00767     // set bits on every entity
00768     unsigned counter = 0;
00769     for( Range::iterator i = entities.begin(); i != entities.end(); ++i )
00770     {
00771         srand( counter++ );
00772         unsigned char bits = (unsigned char)( rand() & 3 );
00773         rval               = mb.tag_set_data( tag, &*i, 1, &bits );CHECK_ERR( rval );
00774         unsigned char bits_out = 0;
00775         rval                   = mb.tag_get_data( tag, &*i, 1, &bits_out );CHECK_ERR( rval );
00776         CHECK_EQUAL( bits, bits_out );
00777     }
00778 
00779     // test default value
00780     unsigned char defval = '\003';
00781     unsigned char zero   = '\0';
00782     Tag tag2             = test_create_tag( mb, "bit_val2", 3, MB_TAG_BIT, MB_TYPE_BIT, &defval );
00783     CHECK( entities.size() >= 3 );
00784     Range::iterator j = entities.begin();
00785     EntityHandle h1   = *j;
00786     ++j;
00787     EntityHandle h2 = *j;
00788     ++j;
00789     EntityHandle h3 = *j;
00790     ++j;
00791     rval = mb.tag_set_data( tag2, &h1, 1, &zero );CHECK_ERR( rval );
00792     rval = mb.tag_set_data( tag2, &h3, 1, &zero );CHECK_ERR( rval );
00793     unsigned char byte;
00794     rval = mb.tag_get_data( tag2, &h2, 1, &byte );CHECK_ERR( rval );
00795     CHECK_EQUAL( defval, byte );
00796     rval = mb.tag_get_data( tag2, &h1, 1, &byte );CHECK_ERR( rval );
00797     CHECK_EQUAL( zero, byte );
00798     rval = mb.tag_get_data( tag2, &h3, 1, &byte );CHECK_ERR( rval );
00799     CHECK_EQUAL( zero, byte );
00800 
00801     // test default value for uninitialized data (tag not set for any entity)
00802     defval   = '\002';
00803     Tag tag3 = test_create_tag( mb, "bit_val3", 2, MB_TAG_BIT, MB_TYPE_BIT, &defval );
00804     rval     = mb.tag_get_data( tag3, &h2, 1, &byte );CHECK_ERR( rval );
00805     CHECK_EQUAL( defval, byte );
00806 }
00807 
00808 void test_clear_bit()
00809 {
00810     // create mesh and tag
00811     Core moab;
00812     Interface& mb = moab;
00813     setup_mesh( mb );
00814     Tag tag = test_create_tag( mb, "clear_bit_val", 2, MB_TAG_BIT, MB_TYPE_BIT, 0 );
00815 
00816     // get some handles to work with
00817     Range entities;
00818     ErrorCode rval = mb.get_entities_by_handle( 0, entities );CHECK_ERR( rval );
00819     CHECK( !entities.empty() );
00820 
00821     const unsigned char bits = 2;
00822     rval                     = mb.tag_clear_data( tag, entities, &bits );CHECK_ERR( rval );
00823 
00824     // set bits on every entity
00825     for( Range::iterator i = entities.begin(); i != entities.end(); ++i )
00826     {
00827         unsigned char bits_out = 0;
00828         rval                   = mb.tag_get_data( tag, &*i, 1, &bits_out );
00829         CHECK_EQUAL( bits, bits_out );
00830     }
00831 }
00832 
00833 void test_get_by_tag()
00834 {
00835     // create mesh and tag
00836     Core moab;
00837     Interface& mb = moab;
00838     setup_mesh( mb );
00839     Tag tag = test_create_tag( mb, "sparse_count", 1, MB_TAG_SPARSE, MB_TYPE_INTEGER, 0 );
00840 
00841     // get some handles to work with
00842     Range entities;
00843     ErrorCode rval = mb.get_entities_by_type( 0, MBVERTEX, entities );CHECK_ERR( rval );
00844     CHECK( !entities.empty() );
00845 
00846     // get five handles
00847     CHECK( entities.size() > 6 );
00848     EntityHandle arr[5] = { *( entities.begin() += entities.size() / 6 ),
00849                             *( entities.begin() += 2 * entities.size() / 6 ),
00850                             *( entities.begin() += 3 * entities.size() / 6 ),
00851                             *( entities.begin() += 4 * entities.size() / 6 ),
00852                             *( entities.begin() += 5 * entities.size() / 6 ) };
00853     int values[5]       = { 1, 2, 3, 4, 5 };
00854     rval                = mb.tag_set_data( tag, arr, 5, values );CHECK_ERR( rval );
00855     const void* const valarr[1] = { 0 };
00856 
00857     // put some in a mesh set
00858     EntityHandle set;
00859     const int num_in_set = 3;
00860     rval                 = mb.create_meshset( 0, set );CHECK_ERR( rval );
00861     rval = mb.add_entities( set, arr, num_in_set );CHECK_ERR( rval );
00862 
00863     // try for whole mesh will null tag value array
00864     int count = -1;
00865     rval      = mb.get_number_entities_by_type_and_tag( 0, MBVERTEX, &tag, 0, 1, count );CHECK_ERR( rval );
00866     CHECK_EQUAL( 5, count );
00867 
00868     // try for whole mesh will null tag value, but non-null array
00869     count = -1;
00870     rval  = mb.get_number_entities_by_type_and_tag( 0, MBVERTEX, &tag, valarr, 1, count );CHECK_ERR( rval );
00871     CHECK_EQUAL( 5, count );
00872 
00873     // try for mesh set
00874     rval = mb.get_number_entities_by_type_and_tag( set, MBVERTEX, &tag, 0, 1, count );CHECK_ERR( rval );
00875     CHECK_EQUAL( num_in_set, count );
00876 
00877     // try for whole mesh will null tag value array
00878     Range found;
00879     rval = mb.get_entities_by_type_and_tag( 0, MBVERTEX, &tag, 0, 1, found );CHECK_ERR( rval );
00880     CHECK_EQUAL( 5u, (unsigned)found.size() );
00881     Range::iterator i = found.begin();
00882     CHECK_EQUAL( arr[0], *i );
00883     ++i;
00884     CHECK_EQUAL( arr[1], *i );
00885     ++i;
00886     CHECK_EQUAL( arr[2], *i );
00887     ++i;
00888     CHECK_EQUAL( arr[3], *i );
00889     ++i;
00890     CHECK_EQUAL( arr[4], *i );
00891 
00892     // try for whole mesh will null tag value, but non-null array
00893     found.clear();
00894     rval = mb.get_entities_by_type_and_tag( 0, MBVERTEX, &tag, valarr, 1, found );CHECK_ERR( rval );
00895     CHECK_EQUAL( 5u, (unsigned)found.size() );
00896     i = found.begin();
00897     CHECK_EQUAL( arr[0], *i );
00898     ++i;
00899     CHECK_EQUAL( arr[1], *i );
00900     ++i;
00901     CHECK_EQUAL( arr[2], *i );
00902     ++i;
00903     CHECK_EQUAL( arr[3], *i );
00904     ++i;
00905     CHECK_EQUAL( arr[4], *i );
00906 
00907     // try for mesh set
00908     found.clear();
00909     rval = mb.get_entities_by_type_and_tag( set, MBVERTEX, &tag, 0, 1, found );CHECK_ERR( rval );
00910     CHECK_EQUAL( 3u, (unsigned)found.size() );
00911     i = found.begin();
00912     CHECK_EQUAL( arr[0], *i );
00913     ++i;
00914     CHECK_EQUAL( arr[1], *i );
00915     ++i;
00916     CHECK_EQUAL( arr[2], *i );
00917 }
00918 
00919 void test_get_by_tag_value()
00920 {
00921     // create mesh and tag
00922     Core moab;
00923     Interface& mb = moab;
00924     setup_mesh( mb );
00925     Tag tag = test_create_tag( mb, "sparse_count", 1, MB_TAG_SPARSE, MB_TYPE_INTEGER, 0 );
00926 
00927     // get some handles to work with
00928     Range entities;
00929     ErrorCode rval = mb.get_entities_by_type( 0, MBVERTEX, entities );CHECK_ERR( rval );
00930     CHECK( !entities.empty() );
00931 
00932     // get five handles
00933     CHECK( entities.size() > 6 );
00934     EntityHandle arr[5] = { *( entities.begin() += entities.size() / 6 ),
00935                             *( entities.begin() += 2 * entities.size() / 6 ),
00936                             *( entities.begin() += 3 * entities.size() / 6 ),
00937                             *( entities.begin() += 4 * entities.size() / 6 ),
00938                             *( entities.begin() += 5 * entities.size() / 6 ) };
00939     int values[5]       = { 0xBEEF, 0xBEEF, 0xBEEF, 0xBEEF, 0xBEEF };
00940     rval                = mb.tag_set_data( tag, arr, 5, values );CHECK_ERR( rval );
00941     const void* const valarr[1] = { values };
00942 
00943     // put some in a mesh set
00944     EntityHandle set;
00945     const int num_in_set = 3;
00946     rval                 = mb.create_meshset( 0, set );CHECK_ERR( rval );
00947     rval = mb.add_entities( set, arr, num_in_set );CHECK_ERR( rval );
00948 
00949     // try for whole mesh
00950     int count = -1;
00951     rval      = mb.get_number_entities_by_type_and_tag( 0, MBVERTEX, &tag, valarr, 1, count );CHECK_ERR( rval );
00952     CHECK_EQUAL( 5, count );
00953 
00954     // try for mesh set
00955     rval = mb.get_number_entities_by_type_and_tag( set, MBVERTEX, &tag, valarr, 1, count );CHECK_ERR( rval );
00956     CHECK_EQUAL( num_in_set, count );
00957 
00958     // try for whole mesh
00959     Range found;
00960     rval = mb.get_entities_by_type_and_tag( 0, MBVERTEX, &tag, valarr, 1, found );CHECK_ERR( rval );
00961     CHECK_EQUAL( 5u, (unsigned)found.size() );
00962     Range::iterator i = found.begin();
00963     CHECK_EQUAL( arr[0], *i );
00964     ++i;
00965     CHECK_EQUAL( arr[1], *i );
00966     ++i;
00967     CHECK_EQUAL( arr[2], *i );
00968     ++i;
00969     CHECK_EQUAL( arr[3], *i );
00970     ++i;
00971     CHECK_EQUAL( arr[4], *i );  //++i;
00972 
00973     // try for mesh set
00974     found.clear();
00975     rval = mb.get_entities_by_type_and_tag( set, MBVERTEX, &tag, valarr, 1, found );CHECK_ERR( rval );
00976     CHECK_EQUAL( 3u, (unsigned)found.size() );
00977     i = found.begin();
00978     CHECK_EQUAL( arr[0], *i );
00979     ++i;
00980     CHECK_EQUAL( arr[1], *i );
00981     ++i;
00982     CHECK_EQUAL( arr[2], *i );  //++i;
00983 }
00984 
00985 void test_get_by_tag_value_dense()
00986 {
00987     // create mesh and tag
00988     ErrorCode rval;
00989     Core moab;
00990     Interface& mb = moab;
00991     setup_mesh( mb );
00992     const int def_val  = 0xABCD;
00993     const int fill_val = 0xBEEF;
00994     const int find_val = 0xFEED;
00995     Tag tag            = test_create_tag( mb, "dense_gbv", 1, MB_TAG_DENSE, MB_TYPE_INTEGER, &def_val );
00996 
00997     // get some handles to work with
00998     Range elements, vertices, results;
00999     rval = mb.get_entities_by_type( 0, MBHEX, elements );CHECK_ERR( rval );
01000     rval = mb.get_entities_by_type( 0, MBVERTEX, vertices );CHECK_ERR( rval );
01001     CHECK( !elements.empty() );
01002 
01003     // set tag on all vertices to fill_val
01004     rval = mb.tag_clear_data( tag, vertices, &fill_val );CHECK_ERR( rval );
01005 
01006     // select three handles
01007     CHECK( elements.size() > 4 );
01008     EntityHandle arr[3] = { *( elements.begin() += elements.size() / 4 ),
01009                             *( elements.begin() += 2 * elements.size() / 4 ),
01010                             *( elements.begin() += 3 * elements.size() / 4 ) };
01011     int values[3]       = { find_val, find_val, find_val };
01012     rval                = mb.tag_set_data( tag, arr, 3, values );CHECK_ERR( rval );
01013 
01014     // get the entities tagged with 'find_val'
01015     const void* const findarr[1] = { &find_val };
01016     results.clear();
01017     rval = mb.get_entities_by_type_and_tag( 0, MBHEX, &tag, findarr, 1, results );CHECK_ERR( rval );
01018     CHECK_EQUAL( (size_t)3, results.size() );
01019     CHECK_EQUAL( arr[0], results.front() );
01020     CHECK_EQUAL( arr[1], *++results.begin() );
01021     CHECK_EQUAL( arr[2], results.back() );
01022 
01023     // should get no vertices
01024     results.clear();
01025     rval = mb.get_entities_by_type_and_tag( 0, MBVERTEX, &tag, findarr, 1, results );CHECK_ERR( rval );
01026     CHECK( results.empty() );
01027 
01028     // try intersecting with an existing range
01029     results = elements;
01030     results.erase( arr[1] );
01031     results.insert( vertices.front() );
01032     rval = mb.get_entities_by_type_and_tag( 0, MBHEX, &tag, findarr, 1, results, Interface::INTERSECT );CHECK_ERR( rval );
01033     CHECK_EQUAL( (size_t)2, results.size() );
01034     CHECK_EQUAL( arr[0], results.front() );
01035     CHECK_EQUAL( arr[2], results.back() );
01036 
01037     // try getting entities with default value
01038     const void* const defarr[1] = { &def_val };
01039     results.clear();
01040     rval = mb.get_entities_by_type_and_tag( 0, MBHEX, &tag, defarr, 1, results );CHECK_ERR( rval );
01041     CHECK_EQUAL( elements.size() - 3, results.size() );
01042     Range expected( elements );
01043     expected.erase( arr[0] );
01044     expected.erase( arr[1] );
01045     expected.erase( arr[2] );
01046     CHECK( expected == results );
01047 }
01048 
01049 void test_mesh_value( Interface& mb,
01050                       const char* tag_name,
01051                       unsigned tag_size,
01052                       TagType tag_storage,
01053                       DataType tag_type,
01054                       const void* value )
01055 {
01056     // create  tag
01057     Tag tag = test_create_tag( mb, tag_name, tag_size, tag_storage, tag_type, 0 );
01058 
01059     unsigned memcmp_size = tag_size;
01060     if( tag_storage == MB_TAG_BIT || tag_type == MB_TYPE_BIT )
01061         memcmp_size = 1;
01062     else if( tag_type == MB_TYPE_DOUBLE )
01063         memcmp_size = sizeof( double );
01064     else if( tag_type == MB_TYPE_INTEGER )
01065         memcmp_size = sizeof( int );
01066     if( tag_type == MB_TYPE_HANDLE ) memcmp_size = sizeof( EntityHandle );
01067 
01068     const EntityHandle mesh = 0;
01069     ErrorCode rval          = mb.tag_set_data( tag, &mesh, 1, value );CHECK_ERR( rval );
01070     std::vector< unsigned char > bytes( memcmp_size, 0 );
01071     rval = mb.tag_get_data( tag, &mesh, 1, &bytes[0] );CHECK_ERR( rval );
01072     CHECK( !memcmp( value, &bytes[0], memcmp_size ) );
01073 
01074     // test again, this time for default value
01075     std::string name2( tag_name );
01076     name2 += "_DEF";
01077     Tag tag2 = test_create_tag( mb, name2.c_str(), tag_size, tag_storage, tag_type, value );
01078     bytes.clear();
01079     bytes.resize( memcmp_size, 0 );
01080     rval = mb.tag_get_data( tag2, &mesh, 1, &bytes[0] );CHECK_ERR( rval );
01081     CHECK( !memcmp( value, &bytes[0], memcmp_size ) );
01082 }
01083 
01084 void test_mesh_value()
01085 {
01086     Core moab;
01087 
01088     double dval = -0.5;
01089     test_mesh_value( moab, "mvd", 1, MB_TAG_DENSE, MB_TYPE_DOUBLE, &dval );
01090 
01091     int sval = 42;
01092     test_mesh_value( moab, "mvs", 1, MB_TAG_SPARSE, MB_TYPE_INTEGER, &sval );
01093 
01094     EntityHandle mval = 0;
01095     test_mesh_value( moab, "mvm", 1, MB_TAG_MESH, MB_TYPE_HANDLE, &mval );
01096 
01097     unsigned char bits = '\002';
01098     test_mesh_value( moab, "mvb", 2, MB_TAG_BIT, MB_TYPE_BIT, &bits );
01099 }
01100 
01101 static void test_delete_type_tag( TagType storage )
01102 {
01103     Core moab;
01104     Interface& mb = moab;
01105     ErrorCode rval;
01106 
01107     setup_mesh( mb );
01108 
01109     // create tag
01110     int default_val     = 42;
01111     const char* tagname = "dead_tag";
01112     Tag tag             = test_create_tag( mb, tagname, 1, storage, MB_TYPE_INTEGER, &default_val );
01113 
01114     // get an entity handle to work with
01115     Range verts;
01116     rval = mb.get_entities_by_type( 0, MBVERTEX, verts );CHECK_ERR( rval );
01117     CHECK( !verts.empty() );
01118     EntityHandle handle = verts.front();
01119 
01120     // set tag value on entity
01121     int value = -5;
01122     if( storage != MB_TAG_MESH )
01123     {
01124         rval = mb.tag_set_data( tag, &handle, 1, &value );CHECK_ERR( rval );
01125     }
01126 
01127     // set tag value on mesh
01128     const EntityHandle mesh = 0;
01129     value                   = 2;
01130     rval                    = mb.tag_set_data( tag, &mesh, 1, &value );CHECK_ERR( rval );
01131 
01132     // delete tag
01133     rval = mb.tag_delete( tag );CHECK_ERR( rval );
01134 
01135     // make sure all basic queries fail with MB_TAG_NOT_FOUND
01136     std::string name;
01137     rval = mb.tag_get_name( tag, name );
01138     CHECK_EQUAL( MB_TAG_NOT_FOUND, rval );
01139     Tag tag2;
01140     rval = mb.tag_get_handle( tagname, 1, MB_TYPE_INTEGER, tag2 );
01141     CHECK_EQUAL( MB_TAG_NOT_FOUND, rval );
01142     int size;
01143     rval = mb.tag_get_bytes( tag, size );
01144     CHECK_EQUAL( MB_TAG_NOT_FOUND, rval );
01145     rval = mb.tag_get_length( tag, size );
01146     CHECK_EQUAL( MB_TAG_NOT_FOUND, rval );
01147     // get get the type from the handle, so this still succeeds
01148     // TagType storage2;
01149     // rval = mb.tag_get_type( tag, storage2 );
01150     // CHECK_EQUAL( MB_TAG_NOT_FOUND, rval );
01151     DataType type;
01152     rval = mb.tag_get_data_type( tag, type );
01153     CHECK_EQUAL( MB_TAG_NOT_FOUND, rval );
01154     rval = mb.tag_get_default_value( tag, &value );
01155     CHECK_EQUAL( MB_TAG_NOT_FOUND, rval );
01156 
01157     // check global list of tags
01158     std::vector< Tag > tags;
01159     rval = mb.tag_get_tags( tags );CHECK_ERR( rval );
01160     CHECK( std::find( tags.begin(), tags.end(), tag ) == tags.end() );
01161 
01162     // check tags on entity
01163     tags.clear();
01164     rval = mb.tag_get_tags_on_entity( handle, tags );CHECK_ERR( rval );
01165     CHECK( std::find( tags.begin(), tags.end(), tag ) == tags.end() );
01166 
01167     // check that a new tag w/ the same name can be created
01168     tag  = test_create_tag( mb, tagname, 1, storage, MB_TYPE_DOUBLE, 0 );
01169     rval = mb.tag_delete( tag );CHECK_ERR( rval );
01170 }
01171 
01172 template < typename Container >
01173 ErrorCode set_bit_data( Interface& mb, Tag tag, const Container& handles, const std::vector< unsigned char >& data )
01174 {
01175     ErrorCode rval;
01176     data.resize( handles.size() );
01177     std::vector< unsigned char >::const_iterator j = data.begin();
01178     for( typename Container::const_iterator i = handles.begin(); i != handles.end(); ++i, ++j )
01179     {
01180         rval = mb.tag_set_data( tag, &*i, 1, &*j );
01181         if( MB_SUCCESS != rval ) return rval;
01182     }
01183 }
01184 
01185 static bool contains_tag( Tag tag, const std::vector< Tag >& list )
01186 {
01187     return std::find( list.begin(), list.end(), tag ) != list.end();
01188 }
01189 
01190 void test_get_entity_tags()
01191 {
01192     Core moab;
01193     Interface& mb = moab;
01194     ErrorCode rval;
01195 
01196     // get 8 handles to work with
01197     setup_mesh( mb );
01198     Range entities;
01199     rval = mb.get_entities_by_handle( 0, entities );CHECK_ERR( rval );
01200     CHECK( entities.size() >= 8 );
01201     Range::iterator i       = entities.begin();
01202     EntityHandle sparse_ent = *i;
01203     ++i;
01204     EntityHandle dense_ent = *i;
01205     ++i;
01206     EntityHandle bit_ent = *i;
01207     ++i;
01208     EntityHandle sparse_dense_ent = *i;
01209     ++i;
01210     EntityHandle sparse_bit_ent = *i;
01211     ++i;
01212     EntityHandle dense_bit_ent = *i;
01213     ++i;
01214     EntityHandle all_tag_ent = *i;
01215     ++i;
01216     EntityHandle no_tag_ent = *i;
01217     ++i;
01218 
01219     // create three tags to work with
01220     Tag sparse, dense, bit;
01221     sparse = test_create_tag( mb, "sparse", 1, MB_TAG_SPARSE, MB_TYPE_INTEGER, 0 );
01222     dense  = test_create_tag( mb, "dense_", 1, MB_TAG_DENSE, MB_TYPE_INTEGER, 0 );
01223     bit    = test_create_tag( mb, "bit___", 1, MB_TAG_BIT, MB_TYPE_BIT, 0 );
01224 
01225     // set tags on handles
01226     EntityHandle sparse_ents[4] = { sparse_ent, sparse_dense_ent, sparse_bit_ent, all_tag_ent };
01227     EntityHandle dense_ents[4]  = { dense_ent, sparse_dense_ent, dense_bit_ent, all_tag_ent };
01228     EntityHandle bit_ents[4]    = { bit_ent, sparse_bit_ent, dense_bit_ent, all_tag_ent };
01229     int values[4]               = { -1, -2, -3, -4 };
01230     rval                        = mb.tag_set_data( sparse, sparse_ents, 4, &values );CHECK_ERR( rval );
01231     rval = mb.tag_set_data( dense, dense_ents, 4, &values );CHECK_ERR( rval );
01232     for( int j = 0; j < 4; ++j )
01233     {
01234         unsigned char bitval = 0xF;
01235         rval                 = mb.tag_set_data( bit, bit_ents + j, 1, &bitval );CHECK_ERR( rval );
01236     }
01237 
01238     // get tags on each entity
01239     std::vector< Tag > sparse_ent_tags, dense_ent_tags, bit_ent_tags, sparse_dense_ent_tags, sparse_bit_ent_tags,
01240         dense_bit_ent_tags, all_tag_ent_tags, no_tag_ent_tags;
01241     rval = mb.tag_get_tags_on_entity( sparse_ent, sparse_ent_tags );CHECK_ERR( rval );
01242     rval = mb.tag_get_tags_on_entity( dense_ent, dense_ent_tags );CHECK_ERR( rval );
01243     rval = mb.tag_get_tags_on_entity( bit_ent, bit_ent_tags );CHECK_ERR( rval );
01244     rval = mb.tag_get_tags_on_entity( sparse_dense_ent, sparse_dense_ent_tags );CHECK_ERR( rval );
01245     rval = mb.tag_get_tags_on_entity( sparse_bit_ent, sparse_bit_ent_tags );CHECK_ERR( rval );
01246     rval = mb.tag_get_tags_on_entity( dense_bit_ent, dense_bit_ent_tags );CHECK_ERR( rval );
01247     rval = mb.tag_get_tags_on_entity( all_tag_ent, all_tag_ent_tags );CHECK_ERR( rval );
01248     rval = mb.tag_get_tags_on_entity( no_tag_ent, no_tag_ent_tags );CHECK_ERR( rval );
01249 
01250     // check expected values
01251     // NOTE:  could potentially get back bit and dense tags for any entity
01252     //        depending on the storage layout.  Only sparse tags guarantee
01253     //        no false positives.  False negatives should never happen for any type.
01254     //        Also, there could be other dense tags already defined.
01255 
01256     // verify sparse tag in all expected lists
01257     CHECK( contains_tag( sparse, sparse_ent_tags ) );
01258     CHECK( contains_tag( sparse, sparse_dense_ent_tags ) );
01259     CHECK( contains_tag( sparse, sparse_bit_ent_tags ) );
01260     CHECK( contains_tag( sparse, all_tag_ent_tags ) );
01261 
01262     // verify sparse tag not in any other lists
01263     CHECK( !contains_tag( sparse, dense_ent_tags ) );
01264     CHECK( !contains_tag( sparse, bit_ent_tags ) );
01265     CHECK( !contains_tag( sparse, dense_bit_ent_tags ) );
01266     CHECK( !contains_tag( sparse, no_tag_ent_tags ) );
01267 
01268     // verify dense tag in all expected lists
01269     CHECK( contains_tag( dense, dense_ent_tags ) );
01270     CHECK( contains_tag( dense, sparse_dense_ent_tags ) );
01271     CHECK( contains_tag( dense, dense_bit_ent_tags ) );
01272     CHECK( contains_tag( dense, all_tag_ent_tags ) );
01273 
01274     // verify bit tag in all expected lists
01275     CHECK( contains_tag( bit, bit_ent_tags ) );
01276     CHECK( contains_tag( bit, sparse_bit_ent_tags ) );
01277     CHECK( contains_tag( bit, dense_bit_ent_tags ) );
01278     CHECK( contains_tag( bit, all_tag_ent_tags ) );
01279 }
01280 
01281 void test_delete_sparse_tag()
01282 {
01283     test_delete_type_tag( MB_TAG_SPARSE );
01284 }
01285 
01286 void test_delete_dense_tag()
01287 {
01288     test_delete_type_tag( MB_TAG_DENSE );
01289 }
01290 
01291 void test_delete_mesh_tag()
01292 {
01293     test_delete_type_tag( MB_TAG_MESH );
01294 }
01295 
01296 void test_delete_tag_data( TagType storage, bool with_default_value )
01297 {
01298     Core moab;
01299     Interface& mb = moab;
01300     ErrorCode rval;
01301 
01302     setup_mesh( mb );
01303 
01304     // subdivide entity handles into three groups:
01305     // 1) entities for which the tag data will be deleted using the array-based function
01306     // 2) entities for which the tag data will be deleted using the range-based function
01307     // 3) entities for which the tag data will not be deleted
01308     Range all_entities, del1_range, keep_range;
01309     std::vector< EntityHandle > del1_list, del2_list, keep_list;
01310     rval = mb.get_entities_by_handle( 0, all_entities );CHECK_ERR( rval );
01311     int c = 0;
01312     for( Range::iterator i = all_entities.begin(); i != all_entities.end(); ++i, ++c )
01313     {
01314         switch( c % 3 )
01315         {
01316             case 0:
01317                 del1_range.insert( *i );
01318                 break;
01319             case 1:
01320                 keep_range.insert( *i );
01321                 break;
01322             case 2:
01323                 del2_list.push_back( *i );
01324                 break;
01325         }
01326     }
01327     del1_list.resize( del1_range.size() );
01328     std::copy( del1_range.begin(), del1_range.end(), del1_list.begin() );
01329     keep_list.resize( keep_range.size() );
01330     std::copy( keep_range.begin(), keep_range.end(), keep_list.begin() );
01331 
01332     // create tag
01333     EntityHandle first   = all_entities.front();
01334     EntityHandle* defval = with_default_value ? &first : 0;
01335     const char* tagname  = "dead_tag";
01336     Tag tag              = test_create_tag( mb, tagname, 1, storage, MB_TYPE_HANDLE, defval );
01337 
01338     // set value for each entity to its handle
01339     rval = mb.tag_set_data( tag, del1_range, &del1_list[0] );CHECK_ERR( rval );
01340     rval = mb.tag_set_data( tag, keep_range, &keep_list[0] );CHECK_ERR( rval );
01341     rval = mb.tag_set_data( tag, &del2_list[0], del2_list.size(), &del2_list[0] );CHECK_ERR( rval );
01342 
01343     // delete tag data
01344     rval = mb.tag_delete_data( tag, del1_range );CHECK_ERR( rval );
01345     rval = mb.tag_delete_data( tag, &del2_list[0], del2_list.size() );CHECK_ERR( rval );
01346 
01347     // test that keep list is unaffected
01348     std::vector< EntityHandle > tag_data( keep_range.size(), 0 );
01349     rval = mb.tag_get_data( tag, keep_range, &tag_data[0] );CHECK_ERR( rval );
01350     CHECK( tag_data == keep_list );
01351 
01352     // try to get data for deleted range
01353     tag_data.clear();
01354     tag_data.resize( del1_range.size(), (EntityHandle)-1 );
01355     rval = mb.tag_get_data( tag, del1_range, &tag_data[0] );
01356     // if we have a default value, should get that for deleted entities
01357     if( with_default_value )
01358     {
01359         CHECK_ERR( rval );
01360         std::vector< EntityHandle > expected( del1_range.size(), *defval );
01361         CHECK( expected == tag_data );
01362     }
01363     else if( rval != MB_TAG_NOT_FOUND )
01364     {
01365         // dense and bit tags might return either MB_TAG_NOT_FOUND or zero bytes.
01366         // sparse tags should always return MB_TAG_NOT_FOUND
01367         CHECK( MB_TAG_SPARSE != storage );
01368         std::vector< EntityHandle > expected( del1_range.size(), 0 );
01369         CHECK( expected == tag_data );
01370     }
01371 
01372     // try to get data for deleted list
01373     tag_data.clear();
01374     tag_data.resize( del1_range.size(), (EntityHandle)-1 );
01375     rval = mb.tag_get_data( tag, del1_range, &tag_data[0] );
01376     // if we have a default value, should get that for deleted entities
01377     if( with_default_value )
01378     {
01379         CHECK_ERR( rval );
01380         std::vector< EntityHandle > expected( del1_range.size(), *defval );
01381         CHECK( expected == tag_data );
01382     }
01383     else if( rval != MB_TAG_NOT_FOUND )
01384     {
01385         // dense and bit tags might return either MB_TAG_NOT_FOUND or zero bytes.
01386         // sparse tags should always return MB_TAG_NOT_FOUND
01387         CHECK( MB_TAG_SPARSE != storage );
01388         std::vector< EntityHandle > expected( del1_range.size(), 0 );
01389         CHECK( expected == tag_data );
01390     }
01391 }
01392 
01393 void test_delete_sparse_data()
01394 {
01395     test_delete_tag_data( MB_TAG_DENSE, false );
01396     test_delete_tag_data( MB_TAG_DENSE, true );
01397 }
01398 
01399 void test_delete_dense_data()
01400 {
01401     test_delete_tag_data( MB_TAG_SPARSE, false );
01402     test_delete_tag_data( MB_TAG_SPARSE, true );
01403 }
01404 
01405 void test_delete_bit_data()
01406 {
01407     Core moab;
01408     Interface& mb = moab;
01409     ErrorCode rval;
01410 
01411     // get an entity to set data on
01412     setup_mesh( mb );
01413     Range entities;
01414     rval = mb.get_entities_by_handle( 0, entities );CHECK_ERR( rval );
01415     CHECK( !entities.empty() );
01416     EntityHandle handle = entities.front();
01417 
01418     // create two tags, one with a default value and one without
01419     unsigned char defval = '\006';  // 110
01420     Tag tag1, tag2;
01421     tag1 = test_create_tag( mb, "tag1", 2, MB_TAG_BIT, MB_TYPE_BIT, 0 );
01422     tag2 = test_create_tag( mb, "tag2", 3, MB_TAG_BIT, MB_TYPE_BIT, &defval );
01423 
01424     // set value for each tag
01425     unsigned char val = '\001';
01426     rval              = mb.tag_set_data( tag1, &handle, 1, &val );CHECK_ERR( rval );
01427     rval = mb.tag_set_data( tag2, &handle, 1, &val );CHECK_ERR( rval );
01428 
01429     // delete both tag values
01430     rval = mb.tag_delete_data( tag1, &handle, 1 );CHECK_ERR( rval );
01431     rval = mb.tag_delete_data( tag2, &handle, 1 );CHECK_ERR( rval );
01432 
01433     // try to get value for tag w/out default.
01434     // should get back either not found, or a zero value.
01435     val  = 0xFF;
01436     rval = mb.tag_get_data( tag1, &handle, 1, &val );
01437     if( MB_SUCCESS == rval )
01438         CHECK_EQUAL( val, '\0' );
01439     else
01440         CHECK_EQUAL( MB_TAG_NOT_FOUND, rval );
01441 
01442     // test that we get back default value for second tag
01443     val  = 0xFF;
01444     rval = mb.tag_get_data( tag2, &handle, 1, &val );CHECK_ERR( rval );
01445     CHECK_EQUAL( defval, val );
01446 }
01447 
01448 void test_get_set_variable_length( const char* name,
01449                                    TagType storage,
01450                                    DataType type,
01451                                    const void** values,
01452                                    const int* lengths,
01453                                    int num_values,
01454                                    const void* default_value,
01455                                    int default_value_length )
01456 {
01457     std::vector< const void* > data;
01458     std::vector< int > data_lens;
01459 
01460     // create mesh and tag
01461     Core moab;
01462     Interface& mb = moab;
01463     setup_mesh( mb );
01464     Tag tag = test_create_var_len_tag( mb, name, storage, type, default_value, default_value_length );
01465 
01466     // get some handles to work with
01467     Range entities;
01468     ErrorCode rval = mb.get_entities_by_handle( 0, entities );CHECK_ERR( rval );
01469     CHECK( !entities.empty() );
01470 
01471     // split handles into four groups
01472     // a) a single handle
01473     // b) some non-consecutive handles in an array
01474     // c) some handles in an Range
01475     // d) remaining handles (remaining in 'entities');
01476     EntityHandle one_handle;
01477     Range::iterator it = entities.begin() += entities.size() / 2;
01478     one_handle         = *it;
01479     entities.erase( it );
01480 
01481     Range handle_range;
01482     std::vector< EntityHandle > handle_list;
01483     for( Range::const_pair_iterator i = entities.const_pair_begin(); i != entities.const_pair_end(); ++i )
01484     {
01485         if( i->first == i->second || i->second - i->first == 1 )
01486         {
01487             EntityHandle h1 = i->first, h2 = i->second;
01488             ++i;
01489             handle_range.insert( h1, h2 );
01490         }
01491         else
01492         {
01493             EntityHandle mid = (EntityHandle)( i->first + ( i->second - i->first + 1 ) / 2 );
01494             handle_list.push_back( mid );
01495             handle_range.insert( mid + 1, i->second );
01496         }
01497     }
01498     entities = subtract( entities, handle_range );
01499     for( unsigned i = 0; i < handle_list.size(); ++i )
01500         entities.erase( handle_list[i] );
01501 
01502     // try getting/setting single handle value
01503     if( num_values == 1 )
01504         rval = mb.tag_clear_data( tag, &one_handle, 1, values[0], lengths[0] );
01505     else
01506         rval = mb.tag_set_by_ptr( tag, &one_handle, 1, values, lengths );CHECK_ERR( rval );
01507     const void* data_ptr;
01508     int data_len;
01509     rval = mb.tag_get_by_ptr( tag, &one_handle, 1, &data_ptr, &data_len );CHECK_ERR( rval );
01510     CHECK_EQUAL( lengths[0], data_len );
01511     CHECK( !memcmp( values[0], data_ptr, data_len ) );
01512 
01513     int typesize = 0;
01514     switch( type )
01515     {
01516         case MB_TYPE_INTEGER:
01517             typesize = sizeof( int );
01518             break;
01519         case MB_TYPE_DOUBLE:
01520             typesize = sizeof( double );
01521             break;
01522         case MB_TYPE_HANDLE:
01523             typesize = sizeof( EntityHandle );
01524             break;
01525         case MB_TYPE_BIT:
01526             typesize = 1;
01527             break;
01528         case MB_TYPE_OPAQUE:
01529             typesize = 1;
01530             break;
01531     }
01532 
01533     // try getting/setting for arrays of handles
01534 
01535     int count, step;
01536     if( num_values == 1 )
01537     {
01538         count = handle_list.size();
01539         step  = 0;
01540         rval  = mb.tag_clear_data( tag, &handle_list[0], count, values[0], lengths[0] );
01541     }
01542     else
01543     {
01544         count = std::min( (int)handle_list.size(), num_values );
01545         step  = 1;
01546         rval  = mb.tag_set_by_ptr( tag, &handle_list[0], count, values, lengths );
01547     }
01548     CHECK_ERR( rval );
01549     data.clear();
01550     data.resize( count, 0 );
01551     data_lens.clear();
01552     data_lens.resize( count, 0 );
01553     rval = mb.tag_get_by_ptr( tag, &handle_list[0], count, &data[0], &data_lens[0] );CHECK_ERR( rval );
01554     for( int i = 0; i < count; ++i )
01555     {
01556         CHECK_EQUAL( lengths[i * step], data_lens[i] );
01557         CHECK( NULL != data[i] );
01558         CHECK( !memcmp( values[i], data[i * step], typesize * lengths[i * step] ) );
01559     }
01560 
01561     // try getting/setting for Range of handles
01562 
01563     if( num_values > 1 )
01564     {
01565         data.resize( num_values );
01566         data_lens.resize( num_values );
01567         std::copy( values, values + num_values, data.begin() );
01568         std::copy( lengths, lengths + num_values, data_lens.begin() );
01569         while( data.size() < handle_range.size() )
01570         {
01571             size_t s = data.size();
01572             data.resize( 2 * s );
01573             std::copy( data.begin(), data.begin() + s, data.begin() + s );
01574             data_lens.resize( 2 * s );
01575             std::copy( data_lens.begin(), data_lens.begin() + s, data_lens.begin() + s );
01576         }
01577         rval = mb.tag_set_by_ptr( tag, handle_range, &data[0], &data_lens[0] );
01578     }
01579     else
01580     {
01581         rval = mb.tag_clear_data( tag, handle_range, values[0], lengths[0] );
01582     }
01583     CHECK_ERR( rval );
01584 
01585     data.clear();
01586     data.resize( handle_range.size(), 0 );
01587     data_lens.clear();
01588     data_lens.resize( handle_range.size(), 0 );
01589     rval = mb.tag_get_by_ptr( tag, handle_range, &data[0], &data_lens[0] );CHECK_ERR( rval );
01590 
01591     for( size_t i = 0; i < data.size(); ++i )
01592     {
01593         const void* expect = values[( i * step ) % num_values];
01594         int expect_len     = lengths[( i * step ) % num_values];
01595         CHECK_EQUAL( expect_len, data_lens[i] );
01596         CHECK( NULL != data[i] );
01597         CHECK( !memcmp( expect, data[i], expect_len * typesize ) );
01598     }
01599 
01600     // try getting unset values
01601 
01602     data.resize( entities.size() );
01603     data_lens.resize( entities.size() );
01604     rval = mb.tag_get_by_ptr( tag, entities, &data[0], &data_lens[0] );
01605     // if there was a default value, we should have gotten it for all unset entities
01606     if( default_value )
01607     {
01608         CHECK_ERR( rval );
01609         for( unsigned i = 0; i < entities.size(); ++i )
01610         {
01611             CHECK_EQUAL( default_value_length, data_lens[i] );
01612             CHECK( NULL != data[i] );
01613             CHECK( !memcmp( default_value, data[i], typesize * default_value_length ) );
01614         }
01615     }
01616     // otherwise we should get MB_TAG_NOT_FOUND
01617     else
01618     {
01619         CHECK_EQUAL( MB_TAG_NOT_FOUND, rval );
01620     }
01621 
01622     // Check that handles for other entities didn't change.
01623 
01624     // one handle
01625     rval = mb.tag_get_by_ptr( tag, &one_handle, 1, &data_ptr, &data_len );CHECK_ERR( rval );
01626     CHECK_EQUAL( lengths[0], data_len );
01627     CHECK( !memcmp( values[0], data_ptr, typesize * data_len ) );
01628 
01629     // array values
01630     count = std::min( (int)handle_list.size(), num_values );
01631     data.clear();
01632     data.resize( count, 0 );
01633     data_lens.clear();
01634     data_lens.resize( count, 0 );
01635     rval = mb.tag_get_by_ptr( tag, &handle_list[0], count, &data[0], &data_lens[0] );CHECK_ERR( rval );
01636     for( int i = 0; i < count; ++i )
01637     {
01638         CHECK_EQUAL( lengths[i], data_lens[i] );
01639         CHECK( NULL != data[i] );
01640         CHECK( !memcmp( values[i], data[i], typesize * lengths[i] ) );
01641     }
01642 
01643     // range values
01644     data.clear();
01645     data.resize( handle_range.size(), 0 );
01646     data_lens.clear();
01647     data_lens.resize( handle_range.size(), 0 );
01648     rval = mb.tag_get_by_ptr( tag, handle_range, &data[0], &data_lens[0] );CHECK_ERR( rval );
01649 
01650     for( size_t i = 0; i < data.size(); ++i )
01651     {
01652         const void* expect = values[i % num_values];
01653         int expect_len     = lengths[i % num_values];
01654         CHECK_EQUAL( expect_len, data_lens[i] );
01655         CHECK( NULL != data[i] );
01656         CHECK( !memcmp( expect, data[i], typesize * expect_len ) );
01657     }
01658 }
01659 
01660 void test_get_set_variable_length_sparse()
01661 {
01662     const double doubles[14] = { 1, 2, 3, 4, -4, -3, -2, -1, 42, 0, 1974, -0.5, 1. / 3, -1e-10 };
01663     const void* dvals[5]     = { doubles, doubles + 3, doubles + 4, doubles + 8, doubles + 10 };
01664     const int dlens[5]       = { 3, 1, 4, 2, 4 };
01665     test_get_set_variable_length( "vnodef", MB_TAG_SPARSE, MB_TYPE_DOUBLE, dvals, dlens, 5, 0, 0 );
01666 
01667     const int ints[32]   = { 1,  2,  3,  4,  5,  6,  7,  8,  9,  10,  11,  12,  13,  14,  15,
01668                            -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15 };
01669     const void* ivals[9] = { ints,      ints + 1,  ints + 3,  ints + 12, ints + 17,
01670                              ints + 21, ints + 28, ints + 29, ints + 31 };
01671     const int ilens[9]   = { 1, 2, 9, 5, 4, 7, 1, 2, 1 };
01672     const int defvals[]  = { 42, 5, 8, 74 };
01673     test_get_set_variable_length( "vdef", MB_TAG_SPARSE, MB_TYPE_INTEGER, ivals, ilens, 9, defvals, 4 );
01674 }
01675 
01676 void test_get_set_variable_length_dense()
01677 {
01678     const double doubles[14] = { 1, 2, 3, 4, -4, -3, -2, -1, 42, 0, 1974, -0.5, 1. / 3, -1e-10 };
01679     const void* dvals[5]     = { doubles, doubles + 3, doubles + 4, doubles + 8, doubles + 10 };
01680     const int dlens[5]       = { 3, 1, 4, 2, 4 };
01681     test_get_set_variable_length( "vnodef", MB_TAG_DENSE, MB_TYPE_DOUBLE, dvals, dlens, 5, 0, 0 );
01682 
01683     const int ints[32]   = { 1,  2,  3,  4,  5,  6,  7,  8,  9,  10,  11,  12,  13,  14,  15,
01684                            -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15 };
01685     const void* ivals[9] = { ints,      ints + 1,  ints + 3,  ints + 12, ints + 17,
01686                              ints + 21, ints + 28, ints + 29, ints + 31 };
01687     const int ilens[9]   = { 1, 2, 9, 5, 4, 7, 1, 2, 1 };
01688     const int defvals[]  = { 42, 5, 8, 74 };
01689     test_get_set_variable_length( "vdef", MB_TAG_DENSE, MB_TYPE_INTEGER, ivals, ilens, 9, defvals, 4 );
01690 }
01691 
01692 void test_get_set_variable_length_mesh()
01693 {
01694     Core moab;
01695     Interface& mb = moab;
01696     ErrorCode rval;
01697 
01698     Tag tag       = test_create_var_len_tag( mb, "vmesh", MB_TAG_MESH, MB_TYPE_INTEGER, 0, 0 );
01699     int values1[] = { 6 };
01700     int values5[] = { 1, 2, 3, 4, 5 };
01701 
01702     int one = 1;
01703     const void* data[1];
01704     data[0]                 = values1;
01705     const EntityHandle mesh = 0;
01706     rval                    = mb.tag_set_by_ptr( tag, &mesh, 1, data, &one );CHECK_ERR( rval );
01707 
01708     int len;
01709     rval = mb.tag_get_by_ptr( tag, &mesh, 1, data, &len );CHECK_ERR( rval );
01710     CHECK_EQUAL( 1, len );
01711     CHECK_EQUAL( values1[0], *reinterpret_cast< const int* >( data[0] ) );
01712 
01713     int five = 5;
01714     data[0]  = values5;
01715     rval     = mb.tag_set_by_ptr( tag, &mesh, 1, data, &five );CHECK_ERR( rval );
01716 
01717     rval = mb.tag_get_by_ptr( tag, &mesh, 1, data, &len );CHECK_ERR( rval );
01718     CHECK_EQUAL( 5, len );
01719     CHECK_EQUAL( values5[0], reinterpret_cast< const int* >( data[0] )[0] );
01720     CHECK_EQUAL( values5[1], reinterpret_cast< const int* >( data[0] )[1] );
01721     CHECK_EQUAL( values5[2], reinterpret_cast< const int* >( data[0] )[2] );
01722     CHECK_EQUAL( values5[3], reinterpret_cast< const int* >( data[0] )[3] );
01723     CHECK_EQUAL( values5[4], reinterpret_cast< const int* >( data[0] )[4] );
01724 }
01725 
01726 void test_clear_variable_length( TagType storage )
01727 {
01728     const double doubles[3] = { 1e-1, 1e-2, 1e-3 };
01729     const void* dvals[]     = { doubles };
01730     const int dlen          = sizeof( doubles ) / sizeof( double );
01731     test_get_set_variable_length( "vnodef_clear", storage, MB_TYPE_DOUBLE, dvals, &dlen, 1, 0, 0 );
01732 
01733     const int ints[32]  = { 1,  2,  3,  4,  5,  6,  7,  8,  9,  10,  11,  12,  13,  14,  15,
01734                            -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15 };
01735     const void* ivals[] = { ints };
01736     const int ilen      = sizeof( ints ) / sizeof( int );
01737     const int defvals[] = { 42, 5, 8, 74 };
01738     test_get_set_variable_length( "vdef_clear", storage, MB_TYPE_INTEGER, ivals, &ilen, 1, defvals, 4 );
01739 }
01740 
01741 void test_clear_sparse_varlen()
01742 {
01743     test_clear_variable_length( MB_TAG_SPARSE );
01744 }
01745 
01746 void test_clear_dense_varlen()
01747 {
01748     test_clear_variable_length( MB_TAG_DENSE );
01749 }
01750 
01751 void test_get_ents_with_default_value()
01752 {
01753     Core moab;
01754     Interface& mb = moab;
01755     ErrorCode rval;
01756     Range result;
01757 
01758     // create a bunch of vertices
01759     std::vector< double > coords( 90, 0.0 );
01760     Range verts;
01761     rval = mb.create_vertices( &coords[0], coords.size() / 3, verts );CHECK_ERR( rval );
01762     CHECK_EQUAL( coords.size() / 3, (size_t)verts.size() );
01763     // create one edge, which we should never get back from
01764     // our queries with type == MBVERTEX
01765     EntityHandle edge, ends[] = { verts.front(), verts.back() };
01766     rval = mb.create_element( MBEDGE, ends, 2, edge );CHECK_ERR( rval );
01767 
01768     // split vertices into four groups
01769     Range sets[4];
01770     size_t s = 0;
01771     for( Range::iterator i = verts.begin(); i != verts.end(); ++i )
01772     {
01773         sets[s].insert( *i );
01774         s = ( s + 1 ) % 4;
01775     }
01776 
01777     // create a sparse tag and set some verts to non-default value
01778     int default_sparse = 5;
01779     Tag tag_sparse     = test_create_tag( mb, "int", 1, MB_TAG_SPARSE, MB_TYPE_INTEGER, &default_sparse );
01780     std::vector< int > sparse_vals( sets[0].size(), -1 );
01781     rval = mb.tag_set_data( tag_sparse, sets[0], &sparse_vals[0] );CHECK_ERR( rval );
01782 
01783     // get all entities with default value for sparse tag
01784     result.clear();
01785     const void* ptrs[] = { &default_sparse };
01786     rval               = mb.get_entities_by_type_and_tag( 0, MBVERTEX, &tag_sparse, ptrs, 1, result );CHECK_ERR( rval );
01787     CHECK_EQUAL( subtract( verts, sets[0] ), result );
01788 
01789     // create a dense tag and set some verts to non-default value
01790     double default_dense = -1.0;
01791     Tag tag_dense        = test_create_tag( mb, "double", 1, MB_TAG_DENSE, MB_TYPE_DOUBLE, &default_dense );
01792     std::vector< double > dense_vals( sets[1].size(), 3.14159 );
01793     rval = mb.tag_set_data( tag_dense, sets[1], &dense_vals[0] );CHECK_ERR( rval );
01794 
01795     // get all entities with default value for dense tag
01796     result.clear();
01797     ptrs[0] = &default_dense;
01798     rval    = mb.get_entities_by_type_and_tag( 0, MBVERTEX, &tag_dense, ptrs, 1, result );CHECK_ERR( rval );
01799     CHECK_EQUAL( subtract( verts, sets[1] ), result );
01800 
01801     // create a variable-length tag and set some verts to non-default value
01802     // SKIP THIS: NO API FOR QUERYING ENTITIES WITH VARIABLE-LENGTH VALUE
01803     // int default_vlen[] = { 1, 2, 3 };
01804     // Tag tag_vlen = test_create_var_len_tag( mb, "vlen", MB_TAG_SPARSE, MB_TYPE_INTEGER,
01805     // default_vlen, sizeof(default_vlen) ); int other_vlen[] = { 4, 5, 6, 7 }; std::vector<const
01806     // void*> vlen_ptrs( sets[2].size(), other_vlen ); std::vector<int> vlen_sizes( sets[2].size)(),
01807     // sizeof(other_vlen) ); rval = mb.tag_set_data( tag_vlen, sets[2], &vlen_ptrs[0],
01808     // &vlen_sizes[0]
01809     // ); CHECK_ERR(rval);
01810 
01811     // check that INTERSECT option works as expected
01812     result.clear();
01813     result.insert( sets[1].front() );
01814     ptrs[0] = &default_sparse;
01815     rval    = mb.get_entities_by_type_and_tag( 0, MBVERTEX, &tag_sparse, ptrs, 1, result, Interface::INTERSECT );CHECK_ERR( rval );
01816     CHECK_EQUAL( (size_t)1, result.size() );
01817     CHECK_EQUAL( sets[1].front(), result.front() );
01818 
01819     // check that UNITE option works as expected
01820     result.clear();
01821     result.insert( edge );
01822     ptrs[0] = &default_sparse;
01823     rval    = mb.get_entities_by_type_and_tag( 0, MBVERTEX, &tag_sparse, ptrs, 1, result, Interface::UNION );CHECK_ERR( rval );
01824     CHECK_EQUAL( edge, result.back() );
01825 }
01826 
01827 void test_bit_tag_big()
01828 {
01829     Core moab;
01830     Interface& mb = moab;
01831     ErrorCode rval;
01832     const size_t NUM_VTX = 30000;
01833 
01834     // create a lot of vertices
01835     std::vector< double > coords( 3 * NUM_VTX, 0.0 );
01836     Range verts;
01837     rval = mb.create_vertices( &coords[0], NUM_VTX, verts );CHECK_ERR( rval );
01838     CHECK_EQUAL( NUM_VTX, (size_t)verts.size() );
01839 
01840     // create a bit tag
01841     Tag tag = test_create_tag( mb, "bb", 4, MB_TAG_BIT, MB_TYPE_BIT, 0 );
01842     // for each vertex, store last four bits of handle as tag value
01843     std::vector< unsigned char > values( NUM_VTX );
01844     std::vector< unsigned char >::iterator it = values.begin();
01845     for( Range::iterator j = verts.begin(); j != verts.end(); ++j, ++it )
01846         *it = (unsigned char)( *j & 0xF );
01847     rval = mb.tag_set_data( tag, verts, &values[0] );CHECK_ERR( rval );
01848 
01849     // retrieve values
01850     std::vector< unsigned char > values2( NUM_VTX, 0 );
01851     rval = mb.tag_get_data( tag, verts, &values2[0] );
01852     CHECK_EQUAL( values, values2 );
01853 
01854     // retrieve individual values
01855     it = values.begin();
01856     for( Range::iterator j = verts.begin(); j != verts.end(); ++j, ++it )
01857     {
01858         char value;
01859         rval = mb.tag_get_data( tag, &*j, 1, &value );CHECK_ERR( rval );
01860         CHECK_EQUAL( *it, value );
01861     }
01862 
01863     // retrieve entities
01864     unsigned char value = 0xC;
01865     Range expected, results;
01866     for( Range::reverse_iterator j = verts.rbegin(); j != verts.rend(); ++j )
01867         if( (unsigned char)( *j & 0xF ) == value ) expected.insert( *j );
01868     const void* vals[] = { &value };
01869     rval               = mb.get_entities_by_type_and_tag( 0, MBVERTEX, &tag, vals, 1, results );CHECK_ERR( rval );
01870     CHECK_EQUAL( expected, results );
01871 
01872     // test singe-bit tag
01873     Tag tag1 = test_create_tag( mb, "bb1", 1, MB_TAG_BIT, MB_TYPE_BIT, 0 );
01874     // set tag to 1 on all vertices
01875     values.clear();
01876     values.resize( NUM_VTX, '\001' );
01877     rval = mb.tag_set_data( tag1, verts, &values[0] );CHECK_ERR( rval );
01878     // retrieve values individually
01879     for( Range::iterator j = verts.begin(); j != verts.end(); ++j )
01880     {
01881         char cvalue;
01882         rval = mb.tag_get_data( tag1, &*j, 1, &cvalue );CHECK_ERR( rval );
01883         CHECK_EQUAL( 1, (int)cvalue );
01884     }
01885     // clear values individually
01886     for( Range::iterator j = verts.begin(); j != verts.end(); ++j )
01887     {
01888         char cvalue = '\0';
01889         rval        = mb.tag_set_data( tag1, &*j, 1, &cvalue );CHECK_ERR( rval );
01890     }
01891     // retrieve values using range
01892     rval = mb.tag_get_data( tag1, verts, &values[0] );CHECK_ERR( rval );
01893     size_t first_one = std::find( values.begin(), values.end(), '\001' ) - values.begin();
01894     CHECK_EQUAL( values.size(), first_one );
01895 }
01896 
01897 void setup_mesh( Interface& mb )
01898 {
01899     Range vertex_handles;
01900     const double vertex_coords[] = { 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 1, 0, 1, 1, 0, 2, 1, 0, 0, 2, 0, 1, 2, 0, 2, 2, 0,
01901 
01902                                      0, 0, 1, 1, 0, 1, 2, 0, 1, 0, 1, 1, 1, 1, 1, 2, 1, 1, 0, 2, 1, 1, 2, 1, 2, 2, 1,
01903 
01904                                      0, 0, 2, 1, 0, 2, 2, 0, 2, 0, 1, 2, 1, 1, 2, 2, 1, 2, 0, 2, 2, 1, 2, 2, 2, 2, 2 };
01905     const unsigned num_vtx       = sizeof( vertex_coords ) / ( 3 * sizeof( double ) );
01906     ErrorCode rval               = mb.create_vertices( vertex_coords, num_vtx, vertex_handles );CHECK_ERR( rval );
01907     CHECK_EQUAL( num_vtx, (unsigned)vertex_handles.size() );
01908 
01909     CHECK_EQUAL( 27u, num_vtx );
01910     EntityHandle elements[8];
01911     EntityHandle conn[8][8] = { { 0, 1, 4, 3, 9, 10, 13, 12 },      { 1, 2, 5, 4, 10, 11, 14, 13 },
01912                                 { 3, 4, 7, 6, 12, 13, 16, 15 },     { 4, 5, 8, 7, 13, 14, 17, 16 },
01913                                 { 9, 10, 13, 12, 18, 19, 22, 21 },  { 10, 11, 14, 13, 19, 20, 23, 22 },
01914                                 { 12, 13, 16, 15, 21, 22, 25, 24 }, { 13, 14, 17, 16, 22, 23, 26, 25 } };
01915     for( unsigned i = 0; i < 8; ++i )
01916     {
01917         rval = mb.create_element( MBHEX, conn[i], 8, elements[i] );CHECK_ERR( rval );
01918     }
01919 
01920     // delete some stuff so there are multiple sequences
01921     rval = mb.delete_entities( elements + 2, 2 );CHECK_ERR( rval );
01922     Range::iterator i = vertex_handles.begin();
01923     i += 16;
01924     rval = mb.delete_entities( &*i, 1 );CHECK_ERR( rval );
01925     i += 2;
01926     rval = mb.delete_entities( &*i, 1 );CHECK_ERR( rval );
01927 }
01928 
01929 /* Found bug where last entity in sequence is not
01930    returned for get entity by tag for a variable-
01931    length tag.  Test to make sure that it remains
01932    fixed.
01933  */
01934 void regression_one_entity_by_var_tag()
01935 {
01936     Core moab;
01937     ErrorCode rval;
01938 
01939     EntityHandle vertex;
01940     const double coords[] = { 0, 0, 0 };
01941     rval                  = moab.create_vertex( coords, vertex );CHECK_ERR( rval );
01942 
01943     Tag tag;
01944     rval = moab.tag_get_handle( "testtag", 0, MB_TYPE_INTEGER, tag, MB_TAG_DENSE | MB_TAG_VARLEN | MB_TAG_EXCL );CHECK_ERR( rval );
01945 
01946     int taglen            = 1;
01947     const void* ptrarr[1] = { &taglen };
01948     rval                  = moab.tag_set_by_ptr( tag, &vertex, 1, ptrarr, &taglen );CHECK_ERR( rval );
01949 
01950     Range ents;
01951     rval = moab.get_entities_by_type_and_tag( 0, MBVERTEX, &tag, 0, 1, ents );CHECK_ERR( rval );
01952 
01953     CHECK_EQUAL( (size_t)1, ents.size() );
01954     CHECK_EQUAL( vertex, ents.front() );
01955 }
01956 
01957 /* Return MB_ENTITY_NOT_FOUND if asked to set a tag on an
01958    entity that doesn't exist.
01959  */
01960 void regression_tag_on_nonexistent_entity()
01961 {
01962     Core moab;
01963     ErrorCode rval;
01964     const int tagval      = 0xdeadbeef;
01965     const void* valarr[1] = { &tagval };
01966     const int numval      = 1;
01967 
01968     // create all three types of tags
01969     Tag dense, sparse, bit;
01970     rval = moab.tag_get_handle( "test_dense", 1, MB_TYPE_INTEGER, dense, MB_TAG_DENSE | MB_TAG_EXCL );CHECK_ERR( rval );
01971     rval = moab.tag_get_handle( "test_sparse", 1, MB_TYPE_INTEGER, sparse, MB_TAG_SPARSE | MB_TAG_EXCL );CHECK_ERR( rval );
01972     rval = moab.tag_get_handle( "test_bit", 4, MB_TYPE_BIT, bit, MB_TAG_EXCL );CHECK_ERR( rval );
01973 
01974     // for each tag type, check all four mechanisms for setting tag data
01975     // (fixed and variable length given array or range).
01976     EntityHandle handle = (EntityHandle)1;
01977     Range handles;
01978     handles.insert( handle );
01979 
01980     rval = moab.tag_set_data( dense, &handle, 1, &tagval );
01981     CHECK_EQUAL( MB_ENTITY_NOT_FOUND, rval );
01982     rval = moab.tag_set_data( sparse, &handle, 1, &tagval );
01983     CHECK_EQUAL( MB_ENTITY_NOT_FOUND, rval );
01984     rval = moab.tag_set_data( bit, &handle, 1, &tagval );
01985     CHECK_EQUAL( MB_ENTITY_NOT_FOUND, rval );
01986 
01987     rval = moab.tag_set_data( dense, handles, &tagval );
01988     CHECK_EQUAL( MB_ENTITY_NOT_FOUND, rval );
01989     rval = moab.tag_set_data( sparse, handles, &tagval );
01990     CHECK_EQUAL( MB_ENTITY_NOT_FOUND, rval );
01991     rval = moab.tag_set_data( bit, handles, &tagval );
01992     CHECK_EQUAL( MB_ENTITY_NOT_FOUND, rval );
01993 
01994     rval = moab.tag_set_by_ptr( dense, &handle, 1, valarr, &numval );
01995     CHECK_EQUAL( MB_ENTITY_NOT_FOUND, rval );
01996     rval = moab.tag_set_by_ptr( sparse, &handle, 1, valarr, &numval );
01997     CHECK_EQUAL( MB_ENTITY_NOT_FOUND, rval );
01998 
01999     rval = moab.tag_set_by_ptr( dense, handles, valarr, &numval );
02000     CHECK_EQUAL( MB_ENTITY_NOT_FOUND, rval );
02001     rval = moab.tag_set_by_ptr( sparse, handles, valarr, &numval );
02002     CHECK_EQUAL( MB_ENTITY_NOT_FOUND, rval );
02003 
02004     // now add create an entity and try an adjacent handle
02005     EntityHandle set;
02006     rval = moab.create_meshset( 0, set );CHECK_ERR( rval );
02007 
02008     handle = (EntityHandle)( set + 1 );
02009     handles.clear();
02010     handles.insert( handle );
02011 
02012     rval = moab.tag_set_data( dense, &handle, 1, &tagval );
02013     CHECK_EQUAL( MB_ENTITY_NOT_FOUND, rval );
02014     rval = moab.tag_set_data( sparse, &handle, 1, &tagval );
02015     CHECK_EQUAL( MB_ENTITY_NOT_FOUND, rval );
02016     rval = moab.tag_set_data( bit, &handle, 1, &tagval );
02017     CHECK_EQUAL( MB_ENTITY_NOT_FOUND, rval );
02018 
02019     rval = moab.tag_set_data( dense, handles, &tagval );
02020     CHECK_EQUAL( MB_ENTITY_NOT_FOUND, rval );
02021     rval = moab.tag_set_data( sparse, handles, &tagval );
02022     CHECK_EQUAL( MB_ENTITY_NOT_FOUND, rval );
02023     rval = moab.tag_set_data( bit, handles, &tagval );
02024     CHECK_EQUAL( MB_ENTITY_NOT_FOUND, rval );
02025 
02026     rval = moab.tag_set_by_ptr( dense, &handle, 1, valarr, &numval );
02027     CHECK_EQUAL( MB_ENTITY_NOT_FOUND, rval );
02028     rval = moab.tag_set_by_ptr( sparse, &handle, 1, valarr, &numval );
02029     CHECK_EQUAL( MB_ENTITY_NOT_FOUND, rval );
02030 
02031     rval = moab.tag_set_by_ptr( dense, handles, valarr, &numval );
02032     CHECK_EQUAL( MB_ENTITY_NOT_FOUND, rval );
02033     rval = moab.tag_set_by_ptr( sparse, handles, valarr, &numval );
02034     CHECK_EQUAL( MB_ENTITY_NOT_FOUND, rval );
02035 }
02036 
02037 void test_tag_iterate_common( TagType storage, bool with_default )
02038 {
02039     // create 1000 vertices
02040     const int NUM_VTX = 1000;
02041     Core moab;
02042     Interface& mb = moab;
02043     std::vector< double > coords( 3 * NUM_VTX );
02044     Range verts, dead;
02045     ErrorCode rval = mb.create_vertices( &coords[0], NUM_VTX, verts );CHECK_ERR( rval );
02046 
02047     // delete about 1% of vertices
02048     const int step    = 100;
02049     int remaining     = NUM_VTX;
02050     Range::iterator i = verts.begin();
02051     for( int j = 0; j < remaining; j += step )
02052     {
02053         rval = mb.delete_entities( &*i, 1 );CHECK_ERR( rval );
02054         dead.insert( *i );
02055         i = verts.erase( i );
02056         i += step - 1;
02057     }
02058 
02059     // Remove some additional values from the range
02060     // so that our handle blocks don't always align with
02061     // sequences
02062     verts.erase( verts.begin() + ( step - 5 ), verts.begin() + ( step + 5 ) );
02063 
02064     // Create an integer tag
02065     Tag tag;
02066     const int defval = 0;
02067     rval = mb.tag_get_handle( "TEST_TAG", 1, MB_TYPE_INTEGER, tag, storage | MB_TAG_CREAT, with_default ? &defval : 0 );CHECK_ERR( rval );
02068 
02069     // Set tag values
02070     std::vector< int > values( verts.size(), defval );
02071     if( !with_default )
02072     {
02073         for( size_t j = 0; j < values.size(); ++j )
02074             values[j] = j;
02075         rval = mb.tag_set_data( tag, verts, &values[0] );CHECK_ERR( rval );
02076     }
02077 
02078     // Check that we get back expected values
02079     i = verts.begin();
02080     void* ptr;
02081     int count, total = 0;
02082     while( i != verts.end() )
02083     {
02084         ptr  = 0;
02085         rval = mb.tag_iterate( tag, i, verts.end(), count, ptr );CHECK_ERR( rval );
02086 
02087         assert( total + count <= (int)verts.size() );
02088         CHECK_ARRAYS_EQUAL( &values[total], count, reinterpret_cast< int* >( ptr ), count );
02089 
02090         if( i == verts.begin() && with_default && storage == MB_TAG_SPARSE ) ( (int*)ptr )[0] = 1.0;
02091 
02092         i += count;
02093         total += count;
02094     }
02095 
02096     // Check that we can set values
02097     i = verts.begin();
02098     while( i != verts.end() )
02099     {
02100         ptr  = 0;
02101         rval = mb.tag_iterate( tag, i, verts.end(), count, ptr );CHECK_ERR( rval );
02102 
02103         Range::iterator end = i + count;
02104         int* arr            = reinterpret_cast< int* >( ptr );
02105         while( end != i )
02106         {
02107             *arr = static_cast< int >( ( *i ) % NUM_VTX );
02108             ++i;
02109             ++arr;
02110         }
02111     }
02112 
02113     // Check that we got back the values that we set
02114     i = verts.begin();
02115     while( i != verts.end() )
02116     {
02117         ptr  = 0;
02118         rval = mb.tag_iterate( tag, i, verts.end(), count, ptr );CHECK_ERR( rval );
02119 
02120         Range::iterator end = i + count;
02121         int* arr            = reinterpret_cast< int* >( ptr );
02122         while( end != i )
02123         {
02124             CHECK_EQUAL( *arr, static_cast< int >( ( *i ) % NUM_VTX ) );
02125             ++i;
02126             ++arr;
02127         }
02128     }
02129 
02130     // Check that we cannot get tag values for invalid handles
02131     rval = mb.tag_iterate( tag, dead.begin(), dead.end(), count, ptr );
02132     CHECK( MB_ENTITY_NOT_FOUND == rval || MB_TAG_NOT_FOUND == rval );
02133 }
02134 void test_tag_iterate_sparse()
02135 {
02136     test_tag_iterate_common( MB_TAG_SPARSE, false );
02137 }
02138 void test_tag_iterate_sparse_default()
02139 {
02140     test_tag_iterate_common( MB_TAG_SPARSE, true );
02141 }
02142 void test_tag_iterate_dense()
02143 {
02144     test_tag_iterate_common( MB_TAG_DENSE, false );
02145 }
02146 void test_tag_iterate_dense_default()
02147 {
02148     test_tag_iterate_common( MB_TAG_DENSE, true );
02149 }
02150 
02151 void test_tag_iterate_invalid()
02152 {
02153     // create 1000 vertices
02154     const int NUM_VTX = 1000;
02155     Core moab;
02156     Interface& mb = moab;
02157     std::vector< double > coords( 3 * NUM_VTX );
02158     Range verts;
02159     ErrorCode rval = mb.create_vertices( &coords[0], NUM_VTX, verts );CHECK_ERR( rval );
02160 
02161     Tag tag;
02162     const int zero = 0;
02163     void* ptr;
02164     int count;
02165 
02166     // Check that we cannot iterate over bit tags
02167     // (this will never be possible because the storage for bit tags
02168     //  is compressed and therefore cannot be directly accessed.)
02169     rval = mb.tag_get_handle( "bits", 1, MB_TYPE_BIT, tag, MB_TAG_EXCL, &zero );CHECK_ERR( rval );
02170     rval = mb.tag_iterate( tag, verts.begin(), verts.end(), count, ptr );
02171     CHECK_EQUAL( MB_TYPE_OUT_OF_RANGE, rval );
02172 
02173     // Check that we cannot iterate over variable-length tags
02174     // (this will never be possible because this API function cannot
02175     //  pass back the length of the tag values)
02176     rval = mb.tag_get_handle( "vden", 1, MB_TYPE_INTEGER, tag, MB_TAG_VARLEN | MB_TAG_DENSE | MB_TAG_EXCL, &zero );CHECK_ERR( rval );
02177     rval = mb.tag_iterate( tag, verts.begin(), verts.end(), count, ptr );
02178     CHECK_EQUAL( MB_VARIABLE_DATA_LENGTH, rval );
02179 
02180     rval = mb.tag_get_handle( "vspr", 1, MB_TYPE_INTEGER, tag, MB_TAG_VARLEN | MB_TAG_SPARSE | MB_TAG_EXCL, &zero );CHECK_ERR( rval );
02181     rval = mb.tag_iterate( tag, verts.begin(), verts.end(), count, ptr );
02182     CHECK_EQUAL( MB_VARIABLE_DATA_LENGTH, rval );
02183 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines