MOAB: Mesh Oriented datABase
(version 5.4.1)
|
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