MOAB: Mesh Oriented datABase  (version 5.3.1)
SequenceManager.cpp
Go to the documentation of this file.
00001 #include "SequenceManager.hpp"
00002 #include "VertexSequence.hpp"
00003 #include "UnstructuredElemSeq.hpp"
00004 #include "ScdVertexData.hpp"
00005 #include "MeshSetSequence.hpp"
00006 #include "SweptElementSeq.hpp"
00007 #include "StructuredElementSeq.hpp"
00008 #include "moab/HomXform.hpp"
00009 #include "PolyElementSeq.hpp"
00010 #include "SysUtil.hpp"
00011 #include "moab/Error.hpp"
00012 
00013 #include <cassert>
00014 #include <new>
00015 #include <algorithm>
00016 
00017 #ifndef NDEBUG
00018 #include <iostream>
00019 #endif
00020 
00021 namespace moab
00022 {
00023 
00024 const EntityID SequenceManager::DEFAULT_VERTEX_SEQUENCE_SIZE  = 512 * 1024;
00025 const EntityID SequenceManager::DEFAULT_ELEMENT_SEQUENCE_SIZE = DEFAULT_VERTEX_SEQUENCE_SIZE;
00026 const EntityID SequenceManager::DEFAULT_POLY_SEQUENCE_SIZE    = 16 * 1024;
00027 const EntityID SequenceManager::DEFAULT_MESHSET_SEQUENCE_SIZE = DEFAULT_VERTEX_SEQUENCE_SIZE;
00028 
00029 const int UNUSED_SIZE = 0;
00030 
00031 EntityID SequenceManager::default_poly_sequence_size( int conn_len )
00032 {
00033     return std::max( DEFAULT_POLY_SEQUENCE_SIZE / conn_len, (EntityID)1 );
00034 }
00035 
00036 SequenceManager::~SequenceManager()
00037 {
00038     // Release variable-length tag data
00039     for( unsigned i = 0; i < tagSizes.size(); ++i )
00040         if( tagSizes[i] == MB_VARIABLE_LENGTH ) release_tag_array( 0, i, false );
00041 }
00042 
00043 void SequenceManager::clear()
00044 {
00045     // reset sequence multiplier
00046     sequence_multiplier = 1.0;
00047 
00048     // Destroy all TypeSequenceManager instances
00049     for( EntityType t = MBVERTEX; t < MBMAXTYPE; ++t )
00050         typeData[t].~TypeSequenceManager();
00051 
00052     // Now re-create TypeSequenceManager instances
00053     for( EntityType t = MBVERTEX; t < MBMAXTYPE; ++t )
00054         new( typeData + t ) TypeSequenceManager();
00055 }
00056 
00057 void SequenceManager::get_entities( Range& entities_out ) const
00058 {
00059     for( EntityType t = MBENTITYSET; t >= MBVERTEX; --t )
00060         typeData[t].get_entities( entities_out );
00061 }
00062 
00063 void SequenceManager::get_entities( std::vector< EntityHandle >& entities_out ) const
00064 {
00065     for( EntityType t = MBVERTEX; t != MBMAXTYPE; ++t )
00066         typeData[t].get_entities( entities_out );
00067 }
00068 
00069 EntityID SequenceManager::get_number_entities() const
00070 {
00071     EntityID sum = 0;
00072     for( EntityType t = MBVERTEX; t != MBMAXTYPE; ++t )
00073         sum += typeData[t].get_number_entities();
00074 
00075     return sum;
00076 }
00077 
00078 ErrorCode SequenceManager::check_valid_entities( Error* /* error */, const Range& entities ) const
00079 {
00080     ErrorCode rval;
00081     Range::const_pair_iterator i;
00082     for( i = entities.const_pair_begin(); i != entities.const_pair_end(); ++i )
00083     {
00084         const EntityType type1 = TYPE_FROM_HANDLE( i->first );
00085         const EntityType type2 = TYPE_FROM_HANDLE( i->second );
00086         if( type1 == type2 )
00087         {
00088             rval = typeData[type1].check_valid_handles( NULL, i->first, i->second );
00089             if( MB_SUCCESS != rval ) return rval;
00090         }
00091         else
00092         {
00093             int junk;
00094             EntityHandle split = CREATE_HANDLE( type2, 0, junk );
00095             rval               = typeData[type1].check_valid_handles( NULL, i->first, split - 1 );
00096             if( MB_SUCCESS != rval ) return rval;
00097             rval = typeData[type2].check_valid_handles( NULL, split, i->second );
00098             if( MB_SUCCESS != rval ) return rval;
00099         }
00100     }
00101 
00102     return MB_SUCCESS;
00103 }
00104 
00105 ErrorCode SequenceManager::check_valid_entities( Error* /* error_handler */, const EntityHandle* entities,
00106                                                  size_t num_entities, bool root_set_okay ) const
00107 {
00108     ErrorCode rval;
00109     const EntitySequence* ptr = 0;
00110 
00111     const EntityHandle* const end = entities + num_entities;
00112     for( ; entities < end; ++entities )
00113     {
00114         rval = find( *entities, ptr );
00115         if( MB_SUCCESS != rval && !( root_set_okay && !*entities ) )
00116         {
00117             if( MB_ENTITY_NOT_FOUND == rval )
00118             {
00119                 // MB_ENTITY_NOT_FOUND could be a non-error condition, do not call MB_SET_ERR on it
00120 #if 0
00121         fprintf(stderr, "[Warning]: Invalid entity handle: 0x%lx\n", (unsigned long)*entities);
00122 #endif
00123             }
00124             return rval;
00125         }
00126     }
00127 
00128     return MB_SUCCESS;
00129 }
00130 
00131 ErrorCode SequenceManager::delete_entity( Error* /* error */, EntityHandle entity )
00132 {
00133     return typeData[TYPE_FROM_HANDLE( entity )].erase( NULL, entity );
00134 }
00135 
00136 ErrorCode SequenceManager::delete_entities( Error* /* error */, const Range& entities )
00137 {
00138     ErrorCode rval = check_valid_entities( NULL, entities );
00139     if( MB_SUCCESS != rval ) return rval;
00140 
00141     ErrorCode result = MB_SUCCESS;
00142     Range::const_pair_iterator i;
00143     for( i = entities.const_pair_begin(); i != entities.const_pair_end(); ++i )
00144     {
00145         const EntityType type1 = TYPE_FROM_HANDLE( i->first );
00146         const EntityType type2 = TYPE_FROM_HANDLE( i->second );
00147         if( type1 == type2 )
00148         {
00149             rval = typeData[type1].erase( NULL, i->first, i->second );
00150             if( MB_SUCCESS != rval ) return result = rval;
00151         }
00152         else
00153         {
00154             int junk;
00155             EntityHandle split = CREATE_HANDLE( type2, 0, junk );
00156             rval               = typeData[type1].erase( NULL, i->first, split - 1 );
00157             if( MB_SUCCESS != rval ) return result = rval;
00158             rval = typeData[type2].erase( NULL, split, i->second );
00159             if( MB_SUCCESS != rval ) return result = rval;
00160         }
00161     }
00162 
00163     return result;
00164 }
00165 
00166 ErrorCode SequenceManager::create_vertex( const double coords[3], EntityHandle& handle )
00167 {
00168     const EntityHandle start = CREATE_HANDLE( MBVERTEX, MB_START_ID );
00169     const EntityHandle end   = CREATE_HANDLE( MBVERTEX, MB_END_ID );
00170     bool append;
00171     TypeSequenceManager::iterator seq = typeData[MBVERTEX].find_free_handle( start, end, append );
00172     VertexSequence* vseq;
00173 
00174     if( seq == typeData[MBVERTEX].end() )
00175     {
00176         SequenceData* seq_data = 0;
00177         EntityID seq_data_size = 0;
00178         handle =
00179             typeData[MBVERTEX].find_free_sequence( DEFAULT_VERTEX_SEQUENCE_SIZE, start, end, seq_data, seq_data_size );
00180         if( !handle ) return MB_FAILURE;
00181 
00182         if( seq_data )
00183             vseq = new VertexSequence( handle, 1, seq_data );
00184         else
00185             vseq = new VertexSequence( handle, 1, DEFAULT_VERTEX_SEQUENCE_SIZE );
00186 
00187         ErrorCode rval = typeData[MBVERTEX].insert_sequence( vseq );
00188         if( MB_SUCCESS != rval )
00189         {
00190             SequenceData* vdata = vseq->data();
00191             delete vseq;
00192             if( !seq_data ) delete vdata;
00193 
00194             return rval;
00195         }
00196     }
00197     else
00198     {
00199         vseq = reinterpret_cast< VertexSequence* >( *seq );
00200         if( append )
00201         {
00202             vseq->push_back( 1 );
00203             handle = vseq->end_handle();
00204             typeData[MBVERTEX].notify_appended( seq );
00205         }
00206         else
00207         {
00208             vseq->push_front( 1 );
00209             handle = vseq->start_handle();
00210             typeData[MBVERTEX].notify_prepended( seq );
00211         }
00212     }
00213 
00214     return vseq->set_coordinates( handle, coords );
00215 }
00216 
00217 ErrorCode SequenceManager::create_element( EntityType type, const EntityHandle* conn, unsigned conn_len,
00218                                            EntityHandle& handle )
00219 {
00220     if( type <= MBVERTEX || type >= MBENTITYSET ) return MB_TYPE_OUT_OF_RANGE;
00221 
00222     const EntityHandle start = CREATE_HANDLE( type, MB_START_ID );
00223     const EntityHandle end   = CREATE_HANDLE( type, MB_END_ID );
00224     bool append;
00225     TypeSequenceManager::iterator seq = typeData[type].find_free_handle( start, end, append, conn_len );
00226     UnstructuredElemSeq* eseq;
00227 
00228     if( seq == typeData[type].end() )
00229     {
00230         SequenceData* seq_data = 0;
00231         unsigned size          = DEFAULT_ELEMENT_SEQUENCE_SIZE;
00232         if( type == MBPOLYGON || type == MBPOLYHEDRON ) { size = default_poly_sequence_size( conn_len ); }
00233         EntityID seq_data_size = 0;
00234         handle = typeData[type].find_free_sequence( size, start, end, seq_data, seq_data_size, conn_len );
00235         if( !handle ) return MB_FAILURE;
00236 
00237         if( MBPOLYGON == type || MBPOLYHEDRON == type )
00238         {
00239             if( seq_data )
00240                 eseq = new PolyElementSeq( handle, 1, conn_len, seq_data );
00241             else
00242                 eseq = new PolyElementSeq( handle, 1, conn_len, size );
00243         }
00244         else
00245         {
00246             if( seq_data )
00247                 eseq = new UnstructuredElemSeq( handle, 1, conn_len, seq_data );
00248             else
00249                 eseq = new UnstructuredElemSeq( handle, 1, conn_len, size );
00250         }
00251 
00252         ErrorCode rval = typeData[type].insert_sequence( eseq );
00253         if( MB_SUCCESS != rval )
00254         {
00255             SequenceData* vdata = eseq->data();
00256             delete eseq;
00257             if( !seq_data ) delete vdata;
00258 
00259             return rval;
00260         }
00261     }
00262     else
00263     {
00264         eseq = reinterpret_cast< UnstructuredElemSeq* >( *seq );
00265         if( append )
00266         {
00267             eseq->push_back( 1 );
00268             handle = eseq->end_handle();
00269             typeData[type].notify_appended( seq );
00270         }
00271         else
00272         {
00273             eseq->push_front( 1 );
00274             handle = eseq->start_handle();
00275             typeData[type].notify_prepended( seq );
00276         }
00277     }
00278 
00279     return eseq->set_connectivity( handle, conn, conn_len );
00280 }
00281 
00282 ErrorCode SequenceManager::create_mesh_set( unsigned flags, EntityHandle& handle )
00283 {
00284     const EntityHandle start = CREATE_HANDLE( MBENTITYSET, MB_START_ID );
00285     const EntityHandle end   = CREATE_HANDLE( MBENTITYSET, MB_END_ID );
00286     bool append;
00287     TypeSequenceManager::iterator seq = typeData[MBENTITYSET].find_free_handle( start, end, append );
00288     MeshSetSequence* msseq;
00289 
00290     if( seq == typeData[MBENTITYSET].end() )
00291     {
00292         SequenceData* seq_data = 0;
00293         EntityID seq_data_size = 0;
00294         handle = typeData[MBENTITYSET].find_free_sequence( DEFAULT_MESHSET_SEQUENCE_SIZE, start, end, seq_data,
00295                                                            seq_data_size );
00296         if( !handle ) return MB_FAILURE;
00297 
00298         if( seq_data )
00299             msseq = new MeshSetSequence( handle, 1, flags, seq_data );
00300         else
00301             msseq = new MeshSetSequence( handle, 1, flags, DEFAULT_MESHSET_SEQUENCE_SIZE );
00302 
00303         ErrorCode rval = typeData[MBENTITYSET].insert_sequence( msseq );
00304         if( MB_SUCCESS != rval )
00305         {
00306             SequenceData* vdata = msseq->data();
00307             delete msseq;
00308             if( !seq_data ) delete vdata;
00309 
00310             return rval;
00311         }
00312     }
00313     else
00314     {
00315         msseq = reinterpret_cast< MeshSetSequence* >( *seq );
00316         if( append )
00317         {
00318             msseq->push_back( 1, &flags );
00319             handle = msseq->end_handle();
00320             typeData[MBENTITYSET].notify_appended( seq );
00321         }
00322         else
00323         {
00324             msseq->push_front( 1, &flags );
00325             handle = msseq->start_handle();
00326             typeData[MBENTITYSET].notify_prepended( seq );
00327         }
00328     }
00329 
00330     return MB_SUCCESS;
00331 }
00332 
00333 ErrorCode SequenceManager::allocate_mesh_set( EntityHandle handle, unsigned flags )
00334 {
00335     SequenceData* data = 0;
00336     TypeSequenceManager::iterator seqptr;
00337     EntityHandle block_start = 1, block_end = 0;
00338     ErrorCode rval = typeData[MBENTITYSET].is_free_handle( handle, seqptr, data, block_start, block_end );
00339     if( MB_SUCCESS != rval ) return rval;
00340 
00341     MeshSetSequence* seq;
00342     if( seqptr != typeData[MBENTITYSET].end() )
00343     {
00344         seq = static_cast< MeshSetSequence* >( *seqptr );
00345         if( seq->start_handle() - 1 == handle )
00346         {
00347             rval = seq->push_front( 1, &flags );
00348             if( MB_SUCCESS == rval )
00349             {
00350                 rval = typeData[MBENTITYSET].notify_prepended( seqptr );
00351                 if( MB_SUCCESS != rval ) seq->pop_front( 1 );
00352             }
00353             return rval;
00354         }
00355         else if( seq->end_handle() + 1 == handle )
00356         {
00357             rval = seq->push_back( 1, &flags );
00358             if( MB_SUCCESS == rval )
00359             {
00360                 rval = typeData[MBENTITYSET].notify_appended( seqptr );
00361                 if( MB_SUCCESS != rval ) seq->pop_back( 1 );
00362             }
00363             return rval;
00364         }
00365         else
00366             return MB_FAILURE;  // Should be unreachable
00367     }
00368     else
00369     {
00370         if( data ) { seq = new MeshSetSequence( handle, 1, flags, data ); }
00371         else
00372         {
00373             assert( handle >= block_start && handle <= block_end );
00374             trim_sequence_block( handle, block_end, DEFAULT_MESHSET_SEQUENCE_SIZE );
00375             seq = new MeshSetSequence( handle, 1, flags, block_end - handle + 1 );
00376         }
00377 
00378         rval = typeData[MBENTITYSET].insert_sequence( seq );
00379         if( MB_SUCCESS != rval )
00380         {
00381             SequenceData* vdata = seq->data();
00382             delete seq;
00383             if( !data ) delete vdata;
00384             return rval;
00385         }
00386 
00387         return MB_SUCCESS;
00388     }
00389 }
00390 
00391 void SequenceManager::trim_sequence_block( EntityHandle start_handle, EntityHandle& end_handle, unsigned max_size )
00392 {
00393     assert( end_handle >= start_handle );
00394     assert( (int)max_size > 0 );  // Cast to int also prohibits some ridiculously large values
00395 
00396     // If input range is larger than preferred size, trim it
00397     if( end_handle - start_handle >= max_size ) end_handle = start_handle + max_size - 1;
00398 }
00399 
00400 EntityHandle SequenceManager::sequence_start_handle( EntityType type, EntityID count, int size, EntityID start,
00401                                                      SequenceData*& data, EntityID& data_size )
00402 {
00403     TypeSequenceManager& tsm = typeData[type];
00404     data                     = 0;
00405     EntityHandle handle      = CREATE_HANDLE( type, start );
00406     if( start < MB_START_ID || !tsm.is_free_sequence( handle, count, data, size ) )
00407     {
00408         EntityHandle pstart = CREATE_HANDLE( type, MB_START_ID );
00409         EntityHandle pend   = CREATE_HANDLE( type, MB_END_ID );
00410         handle              = tsm.find_free_sequence( count, pstart, pend, data, data_size, size );
00411     }
00412 
00413     return handle;
00414 }
00415 
00416 EntityID SequenceManager::new_sequence_size( EntityHandle start, EntityID requested_size, int sequence_size ) const
00417 {
00418 
00419     requested_size = ( EntityID )( this->sequence_multiplier * requested_size );
00420 
00421     if( sequence_size < (int)requested_size ) return requested_size;
00422 
00423     EntityHandle last = typeData[TYPE_FROM_HANDLE( start )].last_free_handle( start );
00424     if( !last )
00425     {
00426         assert( false );
00427         return 0;
00428     }
00429 
00430     EntityID available_size = last - start + 1;
00431     if( sequence_size < available_size )
00432         return sequence_size;
00433     else
00434         return available_size;
00435 }
00436 
00437 ErrorCode SequenceManager::create_entity_sequence( EntityType type, EntityID count, int size, EntityID start,
00438                                                    EntityHandle& handle, EntitySequence*& sequence, int sequence_size )
00439 {
00440     SequenceData* data = NULL;
00441     EntityID data_size = 0;
00442     handle             = sequence_start_handle( type, count, size, start, data, data_size );
00443 
00444     if( !handle ) return MB_MEMORY_ALLOCATION_FAILED;
00445 
00446     switch( type )
00447     {
00448         case MBENTITYSET:
00449         case MBMAXTYPE:
00450             return MB_TYPE_OUT_OF_RANGE;
00451 
00452         case MBVERTEX:
00453             if( size != 0 ) return MB_INDEX_OUT_OF_RANGE;
00454 
00455             if( data )
00456                 sequence = new VertexSequence( handle, count, data );
00457             else
00458             {
00459                 if( !data_size ) data_size = new_sequence_size( handle, count, sequence_size );
00460                 sequence = new VertexSequence( handle, count, data_size );
00461             }
00462             break;
00463 
00464         case MBPOLYGON:
00465         case MBPOLYHEDRON:
00466             if( size == 0 ) return MB_INDEX_OUT_OF_RANGE;
00467 
00468             if( data )
00469                 sequence = new PolyElementSeq( handle, count, size, data );
00470             else
00471             {
00472                 if( !data_size )
00473                     data_size = new_sequence_size(
00474                         handle, count, ( -1 == sequence_size ? default_poly_sequence_size( size ) : sequence_size ) );
00475                 sequence = new PolyElementSeq( handle, count, size, data_size );
00476             }
00477             break;
00478 
00479         default:
00480             if( size == 0 ) return MB_INDEX_OUT_OF_RANGE;
00481 
00482             if( data )
00483                 sequence = new UnstructuredElemSeq( handle, count, size, data );
00484             else
00485             {
00486                 if( !data_size ) data_size = new_sequence_size( handle, count, sequence_size );
00487                 sequence = new UnstructuredElemSeq( handle, count, size, data_size );
00488             }
00489             // tjt calling new_sequence_size 'cuz don't have a sequence data;
00490             // start 41467, count 246
00491             break;
00492     }
00493 
00494     ErrorCode result = typeData[type].insert_sequence( sequence );
00495     if( MB_SUCCESS != result )
00496     {
00497         // Change to NULL if had an existing data or if no existing data,
00498         // change to the new data created
00499         data = data ? 0 : sequence->data();
00500         delete sequence;
00501         delete data;
00502         return result;
00503     }
00504 
00505     return MB_SUCCESS;
00506 }
00507 
00508 ErrorCode SequenceManager::create_meshset_sequence( EntityID count, EntityID start, const unsigned* flags,
00509                                                     EntityHandle& handle, EntitySequence*& sequence )
00510 {
00511     SequenceData* data = 0;
00512     EntityID data_size = 0;
00513     handle             = sequence_start_handle( MBENTITYSET, count, 0, start, data, data_size );
00514 
00515     if( !handle ) return MB_MEMORY_ALLOCATION_FAILED;
00516 
00517     if( data )
00518         sequence = new MeshSetSequence( handle, count, flags, data );
00519     else
00520         sequence = new MeshSetSequence( handle, count, flags, count );
00521 
00522     ErrorCode result = typeData[MBENTITYSET].insert_sequence( sequence );
00523     if( MB_SUCCESS != result )
00524     {
00525         // Change to NULL if had an existing data or if no existing data,
00526         // change to the new data created
00527         data = data ? 0 : sequence->data();
00528         delete sequence;
00529         delete data;
00530         return result;
00531     }
00532 
00533     return MB_SUCCESS;
00534 }
00535 
00536 ErrorCode SequenceManager::create_meshset_sequence( EntityID count, EntityID start, unsigned flags,
00537                                                     EntityHandle& handle, EntitySequence*& sequence )
00538 {
00539     SequenceData* data = 0;
00540     EntityID data_size = 0;
00541     handle             = sequence_start_handle( MBENTITYSET, count, 0, start, data, data_size );
00542     if( !handle ) return MB_MEMORY_ALLOCATION_FAILED;
00543 
00544     if( data )
00545         sequence = new MeshSetSequence( handle, count, flags, data );
00546     else
00547         sequence = new MeshSetSequence( handle, count, flags, count );
00548 
00549     ErrorCode result = typeData[MBENTITYSET].insert_sequence( sequence );
00550     if( MB_SUCCESS != result )
00551     {
00552         // Change to NULL if had an existing data or if no existing data,
00553         // change to the new data created
00554         data = data ? 0 : sequence->data();
00555         delete sequence;
00556         delete data;
00557         return result;
00558     }
00559 
00560     return MB_SUCCESS;
00561 }
00562 
00563 ErrorCode SequenceManager::create_scd_sequence( int imin, int jmin, int kmin, int imax, int jmax, int kmax,
00564                                                 EntityType type, EntityID start_id_hint, EntityHandle& handle,
00565                                                 EntitySequence*& sequence, int* is_periodic )
00566 {
00567     int this_dim = CN::Dimension( type );
00568 
00569     // Use > instead of != in the following assert to also catch cases where imin > imax, etc.
00570     assert( ( this_dim < 3 || kmax > kmin ) && ( this_dim < 2 || jmax > jmin ) && ( this_dim < 1 || imax > imin ) );
00571 
00572     // Compute # entities; not as easy as it would appear...
00573     EntityID num_ent;
00574     if( MBVERTEX == type )
00575         num_ent = ( EntityID )( imax - imin + 1 ) * ( EntityID )( jmax - jmin + 1 ) * ( EntityID )( kmax - kmin + 1 );
00576     else
00577     {
00578         num_ent = ( imax - imin + ( is_periodic && is_periodic[0] ? 1 : 0 ) ) *
00579                   ( this_dim >= 2 ? ( jmax - jmin + ( is_periodic && is_periodic[1] ? 1 : 0 ) ) : 1 ) *
00580                   ( this_dim >= 3 ? ( kmax - kmin ) : 1 );
00581     }
00582 
00583     if( MBVERTEX == type && ( is_periodic && ( is_periodic[0] || is_periodic[1] ) ) ) return MB_FAILURE;
00584 
00585     // Get a start handle
00586     SequenceData* data = 0;
00587     EntityID data_size = 0;
00588     handle             = sequence_start_handle( type, num_ent, -1, start_id_hint, data, data_size );
00589 
00590     if( !handle ) return MB_MEMORY_ALLOCATION_FAILED;
00591     assert( !data );
00592 
00593     switch( type )
00594     {
00595         case MBVERTEX:
00596             data     = new ScdVertexData( handle, imin, jmin, kmin, imax, jmax, kmax );
00597             sequence = new VertexSequence( handle, data->size(), data );
00598             break;
00599         case MBEDGE:
00600         case MBQUAD:
00601         case MBHEX:
00602             sequence = new StructuredElementSeq( handle, imin, jmin, kmin, imax, jmax, kmax, is_periodic );
00603             break;
00604         default:
00605             return MB_TYPE_OUT_OF_RANGE;
00606     }
00607 
00608     ErrorCode result = typeData[type].insert_sequence( sequence );
00609     if( MB_SUCCESS != result )
00610     {
00611         data = sequence->data();
00612         delete sequence;
00613         delete data;
00614         return result;
00615     }
00616 
00617     return MB_SUCCESS;
00618 }
00619 
00620 ErrorCode SequenceManager::create_scd_sequence( const HomCoord& coord_min, const HomCoord& coord_max, EntityType type,
00621                                                 EntityID start_id_hint, EntityHandle& first_handle_out,
00622                                                 EntitySequence*& sequence_out, int* is_periodic )
00623 {
00624     return create_scd_sequence( coord_min.i(), coord_min.j(), coord_min.k(), coord_max.i(), coord_max.j(),
00625                                 coord_max.k(), type, start_id_hint, first_handle_out, sequence_out, is_periodic );
00626 }
00627 
00628 ErrorCode SequenceManager::create_sweep_sequence( int imin, int jmin, int kmin, int imax, int jmax, int kmax, int* Cq,
00629                                                   EntityType type, EntityID start_id_hint, EntityHandle& handle,
00630                                                   EntitySequence*& sequence )
00631 {
00632     int this_dim = CN::Dimension( type );
00633 
00634     assert( ( this_dim < 3 || kmax > kmin ) && ( this_dim < 2 || jmax > jmin ) && ( this_dim < 1 || imax > imin ) );
00635 
00636     EntityID num_ent;
00637     if( MBVERTEX == type )
00638         num_ent = ( EntityID )( imax - imin + 1 ) * ( EntityID )( jmax - jmin + 1 ) * ( EntityID )( kmax - kmin + 1 );
00639     else
00640     {
00641         num_ent = ( imax - imin ) * ( this_dim >= 2 ? ( jmax - jmin ) : 1 ) * ( this_dim >= 3 ? ( kmax - kmin ) : 1 );
00642     }
00643 
00644     // Get a start handle
00645     SequenceData* data = 0;
00646     EntityID data_size = 0;
00647     handle             = sequence_start_handle( type, num_ent, -1, start_id_hint, data, data_size );
00648 
00649     if( !handle ) return MB_MEMORY_ALLOCATION_FAILED;
00650     assert( !data );
00651 
00652     switch( type )
00653     {
00654         case MBVERTEX:
00655             data     = new ScdVertexData( handle, imin, jmin, kmin, imax, jmax, kmax );
00656             sequence = new VertexSequence( handle, data->size(), data );
00657             break;
00658         case MBEDGE:
00659         case MBQUAD:
00660         case MBHEX:
00661             sequence = new SweptElementSeq( handle, imin, jmin, kmin, imax, jmax, kmax, Cq );
00662             break;
00663         default:
00664             return MB_TYPE_OUT_OF_RANGE;
00665     }
00666 
00667     ErrorCode result = typeData[type].insert_sequence( sequence );
00668     if( MB_SUCCESS != result )
00669     {
00670         data = sequence->data();
00671         delete sequence;
00672         delete data;
00673         return result;
00674     }
00675 
00676     return MB_SUCCESS;
00677 }
00678 
00679 ErrorCode SequenceManager::create_sweep_sequence( const HomCoord& coord_min, const HomCoord& coord_max, int* Cq,
00680                                                   EntityType type, EntityID start_id_hint,
00681                                                   EntityHandle& first_handle_out, EntitySequence*& sequence_out )
00682 {
00683     return create_sweep_sequence( coord_min.i(), coord_min.j(), coord_min.k(), coord_max.i(), coord_max.j(),
00684                                   coord_max.k(), Cq, type, start_id_hint, first_handle_out, sequence_out );
00685 }
00686 
00687 ErrorCode SequenceManager::add_vsequence( EntitySequence* vert_seq, EntitySequence* elem_seq, const HomCoord& p1,
00688                                           const HomCoord& q1, const HomCoord& p2, const HomCoord& q2,
00689                                           const HomCoord& p3, const HomCoord& q3, bool bb_input, const HomCoord* bb_min,
00690                                           const HomCoord* bb_max )
00691 {
00692     // Check first that they're structured vtx/elem sequences
00693     ScdVertexData* scd_vd = dynamic_cast< ScdVertexData* >( vert_seq->data() );
00694     if( !scd_vd ) return MB_FAILURE;
00695 
00696     ScdElementData* scd_ed = dynamic_cast< ScdElementData* >( elem_seq->data() );
00697     if( !scd_ed ) return MB_FAILURE;
00698 
00699     if( bb_min && bb_max )
00700         return scd_ed->add_vsequence( scd_vd, p1, q1, p2, q2, p3, q3, bb_input, *bb_min, *bb_max );
00701     else
00702         return scd_ed->add_vsequence( scd_vd, p1, q1, p2, q2, p3, q3, bb_input, HomCoord::unitv[0],
00703                                       HomCoord::unitv[0] );
00704 }
00705 
00706 ErrorCode SequenceManager::replace_subsequence( EntitySequence* new_seq )
00707 {
00708     const EntityType type = TYPE_FROM_HANDLE( new_seq->start_handle() );
00709     return typeData[type].replace_subsequence( new_seq, &tagSizes[0], tagSizes.size() );
00710 }
00711 
00712 void SequenceManager::get_memory_use( unsigned long long& total_entity_storage,
00713                                       unsigned long long& total_storage ) const
00714 
00715 {
00716     total_entity_storage = 0;
00717     total_storage        = 0;
00718     unsigned long long temp_entity, temp_total;
00719     for( EntityType i = MBVERTEX; i < MBMAXTYPE; ++i )
00720     {
00721         temp_entity = temp_total = 0;
00722         get_memory_use( i, temp_entity, temp_total );
00723         total_entity_storage += temp_entity;
00724         total_storage += temp_total;
00725     }
00726 }
00727 
00728 void SequenceManager::get_memory_use( EntityType type, unsigned long long& total_entity_storage,
00729                                       unsigned long long& total_storage ) const
00730 {
00731     typeData[type].get_memory_use( total_entity_storage, total_storage );
00732 }
00733 
00734 void SequenceManager::get_memory_use( const Range& entities, unsigned long long& total_entity_storage,
00735                                       unsigned long long& total_amortized_storage ) const
00736 {
00737     total_entity_storage    = 0;
00738     total_amortized_storage = 0;
00739     unsigned long long temp_entity, temp_total;
00740     Range::const_pair_iterator i;
00741     for( i = entities.const_pair_begin(); i != entities.const_pair_end(); ++i )
00742     {
00743         const EntityType t1 = TYPE_FROM_HANDLE( i->first );
00744         const EntityType t2 = TYPE_FROM_HANDLE( i->second );
00745         if( t1 == t2 )
00746         {
00747             temp_entity = temp_total = 0;
00748             typeData[t1].get_memory_use( i->first, i->second, temp_entity, temp_total );
00749             total_entity_storage += temp_entity;
00750             total_amortized_storage += temp_total;
00751         }
00752         else
00753         {
00754             int junk;
00755 
00756             temp_entity = temp_total = 0;
00757             typeData[t1].get_memory_use( i->first, CREATE_HANDLE( t1, MB_END_ID, junk ), temp_entity, temp_total );
00758             total_entity_storage += temp_entity;
00759             total_amortized_storage += temp_total;
00760 
00761             temp_entity = temp_total = 0;
00762             typeData[t2].get_memory_use( CREATE_HANDLE( t2, MB_START_ID, junk ), i->second, temp_entity, temp_total );
00763             total_entity_storage += temp_entity;
00764             total_amortized_storage += temp_total;
00765         }
00766     }
00767 }
00768 
00769 ErrorCode SequenceManager::reserve_tag_array( Error* /* error_handler */, int size, int& index )
00770 {
00771     if( size < 1 && size != MB_VARIABLE_LENGTH ) { MB_SET_ERR( MB_INVALID_SIZE, "Invalid tag size: " << size ); }
00772 
00773     std::vector< int >::iterator i = std::find( tagSizes.begin(), tagSizes.end(), UNUSED_SIZE );
00774     if( i == tagSizes.end() )
00775     {
00776         index = tagSizes.size();
00777         tagSizes.push_back( size );
00778     }
00779     else
00780     {
00781         index = i - tagSizes.begin();
00782         *i    = size;
00783     }
00784 
00785     return MB_SUCCESS;
00786 }
00787 
00788 ErrorCode SequenceManager::release_tag_array( Error* /* error_handler */, int index, bool release_id )
00789 {
00790     if( (unsigned)index >= tagSizes.size() || UNUSED_SIZE == tagSizes[index] )
00791     {
00792         // MB_TAG_NOT_FOUND could be a non-error condition, do not call MB_SET_ERR on it
00793 #if 0
00794     fprintf(stderr, "[Warning]: Invalid dense tag index: %d\n", index);
00795 #endif
00796         return MB_TAG_NOT_FOUND;
00797     }
00798 
00799     for( EntityType t = MBVERTEX; t <= MBENTITYSET; ++t )
00800     {
00801         TypeSequenceManager& seqs = entity_map( t );
00802         for( TypeSequenceManager::iterator i = seqs.begin(); i != seqs.end(); ++i )
00803             ( *i )->data()->release_tag_data( index, tagSizes[index] );
00804     }
00805 
00806     if( release_id ) tagSizes[index] = UNUSED_SIZE;
00807 
00808     return MB_SUCCESS;
00809 }
00810 
00811 // These are meant to be called from the debugger (not declared in any header)
00812 // so leave them out of release builds (-DNDEBUG).
00813 #ifndef NDEBUG
00814 
00815 std::ostream& operator<<( std::ostream& s, const TypeSequenceManager& seq_man )
00816 {
00817     const SequenceData* prev_data = 0;
00818     for( TypeSequenceManager::const_iterator i = seq_man.begin(); i != seq_man.end(); ++i )
00819     {
00820         const EntitySequence* seq = *i;
00821         if( seq->data() != prev_data )
00822         {
00823             prev_data = seq->data();
00824             s << "SequenceData [" << ID_FROM_HANDLE( seq->data()->start_handle() ) << ","
00825               << ID_FROM_HANDLE( seq->data()->end_handle() ) << "]" << std::endl;
00826         }
00827         s << "  Sequence [" << ID_FROM_HANDLE( seq->start_handle() ) << "," << ID_FROM_HANDLE( seq->end_handle() )
00828           << "]" << std::endl;
00829     }
00830 
00831     return s;
00832 }
00833 
00834 std::ostream& operator<<( std::ostream& s, const SequenceManager& seq_man )
00835 {
00836     for( EntityType t = MBVERTEX; t < MBMAXTYPE; ++t )
00837     {
00838         if( !seq_man.entity_map( t ).empty() )
00839             s << std::endl
00840               << "****************** " << CN::EntityTypeName( t ) << " ******************" << std::endl
00841               << seq_man.entity_map( t ) << std::endl;
00842     }
00843 
00844     return s;
00845 }
00846 
00847 void print_sequences( const SequenceManager& seqman )
00848 {
00849     std::cout << seqman << std::endl;
00850 }
00851 
00852 void print_sequences( const TypeSequenceManager& seqman )
00853 {
00854     std::cout << seqman << std::endl;
00855 }
00856 
00857 #endif
00858 
00859 }  // namespace moab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines