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