[MOAB-dev] r1577 - MOAB/trunk
kraftche at mcs.anl.gov
kraftche at mcs.anl.gov
Fri Feb 1 17:39:12 CST 2008
Author: kraftche
Date: 2008-02-01 17:39:12 -0600 (Fri, 01 Feb 2008)
New Revision: 1577
Added:
MOAB/trunk/TagTest.cpp
Modified:
MOAB/trunk/Makefile.am
Log:
o Add better unit tests for old fixed-length tag functionality.
o Add unit tests for new APIs used for fixed-length tags.
o Add unit tests for variable-length tags.
Modified: MOAB/trunk/Makefile.am
===================================================================
--- MOAB/trunk/Makefile.am 2008-02-01 23:37:36 UTC (rev 1576)
+++ MOAB/trunk/Makefile.am 2008-02-01 23:39:12 UTC (rev 1577)
@@ -28,7 +28,8 @@
adaptive_kd_tree_tests \
file_options_test \
kd_tree_test \
- var_len_test var_len_test_no_template
+ var_len_test var_len_test_no_template \
+ tag_test
# merge_test \ # input files no longer exist?
# test_tag_server \ # fails
@@ -329,7 +330,11 @@
var_len_test_no_template_SOURCES = $(var_len_test_SOURCES)
var_len_test_no_template_CPPFLAGS = -UTEMPLATE_SPECIALIZATION
+tag_test_SOURCES = TagTest.cpp
+tag_test_LDADD = $(top_builddir)/libMOAB.la
+tag_test_DEPENDENCIES = $(tag_test_LDADD)
+
# Other files to clean up (e.g. output from tests)
MOSTLYCLEANFILES = dumped_acis.sat
Added: MOAB/trunk/TagTest.cpp
===================================================================
--- MOAB/trunk/TagTest.cpp (rev 0)
+++ MOAB/trunk/TagTest.cpp 2008-02-01 23:39:12 UTC (rev 1577)
@@ -0,0 +1,1630 @@
+#include "MBCore.hpp"
+#include "TestUtil.hpp"
+#include <stdlib.h>
+
+void test_create_tag();
+void test_invalid_tag_size();
+void test_get_set_sparse_int();
+void test_get_set_dense_int();
+void test_get_set_dense_double();
+void test_get_set_bit();
+void test_get_by_tag( );
+void test_get_by_tag_value( );
+void test_mesh_value();
+void test_get_pointers_sparse();
+void test_get_pointers_dense();
+void test_set_pointers_sparse();
+void test_set_pointers_dense();
+void test_get_entity_tags();
+void test_delete_sparse_tag();
+void test_delete_dense_tag();
+void test_delete_mesh_tag();
+void test_delete_sparse_data();
+void test_delete_dense_data();
+void test_delete_bit_data();
+void test_create_variable_length_tag();
+void test_get_set_variable_length_sparse();
+void test_get_set_variable_length_dense();
+void test_get_set_variable_length_mesh();
+
+int main()
+{
+ int failures = 0;
+
+ failures += RUN_TEST( test_create_tag );
+ failures += RUN_TEST( test_invalid_tag_size );
+ failures += RUN_TEST( test_get_set_sparse_int );
+ failures += RUN_TEST( test_get_set_dense_int );
+ failures += RUN_TEST( test_get_set_dense_double );
+ failures += RUN_TEST( test_get_set_bit );
+ failures += RUN_TEST( test_get_by_tag );
+ failures += RUN_TEST( test_get_by_tag_value );
+ failures += RUN_TEST( test_mesh_value );
+ failures += RUN_TEST( test_get_pointers_sparse );
+ failures += RUN_TEST( test_get_pointers_dense );
+ failures += RUN_TEST( test_set_pointers_sparse );
+ failures += RUN_TEST( test_set_pointers_dense );
+ failures += RUN_TEST( test_get_entity_tags );
+ failures += RUN_TEST( test_delete_sparse_tag );
+ failures += RUN_TEST( test_delete_dense_tag );
+ failures += RUN_TEST( test_delete_mesh_tag );
+ failures += RUN_TEST( test_delete_sparse_data );
+ failures += RUN_TEST( test_delete_dense_data );
+ failures += RUN_TEST( test_delete_bit_data );
+ failures += RUN_TEST( test_create_variable_length_tag );
+ failures += RUN_TEST( test_get_set_variable_length_sparse );
+ failures += RUN_TEST( test_get_set_variable_length_dense );
+ failures += RUN_TEST( test_get_set_variable_length_mesh );
+
+ return failures;
+}
+
+
+void setup_mesh( MBInterface& mesh );
+
+MBTag test_create_tag( MBInterface& mb,
+ const char* name,
+ unsigned bytes,
+ MBTagType storage,
+ MBDataType type,
+ const void* defval,
+ MBErrorCode expect = MB_SUCCESS );
+
+MBTag test_create_var_len_tag( MBInterface& mb,
+ const char* name,
+ MBTagType storage,
+ MBDataType type,
+ const void* defval,
+ int defval_size,
+ MBErrorCode expect = MB_SUCCESS );
+
+void test_get_set( const char* name,
+ unsigned bytes,
+ MBTagType storage,
+ MBDataType type,
+ const void* some_values,
+ int num_values,
+ const void* default_value,
+ bool set_by_pointer = false,
+ bool get_by_pointer = false );
+
+void test_get_set_variable_length( const char* name,
+ MBTagType storage,
+ MBDataType type,
+ const void** values,
+ const int* lengths,
+ int num_values,
+ const void* default_value,
+ int default_value_length );
+
+void test_mesh_value( MBInterface& mb,
+ const char* tag_name,
+ unsigned tag_size,
+ MBTagType tag_storage,
+ MBDataType tag_type,
+ const void* value );
+
+MBTag test_create_tag( MBInterface& mb,
+ const char* name,
+ unsigned bytes,
+ MBTagType storage,
+ MBDataType type,
+ const void* defval,
+ MBErrorCode expect )
+{
+ MBErrorCode rval;
+ MBTag tag;
+
+ if (type == MB_TYPE_OPAQUE)
+ rval = mb.tag_create( name, bytes, storage, tag, defval );
+ else
+ rval = mb.tag_create( name, bytes, storage, type, tag, defval );
+
+ if (expect != MB_SUCCESS) {
+ CHECK_EQUAL( expect, rval );
+ return 0;
+ }
+ CHECK_ERR(rval);
+
+ std::string n;
+ rval = mb.tag_get_name( tag, n );
+ CHECK_ERR(rval);
+ CHECK( n == name );
+
+ MBTag tag2;
+ rval = mb.tag_get_handle( name, tag2 );
+ CHECK_ERR(rval);
+ CHECK_EQUAL( tag, tag2 );
+
+ int s;
+ rval = mb.tag_get_size( tag, s );
+ CHECK_ERR(rval);
+ CHECK_EQUAL( (int)bytes, s );
+
+ MBTagType t;
+ rval = mb.tag_get_type( tag, t );
+ CHECK_ERR(rval);
+ CHECK_EQUAL( storage, t );
+
+ MBDataType d;
+ rval = mb.tag_get_data_type( tag, d );
+ CHECK_ERR(rval);
+ CHECK_EQUAL( type, d );
+
+ std::vector<unsigned char> defv( bytes );
+ rval = mb.tag_get_default_value( tag, &defv[0] );
+ if (defval) {
+ CHECK_ERR(rval);
+ unsigned real_bytes = (storage == MB_TAG_BIT) ? 1 : bytes;
+ CHECK(!memcmp( defval, &defv[0], real_bytes ));
+ }
+ else {
+ CHECK_EQUAL( MB_ENTITY_NOT_FOUND, rval );
+ }
+
+ // make sure we can't create a second tag w/ the same name
+ rval = mb.tag_create( name, bytes, storage, type, tag2, defval );
+ CHECK_EQUAL( MB_ALREADY_ALLOCATED, rval );
+ // we should get back the handle of the existing tag
+ CHECK_EQUAL( tag, tag2 );
+
+ return tag;
+}
+
+
+MBTag test_create_var_len_tag( MBInterface& mb,
+ const char* name,
+ MBTagType storage,
+ MBDataType type,
+ const void* defval,
+ int defval_size,
+ MBErrorCode expect )
+{
+ MBErrorCode rval;
+ MBTag tag;
+
+ rval = mb.tag_create_variable_length( name, storage, type, tag, defval, defval_size );
+ if (expect != MB_SUCCESS) {
+ CHECK_EQUAL( expect, rval );
+ return 0;
+ }
+ CHECK_ERR(rval);
+
+ std::string n;
+ rval = mb.tag_get_name( tag, n );
+ CHECK_ERR(rval);
+ CHECK( n == name );
+
+ MBTag tag2;
+ rval = mb.tag_get_handle( name, tag2 );
+ CHECK_ERR(rval);
+ CHECK_EQUAL( tag, tag2 );
+
+ int s;
+ rval = mb.tag_get_size( tag, s );
+ CHECK_EQUAL( MB_VARIABLE_DATA_LENGTH, rval );
+ //CHECK_ERR(rval);
+ //CHECK_EQUAL( MB_VARIABLE_LENGTH, s );
+
+ MBTagType t;
+ rval = mb.tag_get_type( tag, t );
+ CHECK_ERR(rval);
+ CHECK_EQUAL( storage, t );
+
+ MBDataType d;
+ rval = mb.tag_get_data_type( tag, d );
+ CHECK_ERR(rval);
+ CHECK_EQUAL( type, d );
+
+ int size;
+ const void* defv;
+ rval = mb.tag_get_default_value( tag, defv, size );
+ if (defval) {
+ CHECK_ERR(rval);
+ CHECK_EQUAL( defval_size, size );
+ CHECK(!memcmp( defval, defv, size ));
+ }
+ else {
+ CHECK_EQUAL( MB_ENTITY_NOT_FOUND, rval );
+ }
+
+ // make sure we can't create a second tag w/ the same name
+ rval = mb.tag_create_variable_length( name, storage, type, tag2 );
+ CHECK_EQUAL( MB_ALREADY_ALLOCATED, rval );
+ // we should get back the handle of the existing tag
+ CHECK_EQUAL( tag, tag2 );
+
+ return tag;
+}
+
+
+void test_create_tag()
+{
+ MBCore mb;
+ unsigned char defval[] = { 1, 2, 3, 4, 0, 0, 0, 0 };
+
+ // opaque tags
+ test_create_tag( mb, "opaque_tag_sparse", 8, MB_TAG_SPARSE, MB_TYPE_OPAQUE, defval );
+ test_create_tag( mb, "opaque_tag_dense" , 4, MB_TAG_DENSE, MB_TYPE_OPAQUE, defval );
+ test_create_tag( mb, "opaque_tag_dense2", 1, MB_TAG_DENSE, MB_TYPE_OPAQUE, 0 );
+
+ // integer tags
+ test_create_tag( mb, "int_tag_sparse", sizeof(int), MB_TAG_SPARSE, MB_TYPE_INTEGER, defval );
+ test_create_tag( mb, "int_tag_dense", 8*sizeof(int), MB_TAG_DENSE, MB_TYPE_INTEGER, 0 );
+
+ // double tags
+ double defval2[] = { 3.14159, 2.71828 };
+ test_create_tag( mb, "dbl_tag_sparse", sizeof(double), MB_TAG_SPARSE, MB_TYPE_DOUBLE, 0 );
+ test_create_tag( mb, "dbl_tag_dense", 2*sizeof(double), MB_TAG_DENSE, MB_TYPE_DOUBLE, defval2 );
+
+ // handle tags
+ test_create_tag( mb, "h_tag_dense", sizeof(MBEntityHandle), MB_TAG_DENSE, MB_TYPE_HANDLE, defval );
+
+ // bit tags
+ unsigned char def_bit_val = 0xBF;
+ test_create_tag( mb, "bit_tag_1", 2, MB_TAG_BIT, MB_TYPE_BIT, &def_bit_val );
+}
+
+
+void test_create_variable_length_tag()
+{
+ MBCore mb;
+ unsigned char defval[] = { 1, 2, 3, 4, 0, 0, 0, 0 };
+
+ // opaque tags
+ const void* defptr = defval;
+ test_create_var_len_tag( mb, "opaque_tag_sparse", MB_TAG_SPARSE, MB_TYPE_OPAQUE, defptr, 8 );
+ test_create_var_len_tag( mb, "opaque_tag_dense" , MB_TAG_DENSE, MB_TYPE_OPAQUE, defptr, 4 );
+ test_create_var_len_tag( mb, "opaque_tag_dense2", MB_TAG_DENSE, MB_TYPE_OPAQUE, 0, 0 );
+
+ // integer tags
+ test_create_var_len_tag( mb, "int_tag_sparse", MB_TAG_SPARSE, MB_TYPE_INTEGER, defptr, sizeof(int) );
+ test_create_var_len_tag( mb, "int_tag_dense", MB_TAG_DENSE, MB_TYPE_INTEGER, 0, 0 );
+
+ // double tags
+ double defval2[] = { 3.14159, 2.71828 };
+ defptr = defval2;
+ test_create_var_len_tag( mb, "dbl_tag_sparse", MB_TAG_SPARSE, MB_TYPE_DOUBLE, 0, 0 );
+ test_create_var_len_tag( mb, "dbl_tag_dense", MB_TAG_DENSE, MB_TYPE_DOUBLE, defptr, 2*sizeof(double) );
+
+ // handle tags
+ test_create_var_len_tag( mb, "h_tag_dense", MB_TAG_DENSE, MB_TYPE_HANDLE, 0, 0 );
+}
+
+
+ // test that MOAB enforces the rule that the the size must be multiple of the type
+void test_invalid_tag_size()
+{
+ const MBErrorCode err = MB_INVALID_SIZE;
+ MBCore mb;
+
+ // double
+ test_create_tag( mb, "std ", 0, MB_TAG_DENSE , MB_TYPE_DOUBLE, 0, err );
+ test_create_tag( mb, "std0", 1, MB_TAG_SPARSE, MB_TYPE_DOUBLE, 0, err );
+ test_create_tag( mb, "std1", sizeof(double)-1, MB_TAG_DENSE , MB_TYPE_DOUBLE, 0, err );
+ test_create_tag( mb, "std2", sizeof(double)-2, MB_TAG_SPARSE, MB_TYPE_DOUBLE, 0, err );
+ test_create_tag( mb, "std3", sizeof(double)/2, MB_TAG_SPARSE, MB_TYPE_DOUBLE, 0, err );
+ test_create_tag( mb, "std4", 2*sizeof(double)-1, MB_TAG_DENSE, MB_TYPE_DOUBLE, 0, err );
+
+ // integer
+ test_create_tag( mb, "sti ", 0, MB_TAG_DENSE , MB_TYPE_INTEGER, 0, err );
+ test_create_tag( mb, "sti0", 1, MB_TAG_SPARSE, MB_TYPE_INTEGER, 0, err );
+ test_create_tag( mb, "sti1", sizeof(int)-1, MB_TAG_DENSE , MB_TYPE_INTEGER, 0, err );
+ test_create_tag( mb, "sti2", sizeof(int)/2, MB_TAG_SPARSE, MB_TYPE_INTEGER, 0, err );
+ test_create_tag( mb, "sti3", 2*sizeof(int)-1, MB_TAG_DENSE, MB_TYPE_INTEGER, 0, err );
+
+ // handle
+ test_create_tag( mb, "sth ", 0, MB_TAG_DENSE , MB_TYPE_HANDLE, 0, err );
+ test_create_tag( mb, "sth0", 1, MB_TAG_SPARSE, MB_TYPE_HANDLE, 0, err );
+ test_create_tag( mb, "sth1", sizeof(MBEntityHandle)-1, MB_TAG_DENSE , MB_TYPE_HANDLE, 0, err );
+ test_create_tag( mb, "sth2", sizeof(MBEntityHandle)-2, MB_TAG_SPARSE, MB_TYPE_HANDLE, 0, err );
+ test_create_tag( mb, "sth3", sizeof(MBEntityHandle)/2, MB_TAG_SPARSE, MB_TYPE_HANDLE, 0, err );
+ test_create_tag( mb, "sth4", 2*sizeof(MBEntityHandle)-1, MB_TAG_DENSE, MB_TYPE_HANDLE, 0, err );
+}
+
+// Given a list of sequential values in memory (pointed to by 'concat'),
+// populate a list of pointers to to each value. The number of values
+// is assumed to be the size of 'list'. Individual values have a size of 'bytes'
+static void concat_to_list( const void* concat, std::vector<const void*>& list, size_t bytes )
+{
+ const unsigned char* ptr = reinterpret_cast<const unsigned char*>(concat);
+ std::vector<const void*>::iterator iter = list.begin();
+ for (; iter != list.end(); ++iter, ptr += bytes)
+ *iter = ptr;
+}
+
+ // test get/set of tag values
+void test_get_set( const char* name,
+ unsigned bytes,
+ MBTagType storage,
+ MBDataType type,
+ const void* some_values,
+ int num_values,
+ const void* default_value,
+ bool set_by_pointer,
+ bool get_by_pointer )
+{
+ std::vector<unsigned char> data;
+
+ // create mesh and tag
+ MBCore moab;
+ MBInterface& mb = moab;
+ setup_mesh( mb );
+ MBTag tag = test_create_tag( mb, name, bytes, storage, type, default_value );
+
+ // get some handles to work with
+ MBRange entities;
+ MBErrorCode rval = mb.get_entities_by_handle( 0, entities );
+ CHECK_ERR(rval);
+ CHECK( !entities.empty() );
+
+ // split handles into four groups
+ // a) a single handle
+ // b) some non-consecutive handles in an array
+ // c) some handles in an MBRange
+ // d) remaining handles (remaining in 'entities');
+ MBEntityHandle one_handle;
+ MBRange::iterator i = entities.begin() += entities.size()/2;
+ one_handle = *i;
+ entities.erase( i );
+
+ MBRange handle_range;
+ std::vector<MBEntityHandle> handle_list;
+ for (MBRange::const_pair_iterator i = entities.const_pair_begin();
+ i != entities.const_pair_end(); ++i) {
+ if (i->first == i->second || i->second - i->first == 1) {
+ MBEntityHandle h1 = i->first, h2 = i->second;
+ ++i;
+ handle_range.insert( h1, h2 );
+ }
+ else {
+ MBEntityHandle mid = (MBEntityHandle)(i->first + (i->second - i->first + 1) / 2);
+ handle_list.push_back( mid );
+ handle_range.insert( mid+1, i->second );
+ }
+ }
+ entities = entities.subtract( handle_range );
+ for (unsigned i = 0; i < handle_list.size(); ++i)
+ entities.erase( handle_list[i] );
+
+ // try getting/setting single handle value
+
+ std::vector<const void*> list(1);
+ if (set_by_pointer) {
+ list[0] = some_values;
+ rval = mb.tag_set_data( tag, &one_handle, 1, &list[0] );
+ }
+ else {
+ rval = mb.tag_set_data( tag, &one_handle, 1, some_values );
+ }
+ CHECK_ERR( rval );
+ data.resize( bytes );
+ if (get_by_pointer) {
+ // test that correct size is returned
+ int rsize;
+ rval = mb.tag_get_data( tag, &one_handle, 1, &list[0], &rsize );
+ CHECK_ERR( rval );
+ CHECK_EQUAL( (int)bytes, rsize );
+ // try again with NULL size pointer
+ list[0] = 0;
+ rval = mb.tag_get_data( tag, &one_handle, 1, &list[0] );
+ }
+ else {
+ rval = mb.tag_get_data( tag, &one_handle, 1, &data[0] );
+ list[0] = &data[0];
+ }
+ CHECK_ERR( rval );
+ CHECK( !memcmp( some_values, list[0], bytes ) );
+
+
+ // try getting/setting for arrays of handles
+
+ const int step = std::min( (int)handle_list.size(), num_values );
+ data.resize( step * bytes );
+ for (int i = 0; i < (int)handle_list.size(); i += step) {
+ const int n = std::min( (int)handle_list.size() - i, step );
+ list.resize(n);
+ if (set_by_pointer) {
+ concat_to_list( some_values, list, bytes );
+ rval = mb.tag_set_data( tag, &handle_list[i], n, &list[0] );
+ }
+ else
+ rval = mb.tag_set_data( tag, &handle_list[i], n, some_values );
+ CHECK_ERR( rval );
+
+ if (get_by_pointer) {
+ // check that valid sizes are returned if requested
+ std::vector<int> rsizes(n,0);
+ rval = mb.tag_get_data( tag, &handle_list[i], n, &list[0], &rsizes[0] );
+ CHECK_ERR( rval );
+ for (int j = 0; j < n; ++j)
+ CHECK_EQUAL( (int)bytes, rsizes[j] );
+ // query a second time to verify that it works w/ NULL size array
+ list.clear();
+ list.resize( n, 0 );
+ rval = mb.tag_get_data( tag, &handle_list[i], n, &list[0] );
+ }
+ else {
+ rval = mb.tag_get_data( tag, &handle_list[i], n, &data[0] );
+ concat_to_list( &data[0], list, bytes );
+ }
+ CHECK_ERR( rval );
+
+ const unsigned char* ptr = reinterpret_cast<const unsigned char*>(some_values);
+ for (int j = 0; j < n; ++j, ptr += bytes)
+ CHECK( !memcmp( ptr, list[j], bytes ) );
+ }
+
+ // try getting/setting for MBRange of handles
+
+ // set data for range
+ if (set_by_pointer) {
+ list.resize( num_values );
+ concat_to_list( some_values, list, bytes );
+ while (list.size() < handle_range.size()) {
+ size_t s = list.size();
+ list.resize( 2*s );
+ std::copy( list.begin(), list.begin()+s, list.begin()+s );
+ }
+ rval = mb.tag_set_data( tag, handle_range, &list[0] );
+ }
+ else {
+ std::vector<unsigned char> input_data( handle_range.size() * bytes );
+ for (int i = 0; i < (int)input_data.size(); i += num_values*bytes)
+ memcpy( &input_data[i], some_values, std::min((unsigned)input_data.size()-i,num_values*bytes) );
+ rval = mb.tag_set_data( tag, handle_range, &input_data[0] );
+ }
+ CHECK_ERR( rval );
+
+ // get data for range
+ list.clear();
+ list.resize( handle_range.size(), 0 );
+ if (get_by_pointer) {
+ // check that valid sizes are returned if requested
+ std::vector<int> rsizes( handle_range.size(), 0 );
+ rval = mb.tag_get_data( tag, handle_range, &list[0], &rsizes[0] );
+ CHECK_ERR(rval);
+ for (size_t j = 0; j <handle_range.size(); ++j)
+ CHECK_EQUAL( (int)bytes, rsizes[j] );
+ // query w/ NULL size array to make sure that works also
+ list.clear();
+ list.resize( handle_range.size(), 0 );
+ rval = mb.tag_get_data( tag, handle_range, &list[0] );
+ }
+ else {
+ data.resize( handle_range.size() * bytes );
+ concat_to_list( &data[0], list, bytes );
+ rval = mb.tag_get_data( tag, handle_range, &data[0] );
+ }
+ CHECK_ERR( rval );
+
+ // compare values
+ for (size_t i = 0; i < list.size(); ++i) {
+ CHECK( list[i] != NULL );
+ const void* ptr = reinterpret_cast<const char*>(some_values) + (i % num_values) * bytes;
+ CHECK( !memcmp( list[i], ptr, bytes ) );
+ }
+
+
+ // try getting unset values
+
+ list.resize( entities.size() );
+ if (get_by_pointer) {
+ rval = mb.tag_get_data( tag, entities, &list[0] );
+ }
+ else {
+ data.clear(),
+ data.resize( entities.size() * bytes, '\001' );
+ concat_to_list( &data[0], list, bytes );
+ rval = mb.tag_get_data( tag, entities, &data[0] );
+ }
+ // if there was a default value, we should have gotten it for all unset entities
+ if (default_value) {
+ CHECK_ERR( rval );
+ for (unsigned i = 0; i < entities.size(); ++i)
+ CHECK( !memcmp( default_value, list[i], bytes ) );
+ }
+ // otherwise we should get MB_TAG_NOT_FOUND, *unless* the tag
+ // is dense, in which case we /might/ get all zero bytes instead.
+ else if (MB_TAG_NOT_FOUND != rval) {
+ CHECK_EQUAL( MB_TAG_DENSE, storage );
+ std::vector<unsigned char> zeros( bytes, 0 );
+ for (unsigned i = 0; i < entities.size(); ++i)
+ CHECK( !memcmp( &zeros[0], list[i], bytes ) );
+ }
+
+ // Check that handles for other entities didn't change.
+
+ // Ignore get_by_pointer/set_by_pointer flags from here on.
+ // We've estabilished (hopefully) that both methods work in
+ // the above code. Now we just want to verify correct values,
+ // regarless of the API used to get them.
+
+ // one handle
+ data.resize( bytes );
+ rval = mb.tag_get_data( tag, &one_handle, 1, &data[0] );
+ CHECK_ERR( rval );
+ CHECK( !memcmp( some_values, &data[0], bytes ) );
+
+ // array values
+ data.resize( step * bytes );
+ for (int i = 0; i < (int)handle_list.size(); i += step) {
+ const int n = std::min( (int)handle_list.size() - i, step );
+ rval = mb.tag_get_data( tag, &handle_list[i], n, &data[0] );
+ CHECK_ERR( rval );
+ CHECK( !memcmp( some_values, &data[0], step*bytes ) );
+ rval = mb.tag_set_data( tag, &handle_list[i], n, some_values );
+ CHECK_ERR( rval );
+ }
+
+ // range values
+ list.clear();
+ list.resize( handle_range.size(), 0 );
+ rval = mb.tag_get_data( tag, handle_range, &list[0] );
+ CHECK_ERR( rval );
+ for (size_t i = 0; i< handle_range.size(); ++i) {
+ const void* ptr = reinterpret_cast<const char*>(some_values) + (i % num_values) * bytes;
+ CHECK( !memcmp( ptr, list[i], bytes ) );
+ }
+}
+
+
+void test_get_set_sparse_int()
+{
+ const int data[] = { 21, 00, 46, 30, 26, 63, 05, 49,
+ 31, 39, 86, 77, 24, 37, 25, 98,
+ 26, 20, 01, 54, 16, 28, 55, 49,
+ 96, 18, 28, 18, 53, 00, 80, 48 };
+ const int num_val = sizeof(data)/sizeof(data[0]);
+
+ test_get_set( "sparse_int", sizeof(int)*2,
+ MB_TAG_SPARSE, MB_TYPE_INTEGER,
+ data, num_val/2,
+ 0 );
+
+ const int defaultval = 19740508;
+ test_get_set( "sparse_int_def", sizeof(int),
+ MB_TAG_SPARSE, MB_TYPE_INTEGER,
+ data, num_val,
+ &defaultval );
+}
+
+void test_get_set_dense_int()
+{
+ const int data[] = { 231, 416, 294, 504, 318, 558, 494, 006,
+ 464, 648, 737, 045, 179, 852, 944, 336,
+ 773, 248, 434, 615, 677, 667, 521, 748,
+ 820, 533, 955, 300, 108, 726, 747, 597 };
+ const int num_val = sizeof(data)/sizeof(data[0]);
+
+
+ test_get_set( "dense_int", sizeof(int),
+ MB_TAG_DENSE, MB_TYPE_INTEGER,
+ data, num_val,
+ 0 );
+
+ const int defaultval[] = { 5, 8, 1974 };
+ test_get_set( "dense_int_def", sizeof(int)*3,
+ MB_TAG_DENSE, MB_TYPE_INTEGER,
+ data, num_val/3,
+ defaultval );
+}
+
+void test_get_set_dense_double()
+{
+ const double pi = 3.1415926535897931;
+ const double e = 2.7182818284590451;
+ const double data[] = { 1, 1., pi, e,
+ 2, 1./2, 2*pi, e/2,
+ 3, 1./3, 3*pi, e/3,
+ 4, 1./4, 4*pi, e/4,
+ 5, 1./5, 5*pi, e/5,
+ 6, 1./6, 6*pi, e/6,
+ 0, 100, 1000, 10000 };
+ const int num_val = sizeof(data)/sizeof(data[0]);
+
+
+ test_get_set( "dense_dbl", sizeof(double),
+ MB_TAG_DENSE, MB_TYPE_DOUBLE,
+ data, num_val,
+ 0 );
+
+ const double defaultval[] = { 0.11, 0.22 };
+ test_get_set( "dense_dbl_def", sizeof(double)*2,
+ MB_TAG_DENSE, MB_TYPE_DOUBLE,
+ data, num_val/2,
+ defaultval );
+}
+
+
+void test_get_pointers_sparse()
+{
+ const double data[] = { 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16 };
+ const int num_val = sizeof(data)/sizeof(data[0]);
+
+ test_get_set( "sparse_dbl_ptr", 2*sizeof(double),
+ MB_TAG_SPARSE, MB_TYPE_DOUBLE,
+ data, num_val/2, 0,
+ false, true );
+
+ const double defaultval[] = { -1, -2 };
+ test_get_set( "sparse_dbl_ptr_def", 2*sizeof(double),
+ MB_TAG_SPARSE, MB_TYPE_DOUBLE,
+ data, num_val/2, defaultval,
+ false, true );
+}
+
+
+void test_get_pointers_dense()
+{
+ const unsigned char data[] = "a few aribtrary bytes entered as a string";
+ const int num_val = sizeof(data)/sizeof(data[0]);
+
+ test_get_set( "dense_byte_ptr", 2,
+ MB_TAG_DENSE, MB_TYPE_OPAQUE,
+ data, num_val/2, 0,
+ false, true );
+
+ const unsigned char defaultval[] = "XY";
+ test_get_set( "dense_byte_ptr_def", 2,
+ MB_TAG_DENSE, MB_TYPE_OPAQUE,
+ data, num_val/2, defaultval,
+ false, true );
+}
+
+void test_set_pointers_sparse()
+{
+ const double data[] = { 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16 };
+ const int num_val = sizeof(data)/sizeof(data[0]);
+
+ test_get_set( "sparse_dbl_ptr", 2*sizeof(double),
+ MB_TAG_SPARSE, MB_TYPE_DOUBLE,
+ data, num_val/2, 0,
+ true, false );
+
+ const double defaultval[] = { -1, -2 };
+ test_get_set( "sparse_dbl_ptr_def", 2*sizeof(double),
+ MB_TAG_SPARSE, MB_TYPE_DOUBLE,
+ data, num_val/2, defaultval,
+ true, false );
+}
+
+void test_set_pointers_dense()
+{
+ const unsigned char data[] = "a few aribtrary bytes entered as a string";
+ const int num_val = sizeof(data)/sizeof(data[0]);
+
+ test_get_set( "dense_byte_ptr", 2,
+ MB_TAG_DENSE, MB_TYPE_OPAQUE,
+ data, num_val/2, 0,
+ true, false );
+
+ const unsigned char defaultval[] = "XY";
+ test_get_set( "dense_byte_ptr_def", 2,
+ MB_TAG_DENSE, MB_TYPE_OPAQUE,
+ data, num_val/2, defaultval,
+ true, false );
+}
+
+void test_get_set_bit()
+{
+ // create mesh and tag
+ MBCore moab;
+ MBInterface& mb = moab;
+ setup_mesh( mb );
+ MBTag tag = test_create_tag( mb, "bit_val", 2, MB_TAG_BIT, MB_TYPE_BIT, 0 );
+
+ // get some handles to work with
+ MBRange entities;
+ MBErrorCode rval = mb.get_entities_by_handle( 0, entities );
+ CHECK_ERR(rval);
+ CHECK( !entities.empty() );
+
+ // set bits on every entity
+ unsigned counter = 0;
+ for (MBRange::iterator i = entities.begin(); i != entities.end(); ++i) {
+ srand( counter++ );
+ unsigned char bits = (unsigned char)(rand() & 3);
+ rval = mb.tag_set_data( tag, &*i, 1, &bits );
+ unsigned char bits_out = 0;
+ rval = mb.tag_get_data( tag, &*i, 1, &bits_out );
+ CHECK_EQUAL( bits, bits_out );
+ }
+
+ // test default value
+ unsigned char defval = '\003';
+ unsigned char zero = '\0';
+ MBTag tag2 = test_create_tag( mb, "bit_val2", 3, MB_TAG_BIT, MB_TYPE_BIT, &defval );
+ CHECK( entities.size() >= 3 );
+ MBRange::iterator j = entities.begin();
+ MBEntityHandle h1 = *j; ++j;
+ MBEntityHandle h2 = *j; ++j;
+ MBEntityHandle h3 = *j; ++j;
+ rval = mb.tag_set_data( tag2, &h1, 1, &zero );
+ CHECK_ERR(rval);
+ rval = mb.tag_set_data( tag2, &h3, 1, &zero );
+ CHECK_ERR(rval);
+ unsigned char byte;
+ rval = mb.tag_get_data( tag2, &h2, 1, &byte );
+ CHECK_ERR( rval );
+ CHECK_EQUAL( defval, byte );
+ rval = mb.tag_get_data( tag2, &h1, 1, &byte );
+ CHECK_ERR( rval );
+ CHECK_EQUAL( zero, byte );
+ rval = mb.tag_get_data( tag2, &h3, 1, &byte );
+ CHECK_ERR( rval );
+ CHECK_EQUAL( zero, byte );
+
+ // test default value for uninitialized data (tag not set for any entity)
+ defval = '\002';
+ MBTag tag3 = test_create_tag( mb, "bit_val3", 2, MB_TAG_BIT, MB_TYPE_BIT, &defval );
+ rval = mb.tag_get_data( tag3, &h2, 1, &byte );
+ CHECK_ERR( rval );
+ CHECK_EQUAL( defval, byte );
+}
+
+void test_get_by_tag( )
+{
+ // create mesh and tag
+ MBCore moab;
+ MBInterface& mb = moab;
+ setup_mesh( mb );
+ MBTag tag = test_create_tag( mb, "sparse_count", sizeof(int), MB_TAG_SPARSE, MB_TYPE_INTEGER, 0 );
+
+ // get some handles to work with
+ MBRange entities;
+ MBErrorCode rval = mb.get_entities_by_type( 0, MBVERTEX, entities );
+ CHECK_ERR(rval);
+ CHECK( !entities.empty() );
+
+ // get five handles
+ CHECK( entities.size() > 6 );
+ MBEntityHandle arr[5] = { *(entities.begin() += entities.size()/6),
+ *(entities.begin() += 2*entities.size()/6),
+ *(entities.begin() += 3*entities.size()/6),
+ *(entities.begin() += 4*entities.size()/6),
+ *(entities.begin() += 5*entities.size()/6) };
+ int values[5] = { 1, 2, 3, 4, 5 };
+ rval = mb.tag_set_data( tag, arr, 5, values );
+ CHECK_ERR( rval );
+ const void* const valarr[1] = { 0 };
+
+ // put some in a mesh set
+ MBEntityHandle set;
+ const int num_in_set = 3;
+ rval = mb.create_meshset( 0, set );
+ CHECK_ERR(rval);
+ rval = mb.add_entities( set, arr, num_in_set );
+ CHECK_ERR(rval);
+
+ // try for whole mesh will null tag value array
+ int count = -1;
+ rval = mb.get_number_entities_by_type_and_tag( 0, MBVERTEX, &tag, 0, 1, count );
+ CHECK_ERR( rval );
+ CHECK_EQUAL( 5, count );
+
+ // try for whole mesh will null tag value, but non-null array
+ count = -1;
+ rval = mb.get_number_entities_by_type_and_tag( 0, MBVERTEX, &tag, valarr, 1, count );
+ CHECK_ERR( rval );
+ CHECK_EQUAL( 5, count );
+
+ // try for mesh set
+ rval = mb.get_number_entities_by_type_and_tag( set, MBVERTEX, &tag, 0, 1, count );
+ CHECK_ERR( rval );
+ CHECK_EQUAL( num_in_set, count );
+
+
+ // try for whole mesh will null tag value array
+ MBRange found;
+ rval = mb.get_entities_by_type_and_tag( 0, MBVERTEX, &tag, 0, 1, found );
+ CHECK_ERR( rval );
+ CHECK_EQUAL( 5u, (unsigned)found.size() );
+ MBRange::iterator i = found.begin();
+ CHECK_EQUAL( arr[0], *i ); ++i;
+ CHECK_EQUAL( arr[1], *i ); ++i;
+ CHECK_EQUAL( arr[2], *i ); ++i;
+ CHECK_EQUAL( arr[3], *i ); ++i;
+ CHECK_EQUAL( arr[4], *i ); ++i;
+
+ // try for whole mesh will null tag value, but non-null array
+ found.clear();
+ rval = mb.get_entities_by_type_and_tag( 0, MBVERTEX, &tag, valarr, 1, found );
+ CHECK_ERR( rval );
+ CHECK_EQUAL( 5u, (unsigned)found.size() );
+ i = found.begin();
+ CHECK_EQUAL( arr[0], *i ); ++i;
+ CHECK_EQUAL( arr[1], *i ); ++i;
+ CHECK_EQUAL( arr[2], *i ); ++i;
+ CHECK_EQUAL( arr[3], *i ); ++i;
+ CHECK_EQUAL( arr[4], *i ); ++i;
+
+ // try for mesh set
+ found.clear();
+ rval = mb.get_entities_by_type_and_tag( set, MBVERTEX, &tag, 0, 1, found );
+ CHECK_ERR( rval );
+ CHECK_EQUAL( 3u, (unsigned)found.size() );
+ i = found.begin();
+ CHECK_EQUAL( arr[0], *i ); ++i;
+ CHECK_EQUAL( arr[1], *i ); ++i;
+ CHECK_EQUAL( arr[2], *i ); ++i;
+}
+
+void test_get_by_tag_value( )
+{
+ // create mesh and tag
+ MBCore moab;
+ MBInterface& mb = moab;
+ setup_mesh( mb );
+ MBTag tag = test_create_tag( mb, "sparse_count", sizeof(int), MB_TAG_SPARSE, MB_TYPE_INTEGER, 0 );
+
+ // get some handles to work with
+ MBRange entities;
+ MBErrorCode rval = mb.get_entities_by_type( 0, MBVERTEX, entities );
+ CHECK_ERR(rval);
+ CHECK( !entities.empty() );
+
+ // get five handles
+ CHECK( entities.size() > 6 );
+ MBEntityHandle arr[5] = { *(entities.begin() += entities.size()/6),
+ *(entities.begin() += 2*entities.size()/6),
+ *(entities.begin() += 3*entities.size()/6),
+ *(entities.begin() += 4*entities.size()/6),
+ *(entities.begin() += 5*entities.size()/6) };
+ int values[5] = { 0xBEEF, 0xBEEF, 0xBEEF, 0xBEEF, 0xBEEF };
+ rval = mb.tag_set_data( tag, arr, 5, values );
+ CHECK_ERR( rval );
+ const void* const valarr[1] = { values };
+
+ // put some in a mesh set
+ MBEntityHandle set;
+ const int num_in_set = 3;
+ rval = mb.create_meshset( 0, set );
+ CHECK_ERR(rval);
+ rval = mb.add_entities( set, arr, num_in_set );
+ CHECK_ERR(rval);
+
+ // try for whole mesh
+ int count = -1;
+ rval = mb.get_number_entities_by_type_and_tag( 0, MBVERTEX, &tag, valarr, 1, count );
+ CHECK_ERR( rval );
+ CHECK_EQUAL( 5, count );
+
+ // try for mesh set
+ rval = mb.get_number_entities_by_type_and_tag( set, MBVERTEX, &tag, valarr, 1, count );
+ CHECK_ERR( rval );
+ CHECK_EQUAL( num_in_set, count );
+
+
+ // try for whole mesh
+ MBRange found;
+ rval = mb.get_entities_by_type_and_tag( 0, MBVERTEX, &tag, valarr, 1, found );
+ CHECK_ERR( rval );
+ CHECK_EQUAL( 5u, (unsigned)found.size() );
+ MBRange::iterator i = found.begin();
+ CHECK_EQUAL( arr[0], *i ); ++i;
+ CHECK_EQUAL( arr[1], *i ); ++i;
+ CHECK_EQUAL( arr[2], *i ); ++i;
+ CHECK_EQUAL( arr[3], *i ); ++i;
+ CHECK_EQUAL( arr[4], *i ); ++i;
+
+ // try for mesh set
+ found.clear();
+ rval = mb.get_entities_by_type_and_tag( set, MBVERTEX, &tag, valarr, 1, found );
+ CHECK_ERR( rval );
+ CHECK_EQUAL( 3u, (unsigned)found.size() );
+ i = found.begin();
+ CHECK_EQUAL( arr[0], *i ); ++i;
+ CHECK_EQUAL( arr[1], *i ); ++i;
+ CHECK_EQUAL( arr[2], *i ); ++i;
+}
+
+void test_mesh_value( MBInterface& mb,
+ const char* tag_name,
+ unsigned tag_size,
+ MBTagType tag_storage,
+ MBDataType tag_type,
+ const void* value )
+{
+ // create tag
+ MBTag tag = test_create_tag( mb, tag_name, tag_size, tag_storage, tag_type, 0 );
+
+ unsigned memcmp_size = tag_size;
+ if (tag_storage == MB_TAG_BIT || tag_type == MB_TYPE_BIT)
+ memcmp_size = 1;
+
+ MBErrorCode rval = mb.tag_set_data( tag, 0, 0, value );
+ CHECK_ERR(rval);
+ std::vector<unsigned char> bytes(memcmp_size, 0);
+ rval = mb.tag_get_data( tag, 0, 0, &bytes[0] );
+ CHECK_ERR(rval);
+ CHECK( !memcmp( value, &bytes[0], memcmp_size ) );
+
+ // test again, this time for default value
+ std::string name2( tag_name );
+ name2 += "_DEF";
+ MBTag tag2 = test_create_tag( mb, name2.c_str(), tag_size, tag_storage, tag_type, value );
+ bytes.clear();
+ bytes.resize(memcmp_size, 0);
+ rval = mb.tag_get_data( tag2, 0, 0, &bytes[0] );
+ CHECK_ERR(rval);
+ CHECK( !memcmp( value, &bytes[0], memcmp_size ) );
+}
+
+void test_mesh_value()
+{
+ MBCore moab;
+
+ double dval = -0.5;
+ test_mesh_value( moab, "mvd", sizeof(double), MB_TAG_DENSE, MB_TYPE_DOUBLE, &dval );
+
+ int sval = 42;
+ test_mesh_value( moab, "mvs", sizeof(int), MB_TAG_SPARSE, MB_TYPE_INTEGER, &sval );
+
+ MBEntityHandle mval = 0;
+ test_mesh_value( moab, "mvm", sizeof(MBEntityHandle), MB_TAG_MESH, MB_TYPE_HANDLE, &mval );
+
+ unsigned char bits = '\002';
+ test_mesh_value( moab, "mvb", 2, MB_TAG_BIT, MB_TYPE_BIT, &bits );
+}
+
+static void test_delete_type_tag( MBTagType storage )
+{
+ MBCore moab;
+ MBInterface &mb = moab;
+ MBErrorCode rval;
+
+ setup_mesh( mb );
+
+ // create tag
+ int default_val = 42;
+ const char* tagname = "dead_tag";
+ MBTag tag = test_create_tag( mb, tagname, sizeof(int), storage, MB_TYPE_INTEGER, &default_val );
+
+ // get an entity handle to work with
+ MBRange verts;
+ rval = mb.get_entities_by_type( 0, MBVERTEX, verts );
+ CHECK_ERR( rval );
+ CHECK( !verts.empty() );
+ MBEntityHandle handle = verts.front();
+
+ // set tag value on entity
+ int value = -5;
+ if (storage != MB_TAG_MESH) {
+ rval = mb.tag_set_data( tag, &handle, 1, &value );
+ CHECK_ERR( rval );
+ }
+
+ // set tag value on mesh
+ value = 2;
+ rval = mb.tag_set_data( tag, 0, 0, &value );
+
+ // delete tag
+ rval = mb.tag_delete( tag );
+ CHECK_ERR( rval );
+
+ // make sure all basic queries fail with MB_TAG_NOT_FOUND
+ std::string name;
+ rval = mb.tag_get_name( tag, name );
+ CHECK_EQUAL( MB_TAG_NOT_FOUND, rval );
+ MBTag tag2;
+ rval = mb.tag_get_handle( tagname, tag2 );
+ CHECK_EQUAL( MB_TAG_NOT_FOUND, rval );
+ int size;
+ rval = mb.tag_get_size( tag, size );
+ CHECK_EQUAL( MB_TAG_NOT_FOUND, rval );
+ // get get the type from the handle, so this still succeeds
+ //MBTagType storage2;
+ //rval = mb.tag_get_type( tag, storage2 );
+ //CHECK_EQUAL( MB_TAG_NOT_FOUND, rval );
+ MBDataType type;
+ rval = mb.tag_get_data_type( tag, type );
+ CHECK_EQUAL( MB_TAG_NOT_FOUND, rval );
+ rval = mb.tag_get_default_value( tag, &value );
+ CHECK_EQUAL( MB_TAG_NOT_FOUND, rval );
+
+ // check global list of tags
+ std::vector<MBTag> tags;
+ rval = mb.tag_get_tags( tags );
+ CHECK_ERR( rval );
+ CHECK( std::find( tags.begin(), tags.end(), tag ) == tags.end() );
+
+ // check tags on entity
+ tags.clear();
+ rval = mb.tag_get_tags_on_entity( handle, tags );
+ CHECK_ERR( rval );
+ CHECK( std::find( tags.begin(), tags.end(), tag ) == tags.end() );
+
+ // check get_data for entity
+ rval = mb.tag_get_data( tag, &handle, 1, &value );
+ CHECK_EQUAL( MB_TAG_NOT_FOUND, rval );
+
+ // check get_data for mesh
+ rval = mb.tag_get_data( tag, 0, 0, &value );
+ CHECK_EQUAL( MB_TAG_NOT_FOUND, rval );
+
+ // check that a new tag w/ the same name can be created
+ tag = test_create_tag( mb, tagname, sizeof(double), storage, MB_TYPE_DOUBLE, 0 );
+ rval = mb.tag_delete( tag );
+ CHECK_ERR( rval );
+}
+
+
+template <typename Container>
+MBErrorCode set_bit_data( MBInterface& mb,
+ MBTag tag,
+ const Container& handles,
+ const std::vector<unsigned char>& data )
+{
+ MBErrorCode rval;
+ data.resize( handles.size() );
+ std::vector<unsigned char>::const_iterator j = data.begin();
+ for (typename Container::const_iterator i = handles.begin(); i != handles.end(); ++i, ++j) {
+ rval = mb.tag_set_data( tag, &*i, 1, &*j );
+ if (MB_SUCCESS != rval)
+ return rval;
+ }
+}
+
+static bool contains_tag( MBTag tag, const std::vector<MBTag>& list )
+{
+ return std::find( list.begin(), list.end(), tag ) != list.end();
+}
+
+void test_get_entity_tags()
+{
+ MBCore moab;
+ MBInterface &mb = moab;
+ MBErrorCode rval;
+
+ // get 8 handles to work with
+ setup_mesh( mb );
+ MBRange entities;
+ rval = mb.get_entities_by_handle( 0, entities );
+ CHECK_ERR( rval );
+ CHECK( entities.size() >= 8 );
+ MBRange::iterator i = entities.begin();
+ MBEntityHandle sparse_ent = *i; ++i;
+ MBEntityHandle dense_ent = *i; ++i;
+ MBEntityHandle bit_ent = *i; ++i;
+ MBEntityHandle sparse_dense_ent = *i; ++i;
+ MBEntityHandle sparse_bit_ent = *i; ++i;
+ MBEntityHandle dense_bit_ent = *i; ++i;
+ MBEntityHandle all_tag_ent = *i; ++i;
+ MBEntityHandle no_tag_ent = *i; ++i;
+
+ // create three tags to work with
+ MBTag sparse, dense, bit;
+ sparse = test_create_tag( mb, "sparse", sizeof(int), MB_TAG_SPARSE, MB_TYPE_INTEGER, 0 );
+ dense = test_create_tag( mb, "dense_", sizeof(int), MB_TAG_DENSE , MB_TYPE_INTEGER, 0 );
+ bit = test_create_tag( mb, "bit___", sizeof(int), MB_TAG_BIT , MB_TYPE_BIT , 0 );
+
+ // set tags on handles
+ MBEntityHandle sparse_ents[4] = { sparse_ent, sparse_dense_ent, sparse_bit_ent, all_tag_ent };
+ MBEntityHandle dense_ents[4] = { dense_ent, sparse_dense_ent, dense_bit_ent, all_tag_ent };
+ MBEntityHandle bit_ents[4] = { bit_ent, sparse_bit_ent, dense_bit_ent, all_tag_ent };
+ int values[4] = { -1, -2, -3, -4 };
+ rval = mb.tag_set_data( sparse, sparse_ents, 4, &values );
+ rval = mb.tag_set_data( dense, dense_ents, 4, &values );
+ for (int j = 0; j < 4; ++j) {
+ unsigned char bitval = 0xF;
+ rval = mb.tag_set_data( bit, bit_ents+j, 1, &bitval );
+ CHECK_ERR(rval);
+ }
+
+ // get tags on each entity
+ std::vector<MBTag> sparse_ent_tags, dense_ent_tags, bit_ent_tags,
+ sparse_dense_ent_tags, sparse_bit_ent_tags, dense_bit_ent_tags,
+ all_tag_ent_tags, no_tag_ent_tags;
+ rval = mb.tag_get_tags_on_entity( sparse_ent, sparse_ent_tags );
+ CHECK_ERR(rval);
+ rval = mb.tag_get_tags_on_entity( dense_ent, dense_ent_tags );
+ CHECK_ERR(rval);
+ rval = mb.tag_get_tags_on_entity( bit_ent, bit_ent_tags );
+ CHECK_ERR(rval);
+ rval = mb.tag_get_tags_on_entity( sparse_dense_ent, sparse_dense_ent_tags );
+ CHECK_ERR(rval);
+ rval = mb.tag_get_tags_on_entity( sparse_bit_ent, sparse_bit_ent_tags );
+ CHECK_ERR(rval);
+ rval = mb.tag_get_tags_on_entity( dense_bit_ent, dense_bit_ent_tags );
+ CHECK_ERR(rval);
+ rval = mb.tag_get_tags_on_entity( all_tag_ent, all_tag_ent_tags );
+ CHECK_ERR(rval);
+ rval = mb.tag_get_tags_on_entity( no_tag_ent, no_tag_ent_tags );
+ CHECK_ERR(rval);
+
+ // check expected values
+ // NOTE: could potentially get back bit and dense tags for any entity
+ // depending on the storage layout. Only sparse tags guarantee
+ // no false positives. False negatives should never happen for any type.
+ // Also, there could be other dense tags already defined.
+
+ // verify sparse tag in all expected lists
+ CHECK( contains_tag( sparse, sparse_ent_tags ) );
+ CHECK( contains_tag( sparse, sparse_dense_ent_tags ) );
+ CHECK( contains_tag( sparse, sparse_bit_ent_tags ) );
+ CHECK( contains_tag( sparse, all_tag_ent_tags ) );
+
+ // verify sparse tag not in any other lists
+ CHECK( !contains_tag( sparse, dense_ent_tags ) );
+ CHECK( !contains_tag( sparse, bit_ent_tags ) );
+ CHECK( !contains_tag( sparse, dense_bit_ent_tags ) );
+ CHECK( !contains_tag( sparse, no_tag_ent_tags ) );
+
+ // verify dense tag in all expected lists
+ CHECK( contains_tag( dense, dense_ent_tags ) );
+ CHECK( contains_tag( dense, sparse_dense_ent_tags ) );
+ CHECK( contains_tag( dense, dense_bit_ent_tags ) );
+ CHECK( contains_tag( dense, all_tag_ent_tags ) );
+
+ // verify bit tag in all expected lists
+ CHECK( contains_tag( bit, bit_ent_tags ) );
+ CHECK( contains_tag( bit, sparse_bit_ent_tags ) );
+ CHECK( contains_tag( bit, dense_bit_ent_tags ) );
+ CHECK( contains_tag( bit, all_tag_ent_tags ) );
+}
+
+void test_delete_sparse_tag()
+{
+ test_delete_type_tag( MB_TAG_SPARSE );
+}
+
+void test_delete_dense_tag()
+{
+ test_delete_type_tag( MB_TAG_DENSE );
+}
+
+void test_delete_mesh_tag()
+{
+ test_delete_type_tag( MB_TAG_MESH );
+}
+
+
+void test_delete_tag_data( MBTagType storage, bool with_default_value )
+{
+ MBCore moab;
+ MBInterface &mb = moab;
+ MBErrorCode rval;
+
+ setup_mesh( mb );
+
+ // subdivide entity handles into three groups:
+ // 1) entities for which the tag data will be deleted using the array-based function
+ // 2) entities for which the tag data will be deleted using the range-based function
+ // 3) entities for which the tag data will not be deleted
+ MBRange all_entities, del1_range, keep_range;
+ std::vector<MBEntityHandle> del1_list, del2_list, keep_list;
+ rval = mb.get_entities_by_handle( 0, all_entities );
+ CHECK_ERR( rval );
+ int c = 0;
+ for (MBRange::iterator i = all_entities.begin(); i != all_entities.end(); ++i, ++c) {
+ switch (c%3) {
+ case 0: del1_range.insert( *i ); break;
+ case 1: keep_range.insert( *i ); break;
+ case 2: del2_list.push_back( *i ); break;
+ }
+ }
+ del1_list.resize( del1_range.size() );
+ std::copy( del1_range.begin(), del1_range.end(), del1_list.begin() );
+ keep_list.resize( keep_range.size() );
+ std::copy( keep_range.begin(), keep_range.end(), keep_list.begin() );
+
+ // create tag
+ MBEntityHandle first = all_entities.front();
+ MBEntityHandle* defval = with_default_value ? &first : 0;
+ const char* tagname = "dead_tag";
+ MBTag tag = test_create_tag( mb, tagname, sizeof(MBEntityHandle), storage,
+ MB_TYPE_HANDLE, defval );
+
+ // set value for each entity to its handle
+ rval = mb.tag_set_data( tag, del1_range, &del1_list[0] );
+ CHECK_ERR(rval);
+ rval = mb.tag_set_data( tag, keep_range, &keep_list[0] );
+ CHECK_ERR(rval);
+ rval = mb.tag_set_data( tag, &del2_list[0], del2_list.size(), &del2_list[0] );
+ CHECK_ERR(rval);
+
+ // delete tag data
+ rval = mb.tag_delete_data( tag, del1_range );
+ CHECK_ERR(rval);
+ rval = mb.tag_delete_data( tag, &del2_list[0], del2_list.size() );
+ CHECK_ERR(rval);
+
+ // test that keep list is unaffected
+ std::vector<MBEntityHandle> tag_data( keep_range.size(), 0 );
+ rval = mb.tag_get_data( tag, keep_range, &tag_data[0] );
+ CHECK_ERR(rval);
+ CHECK( tag_data == keep_list );
+
+ // try to get data for deleted range
+ tag_data.clear();
+ tag_data.resize( del1_range.size(), (MBEntityHandle)-1 );
+ rval = mb.tag_get_data( tag, del1_range, &tag_data[0] );
+ // if we have a default value, should get that for deleted entities
+ if (with_default_value) {
+ CHECK_ERR(rval);
+ std::vector<MBEntityHandle> expected( del1_range.size(), *defval );
+ CHECK( expected == tag_data );
+ }
+ else if (rval != MB_TAG_NOT_FOUND) {
+ // dense and bit tags might return either MB_TAG_NOT_FOUND or zero bytes.
+ // sparse tags should always return MB_TAG_NOT_FOUND
+ CHECK( MB_TAG_SPARSE != storage );
+ std::vector<MBEntityHandle> expected( del1_range.size(), 0 );
+ CHECK( expected == tag_data );
+ }
+
+ // try to get data for deleted list
+ tag_data.clear();
+ tag_data.resize( del1_range.size(), (MBEntityHandle)-1 );
+ rval = mb.tag_get_data( tag, del1_range, &tag_data[0] );
+ // if we have a default value, should get that for deleted entities
+ if (with_default_value) {
+ CHECK_ERR(rval);
+ std::vector<MBEntityHandle> expected( del1_range.size(), *defval );
+ CHECK( expected == tag_data );
+ }
+ else if (rval != MB_TAG_NOT_FOUND) {
+ // dense and bit tags might return either MB_TAG_NOT_FOUND or zero bytes.
+ // sparse tags should always return MB_TAG_NOT_FOUND
+ CHECK( MB_TAG_SPARSE != storage );
+ std::vector<MBEntityHandle> expected( del1_range.size(), 0 );
+ CHECK( expected == tag_data );
+ }
+}
+
+void test_delete_sparse_data()
+{
+ test_delete_tag_data( MB_TAG_DENSE, false );
+ test_delete_tag_data( MB_TAG_DENSE, true );
+}
+
+void test_delete_dense_data()
+{
+ test_delete_tag_data( MB_TAG_SPARSE, false );
+ test_delete_tag_data( MB_TAG_SPARSE, true );
+}
+
+void test_delete_bit_data()
+{
+ MBCore moab;
+ MBInterface &mb = moab;
+ MBErrorCode rval;
+
+ // get an entity to set data on
+ setup_mesh( mb );
+ MBRange entities;
+ rval = mb.get_entities_by_handle( 0, entities );
+ CHECK_ERR( rval );
+ CHECK( !entities.empty() );
+ MBEntityHandle handle = entities.front();
+
+ // create two tags, one with a default value and one without
+ unsigned char defval = '\006'; // 110
+ MBTag tag1, tag2;
+ tag1 = test_create_tag( mb, "tag1", 2, MB_TAG_BIT, MB_TYPE_BIT, 0 );
+ tag2 = test_create_tag( mb, "tag2", 3, MB_TAG_BIT, MB_TYPE_BIT, &defval );
+
+ // set value for each tag
+ unsigned char val = '\001';
+ rval = mb.tag_set_data( tag1, &handle, 1, &val );
+ CHECK_ERR( rval );
+ rval = mb.tag_set_data( tag2, &handle, 1, &val );
+ CHECK_ERR( rval );
+
+ // delete both tag values
+ rval = mb.tag_delete_data( tag1, &handle, 1 );
+ CHECK_ERR( rval );
+ rval = mb.tag_delete_data( tag2, &handle, 1 );
+ CHECK_ERR( rval );
+
+ // try to get value for tag w/out default.
+ // should get back either not found, or a zero value.
+ val = 0xFF;
+ rval = mb.tag_get_data( tag1, &handle, 1, &val );
+ if (MB_SUCCESS == rval)
+ CHECK_EQUAL( val, '\0' );
+ else
+ CHECK_EQUAL( MB_TAG_NOT_FOUND, rval );
+
+ // test that we get back default value for second tag
+ val = 0xFF;
+ rval = mb.tag_get_data( tag2, &handle, 1, &val );
+ CHECK_ERR( rval );
+ CHECK_EQUAL( defval, val );
+}
+
+void test_get_set_variable_length( const char* name,
+ MBTagType storage,
+ MBDataType type,
+ const void** values,
+ const int* lengths,
+ int num_values,
+ const void* default_value,
+ int default_value_length )
+{
+ std::vector<const void*> data;
+ std::vector<int> data_lens;
+
+ // create mesh and tag
+ MBCore moab;
+ MBInterface& mb = moab;
+ setup_mesh( mb );
+ MBTag tag = test_create_var_len_tag( mb, name, storage, type,
+ default_value, default_value_length );
+
+ // get some handles to work with
+ MBRange entities;
+ MBErrorCode rval = mb.get_entities_by_handle( 0, entities );
+ CHECK_ERR(rval);
+ CHECK( !entities.empty() );
+
+ // split handles into four groups
+ // a) a single handle
+ // b) some non-consecutive handles in an array
+ // c) some handles in an MBRange
+ // d) remaining handles (remaining in 'entities');
+ MBEntityHandle one_handle;
+ MBRange::iterator i = entities.begin() += entities.size()/2;
+ one_handle = *i;
+ entities.erase( i );
+
+ MBRange handle_range;
+ std::vector<MBEntityHandle> handle_list;
+ for (MBRange::const_pair_iterator i = entities.const_pair_begin();
+ i != entities.const_pair_end(); ++i) {
+ if (i->first == i->second || i->second - i->first == 1) {
+ MBEntityHandle h1 = i->first, h2 = i->second;
+ ++i;
+ handle_range.insert( h1, h2 );
+ }
+ else {
+ MBEntityHandle mid = (MBEntityHandle)(i->first + (i->second - i->first + 1) / 2);
+ handle_list.push_back( mid );
+ handle_range.insert( mid+1, i->second );
+ }
+ }
+ entities = entities.subtract( handle_range );
+ for (unsigned i = 0; i < handle_list.size(); ++i)
+ entities.erase( handle_list[i] );
+
+ // try getting/setting single handle value
+ rval = mb.tag_set_data( tag, &one_handle, 1, values, lengths );
+ CHECK_ERR(rval);
+ const void* data_ptr;
+ int data_len;
+ rval = mb.tag_get_data( tag, &one_handle, 1, &data_ptr, &data_len );
+ CHECK_ERR(rval);
+ CHECK_EQUAL( lengths[0], data_len );
+ CHECK( !memcmp( values[0], data_ptr, data_len ) );
+
+
+ // try getting/setting for arrays of handles
+
+ int count = std::min( (int)handle_list.size(), num_values );
+ rval = mb.tag_set_data( tag, &handle_list[0], count, values, lengths );
+ CHECK_ERR( rval );
+ data.clear();
+ data.resize( count, 0 );
+ data_lens.clear();
+ data_lens.resize( count, 0 );
+ rval = mb.tag_get_data( tag, &handle_list[0], count, &data[0], &data_lens[0] );
+ CHECK_ERR( rval );
+ for (int i = 0; i < count; ++i) {
+ CHECK_EQUAL( lengths[i], data_lens[i] );
+ CHECK( NULL != data[i] );
+ CHECK( !memcmp( values[i], data[i], lengths[i] ) );
+ }
+
+ // try getting/setting for MBRange of handles
+
+ data.resize( num_values );
+ data_lens.resize( num_values );
+ std::copy( values, values + num_values, data.begin() );
+ std::copy( lengths, lengths + num_values, data_lens.begin() );
+ while (data.size() < handle_range.size()) {
+ size_t s = data.size();
+ data.resize( 2*s );
+ std::copy( data.begin(), data.begin() + s, data.begin() + s );
+ data_lens.resize( 2*s );
+ std::copy( data_lens.begin(), data_lens.begin() + s, data_lens.begin() + s );
+ }
+ rval = mb.tag_set_data( tag, handle_range, &data[0], &data_lens[0] );
+ CHECK_ERR( rval );
+
+ data.clear();
+ data.resize( handle_range.size(), 0 );
+ data_lens.clear();
+ data_lens.resize( handle_range.size(), 0 );
+ rval = mb.tag_get_data( tag, handle_range, &data[0], &data_lens[0] );
+ CHECK_ERR( rval );
+
+ for (size_t i = 0; i < data.size(); ++i) {
+ const void* expect = values[i%num_values];
+ int expect_len = lengths[i%num_values];
+ CHECK_EQUAL( expect_len, data_lens[i] );
+ CHECK( NULL != data[i] );
+ CHECK( !memcmp( expect, data[i], expect_len ) );
+ }
+
+
+ // try getting unset values
+
+ data.resize( entities.size() );
+ data_lens.resize( entities.size() );
+ rval = mb.tag_get_data( tag, entities, &data[0], &data_lens[0] );
+ // if there was a default value, we should have gotten it for all unset entities
+ if (default_value) {
+ CHECK_ERR( rval );
+ for (unsigned i = 0; i < entities.size(); ++i) {
+ CHECK_EQUAL( default_value_length, data_lens[i] );
+ CHECK( NULL != data[i] );
+ CHECK( !memcmp( default_value, data[i], default_value_length ) );
+ }
+ }
+ // otherwise we should get MB_TAG_NOT_FOUND
+ else {
+ CHECK_EQUAL( MB_TAG_NOT_FOUND, rval );
+ }
+
+ // Check that handles for other entities didn't change.
+
+ // one handle
+ rval = mb.tag_get_data( tag, &one_handle, 1, &data_ptr, &data_len );
+ CHECK_ERR(rval);
+ CHECK_EQUAL( lengths[0], data_len );
+ CHECK( !memcmp( values[0], data_ptr, data_len ) );
+
+ // array values
+ count = std::min( (int)handle_list.size(), num_values );
+ data.clear();
+ data.resize( count, 0 );
+ data_lens.clear();
+ data_lens.resize( count, 0 );
+ rval = mb.tag_get_data( tag, &handle_list[0], count, &data[0], &data_lens[0] );
+ CHECK_ERR( rval );
+ for (int i = 0; i < count; ++i) {
+ CHECK_EQUAL( lengths[i], data_lens[i] );
+ CHECK( NULL != data[i] );
+ CHECK( !memcmp( values[i], data[i], lengths[i] ) );
+ }
+
+ // range values
+ data.clear();
+ data.resize( handle_range.size(), 0 );
+ data_lens.clear();
+ data_lens.resize( handle_range.size(), 0 );
+ rval = mb.tag_get_data( tag, handle_range, &data[0], &data_lens[0] );
+ CHECK_ERR( rval );
+
+ for (size_t i = 0; i < data.size(); ++i) {
+ const void* expect = values[i%num_values];
+ int expect_len = lengths[i%num_values];
+ CHECK_EQUAL( expect_len, data_lens[i] );
+ CHECK( NULL != data[i] );
+ CHECK( !memcmp( expect, data[i], expect_len ) );
+ }
+
+}
+
+void test_get_set_variable_length_sparse()
+{
+ const double doubles[14] = { 1, 2, 3, 4, -4, -3, -2, -1, 42, 0, 1974, -0.5, 1./3, -1e-10 };
+ const void* dvals[5] = { doubles, doubles + 3, doubles + 4, doubles + 8, doubles + 10 };
+ const int ds = sizeof(double);
+ const int dlens[5] = { 3*ds, 1*ds, 4*ds, 2*ds, 4*ds };
+ test_get_set_variable_length( "vnodef", MB_TAG_SPARSE, MB_TYPE_DOUBLE, dvals, dlens, 5, 0, 0 );
+
+ const int ints[32] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ -1,-2,-3,-4,-5,-6,-7,-8,-9,-10,-11,-12,-13,-14,-15 };
+ const void* ivals[9] = { ints, ints+1, ints+3, ints+12, ints+17, ints+21, ints+28, ints+29, ints+31 };
+ const int is = sizeof(double);
+ const int ilens[9] = { 1*is, 2*is, 9*is, 5*is, 4*is, 7*is, 1*is, 2*is, 1*is };
+ const int defvals[] = { 42, 5, 8, 74 };
+ test_get_set_variable_length( "vdef", MB_TAG_SPARSE, MB_TYPE_INTEGER, ivals, ilens, 9, defvals, sizeof(defvals) );
+}
+
+void test_get_set_variable_length_dense()
+{
+ const double doubles[14] = { 1, 2, 3, 4, -4, -3, -2, -1, 42, 0, 1974, -0.5, 1./3, -1e-10 };
+ const void* dvals[5] = { doubles, doubles + 3, doubles + 4, doubles + 8, doubles + 10 };
+ const int ds = sizeof(double);
+ const int dlens[5] = { 3*ds, 1*ds, 4*ds, 2*ds, 4*ds };
+ test_get_set_variable_length( "vnodef", MB_TAG_DENSE, MB_TYPE_DOUBLE, dvals, dlens, 5, 0, 0 );
+
+ const int ints[32] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ -1,-2,-3,-4,-5,-6,-7,-8,-9,-10,-11,-12,-13,-14,-15 };
+ const void* ivals[9] = { ints, ints+1, ints+3, ints+12, ints+17, ints+21, ints+28, ints+29, ints+31 };
+ const int is = sizeof(double);
+ const int ilens[9] = { 1*is, 2*is, 9*is, 5*is, 4*is, 7*is, 1*is, 2*is, 1*is };
+ const int defvals[] = { 42, 5, 8, 74 };
+ test_get_set_variable_length( "vdef", MB_TAG_DENSE, MB_TYPE_INTEGER, ivals, ilens, 9, defvals, sizeof(defvals) );
+}
+
+void test_get_set_variable_length_mesh()
+{
+ MBCore moab;
+ MBInterface &mb = moab;
+ MBErrorCode rval;
+
+ MBTag tag = test_create_var_len_tag( mb, "vmesh", MB_TAG_MESH, MB_TYPE_INTEGER, 0, 0 );
+ int values1[] = { 6 };
+ int values5[] = { 1, 2, 3, 4, 5 };
+
+ int one = sizeof(int);
+ const void* data[1];
+ data[0] = values1;
+ rval = mb.tag_set_data( tag, 0, 0, data, &one );
+ CHECK_ERR( rval );
+
+ int len;
+ rval = mb.tag_get_data( tag, 0, 0, data, &len );
+ CHECK_ERR( rval );
+ CHECK_EQUAL( (int)sizeof(int), len );
+ CHECK_EQUAL( values1[0], *reinterpret_cast<const int*>(data[0]) );
+
+ int five = 5*sizeof(int);
+ data[0] = values5;
+ rval = mb.tag_set_data( tag, 0, 0, data, &five );
+ CHECK_ERR( rval );
+
+ rval = mb.tag_get_data( tag, 0, 0, data, &len );
+ CHECK_ERR( rval );
+ CHECK_EQUAL( 5*(int)sizeof(int), len );
+ CHECK_EQUAL( values5[0], reinterpret_cast<const int*>(data[0])[0] );
+ CHECK_EQUAL( values5[1], reinterpret_cast<const int*>(data[0])[1] );
+ CHECK_EQUAL( values5[2], reinterpret_cast<const int*>(data[0])[2] );
+ CHECK_EQUAL( values5[3], reinterpret_cast<const int*>(data[0])[3] );
+ CHECK_EQUAL( values5[4], reinterpret_cast<const int*>(data[0])[4] );
+}
+
+
+void setup_mesh( MBInterface& mb )
+{
+ MBRange vertex_handles;
+ 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,
+
+ 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,
+
+ 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 };
+ const unsigned num_vtx = sizeof(vertex_coords)/(3*sizeof(double));
+ MBErrorCode rval = mb.create_vertices( vertex_coords, num_vtx, vertex_handles );
+ CHECK_ERR(rval);
+ CHECK_EQUAL( num_vtx, (unsigned)vertex_handles.size() );
+
+ CHECK_EQUAL( 27u, num_vtx );
+ MBEntityHandle elements[8];
+ MBEntityHandle conn[8][8] = { { 0, 1, 4, 3, 9, 10, 13, 12 },
+ { 1, 2, 5, 4, 10, 11, 14, 13 },
+ { 3, 4, 7, 6, 12, 13, 16, 15 },
+ { 4, 5, 8, 7, 13, 14, 17, 16 },
+ { 9, 10, 13, 12, 18, 19, 22, 21 },
+ { 10, 11, 14, 13, 19, 20, 23, 22 },
+ { 12, 13, 16, 15, 21, 22, 25, 24 },
+ { 13, 14, 17, 16, 22, 23, 26, 25 } };
+ for (unsigned i = 0; i < 8; ++i) {
+ rval = mb.create_element( MBHEX, conn[i], 8, elements[i] );
+ CHECK_ERR(rval);
+ }
+
+ // delete some stuff so there are multiple sequences
+ rval = mb.delete_entities( elements + 2, 2 );
+ CHECK_ERR(rval);
+ MBRange::iterator i = vertex_handles.begin();
+ i += 16;
+ rval = mb.delete_entities( &*i, 1 );
+ CHECK_ERR(rval);
+ i += 2;
+ rval = mb.delete_entities( &*i, 1 );
+ CHECK_ERR(rval);
+}
+
+
+
+
More information about the moab-dev
mailing list