![]() |
Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
00001 /** \file DenseTag.cpp
00002 * \author Jason Kraftcheck
00003 * \date 2010-12-14
00004 */
00005
00006 #include "DenseTag.hpp"
00007 #include "moab/Range.hpp"
00008 #include "TagCompare.hpp"
00009 #include "SysUtil.hpp"
00010 #include "SequenceManager.hpp"
00011 #include "SequenceData.hpp"
00012 #include "moab/Error.hpp"
00013 #include "moab/ErrorHandler.hpp"
00014 #include "moab/CN.hpp"
00015 #include
00016
00017 namespace moab
00018 {
00019
00020 inline static ErrorCode not_found( const std::string& /*name*/, EntityHandle /*h*/ )
00021 {
00022 // MB_TAG_NOT_FOUND could be a non-error condition, do not call MB_SET_ERR on it
00023 #if 0
00024 if (h)
00025 fprintf(stderr, "[Warning]: No dense tag %s value for %s %ld\n",
00026 name.c_str(),
00027 CN::EntityTypeName(TYPE_FROM_HANDLE(h)),
00028 (unsigned long)ID_FROM_HANDLE(h));
00029 else
00030 fprintf(stderr, "[Warning]: No dense tag %s value for root set\n", name.c_str());
00031 #endif
00032
00033 return MB_TAG_NOT_FOUND;
00034 }
00035
00036 inline static ErrorCode ent_not_found( const std::string& /*name*/, EntityHandle /*h*/ )
00037 {
00038 // MB_ENTITY_NOT_FOUND could be a non-error condition, do not call MB_SET_ERR on it
00039 #if 0
00040 fprintf(
00041 stderr,
00042 "[Warning]: Invalid entity handle setting tag %s: %s %ld\n",
00043 name.c_str(),
00044 CN::EntityTypeName(TYPE_FROM_HANDLE(h)),
00045 (unsigned long)ID_FROM_HANDLE(h)
00046 );
00047 #endif
00048
00049 return MB_ENTITY_NOT_FOUND;
00050 }
00051
00052 DenseTag::DenseTag( int index, const char* name, int size, DataType type, const void* default_value )
00053 : TagInfo( name, size, type, default_value, size ), mySequenceArray( index ), meshValue( 0 )
00054 {
00055 }
00056
00057 TagType DenseTag::get_storage_type() const
00058 {
00059 return MB_TAG_DENSE;
00060 }
00061
00062 DenseTag* DenseTag::create_tag( SequenceManager* seqman,
00063 Error* /* error */,
00064 const char* name,
00065 int bytes,
00066 DataType type,
00067 const void* default_value )
00068 {
00069 if( bytes < 1 ) return 0;
00070
00071 int index;
00072 if( MB_SUCCESS != seqman->reserve_tag_array( NULL, bytes, index ) ) return 0;
00073
00074 return new DenseTag( index, name, bytes, type, default_value );
00075 }
00076
00077 DenseTag::~DenseTag()
00078 {
00079 assert( mySequenceArray < 0 );
00080 delete[] meshValue;
00081 }
00082
00083 ErrorCode DenseTag::release_all_data( SequenceManager* seqman, Error* /* error */, bool delete_pending )
00084 {
00085 ErrorCode result = seqman->release_tag_array( NULL, mySequenceArray, delete_pending );
00086 if( MB_SUCCESS == result && delete_pending ) mySequenceArray = -1;
00087 return result;
00088 }
00089
00090 ErrorCode DenseTag::get_array( const SequenceManager* seqman,
00091 Error* /* error */,
00092 EntityHandle h,
00093 const unsigned char* const& ptr,
00094 size_t& count ) const
00095 {
00096 // cast away the const-ness; do we really want to do this?
00097 // probably we are not calling this anywhere;
00098 // clang compiler found this
00099 return get_array_private( seqman, NULL, h, const_cast< const unsigned char*& >( ptr ), count );
00100 }
00101
00102 ErrorCode DenseTag::get_array_private( const SequenceManager* seqman,
00103 Error* /* error */,
00104 EntityHandle h,
00105 const unsigned char*& ptr,
00106 size_t& count ) const
00107 {
00108 const EntitySequence* seq = 0;
00109 ErrorCode rval = seqman->find( h, seq );
00110 if( MB_SUCCESS != rval )
00111 {
00112 if( !h )
00113 { // Root set
00114 ptr = meshValue;
00115 count = 1;
00116 return MB_SUCCESS;
00117 }
00118 else
00119 { // Not root set
00120 ptr = 0;
00121 count = 0;
00122 return ent_not_found( get_name(), h );
00123 }
00124 }
00125
00126 const void* mem = seq->data()->get_tag_data( mySequenceArray );
00127 ptr = reinterpret_cast< const unsigned char* >( mem );
00128 count = seq->data()->end_handle() - h + 1;
00129 if( ptr ) ptr += get_size() * ( h - seq->data()->start_handle() );
00130
00131 return MB_SUCCESS;
00132 }
00133
00134 ErrorCode DenseTag::get_array( const EntitySequence* seq, const unsigned char* const& ptr ) const
00135 {
00136 // cast away the constness; otherwise it would be infinite recursion
00137 // probably we are not calling this anywhere
00138 return get_array_private( seq, const_cast< const unsigned char*& >( ptr ) );
00139 }
00140
00141 ErrorCode DenseTag::get_array_private( const EntitySequence* seq, const unsigned char*& ptr ) const
00142 {
00143 ptr = reinterpret_cast< const unsigned char* >( seq->data()->get_tag_data( mySequenceArray ) );
00144 if( ptr ) ptr += get_size() * ( seq->start_handle() - seq->data()->start_handle() );
00145
00146 return MB_SUCCESS;
00147 }
00148
00149 ErrorCode DenseTag::get_array_private( SequenceManager* seqman,
00150 Error* /* error */,
00151 EntityHandle h,
00152 unsigned char*& ptr,
00153 size_t& count,
00154 bool allocate )
00155 {
00156 EntitySequence* seq = 0;
00157 ErrorCode rval = seqman->find( h, seq );
00158 if( MB_SUCCESS != rval )
00159 {
00160 if( !h )
00161 { // Root set
00162 if( !meshValue && allocate ) meshValue = new unsigned char[get_size()];
00163 ptr = meshValue;
00164 count = 1;
00165 return MB_SUCCESS;
00166 }
00167 else
00168 { // Not root set
00169 ptr = 0;
00170 count = 0;
00171 return ent_not_found( get_name(), h );
00172 }
00173 }
00174
00175 void* mem = seq->data()->get_tag_data( mySequenceArray );
00176 if( !mem && allocate )
00177 {
00178 mem = seq->data()->allocate_tag_array( mySequenceArray, get_size(), get_default_value() );
00179 if( !mem )
00180 {
00181 MB_SET_ERR( MB_MEMORY_ALLOCATION_FAILED, "Memory allocation for dense tag data failed" );
00182 }
00183
00184 if( !get_default_value() ) memset( mem, 0, get_size() * seq->data()->size() );
00185 }
00186
00187 ptr = reinterpret_cast< unsigned char* >( mem );
00188 count = seq->data()->end_handle() - h + 1;
00189 if( ptr ) ptr += get_size() * ( h - seq->data()->start_handle() );
00190 return MB_SUCCESS;
00191 }
00192
00193 ErrorCode DenseTag::get_data( const SequenceManager* seqman,
00194 Error* /* error */,
00195 const EntityHandle* entities,
00196 size_t num_entities,
00197 void* adata ) const
00198 {
00199 size_t junk = 0;
00200 unsigned char* ptr = reinterpret_cast< unsigned char* >( adata );
00201 const EntityHandle* const end = entities + num_entities;
00202 for( const EntityHandle* i = entities; i != end; ++i, ptr += get_size() )
00203 {
00204 const unsigned char* data = 0;
00205 ErrorCode rval = get_array( seqman, NULL, *i, data, junk );MB_CHK_ERR( rval );
00206
00207 if( data )
00208 memcpy( ptr, data, get_size() );
00209 else if( get_default_value() )
00210 memcpy( ptr, get_default_value(), get_size() );
00211 else
00212 return not_found( get_name(), *i );
00213 }
00214
00215 return MB_SUCCESS;
00216 }
00217
00218 ErrorCode DenseTag::get_data( const SequenceManager* seqman,
00219 Error* /* error */,
00220 const Range& entities,
00221 void* values ) const
00222 {
00223 ErrorCode rval;
00224 size_t avail = 0;
00225 const unsigned char* array = NULL; // Initialize to get rid of warning
00226 unsigned char* data = reinterpret_cast< unsigned char* >( values );
00227
00228 for( Range::const_pair_iterator p = entities.const_pair_begin(); p != entities.const_pair_end(); ++p )
00229 {
00230 EntityHandle start = p->first;
00231 while( start <= p->second )
00232 {
00233 rval = get_array( seqman, NULL, start, array, avail );MB_CHK_ERR( rval );
00234
00235 const size_t count = std::min< size_t >( p->second - start + 1, avail );
00236 if( array )
00237 memcpy( data, array, get_size() * count );
00238 else if( get_default_value() )
00239 SysUtil::setmem( data, get_default_value(), get_size(), count );
00240 else
00241 return not_found( get_name(), start );
00242
00243 data += get_size() * count;
00244 start += count;
00245 }
00246 }
00247
00248 return MB_SUCCESS;
00249 }
00250
00251 ErrorCode DenseTag::get_data( const SequenceManager* seqman,
00252 Error* /* error */,
00253 const EntityHandle* entities,
00254 size_t num_entities,
00255 const void** pointers,
00256 int* data_lengths ) const
00257 {
00258 ErrorCode result;
00259 const EntityHandle* const end = entities + num_entities;
00260 size_t junk = 0;
00261 const unsigned char* ptr = NULL; // Initialize to get rid of warning
00262
00263 if( data_lengths )
00264 {
00265 const int len = get_size();
00266 SysUtil::setmem( data_lengths, &len, sizeof( int ), num_entities );
00267 }
00268
00269 for( const EntityHandle* i = entities; i != end; ++i, ++pointers )
00270 {
00271 result = get_array( seqman, NULL, *i, ptr, junk );MB_CHK_ERR( result );
00272
00273 if( ptr )
00274 *pointers = ptr;
00275 else if( get_default_value() )
00276 *pointers = get_default_value();
00277 else
00278 return not_found( get_name(), *i );
00279 }
00280
00281 return MB_SUCCESS;
00282 }
00283
00284 ErrorCode DenseTag::get_data( const SequenceManager* seqman,
00285 Error* /* error */,
00286 const Range& entities,
00287 const void** pointers,
00288 int* data_lengths ) const
00289 {
00290 ErrorCode rval;
00291 size_t avail = 0;
00292 const unsigned char* array = NULL;
00293
00294 if( data_lengths )
00295 {
00296 int len = get_size();
00297 SysUtil::setmem( data_lengths, &len, sizeof( int ), entities.size() );
00298 }
00299
00300 for( Range::const_pair_iterator p = entities.const_pair_begin(); p != entities.const_pair_end(); ++p )
00301 {
00302 EntityHandle start = p->first;
00303 while( start <= p->second )
00304 {
00305 rval = get_array( seqman, NULL, start, array, avail );MB_CHK_ERR( rval );
00306
00307 const size_t count = std::min< size_t >( p->second - start + 1, avail );
00308 if( array )
00309 {
00310 for( EntityHandle end = start + count; start != end; ++start )
00311 {
00312 *pointers = array;
00313 array += get_size();
00314 ++pointers;
00315 }
00316 }
00317 else if( const void* val = get_default_value() )
00318 {
00319 SysUtil::setmem( pointers, &val, sizeof( void* ), count );
00320 pointers += count;
00321 start += count;
00322 }
00323 else
00324 {
00325 return not_found( get_name(), start );
00326 }
00327 }
00328 }
00329
00330 return MB_SUCCESS;
00331 }
00332
00333 ErrorCode DenseTag::set_data( SequenceManager* seqman,
00334 Error* /* error */,
00335 const EntityHandle* entities,
00336 size_t num_entities,
00337 const void* data )
00338 {
00339 ErrorCode rval;
00340 const unsigned char* ptr = reinterpret_cast< const unsigned char* >( data );
00341 const EntityHandle* const end = entities + num_entities;
00342 unsigned char* array = NULL;
00343 size_t junk = 0;
00344
00345 for( const EntityHandle* i = entities; i != end; ++i, ptr += get_size() )
00346 {
00347 rval = get_array_private( seqman, NULL, *i, array, junk, true );MB_CHK_ERR( rval );
00348
00349 memcpy( array, ptr, get_size() );
00350 }
00351
00352 return MB_SUCCESS;
00353 }
00354
00355 ErrorCode DenseTag::set_data( SequenceManager* seqman, Error* /* error */, const Range& entities, const void* values )
00356 {
00357 ErrorCode rval;
00358 const char* data = reinterpret_cast< const char* >( values );
00359 unsigned char* array = NULL;
00360 size_t avail = 0;
00361
00362 for( Range::const_pair_iterator p = entities.const_pair_begin(); p != entities.const_pair_end(); ++p )
00363 {
00364 EntityHandle start = p->first;
00365 while( start <= p->second )
00366 {
00367 rval = get_array_private( seqman, NULL, start, array, avail, true );MB_CHK_ERR( rval );
00368
00369 const size_t count = std::min< size_t >( p->second - start + 1, avail );
00370 memcpy( array, data, get_size() * count );
00371 data += get_size() * count;
00372 start += count;
00373 }
00374 }
00375
00376 return MB_SUCCESS;
00377 }
00378
00379 ErrorCode DenseTag::set_data( SequenceManager* seqman,
00380 Error* /* error */,
00381 const EntityHandle* entities,
00382 size_t num_entities,
00383 void const* const* pointers,
00384 const int* data_lengths )
00385 {
00386 ErrorCode rval = validate_lengths( NULL, data_lengths, num_entities );MB_CHK_ERR( rval );
00387
00388 const EntityHandle* const end = entities + num_entities;
00389 unsigned char* array = NULL;
00390 size_t junk = 0;
00391
00392 for( const EntityHandle* i = entities; i != end; ++i, ++pointers )
00393 {
00394 rval = get_array_private( seqman, NULL, *i, array, junk, true );MB_CHK_ERR( rval );
00395
00396 memcpy( array, *pointers, get_size() );
00397 }
00398
00399 return MB_SUCCESS;
00400 }
00401
00402 ErrorCode DenseTag::set_data( SequenceManager* seqman,
00403 Error* /* error */,
00404 const Range& entities,
00405 void const* const* pointers,
00406 const int* /* data_lengths */ )
00407 {
00408 ErrorCode rval;
00409 unsigned char* array = NULL;
00410 size_t avail = 0;
00411
00412 for( Range::const_pair_iterator p = entities.const_pair_begin(); p != entities.const_pair_end(); ++p )
00413 {
00414 EntityHandle start = p->first;
00415 while( start <= p->second )
00416 {
00417 rval = get_array_private( seqman, NULL, start, array, avail, true );MB_CHK_ERR( rval );
00418
00419 const EntityHandle end = std::min< EntityHandle >( p->second + 1, start + avail );
00420 while( start != end )
00421 {
00422 memcpy( array, *pointers, get_size() );
00423 ++start;
00424 ++pointers;
00425 array += get_size();
00426 }
00427 }
00428 }
00429
00430 return MB_SUCCESS;
00431 }
00432
00433 ErrorCode DenseTag::clear_data( bool allocate,
00434 SequenceManager* seqman,
00435 Error* /* error */,
00436 const EntityHandle* entities,
00437 size_t num_entities,
00438 const void* value_ptr )
00439 {
00440 ErrorCode rval;
00441 const EntityHandle* const end = entities + num_entities;
00442 unsigned char* array = NULL;
00443 size_t junk = 0;
00444
00445 for( const EntityHandle* i = entities; i != end; ++i )
00446 {
00447 rval = get_array_private( seqman, NULL, *i, array, junk, allocate );MB_CHK_ERR( rval );
00448
00449 if( array ) // Array should never be null if allocate == true
00450 memcpy( array, value_ptr, get_size() );
00451 }
00452
00453 return MB_SUCCESS;
00454 }
00455
00456 ErrorCode DenseTag::clear_data( bool allocate,
00457 SequenceManager* seqman,
00458 Error* /* error */,
00459 const Range& entities,
00460 const void* value_ptr )
00461 {
00462 ErrorCode rval;
00463 unsigned char* array = NULL;
00464 size_t avail = 0;
00465
00466 for( Range::const_pair_iterator p = entities.const_pair_begin(); p != entities.const_pair_end(); ++p )
00467 {
00468 EntityHandle start = p->first;
00469 while( start <= p->second )
00470 {
00471 rval = get_array_private( seqman, NULL, start, array, avail, allocate );MB_CHK_ERR( rval );
00472
00473 const size_t count = std::min< size_t >( p->second - start + 1, avail );
00474 if( array ) // Array should never be null if allocate == true
00475 SysUtil::setmem( array, value_ptr, get_size(), count );
00476 start += count;
00477 }
00478 }
00479
00480 return MB_SUCCESS;
00481 }
00482
00483 ErrorCode DenseTag::clear_data( SequenceManager* seqman,
00484 Error* /* error */,
00485 const EntityHandle* entities,
00486 size_t num_entities,
00487 const void* value_ptr,
00488 int value_len )
00489 {
00490 if( value_len && value_len != get_size() ) return MB_INVALID_SIZE;
00491
00492 return clear_data( true, seqman, NULL, entities, num_entities, value_ptr );
00493 }
00494
00495 ErrorCode DenseTag::clear_data( SequenceManager* seqman,
00496 Error* /* error */,
00497 const Range& entities,
00498 const void* value_ptr,
00499 int value_len )
00500 {
00501 if( value_len && value_len != get_size() ) return MB_INVALID_SIZE;
00502
00503 return clear_data( true, seqman, NULL, entities, value_ptr );
00504 }
00505
00506 ErrorCode DenseTag::remove_data( SequenceManager* seqman,
00507 Error* /* error */,
00508 const EntityHandle* entities,
00509 size_t num_entities )
00510 {
00511 std::vector< unsigned char > zeros;
00512 const void* value = get_default_value();
00513 if( !value )
00514 {
00515 zeros.resize( get_size(), 0 );
00516 value = &zeros[0];
00517 }
00518
00519 return clear_data( false, seqman, NULL, entities, num_entities, value );
00520 }
00521
00522 ErrorCode DenseTag::remove_data( SequenceManager* seqman, Error* /* error */, const Range& entities )
00523 {
00524 std::vector< unsigned char > zeros;
00525 const void* value = get_default_value();
00526 if( !value )
00527 {
00528 zeros.resize( get_size(), 0 );
00529 value = &zeros[0];
00530 }
00531
00532 return clear_data( false, seqman, NULL, entities, value );
00533 }
00534
00535 ErrorCode DenseTag::tag_iterate( SequenceManager* seqman,
00536 Error* /* error */,
00537 Range::iterator& iter,
00538 const Range::iterator& end,
00539 void*& data_ptr,
00540 bool allocate )
00541 {
00542 // If asked for nothing, successfully return nothing.
00543 if( iter == end ) return MB_SUCCESS;
00544
00545 unsigned char* array = NULL;
00546 size_t avail = 0;
00547 ErrorCode rval = get_array_private( seqman, NULL, *iter, array, avail, allocate );MB_CHK_ERR( rval );
00548 data_ptr = array;
00549
00550 size_t count = std::min< size_t >( avail, *( iter.end_of_block() ) - *iter + 1 );
00551 if( 0 != *end && *end <= *( iter.end_of_block() ) )
00552 iter = end;
00553 else
00554 iter += count;
00555
00556 return MB_SUCCESS;
00557 }
00558
00559 ErrorCode DenseTag::get_tagged_entities( const SequenceManager* seqman,
00560 Range& entities_in,
00561 EntityType type,
00562 const Range* intersect_list ) const
00563 {
00564 Range tmp;
00565 Range* entities = intersect_list ? &tmp : &entities_in;
00566 Range::iterator hint = entities->begin();
00567 std::pair< EntityType, EntityType > range = type_range( type );
00568 TypeSequenceManager::const_iterator i;
00569 for( EntityType t = range.first; t != range.second; ++t )
00570 {
00571 const TypeSequenceManager& map = seqman->entity_map( t );
00572 for( i = map.begin(); i != map.end(); ++i )
00573 if( ( *i )->data()->get_tag_data( mySequenceArray ) )
00574 hint = entities->insert( hint, ( *i )->start_handle(), ( *i )->end_handle() );
00575 }
00576
00577 if( intersect_list ) entities_in = intersect( *entities, *intersect_list );
00578
00579 return MB_SUCCESS;
00580 }
00581
00582 ErrorCode DenseTag::num_tagged_entities( const SequenceManager* seqman,
00583 size_t& output_count,
00584 EntityType type,
00585 const Range* intersect ) const
00586 {
00587 Range tmp;
00588 ErrorCode rval = get_tagged_entities( seqman, tmp, type, intersect );
00589 output_count += tmp.size();
00590
00591 return rval;
00592 }
00593
00594 ErrorCode DenseTag::find_entities_with_value( const SequenceManager* seqman,
00595 Error* /* error */,
00596 Range& output_entities,
00597 const void* value,
00598 int value_bytes,
00599 EntityType type,
00600 const Range* intersect_entities ) const
00601 {
00602 if( value_bytes && value_bytes != get_size() )
00603 {
00604 MB_SET_ERR( MB_INVALID_SIZE,
00605 "Cannot compare data of size " << value_bytes << " with tag of size " << get_size() );
00606 }
00607
00608 if( !intersect_entities )
00609 {
00610 std::pair< EntityType, EntityType > range = type_range( type );
00611 TypeSequenceManager::const_iterator i;
00612 for( EntityType t = range.first; t != range.second; ++t )
00613 {
00614 const TypeSequenceManager& map = seqman->entity_map( t );
00615 for( i = map.begin(); i != map.end(); ++i )
00616 {
00617 const void* data = ( *i )->data()->get_tag_data( mySequenceArray );
00618 if( data )
00619 {
00620 ByteArrayIterator start( ( *i )->data()->start_handle(), data, *this );
00621 ByteArrayIterator end( ( *i )->end_handle() + 1, 0, 0 );
00622 start += ( *i )->start_handle() - ( *i )->data()->start_handle();
00623 find_tag_values_equal( *this, value, get_size(), start, end, output_entities );
00624 }
00625 }
00626 }
00627 }
00628 else
00629 {
00630 const unsigned char* array = NULL; // Initialize to get rid of warning
00631 size_t count;
00632 ErrorCode rval;
00633
00634 Range::const_pair_iterator p = intersect_entities->begin();
00635 if( type != MBMAXTYPE )
00636 {
00637 p = intersect_entities->lower_bound( type );
00638 assert( TYPE_FROM_HANDLE( p->first ) == type );
00639 }
00640 for( ;
00641 p != intersect_entities->const_pair_end() && ( MBMAXTYPE == type || TYPE_FROM_HANDLE( p->first ) == type );
00642 ++p )
00643 {
00644 EntityHandle start = p->first;
00645 while( start <= p->second )
00646 {
00647 rval = get_array( seqman, NULL, start, array, count );MB_CHK_ERR( rval );
00648
00649 if( p->second - start < count - 1 ) count = p->second - start + 1;
00650
00651 if( array )
00652 {
00653 ByteArrayIterator istart( start, array, *this );
00654 ByteArrayIterator iend( start + count, 0, 0 );
00655 find_tag_values_equal( *this, value, get_size(), istart, iend, output_entities );
00656 }
00657 start += count;
00658 }
00659 }
00660 }
00661
00662 return MB_SUCCESS;
00663 }
00664
00665 bool DenseTag::is_tagged( const SequenceManager* seqman, EntityHandle h ) const
00666 {
00667 const unsigned char* ptr = NULL; // Initialize to get rid of warning
00668 size_t count;
00669 return ( MB_SUCCESS == get_array( seqman, 0, h, ptr, count ) ) && ( NULL != ptr );
00670 }
00671
00672 ErrorCode DenseTag::get_memory_use( const SequenceManager* seqman,
00673 unsigned long& total,
00674 unsigned long& per_entity ) const
00675 {
00676 per_entity = get_size();
00677 total = TagInfo::get_memory_use() + sizeof( *this );
00678 for( EntityType t = MBVERTEX; t <= MBENTITYSET; ++t )
00679 {
00680 const TypeSequenceManager& map = seqman->entity_map( t );
00681 const SequenceData* prev_data = 0;
00682 for( TypeSequenceManager::const_iterator i = map.begin(); i != map.end(); ++i )
00683 {
00684 if( ( *i )->data() != prev_data && ( *i )->data()->get_tag_data( mySequenceArray ) )
00685 {
00686 prev_data = ( *i )->data();
00687 total += get_size() * ( *i )->data()->size();
00688 }
00689 }
00690 }
00691
00692 return MB_SUCCESS;
00693 }
00694
00695 } // namespace moab