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
Tqdcfr.cpp
Go to the documentation of this file.
1 /** 2  * MOAB, a Mesh-Oriented datABase, is a software component for creating, 3  * storing and accessing finite element mesh data. 4  * 5  * Copyright 2004 Sandia Corporation. Under the terms of Contract 6  * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government 7  * retains certain rights in this software. 8  * 9  * This library is free software; you can redistribute it and/or 10  * modify it under the terms of the GNU Lesser General Public 11  * License as published by the Free Software Foundation; either 12  * version 2.1 of the License, or (at your option) any later version. 13  * 14  */ 15  16 #include "Tqdcfr.hpp" 17 #include "moab/Core.hpp" 18 #include "moab/Range.hpp" 19 #include "moab/FileOptions.hpp" 20 #include <iostream> 21 #include <string> 22  23 #ifdef MOAB_HAVE_MPI 24 #include "moab_mpi.h" 25 #endif 26  27 #include "moab/ReadUtilIface.hpp" 28 #include "SequenceManager.hpp" 29 #include "moab/GeomTopoTool.hpp" 30 #include "MBTagConventions.hpp" 31 #include "moab/CN.hpp" 32 #include "Internals.hpp" 33 #include "moab/HigherOrderFactory.hpp" 34 #include "exodus_order.h" 35  36 #include <sstream> 37 #include <cassert> 38 #include <cstring> 39  40 namespace moab 41 { 42  43 static bool debug = false; 44  45 const char Tqdcfr::geom_categories[][CATEGORY_TAG_SIZE] = { "Vertex\0", "Curve\0", "Surface\0", "Volume\0" }; 46  47 // Will be used in a static function, so declared outside class members :( 48 // major/minor cubit version that wrote this file 49 static int major = -1, minor = -1; 50 const EntityType Tqdcfr::group_type_to_mb_type[] = { MBENTITYSET, MBENTITYSET, MBENTITYSET, // group, body, volume 51  MBENTITYSET, MBENTITYSET, MBENTITYSET, // surface, curve, vertex 52  MBHEX, MBTET, MBPYRAMID, MBQUAD, 53  MBTRI, MBEDGE, MBVERTEX }; 54  55 const EntityType Tqdcfr::block_type_to_mb_type[] = { 56  MBVERTEX, // sphere 57  MBEDGE, MBEDGE, MBEDGE, // bars 58  MBEDGE, MBEDGE, MBEDGE, // beams 59  MBEDGE, MBEDGE, MBEDGE, // truss 60  MBEDGE, // spring 61  MBTRI, MBTRI, MBTRI, MBTRI, // tri 62  MBTRI, MBTRI, MBTRI, MBTRI, // trishell 63  MBQUAD, MBQUAD, MBQUAD, MBQUAD, // shell 64  MBQUAD, MBQUAD, MBQUAD, MBQUAD, MBQUAD, // quad 65  MBTET, MBTET, MBTET, MBTET, MBTET, // tet 66  MBPYRAMID, MBPYRAMID, MBPYRAMID, MBPYRAMID, MBPYRAMID, // pyramid 67  MBHEX, MBHEX, MBHEX, MBHEX, MBHEX, // hex 68  MBHEX, // hexshell 69  MBMAXTYPE // last 70 }; 71  72 // Mapping from mesh packet type to moab type 73 const EntityType Tqdcfr::mp_type_to_mb_type[] = { MBHEX, MBHEX, MBHEX, MBHEX, MBHEX, MBHEX, MBHEX, 74  MBHEX, MBTET, MBTET, MBTET, MBTET, MBTET, MBTET, 75  MBTET, MBTET, MBPYRAMID, MBPYRAMID, MBPYRAMID, MBPYRAMID, MBQUAD, 76  MBQUAD, MBQUAD, MBQUAD, MBTRI, MBTRI, MBTRI, MBTRI, 77  MBEDGE, MBEDGE, MBVERTEX }; 78  79 const int Tqdcfr::cub_elem_num_verts[] = { 1, // sphere 80  2, 2, 3, // bars 81  2, 2, 3, // beams 82  2, 2, 3, // truss 83  2, // spring 84  3, 3, 6, 7, // tris 85  3, 3, 6, 7, // trishells 86  4, 4, 8, 9, // shells 87  4, 4, 5, 8, 9, // quads 88  4, 4, 8, 10, 14, // tets 89  5, 5, 8, 13, 18, // pyramids 90  8, 8, 9, 20, 27, 12, // hexes (incl. hexshell at end) 91  0 }; 92  93 const int Tqdcfr::cub_elem_num_verts_len = sizeof( cub_elem_num_verts ) / sizeof( cub_elem_num_verts[0] ); 94  95 // Define node-order map from Cubit to CN. Table is indexed 96 // by EntityType and number of nodes. Entries are NULL if Cubit order 97 // is the same as CN ordering. Non-null entries contain the 98 // index into the MOAB node order for the corresponding vertex 99 // in the Cubit connectivity list. Thus for a 27-node hex: 100 // moab_conn[ cub_hex27_order[i] ] = cubit_conn[ i ]; 101 const int* const* const* const cub_elem_order_map = exodus_elem_order_map; 102  103 const char* const BLOCK_NODESET_OFFSET_TAG_NAME = "BLOCK_NODESET_OFFSET"; 104 const char* const BLOCK_SIDESET_OFFSET_TAG_NAME = "BLOCK_SIDESET_OFFSET"; 105  106 #define RR \ 107  if( MB_SUCCESS != result ) return result 108  109 // acis dimensions for each entity type, to match 110 // enum {BODY, LUMP, SHELL, FACE, LOOP, COEDGE, EDGE, VERTEX, ATTRIB, UNKNOWN} 111  112 #define IO_ASSERT( C ) INT_IO_ERROR( C, __LINE__ ) 113  114 static inline void INT_IO_ERROR( bool condition, unsigned line ) 115 { 116  if( !condition ) 117  { 118  char buffer[] = __FILE__ " "; 119  snprintf( buffer, strlen(buffer), "%s:%u", __FILE__, line ); 120  fflush( stderr ); 121  perror( buffer ); 122  abort(); 123  } 124 } 125  126 void Tqdcfr::FSEEK( unsigned int offset ) 127 { 128  int rval = fseek( cubFile, offset, SEEK_SET ); 129  IO_ASSERT( !rval ); 130 } 131  132 void Tqdcfr::FREADI( unsigned num_ents ) 133 { 134  if( uint_buf.size() < num_ents ) 135  { 136  uint_buf.resize( num_ents ); 137  int_buf = (int*)&uint_buf[0]; 138  } 139  FREADIA( num_ents, &uint_buf[0] ); 140 } 141  142 void Tqdcfr::FREADD( unsigned num_ents ) 143 { 144  dbl_buf.resize( num_ents ); 145  FREADDA( num_ents, &dbl_buf[0] ); 146 } 147  148 void Tqdcfr::FREADC( unsigned num_ents ) 149 { 150  char_buf.resize( num_ents ); 151  FREADCA( num_ents, &char_buf[0] ); 152 } 153  154 // Used for swapping 155 static void swap8_voff( long* data ) 156 { 157  unsigned char tmp, *cdat = (unsigned char*)data; 158  tmp = cdat[0]; 159  cdat[0] = cdat[7], cdat[7] = tmp; 160  tmp = cdat[1]; 161  cdat[1] = cdat[6], cdat[6] = tmp; 162  tmp = cdat[2]; 163  cdat[2] = cdat[5], cdat[5] = tmp; 164  tmp = cdat[3]; 165  cdat[3] = cdat[4], cdat[4] = tmp; 166 } 167  168 static void swap4_uint( unsigned int* data ) 169 { 170  unsigned char tmp, *cdat = (unsigned char*)data; 171  tmp = cdat[0]; 172  cdat[0] = cdat[3], cdat[3] = tmp; 173  tmp = cdat[1]; 174  cdat[1] = cdat[2], cdat[2] = tmp; 175 } 176  177 /* 178 static void swap2_ushort(unsigned short *data) 179 { 180  unsigned char tmp, *cdat = (unsigned char *) data; 181  tmp = cdat[0]; cdat[0] = cdat[1], cdat[1] = tmp; 182 } 183 */ 184  185 void Tqdcfr::FREADIA( unsigned num_ents, unsigned int* array ) 186 { 187  unsigned rval = fread( array, sizeof( unsigned int ), num_ents, cubFile ); 188  IO_ASSERT( rval == num_ents ); 189  if( swapForEndianness ) 190  { 191  unsigned int* pt = array; 192  for( unsigned int i = 0; i < num_ents; i++ ) 193  { 194  swap4_uint( (unsigned int*)pt ); 195  pt++; 196  } 197  } 198 } 199  200 void Tqdcfr::FREADDA( unsigned num_ents, double* array ) 201 { 202  unsigned rval = fread( array, sizeof( double ), num_ents, cubFile ); 203  IO_ASSERT( rval == num_ents ); 204  if( swapForEndianness ) 205  { 206  double* pt = array; 207  for( unsigned int i = 0; i < num_ents; i++ ) 208  { 209  swap8_voff( (long*)pt ); 210  pt++; 211  } 212  } 213 } 214  215 void Tqdcfr::FREADCA( unsigned num_ents, char* array ) 216 { 217  unsigned rval = fread( array, sizeof( char ), num_ents, cubFile ); 218  IO_ASSERT( rval == num_ents ); 219 } 220  221 void Tqdcfr::CONVERT_TO_INTS( unsigned int num_ents ) 222 { 223  for( unsigned int i = 0; i < num_ents; i++ ) 224  int_buf[i] = uint_buf[i]; 225 } 226  227 ReaderIface* Tqdcfr::factory( Interface* iface ) 228 { 229  return new Tqdcfr( iface ); 230 } 231  232 Tqdcfr::Tqdcfr( Interface* impl ) 233  : cubFile( NULL ), globalIdTag( 0 ), cubIdTag( 0 ), geomTag( 0 ), uniqueIdTag( 0 ), blockTag( 0 ), nsTag( 0 ), 234  ssTag( 0 ), attribVectorTag( 0 ), entityNameTag( 0 ), categoryTag( 0 ), hasMidNodesTag( 0 ), 235  swapForEndianness( false ), int_buf( NULL ), mFileSet( 0 ), printedSeqWarning( false ), 236  printedElemWarning( false ), acisDumpFile( NULL ) 237 { 238  assert( NULL != impl ); 239  mdbImpl = impl; 240  impl->query_interface( readUtilIface ); 241  assert( NULL != readUtilIface ); 242  243  currVHandleOffset = -1; 244  for( EntityType this_type = MBVERTEX; this_type < MBMAXTYPE; this_type++ ) 245  currElementIdOffset[this_type] = -1; 246  247  ErrorCode rval; 248  rval = mdbImpl->tag_get_handle( MATERIAL_SET_TAG_NAME, 1, MB_TYPE_INTEGER, blockTag );MB_CHK_SET_ERR_RET( rval, "Failed to tag_get_handle." ); 249  rval = mdbImpl->tag_get_handle( DIRICHLET_SET_TAG_NAME, 1, MB_TYPE_INTEGER, nsTag );MB_CHK_SET_ERR_RET( rval, "Failed to tag_get_handle." ); 250  rval = mdbImpl->tag_get_handle( NEUMANN_SET_TAG_NAME, 1, MB_TYPE_INTEGER, ssTag );MB_CHK_SET_ERR_RET( rval, "Failed to tag_get_handle." ); 251  252  if( 0 == entityNameTag ) 253  { 254  rval = mdbImpl->tag_get_handle( NAME_TAG_NAME, NAME_TAG_SIZE, MB_TYPE_OPAQUE, entityNameTag, 255  MB_TAG_SPARSE | MB_TAG_CREAT );MB_CHK_SET_ERR_RET( rval, "Failed to tag_get_handle." ); 256  } 257  258  cubMOABVertexMap = NULL; 259 } 260  261 Tqdcfr::~Tqdcfr() 262 { 263  mdbImpl->release_interface( readUtilIface ); 264  265  if( NULL != cubMOABVertexMap ) delete cubMOABVertexMap; 266  if( attribVectorTag ) 267  { 268  // get all sets, and release the string vectors 269  Range allSets; // although only geom sets should have these attributes 270  // can't error in a destructor 271  ErrorCode rval = mdbImpl->get_entities_by_type( 0, MBENTITYSET, allSets ); 272  if( rval != MB_SUCCESS ) std::cerr << "WARNING: Could not get_entities_by_type" << std::endl; 273  for( Range::iterator sit = allSets.begin(); sit != allSets.end(); ++sit ) 274  { 275  EntityHandle gset = *sit; 276  std::vector< std::string >* dum_vec; 277  // can't error in a destructor 278  rval = mdbImpl->tag_get_data( attribVectorTag, &gset, 1, &dum_vec ); 279  if( rval != MB_SUCCESS ) std::cerr << "WARNING: Could not tag_get_data" << std::endl; 280  if( NULL != dum_vec ) delete dum_vec; // 281  } 282  mdbImpl->tag_delete( attribVectorTag ); 283  attribVectorTag = NULL; 284  } 285 } 286  287 ErrorCode Tqdcfr::read_tag_values( const char* /* file_name */, 288  const char* /* tag_name */, 289  const FileOptions& /* opts */, 290  std::vector< int >& /* tag_values_out */, 291  const SubsetList* /* subset_list */ ) 292 { 293  return MB_NOT_IMPLEMENTED; 294 } 295  296 ErrorCode Tqdcfr::load_file( const char* file_name, 297  const EntityHandle*, 298  const FileOptions& opts, 299  const ReaderIface::SubsetList* subset_list, 300  const Tag* file_id_tag ) 301 { 302  ErrorCode result; 303  304  int tmpval; 305  if( MB_SUCCESS == opts.get_int_option( "DEBUG_IO", 1, tmpval ) ) 306  { 307  if( 0 < tmpval ) debug = true; 308  } 309  310  if( subset_list ) 311  { 312  MB_SET_ERR( MB_UNSUPPORTED_OPERATION, "Reading subset of files not supported for CUB files" ); 313  } 314  315  // Open file 316  cubFile = fopen( file_name, "rb" ); 317  if( NULL == cubFile ) 318  { 319  MB_SET_ERR( MB_FAILURE, "File not found" ); 320  } 321  322  // Verify magic string 323  FREADC( 4 ); 324  if( !( char_buf[0] == 'C' && char_buf[1] == 'U' && char_buf[2] == 'B' && char_buf[3] == 'E' ) ) 325  { 326  fclose( cubFile ); 327  MB_SET_ERR( MB_FAILURE, "This doesn't appear to be a .cub file" ); 328  } 329  330  // Get "before" entities 331  result = mdbImpl->get_entities_by_handle( 0, beforeEnts );MB_CHK_SET_ERR( result, "Couldn't get \"before\" entities" ); 332  333  // *********************** 334  // Read model header type information... 335  // *********************** 336  if( debug ) std::cout << "Reading file header." << std::endl; 337  result = read_file_header();RR; 338  339  if( debug ) std::cout << "Reading model entries." << std::endl; 340  result = read_model_entries();RR; 341  342  // Read model metadata 343  if( debug ) std::cout << "Reading model metadata." << std::endl; 344  result = read_meta_data( fileTOC.modelMetaDataOffset, modelMetaData );RR; 345  346  double data_version; 347  int md_index = modelMetaData.get_md_entry( 2, "DataVersion" ); 348  if( -1 == md_index ) 349  data_version = 1.0; 350  else 351  data_version = modelMetaData.metadataEntries[md_index].mdDblValue; 352  353  // Get the major/minor cubit version that wrote this file 354  // int major = -1, minor = -1; 355  md_index = modelMetaData.get_md_entry( 2, "CubitVersion" ); 356  if( md_index >= 0 && !modelMetaData.metadataEntries[md_index].mdStringValue.empty() ) 357  sscanf( modelMetaData.metadataEntries[md_index].mdStringValue.c_str(), "%d.%d", &major, &minor ); 358  359  // *********************** 360  // Read mesh... 361  // *********************** 362  int index = find_model( mesh ); 363  if( -1 == index ) return MB_FAILURE; 364  ModelEntry* mesh_model = &modelEntries[index]; 365  366  // First the header & metadata info 367  if( debug ) std::cout << "Reading mesh model header and metadata." << std::endl; 368  result = mesh_model->read_header_info( this, data_version ); 369  if( MB_SUCCESS != result ) return result; 370  result = mesh_model->read_metadata_info( this ); 371  if( MB_SUCCESS != result ) return result; 372  373  // Now read in mesh for each geometry entity; read in order of increasing dimension 374  // so we have all the mesh we need 375  for( int dim = 0; dim < 4; dim++ ) 376  { 377  for( unsigned int gindex = 0; gindex < mesh_model->feModelHeader.geomArray.numEntities; gindex++ ) 378  { 379  Tqdcfr::GeomHeader* geom_header = &mesh_model->feGeomH[gindex]; 380  381  if( geom_header->maxDim != dim ) continue; 382  383  // Read nodes 384  if( debug ) std::cout << "Reading geom index " << gindex << " mesh: nodes... "; 385  result = read_nodes( gindex, mesh_model, geom_header ); 386  if( MB_SUCCESS != result ) return result; 387  388  // Read elements 389  if( debug ) std::cout << "elements... "; 390  result = read_elements( mesh_model, geom_header ); 391  if( MB_SUCCESS != result ) return result; 392  if( debug ) std::cout << std::endl; 393  } 394  } 395  396  // *********************** 397  // Read acis records... 398  // *********************** 399  std::string sat_file_name; 400  if( MB_SUCCESS != opts.get_str_option( "SAT_FILE", sat_file_name ) ) sat_file_name.clear(); 401  result = read_acis_records( sat_file_name.empty() ? NULL : sat_file_name.c_str() );RR; 402  403  // *********************** 404  // Read groups... 405  // *********************** 406  if( debug ) std::cout << "Reading groups... "; 407  for( unsigned int grindex = 0; grindex < mesh_model->feModelHeader.groupArray.numEntities; grindex++ ) 408  { 409  GroupHeader* group_header = &mesh_model->feGroupH[grindex]; 410  result = read_group( grindex, mesh_model, group_header ); 411  if( MB_SUCCESS != result ) return result; 412  } 413  if( debug ) std::cout << mesh_model->feModelHeader.groupArray.numEntities << " read successfully." << std::endl; 414  415  // *********************** 416  // Read blocks... 417  // *********************** 418  if( debug ) std::cout << "Reading blocks... "; 419  Range ho_entities; 420  for( unsigned int blindex = 0; blindex < mesh_model->feModelHeader.blockArray.numEntities; blindex++ ) 421  { 422  BlockHeader* block_header = &mesh_model->feBlockH[blindex]; 423  result = read_block( blindex, data_version, mesh_model, block_header ); 424  if( MB_SUCCESS != result ) return result; 425  } 426  427  if( debug ) std::cout << mesh_model->feModelHeader.blockArray.numEntities << " read successfully." << std::endl; 428  429  // *********************** 430  // Read nodesets... 431  // *********************** 432  if( debug ) std::cout << "Reading nodesets... "; 433  for( unsigned int nsindex = 0; nsindex < mesh_model->feModelHeader.nodesetArray.numEntities; nsindex++ ) 434  { 435  NodesetHeader* nodeset_header = &mesh_model->feNodeSetH[nsindex]; 436  result = read_nodeset( nsindex, mesh_model, nodeset_header ); 437  if( MB_SUCCESS != result ) return result; 438  } 439  if( debug ) std::cout << mesh_model->feModelHeader.nodesetArray.numEntities << " read successfully." << std::endl; 440  441  // *********************** 442  // Read sidesets... 443  // *********************** 444  if( debug ) std::cout << "Reading sidesets..."; 445  for( unsigned int ssindex = 0; ssindex < mesh_model->feModelHeader.sidesetArray.numEntities; ssindex++ ) 446  { 447  SidesetHeader* sideset_header = &mesh_model->feSideSetH[ssindex]; 448  result = read_sideset( ssindex, data_version, mesh_model, sideset_header ); 449  if( MB_SUCCESS != result ) return result; 450  } 451  if( debug ) std::cout << mesh_model->feModelHeader.sidesetArray.numEntities << " read successfully." << std::endl; 452  453  if( debug ) 454  { 455  std::cout << "Read the following mesh:" << std::endl; 456  mdbImpl->list_entities( 0, 0 ); 457  } 458  459  // Convert blocks to nodesets/sidesets if tag is set 460  result = convert_nodesets_sidesets(); 461  if( MB_SUCCESS != result ) return result; 462  463  Range after_ents; 464  result = mdbImpl->get_entities_by_handle( 0, after_ents ); 465  if( MB_SUCCESS != result ) return result; 466  467  after_ents = subtract( after_ents, beforeEnts ); 468  469  if( file_id_tag ) readUtilIface->assign_ids( *file_id_tag, after_ents ); 470  471  if( MB_SUCCESS != opts.get_null_option( "SKIP_TOPOLOGY" ) ) 472  { 473  // ************************** 474  // Restore geometric topology 475  // ************************** 476  GeomTopoTool gtt( mdbImpl, true, 0, true, false ); 477  result = gtt.restore_topology_from_adjacency(); 478  if( MB_SUCCESS != result ) 479  { 480  std::cout << "Failed to restore topology " << std::endl; 481  } 482  } 483  484  // done with the cubit file 485  fclose( cubFile ); 486  return result; 487 } 488  489 ErrorCode Tqdcfr::convert_nodesets_sidesets() 490 { 491  // Look first for the nodeset and sideset offset flags; if they're not 492  // set, we don't need to convert 493  const EntityHandle msh = 0; 494  unsigned int nodeset_offset, sideset_offset; 495  Tag tmp_tag; 496  ErrorCode result = mdbImpl->tag_get_handle( BLOCK_NODESET_OFFSET_TAG_NAME, 1, MB_TYPE_INTEGER, tmp_tag ); 497  if( MB_SUCCESS != result ) 498  nodeset_offset = 0; 499  else 500  { 501  result = mdbImpl->tag_get_data( tmp_tag, &msh, 1, &nodeset_offset ); 502  if( MB_SUCCESS != result ) return result; 503  } 504  505  result = mdbImpl->tag_get_handle( BLOCK_SIDESET_OFFSET_TAG_NAME, 1, MB_TYPE_INTEGER, tmp_tag ); 506  if( MB_SUCCESS != result ) 507  sideset_offset = 0; 508  else 509  { 510  result = mdbImpl->tag_get_data( tmp_tag, &msh, 1, &sideset_offset ); 511  if( MB_SUCCESS != result ) return result; 512  } 513  514  if( 0 == nodeset_offset && 0 == sideset_offset ) return MB_SUCCESS; 515  516  // Look for all blocks 517  Range blocks; 518  result = mdbImpl->get_entities_by_type_and_tag( 0, MBENTITYSET, &blockTag, NULL, 1, blocks ); 519  if( MB_SUCCESS != result || blocks.empty() ) return result; 520  521  // Get the id tag for them 522  std::vector< int > block_ids( blocks.size() ); 523  result = mdbImpl->tag_get_data( globalIdTag, blocks, &block_ids[0] ); 524  if( MB_SUCCESS != result ) return result; 525  526  unsigned int i = 0; 527  Range::iterator rit = blocks.begin(); 528  Range new_nodesets, new_sidesets; 529  std::vector< int > new_nodeset_ids, new_sideset_ids; 530  for( ; rit != blocks.end(); i++, ++rit ) 531  { 532  if( 0 != nodeset_offset && block_ids[i] >= (int)nodeset_offset && 533  ( nodeset_offset > sideset_offset || block_ids[i] < (int)sideset_offset ) ) 534  { 535  // This is a nodeset 536  new_nodesets.insert( *rit ); 537  new_nodeset_ids.push_back( block_ids[i] ); 538  } 539  else if( 0 != sideset_offset && block_ids[i] >= (int)sideset_offset && 540  ( sideset_offset > nodeset_offset || block_ids[i] < (int)nodeset_offset ) ) 541  { 542  // This is a sideset 543  new_sidesets.insert( *rit ); 544  new_sideset_ids.push_back( block_ids[i] ); 545  } 546  } 547  548  // OK, have the new nodesets and sidesets; now remove the block tags, and 549  // add nodeset and sideset tags 550  ErrorCode tmp_result = MB_SUCCESS; 551  if( 0 != nodeset_offset ) 552  { 553  if( 0 == nsTag ) 554  { 555  int default_val = 0; 556  tmp_result = mdbImpl->tag_get_handle( DIRICHLET_SET_TAG_NAME, 1, MB_TYPE_INTEGER, nsTag, 557  MB_TAG_SPARSE | MB_TAG_CREAT, &default_val ); 558  if( MB_SUCCESS != tmp_result ) result = tmp_result; 559  } 560  if( MB_SUCCESS == tmp_result ) tmp_result = mdbImpl->tag_set_data( nsTag, new_nodesets, &new_nodeset_ids[0] ); 561  if( MB_SUCCESS != tmp_result ) result = tmp_result; 562  tmp_result = mdbImpl->tag_delete_data( blockTag, new_nodesets ); 563  if( MB_SUCCESS != tmp_result ) result = tmp_result; 564  } 565  if( 0 != sideset_offset ) 566  { 567  if( 0 == ssTag ) 568  { 569  int default_val = 0; 570  tmp_result = mdbImpl->tag_get_handle( NEUMANN_SET_TAG_NAME, 1, MB_TYPE_INTEGER, ssTag, 571  MB_TAG_SPARSE | MB_TAG_CREAT, &default_val ); 572  if( MB_SUCCESS != tmp_result ) result = tmp_result; 573  } 574  if( MB_SUCCESS == tmp_result ) tmp_result = mdbImpl->tag_set_data( ssTag, new_sidesets, &new_sideset_ids[0] ); 575  if( MB_SUCCESS != tmp_result ) result = tmp_result; 576  tmp_result = mdbImpl->tag_delete_data( blockTag, new_sidesets ); 577  if( MB_SUCCESS != tmp_result ) result = tmp_result; 578  } 579  580  return result; 581 } 582  583 ErrorCode Tqdcfr::read_nodeset( const unsigned int nsindex, Tqdcfr::ModelEntry* model, Tqdcfr::NodesetHeader* nodeseth ) 584 { 585  if( nodeseth->memTypeCt == 0 ) return MB_SUCCESS; 586  587  // Position file 588  FSEEK( model->modelOffset + nodeseth->memOffset ); 589  590  // Read ids for each entity type 591  unsigned int this_type, num_ents; //, uid; 592  std::vector< char > bc_data; 593  unsigned int num_read = 0; 594  std::vector< EntityHandle > ns_entities, excl_entities; 595  for( unsigned int i = 0; i < nodeseth->memTypeCt; i++ ) 596  { 597  // Get how many and what type 598  FREADI( 2 ); 599  num_read += 2 * sizeof( int ); 600  this_type = uint_buf[0]; 601  num_ents = uint_buf[1]; 602  603  // Now get the ids 604  FREADI( num_ents ); 605  num_read += sizeof( int ); 606  CONVERT_TO_INTS( num_ents ); 607  608  ErrorCode result = get_entities( this_type + 2, &int_buf[0], num_ents, ns_entities, excl_entities ); 609  if( MB_SUCCESS != result ) return result; 610  } 611  // Check for more data 612  if( num_read < nodeseth->nsLength ) 613  { 614  FREADC( 2 ); // num_read += 2; 615  if( char_buf[0] == 'i' && char_buf[1] == 'd' ) 616  { 617  FREADI( 1 ); // num_read += sizeof(int); 618  // uid = int_buf[0]; 619  } 620  else 621  { 622  if( char_buf[0] == 'b' && char_buf[1] == 'c' ) 623  { 624  FREADI( 1 ); // num_read += sizeof(int); 625  int num_bcs = uint_buf[0]; 626  bc_data.resize( num_bcs ); 627  FREADCA( num_bcs, &bc_data[0] ); // num_read += num_bcs; 628  } 629  } 630  } 631  632  if( debug ) 633  { 634  nodeseth->print(); 635  if( !bc_data.empty() ) 636  { 637  std::cout << "bc_data = "; 638  std::vector< char >::iterator vit = bc_data.begin(); 639  for( ; vit != bc_data.end(); ++vit ) 640  { 641  std::cout << std::hex << (int)( (unsigned char)*vit ) << " "; 642  } 643  std::cout << ": "; 644  vit = bc_data.begin(); 645  for( ; vit != bc_data.end(); ++vit ) 646  { 647  std::cout << *vit; 648  } 649  std::cout << std::endl; 650  } 651  } 652  653  // And put entities into this nodeset's set 654  ErrorCode result = put_into_set( nodeseth->setHandle, ns_entities, excl_entities ); 655  if( MB_SUCCESS != result ) return result; 656  657  result = get_names( model->nodesetMD, nsindex, nodeseth->setHandle ); 658  if( MB_SUCCESS != result ) return result; 659  660  const int def_bc_data_len = 0; 661  std::string tag_name = std::string( DIRICHLET_SET_TAG_NAME ) + "__BC_DATA"; 662  Tag nbc_data; 663  result = mdbImpl->tag_get_handle( tag_name.c_str(), def_bc_data_len, MB_TYPE_OPAQUE, nbc_data, 664  MB_TAG_CREAT | MB_TAG_SPARSE | MB_TAG_BYTES | MB_TAG_VARLEN, NULL ); 665  if( MB_SUCCESS != result ) return result; 666  void const* tag_data[] = { ( bc_data.empty() ) ? NULL : &( bc_data[0] ) }; 667  int tag_size = bc_data.size(); 668  result = mdbImpl->tag_set_by_ptr( nbc_data, &nodeseth->setHandle, 1, tag_data, &tag_size ); 669  if( MB_SUCCESS != result ) return result; 670  671  return result; 672 } 673  674 ErrorCode Tqdcfr::read_sideset( const unsigned int ssindex, 675  const double data_version, 676  Tqdcfr::ModelEntry* model, 677  Tqdcfr::SidesetHeader* sideseth ) 678 { 679  if( sideseth->memCt == 0 ) return MB_SUCCESS; 680  681  ErrorCode result; 682  683  // Position file 684  FSEEK( model->modelOffset + sideseth->memOffset ); 685  686  // Read ids for each entity type 687  unsigned int this_type, num_ents, sense_size; 688  689  std::vector< char > bc_data; 690  unsigned int num_read = 0; //, uid; 691  std::vector< EntityHandle > ss_entities, excl_entities; 692  if( data_version <= 1.0 ) 693  { 694  for( unsigned int i = 0; i < sideseth->memTypeCt; i++ ) 695  { 696  // Get how many and what type 697  FREADI( 3 ); 698  num_read += 3 * sizeof( int ); 699  this_type = uint_buf[0]; 700  num_ents = uint_buf[1]; 701  sense_size = uint_buf[2]; 702  703  // Now get the ids 704  FREADI( num_ents ); 705  num_read += sizeof( int ); 706  CONVERT_TO_INTS( num_ents ); 707  708  result = get_entities( this_type + 2, &int_buf[0], num_ents, ss_entities, excl_entities ); 709  if( MB_SUCCESS != result ) return result; 710  711  if( sense_size == 1 ) 712  { 713  // Byte-size sense flags; make sure read ends aligned... 714  unsigned int read_length = ( num_ents / 8 ) * 8; 715  if( read_length < num_ents ) read_length += 8; 716  FREADC( read_length ); 717  num_read += read_length; 718  } 719  else if( sense_size == 2 ) 720  { 721  // Int-size sense flags 722  FREADI( num_ents ); 723  num_read += sizeof( int ); 724  } 725  726  // Now do something with them... 727  process_sideset_10( this_type, num_ents, sense_size, ss_entities, sideseth ); 728  } 729  } 730  else 731  { 732  for( unsigned int i = 0; i < sideseth->memTypeCt; i++ ) 733  { 734  // Get how many and what type 735  FREADI( 1 ); 736  num_read += sizeof( int ); 737  num_ents = uint_buf[0]; 738  739  // Get the types, and ids 740  std::vector< unsigned int > mem_types( num_ents ), mem_ids( num_ents ); 741  FREADIA( num_ents, &mem_types[0] ); 742  num_read += num_ents * sizeof( int ); 743  FREADI( num_ents ); 744  num_read += sizeof( int ); 745  746  result = get_entities( &mem_types[0], &int_buf[0], num_ents, false, ss_entities ); 747  if( MB_SUCCESS != result ) return result; 748  749  // Byte-size sense flags; make sure read ends aligned... 750  unsigned int read_length = ( num_ents / 8 ) * 8; 751  if( read_length < num_ents ) read_length += 8; 752  FREADC( read_length ); 753  num_read += read_length; 754  755  // wrt entities 756  FREADI( 1 ); 757  num_read += sizeof( int ); 758  int num_wrts = uint_buf[0]; 759  FREADI( num_wrts ); 760  num_read += num_wrts * sizeof( int ); 761  762  result = process_sideset_11( ss_entities, num_wrts, sideseth ); 763  if( MB_SUCCESS != result ) return result; 764  } 765  } 766  767  // Now set the dist factors 768  if( sideseth->numDF > 0 ) 769  { 770  // Have to read dist factors 771  FREADD( sideseth->numDF ); 772  num_read += sideseth->numDF * sizeof( double ); 773  Tag distFactorTag; 774  result = mdbImpl->tag_get_handle( "distFactor", 0, MB_TYPE_DOUBLE, distFactorTag, 775  MB_TAG_SPARSE | MB_TAG_VARLEN | MB_TAG_CREAT ); 776  if( MB_SUCCESS != result ) return result; 777  const void* dist_data = &dbl_buf[0]; 778  const int dist_size = sideseth->numDF; 779  result = mdbImpl->tag_set_by_ptr( distFactorTag, &sideseth->setHandle, 1, &dist_data, &dist_size ); 780  if( MB_SUCCESS != result ) return result; 781  } 782  783  // Check for more data 784  if( data_version > 1.0 && num_read < sideseth->ssLength ) 785  { 786  FREADC( 2 ); // num_read += 2; 787  if( char_buf[0] == 'i' && char_buf[1] == 'd' ) 788  { 789  FREADI( 1 ); // num_read += sizeof(int); 790  // uid = int_buf[0]; 791  } 792  else 793  { 794  // Check for bc_data 795  if( char_buf[0] == 'b' && char_buf[1] == 'c' ) 796  { 797  FREADI( 1 ); // num_read += sizeof(int); 798  int num_bcs = uint_buf[0]; 799  bc_data.resize( num_bcs ); 800  FREADCA( num_bcs, &bc_data[0] ); // num_read += num_bcs; 801  } 802  } 803  } 804  805  if( debug ) 806  { 807  sideseth->print(); 808  if( !bc_data.empty() ) 809  { 810  std::cout << "bc_data = "; 811  std::vector< char >::iterator vit = bc_data.begin(); 812  for( ; vit != bc_data.end(); ++vit ) 813  { 814  std::cout << std::hex << (int)( (unsigned char)*vit ) << " "; 815  } 816  std::cout << ": "; 817  vit = bc_data.begin(); 818  for( ; vit != bc_data.end(); ++vit ) 819  { 820  std::cout << *vit; 821  } 822  std::cout << std::endl; 823  } 824  } 825  826  result = get_names( model->sidesetMD, ssindex, sideseth->setHandle ); 827  if( MB_SUCCESS != result ) return result; 828  829  const int def_bc_data_len = 0; 830  std::string tag_name = std::string( NEUMANN_SET_TAG_NAME ) + "__BC_DATA"; 831  Tag nbc_data; 832  result = mdbImpl->tag_get_handle( tag_name.c_str(), def_bc_data_len, MB_TYPE_OPAQUE, nbc_data, 833  MB_TAG_CREAT | MB_TAG_SPARSE | MB_TAG_BYTES | MB_TAG_VARLEN, NULL ); 834  if( MB_SUCCESS != result ) return result; 835  void const* tag_data[] = { ( bc_data.empty() ) ? NULL : &( bc_data[0] ) }; 836  int tag_size = bc_data.size(); 837  result = mdbImpl->tag_set_by_ptr( nbc_data, &sideseth->setHandle, 1, tag_data, &tag_size ); 838  if( MB_SUCCESS != result ) return result; 839  840  return MB_SUCCESS; 841 } 842  843 ErrorCode Tqdcfr::process_sideset_10( const int this_type, 844  const int num_ents, 845  const int sense_size, 846  std::vector< EntityHandle >& ss_entities, 847  Tqdcfr::SidesetHeader* sideseth ) 848 { 849  std::vector< EntityHandle > forward, reverse; 850  if( this_type == 3 // Surface 851  && sense_size == 1 // Byte size 852  ) 853  { 854  // Interpret sense flags w/o reference to anything 855  for( int i = 0; i < num_ents; i++ ) 856  { 857  if( (int)char_buf[i] == 0 ) 858  forward.push_back( ss_entities[i] ); 859  else if( (int)char_buf[i] == 1 ) 860  reverse.push_back( ss_entities[i] ); 861  else if( (int)char_buf[i] == -1 ) 862  { // -1 means "unknown", which means both 863  forward.push_back( ss_entities[i] ); 864  reverse.push_back( ss_entities[i] ); 865  } 866  } 867  } 868  else if( this_type == 4 // Curve 869  && sense_size == 2 // int32 size 870  ) 871  { 872  for( int i = 0; i < num_ents; i++ ) 873  { 874  if( uint_buf[i] == 0 ) 875  forward.push_back( ss_entities[i] ); 876  else if( uint_buf[i] == 1 ) 877  reverse.push_back( ss_entities[i] ); 878  else if( *( (int*)&uint_buf[i] ) == -1 ) 879  { // -1 means "unknown", which means both 880  forward.push_back( ss_entities[i] ); 881  reverse.push_back( ss_entities[i] ); 882  } 883  } 884  } 885  886  // Now actually put them in the set 887  ErrorCode result = MB_SUCCESS; 888  if( !forward.empty() ) 889  { 890  ErrorCode tmp_result = mdbImpl->add_entities( sideseth->setHandle, &forward[0], forward.size() ); 891  if( tmp_result != MB_SUCCESS ) result = tmp_result; 892  } 893  if( !reverse.empty() ) 894  { 895  // Need to make a new set, add a reverse sense tag, then add to the sideset 896  EntityHandle reverse_set; 897  ErrorCode tmp_result = create_set( reverse_set ); 898  if( MB_SUCCESS != tmp_result ) result = tmp_result; 899  tmp_result = mdbImpl->add_entities( reverse_set, &reverse[0], reverse.size() ); 900  if( tmp_result != MB_SUCCESS ) result = tmp_result; 901  int def_val = 1; 902  Tag sense_tag; 903  tmp_result = mdbImpl->tag_get_handle( "NEUSET_SENSE", 1, MB_TYPE_INTEGER, sense_tag, 904  MB_TAG_SPARSE | MB_TAG_CREAT, &def_val ); 905  if( tmp_result != MB_SUCCESS ) result = tmp_result; 906  def_val = -1; 907  tmp_result = mdbImpl->tag_set_data( sense_tag, &reverse_set, 1, &def_val ); 908  if( tmp_result != MB_SUCCESS ) result = tmp_result; 909  tmp_result = mdbImpl->add_entities( sideseth->setHandle, &reverse_set, 1 ); 910  if( tmp_result != MB_SUCCESS ) result = tmp_result; 911  } 912  913  return result; 914 } 915  916 ErrorCode Tqdcfr::process_sideset_11( std::vector< EntityHandle >& ss_entities, 917  int num_wrts, 918  Tqdcfr::SidesetHeader* sideseth ) 919 { 920  std::vector< EntityHandle > forward, reverse; 921  922  unsigned int num_ents = ss_entities.size(); 923  unsigned int* wrt_it = &uint_buf[0]; 924  925  for( unsigned int i = 0; i < num_ents; i++ ) 926  { 927  unsigned int num_wrt = 0; 928  if( 0 != num_wrts ) num_wrt = *wrt_it++; 929  for( unsigned int j = 0; j < num_wrt; j++ ) 930  wrt_it += 2; 931  // Assume here that if it's in the list twice, we get both senses 932  if( num_wrt > 1 ) 933  { 934  forward.push_back( ss_entities[i] ); 935  reverse.push_back( ss_entities[i] ); 936  } 937  else 938  { 939  // Else interpret the sense flag 940  if( (int)char_buf[i] == 0 ) 941  forward.push_back( ss_entities[i] ); 942  else if( (int)char_buf[i] == 1 ) 943  reverse.push_back( ss_entities[i] ); 944  else if( (int)char_buf[i] == -1 ) 945  { // -1 means "unknown", which means both 946  forward.push_back( ss_entities[i] ); 947  reverse.push_back( ss_entities[i] ); 948  } 949  } 950  } 951  952  // Now actually put them in the set 953  ErrorCode result = MB_SUCCESS; 954  if( !forward.empty() ) 955  { 956  ErrorCode tmp_result = mdbImpl->add_entities( sideseth->setHandle, &forward[0], forward.size() ); 957  if( tmp_result != MB_SUCCESS ) result = tmp_result; 958  } 959  if( !reverse.empty() ) 960  { 961  // Need to make a new set, add a reverse sense tag, then add to the sideset 962  EntityHandle reverse_set; 963  ErrorCode tmp_result = create_set( reverse_set ); 964  if( MB_SUCCESS != tmp_result ) result = tmp_result; 965  tmp_result = mdbImpl->add_entities( reverse_set, &reverse[0], reverse.size() ); 966  if( tmp_result != MB_SUCCESS ) result = tmp_result; 967  int def_val = 1; 968  Tag sense_tag; 969  tmp_result = mdbImpl->tag_get_handle( "NEUSET_SENSE", 1, MB_TYPE_INTEGER, sense_tag, 970  MB_TAG_SPARSE | MB_TAG_CREAT, &def_val ); 971  if( tmp_result != MB_SUCCESS && tmp_result != MB_ALREADY_ALLOCATED ) result = tmp_result; 972  def_val = -1; 973  tmp_result = mdbImpl->tag_set_data( sense_tag, &reverse_set, 1, &def_val ); 974  if( tmp_result != MB_SUCCESS ) result = tmp_result; 975  tmp_result = mdbImpl->add_entities( sideseth->setHandle, &reverse_set, 1 ); 976  if( tmp_result != MB_SUCCESS ) result = tmp_result; 977  } 978  979  return result; 980 } 981  982 ErrorCode Tqdcfr::read_block( const unsigned int blindex, 983  const double /*data_version*/, 984  Tqdcfr::ModelEntry* model, 985  Tqdcfr::BlockHeader* blockh ) 986 { 987  if( blockh->memCt == 0 ) return MB_SUCCESS; 988  989  // Position file 990  FSEEK( model->modelOffset + blockh->memOffset ); 991  992  // Read ids for each entity type 993  unsigned int num_read = 0; 994  int this_type, num_ents; //, uid; 995  std::vector< EntityHandle > block_entities, excl_entities; 996  for( unsigned int i = 0; i < blockh->memTypeCt; i++ ) 997  { 998  // Get how many and what type 999  FREADI( 2 ); 1000  num_read += 2 * sizeof( int ); 1001  this_type = uint_buf[0]; 1002  num_ents = uint_buf[1]; 1003  1004  // Now get the ids 1005  FREADI( num_ents ); 1006  num_read += num_ents * sizeof( int ); 1007  CONVERT_TO_INTS( num_ents ); 1008  1009  ErrorCode result = get_entities( this_type + 2, &int_buf[0], num_ents, block_entities, excl_entities ); 1010  if( MB_SUCCESS != result ) return result; 1011  } 1012  1013  // And put entities into this block's set 1014  ErrorCode result = put_into_set( blockh->setHandle, block_entities, excl_entities ); 1015  if( MB_SUCCESS != result ) return result; 1016  1017  // Read attribs if there are any 1018  Tag block_attribs; 1019  { 1020  int def_block_attributes_length = 0; 1021  result = mdbImpl->tag_get_handle( BLOCK_ATTRIBUTES, def_block_attributes_length, MB_TYPE_DOUBLE, block_attribs, 1022  MB_TAG_CREAT | MB_TAG_SPARSE | MB_TAG_VARLEN, NULL ); 1023  if( MB_SUCCESS != result && MB_ALREADY_ALLOCATED != result ) return result; 1024  } 1025  1026  if( blockh->attribOrder > 0 ) 1027  { 1028  FREADD( blockh->attribOrder ); 1029  num_read += sizeof( double ); 1030  void const* tag_data[] = { &dbl_buf[0] }; 1031  int tag_sizes[] = { static_cast< int >( blockh->attribOrder ) }; 1032  result = mdbImpl->tag_set_by_ptr( block_attribs, &( blockh->setHandle ), 1, tag_data, tag_sizes ); 1033  if( MB_SUCCESS != result ) return result; 1034  } 1035  1036  // Check for more data 1037  if( num_read < blockh->blockLength ) 1038  { 1039  FREADC( 2 ); // num_read += 2; 1040  if( char_buf[0] == 'i' && char_buf[1] == 'd' ) 1041  { 1042  FREADI( 1 ); // num_read += sizeof(int); 1043  // uid = int_buf[0]; 1044  } 1045  } 1046  1047  result = get_names( model->blockMD, blindex, blockh->setHandle ); 1048  if( MB_SUCCESS != result ) return result; 1049  1050  // Put additional higher-order nodes into element connectivity list. 1051  // Cubit saves full connectivity list only for NodeHex and NodeTet 1052  // elements. Other element types will only have the corners and 1053  // the mid-element node if there is one. Need to reconstruct additional 1054  // connectivity entries from mid-nodes of adjacent lower-order entities. 1055  int node_per_elem = cub_elem_num_verts[blockh->blockElemType]; 1056  if( blockh->blockEntityType == MBMAXTYPE ) return MB_SUCCESS; 1057  if( ( 14 == major && 2 < minor ) || 15 <= major ) 1058  { 1059  if( 55 == blockh->blockElemType || CN::VerticesPerEntity( blockh->blockEntityType ) == node_per_elem ) 1060  return MB_SUCCESS; 1061  } 1062  else 1063  { 1064  if( 52 == blockh->blockElemType || CN::VerticesPerEntity( blockh->blockEntityType ) == node_per_elem ) 1065  return MB_SUCCESS; 1066  } 1067  1068  // Can't use Interface::convert_entities because block could contain 1069  // both entity sets and entities. convert_entities will fail if block 1070  // contains an entity set, but we still need to call it on any elements 1071  // directly in the block (rather than a geometry subset). So bypass 1072  // Interface and call HOFactory directly with an Range of entities. 1073  Range ho_entities, entities; 1074  mdbImpl->get_entities_by_type( blockh->setHandle, blockh->blockEntityType, entities, true ); 1075  if( CN::Dimension( blockh->blockEntityType ) > 2 ) 1076  { 1077  result = mdbImpl->get_adjacencies( entities, 2, false, ho_entities, Interface::UNION ); 1078  if( MB_SUCCESS != result ) return result; 1079  } 1080  if( CN::Dimension( blockh->blockEntityType ) > 1 ) 1081  { 1082  result = mdbImpl->get_adjacencies( entities, 1, false, ho_entities, Interface::UNION ); 1083  if( MB_SUCCESS != result ) return result; 1084  } 1085  entities.merge( ho_entities ); 1086  1087  Core* mbcore = dynamic_cast< Core* >( mdbImpl ); 1088  assert( mbcore != NULL ); 1089  HigherOrderFactory ho_fact( mbcore, 0 ); 1090  return ho_fact.convert( entities, !!blockh->hasMidNodes[1], !!blockh->hasMidNodes[2], !!blockh->hasMidNodes[3] ); 1091 } 1092  1093 ErrorCode Tqdcfr::get_names( MetaDataContainer& md, unsigned int set_index, EntityHandle seth ) 1094 { 1095  ErrorCode result = MB_SUCCESS; 1096  1097  // Now get block names, if any 1098  int md_index = md.get_md_entry( set_index, "Name" ); 1099  if( -1 == md_index ) return result; 1100  MetaDataContainer::MetaDataEntry* md_entry = &( md.metadataEntries[md_index] ); 1101  // assert(md_entry->mdStringValue.length() + 1 <= NAME_TAG_SIZE); 1102  char name_tag_data[NAME_TAG_SIZE]; 1103  memset( name_tag_data, 0, NAME_TAG_SIZE ); // Make sure any extra bytes zeroed 1104  strncpy( name_tag_data, md_entry->mdStringValue.c_str(), NAME_TAG_SIZE - 1 ); 1105  result = mdbImpl->tag_set_data( entityNameTag, &seth, 1, name_tag_data ); 1106  if( MB_SUCCESS != result ) return result; 1107  1108  // Look for extra names 1109  md_index = md.get_md_entry( set_index, "NumExtraNames" ); 1110  if( -1 == md_index ) return result; 1111  int num_names = md.metadataEntries[md_index].mdIntValue; 1112  for( int i = 0; i < num_names; i++ ) 1113  { 1114  std::ostringstream extra_name_label( "ExtraName" ); 1115  extra_name_label << i; 1116  std::ostringstream moab_extra_name( "EXTRA_" ); 1117  moab_extra_name << NAME_TAG_NAME << i; 1118  md_index = md.get_md_entry( set_index, extra_name_label.str().c_str() ); 1119  if( -1 != md_index ) 1120  { 1121  md_entry = &( md.metadataEntries[md_index] ); 1122  Tag extra_name_tag; 1123  ErrorCode rval; 1124  rval = mdbImpl->tag_get_handle( moab_extra_name.str().c_str(), NAME_TAG_SIZE, MB_TYPE_OPAQUE, 1125  extra_name_tag, MB_TAG_SPARSE | MB_TAG_CREAT );MB_CHK_ERR( rval ); 1126  memset( name_tag_data, 0, NAME_TAG_SIZE ); // Make sure any extra bytes zeroed 1127  strncpy( name_tag_data, md_entry->mdStringValue.c_str(), NAME_TAG_SIZE - 1 ); 1128  result = mdbImpl->tag_set_data( extra_name_tag, &seth, 1, name_tag_data ); 1129  } 1130  } 1131  1132  return result; 1133 } 1134  1135 ErrorCode Tqdcfr::read_group( const unsigned int group_index, Tqdcfr::ModelEntry* model, Tqdcfr::GroupHeader* grouph ) 1136 { 1137  // Position file 1138  FSEEK( model->modelOffset + grouph->memOffset ); 1139  char name_tag_data[NAME_TAG_SIZE]; 1140  1141  // Read ids for each entity type 1142  int this_type, num_ents; 1143  std::vector< EntityHandle > grp_entities, excl_entities; 1144  for( unsigned int i = 0; i < grouph->memTypeCt; i++ ) 1145  { 1146  // Get how many and what type 1147  FREADI( 2 ); 1148  this_type = uint_buf[0]; 1149  num_ents = uint_buf[1]; 1150  1151  // Now get the ids 1152  FREADI( num_ents ); 1153  CONVERT_TO_INTS( num_ents ); 1154  1155  // Get the entities in this group 1156  ErrorCode result = get_entities( this_type, &int_buf[0], num_ents, grp_entities, excl_entities ); 1157  if( MB_SUCCESS != result ) return result; 1158  } 1159  1160  // Now add the entities 1161  ErrorCode result = put_into_set( grouph->setHandle, grp_entities, excl_entities ); 1162  if( MB_SUCCESS != result ) return result; 1163  1164  // Now get group names, if any 1165  int md_index = model->groupMD.get_md_entry( grouph->grpID, "NAME" ); 1166  if( -1 != md_index ) 1167  { 1168  MetaDataContainer::MetaDataEntry* md_entry = &( model->groupMD.metadataEntries[md_index] ); 1169  if( 0 == entityNameTag ) 1170  { 1171  memset( name_tag_data, 0, NAME_TAG_SIZE ); 1172  result = mdbImpl->tag_get_handle( NAME_TAG_NAME, NAME_TAG_SIZE, MB_TYPE_OPAQUE, entityNameTag, 1173  MB_TAG_SPARSE | MB_TAG_CREAT, name_tag_data ); 1174  if( MB_SUCCESS != result ) return result; 1175  } 1176  // assert(md_entry->mdStringValue.length() + 1 <= NAME_TAG_SIZE); 1177  memset( name_tag_data, 0, NAME_TAG_SIZE ); // Make sure any extra bytes zeroed 1178  strncpy( name_tag_data, md_entry->mdStringValue.c_str(), NAME_TAG_SIZE - 1 ); 1179  result = mdbImpl->tag_set_data( entityNameTag, &grouph->setHandle, 1, name_tag_data ); 1180  if( MB_SUCCESS != result ) return result; 1181  1182  // Look for extra names 1183  md_index = model->groupMD.get_md_entry( group_index, "NumExtraNames" ); 1184  if( -1 != md_index ) 1185  { 1186  int num_names = model->groupMD.metadataEntries[md_index].mdIntValue; 1187  for( int i = 0; i < num_names; i++ ) 1188  { 1189  std::ostringstream extra_name_label( "ExtraName" ); 1190  extra_name_label << i; 1191  std::ostringstream moab_extra_name( "EXTRA_" ); 1192  moab_extra_name << NAME_TAG_NAME << i; 1193  md_index = model->groupMD.get_md_entry( group_index, extra_name_label.str().c_str() ); 1194  if( -1 != md_index ) 1195  { 1196  md_entry = &( model->groupMD.metadataEntries[md_index] ); 1197  Tag extra_name_tag; 1198  memset( name_tag_data, 0, NAME_TAG_SIZE ); 1199  result = mdbImpl->tag_get_handle( moab_extra_name.str().c_str(), NAME_TAG_SIZE, MB_TYPE_OPAQUE, 1200  extra_name_tag, MB_TAG_SPARSE | MB_TAG_CREAT, name_tag_data ); 1201  if( MB_SUCCESS != result ) return result; 1202  // assert(md_entry->mdStringValue.length() + 1 <= NAME_TAG_SIZE); 1203  memset( name_tag_data, 0, NAME_TAG_SIZE ); // Make sure any extra bytes zeroed 1204  strncpy( name_tag_data, md_entry->mdStringValue.c_str(), NAME_TAG_SIZE - 1 ); 1205  result = mdbImpl->tag_set_data( extra_name_tag, &grouph->setHandle, 1, name_tag_data ); 1206  } 1207  } 1208  } 1209  } 1210  1211  return result; 1212 } 1213  1214 ErrorCode Tqdcfr::put_into_set( EntityHandle set_handle, 1215  std::vector< EntityHandle >& entities, 1216  std::vector< EntityHandle >& excl_entities ) 1217 { 1218  // And put entities into this block's set 1219  ErrorCode result = mdbImpl->add_entities( set_handle, &entities[0], entities.size() ); 1220  if( MB_SUCCESS != result ) return result; 1221  1222  // Check for excluded entities, and add them to a vector hung off the block if there 1223  Tag excl_tag; 1224  if( !excl_entities.empty() ) 1225  { 1226  result = mdbImpl->tag_get_handle( "Exclude_Entities", sizeof( std::vector< EntityHandle >* ), MB_TYPE_OPAQUE, 1227  excl_tag, MB_TAG_SPARSE | MB_TAG_CREAT ); 1228  if( MB_SUCCESS != result ) return result; 1229  std::vector< EntityHandle >* new_vector = new std::vector< EntityHandle >; 1230  new_vector->swap( excl_entities ); 1231  result = mdbImpl->tag_set_data( excl_tag, &set_handle, 1, &new_vector ); 1232  if( MB_SUCCESS != result ) 1233  { 1234  delete new_vector; 1235  return MB_FAILURE; 1236  } 1237  } 1238  1239  return MB_SUCCESS; 1240 } 1241  1242 ErrorCode Tqdcfr::get_entities( const unsigned int* mem_types, 1243  int* id_buf, 1244  const unsigned int id_buf_size, 1245  const bool is_group, 1246  std::vector< EntityHandle >& entities ) 1247 { 1248  ErrorCode tmp_result, result = MB_SUCCESS; 1249  1250  for( unsigned int i = 0; i < id_buf_size; i++ ) 1251  { 1252  if( is_group ) 1253  tmp_result = get_entities( mem_types[i], id_buf + i, 1, entities, entities ); 1254  else 1255  // For blocks/nodesets/sidesets, use CSOEntityType, which is 2 greater than 1256  // group entity types 1257  tmp_result = get_entities( mem_types[i] + 2, id_buf + i, 1, entities, entities ); 1258  if( MB_SUCCESS != tmp_result ) result = tmp_result; 1259  } 1260  1261  return result; 1262 } 1263  1264 ErrorCode Tqdcfr::get_entities( const unsigned int this_type, 1265  int* id_buf, 1266  const unsigned int id_buf_size, 1267  std::vector< EntityHandle >& entities, 1268  std::vector< EntityHandle >& excl_entities ) 1269 { 1270  ErrorCode result = MB_FAILURE; 1271  1272  if( this_type <= VERTEX ) 1273  result = get_ref_entities( this_type, id_buf, id_buf_size, entities ); 1274  else if( this_type >= HEX && this_type <= NODE ) 1275  result = get_mesh_entities( this_type, id_buf, id_buf_size, entities, excl_entities ); 1276  1277  return result; 1278 } 1279  1280 ErrorCode Tqdcfr::get_ref_entities( const unsigned int this_type, 1281  int* id_buf, 1282  const unsigned int id_buf_size, 1283  std::vector< EntityHandle >& entities ) 1284 { 1285  for( unsigned int i = 0; i < id_buf_size; i++ ) 1286  entities.push_back( ( gidSetMap[5 - this_type] )[id_buf[i]] ); 1287  1288  return MB_SUCCESS; 1289 } 1290  1291 ErrorCode Tqdcfr::get_mesh_entities( const unsigned int this_type, 1292  int* id_buf, 1293  const unsigned int id_buf_size, 1294  std::vector< EntityHandle >& entities, 1295  std::vector< EntityHandle >& excl_entities ) 1296 { 1297  ErrorCode result = MB_SUCCESS; 1298  std::vector< EntityHandle >* ent_list = NULL; 1299  EntityType this_ent_type = MBVERTEX; 1300  const unsigned int arr_len = sizeof( group_type_to_mb_type ) / sizeof( group_type_to_mb_type[0] ); 1301  if( this_type > 1000 ) 1302  { 1303  if( this_type - 1000 < arr_len ) 1304  { 1305  this_ent_type = group_type_to_mb_type[this_type - 1000]; 1306  ent_list = &excl_entities; 1307  } 1308  } 1309  else 1310  { 1311  if( this_type < arr_len ) 1312  { 1313  this_ent_type = group_type_to_mb_type[this_type]; 1314  ent_list = &entities; 1315  } 1316  } 1317  if( NULL == ent_list ) 1318  { 1319  MB_SET_ERR( MB_FAILURE, "Entities list is NULL" ); 1320  } 1321  1322  // Get entities with this type, and get their cub id tags 1323  if( MBVERTEX == this_ent_type ) 1324  { 1325  // Use either vertex offset or cubMOABVertexMap 1326  if( NULL == cubMOABVertexMap ) 1327  { 1328  for( unsigned int i = 0; i < id_buf_size; i++ ) 1329  ent_list->push_back( (EntityHandle)( id_buf[i] + currVHandleOffset ) ); 1330  } 1331  else 1332  { 1333  for( unsigned int i = 0; i < id_buf_size; i++ ) 1334  { 1335  assert( 0 != ( *cubMOABVertexMap )[id_buf[i]] ); 1336  ent_list->push_back( ( *cubMOABVertexMap )[id_buf[i]] ); 1337  } 1338  } 1339  } 1340  else 1341  { 1342  Range tmp_ents; 1343  result = mdbImpl->get_entities_by_type( 0, this_ent_type, tmp_ents ); 1344  if( MB_SUCCESS != result ) return result; 1345  if( tmp_ents.empty() && 0 != id_buf_size ) return MB_FAILURE; 1346  1347  std::vector< int > cub_ids( tmp_ents.size() ); 1348  result = mdbImpl->tag_get_data( globalIdTag, tmp_ents, &cub_ids[0] ); 1349  if( MB_SUCCESS != result && MB_TAG_NOT_FOUND != result ) return result; 1350  1351  // Now go through id list, finding each entity by id 1352  for( unsigned int i = 0; i < id_buf_size; i++ ) 1353  { 1354  std::vector< int >::iterator vit = std::find( cub_ids.begin(), cub_ids.end(), id_buf[i] ); 1355  if( vit != cub_ids.end() ) 1356  { 1357  EntityHandle this_ent = tmp_ents[vit - cub_ids.begin()]; 1358  if( mdbImpl->type_from_handle( this_ent ) != MBMAXTYPE ) ent_list->push_back( this_ent ); 1359  } 1360  else 1361  { 1362  std::cout << "Warning: didn't find " << CN::EntityTypeName( this_ent_type ) << " " << id_buf[i] 1363  << std::endl; 1364  } 1365  } 1366  } 1367  1368  return result; 1369 } 1370  1371 ErrorCode Tqdcfr::read_nodes( const unsigned int gindex, Tqdcfr::ModelEntry* model, Tqdcfr::GeomHeader* entity ) 1372 { 1373  if( entity->nodeCt == 0 ) 1374  { 1375  if( debug ) std::cout << "(no nodes) "; 1376  return MB_SUCCESS; 1377  } 1378  1379  // Get the ids & coords in separate calls to minimize memory usage 1380  // Position the file 1381  FSEEK( model->modelOffset + entity->nodeOffset ); 1382  // Get node ids in uint_buf 1383  FREADI( entity->nodeCt ); 1384  1385  if( debug ) 1386  { 1387  std::cout << "("; 1388  for( unsigned int i = 0; i < entity->nodeCt; i++ ) 1389  { 1390  std::cout << uint_buf[i]; 1391  if( i != entity->nodeCt - 1 ) std::cout << ", "; 1392  } 1393  std::cout << ")..."; 1394  } 1395  1396  // Get a space for reading nodal data directly into MB, and read that data 1397  EntityHandle vhandle = 0; 1398  std::vector< double* > arrays; 1399  readUtilIface->get_node_coords( 3, entity->nodeCt, uint_buf[0], vhandle, arrays, 1400  SequenceManager::DEFAULT_VERTEX_SEQUENCE_SIZE ); 1401  1402  // Get node x's in arrays[0] 1403  FREADDA( entity->nodeCt, arrays[0] ); 1404  // Get node y's in arrays[1] 1405  FREADDA( entity->nodeCt, arrays[1] ); 1406  // Get node z's in arrays[2] 1407  FREADDA( entity->nodeCt, arrays[2] ); 1408  1409  // Add these nodes into the entity's set 1410  Range dum_range( vhandle, vhandle + entity->nodeCt - 1 ); 1411  ErrorCode result = mdbImpl->add_entities( entity->setHandle, dum_range ); 1412  if( MB_SUCCESS != result ) return result; 1413  1414  // Check for id contiguity; know that cid's will never be > 32bit, so 1415  // ids can be unsigned int 1416  unsigned int max_cid, min_cid; 1417  int contig; 1418  check_contiguous( entity->nodeCt, contig, min_cid, max_cid ); 1419  1420  // Compute the offset we get in this batch and compare to any previous one 1421  long vhandle_offset = vhandle - min_cid; 1422  if( -1 == currVHandleOffset ) currVHandleOffset = vhandle_offset; 1423  1424  // In 2 situations we'll need to add/modify a cubit_id -> vhandle map: 1425  // case A: no map yet, and either this offset different from 1426  // previous or not contiguous 1427  if( !cubMOABVertexMap && ( currVHandleOffset != vhandle_offset || !contig ) ) 1428  { 1429  // Get all vertices, removing ones in this batch 1430  Range vrange, tmp_range( dum_range ); 1431  result = mdbImpl->get_entities_by_type( 0, MBVERTEX, vrange );RR; 1432  if( !beforeEnts.empty() ) tmp_range.merge( beforeEnts.subset_by_type( MBVERTEX ) ); 1433  vrange = subtract( vrange, tmp_range ); 1434  // Compute the max cid; map is indexed by cid, so size is max_cid + 1 1435 #define MAX( a, b ) ( ( a ) > ( b ) ? ( a ) : ( b ) ) 1436 #define MIN( a, b ) ( ( a ) < ( b ) ? ( a ) : ( b ) ) 1437  // Sanity check that max vhandle is larger than offset 1438  long new_max = *vrange.rbegin() - currVHandleOffset; 1439  assert( new_max >= 0 && ( (long)*vrange.begin() ) - currVHandleOffset >= 0 ); 1440  max_cid = MAX( max_cid, ( (unsigned int)new_max ) ); 1441  cubMOABVertexMap = new std::vector< EntityHandle >( max_cid + 1 ); 1442  // Initialize to zero then put previous vertices into the map 1443  std::fill( cubMOABVertexMap->begin(), cubMOABVertexMap->end(), 0 ); 1444  Range::iterator rit; 1445  for( rit = vrange.begin(); rit != vrange.end(); ++rit ) 1446  { 1447  assert( ( (long)*rit ) - currVHandleOffset >= 0 && ( (long)*rit ) - currVHandleOffset <= max_cid ); 1448  ( *cubMOABVertexMap )[*rit - currVHandleOffset] = *rit; 1449  } 1450  } 1451  // case B: there is a map and we need to resize it 1452  else if( cubMOABVertexMap && max_cid + 1 > cubMOABVertexMap->size() ) 1453  { 1454  unsigned int old_size = cubMOABVertexMap->size(); 1455  cubMOABVertexMap->resize( max_cid + 1 ); 1456  std::fill( &( *cubMOABVertexMap )[old_size], &( *cubMOABVertexMap )[0] + cubMOABVertexMap->size(), 0 ); 1457  } 1458  1459  // OK, we have a map or don't need one 1460  if( NULL == cubMOABVertexMap ) 1461  { 1462  // If we're not forward-contiguous (i.e. we're reverse or 1463  // out-of-order contiguous), re-order coordinates for handles 1464  // so that they are 1465  if( -1 == contig || -2 == contig ) 1466  { 1467  // In case the arrays are large, do each coord separately 1468  std::vector< double > tmp_coords( entity->nodeCt ); 1469  for( unsigned int j = 0; j < 3; j++ ) 1470  { 1471  // Permute the coords into new order 1472  for( unsigned int i = 0; i < entity->nodeCt; i++ ) 1473  { 1474  assert( uint_buf[i] >= min_cid && max_cid - uint_buf[i] < entity->nodeCt ); 1475  tmp_coords[uint_buf[i] - min_cid] = arrays[j][i]; 1476  } 1477  // Copy the permuted to storage 1478  std::copy( &tmp_coords[0], &tmp_coords[0] + entity->nodeCt, arrays[j] ); 1479  } 1480  // Now re-order the ids; either way just go off min, max cid 1481  for( unsigned int i = 0; i < entity->nodeCt; i++ ) 1482  uint_buf[i] = min_cid + i; 1483  } 1484  else if( !contig ) 1485  // Shouldn't get here, since in non-contiguous case map should be there 1486  assert( false ); 1487  } 1488  else 1489  { 1490  // Put new vertices into the map 1491  // Now set the new values 1492  unsigned int* vit = &uint_buf[0]; 1493  Range::iterator rit = dum_range.begin(); 1494  for( ; rit != dum_range.end(); vit++, ++rit ) 1495  { 1496  assert( *vit < cubMOABVertexMap->size() ); 1497  ( *cubMOABVertexMap )[*vit] = *rit; 1498  } 1499  } 1500  1501  // No longer need to use uint_buf; convert in-place to ints, so we 1502  // can assign gid tag 1503  CONVERT_TO_INTS( entity->nodeCt ); 1504  result = mdbImpl->tag_set_data( globalIdTag, dum_range, &int_buf[0] ); 1505  if( MB_SUCCESS != result ) return result; 1506  1507  // Set the dimension to at least zero (entity has at least nodes) on the geom tag 1508  int max_dim = 0; 1509  result = mdbImpl->tag_set_data( geomTag, &( entity->setHandle ), 1, &max_dim ); 1510  if( MB_SUCCESS != result ) return result; 1511  // Set the category tag just in case there're only vertices in this set 1512  result = mdbImpl->tag_set_data( categoryTag, &entity->setHandle, 1, &geom_categories[0] ); 1513  if( MB_SUCCESS != result ) return result; 1514  1515  // Get fixed node data and assign 1516  int md_index = model->nodeMD.get_md_entry( gindex, "FixedNodes" ); 1517  if( -1 == md_index ) return MB_SUCCESS; 1518  MetaDataContainer::MetaDataEntry* md_entry = &( model->nodeMD.metadataEntries[md_index] ); 1519  1520  std::vector< int > fixed_flags( entity->nodeCt ); 1521  std::fill( fixed_flags.begin(), fixed_flags.end(), 0 ); 1522  if( md_entry->mdDataType != 3 ) return MB_FAILURE; 1523  1524  for( std::vector< unsigned int >::iterator vit = md_entry->mdIntArrayValue.begin(); 1525  vit != md_entry->mdIntArrayValue.end(); ++vit ) 1526  { 1527 #ifndef NDEBUG 1528  EntityHandle fixed_v = 1529  ( cubMOABVertexMap ? ( *cubMOABVertexMap )[*vit] : (EntityHandle)currVHandleOffset + *vit ); 1530  assert( fixed_v >= *dum_range.begin() && fixed_v <= *dum_range.rbegin() ); 1531 #endif 1532  fixed_flags[*vit - *dum_range.begin()] = 1; 1533  } 1534  1535  Tag fixedFlagTag; 1536  int dum_val = 0; 1537  result = mdbImpl->tag_get_handle( "NodeFixed", 1, MB_TYPE_INTEGER, fixedFlagTag, MB_TAG_SPARSE | MB_TAG_CREAT, 1538  &dum_val ); 1539  if( MB_SUCCESS != result ) return result; 1540  result = mdbImpl->tag_set_data( fixedFlagTag, dum_range, &fixed_flags[0] ); 1541  1542  return result; 1543 } 1544  1545 ErrorCode Tqdcfr::read_elements( Tqdcfr::ModelEntry* model, Tqdcfr::GeomHeader* entity ) 1546 { 1547  if( entity->elemTypeCt == 0 ) return MB_SUCCESS; 1548  const int in_order_map[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1549  14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27 }; 1550  1551  // Get data in separate calls to minimize memory usage 1552  // Position the file 1553  FSEEK( model->modelOffset + entity->elemOffset ); 1554  1555  int int_type, nodes_per_elem, num_elem; 1556  int max_dim = -1; 1557  ErrorCode result; 1558  for( unsigned int i = 0; i < entity->elemTypeCt; i++ ) 1559  { 1560  // For this elem type, get the type, nodes per elem, num elems 1561  FREADI( 3 ); 1562  int_type = uint_buf[0]; 1563  nodes_per_elem = uint_buf[1]; 1564  num_elem = uint_buf[2]; 1565  1566  // Get MB element type from cub file's 1567  EntityType elem_type = mp_type_to_mb_type[int_type]; 1568  max_dim = ( max_dim < CN::Dimension( elem_type ) ? CN::Dimension( elem_type ) : max_dim ); 1569  1570  if( debug ) std::cout << "type " << CN::EntityTypeName( elem_type ) << ":"; 1571  1572  const int* node_order = cub_elem_order_map[elem_type][nodes_per_elem]; 1573  if( !node_order ) node_order = in_order_map; 1574  1575  // Get element ids 1576  FREADI( num_elem ); 1577  1578  // Check to see if ids are contiguous... 1579  int contig; 1580  unsigned int max_id, min_id; 1581  check_contiguous( num_elem, contig, min_id, max_id ); 1582  if( 0 == contig && !printedElemWarning ) 1583  { 1584  std::cout << "Element ids are not contiguous!" << std::endl; 1585  printedElemWarning = true; 1586  } 1587  1588  // Get a space for reading connectivity data directly into MB 1589  EntityHandle *conn, start_handle; 1590  1591  result = readUtilIface->get_element_connect( num_elem, nodes_per_elem, elem_type, int_buf[0], start_handle, 1592  conn, SequenceManager::DEFAULT_ELEMENT_SEQUENCE_SIZE ); 1593  if( MB_SUCCESS != result ) return result; 1594  1595  Range dum_range( start_handle, start_handle + num_elem - 1 ); 1596  1597  long elem_offset; 1598  elem_offset = ( 1 == contig ? start_handle - int_buf[0] : int_buf[num_elem - 1] ); 1599  if( -1 == currElementIdOffset[elem_type] ) currElementIdOffset[elem_type] = elem_offset; 1600  1601  // Set the gids on elements 1602  CONVERT_TO_INTS( num_elem ); 1603  result = mdbImpl->tag_set_data( globalIdTag, dum_range, &int_buf[0] ); 1604  if( MB_SUCCESS != result ) return result; 1605  1606  // Get the connectivity array 1607  unsigned int total_conn = num_elem * nodes_per_elem; 1608  if( major >= 14 ) FREADI( num_elem ); // We need to skip num_elem in advance, it looks like 1609  FREADI( total_conn ); 1610  1611  // Post-process connectivity into handles 1612  EntityHandle new_handle; 1613  int j = 0; 1614  for( int e = 0; e < num_elem; ++e ) 1615  { 1616  for( int k = 0; k < nodes_per_elem; ++k, ++j ) 1617  { 1618  if( debug ) 1619  { 1620  if( 0 == j ) std::cout << "Conn="; 1621  std::cout << ", " << uint_buf[j]; 1622  } 1623  if( NULL == cubMOABVertexMap ) 1624  new_handle = (EntityHandle)currVHandleOffset + uint_buf[j]; 1625  else 1626  { 1627  assert( uint_buf[j] < cubMOABVertexMap->size() && 0 != ( *cubMOABVertexMap )[uint_buf[j]] ); 1628  new_handle = ( *cubMOABVertexMap )[uint_buf[j]]; 1629  } 1630 #ifndef NDEBUG 1631  EntityHandle dum_handle; 1632  assert( MB_SUCCESS == 1633  mdbImpl->handle_from_id( MBVERTEX, mdbImpl->id_from_handle( new_handle ), dum_handle ) ); 1634 #endif 1635  conn[e * nodes_per_elem + node_order[k]] = new_handle; 1636  } 1637  } 1638  1639  // Add these elements into the entity's set 1640  result = mdbImpl->add_entities( entity->setHandle, dum_range ); 1641  if( MB_SUCCESS != result ) return result; 1642  1643  // Notify MOAB of the new elements 1644  result = readUtilIface->update_adjacencies( start_handle, num_elem, nodes_per_elem, conn ); 1645  if( MB_SUCCESS != result ) return result; 1646  } 1647  1648  // Set the dimension on the geom tag 1649  result = mdbImpl->tag_set_data( geomTag, &entity->setHandle, 1, &max_dim ); 1650  if( MB_SUCCESS != result ) return result; 1651  if( max_dim != -1 ) 1652  { 1653  result = mdbImpl->tag_set_data( categoryTag, &entity->setHandle, 1, &geom_categories[max_dim] ); 1654  if( MB_SUCCESS != result ) return result; 1655  } 1656  1657  return MB_SUCCESS; 1658 } 1659  1660 void Tqdcfr::check_contiguous( const unsigned int num_ents, int& contig, unsigned int& min_id, unsigned int& max_id ) 1661 { 1662  unsigned int *id_it, curr_id, i; 1663  1664  // Check in forward-contiguous direction 1665  id_it = &uint_buf[0]; 1666  curr_id = *id_it++ + 1; 1667  contig = 1; 1668  min_id = uint_buf[0]; 1669  max_id = uint_buf[0]; 1670  for( i = 1; i < num_ents; id_it++, i++, curr_id++ ) 1671  { 1672  if( *id_it != curr_id ) 1673  { 1674  contig = 0; 1675  } 1676  min_id = MIN( min_id, uint_buf[i] ); 1677  max_id = MAX( max_id, uint_buf[i] ); 1678  } 1679  1680  // If we got here and we're at the end of the loop, it's forward-contiguous 1681  if( 1 == contig ) return; 1682  1683  // Check in reverse-contiguous direction 1684  contig = -1; 1685  id_it = &uint_buf[0]; 1686  curr_id = *id_it++ - 1; 1687  for( i = 1; i < num_ents; id_it++, i++, curr_id-- ) 1688  { 1689  if( *id_it != curr_id ) 1690  { 1691  contig = 0; 1692  break; 1693  } 1694  } 1695  1696  // If we got here and we're at the end of the loop, it's reverse-contiguous 1697  if( -1 == contig ) return; 1698  1699  // One final check, for contiguous but out of order 1700  if( max_id - min_id + 1 == num_ents ) contig = -2; 1701  1702  // Else it's not contiguous at all 1703  contig = 0; 1704 } 1705  1706 void Tqdcfr::FEModelHeader::init( const unsigned int offset, Tqdcfr* instance ) 1707 { 1708  instance->FSEEK( offset ); 1709  instance->FREADI( 4 ); 1710  feEndian = instance->uint_buf[0]; 1711  feSchema = instance->uint_buf[1]; 1712  feCompressFlag = instance->uint_buf[2]; 1713  feLength = instance->uint_buf[3]; 1714  instance->FREADI( 3 ); 1715  geomArray.init( instance->uint_buf ); 1716  instance->FREADI( 2 ); 1717  nodeArray.metaDataOffset = instance->uint_buf[0]; 1718  elementArray.metaDataOffset = instance->uint_buf[1]; 1719  instance->FREADI( 3 ); 1720  groupArray.init( instance->uint_buf ); 1721  instance->FREADI( 3 ); 1722  blockArray.init( instance->uint_buf ); 1723  instance->FREADI( 3 ); 1724  nodesetArray.init( instance->uint_buf ); 1725  instance->FREADI( 3 ); 1726  sidesetArray.init( instance->uint_buf ); 1727  instance->FREADI( 1 ); 1728 } 1729  1730 ErrorCode Tqdcfr::read_file_header() 1731 { 1732  // Read file header 1733  FSEEK( 4 ); 1734  // Read the first int from the file 1735  // If it is 0, it is littleEndian 1736  unsigned rval = fread( &fileTOC.fileEndian, sizeof( unsigned int ), 1, cubFile ); 1737  IO_ASSERT( rval == 1 ); 1738 #ifdef WORDS_BIGENDIAN 1739  if( fileTOC.fileEndian == 0 ) swapForEndianness = true; 1740 #else 1741  if( fileTOC.fileEndian != 0 ) swapForEndianness = true; 1742 #endif 1743  if( debug ) std::cout << " swapping ? " << swapForEndianness << "\n"; 1744  FREADI( 5 ); 1745  // fileTOC.fileEndian = uint_buf[0]; 1746  fileTOC.fileSchema = uint_buf[0]; 1747  fileTOC.numModels = uint_buf[1]; 1748  fileTOC.modelTableOffset = uint_buf[2]; 1749  fileTOC.modelMetaDataOffset = uint_buf[3]; 1750  fileTOC.activeFEModel = uint_buf[4]; 1751  if( debug ) fileTOC.print(); 1752  1753  return MB_SUCCESS; 1754 } 1755  1756 ErrorCode Tqdcfr::read_model_entries() 1757 { 1758  // Read model entries 1759  FSEEK( fileTOC.modelTableOffset ); 1760  FREADI( fileTOC.numModels * 6 ); 1761  modelEntries.resize( fileTOC.numModels ); 1762  if( modelEntries.empty() ) return MB_FAILURE; 1763  std::vector< unsigned int >::iterator int_it = uint_buf.begin(); 1764  for( unsigned int i = 0; i < fileTOC.numModels; i++ ) 1765  { 1766  modelEntries[i].modelHandle = *int_it++; 1767  modelEntries[i].modelOffset = *int_it++; 1768  modelEntries[i].modelLength = *int_it++; 1769  modelEntries[i].modelType = *int_it++; 1770  modelEntries[i].modelOwner = *int_it++; 1771  modelEntries[i].modelPad = *int_it++; 1772  if( int_it == uint_buf.end() && i != fileTOC.numModels - 1 ) return MB_FAILURE; 1773  if( debug ) modelEntries[i].print(); 1774  } 1775  1776  return MB_SUCCESS; 1777 } 1778  1779 int Tqdcfr::find_model( const unsigned int model_type ) 1780 { 1781  for( unsigned int i = 0; i < fileTOC.numModels; i++ ) 1782  { 1783  if( modelEntries[i].modelType == model_type ) return i; 1784  } 1785  1786  return -1; 1787 } 1788  1789 ErrorCode Tqdcfr::read_meta_data( const unsigned int metadata_offset, Tqdcfr::MetaDataContainer& mc ) 1790 { 1791  // Read the metadata header 1792  FSEEK( metadata_offset ); 1793  FREADI( 3 ); 1794  mc.mdSchema = uint_buf[0]; 1795  mc.compressFlag = uint_buf[1]; 1796  1797  // Allocate space for the entries 1798  mc.metadataEntries.resize( uint_buf[2] ); 1799  1800  // Now read the metadata values 1801  for( unsigned int i = 0; i < mc.metadataEntries.size(); i++ ) 1802  { 1803  FREADI( 2 ); 1804  mc.metadataEntries[i].mdOwner = uint_buf[0]; 1805  mc.metadataEntries[i].mdDataType = uint_buf[1]; 1806  1807  // Read the name string 1808  read_md_string( mc.metadataEntries[i].mdName ); 1809  1810  if( mc.metadataEntries[i].mdDataType == 0 ) 1811  { 1812  // integer 1813  FREADI( 1 ); 1814  mc.metadataEntries[i].mdIntValue = uint_buf[0]; 1815  } 1816  else if( mc.metadataEntries[i].mdDataType == 1 ) 1817  { 1818  // string 1819  read_md_string( mc.metadataEntries[i].mdStringValue ); 1820  } 1821  else if( mc.metadataEntries[i].mdDataType == 2 ) 1822  { 1823  // double 1824  FREADD( 1 ); 1825  mc.metadataEntries[i].mdDblValue = dbl_buf[0]; 1826  } 1827  else if( mc.metadataEntries[i].mdDataType == 3 ) 1828  { 1829  // int array 1830  FREADI( 1 ); 1831  mc.metadataEntries[i].mdIntArrayValue.resize( uint_buf[0] ); 1832  FREADI( mc.metadataEntries[i].mdIntArrayValue.size() ); 1833  std::copy( uint_buf.begin(), uint_buf.begin() + mc.metadataEntries[i].mdIntArrayValue.size(), 1834  mc.metadataEntries[i].mdIntArrayValue.begin() ); 1835  } 1836  else if( mc.metadataEntries[i].mdDataType == 4 ) 1837  { 1838  // double array 1839  FREADI( 1 ); 1840  mc.metadataEntries[i].mdDblArrayValue.resize( uint_buf[0] ); 1841  FREADD( mc.metadataEntries[i].mdDblArrayValue.size() ); 1842  std::copy( dbl_buf.begin(), dbl_buf.begin() + mc.metadataEntries[i].mdDblArrayValue.size(), 1843  mc.metadataEntries[i].mdDblArrayValue.begin() ); 1844  } 1845  else 1846  return MB_FAILURE; 1847  } 1848  if( debug ) mc.print(); 1849  1850  return MB_SUCCESS; 1851 } 1852  1853 ErrorCode Tqdcfr::read_md_string( std::string& name ) 1854 { 1855  FREADI( 1 ); 1856  int str_size = uint_buf[0]; 1857  if( str_size > 0 ) 1858  { 1859  FREADC( str_size ); 1860  if( char_buf.size() <= (unsigned int)str_size ) char_buf.resize( str_size + 1 ); 1861  char_buf[str_size] = '\0'; 1862  name = (char*)&char_buf[0]; 1863  // Read pad if any 1864  int extra = str_size % sizeof( int ); 1865  if( extra ) 1866  { 1867  // Read extra chars to end of pad 1868  str_size = sizeof( int ) - extra; 1869  FREADC( str_size ); 1870  } 1871  } 1872  1873  return MB_SUCCESS; 1874 } 1875  1876 ErrorCode Tqdcfr::GeomHeader::read_info_header( const unsigned int model_offset, 1877  const Tqdcfr::FEModelHeader::ArrayInfo& info, 1878  Tqdcfr* instance, 1879  Tqdcfr::GeomHeader*& geom_headers ) 1880 { 1881  geom_headers = new GeomHeader[info.numEntities]; 1882  instance->FSEEK( model_offset + info.tableOffset ); 1883  int dum_int; 1884  ErrorCode result; 1885  1886  if( 0 == instance->categoryTag ) 1887  { 1888  static const char val[CATEGORY_TAG_SIZE] = { 0 }; 1889  result = instance->mdbImpl->tag_get_handle( CATEGORY_TAG_NAME, CATEGORY_TAG_SIZE, MB_TYPE_OPAQUE, 1890  instance->categoryTag, MB_TAG_SPARSE | MB_TAG_CREAT, val ); 1891  if( MB_SUCCESS != result ) return result; 1892  } 1893  1894  for( unsigned int i = 0; i < info.numEntities; i++ ) 1895  { 1896  instance->FREADI( 8 ); 1897  geom_headers[i].nodeCt = instance->uint_buf[0]; 1898  geom_headers[i].nodeOffset = instance->uint_buf[1]; 1899  geom_headers[i].elemCt = instance->uint_buf[2]; 1900  geom_headers[i].elemOffset = instance->uint_buf[3]; 1901  geom_headers[i].elemTypeCt = instance->uint_buf[4]; 1902  geom_headers[i].elemLength = instance->uint_buf[5]; 1903  geom_headers[i].geomID = instance->uint_buf[6]; 1904  1905  // Don't represent in MOAB if no mesh 1906  if( geom_headers[i].nodeCt == 0 && geom_headers[i].elemCt == 0 ) continue; 1907  1908  // Create an entity set for this entity 1909  result = instance->create_set( geom_headers[i].setHandle ); 1910  if( MB_SUCCESS != result ) return result; 1911  1912  // Set the dimension to -1; will have to reset later, after elements are read 1913  dum_int = -1; 1914  result = instance->mdbImpl->tag_set_data( instance->geomTag, &( geom_headers[i].setHandle ), 1, &dum_int ); 1915  if( MB_SUCCESS != result ) return result; 1916  1917  // Set a unique id tag 1918  result = instance->mdbImpl->tag_set_data( instance->uniqueIdTag, &( geom_headers[i].setHandle ), 1, 1919  &( geom_headers[i].geomID ) ); 1920  if( MB_SUCCESS != result ) return result; 1921  1922  // Put the set and uid into a map for later 1923  instance->uidSetMap[geom_headers[i].geomID] = geom_headers[i].setHandle; 1924  } 1925  1926  // Now get the dimensions of elements for each geom entity 1927  for( unsigned int i = 0; i < info.numEntities; i++ ) 1928  { 1929  if( geom_headers[i].elemTypeCt == 0 ) continue; 1930  instance->FSEEK( model_offset + geom_headers[i].elemOffset ); 1931  for( unsigned int j = 0; j < geom_headers[i].elemTypeCt; j++ ) 1932  { 1933  // For this elem type, get the type, nodes per elem, num elems 1934  instance->FREADI( 3 ); 1935  int int_type = instance->uint_buf[0]; 1936  int nodes_per_elem = instance->uint_buf[1]; 1937  int num_elem = instance->uint_buf[2]; 1938  EntityType elem_type = mp_type_to_mb_type[int_type]; 1939  geom_headers[i].maxDim = std::max( geom_headers[i].maxDim, (int)CN::Dimension( elem_type ) ); 1940  if( j < geom_headers[i].elemTypeCt - 1 ) 1941  { 1942  int num_skipped_ints = num_elem + num_elem * nodes_per_elem; 1943  if( major >= 14 ) num_skipped_ints += num_elem; 1944  instance->FREADI( num_skipped_ints ); 1945  } 1946  } 1947  } 1948  1949  return MB_SUCCESS; 1950 } 1951  1952 ErrorCode Tqdcfr::GroupHeader::read_info_header( const unsigned int model_offset, 1953  const Tqdcfr::FEModelHeader::ArrayInfo& info, 1954  Tqdcfr* instance, 1955  Tqdcfr::GroupHeader*& group_headers ) 1956 { 1957  group_headers = new GroupHeader[info.numEntities]; 1958  instance->FSEEK( model_offset + info.tableOffset ); 1959  ErrorCode result; 1960  1961  if( 0 == instance->categoryTag ) 1962  { 1963  static const char val[CATEGORY_TAG_SIZE] = { 0 }; 1964  result = instance->mdbImpl->tag_get_handle( CATEGORY_TAG_NAME, CATEGORY_TAG_SIZE, MB_TYPE_OPAQUE, 1965  instance->categoryTag, MB_TAG_SPARSE | MB_TAG_CREAT, val ); 1966  if( MB_SUCCESS != result ) return result; 1967  } 1968  1969  for( unsigned int i = 0; i < info.numEntities; i++ ) 1970  { 1971  // Create an entity set for this entity 1972  result = instance->create_set( group_headers[i].setHandle ); 1973  if( MB_SUCCESS != result ) return result; 1974  static const char group_category[CATEGORY_TAG_SIZE] = "Group\0"; 1975  1976  instance->FREADI( 6 ); 1977  group_headers[i].grpID = instance->uint_buf[0]; 1978  group_headers[i].grpType = instance->uint_buf[1]; 1979  group_headers[i].memCt = instance->uint_buf[2]; 1980  group_headers[i].memOffset = instance->uint_buf[3]; 1981  group_headers[i].memTypeCt = instance->uint_buf[4]; 1982  group_headers[i].grpLength = instance->uint_buf[5]; 1983  1984  // Set the category tag to signify this is a group 1985  result = instance->mdbImpl->tag_set_data( instance->categoryTag, &( group_headers[i].setHandle ), 1, 1986  group_category ); 1987  if( MB_SUCCESS != result ) return result; 1988  1989  // Set a global id tag 1990  result = instance->mdbImpl->tag_set_data( instance->globalIdTag, &( group_headers[i].setHandle ), 1, 1991  &( group_headers[i].grpID ) ); 1992  if( MB_SUCCESS != result ) return result; 1993  1994  instance->gidSetMap[5][group_headers[i].grpID] = group_headers[i].setHandle; 1995  } 1996  1997  return MB_SUCCESS; 1998 } 1999  2000 ErrorCode Tqdcfr::BlockHeader::read_info_header( const double data_version, 2001  const unsigned int model_offset, 2002  const Tqdcfr::FEModelHeader::ArrayInfo& info, 2003  Tqdcfr* instance, 2004  Tqdcfr::BlockHeader*& block_headers ) 2005 { 2006  block_headers = new BlockHeader[info.numEntities]; 2007  instance->FSEEK( model_offset + info.tableOffset ); 2008  ErrorCode result; 2009  2010  if( 0 == instance->categoryTag ) 2011  { 2012  static const char val[CATEGORY_TAG_SIZE] = { 0 }; 2013  result = instance->mdbImpl->tag_get_handle( CATEGORY_TAG_NAME, CATEGORY_TAG_SIZE, MB_TYPE_OPAQUE, 2014  instance->categoryTag, MB_TAG_SPARSE | MB_TAG_CREAT, val ); 2015  if( MB_SUCCESS != result && MB_ALREADY_ALLOCATED != result ) return result; 2016  } 2017  2018  for( unsigned int i = 0; i < info.numEntities; i++ ) 2019  { 2020  // Create an entity set for this entity 2021  result = instance->create_set( block_headers[i].setHandle ); 2022  if( MB_SUCCESS != result ) return result; 2023  static const char material_category[CATEGORY_TAG_SIZE] = "Material Set\0"; 2024  2025  instance->FREADI( 12 ); 2026  block_headers[i].blockID = instance->uint_buf[0]; 2027  block_headers[i].blockElemType = instance->uint_buf[1]; 2028  block_headers[i].memCt = instance->uint_buf[2]; 2029  block_headers[i].memOffset = instance->uint_buf[3]; 2030  block_headers[i].memTypeCt = instance->uint_buf[4]; 2031  block_headers[i].attribOrder = instance->uint_buf[5]; // Attrib order 2032  block_headers[i].blockCol = instance->uint_buf[6]; 2033  block_headers[i].blockMixElemType = instance->uint_buf[7]; // Mixed elem type 2034  block_headers[i].blockPyrType = instance->uint_buf[8]; 2035  block_headers[i].blockMat = instance->uint_buf[9]; 2036  block_headers[i].blockLength = instance->uint_buf[10]; 2037  block_headers[i].blockDim = instance->uint_buf[11]; 2038  2039  Tag bhTag_header; 2040  { 2041  std::vector< int > def_uint_zero( 3, 0 ); 2042  result = instance->mdbImpl->tag_get_handle( BLOCK_HEADER, 3 * sizeof( unsigned int ), MB_TYPE_INTEGER, 2043  bhTag_header, MB_TAG_CREAT | MB_TAG_SPARSE | MB_TAG_BYTES, 2044  &def_uint_zero[0] ); 2045  if( MB_SUCCESS != result ) return result; 2046  int block_header_data[] = { static_cast< int >( block_headers[i].blockCol ), 2047  static_cast< int >( block_headers[i].blockMat ), 2048  static_cast< int >( block_headers[i].blockDim ) }; 2049  result = 2050  instance->mdbImpl->tag_set_data( bhTag_header, &( block_headers[i].setHandle ), 1, block_header_data ); 2051  } 2052  2053  if( MB_SUCCESS != result ) return result; 2054  2055  // Adjust element type for data version; older element types didn't include 2056  // 4 new trishell element types 2057  if( data_version <= 1.0 && block_headers[i].blockElemType >= 15 ) block_headers[i].blockElemType += 4; 2058  2059  if( block_headers[i].blockElemType >= (unsigned)cub_elem_num_verts_len ) 2060  { 2061  // Block element type unassigned, will have to infer from verts/element; make sure it's 2062  // the expected value of 52 2063  if( ( 14 == major && 2 < minor ) || 15 <= major ) 2064  { 2065  if( 55 != block_headers[i].blockElemType ) 2066  MB_SET_ERR( MB_FAILURE, "Invalid block element type: " << block_headers[i].blockElemType ); 2067  } 2068  else 2069  { 2070  if( 52 != block_headers[i].blockElemType ) 2071  MB_SET_ERR( MB_FAILURE, "Invalid block element type: " << block_headers[i].blockElemType ); 2072  } 2073  } 2074  2075  // Set the material set tag and id tag both to id 2076  result = instance->mdbImpl->tag_set_data( instance->blockTag, &( block_headers[i].setHandle ), 1, 2077  &( block_headers[i].blockID ) ); 2078  if( MB_SUCCESS != result ) return result; 2079  result = instance->mdbImpl->tag_set_data( instance->globalIdTag, &( block_headers[i].setHandle ), 1, 2080  &( block_headers[i].blockID ) ); 2081  if( MB_SUCCESS != result ) return result; 2082  result = instance->mdbImpl->tag_set_data( instance->categoryTag, &( block_headers[i].setHandle ), 1, 2083  material_category ); 2084  if( MB_SUCCESS != result ) return result; 2085  2086  // If this block is empty, continue 2087  if( !block_headers[i].memCt ) continue; 2088  2089  // Check the number of vertices in the element type, and set the has mid nodes tag 2090  // accordingly; if element type wasn't set, they're unlikely to have mid nodes 2091  // 52 is for CUBIT versions below 14.1, 55 for CUBIT version 14.9 and above 2092  if( 52 != block_headers[i].blockElemType && 55 != block_headers[i].blockElemType ) 2093  { 2094  int num_verts = cub_elem_num_verts[block_headers[i].blockElemType]; 2095  block_headers[i].blockEntityType = block_type_to_mb_type[block_headers[i].blockElemType]; 2096  if( ( block_headers[i].blockEntityType < MBMAXTYPE ) && 2097  ( num_verts != CN::VerticesPerEntity( block_headers[i].blockEntityType ) ) ) 2098  { 2099  // Not a linear element; try to find hasMidNodes values 2100  for( int j = 0; j < 4; j++ ) 2101  block_headers[i].hasMidNodes[j] = 0; 2102  if( 0 == instance->hasMidNodesTag ) 2103  { 2104  result = instance->mdbImpl->tag_get_handle( HAS_MID_NODES_TAG_NAME, 4, MB_TYPE_INTEGER, 2105  instance->hasMidNodesTag, MB_TAG_SPARSE | MB_TAG_CREAT, 2106  block_headers[i].hasMidNodes ); 2107  if( MB_SUCCESS != result ) return result; 2108  } 2109  2110  CN::HasMidNodes( block_headers[i].blockEntityType, num_verts, block_headers[i].hasMidNodes ); 2111  2112  // Now set the tag on this set 2113  result = instance->mdbImpl->tag_set_data( instance->hasMidNodesTag, &block_headers[i].setHandle, 1, 2114  block_headers[i].hasMidNodes ); 2115  if( MB_SUCCESS != result ) return result; 2116  } 2117  } 2118  } 2119  2120  return MB_SUCCESS; 2121 } 2122  2123 ErrorCode Tqdcfr::NodesetHeader::read_info_header( const unsigned int model_offset, 2124  const Tqdcfr::FEModelHeader::ArrayInfo& info, 2125  Tqdcfr* instance, 2126  Tqdcfr::NodesetHeader*& nodeset_headers ) 2127 { 2128  nodeset_headers = new NodesetHeader[info.numEntities]; 2129  instance->FSEEK( model_offset + info.tableOffset ); 2130  ErrorCode result; 2131  2132  if( 0 == instance->categoryTag ) 2133  { 2134  static const char val[CATEGORY_TAG_SIZE] = { 0 }; 2135  result = instance->mdbImpl->tag_get_handle( CATEGORY_TAG_NAME, CATEGORY_TAG_SIZE, MB_TYPE_OPAQUE, 2136  instance->categoryTag, MB_TAG_SPARSE | MB_TAG_CREAT, val ); 2137  if( MB_SUCCESS != result ) return result; 2138  } 2139  2140  for( unsigned int i = 0; i < info.numEntities; i++ ) 2141  { 2142  // Create an entity set for this entity 2143  result = instance->create_set( nodeset_headers[i].setHandle ); 2144  if( MB_SUCCESS != result ) return result; 2145  static const char dirichlet_category[CATEGORY_TAG_SIZE] = "Dirichlet Set\0"; 2146  2147  instance->FREADI( 8 ); 2148  nodeset_headers[i].nsID = instance->uint_buf[0]; 2149  nodeset_headers[i].memCt = instance->uint_buf[1]; 2150  nodeset_headers[i].memOffset = instance->uint_buf[2]; 2151  nodeset_headers[i].memTypeCt = instance->uint_buf[3]; 2152  nodeset_headers[i].pointSym = instance->uint_buf[4]; // Point sym 2153  nodeset_headers[i].nsCol = instance->uint_buf[5]; 2154  nodeset_headers[i].nsLength = instance->uint_buf[6]; 2155  // Pad 2156  2157  // Set the dirichlet set tag and id tag both to id 2158  result = instance->mdbImpl->tag_set_data( instance->nsTag, &( nodeset_headers[i].setHandle ), 1, 2159  &( nodeset_headers[i].nsID ) ); 2160  if( MB_SUCCESS != result ) return result; 2161  result = instance->mdbImpl->tag_set_data( instance->globalIdTag, &( nodeset_headers[i].setHandle ), 1, 2162  &( nodeset_headers[i].nsID ) ); 2163  if( MB_SUCCESS != result ) return result; 2164  result = instance->mdbImpl->tag_set_data( instance->categoryTag, &( nodeset_headers[i].setHandle ), 1, 2165  dirichlet_category ); 2166  if( MB_SUCCESS != result ) return result; 2167  } 2168  2169  return MB_SUCCESS; 2170 } 2171  2172 ErrorCode Tqdcfr::SidesetHeader::read_info_header( const unsigned int model_offset, 2173  const Tqdcfr::FEModelHeader::ArrayInfo& info, 2174  Tqdcfr* instance, 2175  Tqdcfr::SidesetHeader*& sideset_headers ) 2176 { 2177  sideset_headers = new SidesetHeader[info.numEntities]; 2178  instance->FSEEK( model_offset + info.tableOffset ); 2179  ErrorCode result; 2180  2181  if( 0 == instance->categoryTag ) 2182  { 2183  static const char val[CATEGORY_TAG_SIZE] = { 0 }; 2184  result = instance->mdbImpl->tag_get_handle( CATEGORY_TAG_NAME, CATEGORY_TAG_SIZE, MB_TYPE_OPAQUE, 2185  instance->categoryTag, MB_TAG_SPARSE | MB_TAG_CREAT, val ); 2186  if( MB_SUCCESS != result ) return result; 2187  } 2188  2189  for( unsigned int i = 0; i < info.numEntities; i++ ) 2190  { 2191  // Create an entity set for this entity 2192  result = instance->create_set( sideset_headers[i].setHandle ); 2193  if( MB_SUCCESS != result ) return result; 2194  static const char neumann_category[CATEGORY_TAG_SIZE] = "Neumann Set\0"; 2195  2196  instance->FREADI( 8 ); 2197  sideset_headers[i].ssID = instance->uint_buf[0]; 2198  sideset_headers[i].memCt = instance->uint_buf[1]; 2199  sideset_headers[i].memOffset = instance->uint_buf[2]; 2200  sideset_headers[i].memTypeCt = instance->uint_buf[3]; 2201  sideset_headers[i].numDF = instance->uint_buf[4]; // Num dist factors 2202  sideset_headers[i].ssCol = instance->uint_buf[5]; 2203  sideset_headers[i].useShell = instance->uint_buf[6]; 2204  sideset_headers[i].ssLength = instance->uint_buf[7]; 2205  2206  // Set the neumann set tag and id tag both to id 2207  result = instance->mdbImpl->tag_set_data( instance->ssTag, &( sideset_headers[i].setHandle ), 1, 2208  &( sideset_headers[i].ssID ) ); 2209  if( MB_SUCCESS != result ) return result; 2210  result = instance->mdbImpl->tag_set_data( instance->globalIdTag, &( sideset_headers[i].setHandle ), 1, 2211  &( sideset_headers[i].ssID ) ); 2212  if( MB_SUCCESS != result ) return result; 2213  result = instance->mdbImpl->tag_set_data( instance->categoryTag, &( sideset_headers[i].setHandle ), 1, 2214  neumann_category ); 2215  if( MB_SUCCESS != result ) return result; 2216  } 2217  2218  return MB_SUCCESS; 2219 } 2220  2221 void Tqdcfr::ModelEntry::print_geom_headers( const char* prefix, GeomHeader* header, const unsigned int num_headers ) 2222 { 2223  if( !debug ) return; 2224  std::cout << prefix << std::endl; 2225  if( NULL != header ) 2226  { 2227  for( unsigned int i = 0; i < num_headers; i++ ) 2228  { 2229  std::cout << "Index " << i << std::endl; 2230  header[i].print(); 2231  } 2232  } 2233 } 2234  2235 void Tqdcfr::ModelEntry::print_group_headers( const char* prefix, GroupHeader* header, const unsigned int num_headers ) 2236 { 2237  if( !debug ) return; 2238  std::cout << prefix << std::endl; 2239  if( NULL != header ) 2240  { 2241  for( unsigned int i = 0; i < num_headers; i++ ) 2242  header[i].print(); 2243  } 2244 } 2245  2246 void Tqdcfr::ModelEntry::print_block_headers( const char* prefix, BlockHeader* header, const unsigned int num_headers ) 2247 { 2248  if( !debug ) return; 2249  std::cout << prefix << std::endl; 2250  if( NULL != header ) 2251  { 2252  for( unsigned int i = 0; i < num_headers; i++ ) 2253  header[i].print(); 2254  } 2255 } 2256  2257 void Tqdcfr::ModelEntry::print_nodeset_headers( const char* prefix, 2258  NodesetHeader* header, 2259  const unsigned int num_headers ) 2260 { 2261  if( !debug ) return; 2262  std::cout << prefix << std::endl; 2263  if( NULL != header ) 2264  { 2265  for( unsigned int i = 0; i < num_headers; i++ ) 2266  header[i].print(); 2267  } 2268 } 2269  2270 void Tqdcfr::ModelEntry::print_sideset_headers( const char* prefix, 2271  SidesetHeader* header, 2272  const unsigned int num_headers ) 2273 { 2274  if( !debug ) return; 2275  std::cout << prefix << std::endl; 2276  if( NULL != header ) 2277  { 2278  for( unsigned int i = 0; i < num_headers; i++ ) 2279  header[i].print(); 2280  } 2281 } 2282  2283 ErrorCode Tqdcfr::ModelEntry::read_header_info( Tqdcfr* instance, const double data_version ) 2284 { 2285  feModelHeader.init( modelOffset, instance ); 2286  int negone = -1; 2287  ErrorCode result; 2288  instance->globalIdTag = instance->mdbImpl->globalId_tag(); 2289  2290  if( feModelHeader.geomArray.numEntities > 0 ) 2291  { 2292  result = instance->mdbImpl->tag_get_handle( GEOM_DIMENSION_TAG_NAME, 1, MB_TYPE_INTEGER, instance->geomTag, 2293  MB_TAG_SPARSE | MB_TAG_CREAT, &negone ); 2294  if( MB_SUCCESS != result ) return result; 2295  2296  result = instance->mdbImpl->tag_get_handle( "UNIQUE_ID", 1, MB_TYPE_INTEGER, instance->uniqueIdTag, 2297  MB_TAG_SPARSE | MB_TAG_CREAT, &negone ); 2298  if( MB_SUCCESS != result ) return result; 2299  2300  result = Tqdcfr::GeomHeader::read_info_header( modelOffset, feModelHeader.geomArray, instance, feGeomH ); 2301  print_geom_headers( "Geom headers:", feGeomH, feModelHeader.geomArray.numEntities ); 2302  if( MB_SUCCESS != result ) return result; 2303  } 2304  2305  if( feModelHeader.groupArray.numEntities > 0 ) 2306  { 2307  result = Tqdcfr::GroupHeader::read_info_header( modelOffset, feModelHeader.groupArray, instance, feGroupH ); 2308  print_group_headers( "Group headers:", feGroupH, feModelHeader.groupArray.numEntities ); 2309  if( MB_SUCCESS != result ) return result; 2310  } 2311  2312  if( feModelHeader.blockArray.numEntities > 0 ) 2313  { 2314  result = instance->mdbImpl->tag_get_handle( MATERIAL_SET_TAG_NAME, 1, MB_TYPE_INTEGER, instance->blockTag, 2315  MB_TAG_SPARSE | MB_TAG_CREAT, &negone ); 2316  if( MB_SUCCESS != result ) return result; 2317  2318  result = Tqdcfr::BlockHeader::read_info_header( data_version, modelOffset, feModelHeader.blockArray, instance, 2319  feBlockH ); 2320  print_block_headers( "Block headers:", feBlockH, feModelHeader.blockArray.numEntities ); 2321  if( MB_SUCCESS != result ) return result; 2322  } 2323  if( feModelHeader.nodesetArray.numEntities > 0 ) 2324  { 2325  result = instance->mdbImpl->tag_get_handle( DIRICHLET_SET_TAG_NAME, 1, MB_TYPE_INTEGER, instance->nsTag, 2326  MB_TAG_SPARSE | MB_TAG_CREAT, &negone ); 2327  if( MB_SUCCESS != result ) return result; 2328  2329  result = 2330  Tqdcfr::NodesetHeader::read_info_header( modelOffset, feModelHeader.nodesetArray, instance, feNodeSetH ); 2331  if( MB_SUCCESS != result ) return result; 2332  print_nodeset_headers( "Nodeset headers:", feNodeSetH, feModelHeader.nodesetArray.numEntities ); 2333  } 2334  if( feModelHeader.sidesetArray.numEntities > 0 ) 2335  { 2336  result = instance->mdbImpl->tag_get_handle( NEUMANN_SET_TAG_NAME, 1, MB_TYPE_INTEGER, instance->ssTag, 2337  MB_TAG_SPARSE | MB_TAG_CREAT, &negone ); 2338  if( MB_SUCCESS != result ) return result; 2339  2340  result = 2341  Tqdcfr::SidesetHeader::read_info_header( modelOffset, feModelHeader.sidesetArray, instance, feSideSetH ); 2342  print_sideset_headers( "SideSet headers:", feSideSetH, feModelHeader.sidesetArray.numEntities ); 2343  } 2344  2345  return MB_SUCCESS; 2346 } 2347  2348 ErrorCode Tqdcfr::ModelEntry::read_metadata_info( Tqdcfr* tqd ) 2349 { 2350  if( debug ) std::cout << "Geom metadata:" << std::endl; 2351  tqd->read_meta_data( modelOffset + feModelHeader.geomArray.metaDataOffset, geomMD ); 2352  if( debug ) std::cout << "Node metadata:" << std::endl; 2353  tqd->read_meta_data( modelOffset + feModelHeader.nodeArray.metaDataOffset, nodeMD ); 2354  if( debug ) std::cout << "Elem metadata:" << std::endl; 2355  tqd->read_meta_data( modelOffset + feModelHeader.elementArray.metaDataOffset, elementMD ); 2356  if( debug ) std::cout << "Group metadata:" << std::endl; 2357  tqd->read_meta_data( modelOffset + feModelHeader.groupArray.metaDataOffset, groupMD ); 2358  if( debug ) std::cout << "Block metadata:" << std::endl; 2359  tqd->read_meta_data( modelOffset + feModelHeader.blockArray.metaDataOffset, blockMD ); 2360  if( debug ) std::cout << "Nodeset metadata:" << std::endl; 2361  tqd->read_meta_data( modelOffset + feModelHeader.nodesetArray.metaDataOffset, nodesetMD ); 2362  if( debug ) std::cout << "Sideset metadata:" << std::endl; 2363  tqd->read_meta_data( modelOffset + feModelHeader.sidesetArray.metaDataOffset, sidesetMD ); 2364  2365  return MB_SUCCESS; 2366 } 2367  2368 ErrorCode Tqdcfr::read_acis_records( const char* sat_filename ) 2369 { 2370  // Get the acis model location 2371  unsigned int acis_model_offset = 0, acis_model_length = 0, acis_model_handle = 1, acis_sat_type = 1; 2372  for( unsigned int i = 0; i < fileTOC.numModels; i++ ) 2373  { 2374  if( modelEntries[i].modelHandle == acis_model_handle && modelEntries[i].modelType == acis_sat_type ) 2375  { 2376  acis_model_offset = modelEntries[i].modelOffset; 2377  acis_model_length = modelEntries[i].modelLength; 2378  break; 2379  } 2380  } 2381  2382  if( acis_model_length == 0 ) return MB_SUCCESS; 2383  2384  std::vector< AcisRecord > records; 2385  2386  acisDumpFile = NULL; 2387  if( sat_filename ) 2388  { 2389  acisDumpFile = fopen( sat_filename, "w+" ); 2390  if( NULL == acisDumpFile ) return MB_FAILURE; 2391  } 2392  2393  // Position the file at the start of the acis model 2394  FSEEK( acis_model_offset ); 2395  2396  unsigned int bytes_left = acis_model_length; 2397  2398  struct AcisRecord this_record; 2399  reset_record( this_record ); 2400  char* ret; 2401  2402  // Make the char buffer at least buf_size + 1 long, to fit null char 2403  const unsigned int buf_size = 1023; 2404  2405  // CHECK_SIZE(char_buf, buf_size + 1); 2406  char_buf.resize( buf_size + 1 ); 2407  2408  while( 0 != bytes_left ) 2409  { 2410  // Read the next buff characters, or bytes_left if smaller 2411  unsigned int next_buf = ( bytes_left > buf_size ? buf_size : bytes_left ); 2412  FREADC( next_buf ); 2413  2414  if( NULL != acisDumpFile ) fwrite( &char_buf[0], sizeof( char ), next_buf, acisDumpFile ); 2415  2416  // Put null at end of string to stop searches 2417  char_buf.resize( next_buf + 1 ); 2418  char_buf[next_buf] = '\0'; 2419  unsigned int buf_pos = 0; 2420  2421  // Check for first read, and if so, get rid of the header 2422  if( bytes_left == acis_model_length ) 2423  { 2424  // Look for 3 newlines 2425  ret = strchr( &( char_buf[0] ), '\n' ); 2426  ret = strchr( ret + 1, '\n' ); 2427  ret = strchr( ret + 1, '\n' ); 2428  if( NULL == ret ) return MB_FAILURE; 2429  buf_pos += ret - &( char_buf[0] ) + 1; 2430  } 2431  2432  bytes_left -= next_buf; 2433  2434  // Now start grabbing records 2435  do 2436  { 2437  // Get next occurrence of '#' (record terminator) 2438  ret = strchr( &( char_buf[buf_pos] ), '#' ); 2439  while( ret && (unsigned int)( ret + 1 - &char_buf[0] ) < bytes_left && *( ret + 1 ) != '\n' && 2440  *( ret + 1 ) != '\r' && *( ret + 1 ) != 0 ) // CR added for windows 2441  ret = strchr( ret + 1, '#' ); 2442  if( NULL != ret ) 2443  { 2444  // Grab the string (inclusive of the record terminator and the line feed) and 2445  // complete the record 2446  int num_chars = ret - &( char_buf[buf_pos] ) + 2; 2447  if( *( ret + 1 ) == '\r' ) num_chars++; // add more one character for Windows CR 2448  this_record.att_string.append( &( char_buf[buf_pos] ), num_chars ); 2449  buf_pos += num_chars; 2450  process_record( this_record ); 2451  2452  // Put the record in the list... 2453  records.push_back( this_record ); 2454  2455  // And reset the record 2456  reset_record( this_record ); 2457  } 2458  else 2459  { 2460  // Reached end of buffer; cache string then go get another; discard last character, 2461  // which will be the null character 2462  this_record.att_string.append( &( char_buf[buf_pos] ), next_buf - buf_pos ); 2463  buf_pos = next_buf; 2464  } 2465  } while( buf_pos < next_buf ); 2466  } 2467  2468  if( NULL != acisDumpFile ) 2469  fwrite( "\n======================\nSorted acis records:\n======================\n", 1, 68, acisDumpFile ); 2470  2471  // Now interpret the records 2472  interpret_acis_records( records ); 2473  2474  if( NULL != acisDumpFile ) fclose( acisDumpFile ); 2475  2476  return MB_SUCCESS; 2477 } 2478  2479 ErrorCode Tqdcfr::interpret_acis_records( std::vector< AcisRecord >& records ) 2480 { 2481  // Make a tag for the vector holding unrecognized attributes 2482  void* default_val = NULL; 2483  ErrorCode result = mdbImpl->tag_get_handle( "ATTRIB_VECTOR", sizeof( void* ), MB_TYPE_OPAQUE, attribVectorTag, 2484  MB_TAG_CREAT | MB_TAG_SPARSE, &default_val ); 2485  if( MB_SUCCESS != result ) return result; 2486  2487  unsigned int current_record = 0; 2488  2489 #define REC records[current_record] 2490  2491  while( current_record != records.size() ) 2492  { 2493  // If this record's been processed, or if it's an attribute, continue 2494  if( REC.processed || REC.rec_type == Tqdcfr::ATTRIB ) 2495  { 2496  current_record++; 2497  continue; 2498  } 2499  2500  if( REC.rec_type == Tqdcfr::UNKNOWN ) 2501  { 2502  REC.processed = true; 2503  current_record++; 2504  continue; 2505  } 2506  2507  // It's a known, non-attrib rec type; parse for any attribs 2508  parse_acis_attribs( current_record, records ); 2509  2510  REC.processed = true; 2511  2512  current_record++; 2513  } 2514  2515  return MB_SUCCESS; 2516 } 2517  2518 ErrorCode Tqdcfr::parse_acis_attribs( const unsigned int entity_rec_num, std::vector< AcisRecord >& records ) 2519 { 2520  unsigned int num_read; 2521  std::vector< std::string > attrib_vec; 2522  char temp_name[1024]; 2523  char name_tag_val[NAME_TAG_SIZE]; 2524  std::string name_tag; 2525  int id = -1; 2526  int uid = -1; 2527  int next_attrib = -1; 2528  ErrorCode result; 2529  2530  int current_attrib = records[entity_rec_num].first_attrib; 2531  if( -1 == current_attrib ) return MB_SUCCESS; 2532  2533  if( NULL != acisDumpFile ) 2534  { 2535  fwrite( "-----------------------------------------------------------------------\n", 1, 72, acisDumpFile ); 2536  fwrite( records[entity_rec_num].att_string.c_str(), sizeof( char ), records[entity_rec_num].att_string.length(), 2537  acisDumpFile ); 2538  } 2539  2540  while( -1 != current_attrib ) 2541  { 2542  if( records[current_attrib].rec_type != Tqdcfr::UNKNOWN && 2543  ( records[current_attrib].att_next != next_attrib || 2544  records[current_attrib].att_ent_num != (int)entity_rec_num ) ) 2545  return MB_FAILURE; 2546  2547  if( NULL != acisDumpFile ) 2548  fwrite( records[current_attrib].att_string.c_str(), sizeof( char ), 2549  records[current_attrib].att_string.length(), acisDumpFile ); 2550  2551  // Is the attrib one we already recognize? 2552  if( strncmp( records[current_attrib].att_string.c_str(), "ENTITY_NAME", 11 ) == 0 ) 2553  { 2554  // Parse name 2555  int num_chars; 2556  num_read = 2557  sscanf( records[current_attrib].att_string.c_str(), "ENTITY_NAME @%d %s", &num_chars, temp_name ); 2558  if( num_read != 2 ) 2559  num_read = 2560  sscanf( records[current_attrib].att_string.c_str(), "ENTITY_NAME %d %s", &num_chars, temp_name ); 2561  if( num_read != 2 ) return MB_FAILURE; 2562  2563  // Put the name on the entity 2564  name_tag = std::string( temp_name, num_chars ); 2565  } 2566  else if( strncmp( records[current_attrib].att_string.c_str(), "ENTITY_ID", 9 ) == 0 ) 2567  { 2568  // Parse id 2569  int bounding_uid, bounding_sense; 2570  num_read = sscanf( records[current_attrib].att_string.c_str(), "ENTITY_ID 0 3 %d %d %d", &id, &bounding_uid, 2571  &bounding_sense ); 2572  if( 3 != num_read ) 2573  { 2574  // Try reading updated entity_id format, which has coordinate triple embedded in it 2575  // too 2576  float dumx, dumy, dumz; 2577  num_read = sscanf( records[current_attrib].att_string.c_str(), "ENTITY_ID 3 %f %f %f 3 %d %d %d", &dumx, 2578  &dumy, &dumz, &id, &bounding_uid, &bounding_sense ); 2579  num_read -= 3; 2580  } 2581  2582  if( 3 != num_read ) 2583  std::cout << "Warning: bad ENTITY_ID attribute in .sat file, record number " << entity_rec_num 2584  << ", record follows:" << std::endl 2585  << records[current_attrib].att_string.c_str() << std::endl; 2586  } 2587  else if( strncmp( records[current_attrib].att_string.c_str(), "UNIQUE_ID", 9 ) == 0 ) 2588  { 2589  // Parse uid 2590  if( major >= 14 ) // Change of format for cubit 14: 2591  num_read = sscanf( records[current_attrib].att_string.c_str(), "UNIQUE_ID 0 1 %d", &uid ); 2592  else 2593  num_read = sscanf( records[current_attrib].att_string.c_str(), "UNIQUE_ID 1 0 1 %d", &uid ); 2594  if( 1 != num_read ) return MB_FAILURE; 2595  } 2596  else if( strncmp( records[current_attrib].att_string.c_str(), "COMPOSITE_ATTRIB @9 UNIQUE_ID", 29 ) == 0 ) 2597  { 2598  // Parse uid 2599  int dum1, dum2, dum3, dum4; 2600  num_read = sscanf( records[current_attrib].att_string.c_str(), 2601  "COMPOSITE_ATTRIB @9 UNIQUE_ID %d %d %d %d %d", &dum1, &dum2, &dum3, &dum4, &uid ); 2602  if( 5 != num_read ) return MB_FAILURE; 2603  } 2604  else if( strncmp( records[current_attrib].att_string.c_str(), "COMPOSITE_ATTRIB @9 ENTITY_ID", 29 ) == 0 ) 2605  { 2606  // Parse id 2607  int dum1, dum2, dum3; 2608  num_read = sscanf( records[current_attrib].att_string.c_str(), "COMPOSITE_ATTRIB @9 ENTITY_ID %d %d %d %d", 2609  &dum1, &dum2, &dum3, &id ); 2610  if( 4 != num_read ) return MB_FAILURE; 2611  } 2612  else 2613  { 2614  attrib_vec.push_back( records[current_attrib].att_string ); 2615  } 2616  2617  records[current_attrib].processed = true; 2618  next_attrib = current_attrib; 2619  current_attrib = records[current_attrib].att_prev; 2620  } 2621  2622  // At this point, there aren't entity sets for entity types which don't contain mesh 2623  // in this case, just return 2624  if( records[entity_rec_num].rec_type == aBODY || ( records[entity_rec_num].entity == 0 && uid == -1 ) ) 2625  { 2626  return MB_SUCCESS; 2627  // Warning: couldn't resolve entity of type 1 because no uid was found. 2628  // ddriv: GeomTopoTool.cpp:172: ErrorCode GeomTopoTool::separate_by_dimension(const Range&, 2629  // Range*, void**): Assertion `false' failed. xxx 2630  } 2631  2632  // Parsed the data; now put on mdb entities; first we need to find the entity 2633  if( records[entity_rec_num].entity == 0 ) 2634  { 2635  records[entity_rec_num].entity = uidSetMap[uid]; 2636  } 2637  2638  if( 0 == records[entity_rec_num].entity ) return MB_SUCCESS; // We do not have a MOAB entity for this, skip 2639  2640  // assert(records[entity_rec_num].entity); 2641  2642  // Set the id 2643  if( id != -1 ) 2644  { 2645  result = mdbImpl->tag_set_data( globalIdTag, &( records[entity_rec_num].entity ), 1, &id ); 2646  if( MB_SUCCESS != result ) return result; 2647  2648  int ent_dim = -1; 2649  if( records[entity_rec_num].rec_type == aBODY ) 2650  ent_dim = 4; 2651  else if( records[entity_rec_num].rec_type == LUMP ) 2652  ent_dim = 3; 2653  else if( records[entity_rec_num].rec_type == FACE ) 2654  ent_dim = 2; 2655  else if( records[entity_rec_num].rec_type == aEDGE ) 2656  ent_dim = 1; 2657  else if( records[entity_rec_num].rec_type == aVERTEX ) 2658  ent_dim = 0; 2659  if( -1 != ent_dim ) gidSetMap[ent_dim][id] = records[entity_rec_num].entity; 2660  } 2661  2662  // Set the name 2663  if( !name_tag.empty() ) 2664  { 2665  if( 0 == entityNameTag ) 2666  { 2667  char dum_val[NAME_TAG_SIZE] = { 0 }; 2668  result = mdbImpl->tag_get_handle( NAME_TAG_NAME, NAME_TAG_SIZE, MB_TYPE_OPAQUE, entityNameTag, 2669  MB_TAG_SPARSE | MB_TAG_CREAT, dum_val ); 2670  if( MB_SUCCESS != result ) return result; 2671  } 2672  2673  size_t len = name_tag.size(); 2674  if( len >= NAME_TAG_SIZE ) len = NAME_TAG_SIZE - 1; // Truncate a name that is too big 2675  memcpy( name_tag_val, name_tag.c_str(), len ); 2676  memset( name_tag_val + len, '\0', NAME_TAG_SIZE - len ); 2677  result = mdbImpl->tag_set_data( entityNameTag, &( records[entity_rec_num].entity ), 1, name_tag_val ); 2678  if( MB_SUCCESS != result ) return result; 2679  } 2680  2681  if( !attrib_vec.empty() ) 2682  { 2683  // Put the attrib vector in a tag on the entity 2684  std::vector< std::string >* dum_vec; 2685  result = mdbImpl->tag_get_data( attribVectorTag, &( records[entity_rec_num].entity ), 1, &dum_vec ); 2686  if( MB_SUCCESS != result && MB_TAG_NOT_FOUND != result ) return result; 2687  if( MB_TAG_NOT_FOUND == result || dum_vec == NULL ) 2688  { 2689  // Put this list directly on the entity 2690  dum_vec = new std::vector< std::string >; 2691  dum_vec->swap( attrib_vec ); 2692  result = mdbImpl->tag_set_data( attribVectorTag, &( records[entity_rec_num].entity ), 1, &dum_vec ); 2693  if( MB_SUCCESS != result ) 2694  { 2695  delete dum_vec; 2696  return result; 2697  } 2698  } 2699  else 2700  { 2701  // Copy this list over, and delete this list 2702  std::copy( attrib_vec.begin(), attrib_vec.end(), std::back_inserter( *dum_vec ) ); 2703  } 2704  } 2705  2706  return MB_SUCCESS; 2707 } 2708  2709 ErrorCode Tqdcfr::reset_record( AcisRecord& this_record ) 2710 { 2711  this_record.rec_type = Tqdcfr::UNKNOWN; 2712  this_record.att_string.clear(); 2713  this_record.first_attrib = this_record.att_prev = this_record.att_next = this_record.att_ent_num = -1; 2714  this_record.processed = false; 2715  this_record.entity = 0; 2716  2717  return MB_SUCCESS; 2718 } 2719  2720 ErrorCode Tqdcfr::process_record( AcisRecord& this_record ) 2721 { 2722  // Get the entity type 2723  const char* type_substr; 2724  2725  // Try attribs first, since the others have some common processing between them 2726  if( ( type_substr = strstr( this_record.att_string.c_str(), "attrib" ) ) != NULL && 2727  type_substr - this_record.att_string.c_str() < 20 ) 2728  { 2729  this_record.rec_type = Tqdcfr::ATTRIB; 2730  bool simple_attrib = false; 2731  bool generic_attrib = false; 2732  if( ( type_substr = strstr( this_record.att_string.c_str(), "simple-snl-attrib" ) ) != NULL ) 2733  simple_attrib = true; 2734  else if( ( type_substr = strstr( this_record.att_string.c_str(), "integer_attrib-name_attrib-gen-attrib" ) ) != 2735  NULL ) 2736  generic_attrib = true; 2737  else 2738  { 2739  this_record.rec_type = Tqdcfr::UNKNOWN; 2740  return MB_SUCCESS; 2741  } 2742  2743  // Find next space 2744  type_substr = strchr( type_substr, ' ' ); 2745  if( NULL == type_substr ) return MB_FAILURE; 2746  2747  // Read the numbers from there 2748  int num_converted = sscanf( type_substr, " $-1 -1 $%d $%d $%d -1", &( this_record.att_prev ), 2749  &( this_record.att_next ), &( this_record.att_ent_num ) ); 2750  if( num_converted != 3 ) return MB_FAILURE; 2751  2752  // Trim the string to the attribute, if it's a simple attrib 2753  if( simple_attrib ) 2754  { 2755  type_substr = strstr( this_record.att_string.c_str(), "NEW_SIMPLE_ATTRIB" ); 2756  if( NULL == type_substr ) return MB_FAILURE; 2757  type_substr = strstr( type_substr, "@" ); 2758  if( NULL == type_substr ) return MB_FAILURE; 2759  type_substr = strstr( type_substr, " " ) + 1; 2760  // Copy the rest of the string to a dummy string 2761  std::string dum_str( type_substr ); 2762  this_record.att_string = dum_str; 2763  } 2764  else if( generic_attrib ) 2765  { 2766  type_substr = strstr( this_record.att_string.c_str(), "CUBIT_ID" ); 2767  if( NULL == type_substr ) return MB_FAILURE; 2768  // Copy the rest of the string to a dummy string 2769  std::string dum_str( type_substr ); 2770  this_record.att_string = dum_str; 2771  } 2772  } 2773  else 2774  { 2775  // Else it's a topological entity, I think 2776  if( ( type_substr = strstr( this_record.att_string.c_str(), "body" ) ) != NULL && 2777  type_substr - this_record.att_string.c_str() < 20 ) 2778  { 2779  this_record.rec_type = Tqdcfr::aBODY; 2780  } 2781  else if( ( type_substr = strstr( this_record.att_string.c_str(), "lump" ) ) != NULL && 2782  type_substr - this_record.att_string.c_str() < 20 ) 2783  { 2784  this_record.rec_type = Tqdcfr::LUMP; 2785  } 2786  else if( ( type_substr = strstr( this_record.att_string.c_str(), "shell" ) ) != NULL && 2787  type_substr - this_record.att_string.c_str() < 20 ) 2788  { 2789  // Don't care about shells 2790  this_record.rec_type = Tqdcfr::UNKNOWN; 2791  } 2792  else if( ( type_substr = strstr( this_record.att_string.c_str(), "surface" ) ) != NULL && 2793  type_substr - this_record.att_string.c_str() < 20 ) 2794  { 2795  // Don't care about surfaces 2796  this_record.rec_type = Tqdcfr::UNKNOWN; 2797  } 2798  else if( ( type_substr = strstr( this_record.att_string.c_str(), "face" ) ) != NULL && 2799  type_substr - this_record.att_string.c_str() < 20 ) 2800  { 2801  this_record.rec_type = Tqdcfr::FACE; 2802  } 2803  else if( ( type_substr = strstr( this_record.att_string.c_str(), "loop" ) ) != NULL && 2804  type_substr - this_record.att_string.c_str() < 20 ) 2805  { 2806  // Don't care about loops 2807  this_record.rec_type = Tqdcfr::UNKNOWN; 2808  } 2809  else if( ( type_substr = strstr( this_record.att_string.c_str(), "coedge" ) ) != NULL && 2810  type_substr - this_record.att_string.c_str() < 20 ) 2811  { 2812  // Don't care about coedges 2813  this_record.rec_type = Tqdcfr::UNKNOWN; 2814  } 2815  else if( ( type_substr = strstr( this_record.att_string.c_str(), "edge" ) ) != NULL && 2816  type_substr - this_record.att_string.c_str() < 20 ) 2817  { 2818  this_record.rec_type = Tqdcfr::aEDGE; 2819  } 2820  else if( ( type_substr = strstr( this_record.att_string.c_str(), "vertex" ) ) != NULL && 2821  type_substr - this_record.att_string.c_str() < 20 ) 2822  { 2823  this_record.rec_type = Tqdcfr::aVERTEX; 2824  } 2825  else 2826  this_record.rec_type = Tqdcfr::UNKNOWN; 2827  2828  if( this_record.rec_type != Tqdcfr::UNKNOWN ) 2829  { 2830  // Print a warning if it looks like there are sequence numbers 2831  if( type_substr != this_record.att_string.c_str() && !printedSeqWarning ) 2832  { 2833  std::cout << "Warning: acis file has sequence numbers!" << std::endl; 2834  printedSeqWarning = true; 2835  } 2836  2837  // Scan ahead to the next white space 2838  type_substr = strchr( type_substr, ' ' ); 2839  if( NULL == type_substr ) return MB_FAILURE; 2840  2841  // Get the id of the first attrib 2842  int num_converted = sscanf( type_substr, " $%d", &( this_record.first_attrib ) ); 2843  if( num_converted != 1 ) return MB_FAILURE; 2844  } 2845  } 2846  2847  return MB_SUCCESS; 2848 } 2849  2850 Tqdcfr::FileTOC::FileTOC() 2851  : fileEndian( 0 ), fileSchema( 0 ), numModels( 0 ), modelTableOffset( 0 ), modelMetaDataOffset( 0 ), 2852  activeFEModel( 0 ) 2853 { 2854 } 2855  2856 void Tqdcfr::FileTOC::print() 2857 { 2858  std::cout << "FileTOC:End, Sch, #Mdl, TabOff, " 2859  << "MdlMDOff, actFEMdl = "; 2860  std::cout << fileEndian << ", " << fileSchema << ", " << numModels << ", " << modelTableOffset << ", " 2861  << modelMetaDataOffset << ", " << activeFEModel << std::endl; 2862 } 2863  2864 Tqdcfr::FEModelHeader::ArrayInfo::ArrayInfo() : numEntities( 0 ), tableOffset( 0 ), metaDataOffset( 0 ) {} 2865  2866 void Tqdcfr::FEModelHeader::ArrayInfo::print() 2867 { 2868  std::cout << "ArrayInfo:numEntities, tableOffset, metaDataOffset = " << numEntities << ", " << tableOffset << ", " 2869  << metaDataOffset << std::endl; 2870 } 2871  2872 void Tqdcfr::FEModelHeader::ArrayInfo::init( const std::vector< unsigned int >& uint_buf_in ) 2873 { 2874  numEntities = uint_buf_in[0]; 2875  tableOffset = uint_buf_in[1]; 2876  metaDataOffset = uint_buf_in[2]; 2877 } 2878  2879 void Tqdcfr::FEModelHeader::print() 2880 { 2881  std::cout << "FEModelHeader:feEndian, feSchema, feCompressFlag, feLength = " << feEndian << ", " << feSchema << ", " 2882  << feCompressFlag << ", " << feLength << std::endl; 2883  std::cout << "geomArray: "; 2884  geomArray.print(); 2885  std::cout << "nodeArray: "; 2886  nodeArray.print(); 2887  std::cout << "elementArray: "; 2888  elementArray.print(); 2889  std::cout << "groupArray: "; 2890  groupArray.print(); 2891  std::cout << "blockArray: "; 2892  blockArray.print(); 2893  std::cout << "nodesetArray: "; 2894  nodesetArray.print(); 2895  std::cout << "sidesetArray: "; 2896  sidesetArray.print(); 2897 } 2898  2899 Tqdcfr::GeomHeader::GeomHeader() 2900  : geomID( 0 ), nodeCt( 0 ), nodeOffset( 0 ), elemCt( 0 ), elemOffset( 0 ), elemTypeCt( 0 ), elemLength( 0 ), 2901  maxDim( 0 ), setHandle( 0 ) 2902 { 2903 } 2904  2905 void Tqdcfr::GeomHeader::print() 2906 { 2907  std::cout << "geomID = " << geomID << std::endl; 2908  std::cout << "nodeCt = " << nodeCt << std::endl; 2909  std::cout << "nodeOffset = " << nodeOffset << std::endl; 2910  std::cout << "elemCt = " << elemCt << std::endl; 2911  std::cout << "elemOffset = " << elemOffset << std::endl; 2912  std::cout << "elemTypeCt = " << elemTypeCt << std::endl; 2913  std::cout << "elemLength = " << elemLength << std::endl; 2914  std::cout << "setHandle = " << setHandle << std::endl; 2915 } 2916  2917 Tqdcfr::GroupHeader::GroupHeader() 2918  : grpID( 0 ), grpType( 0 ), memCt( 0 ), memOffset( 0 ), memTypeCt( 0 ), grpLength( 0 ), setHandle( 0 ) 2919 { 2920 } 2921  2922 void Tqdcfr::GroupHeader::print() 2923 { 2924  std::cout << "grpID = " << grpID << std::endl; 2925  std::cout << "grpType = " << grpType << std::endl; 2926  std::cout << "memCt = " << memCt << std::endl; 2927  std::cout << "memOffset = " << memOffset << std::endl; 2928  std::cout << "memTypeCt = " << memTypeCt << std::endl; 2929  std::cout << "grpLength = " << grpLength << std::endl; 2930  std::cout << "setHandle = " << setHandle << std::endl; 2931 } 2932  2933 Tqdcfr::BlockHeader::BlockHeader() 2934  : blockID( 0 ), blockElemType( 0 ), memCt( 0 ), memOffset( 0 ), memTypeCt( 0 ), attribOrder( 0 ), blockCol( 0 ), 2935  blockMixElemType( 0 ), blockPyrType( 0 ), blockMat( 0 ), blockLength( 0 ), blockDim( 0 ), setHandle( 0 ), 2936  blockEntityType( MBMAXTYPE ) 2937 { 2938 } 2939  2940 void Tqdcfr::BlockHeader::print() 2941 { 2942  std::cout << "blockID = " << blockID << std::endl; 2943  std::cout << "blockElemType = " << blockElemType << std::endl; 2944  std::cout << "memCt = " << memCt << std::endl; 2945  std::cout << "memOffset = " << memOffset << std::endl; 2946  std::cout << "memTypeCt = " << memTypeCt << std::endl; 2947  std::cout << "attribOrder = " << attribOrder << std::endl; 2948  std::cout << "blockCol = " << blockCol << std::endl; 2949  std::cout << "blockMixElemType = " << blockMixElemType << std::endl; 2950  std::cout << "blockPyrType = " << blockPyrType << std::endl; 2951  std::cout << "blockMat = " << blockMat << std::endl; 2952  std::cout << "blockLength = " << blockLength << std::endl; 2953  std::cout << "blockDim = " << blockDim << std::endl; 2954  std::cout << "setHandle = " << setHandle << std::endl; 2955  std::cout << "blockEntityType = " << blockEntityType << std::endl; 2956 } 2957  2958 Tqdcfr::NodesetHeader::NodesetHeader() 2959  : nsID( 0 ), memCt( 0 ), memOffset( 0 ), memTypeCt( 0 ), pointSym( 0 ), nsCol( 0 ), nsLength( 0 ), setHandle( 0 ) 2960 { 2961 } 2962  2963 void Tqdcfr::NodesetHeader::print() 2964 { 2965  std::cout << "nsID = " << nsID << std::endl; 2966  std::cout << "memCt = " << memCt << std::endl; 2967  std::cout << "memOffset = " << memOffset << std::endl; 2968  std::cout << "memTypeCt = " << memTypeCt << std::endl; 2969  std::cout << "pointSym = " << pointSym << std::endl; 2970  std::cout << "nsCol = " << nsCol << std::endl; 2971  std::cout << "nsLength = " << nsLength << std::endl; 2972  std::cout << "setHandle = " << setHandle << std::endl; 2973 } 2974  2975 Tqdcfr::SidesetHeader::SidesetHeader() 2976  : ssID( 0 ), memCt( 0 ), memOffset( 0 ), memTypeCt( 0 ), numDF( 0 ), ssCol( 0 ), useShell( 0 ), ssLength( 0 ), 2977  setHandle( 0 ) 2978 { 2979 } 2980  2981 void Tqdcfr::SidesetHeader::print() 2982 { 2983  std::cout << "ssID = " << ssID << std::endl; 2984  std::cout << "memCt = " << memCt << std::endl; 2985  std::cout << "memOffset = " << memOffset << std::endl; 2986  std::cout << "memTypeCt = " << memTypeCt << std::endl; 2987  std::cout << "numDF = " << numDF << std::endl; 2988  std::cout << "ssCol = " << ssCol << std::endl; 2989  std::cout << "useShell = " << useShell << std::endl; 2990  std::cout << "ssLength = " << ssLength << std::endl; 2991  std::cout << "setHandle = " << setHandle << std::endl; 2992 } 2993  2994 Tqdcfr::MetaDataContainer::MetaDataEntry::MetaDataEntry() 2995  : mdOwner( 0 ), mdDataType( 0 ), mdIntValue( 0 ), mdName( "(uninit)" ), mdStringValue( "(uninit)" ), mdDblValue( 0 ) 2996 { 2997 } 2998  2999 void Tqdcfr::MetaDataContainer::MetaDataEntry::print() 3000 { 3001  std::cout << "MetaDataEntry:own, typ, name, I, D, S = " << mdOwner << ", " << mdDataType << ", " << mdName << ", " 3002  << mdIntValue << ", " << mdDblValue << ", " << mdStringValue; 3003  unsigned int i; 3004  if( mdIntArrayValue.size() ) 3005  { 3006  std::cout << std::endl << "IArray = " << mdIntArrayValue[0]; 3007  for( i = 1; i < mdIntArrayValue.size(); i++ ) 3008  std::cout << ", " << mdIntArrayValue[i]; 3009  } 3010  if( mdDblArrayValue.size() ) 3011  { 3012  std::cout << std::endl << "DArray = " << mdDblArrayValue[0]; 3013  for( i = 1; i < mdDblArrayValue.size(); i++ ) 3014  std::cout << ", " << mdDblArrayValue[i]; 3015  } 3016  std::cout << std::endl; 3017 } 3018  3019 void Tqdcfr::MetaDataContainer::print() 3020 { 3021  std::cout << "MetaDataContainer:mdSchema, compressFlag, numDatums = " << mdSchema << ", " << compressFlag << ", " 3022  << metadataEntries.size() << std::endl; 3023  3024  for( unsigned int i = 0; i < metadataEntries.size(); i++ ) 3025  metadataEntries[i].print(); 3026 } 3027  3028 Tqdcfr::MetaDataContainer::MetaDataContainer() : mdSchema( 0 ), compressFlag( 0 ) {} 3029  3030 int Tqdcfr::MetaDataContainer::get_md_entry( const unsigned int owner, const std::string& name ) 3031 { 3032  for( unsigned int i = 0; i < metadataEntries.size(); i++ ) 3033  { 3034  if( owner == metadataEntries[i].mdOwner && name == metadataEntries[i].mdName ) return i; 3035  } 3036  3037  return -1; 3038 } 3039  3040 Tqdcfr::ModelEntry::ModelEntry() 3041  : modelHandle( 0 ), modelOffset( 0 ), modelLength( 0 ), modelType( 0 ), modelOwner( 0 ), modelPad( 0 ), 3042  feGeomH( NULL ), feGroupH( NULL ), feBlockH( NULL ), feNodeSetH( NULL ), feSideSetH( NULL ) 3043 { 3044 } 3045  3046 Tqdcfr::ModelEntry::~ModelEntry() 3047 { 3048  delete[] feGeomH; 3049  delete[] feGroupH; 3050  delete[] feBlockH; 3051  delete[] feNodeSetH; 3052  delete[] feSideSetH; 3053 } 3054  3055 void Tqdcfr::ModelEntry::print() 3056 { 3057  std::cout << "ModelEntry: Han, Of, Len, Tp, Own, Pd = " << modelHandle << ", " << modelOffset << ", " << modelLength 3058  << ", " << modelType << ", " << modelOwner << ", " << modelPad << std::endl; 3059 } 3060  3061 ErrorCode Tqdcfr::create_set( EntityHandle& h, unsigned int flags ) 3062 { 3063  return mdbImpl->create_meshset( flags, h ); 3064 } 3065  3066 } // namespace moab