Loading [MathJax]/extensions/tex2jax.js
Mesh Oriented datABase  (version 5.5.1)
An array-based unstructured mesh library
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
SequenceManager.cpp
Go to the documentation of this file.
1 #include "SequenceManager.hpp" 2 #include "VertexSequence.hpp" 3 #include "UnstructuredElemSeq.hpp" 4 #include "ScdVertexData.hpp" 5 #include "MeshSetSequence.hpp" 6 #include "SweptElementSeq.hpp" 7 #include "StructuredElementSeq.hpp" 8 #include "moab/HomXform.hpp" 9 #include "PolyElementSeq.hpp" 10 #include "SysUtil.hpp" 11 #include "moab/Error.hpp" 12  13 #include <cassert> 14 #include <new> 15 #include <algorithm> 16  17 #ifndef NDEBUG 18 #include <iostream> 19 #endif 20  21 namespace moab 22 { 23  24 const EntityID SequenceManager::DEFAULT_VERTEX_SEQUENCE_SIZE = 16 * 1024; 25 const EntityID SequenceManager::DEFAULT_ELEMENT_SEQUENCE_SIZE = DEFAULT_VERTEX_SEQUENCE_SIZE; 26 const EntityID SequenceManager::DEFAULT_POLY_SEQUENCE_SIZE = 16 * 1024; 27 const EntityID SequenceManager::DEFAULT_MESHSET_SEQUENCE_SIZE = DEFAULT_VERTEX_SEQUENCE_SIZE; 28  29 const int UNUSED_SIZE = 0; 30  31 EntityID SequenceManager::default_poly_sequence_size( int conn_len ) 32 { 33  return std::max( DEFAULT_POLY_SEQUENCE_SIZE / conn_len, (EntityID)1 ); 34 } 35  36 SequenceManager::~SequenceManager() 37 { 38  // Release variable-length tag data 39  for( unsigned i = 0; i < tagSizes.size(); ++i ) 40  if( tagSizes[i] == MB_VARIABLE_LENGTH ) release_tag_array( 0, i, false ); 41 } 42  43 void SequenceManager::clear() 44 { 45  // reset sequence multiplier 46  sequence_multiplier = 1.0; 47  48  // Destroy all TypeSequenceManager instances 49  for( EntityType t = MBVERTEX; t < MBMAXTYPE; ++t ) 50  typeData[t].~TypeSequenceManager(); 51  52  // Now re-create TypeSequenceManager instances 53  for( EntityType t = MBVERTEX; t < MBMAXTYPE; ++t ) 54  new( typeData + t ) TypeSequenceManager(); 55 } 56  57 void SequenceManager::get_entities( Range& entities_out ) const 58 { 59  for( EntityType t = MBENTITYSET; t >= MBVERTEX; --t ) 60  typeData[t].get_entities( entities_out ); 61 } 62  63 void SequenceManager::get_entities( std::vector< EntityHandle >& entities_out ) const 64 { 65  for( EntityType t = MBVERTEX; t != MBMAXTYPE; ++t ) 66  typeData[t].get_entities( entities_out ); 67 } 68  69 EntityID SequenceManager::get_number_entities() const 70 { 71  EntityID sum = 0; 72  for( EntityType t = MBVERTEX; t != MBMAXTYPE; ++t ) 73  sum += typeData[t].get_number_entities(); 74  75  return sum; 76 } 77  78 ErrorCode SequenceManager::check_valid_entities( Error* /* error */, const Range& entities ) const 79 { 80  ErrorCode rval; 81  Range::const_pair_iterator i; 82  for( i = entities.const_pair_begin(); i != entities.const_pair_end(); ++i ) 83  { 84  const EntityType type1 = TYPE_FROM_HANDLE( i->first ); 85  const EntityType type2 = TYPE_FROM_HANDLE( i->second ); 86  if( type1 == type2 ) 87  { 88  rval = typeData[type1].check_valid_handles( NULL, i->first, i->second ); 89  if( MB_SUCCESS != rval ) return rval; 90  } 91  else 92  { 93  int junk; 94  EntityHandle split = CREATE_HANDLE( type2, 0, junk ); 95  rval = typeData[type1].check_valid_handles( NULL, i->first, split - 1 ); 96  if( MB_SUCCESS != rval ) return rval; 97  rval = typeData[type2].check_valid_handles( NULL, split, i->second ); 98  if( MB_SUCCESS != rval ) return rval; 99  } 100  } 101  102  return MB_SUCCESS; 103 } 104  105 ErrorCode SequenceManager::check_valid_entities( Error* /* error_handler */, 106  const EntityHandle* entities, 107  size_t num_entities, 108  bool root_set_okay ) const 109 { 110  ErrorCode rval; 111  const EntitySequence* ptr = 0; 112  113  const EntityHandle* const end = entities + num_entities; 114  for( ; entities < end; ++entities ) 115  { 116  rval = find( *entities, ptr ); 117  if( MB_SUCCESS != rval && !( root_set_okay && !*entities ) ) 118  { 119  if( MB_ENTITY_NOT_FOUND == rval ) 120  { 121  // MB_ENTITY_NOT_FOUND could be a non-error condition, do not call MB_SET_ERR on it 122 #if 0 123  fprintf(stderr, "[Warning]: Invalid entity handle: 0x%lx\n", (unsigned long)*entities); 124 #endif 125  } 126  return rval; 127  } 128  } 129  130  return MB_SUCCESS; 131 } 132  133 ErrorCode SequenceManager::delete_entity( Error* /* error */, EntityHandle entity ) 134 { 135  return typeData[TYPE_FROM_HANDLE( entity )].erase( NULL, entity ); 136 } 137  138 ErrorCode SequenceManager::delete_entities( Error* /* error */, const Range& entities ) 139 { 140  ErrorCode rval = check_valid_entities( NULL, entities ); 141  if( MB_SUCCESS != rval ) return rval; 142  143  ErrorCode result = MB_SUCCESS; 144  Range::const_pair_iterator i; 145  for( i = entities.const_pair_begin(); i != entities.const_pair_end(); ++i ) 146  { 147  const EntityType type1 = TYPE_FROM_HANDLE( i->first ); 148  const EntityType type2 = TYPE_FROM_HANDLE( i->second ); 149  if( type1 == type2 ) 150  { 151  rval = typeData[type1].erase( NULL, i->first, i->second ); 152  if( MB_SUCCESS != rval ) return result = rval; 153  } 154  else 155  { 156  int junk; 157  EntityHandle split = CREATE_HANDLE( type2, 0, junk ); 158  rval = typeData[type1].erase( NULL, i->first, split - 1 ); 159  if( MB_SUCCESS != rval ) return result = rval; 160  rval = typeData[type2].erase( NULL, split, i->second ); 161  if( MB_SUCCESS != rval ) return result = rval; 162  } 163  } 164  165  return result; 166 } 167  168 ErrorCode SequenceManager::create_vertex( const double coords[3], EntityHandle& handle ) 169 { 170  const EntityHandle start = CREATE_HANDLE( MBVERTEX, MB_START_ID ); 171  const EntityHandle end = CREATE_HANDLE( MBVERTEX, MB_END_ID ); 172  bool append; 173  TypeSequenceManager::iterator seq = typeData[MBVERTEX].find_free_handle( start, end, append ); 174  VertexSequence* vseq; 175  176  if( seq == typeData[MBVERTEX].end() ) 177  { 178  SequenceData* seq_data = 0; 179  EntityID seq_data_size = 0; 180  handle = 181  typeData[MBVERTEX].find_free_sequence( DEFAULT_VERTEX_SEQUENCE_SIZE, start, end, seq_data, seq_data_size ); 182  if( !handle ) return MB_FAILURE; 183  184  if( seq_data ) 185  vseq = new VertexSequence( handle, 1, seq_data ); 186  else 187  vseq = new VertexSequence( handle, 1, DEFAULT_VERTEX_SEQUENCE_SIZE ); 188  189  ErrorCode rval = typeData[MBVERTEX].insert_sequence( vseq ); 190  if( MB_SUCCESS != rval ) 191  { 192  SequenceData* vdata = vseq->data(); 193  delete vseq; 194  if( !seq_data ) delete vdata; 195  196  return rval; 197  } 198  } 199  else 200  { 201  vseq = reinterpret_cast< VertexSequence* >( *seq ); 202  if( append ) 203  { 204  vseq->push_back( 1 ); 205  handle = vseq->end_handle(); 206  typeData[MBVERTEX].notify_appended( seq ); 207  } 208  else 209  { 210  vseq->push_front( 1 ); 211  handle = vseq->start_handle(); 212  typeData[MBVERTEX].notify_prepended( seq ); 213  } 214  } 215  216  return vseq->set_coordinates( handle, coords ); 217 } 218  219 ErrorCode SequenceManager::create_element( EntityType type, 220  const EntityHandle* conn, 221  unsigned conn_len, 222  EntityHandle& handle ) 223 { 224  if( type <= MBVERTEX || type >= MBENTITYSET ) return MB_TYPE_OUT_OF_RANGE; 225  226  const EntityHandle start = CREATE_HANDLE( type, MB_START_ID ); 227  const EntityHandle end = CREATE_HANDLE( type, MB_END_ID ); 228  bool append; 229  TypeSequenceManager::iterator seq = typeData[type].find_free_handle( start, end, append, conn_len ); 230  UnstructuredElemSeq* eseq; 231  232  if( seq == typeData[type].end() ) 233  { 234  SequenceData* seq_data = 0; 235  unsigned size = DEFAULT_ELEMENT_SEQUENCE_SIZE; 236  if( type == MBPOLYGON || type == MBPOLYHEDRON ) 237  { 238  size = default_poly_sequence_size( conn_len ); 239  } 240  EntityID seq_data_size = 0; 241  handle = typeData[type].find_free_sequence( size, start, end, seq_data, seq_data_size, conn_len ); 242  if( !handle ) return MB_FAILURE; 243  244  if( MBPOLYGON == type || MBPOLYHEDRON == type ) 245  { 246  if( seq_data ) 247  eseq = new PolyElementSeq( handle, 1, conn_len, seq_data ); 248  else 249  eseq = new PolyElementSeq( handle, 1, conn_len, size ); 250  } 251  else 252  { 253  if( seq_data ) 254  eseq = new UnstructuredElemSeq( handle, 1, conn_len, seq_data ); 255  else 256  eseq = new UnstructuredElemSeq( handle, 1, conn_len, size ); 257  } 258  259  ErrorCode rval = typeData[type].insert_sequence( eseq ); 260  if( MB_SUCCESS != rval ) 261  { 262  SequenceData* vdata = eseq->data(); 263  delete eseq; 264  if( !seq_data ) delete vdata; 265  266  return rval; 267  } 268  } 269  else 270  { 271  eseq = reinterpret_cast< UnstructuredElemSeq* >( *seq ); 272  if( append ) 273  { 274  eseq->push_back( 1 ); 275  handle = eseq->end_handle(); 276  typeData[type].notify_appended( seq ); 277  } 278  else 279  { 280  eseq->push_front( 1 ); 281  handle = eseq->start_handle(); 282  typeData[type].notify_prepended( seq ); 283  } 284  } 285  286  return eseq->set_connectivity( handle, conn, conn_len ); 287 } 288  289 ErrorCode SequenceManager::create_mesh_set( unsigned flags, EntityHandle& handle ) 290 { 291  const EntityHandle start = CREATE_HANDLE( MBENTITYSET, MB_START_ID ); 292  const EntityHandle end = CREATE_HANDLE( MBENTITYSET, MB_END_ID ); 293  bool append; 294  TypeSequenceManager::iterator seq = typeData[MBENTITYSET].find_free_handle( start, end, append ); 295  MeshSetSequence* msseq; 296  297  if( seq == typeData[MBENTITYSET].end() ) 298  { 299  SequenceData* seq_data = 0; 300  EntityID seq_data_size = 0; 301  handle = typeData[MBENTITYSET].find_free_sequence( DEFAULT_MESHSET_SEQUENCE_SIZE, start, end, seq_data, 302  seq_data_size ); 303  if( !handle ) return MB_FAILURE; 304  305  if( seq_data ) 306  msseq = new MeshSetSequence( handle, 1, flags, seq_data ); 307  else 308  msseq = new MeshSetSequence( handle, 1, flags, DEFAULT_MESHSET_SEQUENCE_SIZE ); 309  310  ErrorCode rval = typeData[MBENTITYSET].insert_sequence( msseq ); 311  if( MB_SUCCESS != rval ) 312  { 313  SequenceData* vdata = msseq->data(); 314  delete msseq; 315  if( !seq_data ) delete vdata; 316  317  return rval; 318  } 319  } 320  else 321  { 322  msseq = reinterpret_cast< MeshSetSequence* >( *seq ); 323  if( append ) 324  { 325  msseq->push_back( 1, &flags ); 326  handle = msseq->end_handle(); 327  typeData[MBENTITYSET].notify_appended( seq ); 328  } 329  else 330  { 331  msseq->push_front( 1, &flags ); 332  handle = msseq->start_handle(); 333  typeData[MBENTITYSET].notify_prepended( seq ); 334  } 335  } 336  337  return MB_SUCCESS; 338 } 339  340 ErrorCode SequenceManager::allocate_mesh_set( EntityHandle handle, unsigned flags ) 341 { 342  SequenceData* data = 0; 343  TypeSequenceManager::iterator seqptr; 344  EntityHandle block_start = 1, block_end = 0; 345  ErrorCode rval = typeData[MBENTITYSET].is_free_handle( handle, seqptr, data, block_start, block_end ); 346  if( MB_SUCCESS != rval ) return rval; 347  348  MeshSetSequence* seq; 349  if( seqptr != typeData[MBENTITYSET].end() ) 350  { 351  seq = static_cast< MeshSetSequence* >( *seqptr ); 352  if( seq->start_handle() - 1 == handle ) 353  { 354  rval = seq->push_front( 1, &flags ); 355  if( MB_SUCCESS == rval ) 356  { 357  rval = typeData[MBENTITYSET].notify_prepended( seqptr ); 358  if( MB_SUCCESS != rval ) seq->pop_front( 1 ); 359  } 360  return rval; 361  } 362  else if( seq->end_handle() + 1 == handle ) 363  { 364  rval = seq->push_back( 1, &flags ); 365  if( MB_SUCCESS == rval ) 366  { 367  rval = typeData[MBENTITYSET].notify_appended( seqptr ); 368  if( MB_SUCCESS != rval ) seq->pop_back( 1 ); 369  } 370  return rval; 371  } 372  else 373  return MB_FAILURE; // Should be unreachable 374  } 375  else 376  { 377  if( data ) 378  { 379  seq = new MeshSetSequence( handle, 1, flags, data ); 380  } 381  else 382  { 383  assert( handle >= block_start && handle <= block_end ); 384  trim_sequence_block( handle, block_end, DEFAULT_MESHSET_SEQUENCE_SIZE ); 385  seq = new MeshSetSequence( handle, 1, flags, block_end - handle + 1 ); 386  } 387  388  rval = typeData[MBENTITYSET].insert_sequence( seq ); 389  if( MB_SUCCESS != rval ) 390  { 391  SequenceData* vdata = seq->data(); 392  delete seq; 393  if( !data ) delete vdata; 394  return rval; 395  } 396  397  return MB_SUCCESS; 398  } 399 } 400  401 void SequenceManager::trim_sequence_block( EntityHandle start_handle, EntityHandle& end_handle, unsigned max_size ) 402 { 403  assert( end_handle >= start_handle ); 404  assert( (int)max_size > 0 ); // Cast to int also prohibits some ridiculously large values 405  406  // If input range is larger than preferred size, trim it 407  if( end_handle - start_handle >= max_size ) end_handle = start_handle + max_size - 1; 408 } 409  410 EntityHandle SequenceManager::sequence_start_handle( EntityType type, 411  EntityID count, 412  int size, 413  EntityID start, 414  SequenceData*& data, 415  EntityID& data_size ) 416 { 417  TypeSequenceManager& tsm = typeData[type]; 418  data = 0; 419  EntityHandle handle = CREATE_HANDLE( type, start ); 420  if( start < MB_START_ID || !tsm.is_free_sequence( handle, count, data, size ) ) 421  { 422  EntityHandle pstart = CREATE_HANDLE( type, MB_START_ID ); 423  EntityHandle pend = CREATE_HANDLE( type, MB_END_ID ); 424  handle = tsm.find_free_sequence( count, pstart, pend, data, data_size, size ); 425  } 426  427  return handle; 428 } 429  430 EntityID SequenceManager::new_sequence_size( EntityHandle start, EntityID requested_size, int sequence_size ) const 431 { 432  433  requested_size = (EntityID)( this->sequence_multiplier * requested_size ); 434  435  if( sequence_size < (int)requested_size ) return requested_size; 436  437  EntityHandle last = typeData[TYPE_FROM_HANDLE( start )].last_free_handle( start ); 438  if( !last ) 439  { 440  assert( false ); 441  return 0; 442  } 443  444  EntityID available_size = last - start + 1; 445  if( sequence_size < available_size ) 446  return sequence_size; 447  else 448  return available_size; 449 } 450  451 ErrorCode SequenceManager::create_entity_sequence( EntityType type, 452  EntityID count, 453  int size, 454  EntityID start, 455  EntityHandle& handle, 456  EntitySequence*& sequence, 457  int sequence_size ) 458 { 459  SequenceData* data = NULL; 460  EntityID data_size = 0; 461  handle = sequence_start_handle( type, count, size, start, data, data_size ); 462  463  if( !handle ) return MB_MEMORY_ALLOCATION_FAILED; 464  465  switch( type ) 466  { 467  case MBENTITYSET: 468  case MBMAXTYPE: 469  return MB_TYPE_OUT_OF_RANGE; 470  471  case MBVERTEX: 472  if( size != 0 ) return MB_INDEX_OUT_OF_RANGE; 473  474  if( data ) 475  sequence = new VertexSequence( handle, count, data ); 476  else 477  { 478  if( !data_size ) data_size = new_sequence_size( handle, count, sequence_size ); 479  sequence = new VertexSequence( handle, count, data_size ); 480  } 481  break; 482  483  case MBPOLYGON: 484  case MBPOLYHEDRON: 485  if( size == 0 ) return MB_INDEX_OUT_OF_RANGE; 486  487  if( data ) 488  sequence = new PolyElementSeq( handle, count, size, data ); 489  else 490  { 491  if( !data_size ) 492  data_size = new_sequence_size( 493  handle, count, ( -1 == sequence_size ? default_poly_sequence_size( size ) : sequence_size ) ); 494  sequence = new PolyElementSeq( handle, count, size, data_size ); 495  } 496  break; 497  498  default: 499  if( size == 0 ) return MB_INDEX_OUT_OF_RANGE; 500  501  if( data ) 502  sequence = new UnstructuredElemSeq( handle, count, size, data ); 503  else 504  { 505  if( !data_size ) data_size = new_sequence_size( handle, count, sequence_size ); 506  sequence = new UnstructuredElemSeq( handle, count, size, data_size ); 507  } 508  // tjt calling new_sequence_size 'cuz don't have a sequence data; 509  // start 41467, count 246 510  break; 511  } 512  513  ErrorCode result = typeData[type].insert_sequence( sequence ); 514  if( MB_SUCCESS != result ) 515  { 516  // Change to NULL if had an existing data or if no existing data, 517  // change to the new data created 518  data = data ? 0 : sequence->data(); 519  delete sequence; 520  delete data; 521  return result; 522  } 523  524  return MB_SUCCESS; 525 } 526  527 ErrorCode SequenceManager::create_meshset_sequence( EntityID count, 528  EntityID start, 529  const unsigned* flags, 530  EntityHandle& handle, 531  EntitySequence*& sequence ) 532 { 533  SequenceData* data = 0; 534  EntityID data_size = 0; 535  handle = sequence_start_handle( MBENTITYSET, count, 0, start, data, data_size ); 536  537  if( !handle ) return MB_MEMORY_ALLOCATION_FAILED; 538  539  if( data ) 540  sequence = new MeshSetSequence( handle, count, flags, data ); 541  else 542  sequence = new MeshSetSequence( handle, count, flags, count ); 543  544  ErrorCode result = typeData[MBENTITYSET].insert_sequence( sequence ); 545  if( MB_SUCCESS != result ) 546  { 547  // Change to NULL if had an existing data or if no existing data, 548  // change to the new data created 549  data = data ? 0 : sequence->data(); 550  delete sequence; 551  delete data; 552  return result; 553  } 554  555  return MB_SUCCESS; 556 } 557  558 ErrorCode SequenceManager::create_meshset_sequence( EntityID count, 559  EntityID start, 560  unsigned flags, 561  EntityHandle& handle, 562  EntitySequence*& sequence ) 563 { 564  SequenceData* data = 0; 565  EntityID data_size = 0; 566  handle = sequence_start_handle( MBENTITYSET, count, 0, start, data, data_size ); 567  if( !handle ) return MB_MEMORY_ALLOCATION_FAILED; 568  569  if( data ) 570  sequence = new MeshSetSequence( handle, count, flags, data ); 571  else 572  sequence = new MeshSetSequence( handle, count, flags, count ); 573  574  ErrorCode result = typeData[MBENTITYSET].insert_sequence( sequence ); 575  if( MB_SUCCESS != result ) 576  { 577  // Change to NULL if had an existing data or if no existing data, 578  // change to the new data created 579  data = data ? 0 : sequence->data(); 580  delete sequence; 581  delete data; 582  return result; 583  } 584  585  return MB_SUCCESS; 586 } 587  588 ErrorCode SequenceManager::create_scd_sequence( int imin, 589  int jmin, 590  int kmin, 591  int imax, 592  int jmax, 593  int kmax, 594  EntityType type, 595  EntityID start_id_hint, 596  EntityHandle& handle, 597  EntitySequence*& sequence, 598  int* is_periodic ) 599 { 600  int this_dim = CN::Dimension( type ); 601  602  // Use > instead of != in the following assert to also catch cases where imin > imax, etc. 603  assert( ( this_dim < 3 || kmax > kmin ) && ( this_dim < 2 || jmax > jmin ) && ( this_dim < 1 || imax > imin ) ); 604  605  // Compute # entities; not as easy as it would appear... 606  EntityID num_ent; 607  if( MBVERTEX == type ) 608  num_ent = (EntityID)( imax - imin + 1 ) * (EntityID)( jmax - jmin + 1 ) * (EntityID)( kmax - kmin + 1 ); 609  else 610  { 611  num_ent = ( imax - imin + ( is_periodic && is_periodic[0] ? 1 : 0 ) ) * 612  ( this_dim >= 2 ? ( jmax - jmin + ( is_periodic && is_periodic[1] ? 1 : 0 ) ) : 1 ) * 613  ( this_dim >= 3 ? ( kmax - kmin ) : 1 ); 614  } 615  616  if( MBVERTEX == type && ( is_periodic && ( is_periodic[0] || is_periodic[1] ) ) ) return MB_FAILURE; 617  618  // Get a start handle 619  SequenceData* data = 0; 620  EntityID data_size = 0; 621  handle = sequence_start_handle( type, num_ent, -1, start_id_hint, data, data_size ); 622  623  if( !handle ) return MB_MEMORY_ALLOCATION_FAILED; 624  assert( !data ); 625  626  switch( type ) 627  { 628  case MBVERTEX: 629  data = new ScdVertexData( handle, imin, jmin, kmin, imax, jmax, kmax ); 630  sequence = new VertexSequence( handle, data->size(), data ); 631  break; 632  case MBEDGE: 633  case MBQUAD: 634  case MBHEX: 635  sequence = new StructuredElementSeq( handle, imin, jmin, kmin, imax, jmax, kmax, is_periodic ); 636  break; 637  default: 638  return MB_TYPE_OUT_OF_RANGE; 639  } 640  641  ErrorCode result = typeData[type].insert_sequence( sequence ); 642  if( MB_SUCCESS != result ) 643  { 644  data = sequence->data(); 645  delete sequence; 646  delete data; 647  return result; 648  } 649  650  return MB_SUCCESS; 651 } 652  653 ErrorCode SequenceManager::create_scd_sequence( const HomCoord& coord_min, 654  const HomCoord& coord_max, 655  EntityType type, 656  EntityID start_id_hint, 657  EntityHandle& first_handle_out, 658  EntitySequence*& sequence_out, 659  int* is_periodic ) 660 { 661  return create_scd_sequence( coord_min.i(), coord_min.j(), coord_min.k(), coord_max.i(), coord_max.j(), 662  coord_max.k(), type, start_id_hint, first_handle_out, sequence_out, is_periodic ); 663 } 664  665 ErrorCode SequenceManager::create_sweep_sequence( int imin, 666  int jmin, 667  int kmin, 668  int imax, 669  int jmax, 670  int kmax, 671  int* Cq, 672  EntityType type, 673  EntityID start_id_hint, 674  EntityHandle& handle, 675  EntitySequence*& sequence ) 676 { 677  int this_dim = CN::Dimension( type ); 678  679  assert( ( this_dim < 3 || kmax > kmin ) && ( this_dim < 2 || jmax > jmin ) && ( this_dim < 1 || imax > imin ) ); 680  681  EntityID num_ent; 682  if( MBVERTEX == type ) 683  num_ent = (EntityID)( imax - imin + 1 ) * (EntityID)( jmax - jmin + 1 ) * (EntityID)( kmax - kmin + 1 ); 684  else 685  { 686  num_ent = ( imax - imin ) * ( this_dim >= 2 ? ( jmax - jmin ) : 1 ) * ( this_dim >= 3 ? ( kmax - kmin ) : 1 ); 687  } 688  689  // Get a start handle 690  SequenceData* data = 0; 691  EntityID data_size = 0; 692  handle = sequence_start_handle( type, num_ent, -1, start_id_hint, data, data_size ); 693  694  if( !handle ) return MB_MEMORY_ALLOCATION_FAILED; 695  assert( !data ); 696  697  switch( type ) 698  { 699  case MBVERTEX: 700  data = new ScdVertexData( handle, imin, jmin, kmin, imax, jmax, kmax ); 701  sequence = new VertexSequence( handle, data->size(), data ); 702  break; 703  case MBEDGE: 704  case MBQUAD: 705  case MBHEX: 706  sequence = new SweptElementSeq( handle, imin, jmin, kmin, imax, jmax, kmax, Cq ); 707  break; 708  default: 709  return MB_TYPE_OUT_OF_RANGE; 710  } 711  712  ErrorCode result = typeData[type].insert_sequence( sequence ); 713  if( MB_SUCCESS != result ) 714  { 715  data = sequence->data(); 716  delete sequence; 717  delete data; 718  return result; 719  } 720  721  return MB_SUCCESS; 722 } 723  724 ErrorCode SequenceManager::create_sweep_sequence( const HomCoord& coord_min, 725  const HomCoord& coord_max, 726  int* Cq, 727  EntityType type, 728  EntityID start_id_hint, 729  EntityHandle& first_handle_out, 730  EntitySequence*& sequence_out ) 731 { 732  return create_sweep_sequence( coord_min.i(), coord_min.j(), coord_min.k(), coord_max.i(), coord_max.j(), 733  coord_max.k(), Cq, type, start_id_hint, first_handle_out, sequence_out ); 734 } 735  736 ErrorCode SequenceManager::add_vsequence( EntitySequence* vert_seq, 737  EntitySequence* elem_seq, 738  const HomCoord& p1, 739  const HomCoord& q1, 740  const HomCoord& p2, 741  const HomCoord& q2, 742  const HomCoord& p3, 743  const HomCoord& q3, 744  bool bb_input, 745  const HomCoord* bb_min, 746  const HomCoord* bb_max ) 747 { 748  // Check first that they're structured vtx/elem sequences 749  ScdVertexData* scd_vd = dynamic_cast< ScdVertexData* >( vert_seq->data() ); 750  if( !scd_vd ) return MB_FAILURE; 751  752  ScdElementData* scd_ed = dynamic_cast< ScdElementData* >( elem_seq->data() ); 753  if( !scd_ed ) return MB_FAILURE; 754  755  if( bb_min && bb_max ) 756  return scd_ed->add_vsequence( scd_vd, p1, q1, p2, q2, p3, q3, bb_input, *bb_min, *bb_max ); 757  else 758  return scd_ed->add_vsequence( scd_vd, p1, q1, p2, q2, p3, q3, bb_input, HomCoord::unitv[0], 759  HomCoord::unitv[0] ); 760 } 761  762 ErrorCode SequenceManager::replace_subsequence( EntitySequence* new_seq ) 763 { 764  const EntityType type = TYPE_FROM_HANDLE( new_seq->start_handle() ); 765  return typeData[type].replace_subsequence( new_seq, &tagSizes[0], tagSizes.size() ); 766 } 767  768 void SequenceManager::get_memory_use( unsigned long long& total_entity_storage, 769  unsigned long long& total_storage ) const 770  771 { 772  total_entity_storage = 0; 773  total_storage = 0; 774  unsigned long long temp_entity, temp_total; 775  for( EntityType i = MBVERTEX; i < MBMAXTYPE; ++i ) 776  { 777  temp_entity = temp_total = 0; 778  get_memory_use( i, temp_entity, temp_total ); 779  total_entity_storage += temp_entity; 780  total_storage += temp_total; 781  } 782 } 783  784 void SequenceManager::get_memory_use( EntityType type, 785  unsigned long long& total_entity_storage, 786  unsigned long long& total_storage ) const 787 { 788  typeData[type].get_memory_use( total_entity_storage, total_storage ); 789 } 790  791 void SequenceManager::get_memory_use( const Range& entities, 792  unsigned long long& total_entity_storage, 793  unsigned long long& total_amortized_storage ) const 794 { 795  total_entity_storage = 0; 796  total_amortized_storage = 0; 797  unsigned long long temp_entity, temp_total; 798  Range::const_pair_iterator i; 799  for( i = entities.const_pair_begin(); i != entities.const_pair_end(); ++i ) 800  { 801  const EntityType t1 = TYPE_FROM_HANDLE( i->first ); 802  const EntityType t2 = TYPE_FROM_HANDLE( i->second ); 803  if( t1 == t2 ) 804  { 805  temp_entity = temp_total = 0; 806  typeData[t1].get_memory_use( i->first, i->second, temp_entity, temp_total ); 807  total_entity_storage += temp_entity; 808  total_amortized_storage += temp_total; 809  } 810  else 811  { 812  int junk; 813  814  temp_entity = temp_total = 0; 815  typeData[t1].get_memory_use( i->first, CREATE_HANDLE( t1, MB_END_ID, junk ), temp_entity, temp_total ); 816  total_entity_storage += temp_entity; 817  total_amortized_storage += temp_total; 818  819  temp_entity = temp_total = 0; 820  typeData[t2].get_memory_use( CREATE_HANDLE( t2, MB_START_ID, junk ), i->second, temp_entity, temp_total ); 821  total_entity_storage += temp_entity; 822  total_amortized_storage += temp_total; 823  } 824  } 825 } 826  827 ErrorCode SequenceManager::reserve_tag_array( Error* /* error_handler */, int size, int& index ) 828 { 829  if( size < 1 && size != MB_VARIABLE_LENGTH ) 830  { 831  MB_SET_ERR( MB_INVALID_SIZE, "Invalid tag size: " << size ); 832  } 833  834  std::vector< int >::iterator i = std::find( tagSizes.begin(), tagSizes.end(), UNUSED_SIZE ); 835  if( i == tagSizes.end() ) 836  { 837  index = tagSizes.size(); 838  tagSizes.push_back( size ); 839  } 840  else 841  { 842  index = i - tagSizes.begin(); 843  *i = size; 844  } 845  846  return MB_SUCCESS; 847 } 848  849 ErrorCode SequenceManager::release_tag_array( Error* /* error_handler */, int index, bool release_id ) 850 { 851  if( (unsigned)index >= tagSizes.size() || UNUSED_SIZE == tagSizes[index] ) 852  { 853  // MB_TAG_NOT_FOUND could be a non-error condition, do not call MB_SET_ERR on it 854 #if 0 855  fprintf(stderr, "[Warning]: Invalid dense tag index: %d\n", index); 856 #endif 857  return MB_TAG_NOT_FOUND; 858  } 859  860  for( EntityType t = MBVERTEX; t <= MBENTITYSET; ++t ) 861  { 862  TypeSequenceManager& seqs = entity_map( t ); 863  for( TypeSequenceManager::iterator i = seqs.begin(); i != seqs.end(); ++i ) 864  ( *i )->data()->release_tag_data( index, tagSizes[index] ); 865  } 866  867  if( release_id ) tagSizes[index] = UNUSED_SIZE; 868  869  return MB_SUCCESS; 870 } 871  872 // These are meant to be called from the debugger (not declared in any header) 873 // so leave them out of release builds (-DNDEBUG). 874 #ifndef NDEBUG 875  876 std::ostream& operator<<( std::ostream& s, const TypeSequenceManager& seq_man ) 877 { 878  const SequenceData* prev_data = 0; 879  for( TypeSequenceManager::const_iterator i = seq_man.begin(); i != seq_man.end(); ++i ) 880  { 881  const EntitySequence* seq = *i; 882  if( seq->data() != prev_data ) 883  { 884  prev_data = seq->data(); 885  s << "SequenceData [" << ID_FROM_HANDLE( seq->data()->start_handle() ) << "," 886  << ID_FROM_HANDLE( seq->data()->end_handle() ) << "]" << std::endl; 887  } 888  s << " Sequence [" << ID_FROM_HANDLE( seq->start_handle() ) << "," << ID_FROM_HANDLE( seq->end_handle() ) 889  << "]" << std::endl; 890  } 891  892  return s; 893 } 894  895 std::ostream& operator<<( std::ostream& s, const SequenceManager& seq_man ) 896 { 897  for( EntityType t = MBVERTEX; t < MBMAXTYPE; ++t ) 898  { 899  if( !seq_man.entity_map( t ).empty() ) 900  s << std::endl 901  << "****************** " << CN::EntityTypeName( t ) << " ******************" << std::endl 902  << seq_man.entity_map( t ) << std::endl; 903  } 904  905  return s; 906 } 907  908 void print_sequences( const SequenceManager& seqman ) 909 { 910  std::cout << seqman << std::endl; 911 } 912  913 void print_sequences( const TypeSequenceManager& seqman ) 914 { 915  std::cout << seqman << std::endl; 916 } 917  918 #endif 919  920 } // namespace moab