MOAB: Mesh Oriented datABase
(version 5.4.1)
|
00001 /** 00002 * MOAB, a Mesh-Oriented datABase, is a software component for creating, 00003 * storing and accessing finite element mesh data. 00004 * 00005 * Copyright 2004 Sandia Corporation. Under the terms of Contract 00006 * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government 00007 * retains certain rights in this software. 00008 * 00009 * This library is free software; you can redistribute it and/or 00010 * modify it under the terms of the GNU Lesser General Public 00011 * License as published by the Free Software Foundation; either 00012 * version 2.1 of the License, or (at your option) any later version. 00013 * 00014 */ 00015 00016 #include "Tqdcfr.hpp" 00017 #include "moab/Core.hpp" 00018 #include "moab/Range.hpp" 00019 #include "moab/FileOptions.hpp" 00020 #include <iostream> 00021 #include <string> 00022 00023 #ifdef MOAB_HAVE_MPI 00024 #include "moab_mpi.h" 00025 #endif 00026 00027 #include "moab/ReadUtilIface.hpp" 00028 #include "SequenceManager.hpp" 00029 #include "moab/GeomTopoTool.hpp" 00030 #include "MBTagConventions.hpp" 00031 #include "moab/CN.hpp" 00032 #include "Internals.hpp" 00033 #include "moab/HigherOrderFactory.hpp" 00034 #include "exodus_order.h" 00035 00036 #include <sstream> 00037 #include <cassert> 00038 #include <cstring> 00039 00040 namespace moab 00041 { 00042 00043 static bool debug = false; 00044 00045 const char Tqdcfr::geom_categories[][CATEGORY_TAG_SIZE] = { "Vertex\0", "Curve\0", "Surface\0", "Volume\0" }; 00046 00047 // Will be used in a static function, so declared outside class members :( 00048 // major/minor cubit version that wrote this file 00049 static int major = -1, minor = -1; 00050 const EntityType Tqdcfr::group_type_to_mb_type[] = { MBENTITYSET, MBENTITYSET, MBENTITYSET, // group, body, volume 00051 MBENTITYSET, MBENTITYSET, MBENTITYSET, // surface, curve, vertex 00052 MBHEX, MBTET, MBPYRAMID, MBQUAD, 00053 MBTRI, MBEDGE, MBVERTEX }; 00054 00055 const EntityType Tqdcfr::block_type_to_mb_type[] = { 00056 MBVERTEX, // sphere 00057 MBEDGE, MBEDGE, MBEDGE, // bars 00058 MBEDGE, MBEDGE, MBEDGE, // beams 00059 MBEDGE, MBEDGE, MBEDGE, // truss 00060 MBEDGE, // spring 00061 MBTRI, MBTRI, MBTRI, MBTRI, // tri 00062 MBTRI, MBTRI, MBTRI, MBTRI, // trishell 00063 MBQUAD, MBQUAD, MBQUAD, MBQUAD, // shell 00064 MBQUAD, MBQUAD, MBQUAD, MBQUAD, MBQUAD, // quad 00065 MBTET, MBTET, MBTET, MBTET, MBTET, // tet 00066 MBPYRAMID, MBPYRAMID, MBPYRAMID, MBPYRAMID, MBPYRAMID, // pyramid 00067 MBHEX, MBHEX, MBHEX, MBHEX, MBHEX, // hex 00068 MBHEX, // hexshell 00069 MBMAXTYPE // last 00070 }; 00071 00072 // Mapping from mesh packet type to moab type 00073 const EntityType Tqdcfr::mp_type_to_mb_type[] = { MBHEX, MBHEX, MBHEX, MBHEX, MBHEX, MBHEX, MBHEX, 00074 MBHEX, MBTET, MBTET, MBTET, MBTET, MBTET, MBTET, 00075 MBTET, MBTET, MBPYRAMID, MBPYRAMID, MBPYRAMID, MBPYRAMID, MBQUAD, 00076 MBQUAD, MBQUAD, MBQUAD, MBTRI, MBTRI, MBTRI, MBTRI, 00077 MBEDGE, MBEDGE, MBVERTEX }; 00078 00079 const int Tqdcfr::cub_elem_num_verts[] = { 1, // sphere 00080 2, 2, 3, // bars 00081 2, 2, 3, // beams 00082 2, 2, 3, // truss 00083 2, // spring 00084 3, 3, 6, 7, // tris 00085 3, 3, 6, 7, // trishells 00086 4, 4, 8, 9, // shells 00087 4, 4, 5, 8, 9, // quads 00088 4, 4, 8, 10, 14, // tets 00089 5, 5, 8, 13, 18, // pyramids 00090 8, 8, 9, 20, 27, 12, // hexes (incl. hexshell at end) 00091 0 }; 00092 00093 const int Tqdcfr::cub_elem_num_verts_len = sizeof( cub_elem_num_verts ) / sizeof( cub_elem_num_verts[0] ); 00094 00095 // Define node-order map from Cubit to CN. Table is indexed 00096 // by EntityType and number of nodes. Entries are NULL if Cubit order 00097 // is the same as CN ordering. Non-null entries contain the 00098 // index into the MOAB node order for the corresponding vertex 00099 // in the Cubit connectivity list. Thus for a 27-node hex: 00100 // moab_conn[ cub_hex27_order[i] ] = cubit_conn[ i ]; 00101 const int* const* const* const cub_elem_order_map = exodus_elem_order_map; 00102 00103 const char* const BLOCK_NODESET_OFFSET_TAG_NAME = "BLOCK_NODESET_OFFSET"; 00104 const char* const BLOCK_SIDESET_OFFSET_TAG_NAME = "BLOCK_SIDESET_OFFSET"; 00105 00106 #define RR \ 00107 if( MB_SUCCESS != result ) return result 00108 00109 // acis dimensions for each entity type, to match 00110 // enum {BODY, LUMP, SHELL, FACE, LOOP, COEDGE, EDGE, VERTEX, ATTRIB, UNKNOWN} 00111 00112 #define IO_ASSERT( C ) INT_IO_ERROR( C, __LINE__ ) 00113 00114 static inline void INT_IO_ERROR( bool condition, unsigned line ) 00115 { 00116 if( !condition ) 00117 { 00118 char buffer[] = __FILE__ " "; 00119 sprintf( buffer, "%s:%u", __FILE__, line ); 00120 fflush( stderr ); 00121 perror( buffer ); 00122 abort(); 00123 } 00124 } 00125 00126 void Tqdcfr::FSEEK( unsigned int offset ) 00127 { 00128 int rval = fseek( cubFile, offset, SEEK_SET ); 00129 IO_ASSERT( !rval ); 00130 } 00131 00132 void Tqdcfr::FREADI( unsigned num_ents ) 00133 { 00134 if( uint_buf.size() < num_ents ) 00135 { 00136 uint_buf.resize( num_ents ); 00137 int_buf = (int*)&uint_buf[0]; 00138 } 00139 FREADIA( num_ents, &uint_buf[0] ); 00140 } 00141 00142 void Tqdcfr::FREADD( unsigned num_ents ) 00143 { 00144 dbl_buf.resize( num_ents ); 00145 FREADDA( num_ents, &dbl_buf[0] ); 00146 } 00147 00148 void Tqdcfr::FREADC( unsigned num_ents ) 00149 { 00150 char_buf.resize( num_ents ); 00151 FREADCA( num_ents, &char_buf[0] ); 00152 } 00153 00154 // Used for swapping 00155 static void swap8_voff( long* data ) 00156 { 00157 unsigned char tmp, *cdat = (unsigned char*)data; 00158 tmp = cdat[0]; 00159 cdat[0] = cdat[7], cdat[7] = tmp; 00160 tmp = cdat[1]; 00161 cdat[1] = cdat[6], cdat[6] = tmp; 00162 tmp = cdat[2]; 00163 cdat[2] = cdat[5], cdat[5] = tmp; 00164 tmp = cdat[3]; 00165 cdat[3] = cdat[4], cdat[4] = tmp; 00166 } 00167 00168 static void swap4_uint( unsigned int* data ) 00169 { 00170 unsigned char tmp, *cdat = (unsigned char*)data; 00171 tmp = cdat[0]; 00172 cdat[0] = cdat[3], cdat[3] = tmp; 00173 tmp = cdat[1]; 00174 cdat[1] = cdat[2], cdat[2] = tmp; 00175 } 00176 00177 /* 00178 static void swap2_ushort(unsigned short *data) 00179 { 00180 unsigned char tmp, *cdat = (unsigned char *) data; 00181 tmp = cdat[0]; cdat[0] = cdat[1], cdat[1] = tmp; 00182 } 00183 */ 00184 00185 void Tqdcfr::FREADIA( unsigned num_ents, unsigned int* array ) 00186 { 00187 unsigned rval = fread( array, sizeof( unsigned int ), num_ents, cubFile ); 00188 IO_ASSERT( rval == num_ents ); 00189 if( swapForEndianness ) 00190 { 00191 unsigned int* pt = array; 00192 for( unsigned int i = 0; i < num_ents; i++ ) 00193 { 00194 swap4_uint( (unsigned int*)pt ); 00195 pt++; 00196 } 00197 } 00198 } 00199 00200 void Tqdcfr::FREADDA( unsigned num_ents, double* array ) 00201 { 00202 unsigned rval = fread( array, sizeof( double ), num_ents, cubFile ); 00203 IO_ASSERT( rval == num_ents ); 00204 if( swapForEndianness ) 00205 { 00206 double* pt = array; 00207 for( unsigned int i = 0; i < num_ents; i++ ) 00208 { 00209 swap8_voff( (long*)pt ); 00210 pt++; 00211 } 00212 } 00213 } 00214 00215 void Tqdcfr::FREADCA( unsigned num_ents, char* array ) 00216 { 00217 unsigned rval = fread( array, sizeof( char ), num_ents, cubFile ); 00218 IO_ASSERT( rval == num_ents ); 00219 } 00220 00221 void Tqdcfr::CONVERT_TO_INTS( unsigned int num_ents ) 00222 { 00223 for( unsigned int i = 0; i < num_ents; i++ ) 00224 int_buf[i] = uint_buf[i]; 00225 } 00226 00227 ReaderIface* Tqdcfr::factory( Interface* iface ) 00228 { 00229 return new Tqdcfr( iface ); 00230 } 00231 00232 Tqdcfr::Tqdcfr( Interface* impl ) 00233 : cubFile( NULL ), globalIdTag( 0 ), cubIdTag( 0 ), geomTag( 0 ), uniqueIdTag( 0 ), blockTag( 0 ), nsTag( 0 ), 00234 ssTag( 0 ), attribVectorTag( 0 ), entityNameTag( 0 ), categoryTag( 0 ), hasMidNodesTag( 0 ), 00235 swapForEndianness( false ), int_buf( NULL ), mFileSet( 0 ), printedSeqWarning( false ), 00236 printedElemWarning( false ), acisDumpFile( NULL ) 00237 { 00238 assert( NULL != impl ); 00239 mdbImpl = impl; 00240 impl->query_interface( readUtilIface ); 00241 assert( NULL != readUtilIface ); 00242 00243 currVHandleOffset = -1; 00244 for( EntityType this_type = MBVERTEX; this_type < MBMAXTYPE; this_type++ ) 00245 currElementIdOffset[this_type] = -1; 00246 00247 ErrorCode rval; 00248 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." ); 00249 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." ); 00250 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." ); 00251 00252 if( 0 == entityNameTag ) 00253 { 00254 rval = mdbImpl->tag_get_handle( NAME_TAG_NAME, NAME_TAG_SIZE, MB_TYPE_OPAQUE, entityNameTag, 00255 MB_TAG_SPARSE | MB_TAG_CREAT );MB_CHK_SET_ERR_RET( rval, "Failed to tag_get_handle." ); 00256 } 00257 00258 cubMOABVertexMap = NULL; 00259 } 00260 00261 Tqdcfr::~Tqdcfr() 00262 { 00263 mdbImpl->release_interface( readUtilIface ); 00264 00265 if( NULL != cubMOABVertexMap ) delete cubMOABVertexMap; 00266 if( attribVectorTag ) 00267 { 00268 // get all sets, and release the string vectors 00269 Range allSets; // although only geom sets should have these attributes 00270 // can't error in a destructor 00271 ErrorCode rval = mdbImpl->get_entities_by_type( 0, MBENTITYSET, allSets ); 00272 if( rval != MB_SUCCESS ) std::cerr << "WARNING: Could not get_entities_by_type" << std::endl; 00273 for( Range::iterator sit = allSets.begin(); sit != allSets.end(); ++sit ) 00274 { 00275 EntityHandle gset = *sit; 00276 std::vector< std::string >* dum_vec; 00277 // can't error in a destructor 00278 rval = mdbImpl->tag_get_data( attribVectorTag, &gset, 1, &dum_vec ); 00279 if( rval != MB_SUCCESS ) std::cerr << "WARNING: Could not tag_get_data" << std::endl; 00280 if( NULL != dum_vec ) delete dum_vec; // 00281 } 00282 mdbImpl->tag_delete( attribVectorTag ); 00283 attribVectorTag = NULL; 00284 } 00285 } 00286 00287 ErrorCode Tqdcfr::read_tag_values( const char* /* file_name */, 00288 const char* /* tag_name */, 00289 const FileOptions& /* opts */, 00290 std::vector< int >& /* tag_values_out */, 00291 const SubsetList* /* subset_list */ ) 00292 { 00293 return MB_NOT_IMPLEMENTED; 00294 } 00295 00296 ErrorCode Tqdcfr::load_file( const char* file_name, 00297 const EntityHandle*, 00298 const FileOptions& opts, 00299 const ReaderIface::SubsetList* subset_list, 00300 const Tag* file_id_tag ) 00301 { 00302 ErrorCode result; 00303 00304 int tmpval; 00305 if( MB_SUCCESS == opts.get_int_option( "DEBUG_IO", 1, tmpval ) ) 00306 { 00307 if( 0 < tmpval ) debug = true; 00308 } 00309 00310 if( subset_list ) 00311 { 00312 MB_SET_ERR( MB_UNSUPPORTED_OPERATION, "Reading subset of files not supported for CUB files" ); 00313 } 00314 00315 // Open file 00316 cubFile = fopen( file_name, "rb" ); 00317 if( NULL == cubFile ) 00318 { 00319 MB_SET_ERR( MB_FAILURE, "File not found" ); 00320 } 00321 00322 // Verify magic string 00323 FREADC( 4 ); 00324 if( !( char_buf[0] == 'C' && char_buf[1] == 'U' && char_buf[2] == 'B' && char_buf[3] == 'E' ) ) 00325 { 00326 fclose( cubFile ); 00327 MB_SET_ERR( MB_FAILURE, "This doesn't appear to be a .cub file" ); 00328 } 00329 00330 // Get "before" entities 00331 result = mdbImpl->get_entities_by_handle( 0, beforeEnts );MB_CHK_SET_ERR( result, "Couldn't get \"before\" entities" ); 00332 00333 // *********************** 00334 // Read model header type information... 00335 // *********************** 00336 if( debug ) std::cout << "Reading file header." << std::endl; 00337 result = read_file_header();RR; 00338 00339 if( debug ) std::cout << "Reading model entries." << std::endl; 00340 result = read_model_entries();RR; 00341 00342 // Read model metadata 00343 if( debug ) std::cout << "Reading model metadata." << std::endl; 00344 result = read_meta_data( fileTOC.modelMetaDataOffset, modelMetaData );RR; 00345 00346 double data_version; 00347 int md_index = modelMetaData.get_md_entry( 2, "DataVersion" ); 00348 if( -1 == md_index ) 00349 data_version = 1.0; 00350 else 00351 data_version = modelMetaData.metadataEntries[md_index].mdDblValue; 00352 00353 // Get the major/minor cubit version that wrote this file 00354 // int major = -1, minor = -1; 00355 md_index = modelMetaData.get_md_entry( 2, "CubitVersion" ); 00356 if( md_index >= 0 && !modelMetaData.metadataEntries[md_index].mdStringValue.empty() ) 00357 sscanf( modelMetaData.metadataEntries[md_index].mdStringValue.c_str(), "%d.%d", &major, &minor ); 00358 00359 // *********************** 00360 // Read mesh... 00361 // *********************** 00362 int index = find_model( mesh ); 00363 if( -1 == index ) return MB_FAILURE; 00364 ModelEntry* mesh_model = &modelEntries[index]; 00365 00366 // First the header & metadata info 00367 if( debug ) std::cout << "Reading mesh model header and metadata." << std::endl; 00368 result = mesh_model->read_header_info( this, data_version ); 00369 if( MB_SUCCESS != result ) return result; 00370 result = mesh_model->read_metadata_info( this ); 00371 if( MB_SUCCESS != result ) return result; 00372 00373 // Now read in mesh for each geometry entity; read in order of increasing dimension 00374 // so we have all the mesh we need 00375 for( int dim = 0; dim < 4; dim++ ) 00376 { 00377 for( unsigned int gindex = 0; gindex < mesh_model->feModelHeader.geomArray.numEntities; gindex++ ) 00378 { 00379 Tqdcfr::GeomHeader* geom_header = &mesh_model->feGeomH[gindex]; 00380 00381 if( geom_header->maxDim != dim ) continue; 00382 00383 // Read nodes 00384 if( debug ) std::cout << "Reading geom index " << gindex << " mesh: nodes... "; 00385 result = read_nodes( gindex, mesh_model, geom_header ); 00386 if( MB_SUCCESS != result ) return result; 00387 00388 // Read elements 00389 if( debug ) std::cout << "elements... "; 00390 result = read_elements( mesh_model, geom_header ); 00391 if( MB_SUCCESS != result ) return result; 00392 if( debug ) std::cout << std::endl; 00393 } 00394 } 00395 00396 // *********************** 00397 // Read acis records... 00398 // *********************** 00399 std::string sat_file_name; 00400 if( MB_SUCCESS != opts.get_str_option( "SAT_FILE", sat_file_name ) ) sat_file_name.clear(); 00401 result = read_acis_records( sat_file_name.empty() ? NULL : sat_file_name.c_str() );RR; 00402 00403 // *********************** 00404 // Read groups... 00405 // *********************** 00406 if( debug ) std::cout << "Reading groups... "; 00407 for( unsigned int grindex = 0; grindex < mesh_model->feModelHeader.groupArray.numEntities; grindex++ ) 00408 { 00409 GroupHeader* group_header = &mesh_model->feGroupH[grindex]; 00410 result = read_group( grindex, mesh_model, group_header ); 00411 if( MB_SUCCESS != result ) return result; 00412 } 00413 if( debug ) std::cout << mesh_model->feModelHeader.groupArray.numEntities << " read successfully." << std::endl; 00414 00415 // *********************** 00416 // Read blocks... 00417 // *********************** 00418 if( debug ) std::cout << "Reading blocks... "; 00419 Range ho_entities; 00420 for( unsigned int blindex = 0; blindex < mesh_model->feModelHeader.blockArray.numEntities; blindex++ ) 00421 { 00422 BlockHeader* block_header = &mesh_model->feBlockH[blindex]; 00423 result = read_block( blindex, data_version, mesh_model, block_header ); 00424 if( MB_SUCCESS != result ) return result; 00425 } 00426 00427 if( debug ) std::cout << mesh_model->feModelHeader.blockArray.numEntities << " read successfully." << std::endl; 00428 00429 // *********************** 00430 // Read nodesets... 00431 // *********************** 00432 if( debug ) std::cout << "Reading nodesets... "; 00433 for( unsigned int nsindex = 0; nsindex < mesh_model->feModelHeader.nodesetArray.numEntities; nsindex++ ) 00434 { 00435 NodesetHeader* nodeset_header = &mesh_model->feNodeSetH[nsindex]; 00436 result = read_nodeset( nsindex, mesh_model, nodeset_header ); 00437 if( MB_SUCCESS != result ) return result; 00438 } 00439 if( debug ) std::cout << mesh_model->feModelHeader.nodesetArray.numEntities << " read successfully." << std::endl; 00440 00441 // *********************** 00442 // Read sidesets... 00443 // *********************** 00444 if( debug ) std::cout << "Reading sidesets..."; 00445 for( unsigned int ssindex = 0; ssindex < mesh_model->feModelHeader.sidesetArray.numEntities; ssindex++ ) 00446 { 00447 SidesetHeader* sideset_header = &mesh_model->feSideSetH[ssindex]; 00448 result = read_sideset( ssindex, data_version, mesh_model, sideset_header ); 00449 if( MB_SUCCESS != result ) return result; 00450 } 00451 if( debug ) std::cout << mesh_model->feModelHeader.sidesetArray.numEntities << " read successfully." << std::endl; 00452 00453 if( debug ) 00454 { 00455 std::cout << "Read the following mesh:" << std::endl; 00456 mdbImpl->list_entities( 0, 0 ); 00457 } 00458 00459 // Convert blocks to nodesets/sidesets if tag is set 00460 result = convert_nodesets_sidesets(); 00461 if( MB_SUCCESS != result ) return result; 00462 00463 Range after_ents; 00464 result = mdbImpl->get_entities_by_handle( 0, after_ents ); 00465 if( MB_SUCCESS != result ) return result; 00466 00467 after_ents = subtract( after_ents, beforeEnts ); 00468 00469 if( file_id_tag ) readUtilIface->assign_ids( *file_id_tag, after_ents ); 00470 00471 if( MB_SUCCESS != opts.get_null_option( "SKIP_TOPOLOGY" ) ) 00472 { 00473 // ************************** 00474 // Restore geometric topology 00475 // ************************** 00476 GeomTopoTool gtt( mdbImpl, true, 0, true, false ); 00477 result = gtt.restore_topology_from_adjacency(); 00478 if( MB_SUCCESS != result ) 00479 { 00480 std::cout << "Failed to restore topology " << std::endl; 00481 } 00482 } 00483 00484 // done with the cubit file 00485 fclose( cubFile ); 00486 return result; 00487 } 00488 00489 ErrorCode Tqdcfr::convert_nodesets_sidesets() 00490 { 00491 // Look first for the nodeset and sideset offset flags; if they're not 00492 // set, we don't need to convert 00493 const EntityHandle msh = 0; 00494 unsigned int nodeset_offset, sideset_offset; 00495 Tag tmp_tag; 00496 ErrorCode result = mdbImpl->tag_get_handle( BLOCK_NODESET_OFFSET_TAG_NAME, 1, MB_TYPE_INTEGER, tmp_tag ); 00497 if( MB_SUCCESS != result ) 00498 nodeset_offset = 0; 00499 else 00500 { 00501 result = mdbImpl->tag_get_data( tmp_tag, &msh, 1, &nodeset_offset ); 00502 if( MB_SUCCESS != result ) return result; 00503 } 00504 00505 result = mdbImpl->tag_get_handle( BLOCK_SIDESET_OFFSET_TAG_NAME, 1, MB_TYPE_INTEGER, tmp_tag ); 00506 if( MB_SUCCESS != result ) 00507 sideset_offset = 0; 00508 else 00509 { 00510 result = mdbImpl->tag_get_data( tmp_tag, &msh, 1, &sideset_offset ); 00511 if( MB_SUCCESS != result ) return result; 00512 } 00513 00514 if( 0 == nodeset_offset && 0 == sideset_offset ) return MB_SUCCESS; 00515 00516 // Look for all blocks 00517 Range blocks; 00518 result = mdbImpl->get_entities_by_type_and_tag( 0, MBENTITYSET, &blockTag, NULL, 1, blocks ); 00519 if( MB_SUCCESS != result || blocks.empty() ) return result; 00520 00521 // Get the id tag for them 00522 std::vector< int > block_ids( blocks.size() ); 00523 result = mdbImpl->tag_get_data( globalIdTag, blocks, &block_ids[0] ); 00524 if( MB_SUCCESS != result ) return result; 00525 00526 unsigned int i = 0; 00527 Range::iterator rit = blocks.begin(); 00528 Range new_nodesets, new_sidesets; 00529 std::vector< int > new_nodeset_ids, new_sideset_ids; 00530 for( ; rit != blocks.end(); i++, ++rit ) 00531 { 00532 if( 0 != nodeset_offset && block_ids[i] >= (int)nodeset_offset && 00533 ( nodeset_offset > sideset_offset || block_ids[i] < (int)sideset_offset ) ) 00534 { 00535 // This is a nodeset 00536 new_nodesets.insert( *rit ); 00537 new_nodeset_ids.push_back( block_ids[i] ); 00538 } 00539 else if( 0 != sideset_offset && block_ids[i] >= (int)sideset_offset && 00540 ( sideset_offset > nodeset_offset || block_ids[i] < (int)nodeset_offset ) ) 00541 { 00542 // This is a sideset 00543 new_sidesets.insert( *rit ); 00544 new_sideset_ids.push_back( block_ids[i] ); 00545 } 00546 } 00547 00548 // OK, have the new nodesets and sidesets; now remove the block tags, and 00549 // add nodeset and sideset tags 00550 ErrorCode tmp_result = MB_SUCCESS; 00551 if( 0 != nodeset_offset ) 00552 { 00553 if( 0 == nsTag ) 00554 { 00555 int default_val = 0; 00556 tmp_result = mdbImpl->tag_get_handle( DIRICHLET_SET_TAG_NAME, 1, MB_TYPE_INTEGER, nsTag, 00557 MB_TAG_SPARSE | MB_TAG_CREAT, &default_val ); 00558 if( MB_SUCCESS != tmp_result ) result = tmp_result; 00559 } 00560 if( MB_SUCCESS == tmp_result ) tmp_result = mdbImpl->tag_set_data( nsTag, new_nodesets, &new_nodeset_ids[0] ); 00561 if( MB_SUCCESS != tmp_result ) result = tmp_result; 00562 tmp_result = mdbImpl->tag_delete_data( blockTag, new_nodesets ); 00563 if( MB_SUCCESS != tmp_result ) result = tmp_result; 00564 } 00565 if( 0 != sideset_offset ) 00566 { 00567 if( 0 == ssTag ) 00568 { 00569 int default_val = 0; 00570 tmp_result = mdbImpl->tag_get_handle( NEUMANN_SET_TAG_NAME, 1, MB_TYPE_INTEGER, ssTag, 00571 MB_TAG_SPARSE | MB_TAG_CREAT, &default_val ); 00572 if( MB_SUCCESS != tmp_result ) result = tmp_result; 00573 } 00574 if( MB_SUCCESS == tmp_result ) tmp_result = mdbImpl->tag_set_data( ssTag, new_sidesets, &new_sideset_ids[0] ); 00575 if( MB_SUCCESS != tmp_result ) result = tmp_result; 00576 tmp_result = mdbImpl->tag_delete_data( blockTag, new_sidesets ); 00577 if( MB_SUCCESS != tmp_result ) result = tmp_result; 00578 } 00579 00580 return result; 00581 } 00582 00583 ErrorCode Tqdcfr::read_nodeset( const unsigned int nsindex, Tqdcfr::ModelEntry* model, Tqdcfr::NodesetHeader* nodeseth ) 00584 { 00585 if( nodeseth->memTypeCt == 0 ) return MB_SUCCESS; 00586 00587 // Position file 00588 FSEEK( model->modelOffset + nodeseth->memOffset ); 00589 00590 // Read ids for each entity type 00591 unsigned int this_type, num_ents; //, uid; 00592 std::vector< char > bc_data; 00593 unsigned int num_read = 0; 00594 std::vector< EntityHandle > ns_entities, excl_entities; 00595 for( unsigned int i = 0; i < nodeseth->memTypeCt; i++ ) 00596 { 00597 // Get how many and what type 00598 FREADI( 2 ); 00599 num_read += 2 * sizeof( int ); 00600 this_type = uint_buf[0]; 00601 num_ents = uint_buf[1]; 00602 00603 // Now get the ids 00604 FREADI( num_ents ); 00605 num_read += sizeof( int ); 00606 CONVERT_TO_INTS( num_ents ); 00607 00608 ErrorCode result = get_entities( this_type + 2, &int_buf[0], num_ents, ns_entities, excl_entities ); 00609 if( MB_SUCCESS != result ) return result; 00610 } 00611 // Check for more data 00612 if( num_read < nodeseth->nsLength ) 00613 { 00614 FREADC( 2 ); // num_read += 2; 00615 if( char_buf[0] == 'i' && char_buf[1] == 'd' ) 00616 { 00617 FREADI( 1 ); // num_read += sizeof(int); 00618 // uid = int_buf[0]; 00619 } 00620 else 00621 { 00622 if( char_buf[0] == 'b' && char_buf[1] == 'c' ) 00623 { 00624 FREADI( 1 ); // num_read += sizeof(int); 00625 int num_bcs = uint_buf[0]; 00626 bc_data.resize( num_bcs ); 00627 FREADCA( num_bcs, &bc_data[0] ); // num_read += num_bcs; 00628 } 00629 } 00630 } 00631 00632 if( debug ) 00633 { 00634 nodeseth->print(); 00635 if( !bc_data.empty() ) 00636 { 00637 std::cout << "bc_data = "; 00638 std::vector< char >::iterator vit = bc_data.begin(); 00639 for( ; vit != bc_data.end(); ++vit ) 00640 { 00641 std::cout << std::hex << (int)( (unsigned char)*vit ) << " "; 00642 } 00643 std::cout << ": "; 00644 vit = bc_data.begin(); 00645 for( ; vit != bc_data.end(); ++vit ) 00646 { 00647 std::cout << *vit; 00648 } 00649 std::cout << std::endl; 00650 } 00651 } 00652 00653 // And put entities into this nodeset's set 00654 ErrorCode result = put_into_set( nodeseth->setHandle, ns_entities, excl_entities ); 00655 if( MB_SUCCESS != result ) return result; 00656 00657 result = get_names( model->nodesetMD, nsindex, nodeseth->setHandle ); 00658 if( MB_SUCCESS != result ) return result; 00659 00660 const int def_bc_data_len = 0; 00661 std::string tag_name = std::string( DIRICHLET_SET_TAG_NAME ) + "__BC_DATA"; 00662 Tag nbc_data; 00663 result = mdbImpl->tag_get_handle( tag_name.c_str(), def_bc_data_len, MB_TYPE_OPAQUE, nbc_data, 00664 MB_TAG_CREAT | MB_TAG_SPARSE | MB_TAG_BYTES | MB_TAG_VARLEN, NULL ); 00665 if( MB_SUCCESS != result ) return result; 00666 void const* tag_data[] = { ( bc_data.empty() ) ? NULL : &( bc_data[0] ) }; 00667 int tag_size = bc_data.size(); 00668 result = mdbImpl->tag_set_by_ptr( nbc_data, &nodeseth->setHandle, 1, tag_data, &tag_size ); 00669 if( MB_SUCCESS != result ) return result; 00670 00671 return result; 00672 } 00673 00674 ErrorCode Tqdcfr::read_sideset( const unsigned int ssindex, 00675 const double data_version, 00676 Tqdcfr::ModelEntry* model, 00677 Tqdcfr::SidesetHeader* sideseth ) 00678 { 00679 if( sideseth->memCt == 0 ) return MB_SUCCESS; 00680 00681 ErrorCode result; 00682 00683 // Position file 00684 FSEEK( model->modelOffset + sideseth->memOffset ); 00685 00686 // Read ids for each entity type 00687 unsigned int this_type, num_ents, sense_size; 00688 00689 std::vector< char > bc_data; 00690 unsigned int num_read = 0; //, uid; 00691 std::vector< EntityHandle > ss_entities, excl_entities; 00692 if( data_version <= 1.0 ) 00693 { 00694 for( unsigned int i = 0; i < sideseth->memTypeCt; i++ ) 00695 { 00696 // Get how many and what type 00697 FREADI( 3 ); 00698 num_read += 3 * sizeof( int ); 00699 this_type = uint_buf[0]; 00700 num_ents = uint_buf[1]; 00701 sense_size = uint_buf[2]; 00702 00703 // Now get the ids 00704 FREADI( num_ents ); 00705 num_read += sizeof( int ); 00706 CONVERT_TO_INTS( num_ents ); 00707 00708 result = get_entities( this_type + 2, &int_buf[0], num_ents, ss_entities, excl_entities ); 00709 if( MB_SUCCESS != result ) return result; 00710 00711 if( sense_size == 1 ) 00712 { 00713 // Byte-size sense flags; make sure read ends aligned... 00714 unsigned int read_length = ( num_ents / 8 ) * 8; 00715 if( read_length < num_ents ) read_length += 8; 00716 FREADC( read_length ); 00717 num_read += read_length; 00718 } 00719 else if( sense_size == 2 ) 00720 { 00721 // Int-size sense flags 00722 FREADI( num_ents ); 00723 num_read += sizeof( int ); 00724 } 00725 00726 // Now do something with them... 00727 process_sideset_10( this_type, num_ents, sense_size, ss_entities, sideseth ); 00728 } 00729 } 00730 else 00731 { 00732 for( unsigned int i = 0; i < sideseth->memTypeCt; i++ ) 00733 { 00734 // Get how many and what type 00735 FREADI( 1 ); 00736 num_read += sizeof( int ); 00737 num_ents = uint_buf[0]; 00738 00739 // Get the types, and ids 00740 std::vector< unsigned int > mem_types( num_ents ), mem_ids( num_ents ); 00741 FREADIA( num_ents, &mem_types[0] ); 00742 num_read += num_ents * sizeof( int ); 00743 FREADI( num_ents ); 00744 num_read += sizeof( int ); 00745 00746 result = get_entities( &mem_types[0], &int_buf[0], num_ents, false, ss_entities ); 00747 if( MB_SUCCESS != result ) return result; 00748 00749 // Byte-size sense flags; make sure read ends aligned... 00750 unsigned int read_length = ( num_ents / 8 ) * 8; 00751 if( read_length < num_ents ) read_length += 8; 00752 FREADC( read_length ); 00753 num_read += read_length; 00754 00755 // wrt entities 00756 FREADI( 1 ); 00757 num_read += sizeof( int ); 00758 int num_wrts = uint_buf[0]; 00759 FREADI( num_wrts ); 00760 num_read += num_wrts * sizeof( int ); 00761 00762 result = process_sideset_11( ss_entities, num_wrts, sideseth ); 00763 if( MB_SUCCESS != result ) return result; 00764 } 00765 } 00766 00767 // Now set the dist factors 00768 if( sideseth->numDF > 0 ) 00769 { 00770 // Have to read dist factors 00771 FREADD( sideseth->numDF ); 00772 num_read += sideseth->numDF * sizeof( double ); 00773 Tag distFactorTag; 00774 result = mdbImpl->tag_get_handle( "distFactor", 0, MB_TYPE_DOUBLE, distFactorTag, 00775 MB_TAG_SPARSE | MB_TAG_VARLEN | MB_TAG_CREAT ); 00776 if( MB_SUCCESS != result ) return result; 00777 const void* dist_data = &dbl_buf[0]; 00778 const int dist_size = sideseth->numDF; 00779 result = mdbImpl->tag_set_by_ptr( distFactorTag, &sideseth->setHandle, 1, &dist_data, &dist_size ); 00780 if( MB_SUCCESS != result ) return result; 00781 } 00782 00783 // Check for more data 00784 if( data_version > 1.0 && num_read < sideseth->ssLength ) 00785 { 00786 FREADC( 2 ); // num_read += 2; 00787 if( char_buf[0] == 'i' && char_buf[1] == 'd' ) 00788 { 00789 FREADI( 1 ); // num_read += sizeof(int); 00790 // uid = int_buf[0]; 00791 } 00792 else 00793 { 00794 // Check for bc_data 00795 if( char_buf[0] == 'b' && char_buf[1] == 'c' ) 00796 { 00797 FREADI( 1 ); // num_read += sizeof(int); 00798 int num_bcs = uint_buf[0]; 00799 bc_data.resize( num_bcs ); 00800 FREADCA( num_bcs, &bc_data[0] ); // num_read += num_bcs; 00801 } 00802 } 00803 } 00804 00805 if( debug ) 00806 { 00807 sideseth->print(); 00808 if( !bc_data.empty() ) 00809 { 00810 std::cout << "bc_data = "; 00811 std::vector< char >::iterator vit = bc_data.begin(); 00812 for( ; vit != bc_data.end(); ++vit ) 00813 { 00814 std::cout << std::hex << (int)( (unsigned char)*vit ) << " "; 00815 } 00816 std::cout << ": "; 00817 vit = bc_data.begin(); 00818 for( ; vit != bc_data.end(); ++vit ) 00819 { 00820 std::cout << *vit; 00821 } 00822 std::cout << std::endl; 00823 } 00824 } 00825 00826 result = get_names( model->sidesetMD, ssindex, sideseth->setHandle ); 00827 if( MB_SUCCESS != result ) return result; 00828 00829 const int def_bc_data_len = 0; 00830 std::string tag_name = std::string( NEUMANN_SET_TAG_NAME ) + "__BC_DATA"; 00831 Tag nbc_data; 00832 result = mdbImpl->tag_get_handle( tag_name.c_str(), def_bc_data_len, MB_TYPE_OPAQUE, nbc_data, 00833 MB_TAG_CREAT | MB_TAG_SPARSE | MB_TAG_BYTES | MB_TAG_VARLEN, NULL ); 00834 if( MB_SUCCESS != result ) return result; 00835 void const* tag_data[] = { ( bc_data.empty() ) ? NULL : &( bc_data[0] ) }; 00836 int tag_size = bc_data.size(); 00837 result = mdbImpl->tag_set_by_ptr( nbc_data, &sideseth->setHandle, 1, tag_data, &tag_size ); 00838 if( MB_SUCCESS != result ) return result; 00839 00840 return MB_SUCCESS; 00841 } 00842 00843 ErrorCode Tqdcfr::process_sideset_10( const int this_type, 00844 const int num_ents, 00845 const int sense_size, 00846 std::vector< EntityHandle >& ss_entities, 00847 Tqdcfr::SidesetHeader* sideseth ) 00848 { 00849 std::vector< EntityHandle > forward, reverse; 00850 if( this_type == 3 // Surface 00851 && sense_size == 1 // Byte size 00852 ) 00853 { 00854 // Interpret sense flags w/o reference to anything 00855 for( int i = 0; i < num_ents; i++ ) 00856 { 00857 if( (int)char_buf[i] == 0 ) 00858 forward.push_back( ss_entities[i] ); 00859 else if( (int)char_buf[i] == 1 ) 00860 reverse.push_back( ss_entities[i] ); 00861 else if( (int)char_buf[i] == -1 ) 00862 { // -1 means "unknown", which means both 00863 forward.push_back( ss_entities[i] ); 00864 reverse.push_back( ss_entities[i] ); 00865 } 00866 } 00867 } 00868 else if( this_type == 4 // Curve 00869 && sense_size == 2 // int32 size 00870 ) 00871 { 00872 for( int i = 0; i < num_ents; i++ ) 00873 { 00874 if( uint_buf[i] == 0 ) 00875 forward.push_back( ss_entities[i] ); 00876 else if( uint_buf[i] == 1 ) 00877 reverse.push_back( ss_entities[i] ); 00878 else if( *( (int*)&uint_buf[i] ) == -1 ) 00879 { // -1 means "unknown", which means both 00880 forward.push_back( ss_entities[i] ); 00881 reverse.push_back( ss_entities[i] ); 00882 } 00883 } 00884 } 00885 00886 // Now actually put them in the set 00887 ErrorCode result = MB_SUCCESS; 00888 if( !forward.empty() ) 00889 { 00890 ErrorCode tmp_result = mdbImpl->add_entities( sideseth->setHandle, &forward[0], forward.size() ); 00891 if( tmp_result != MB_SUCCESS ) result = tmp_result; 00892 } 00893 if( !reverse.empty() ) 00894 { 00895 // Need to make a new set, add a reverse sense tag, then add to the sideset 00896 EntityHandle reverse_set; 00897 ErrorCode tmp_result = create_set( reverse_set ); 00898 if( MB_SUCCESS != tmp_result ) result = tmp_result; 00899 tmp_result = mdbImpl->add_entities( reverse_set, &reverse[0], reverse.size() ); 00900 if( tmp_result != MB_SUCCESS ) result = tmp_result; 00901 int def_val = 1; 00902 Tag sense_tag; 00903 tmp_result = mdbImpl->tag_get_handle( "NEUSET_SENSE", 1, MB_TYPE_INTEGER, sense_tag, 00904 MB_TAG_SPARSE | MB_TAG_CREAT, &def_val ); 00905 if( tmp_result != MB_SUCCESS ) result = tmp_result; 00906 def_val = -1; 00907 tmp_result = mdbImpl->tag_set_data( sense_tag, &reverse_set, 1, &def_val ); 00908 if( tmp_result != MB_SUCCESS ) result = tmp_result; 00909 tmp_result = mdbImpl->add_entities( sideseth->setHandle, &reverse_set, 1 ); 00910 if( tmp_result != MB_SUCCESS ) result = tmp_result; 00911 } 00912 00913 return result; 00914 } 00915 00916 ErrorCode Tqdcfr::process_sideset_11( std::vector< EntityHandle >& ss_entities, 00917 int num_wrts, 00918 Tqdcfr::SidesetHeader* sideseth ) 00919 { 00920 std::vector< EntityHandle > forward, reverse; 00921 00922 unsigned int num_ents = ss_entities.size(); 00923 unsigned int* wrt_it = &uint_buf[0]; 00924 00925 for( unsigned int i = 0; i < num_ents; i++ ) 00926 { 00927 unsigned int num_wrt = 0; 00928 if( 0 != num_wrts ) num_wrt = *wrt_it++; 00929 for( unsigned int j = 0; j < num_wrt; j++ ) 00930 wrt_it += 2; 00931 // Assume here that if it's in the list twice, we get both senses 00932 if( num_wrt > 1 ) 00933 { 00934 forward.push_back( ss_entities[i] ); 00935 reverse.push_back( ss_entities[i] ); 00936 } 00937 else 00938 { 00939 // Else interpret the sense flag 00940 if( (int)char_buf[i] == 0 ) 00941 forward.push_back( ss_entities[i] ); 00942 else if( (int)char_buf[i] == 1 ) 00943 reverse.push_back( ss_entities[i] ); 00944 else if( (int)char_buf[i] == -1 ) 00945 { // -1 means "unknown", which means both 00946 forward.push_back( ss_entities[i] ); 00947 reverse.push_back( ss_entities[i] ); 00948 } 00949 } 00950 } 00951 00952 // Now actually put them in the set 00953 ErrorCode result = MB_SUCCESS; 00954 if( !forward.empty() ) 00955 { 00956 ErrorCode tmp_result = mdbImpl->add_entities( sideseth->setHandle, &forward[0], forward.size() ); 00957 if( tmp_result != MB_SUCCESS ) result = tmp_result; 00958 } 00959 if( !reverse.empty() ) 00960 { 00961 // Need to make a new set, add a reverse sense tag, then add to the sideset 00962 EntityHandle reverse_set; 00963 ErrorCode tmp_result = create_set( reverse_set ); 00964 if( MB_SUCCESS != tmp_result ) result = tmp_result; 00965 tmp_result = mdbImpl->add_entities( reverse_set, &reverse[0], reverse.size() ); 00966 if( tmp_result != MB_SUCCESS ) result = tmp_result; 00967 int def_val = 1; 00968 Tag sense_tag; 00969 tmp_result = mdbImpl->tag_get_handle( "NEUSET_SENSE", 1, MB_TYPE_INTEGER, sense_tag, 00970 MB_TAG_SPARSE | MB_TAG_CREAT, &def_val ); 00971 if( tmp_result != MB_SUCCESS && tmp_result != MB_ALREADY_ALLOCATED ) result = tmp_result; 00972 def_val = -1; 00973 tmp_result = mdbImpl->tag_set_data( sense_tag, &reverse_set, 1, &def_val ); 00974 if( tmp_result != MB_SUCCESS ) result = tmp_result; 00975 tmp_result = mdbImpl->add_entities( sideseth->setHandle, &reverse_set, 1 ); 00976 if( tmp_result != MB_SUCCESS ) result = tmp_result; 00977 } 00978 00979 return result; 00980 } 00981 00982 ErrorCode Tqdcfr::read_block( const unsigned int blindex, 00983 const double /*data_version*/, 00984 Tqdcfr::ModelEntry* model, 00985 Tqdcfr::BlockHeader* blockh ) 00986 { 00987 if( blockh->memCt == 0 ) return MB_SUCCESS; 00988 00989 // Position file 00990 FSEEK( model->modelOffset + blockh->memOffset ); 00991 00992 // Read ids for each entity type 00993 unsigned int num_read = 0; 00994 int this_type, num_ents; //, uid; 00995 std::vector< EntityHandle > block_entities, excl_entities; 00996 for( unsigned int i = 0; i < blockh->memTypeCt; i++ ) 00997 { 00998 // Get how many and what type 00999 FREADI( 2 ); 01000 num_read += 2 * sizeof( int ); 01001 this_type = uint_buf[0]; 01002 num_ents = uint_buf[1]; 01003 01004 // Now get the ids 01005 FREADI( num_ents ); 01006 num_read += num_ents * sizeof( int ); 01007 CONVERT_TO_INTS( num_ents ); 01008 01009 ErrorCode result = get_entities( this_type + 2, &int_buf[0], num_ents, block_entities, excl_entities ); 01010 if( MB_SUCCESS != result ) return result; 01011 } 01012 01013 // And put entities into this block's set 01014 ErrorCode result = put_into_set( blockh->setHandle, block_entities, excl_entities ); 01015 if( MB_SUCCESS != result ) return result; 01016 01017 // Read attribs if there are any 01018 Tag block_attribs; 01019 { 01020 int def_block_attributes_length = 0; 01021 result = mdbImpl->tag_get_handle( BLOCK_ATTRIBUTES, def_block_attributes_length, MB_TYPE_DOUBLE, block_attribs, 01022 MB_TAG_CREAT | MB_TAG_SPARSE | MB_TAG_VARLEN, NULL ); 01023 if( MB_SUCCESS != result && MB_ALREADY_ALLOCATED != result ) return result; 01024 } 01025 01026 if( blockh->attribOrder > 0 ) 01027 { 01028 FREADD( blockh->attribOrder ); 01029 num_read += sizeof( double ); 01030 void const* tag_data[] = { &dbl_buf[0] }; 01031 int tag_sizes[] = { static_cast< int >( blockh->attribOrder ) }; 01032 result = mdbImpl->tag_set_by_ptr( block_attribs, &( blockh->setHandle ), 1, tag_data, tag_sizes ); 01033 if( MB_SUCCESS != result ) return result; 01034 } 01035 01036 // Check for more data 01037 if( num_read < blockh->blockLength ) 01038 { 01039 FREADC( 2 ); // num_read += 2; 01040 if( char_buf[0] == 'i' && char_buf[1] == 'd' ) 01041 { 01042 FREADI( 1 ); // num_read += sizeof(int); 01043 // uid = int_buf[0]; 01044 } 01045 } 01046 01047 result = get_names( model->blockMD, blindex, blockh->setHandle ); 01048 if( MB_SUCCESS != result ) return result; 01049 01050 // Put additional higher-order nodes into element connectivity list. 01051 // Cubit saves full connectivity list only for NodeHex and NodeTet 01052 // elements. Other element types will only have the corners and 01053 // the mid-element node if there is one. Need to reconstruct additional 01054 // connectivity entries from mid-nodes of adjacent lower-order entities. 01055 int node_per_elem = cub_elem_num_verts[blockh->blockElemType]; 01056 if( blockh->blockEntityType == MBMAXTYPE ) return MB_SUCCESS; 01057 if( ( 14 == major && 2 < minor ) || 15 <= major ) 01058 { 01059 if( 55 == blockh->blockElemType || CN::VerticesPerEntity( blockh->blockEntityType ) == node_per_elem ) 01060 return MB_SUCCESS; 01061 } 01062 else 01063 { 01064 if( 52 == blockh->blockElemType || CN::VerticesPerEntity( blockh->blockEntityType ) == node_per_elem ) 01065 return MB_SUCCESS; 01066 } 01067 01068 // Can't use Interface::convert_entities because block could contain 01069 // both entity sets and entities. convert_entities will fail if block 01070 // contains an entity set, but we still need to call it on any elements 01071 // directly in the block (rather than a geometry subset). So bypass 01072 // Interface and call HOFactory directly with an Range of entities. 01073 Range ho_entities, entities; 01074 mdbImpl->get_entities_by_type( blockh->setHandle, blockh->blockEntityType, entities, true ); 01075 if( CN::Dimension( blockh->blockEntityType ) > 2 ) 01076 { 01077 result = mdbImpl->get_adjacencies( entities, 2, false, ho_entities, Interface::UNION ); 01078 if( MB_SUCCESS != result ) return result; 01079 } 01080 if( CN::Dimension( blockh->blockEntityType ) > 1 ) 01081 { 01082 result = mdbImpl->get_adjacencies( entities, 1, false, ho_entities, Interface::UNION ); 01083 if( MB_SUCCESS != result ) return result; 01084 } 01085 entities.merge( ho_entities ); 01086 01087 Core* mbcore = dynamic_cast< Core* >( mdbImpl ); 01088 assert( mbcore != NULL ); 01089 HigherOrderFactory ho_fact( mbcore, 0 ); 01090 return ho_fact.convert( entities, !!blockh->hasMidNodes[1], !!blockh->hasMidNodes[2], !!blockh->hasMidNodes[3] ); 01091 } 01092 01093 ErrorCode Tqdcfr::get_names( MetaDataContainer& md, unsigned int set_index, EntityHandle seth ) 01094 { 01095 ErrorCode result = MB_SUCCESS; 01096 01097 // Now get block names, if any 01098 int md_index = md.get_md_entry( set_index, "Name" ); 01099 if( -1 == md_index ) return result; 01100 MetaDataContainer::MetaDataEntry* md_entry = &( md.metadataEntries[md_index] ); 01101 // assert(md_entry->mdStringValue.length() + 1 <= NAME_TAG_SIZE); 01102 char name_tag_data[NAME_TAG_SIZE]; 01103 memset( name_tag_data, 0, NAME_TAG_SIZE ); // Make sure any extra bytes zeroed 01104 strncpy( name_tag_data, md_entry->mdStringValue.c_str(), NAME_TAG_SIZE - 1 ); 01105 result = mdbImpl->tag_set_data( entityNameTag, &seth, 1, name_tag_data ); 01106 if( MB_SUCCESS != result ) return result; 01107 01108 // Look for extra names 01109 md_index = md.get_md_entry( set_index, "NumExtraNames" ); 01110 if( -1 == md_index ) return result; 01111 int num_names = md.metadataEntries[md_index].mdIntValue; 01112 for( int i = 0; i < num_names; i++ ) 01113 { 01114 std::ostringstream extra_name_label( "ExtraName" ); 01115 extra_name_label << i; 01116 std::ostringstream moab_extra_name( "EXTRA_" ); 01117 moab_extra_name << NAME_TAG_NAME << i; 01118 md_index = md.get_md_entry( set_index, extra_name_label.str().c_str() ); 01119 if( -1 != md_index ) 01120 { 01121 md_entry = &( md.metadataEntries[md_index] ); 01122 Tag extra_name_tag; 01123 ErrorCode rval; 01124 rval = mdbImpl->tag_get_handle( moab_extra_name.str().c_str(), NAME_TAG_SIZE, MB_TYPE_OPAQUE, 01125 extra_name_tag, MB_TAG_SPARSE | MB_TAG_CREAT );MB_CHK_ERR( rval ); 01126 memset( name_tag_data, 0, NAME_TAG_SIZE ); // Make sure any extra bytes zeroed 01127 strncpy( name_tag_data, md_entry->mdStringValue.c_str(), NAME_TAG_SIZE - 1 ); 01128 result = mdbImpl->tag_set_data( extra_name_tag, &seth, 1, name_tag_data ); 01129 } 01130 } 01131 01132 return result; 01133 } 01134 01135 ErrorCode Tqdcfr::read_group( const unsigned int group_index, Tqdcfr::ModelEntry* model, Tqdcfr::GroupHeader* grouph ) 01136 { 01137 // Position file 01138 FSEEK( model->modelOffset + grouph->memOffset ); 01139 char name_tag_data[NAME_TAG_SIZE]; 01140 01141 // Read ids for each entity type 01142 int this_type, num_ents; 01143 std::vector< EntityHandle > grp_entities, excl_entities; 01144 for( unsigned int i = 0; i < grouph->memTypeCt; i++ ) 01145 { 01146 // Get how many and what type 01147 FREADI( 2 ); 01148 this_type = uint_buf[0]; 01149 num_ents = uint_buf[1]; 01150 01151 // Now get the ids 01152 FREADI( num_ents ); 01153 CONVERT_TO_INTS( num_ents ); 01154 01155 // Get the entities in this group 01156 ErrorCode result = get_entities( this_type, &int_buf[0], num_ents, grp_entities, excl_entities ); 01157 if( MB_SUCCESS != result ) return result; 01158 } 01159 01160 // Now add the entities 01161 ErrorCode result = put_into_set( grouph->setHandle, grp_entities, excl_entities ); 01162 if( MB_SUCCESS != result ) return result; 01163 01164 // Now get group names, if any 01165 int md_index = model->groupMD.get_md_entry( grouph->grpID, "NAME" ); 01166 if( -1 != md_index ) 01167 { 01168 MetaDataContainer::MetaDataEntry* md_entry = &( model->groupMD.metadataEntries[md_index] ); 01169 if( 0 == entityNameTag ) 01170 { 01171 memset( name_tag_data, 0, NAME_TAG_SIZE ); 01172 result = mdbImpl->tag_get_handle( NAME_TAG_NAME, NAME_TAG_SIZE, MB_TYPE_OPAQUE, entityNameTag, 01173 MB_TAG_SPARSE | MB_TAG_CREAT, name_tag_data ); 01174 if( MB_SUCCESS != result ) return result; 01175 } 01176 // assert(md_entry->mdStringValue.length() + 1 <= NAME_TAG_SIZE); 01177 memset( name_tag_data, 0, NAME_TAG_SIZE ); // Make sure any extra bytes zeroed 01178 strncpy( name_tag_data, md_entry->mdStringValue.c_str(), NAME_TAG_SIZE - 1 ); 01179 result = mdbImpl->tag_set_data( entityNameTag, &grouph->setHandle, 1, name_tag_data ); 01180 if( MB_SUCCESS != result ) return result; 01181 01182 // Look for extra names 01183 md_index = model->groupMD.get_md_entry( group_index, "NumExtraNames" ); 01184 if( -1 != md_index ) 01185 { 01186 int num_names = model->groupMD.metadataEntries[md_index].mdIntValue; 01187 for( int i = 0; i < num_names; i++ ) 01188 { 01189 std::ostringstream extra_name_label( "ExtraName" ); 01190 extra_name_label << i; 01191 std::ostringstream moab_extra_name( "EXTRA_" ); 01192 moab_extra_name << NAME_TAG_NAME << i; 01193 md_index = model->groupMD.get_md_entry( group_index, extra_name_label.str().c_str() ); 01194 if( -1 != md_index ) 01195 { 01196 md_entry = &( model->groupMD.metadataEntries[md_index] ); 01197 Tag extra_name_tag; 01198 memset( name_tag_data, 0, NAME_TAG_SIZE ); 01199 result = mdbImpl->tag_get_handle( moab_extra_name.str().c_str(), NAME_TAG_SIZE, MB_TYPE_OPAQUE, 01200 extra_name_tag, MB_TAG_SPARSE | MB_TAG_CREAT, name_tag_data ); 01201 if( MB_SUCCESS != result ) return result; 01202 // assert(md_entry->mdStringValue.length() + 1 <= NAME_TAG_SIZE); 01203 memset( name_tag_data, 0, NAME_TAG_SIZE ); // Make sure any extra bytes zeroed 01204 strncpy( name_tag_data, md_entry->mdStringValue.c_str(), NAME_TAG_SIZE - 1 ); 01205 result = mdbImpl->tag_set_data( extra_name_tag, &grouph->setHandle, 1, name_tag_data ); 01206 } 01207 } 01208 } 01209 } 01210 01211 return result; 01212 } 01213 01214 ErrorCode Tqdcfr::put_into_set( EntityHandle set_handle, 01215 std::vector< EntityHandle >& entities, 01216 std::vector< EntityHandle >& excl_entities ) 01217 { 01218 // And put entities into this block's set 01219 ErrorCode result = mdbImpl->add_entities( set_handle, &entities[0], entities.size() ); 01220 if( MB_SUCCESS != result ) return result; 01221 01222 // Check for excluded entities, and add them to a vector hung off the block if there 01223 Tag excl_tag; 01224 if( !excl_entities.empty() ) 01225 { 01226 result = mdbImpl->tag_get_handle( "Exclude_Entities", sizeof( std::vector< EntityHandle >* ), MB_TYPE_OPAQUE, 01227 excl_tag, MB_TAG_SPARSE | MB_TAG_CREAT ); 01228 if( MB_SUCCESS != result ) return result; 01229 std::vector< EntityHandle >* new_vector = new std::vector< EntityHandle >; 01230 new_vector->swap( excl_entities ); 01231 result = mdbImpl->tag_set_data( excl_tag, &set_handle, 1, &new_vector ); 01232 if( MB_SUCCESS != result ) 01233 { 01234 delete new_vector; 01235 return MB_FAILURE; 01236 } 01237 } 01238 01239 return MB_SUCCESS; 01240 } 01241 01242 ErrorCode Tqdcfr::get_entities( const unsigned int* mem_types, 01243 int* id_buf, 01244 const unsigned int id_buf_size, 01245 const bool is_group, 01246 std::vector< EntityHandle >& entities ) 01247 { 01248 ErrorCode tmp_result, result = MB_SUCCESS; 01249 01250 for( unsigned int i = 0; i < id_buf_size; i++ ) 01251 { 01252 if( is_group ) 01253 tmp_result = get_entities( mem_types[i], id_buf + i, 1, entities, entities ); 01254 else 01255 // For blocks/nodesets/sidesets, use CSOEntityType, which is 2 greater than 01256 // group entity types 01257 tmp_result = get_entities( mem_types[i] + 2, id_buf + i, 1, entities, entities ); 01258 if( MB_SUCCESS != tmp_result ) result = tmp_result; 01259 } 01260 01261 return result; 01262 } 01263 01264 ErrorCode Tqdcfr::get_entities( const unsigned int this_type, 01265 int* id_buf, 01266 const unsigned int id_buf_size, 01267 std::vector< EntityHandle >& entities, 01268 std::vector< EntityHandle >& excl_entities ) 01269 { 01270 ErrorCode result = MB_FAILURE; 01271 01272 if( this_type <= VERTEX ) 01273 result = get_ref_entities( this_type, id_buf, id_buf_size, entities ); 01274 else if( this_type >= HEX && this_type <= NODE ) 01275 result = get_mesh_entities( this_type, id_buf, id_buf_size, entities, excl_entities ); 01276 01277 return result; 01278 } 01279 01280 ErrorCode Tqdcfr::get_ref_entities( const unsigned int this_type, 01281 int* id_buf, 01282 const unsigned int id_buf_size, 01283 std::vector< EntityHandle >& entities ) 01284 { 01285 for( unsigned int i = 0; i < id_buf_size; i++ ) 01286 entities.push_back( ( gidSetMap[5 - this_type] )[id_buf[i]] ); 01287 01288 return MB_SUCCESS; 01289 } 01290 01291 ErrorCode Tqdcfr::get_mesh_entities( const unsigned int this_type, 01292 int* id_buf, 01293 const unsigned int id_buf_size, 01294 std::vector< EntityHandle >& entities, 01295 std::vector< EntityHandle >& excl_entities ) 01296 { 01297 ErrorCode result = MB_SUCCESS; 01298 std::vector< EntityHandle >* ent_list = NULL; 01299 EntityType this_ent_type = MBVERTEX; 01300 const unsigned int arr_len = sizeof( group_type_to_mb_type ) / sizeof( group_type_to_mb_type[0] ); 01301 if( this_type > 1000 ) 01302 { 01303 if( this_type - 1000 < arr_len ) 01304 { 01305 this_ent_type = group_type_to_mb_type[this_type - 1000]; 01306 ent_list = &excl_entities; 01307 } 01308 } 01309 else 01310 { 01311 if( this_type < arr_len ) 01312 { 01313 this_ent_type = group_type_to_mb_type[this_type]; 01314 ent_list = &entities; 01315 } 01316 } 01317 if( NULL == ent_list ) 01318 { 01319 MB_SET_ERR( MB_FAILURE, "Entities list is NULL" ); 01320 } 01321 01322 // Get entities with this type, and get their cub id tags 01323 if( MBVERTEX == this_ent_type ) 01324 { 01325 // Use either vertex offset or cubMOABVertexMap 01326 if( NULL == cubMOABVertexMap ) 01327 { 01328 for( unsigned int i = 0; i < id_buf_size; i++ ) 01329 ent_list->push_back( (EntityHandle)( id_buf[i] + currVHandleOffset ) ); 01330 } 01331 else 01332 { 01333 for( unsigned int i = 0; i < id_buf_size; i++ ) 01334 { 01335 assert( 0 != ( *cubMOABVertexMap )[id_buf[i]] ); 01336 ent_list->push_back( ( *cubMOABVertexMap )[id_buf[i]] ); 01337 } 01338 } 01339 } 01340 else 01341 { 01342 Range tmp_ents; 01343 result = mdbImpl->get_entities_by_type( 0, this_ent_type, tmp_ents ); 01344 if( MB_SUCCESS != result ) return result; 01345 if( tmp_ents.empty() && 0 != id_buf_size ) return MB_FAILURE; 01346 01347 std::vector< int > cub_ids( tmp_ents.size() ); 01348 result = mdbImpl->tag_get_data( globalIdTag, tmp_ents, &cub_ids[0] ); 01349 if( MB_SUCCESS != result && MB_TAG_NOT_FOUND != result ) return result; 01350 01351 // Now go through id list, finding each entity by id 01352 for( unsigned int i = 0; i < id_buf_size; i++ ) 01353 { 01354 std::vector< int >::iterator vit = std::find( cub_ids.begin(), cub_ids.end(), id_buf[i] ); 01355 if( vit != cub_ids.end() ) 01356 { 01357 EntityHandle this_ent = tmp_ents[vit - cub_ids.begin()]; 01358 if( mdbImpl->type_from_handle( this_ent ) != MBMAXTYPE ) ent_list->push_back( this_ent ); 01359 } 01360 else 01361 { 01362 std::cout << "Warning: didn't find " << CN::EntityTypeName( this_ent_type ) << " " << id_buf[i] 01363 << std::endl; 01364 } 01365 } 01366 } 01367 01368 return result; 01369 } 01370 01371 ErrorCode Tqdcfr::read_nodes( const unsigned int gindex, Tqdcfr::ModelEntry* model, Tqdcfr::GeomHeader* entity ) 01372 { 01373 if( entity->nodeCt == 0 ) 01374 { 01375 if( debug ) std::cout << "(no nodes) "; 01376 return MB_SUCCESS; 01377 } 01378 01379 // Get the ids & coords in separate calls to minimize memory usage 01380 // Position the file 01381 FSEEK( model->modelOffset + entity->nodeOffset ); 01382 // Get node ids in uint_buf 01383 FREADI( entity->nodeCt ); 01384 01385 if( debug ) 01386 { 01387 std::cout << "("; 01388 for( unsigned int i = 0; i < entity->nodeCt; i++ ) 01389 { 01390 std::cout << uint_buf[i]; 01391 if( i != entity->nodeCt - 1 ) std::cout << ", "; 01392 } 01393 std::cout << ")..."; 01394 } 01395 01396 // Get a space for reading nodal data directly into MB, and read that data 01397 EntityHandle vhandle = 0; 01398 std::vector< double* > arrays; 01399 readUtilIface->get_node_coords( 3, entity->nodeCt, uint_buf[0], vhandle, arrays, 01400 SequenceManager::DEFAULT_VERTEX_SEQUENCE_SIZE ); 01401 01402 // Get node x's in arrays[0] 01403 FREADDA( entity->nodeCt, arrays[0] ); 01404 // Get node y's in arrays[1] 01405 FREADDA( entity->nodeCt, arrays[1] ); 01406 // Get node z's in arrays[2] 01407 FREADDA( entity->nodeCt, arrays[2] ); 01408 01409 // Add these nodes into the entity's set 01410 Range dum_range( vhandle, vhandle + entity->nodeCt - 1 ); 01411 ErrorCode result = mdbImpl->add_entities( entity->setHandle, dum_range ); 01412 if( MB_SUCCESS != result ) return result; 01413 01414 // Check for id contiguity; know that cid's will never be > 32bit, so 01415 // ids can be unsigned int 01416 unsigned int max_cid, min_cid; 01417 int contig; 01418 check_contiguous( entity->nodeCt, contig, min_cid, max_cid ); 01419 01420 // Compute the offset we get in this batch and compare to any previous one 01421 long vhandle_offset = vhandle - min_cid; 01422 if( -1 == currVHandleOffset ) currVHandleOffset = vhandle_offset; 01423 01424 // In 2 situations we'll need to add/modify a cubit_id -> vhandle map: 01425 // case A: no map yet, and either this offset different from 01426 // previous or not contiguous 01427 if( !cubMOABVertexMap && ( currVHandleOffset != vhandle_offset || !contig ) ) 01428 { 01429 // Get all vertices, removing ones in this batch 01430 Range vrange, tmp_range( dum_range ); 01431 result = mdbImpl->get_entities_by_type( 0, MBVERTEX, vrange );RR; 01432 if( !beforeEnts.empty() ) tmp_range.merge( beforeEnts.subset_by_type( MBVERTEX ) ); 01433 vrange = subtract( vrange, tmp_range ); 01434 // Compute the max cid; map is indexed by cid, so size is max_cid + 1 01435 #define MAX( a, b ) ( ( a ) > ( b ) ? ( a ) : ( b ) ) 01436 #define MIN( a, b ) ( ( a ) < ( b ) ? ( a ) : ( b ) ) 01437 // Sanity check that max vhandle is larger than offset 01438 long new_max = *vrange.rbegin() - currVHandleOffset; 01439 assert( new_max >= 0 && ( (long)*vrange.begin() ) - currVHandleOffset >= 0 ); 01440 max_cid = MAX( max_cid, ( (unsigned int)new_max ) ); 01441 cubMOABVertexMap = new std::vector< EntityHandle >( max_cid + 1 ); 01442 // Initialize to zero then put previous vertices into the map 01443 std::fill( cubMOABVertexMap->begin(), cubMOABVertexMap->end(), 0 ); 01444 Range::iterator rit; 01445 for( rit = vrange.begin(); rit != vrange.end(); ++rit ) 01446 { 01447 assert( ( (long)*rit ) - currVHandleOffset >= 0 && ( (long)*rit ) - currVHandleOffset <= max_cid ); 01448 ( *cubMOABVertexMap )[*rit - currVHandleOffset] = *rit; 01449 } 01450 } 01451 // case B: there is a map and we need to resize it 01452 else if( cubMOABVertexMap && max_cid + 1 > cubMOABVertexMap->size() ) 01453 { 01454 unsigned int old_size = cubMOABVertexMap->size(); 01455 cubMOABVertexMap->resize( max_cid + 1 ); 01456 std::fill( &( *cubMOABVertexMap )[old_size], &( *cubMOABVertexMap )[0] + cubMOABVertexMap->size(), 0 ); 01457 } 01458 01459 // OK, we have a map or don't need one 01460 if( NULL == cubMOABVertexMap ) 01461 { 01462 // If we're not forward-contiguous (i.e. we're reverse or 01463 // out-of-order contiguous), re-order coordinates for handles 01464 // so that they are 01465 if( -1 == contig || -2 == contig ) 01466 { 01467 // In case the arrays are large, do each coord separately 01468 std::vector< double > tmp_coords( entity->nodeCt ); 01469 for( unsigned int j = 0; j < 3; j++ ) 01470 { 01471 // Permute the coords into new order 01472 for( unsigned int i = 0; i < entity->nodeCt; i++ ) 01473 { 01474 assert( uint_buf[i] >= min_cid && max_cid - uint_buf[i] < entity->nodeCt ); 01475 tmp_coords[uint_buf[i] - min_cid] = arrays[j][i]; 01476 } 01477 // Copy the permuted to storage 01478 std::copy( &tmp_coords[0], &tmp_coords[0] + entity->nodeCt, arrays[j] ); 01479 } 01480 // Now re-order the ids; either way just go off min, max cid 01481 for( unsigned int i = 0; i < entity->nodeCt; i++ ) 01482 uint_buf[i] = min_cid + i; 01483 } 01484 else if( !contig ) 01485 // Shouldn't get here, since in non-contiguous case map should be there 01486 assert( false ); 01487 } 01488 else 01489 { 01490 // Put new vertices into the map 01491 // Now set the new values 01492 unsigned int* vit = &uint_buf[0]; 01493 Range::iterator rit = dum_range.begin(); 01494 for( ; rit != dum_range.end(); vit++, ++rit ) 01495 { 01496 assert( *vit < cubMOABVertexMap->size() ); 01497 ( *cubMOABVertexMap )[*vit] = *rit; 01498 } 01499 } 01500 01501 // No longer need to use uint_buf; convert in-place to ints, so we 01502 // can assign gid tag 01503 CONVERT_TO_INTS( entity->nodeCt ); 01504 result = mdbImpl->tag_set_data( globalIdTag, dum_range, &int_buf[0] ); 01505 if( MB_SUCCESS != result ) return result; 01506 01507 // Set the dimension to at least zero (entity has at least nodes) on the geom tag 01508 int max_dim = 0; 01509 result = mdbImpl->tag_set_data( geomTag, &( entity->setHandle ), 1, &max_dim ); 01510 if( MB_SUCCESS != result ) return result; 01511 // Set the category tag just in case there're only vertices in this set 01512 result = mdbImpl->tag_set_data( categoryTag, &entity->setHandle, 1, &geom_categories[0] ); 01513 if( MB_SUCCESS != result ) return result; 01514 01515 // Get fixed node data and assign 01516 int md_index = model->nodeMD.get_md_entry( gindex, "FixedNodes" ); 01517 if( -1 == md_index ) return MB_SUCCESS; 01518 MetaDataContainer::MetaDataEntry* md_entry = &( model->nodeMD.metadataEntries[md_index] ); 01519 01520 std::vector< int > fixed_flags( entity->nodeCt ); 01521 std::fill( fixed_flags.begin(), fixed_flags.end(), 0 ); 01522 if( md_entry->mdDataType != 3 ) return MB_FAILURE; 01523 01524 for( std::vector< unsigned int >::iterator vit = md_entry->mdIntArrayValue.begin(); 01525 vit != md_entry->mdIntArrayValue.end(); ++vit ) 01526 { 01527 #ifndef NDEBUG 01528 EntityHandle fixed_v = 01529 ( cubMOABVertexMap ? ( *cubMOABVertexMap )[*vit] : (EntityHandle)currVHandleOffset + *vit ); 01530 assert( fixed_v >= *dum_range.begin() && fixed_v <= *dum_range.rbegin() ); 01531 #endif 01532 fixed_flags[*vit - *dum_range.begin()] = 1; 01533 } 01534 01535 Tag fixedFlagTag; 01536 int dum_val = 0; 01537 result = mdbImpl->tag_get_handle( "NodeFixed", 1, MB_TYPE_INTEGER, fixedFlagTag, MB_TAG_SPARSE | MB_TAG_CREAT, 01538 &dum_val ); 01539 if( MB_SUCCESS != result ) return result; 01540 result = mdbImpl->tag_set_data( fixedFlagTag, dum_range, &fixed_flags[0] ); 01541 01542 return result; 01543 } 01544 01545 ErrorCode Tqdcfr::read_elements( Tqdcfr::ModelEntry* model, Tqdcfr::GeomHeader* entity ) 01546 { 01547 if( entity->elemTypeCt == 0 ) return MB_SUCCESS; 01548 const int in_order_map[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 01549 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27 }; 01550 01551 // Get data in separate calls to minimize memory usage 01552 // Position the file 01553 FSEEK( model->modelOffset + entity->elemOffset ); 01554 01555 int int_type, nodes_per_elem, num_elem; 01556 int max_dim = -1; 01557 ErrorCode result; 01558 for( unsigned int i = 0; i < entity->elemTypeCt; i++ ) 01559 { 01560 // For this elem type, get the type, nodes per elem, num elems 01561 FREADI( 3 ); 01562 int_type = uint_buf[0]; 01563 nodes_per_elem = uint_buf[1]; 01564 num_elem = uint_buf[2]; 01565 01566 // Get MB element type from cub file's 01567 EntityType elem_type = mp_type_to_mb_type[int_type]; 01568 max_dim = ( max_dim < CN::Dimension( elem_type ) ? CN::Dimension( elem_type ) : max_dim ); 01569 01570 if( debug ) std::cout << "type " << CN::EntityTypeName( elem_type ) << ":"; 01571 01572 const int* node_order = cub_elem_order_map[elem_type][nodes_per_elem]; 01573 if( !node_order ) node_order = in_order_map; 01574 01575 // Get element ids 01576 FREADI( num_elem ); 01577 01578 // Check to see if ids are contiguous... 01579 int contig; 01580 unsigned int max_id, min_id; 01581 check_contiguous( num_elem, contig, min_id, max_id ); 01582 if( 0 == contig && !printedElemWarning ) 01583 { 01584 std::cout << "Element ids are not contiguous!" << std::endl; 01585 printedElemWarning = true; 01586 } 01587 01588 // Get a space for reading connectivity data directly into MB 01589 EntityHandle *conn, start_handle; 01590 01591 result = readUtilIface->get_element_connect( num_elem, nodes_per_elem, elem_type, int_buf[0], start_handle, 01592 conn, SequenceManager::DEFAULT_ELEMENT_SEQUENCE_SIZE ); 01593 if( MB_SUCCESS != result ) return result; 01594 01595 Range dum_range( start_handle, start_handle + num_elem - 1 ); 01596 01597 long elem_offset; 01598 elem_offset = ( 1 == contig ? start_handle - int_buf[0] : int_buf[num_elem - 1] ); 01599 if( -1 == currElementIdOffset[elem_type] ) currElementIdOffset[elem_type] = elem_offset; 01600 01601 // Set the gids on elements 01602 CONVERT_TO_INTS( num_elem ); 01603 result = mdbImpl->tag_set_data( globalIdTag, dum_range, &int_buf[0] ); 01604 if( MB_SUCCESS != result ) return result; 01605 01606 // Get the connectivity array 01607 unsigned int total_conn = num_elem * nodes_per_elem; 01608 if( major >= 14 ) FREADI( num_elem ); // We need to skip num_elem in advance, it looks like 01609 FREADI( total_conn ); 01610 01611 // Post-process connectivity into handles 01612 EntityHandle new_handle; 01613 int j = 0; 01614 for( int e = 0; e < num_elem; ++e ) 01615 { 01616 for( int k = 0; k < nodes_per_elem; ++k, ++j ) 01617 { 01618 if( debug ) 01619 { 01620 if( 0 == j ) std::cout << "Conn="; 01621 std::cout << ", " << uint_buf[j]; 01622 } 01623 if( NULL == cubMOABVertexMap ) 01624 new_handle = (EntityHandle)currVHandleOffset + uint_buf[j]; 01625 else 01626 { 01627 assert( uint_buf[j] < cubMOABVertexMap->size() && 0 != ( *cubMOABVertexMap )[uint_buf[j]] ); 01628 new_handle = ( *cubMOABVertexMap )[uint_buf[j]]; 01629 } 01630 #ifndef NDEBUG 01631 EntityHandle dum_handle; 01632 assert( MB_SUCCESS == 01633 mdbImpl->handle_from_id( MBVERTEX, mdbImpl->id_from_handle( new_handle ), dum_handle ) ); 01634 #endif 01635 conn[e * nodes_per_elem + node_order[k]] = new_handle; 01636 } 01637 } 01638 01639 // Add these elements into the entity's set 01640 result = mdbImpl->add_entities( entity->setHandle, dum_range ); 01641 if( MB_SUCCESS != result ) return result; 01642 01643 // Notify MOAB of the new elements 01644 result = readUtilIface->update_adjacencies( start_handle, num_elem, nodes_per_elem, conn ); 01645 if( MB_SUCCESS != result ) return result; 01646 } 01647 01648 // Set the dimension on the geom tag 01649 result = mdbImpl->tag_set_data( geomTag, &entity->setHandle, 1, &max_dim ); 01650 if( MB_SUCCESS != result ) return result; 01651 if( max_dim != -1 ) 01652 { 01653 result = mdbImpl->tag_set_data( categoryTag, &entity->setHandle, 1, &geom_categories[max_dim] ); 01654 if( MB_SUCCESS != result ) return result; 01655 } 01656 01657 return MB_SUCCESS; 01658 } 01659 01660 void Tqdcfr::check_contiguous( const unsigned int num_ents, int& contig, unsigned int& min_id, unsigned int& max_id ) 01661 { 01662 unsigned int *id_it, curr_id, i; 01663 01664 // Check in forward-contiguous direction 01665 id_it = &uint_buf[0]; 01666 curr_id = *id_it++ + 1; 01667 contig = 1; 01668 min_id = uint_buf[0]; 01669 max_id = uint_buf[0]; 01670 for( i = 1; i < num_ents; id_it++, i++, curr_id++ ) 01671 { 01672 if( *id_it != curr_id ) 01673 { 01674 contig = 0; 01675 } 01676 min_id = MIN( min_id, uint_buf[i] ); 01677 max_id = MAX( max_id, uint_buf[i] ); 01678 } 01679 01680 // If we got here and we're at the end of the loop, it's forward-contiguous 01681 if( 1 == contig ) return; 01682 01683 // Check in reverse-contiguous direction 01684 contig = -1; 01685 id_it = &uint_buf[0]; 01686 curr_id = *id_it++ - 1; 01687 for( i = 1; i < num_ents; id_it++, i++, curr_id-- ) 01688 { 01689 if( *id_it != curr_id ) 01690 { 01691 contig = 0; 01692 break; 01693 } 01694 } 01695 01696 // If we got here and we're at the end of the loop, it's reverse-contiguous 01697 if( -1 == contig ) return; 01698 01699 // One final check, for contiguous but out of order 01700 if( max_id - min_id + 1 == num_ents ) contig = -2; 01701 01702 // Else it's not contiguous at all 01703 contig = 0; 01704 } 01705 01706 void Tqdcfr::FEModelHeader::init( const unsigned int offset, Tqdcfr* instance ) 01707 { 01708 instance->FSEEK( offset ); 01709 instance->FREADI( 4 ); 01710 feEndian = instance->uint_buf[0]; 01711 feSchema = instance->uint_buf[1]; 01712 feCompressFlag = instance->uint_buf[2]; 01713 feLength = instance->uint_buf[3]; 01714 instance->FREADI( 3 ); 01715 geomArray.init( instance->uint_buf ); 01716 instance->FREADI( 2 ); 01717 nodeArray.metaDataOffset = instance->uint_buf[0]; 01718 elementArray.metaDataOffset = instance->uint_buf[1]; 01719 instance->FREADI( 3 ); 01720 groupArray.init( instance->uint_buf ); 01721 instance->FREADI( 3 ); 01722 blockArray.init( instance->uint_buf ); 01723 instance->FREADI( 3 ); 01724 nodesetArray.init( instance->uint_buf ); 01725 instance->FREADI( 3 ); 01726 sidesetArray.init( instance->uint_buf ); 01727 instance->FREADI( 1 ); 01728 } 01729 01730 ErrorCode Tqdcfr::read_file_header() 01731 { 01732 // Read file header 01733 FSEEK( 4 ); 01734 // Read the first int from the file 01735 // If it is 0, it is littleEndian 01736 unsigned rval = fread( &fileTOC.fileEndian, sizeof( unsigned int ), 1, cubFile ); 01737 IO_ASSERT( rval == 1 ); 01738 #ifdef WORDS_BIGENDIAN 01739 if( fileTOC.fileEndian == 0 ) swapForEndianness = true; 01740 #else 01741 if( fileTOC.fileEndian != 0 ) swapForEndianness = true; 01742 #endif 01743 if( debug ) std::cout << " swapping ? " << swapForEndianness << "\n"; 01744 FREADI( 5 ); 01745 // fileTOC.fileEndian = uint_buf[0]; 01746 fileTOC.fileSchema = uint_buf[0]; 01747 fileTOC.numModels = uint_buf[1]; 01748 fileTOC.modelTableOffset = uint_buf[2]; 01749 fileTOC.modelMetaDataOffset = uint_buf[3]; 01750 fileTOC.activeFEModel = uint_buf[4]; 01751 if( debug ) fileTOC.print(); 01752 01753 return MB_SUCCESS; 01754 } 01755 01756 ErrorCode Tqdcfr::read_model_entries() 01757 { 01758 // Read model entries 01759 FSEEK( fileTOC.modelTableOffset ); 01760 FREADI( fileTOC.numModels * 6 ); 01761 modelEntries.resize( fileTOC.numModels ); 01762 if( modelEntries.empty() ) return MB_FAILURE; 01763 std::vector< unsigned int >::iterator int_it = uint_buf.begin(); 01764 for( unsigned int i = 0; i < fileTOC.numModels; i++ ) 01765 { 01766 modelEntries[i].modelHandle = *int_it++; 01767 modelEntries[i].modelOffset = *int_it++; 01768 modelEntries[i].modelLength = *int_it++; 01769 modelEntries[i].modelType = *int_it++; 01770 modelEntries[i].modelOwner = *int_it++; 01771 modelEntries[i].modelPad = *int_it++; 01772 if( int_it == uint_buf.end() && i != fileTOC.numModels - 1 ) return MB_FAILURE; 01773 if( debug ) modelEntries[i].print(); 01774 } 01775 01776 return MB_SUCCESS; 01777 } 01778 01779 int Tqdcfr::find_model( const unsigned int model_type ) 01780 { 01781 for( unsigned int i = 0; i < fileTOC.numModels; i++ ) 01782 { 01783 if( modelEntries[i].modelType == model_type ) return i; 01784 } 01785 01786 return -1; 01787 } 01788 01789 ErrorCode Tqdcfr::read_meta_data( const unsigned int metadata_offset, Tqdcfr::MetaDataContainer& mc ) 01790 { 01791 // Read the metadata header 01792 FSEEK( metadata_offset ); 01793 FREADI( 3 ); 01794 mc.mdSchema = uint_buf[0]; 01795 mc.compressFlag = uint_buf[1]; 01796 01797 // Allocate space for the entries 01798 mc.metadataEntries.resize( uint_buf[2] ); 01799 01800 // Now read the metadata values 01801 for( unsigned int i = 0; i < mc.metadataEntries.size(); i++ ) 01802 { 01803 FREADI( 2 ); 01804 mc.metadataEntries[i].mdOwner = uint_buf[0]; 01805 mc.metadataEntries[i].mdDataType = uint_buf[1]; 01806 01807 // Read the name string 01808 read_md_string( mc.metadataEntries[i].mdName ); 01809 01810 if( mc.metadataEntries[i].mdDataType == 0 ) 01811 { 01812 // integer 01813 FREADI( 1 ); 01814 mc.metadataEntries[i].mdIntValue = uint_buf[0]; 01815 } 01816 else if( mc.metadataEntries[i].mdDataType == 1 ) 01817 { 01818 // string 01819 read_md_string( mc.metadataEntries[i].mdStringValue ); 01820 } 01821 else if( mc.metadataEntries[i].mdDataType == 2 ) 01822 { 01823 // double 01824 FREADD( 1 ); 01825 mc.metadataEntries[i].mdDblValue = dbl_buf[0]; 01826 } 01827 else if( mc.metadataEntries[i].mdDataType == 3 ) 01828 { 01829 // int array 01830 FREADI( 1 ); 01831 mc.metadataEntries[i].mdIntArrayValue.resize( uint_buf[0] ); 01832 FREADI( mc.metadataEntries[i].mdIntArrayValue.size() ); 01833 std::copy( uint_buf.begin(), uint_buf.begin() + mc.metadataEntries[i].mdIntArrayValue.size(), 01834 mc.metadataEntries[i].mdIntArrayValue.begin() ); 01835 } 01836 else if( mc.metadataEntries[i].mdDataType == 4 ) 01837 { 01838 // double array 01839 FREADI( 1 ); 01840 mc.metadataEntries[i].mdDblArrayValue.resize( uint_buf[0] ); 01841 FREADD( mc.metadataEntries[i].mdDblArrayValue.size() ); 01842 std::copy( dbl_buf.begin(), dbl_buf.begin() + mc.metadataEntries[i].mdDblArrayValue.size(), 01843 mc.metadataEntries[i].mdDblArrayValue.begin() ); 01844 } 01845 else 01846 return MB_FAILURE; 01847 } 01848 if( debug ) mc.print(); 01849 01850 return MB_SUCCESS; 01851 } 01852 01853 ErrorCode Tqdcfr::read_md_string( std::string& name ) 01854 { 01855 FREADI( 1 ); 01856 int str_size = uint_buf[0]; 01857 if( str_size > 0 ) 01858 { 01859 FREADC( str_size ); 01860 if( char_buf.size() <= (unsigned int)str_size ) char_buf.resize( str_size + 1 ); 01861 char_buf[str_size] = '\0'; 01862 name = (char*)&char_buf[0]; 01863 // Read pad if any 01864 int extra = str_size % sizeof( int ); 01865 if( extra ) 01866 { 01867 // Read extra chars to end of pad 01868 str_size = sizeof( int ) - extra; 01869 FREADC( str_size ); 01870 } 01871 } 01872 01873 return MB_SUCCESS; 01874 } 01875 01876 ErrorCode Tqdcfr::GeomHeader::read_info_header( const unsigned int model_offset, 01877 const Tqdcfr::FEModelHeader::ArrayInfo& info, 01878 Tqdcfr* instance, 01879 Tqdcfr::GeomHeader*& geom_headers ) 01880 { 01881 geom_headers = new GeomHeader[info.numEntities]; 01882 instance->FSEEK( model_offset + info.tableOffset ); 01883 int dum_int; 01884 ErrorCode result; 01885 01886 if( 0 == instance->categoryTag ) 01887 { 01888 static const char val[CATEGORY_TAG_SIZE] = { 0 }; 01889 result = instance->mdbImpl->tag_get_handle( CATEGORY_TAG_NAME, CATEGORY_TAG_SIZE, MB_TYPE_OPAQUE, 01890 instance->categoryTag, MB_TAG_SPARSE | MB_TAG_CREAT, val ); 01891 if( MB_SUCCESS != result ) return result; 01892 } 01893 01894 for( unsigned int i = 0; i < info.numEntities; i++ ) 01895 { 01896 instance->FREADI( 8 ); 01897 geom_headers[i].nodeCt = instance->uint_buf[0]; 01898 geom_headers[i].nodeOffset = instance->uint_buf[1]; 01899 geom_headers[i].elemCt = instance->uint_buf[2]; 01900 geom_headers[i].elemOffset = instance->uint_buf[3]; 01901 geom_headers[i].elemTypeCt = instance->uint_buf[4]; 01902 geom_headers[i].elemLength = instance->uint_buf[5]; 01903 geom_headers[i].geomID = instance->uint_buf[6]; 01904 01905 // Don't represent in MOAB if no mesh 01906 if( geom_headers[i].nodeCt == 0 && geom_headers[i].elemCt == 0 ) continue; 01907 01908 // Create an entity set for this entity 01909 result = instance->create_set( geom_headers[i].setHandle ); 01910 if( MB_SUCCESS != result ) return result; 01911 01912 // Set the dimension to -1; will have to reset later, after elements are read 01913 dum_int = -1; 01914 result = instance->mdbImpl->tag_set_data( instance->geomTag, &( geom_headers[i].setHandle ), 1, &dum_int ); 01915 if( MB_SUCCESS != result ) return result; 01916 01917 // Set a unique id tag 01918 result = instance->mdbImpl->tag_set_data( instance->uniqueIdTag, &( geom_headers[i].setHandle ), 1, 01919 &( geom_headers[i].geomID ) ); 01920 if( MB_SUCCESS != result ) return result; 01921 01922 // Put the set and uid into a map for later 01923 instance->uidSetMap[geom_headers[i].geomID] = geom_headers[i].setHandle; 01924 } 01925 01926 // Now get the dimensions of elements for each geom entity 01927 for( unsigned int i = 0; i < info.numEntities; i++ ) 01928 { 01929 if( geom_headers[i].elemTypeCt == 0 ) continue; 01930 instance->FSEEK( model_offset + geom_headers[i].elemOffset ); 01931 for( unsigned int j = 0; j < geom_headers[i].elemTypeCt; j++ ) 01932 { 01933 // For this elem type, get the type, nodes per elem, num elems 01934 instance->FREADI( 3 ); 01935 int int_type = instance->uint_buf[0]; 01936 int nodes_per_elem = instance->uint_buf[1]; 01937 int num_elem = instance->uint_buf[2]; 01938 EntityType elem_type = mp_type_to_mb_type[int_type]; 01939 geom_headers[i].maxDim = std::max( geom_headers[i].maxDim, (int)CN::Dimension( elem_type ) ); 01940 if( j < geom_headers[i].elemTypeCt - 1 ) 01941 { 01942 int num_skipped_ints = num_elem + num_elem * nodes_per_elem; 01943 if( major >= 14 ) num_skipped_ints += num_elem; 01944 instance->FREADI( num_skipped_ints ); 01945 } 01946 } 01947 } 01948 01949 return MB_SUCCESS; 01950 } 01951 01952 ErrorCode Tqdcfr::GroupHeader::read_info_header( const unsigned int model_offset, 01953 const Tqdcfr::FEModelHeader::ArrayInfo& info, 01954 Tqdcfr* instance, 01955 Tqdcfr::GroupHeader*& group_headers ) 01956 { 01957 group_headers = new GroupHeader[info.numEntities]; 01958 instance->FSEEK( model_offset + info.tableOffset ); 01959 ErrorCode result; 01960 01961 if( 0 == instance->categoryTag ) 01962 { 01963 static const char val[CATEGORY_TAG_SIZE] = { 0 }; 01964 result = instance->mdbImpl->tag_get_handle( CATEGORY_TAG_NAME, CATEGORY_TAG_SIZE, MB_TYPE_OPAQUE, 01965 instance->categoryTag, MB_TAG_SPARSE | MB_TAG_CREAT, val ); 01966 if( MB_SUCCESS != result ) return result; 01967 } 01968 01969 for( unsigned int i = 0; i < info.numEntities; i++ ) 01970 { 01971 // Create an entity set for this entity 01972 result = instance->create_set( group_headers[i].setHandle ); 01973 if( MB_SUCCESS != result ) return result; 01974 static const char group_category[CATEGORY_TAG_SIZE] = "Group\0"; 01975 01976 instance->FREADI( 6 ); 01977 group_headers[i].grpID = instance->uint_buf[0]; 01978 group_headers[i].grpType = instance->uint_buf[1]; 01979 group_headers[i].memCt = instance->uint_buf[2]; 01980 group_headers[i].memOffset = instance->uint_buf[3]; 01981 group_headers[i].memTypeCt = instance->uint_buf[4]; 01982 group_headers[i].grpLength = instance->uint_buf[5]; 01983 01984 // Set the category tag to signify this is a group 01985 result = instance->mdbImpl->tag_set_data( instance->categoryTag, &( group_headers[i].setHandle ), 1, 01986 group_category ); 01987 if( MB_SUCCESS != result ) return result; 01988 01989 // Set a global id tag 01990 result = instance->mdbImpl->tag_set_data( instance->globalIdTag, &( group_headers[i].setHandle ), 1, 01991 &( group_headers[i].grpID ) ); 01992 if( MB_SUCCESS != result ) return result; 01993 01994 instance->gidSetMap[5][group_headers[i].grpID] = group_headers[i].setHandle; 01995 } 01996 01997 return MB_SUCCESS; 01998 } 01999 02000 ErrorCode Tqdcfr::BlockHeader::read_info_header( const double data_version, 02001 const unsigned int model_offset, 02002 const Tqdcfr::FEModelHeader::ArrayInfo& info, 02003 Tqdcfr* instance, 02004 Tqdcfr::BlockHeader*& block_headers ) 02005 { 02006 block_headers = new BlockHeader[info.numEntities]; 02007 instance->FSEEK( model_offset + info.tableOffset ); 02008 ErrorCode result; 02009 02010 if( 0 == instance->categoryTag ) 02011 { 02012 static const char val[CATEGORY_TAG_SIZE] = { 0 }; 02013 result = instance->mdbImpl->tag_get_handle( CATEGORY_TAG_NAME, CATEGORY_TAG_SIZE, MB_TYPE_OPAQUE, 02014 instance->categoryTag, MB_TAG_SPARSE | MB_TAG_CREAT, val ); 02015 if( MB_SUCCESS != result && MB_ALREADY_ALLOCATED != result ) return result; 02016 } 02017 02018 for( unsigned int i = 0; i < info.numEntities; i++ ) 02019 { 02020 // Create an entity set for this entity 02021 result = instance->create_set( block_headers[i].setHandle ); 02022 if( MB_SUCCESS != result ) return result; 02023 static const char material_category[CATEGORY_TAG_SIZE] = "Material Set\0"; 02024 02025 instance->FREADI( 12 ); 02026 block_headers[i].blockID = instance->uint_buf[0]; 02027 block_headers[i].blockElemType = instance->uint_buf[1]; 02028 block_headers[i].memCt = instance->uint_buf[2]; 02029 block_headers[i].memOffset = instance->uint_buf[3]; 02030 block_headers[i].memTypeCt = instance->uint_buf[4]; 02031 block_headers[i].attribOrder = instance->uint_buf[5]; // Attrib order 02032 block_headers[i].blockCol = instance->uint_buf[6]; 02033 block_headers[i].blockMixElemType = instance->uint_buf[7]; // Mixed elem type 02034 block_headers[i].blockPyrType = instance->uint_buf[8]; 02035 block_headers[i].blockMat = instance->uint_buf[9]; 02036 block_headers[i].blockLength = instance->uint_buf[10]; 02037 block_headers[i].blockDim = instance->uint_buf[11]; 02038 02039 Tag bhTag_header; 02040 { 02041 std::vector< int > def_uint_zero( 3, 0 ); 02042 result = instance->mdbImpl->tag_get_handle( BLOCK_HEADER, 3 * sizeof( unsigned int ), MB_TYPE_INTEGER, 02043 bhTag_header, MB_TAG_CREAT | MB_TAG_SPARSE | MB_TAG_BYTES, 02044 &def_uint_zero[0] ); 02045 if( MB_SUCCESS != result ) return result; 02046 int block_header_data[] = { static_cast< int >( block_headers[i].blockCol ), 02047 static_cast< int >( block_headers[i].blockMat ), 02048 static_cast< int >( block_headers[i].blockDim ) }; 02049 result = 02050 instance->mdbImpl->tag_set_data( bhTag_header, &( block_headers[i].setHandle ), 1, block_header_data ); 02051 } 02052 02053 if( MB_SUCCESS != result ) return result; 02054 02055 // Adjust element type for data version; older element types didn't include 02056 // 4 new trishell element types 02057 if( data_version <= 1.0 && block_headers[i].blockElemType >= 15 ) block_headers[i].blockElemType += 4; 02058 02059 if( block_headers[i].blockElemType >= (unsigned)cub_elem_num_verts_len ) 02060 { 02061 // Block element type unassigned, will have to infer from verts/element; make sure it's 02062 // the expected value of 52 02063 if( ( 14 == major && 2 < minor ) || 15 <= major ) 02064 { 02065 if( 55 != block_headers[i].blockElemType ) 02066 MB_SET_ERR( MB_FAILURE, "Invalid block element type: " << block_headers[i].blockElemType ); 02067 } 02068 else 02069 { 02070 if( 52 != block_headers[i].blockElemType ) 02071 MB_SET_ERR( MB_FAILURE, "Invalid block element type: " << block_headers[i].blockElemType ); 02072 } 02073 } 02074 02075 // Set the material set tag and id tag both to id 02076 result = instance->mdbImpl->tag_set_data( instance->blockTag, &( block_headers[i].setHandle ), 1, 02077 &( block_headers[i].blockID ) ); 02078 if( MB_SUCCESS != result ) return result; 02079 result = instance->mdbImpl->tag_set_data( instance->globalIdTag, &( block_headers[i].setHandle ), 1, 02080 &( block_headers[i].blockID ) ); 02081 if( MB_SUCCESS != result ) return result; 02082 result = instance->mdbImpl->tag_set_data( instance->categoryTag, &( block_headers[i].setHandle ), 1, 02083 material_category ); 02084 if( MB_SUCCESS != result ) return result; 02085 02086 // If this block is empty, continue 02087 if( !block_headers[i].memCt ) continue; 02088 02089 // Check the number of vertices in the element type, and set the has mid nodes tag 02090 // accordingly; if element type wasn't set, they're unlikely to have mid nodes 02091 // 52 is for CUBIT versions below 14.1, 55 for CUBIT version 14.9 and above 02092 if( 52 != block_headers[i].blockElemType && 55 != block_headers[i].blockElemType ) 02093 { 02094 int num_verts = cub_elem_num_verts[block_headers[i].blockElemType]; 02095 block_headers[i].blockEntityType = block_type_to_mb_type[block_headers[i].blockElemType]; 02096 if( ( block_headers[i].blockEntityType < MBMAXTYPE ) && 02097 ( num_verts != CN::VerticesPerEntity( block_headers[i].blockEntityType ) ) ) 02098 { 02099 // Not a linear element; try to find hasMidNodes values 02100 for( int j = 0; j < 4; j++ ) 02101 block_headers[i].hasMidNodes[j] = 0; 02102 if( 0 == instance->hasMidNodesTag ) 02103 { 02104 result = instance->mdbImpl->tag_get_handle( HAS_MID_NODES_TAG_NAME, 4, MB_TYPE_INTEGER, 02105 instance->hasMidNodesTag, MB_TAG_SPARSE | MB_TAG_CREAT, 02106 block_headers[i].hasMidNodes ); 02107 if( MB_SUCCESS != result ) return result; 02108 } 02109 02110 CN::HasMidNodes( block_headers[i].blockEntityType, num_verts, block_headers[i].hasMidNodes ); 02111 02112 // Now set the tag on this set 02113 result = instance->mdbImpl->tag_set_data( instance->hasMidNodesTag, &block_headers[i].setHandle, 1, 02114 block_headers[i].hasMidNodes ); 02115 if( MB_SUCCESS != result ) return result; 02116 } 02117 } 02118 } 02119 02120 return MB_SUCCESS; 02121 } 02122 02123 ErrorCode Tqdcfr::NodesetHeader::read_info_header( const unsigned int model_offset, 02124 const Tqdcfr::FEModelHeader::ArrayInfo& info, 02125 Tqdcfr* instance, 02126 Tqdcfr::NodesetHeader*& nodeset_headers ) 02127 { 02128 nodeset_headers = new NodesetHeader[info.numEntities]; 02129 instance->FSEEK( model_offset + info.tableOffset ); 02130 ErrorCode result; 02131 02132 if( 0 == instance->categoryTag ) 02133 { 02134 static const char val[CATEGORY_TAG_SIZE] = { 0 }; 02135 result = instance->mdbImpl->tag_get_handle( CATEGORY_TAG_NAME, CATEGORY_TAG_SIZE, MB_TYPE_OPAQUE, 02136 instance->categoryTag, MB_TAG_SPARSE | MB_TAG_CREAT, val ); 02137 if( MB_SUCCESS != result ) return result; 02138 } 02139 02140 for( unsigned int i = 0; i < info.numEntities; i++ ) 02141 { 02142 // Create an entity set for this entity 02143 result = instance->create_set( nodeset_headers[i].setHandle ); 02144 if( MB_SUCCESS != result ) return result; 02145 static const char dirichlet_category[CATEGORY_TAG_SIZE] = "Dirichlet Set\0"; 02146 02147 instance->FREADI( 8 ); 02148 nodeset_headers[i].nsID = instance->uint_buf[0]; 02149 nodeset_headers[i].memCt = instance->uint_buf[1]; 02150 nodeset_headers[i].memOffset = instance->uint_buf[2]; 02151 nodeset_headers[i].memTypeCt = instance->uint_buf[3]; 02152 nodeset_headers[i].pointSym = instance->uint_buf[4]; // Point sym 02153 nodeset_headers[i].nsCol = instance->uint_buf[5]; 02154 nodeset_headers[i].nsLength = instance->uint_buf[6]; 02155 // Pad 02156 02157 // Set the dirichlet set tag and id tag both to id 02158 result = instance->mdbImpl->tag_set_data( instance->nsTag, &( nodeset_headers[i].setHandle ), 1, 02159 &( nodeset_headers[i].nsID ) ); 02160 if( MB_SUCCESS != result ) return result; 02161 result = instance->mdbImpl->tag_set_data( instance->globalIdTag, &( nodeset_headers[i].setHandle ), 1, 02162 &( nodeset_headers[i].nsID ) ); 02163 if( MB_SUCCESS != result ) return result; 02164 result = instance->mdbImpl->tag_set_data( instance->categoryTag, &( nodeset_headers[i].setHandle ), 1, 02165 dirichlet_category ); 02166 if( MB_SUCCESS != result ) return result; 02167 } 02168 02169 return MB_SUCCESS; 02170 } 02171 02172 ErrorCode Tqdcfr::SidesetHeader::read_info_header( const unsigned int model_offset, 02173 const Tqdcfr::FEModelHeader::ArrayInfo& info, 02174 Tqdcfr* instance, 02175 Tqdcfr::SidesetHeader*& sideset_headers ) 02176 { 02177 sideset_headers = new SidesetHeader[info.numEntities]; 02178 instance->FSEEK( model_offset + info.tableOffset ); 02179 ErrorCode result; 02180 02181 if( 0 == instance->categoryTag ) 02182 { 02183 static const char val[CATEGORY_TAG_SIZE] = { 0 }; 02184 result = instance->mdbImpl->tag_get_handle( CATEGORY_TAG_NAME, CATEGORY_TAG_SIZE, MB_TYPE_OPAQUE, 02185 instance->categoryTag, MB_TAG_SPARSE | MB_TAG_CREAT, val ); 02186 if( MB_SUCCESS != result ) return result; 02187 } 02188 02189 for( unsigned int i = 0; i < info.numEntities; i++ ) 02190 { 02191 // Create an entity set for this entity 02192 result = instance->create_set( sideset_headers[i].setHandle ); 02193 if( MB_SUCCESS != result ) return result; 02194 static const char neumann_category[CATEGORY_TAG_SIZE] = "Neumann Set\0"; 02195 02196 instance->FREADI( 8 ); 02197 sideset_headers[i].ssID = instance->uint_buf[0]; 02198 sideset_headers[i].memCt = instance->uint_buf[1]; 02199 sideset_headers[i].memOffset = instance->uint_buf[2]; 02200 sideset_headers[i].memTypeCt = instance->uint_buf[3]; 02201 sideset_headers[i].numDF = instance->uint_buf[4]; // Num dist factors 02202 sideset_headers[i].ssCol = instance->uint_buf[5]; 02203 sideset_headers[i].useShell = instance->uint_buf[6]; 02204 sideset_headers[i].ssLength = instance->uint_buf[7]; 02205 02206 // Set the neumann set tag and id tag both to id 02207 result = instance->mdbImpl->tag_set_data( instance->ssTag, &( sideset_headers[i].setHandle ), 1, 02208 &( sideset_headers[i].ssID ) ); 02209 if( MB_SUCCESS != result ) return result; 02210 result = instance->mdbImpl->tag_set_data( instance->globalIdTag, &( sideset_headers[i].setHandle ), 1, 02211 &( sideset_headers[i].ssID ) ); 02212 if( MB_SUCCESS != result ) return result; 02213 result = instance->mdbImpl->tag_set_data( instance->categoryTag, &( sideset_headers[i].setHandle ), 1, 02214 neumann_category ); 02215 if( MB_SUCCESS != result ) return result; 02216 } 02217 02218 return MB_SUCCESS; 02219 } 02220 02221 void Tqdcfr::ModelEntry::print_geom_headers( const char* prefix, GeomHeader* header, const unsigned int num_headers ) 02222 { 02223 if( !debug ) return; 02224 std::cout << prefix << std::endl; 02225 if( NULL != header ) 02226 { 02227 for( unsigned int i = 0; i < num_headers; i++ ) 02228 { 02229 std::cout << "Index " << i << std::endl; 02230 header[i].print(); 02231 } 02232 } 02233 } 02234 02235 void Tqdcfr::ModelEntry::print_group_headers( const char* prefix, GroupHeader* header, const unsigned int num_headers ) 02236 { 02237 if( !debug ) return; 02238 std::cout << prefix << std::endl; 02239 if( NULL != header ) 02240 { 02241 for( unsigned int i = 0; i < num_headers; i++ ) 02242 header[i].print(); 02243 } 02244 } 02245 02246 void Tqdcfr::ModelEntry::print_block_headers( const char* prefix, BlockHeader* header, const unsigned int num_headers ) 02247 { 02248 if( !debug ) return; 02249 std::cout << prefix << std::endl; 02250 if( NULL != header ) 02251 { 02252 for( unsigned int i = 0; i < num_headers; i++ ) 02253 header[i].print(); 02254 } 02255 } 02256 02257 void Tqdcfr::ModelEntry::print_nodeset_headers( const char* prefix, 02258 NodesetHeader* header, 02259 const unsigned int num_headers ) 02260 { 02261 if( !debug ) return; 02262 std::cout << prefix << std::endl; 02263 if( NULL != header ) 02264 { 02265 for( unsigned int i = 0; i < num_headers; i++ ) 02266 header[i].print(); 02267 } 02268 } 02269 02270 void Tqdcfr::ModelEntry::print_sideset_headers( const char* prefix, 02271 SidesetHeader* header, 02272 const unsigned int num_headers ) 02273 { 02274 if( !debug ) return; 02275 std::cout << prefix << std::endl; 02276 if( NULL != header ) 02277 { 02278 for( unsigned int i = 0; i < num_headers; i++ ) 02279 header[i].print(); 02280 } 02281 } 02282 02283 ErrorCode Tqdcfr::ModelEntry::read_header_info( Tqdcfr* instance, const double data_version ) 02284 { 02285 feModelHeader.init( modelOffset, instance ); 02286 int negone = -1; 02287 ErrorCode result; 02288 instance->globalIdTag = instance->mdbImpl->globalId_tag(); 02289 02290 if( feModelHeader.geomArray.numEntities > 0 ) 02291 { 02292 result = instance->mdbImpl->tag_get_handle( GEOM_DIMENSION_TAG_NAME, 1, MB_TYPE_INTEGER, instance->geomTag, 02293 MB_TAG_SPARSE | MB_TAG_CREAT, &negone ); 02294 if( MB_SUCCESS != result ) return result; 02295 02296 result = instance->mdbImpl->tag_get_handle( "UNIQUE_ID", 1, MB_TYPE_INTEGER, instance->uniqueIdTag, 02297 MB_TAG_SPARSE | MB_TAG_CREAT, &negone ); 02298 if( MB_SUCCESS != result ) return result; 02299 02300 result = Tqdcfr::GeomHeader::read_info_header( modelOffset, feModelHeader.geomArray, instance, feGeomH ); 02301 print_geom_headers( "Geom headers:", feGeomH, feModelHeader.geomArray.numEntities ); 02302 if( MB_SUCCESS != result ) return result; 02303 } 02304 02305 if( feModelHeader.groupArray.numEntities > 0 ) 02306 { 02307 result = Tqdcfr::GroupHeader::read_info_header( modelOffset, feModelHeader.groupArray, instance, feGroupH ); 02308 print_group_headers( "Group headers:", feGroupH, feModelHeader.groupArray.numEntities ); 02309 if( MB_SUCCESS != result ) return result; 02310 } 02311 02312 if( feModelHeader.blockArray.numEntities > 0 ) 02313 { 02314 result = instance->mdbImpl->tag_get_handle( MATERIAL_SET_TAG_NAME, 1, MB_TYPE_INTEGER, instance->blockTag, 02315 MB_TAG_SPARSE | MB_TAG_CREAT, &negone ); 02316 if( MB_SUCCESS != result ) return result; 02317 02318 result = Tqdcfr::BlockHeader::read_info_header( data_version, modelOffset, feModelHeader.blockArray, instance, 02319 feBlockH ); 02320 print_block_headers( "Block headers:", feBlockH, feModelHeader.blockArray.numEntities ); 02321 if( MB_SUCCESS != result ) return result; 02322 } 02323 if( feModelHeader.nodesetArray.numEntities > 0 ) 02324 { 02325 result = instance->mdbImpl->tag_get_handle( DIRICHLET_SET_TAG_NAME, 1, MB_TYPE_INTEGER, instance->nsTag, 02326 MB_TAG_SPARSE | MB_TAG_CREAT, &negone ); 02327 if( MB_SUCCESS != result ) return result; 02328 02329 result = 02330 Tqdcfr::NodesetHeader::read_info_header( modelOffset, feModelHeader.nodesetArray, instance, feNodeSetH ); 02331 if( MB_SUCCESS != result ) return result; 02332 print_nodeset_headers( "Nodeset headers:", feNodeSetH, feModelHeader.nodesetArray.numEntities ); 02333 } 02334 if( feModelHeader.sidesetArray.numEntities > 0 ) 02335 { 02336 result = instance->mdbImpl->tag_get_handle( NEUMANN_SET_TAG_NAME, 1, MB_TYPE_INTEGER, instance->ssTag, 02337 MB_TAG_SPARSE | MB_TAG_CREAT, &negone ); 02338 if( MB_SUCCESS != result ) return result; 02339 02340 result = 02341 Tqdcfr::SidesetHeader::read_info_header( modelOffset, feModelHeader.sidesetArray, instance, feSideSetH ); 02342 print_sideset_headers( "SideSet headers:", feSideSetH, feModelHeader.sidesetArray.numEntities ); 02343 } 02344 02345 return MB_SUCCESS; 02346 } 02347 02348 ErrorCode Tqdcfr::ModelEntry::read_metadata_info( Tqdcfr* tqd ) 02349 { 02350 if( debug ) std::cout << "Geom metadata:" << std::endl; 02351 tqd->read_meta_data( modelOffset + feModelHeader.geomArray.metaDataOffset, geomMD ); 02352 if( debug ) std::cout << "Node metadata:" << std::endl; 02353 tqd->read_meta_data( modelOffset + feModelHeader.nodeArray.metaDataOffset, nodeMD ); 02354 if( debug ) std::cout << "Elem metadata:" << std::endl; 02355 tqd->read_meta_data( modelOffset + feModelHeader.elementArray.metaDataOffset, elementMD ); 02356 if( debug ) std::cout << "Group metadata:" << std::endl; 02357 tqd->read_meta_data( modelOffset + feModelHeader.groupArray.metaDataOffset, groupMD ); 02358 if( debug ) std::cout << "Block metadata:" << std::endl; 02359 tqd->read_meta_data( modelOffset + feModelHeader.blockArray.metaDataOffset, blockMD ); 02360 if( debug ) std::cout << "Nodeset metadata:" << std::endl; 02361 tqd->read_meta_data( modelOffset + feModelHeader.nodesetArray.metaDataOffset, nodesetMD ); 02362 if( debug ) std::cout << "Sideset metadata:" << std::endl; 02363 tqd->read_meta_data( modelOffset + feModelHeader.sidesetArray.metaDataOffset, sidesetMD ); 02364 02365 return MB_SUCCESS; 02366 } 02367 02368 ErrorCode Tqdcfr::read_acis_records( const char* sat_filename ) 02369 { 02370 // Get the acis model location 02371 unsigned int acis_model_offset = 0, acis_model_length = 0, acis_model_handle = 1, acis_sat_type = 1; 02372 for( unsigned int i = 0; i < fileTOC.numModels; i++ ) 02373 { 02374 if( modelEntries[i].modelHandle == acis_model_handle && modelEntries[i].modelType == acis_sat_type ) 02375 { 02376 acis_model_offset = modelEntries[i].modelOffset; 02377 acis_model_length = modelEntries[i].modelLength; 02378 break; 02379 } 02380 } 02381 02382 if( acis_model_length == 0 ) return MB_SUCCESS; 02383 02384 std::vector< AcisRecord > records; 02385 02386 acisDumpFile = NULL; 02387 if( sat_filename ) 02388 { 02389 acisDumpFile = fopen( sat_filename, "w+" ); 02390 if( NULL == acisDumpFile ) return MB_FAILURE; 02391 } 02392 02393 // Position the file at the start of the acis model 02394 FSEEK( acis_model_offset ); 02395 02396 unsigned int bytes_left = acis_model_length; 02397 02398 struct AcisRecord this_record; 02399 reset_record( this_record ); 02400 char* ret; 02401 02402 // Make the char buffer at least buf_size + 1 long, to fit null char 02403 const unsigned int buf_size = 1023; 02404 02405 // CHECK_SIZE(char_buf, buf_size + 1); 02406 char_buf.resize( buf_size + 1 ); 02407 02408 while( 0 != bytes_left ) 02409 { 02410 // Read the next buff characters, or bytes_left if smaller 02411 unsigned int next_buf = ( bytes_left > buf_size ? buf_size : bytes_left ); 02412 FREADC( next_buf ); 02413 02414 if( NULL != acisDumpFile ) fwrite( &char_buf[0], sizeof( char ), next_buf, acisDumpFile ); 02415 02416 // Put null at end of string to stop searches 02417 char_buf.resize( next_buf + 1 ); 02418 char_buf[next_buf] = '\0'; 02419 unsigned int buf_pos = 0; 02420 02421 // Check for first read, and if so, get rid of the header 02422 if( bytes_left == acis_model_length ) 02423 { 02424 // Look for 3 newlines 02425 ret = strchr( &( char_buf[0] ), '\n' ); 02426 ret = strchr( ret + 1, '\n' ); 02427 ret = strchr( ret + 1, '\n' ); 02428 if( NULL == ret ) return MB_FAILURE; 02429 buf_pos += ret - &( char_buf[0] ) + 1; 02430 } 02431 02432 bytes_left -= next_buf; 02433 02434 // Now start grabbing records 02435 do 02436 { 02437 // Get next occurrence of '#' (record terminator) 02438 ret = strchr( &( char_buf[buf_pos] ), '#' ); 02439 while( ret && (unsigned int)( ret + 1 - &char_buf[0] ) < bytes_left && *( ret + 1 ) != '\n' && 02440 *( ret + 1 ) != '\r' && *( ret + 1 ) != 0 ) // CR added for windows 02441 ret = strchr( ret + 1, '#' ); 02442 if( NULL != ret ) 02443 { 02444 // Grab the string (inclusive of the record terminator and the line feed) and 02445 // complete the record 02446 int num_chars = ret - &( char_buf[buf_pos] ) + 2; 02447 if( *( ret + 1 ) == '\r' ) num_chars++; // add more one character for Windows CR 02448 this_record.att_string.append( &( char_buf[buf_pos] ), num_chars ); 02449 buf_pos += num_chars; 02450 process_record( this_record ); 02451 02452 // Put the record in the list... 02453 records.push_back( this_record ); 02454 02455 // And reset the record 02456 reset_record( this_record ); 02457 } 02458 else 02459 { 02460 // Reached end of buffer; cache string then go get another; discard last character, 02461 // which will be the null character 02462 this_record.att_string.append( &( char_buf[buf_pos] ), next_buf - buf_pos ); 02463 buf_pos = next_buf; 02464 } 02465 } while( buf_pos < next_buf ); 02466 } 02467 02468 if( NULL != acisDumpFile ) 02469 fwrite( "\n======================\nSorted acis records:\n======================\n", 1, 68, acisDumpFile ); 02470 02471 // Now interpret the records 02472 interpret_acis_records( records ); 02473 02474 if( NULL != acisDumpFile ) fclose( acisDumpFile ); 02475 02476 return MB_SUCCESS; 02477 } 02478 02479 ErrorCode Tqdcfr::interpret_acis_records( std::vector< AcisRecord >& records ) 02480 { 02481 // Make a tag for the vector holding unrecognized attributes 02482 void* default_val = NULL; 02483 ErrorCode result = mdbImpl->tag_get_handle( "ATTRIB_VECTOR", sizeof( void* ), MB_TYPE_OPAQUE, attribVectorTag, 02484 MB_TAG_CREAT | MB_TAG_SPARSE, &default_val ); 02485 if( MB_SUCCESS != result ) return result; 02486 02487 unsigned int current_record = 0; 02488 02489 #define REC records[current_record] 02490 02491 while( current_record != records.size() ) 02492 { 02493 // If this record's been processed, or if it's an attribute, continue 02494 if( REC.processed || REC.rec_type == Tqdcfr::ATTRIB ) 02495 { 02496 current_record++; 02497 continue; 02498 } 02499 02500 if( REC.rec_type == Tqdcfr::UNKNOWN ) 02501 { 02502 REC.processed = true; 02503 current_record++; 02504 continue; 02505 } 02506 02507 // It's a known, non-attrib rec type; parse for any attribs 02508 parse_acis_attribs( current_record, records ); 02509 02510 REC.processed = true; 02511 02512 current_record++; 02513 } 02514 02515 return MB_SUCCESS; 02516 } 02517 02518 ErrorCode Tqdcfr::parse_acis_attribs( const unsigned int entity_rec_num, std::vector< AcisRecord >& records ) 02519 { 02520 unsigned int num_read; 02521 std::vector< std::string > attrib_vec; 02522 char temp_name[1024]; 02523 char name_tag_val[NAME_TAG_SIZE]; 02524 std::string name_tag; 02525 int id = -1; 02526 int uid = -1; 02527 int next_attrib = -1; 02528 ErrorCode result; 02529 02530 int current_attrib = records[entity_rec_num].first_attrib; 02531 if( -1 == current_attrib ) return MB_SUCCESS; 02532 02533 if( NULL != acisDumpFile ) 02534 { 02535 fwrite( "-----------------------------------------------------------------------\n", 1, 72, acisDumpFile ); 02536 fwrite( records[entity_rec_num].att_string.c_str(), sizeof( char ), records[entity_rec_num].att_string.length(), 02537 acisDumpFile ); 02538 } 02539 02540 while( -1 != current_attrib ) 02541 { 02542 if( records[current_attrib].rec_type != Tqdcfr::UNKNOWN && 02543 ( records[current_attrib].att_next != next_attrib || 02544 records[current_attrib].att_ent_num != (int)entity_rec_num ) ) 02545 return MB_FAILURE; 02546 02547 if( NULL != acisDumpFile ) 02548 fwrite( records[current_attrib].att_string.c_str(), sizeof( char ), 02549 records[current_attrib].att_string.length(), acisDumpFile ); 02550 02551 // Is the attrib one we already recognize? 02552 if( strncmp( records[current_attrib].att_string.c_str(), "ENTITY_NAME", 11 ) == 0 ) 02553 { 02554 // Parse name 02555 int num_chars; 02556 num_read = 02557 sscanf( records[current_attrib].att_string.c_str(), "ENTITY_NAME @%d %s", &num_chars, temp_name ); 02558 if( num_read != 2 ) 02559 num_read = 02560 sscanf( records[current_attrib].att_string.c_str(), "ENTITY_NAME %d %s", &num_chars, temp_name ); 02561 if( num_read != 2 ) return MB_FAILURE; 02562 02563 // Put the name on the entity 02564 name_tag = std::string( temp_name, num_chars ); 02565 } 02566 else if( strncmp( records[current_attrib].att_string.c_str(), "ENTITY_ID", 9 ) == 0 ) 02567 { 02568 // Parse id 02569 int bounding_uid, bounding_sense; 02570 num_read = sscanf( records[current_attrib].att_string.c_str(), "ENTITY_ID 0 3 %d %d %d", &id, &bounding_uid, 02571 &bounding_sense ); 02572 if( 3 != num_read ) 02573 { 02574 // Try reading updated entity_id format, which has coordinate triple embedded in it 02575 // too 02576 float dumx, dumy, dumz; 02577 num_read = sscanf( records[current_attrib].att_string.c_str(), "ENTITY_ID 3 %f %f %f 3 %d %d %d", &dumx, 02578 &dumy, &dumz, &id, &bounding_uid, &bounding_sense ); 02579 num_read -= 3; 02580 } 02581 02582 if( 3 != num_read ) 02583 std::cout << "Warning: bad ENTITY_ID attribute in .sat file, record number " << entity_rec_num 02584 << ", record follows:" << std::endl 02585 << records[current_attrib].att_string.c_str() << std::endl; 02586 } 02587 else if( strncmp( records[current_attrib].att_string.c_str(), "UNIQUE_ID", 9 ) == 0 ) 02588 { 02589 // Parse uid 02590 if( major >= 14 ) // Change of format for cubit 14: 02591 num_read = sscanf( records[current_attrib].att_string.c_str(), "UNIQUE_ID 0 1 %d", &uid ); 02592 else 02593 num_read = sscanf( records[current_attrib].att_string.c_str(), "UNIQUE_ID 1 0 1 %d", &uid ); 02594 if( 1 != num_read ) return MB_FAILURE; 02595 } 02596 else if( strncmp( records[current_attrib].att_string.c_str(), "COMPOSITE_ATTRIB @9 UNIQUE_ID", 29 ) == 0 ) 02597 { 02598 // Parse uid 02599 int dum1, dum2, dum3, dum4; 02600 num_read = sscanf( records[current_attrib].att_string.c_str(), 02601 "COMPOSITE_ATTRIB @9 UNIQUE_ID %d %d %d %d %d", &dum1, &dum2, &dum3, &dum4, &uid ); 02602 if( 5 != num_read ) return MB_FAILURE; 02603 } 02604 else if( strncmp( records[current_attrib].att_string.c_str(), "COMPOSITE_ATTRIB @9 ENTITY_ID", 29 ) == 0 ) 02605 { 02606 // Parse id 02607 int dum1, dum2, dum3; 02608 num_read = sscanf( records[current_attrib].att_string.c_str(), "COMPOSITE_ATTRIB @9 ENTITY_ID %d %d %d %d", 02609 &dum1, &dum2, &dum3, &id ); 02610 if( 4 != num_read ) return MB_FAILURE; 02611 } 02612 else 02613 { 02614 attrib_vec.push_back( records[current_attrib].att_string ); 02615 } 02616 02617 records[current_attrib].processed = true; 02618 next_attrib = current_attrib; 02619 current_attrib = records[current_attrib].att_prev; 02620 } 02621 02622 // At this point, there aren't entity sets for entity types which don't contain mesh 02623 // in this case, just return 02624 if( records[entity_rec_num].rec_type == aBODY || ( records[entity_rec_num].entity == 0 && uid == -1 ) ) 02625 { 02626 return MB_SUCCESS; 02627 // Warning: couldn't resolve entity of type 1 because no uid was found. 02628 // ddriv: GeomTopoTool.cpp:172: ErrorCode GeomTopoTool::separate_by_dimension(const Range&, 02629 // Range*, void**): Assertion `false' failed. xxx 02630 } 02631 02632 // Parsed the data; now put on mdb entities; first we need to find the entity 02633 if( records[entity_rec_num].entity == 0 ) 02634 { 02635 records[entity_rec_num].entity = uidSetMap[uid]; 02636 } 02637 02638 if( 0 == records[entity_rec_num].entity ) return MB_SUCCESS; // We do not have a MOAB entity for this, skip 02639 02640 // assert(records[entity_rec_num].entity); 02641 02642 // Set the id 02643 if( id != -1 ) 02644 { 02645 result = mdbImpl->tag_set_data( globalIdTag, &( records[entity_rec_num].entity ), 1, &id ); 02646 if( MB_SUCCESS != result ) return result; 02647 02648 int ent_dim = -1; 02649 if( records[entity_rec_num].rec_type == aBODY ) 02650 ent_dim = 4; 02651 else if( records[entity_rec_num].rec_type == LUMP ) 02652 ent_dim = 3; 02653 else if( records[entity_rec_num].rec_type == FACE ) 02654 ent_dim = 2; 02655 else if( records[entity_rec_num].rec_type == aEDGE ) 02656 ent_dim = 1; 02657 else if( records[entity_rec_num].rec_type == aVERTEX ) 02658 ent_dim = 0; 02659 if( -1 != ent_dim ) gidSetMap[ent_dim][id] = records[entity_rec_num].entity; 02660 } 02661 02662 // Set the name 02663 if( !name_tag.empty() ) 02664 { 02665 if( 0 == entityNameTag ) 02666 { 02667 char dum_val[NAME_TAG_SIZE] = { 0 }; 02668 result = mdbImpl->tag_get_handle( NAME_TAG_NAME, NAME_TAG_SIZE, MB_TYPE_OPAQUE, entityNameTag, 02669 MB_TAG_SPARSE | MB_TAG_CREAT, dum_val ); 02670 if( MB_SUCCESS != result ) return result; 02671 } 02672 02673 size_t len = name_tag.size(); 02674 if( len >= NAME_TAG_SIZE ) len = NAME_TAG_SIZE - 1; // Truncate a name that is too big 02675 memcpy( name_tag_val, name_tag.c_str(), len ); 02676 memset( name_tag_val + len, '\0', NAME_TAG_SIZE - len ); 02677 result = mdbImpl->tag_set_data( entityNameTag, &( records[entity_rec_num].entity ), 1, name_tag_val ); 02678 if( MB_SUCCESS != result ) return result; 02679 } 02680 02681 if( !attrib_vec.empty() ) 02682 { 02683 // Put the attrib vector in a tag on the entity 02684 std::vector< std::string >* dum_vec; 02685 result = mdbImpl->tag_get_data( attribVectorTag, &( records[entity_rec_num].entity ), 1, &dum_vec ); 02686 if( MB_SUCCESS != result && MB_TAG_NOT_FOUND != result ) return result; 02687 if( MB_TAG_NOT_FOUND == result || dum_vec == NULL ) 02688 { 02689 // Put this list directly on the entity 02690 dum_vec = new std::vector< std::string >; 02691 dum_vec->swap( attrib_vec ); 02692 result = mdbImpl->tag_set_data( attribVectorTag, &( records[entity_rec_num].entity ), 1, &dum_vec ); 02693 if( MB_SUCCESS != result ) 02694 { 02695 delete dum_vec; 02696 return result; 02697 } 02698 } 02699 else 02700 { 02701 // Copy this list over, and delete this list 02702 std::copy( attrib_vec.begin(), attrib_vec.end(), std::back_inserter( *dum_vec ) ); 02703 } 02704 } 02705 02706 return MB_SUCCESS; 02707 } 02708 02709 ErrorCode Tqdcfr::reset_record( AcisRecord& this_record ) 02710 { 02711 this_record.rec_type = Tqdcfr::UNKNOWN; 02712 this_record.att_string.clear(); 02713 this_record.first_attrib = this_record.att_prev = this_record.att_next = this_record.att_ent_num = -1; 02714 this_record.processed = false; 02715 this_record.entity = 0; 02716 02717 return MB_SUCCESS; 02718 } 02719 02720 ErrorCode Tqdcfr::process_record( AcisRecord& this_record ) 02721 { 02722 // Get the entity type 02723 const char* type_substr; 02724 02725 // Try attribs first, since the others have some common processing between them 02726 if( ( type_substr = strstr( this_record.att_string.c_str(), "attrib" ) ) != NULL && 02727 type_substr - this_record.att_string.c_str() < 20 ) 02728 { 02729 this_record.rec_type = Tqdcfr::ATTRIB; 02730 bool simple_attrib = false; 02731 bool generic_attrib = false; 02732 if( ( type_substr = strstr( this_record.att_string.c_str(), "simple-snl-attrib" ) ) != NULL ) 02733 simple_attrib = true; 02734 else if( ( type_substr = strstr( this_record.att_string.c_str(), "integer_attrib-name_attrib-gen-attrib" ) ) != 02735 NULL ) 02736 generic_attrib = true; 02737 else 02738 { 02739 this_record.rec_type = Tqdcfr::UNKNOWN; 02740 return MB_SUCCESS; 02741 } 02742 02743 // Find next space 02744 type_substr = strchr( type_substr, ' ' ); 02745 if( NULL == type_substr ) return MB_FAILURE; 02746 02747 // Read the numbers from there 02748 int num_converted = sscanf( type_substr, " $-1 -1 $%d $%d $%d -1", &( this_record.att_prev ), 02749 &( this_record.att_next ), &( this_record.att_ent_num ) ); 02750 if( num_converted != 3 ) return MB_FAILURE; 02751 02752 // Trim the string to the attribute, if it's a simple attrib 02753 if( simple_attrib ) 02754 { 02755 type_substr = strstr( this_record.att_string.c_str(), "NEW_SIMPLE_ATTRIB" ); 02756 if( NULL == type_substr ) return MB_FAILURE; 02757 type_substr = strstr( type_substr, "@" ); 02758 if( NULL == type_substr ) return MB_FAILURE; 02759 type_substr = strstr( type_substr, " " ) + 1; 02760 // Copy the rest of the string to a dummy string 02761 std::string dum_str( type_substr ); 02762 this_record.att_string = dum_str; 02763 } 02764 else if( generic_attrib ) 02765 { 02766 type_substr = strstr( this_record.att_string.c_str(), "CUBIT_ID" ); 02767 if( NULL == type_substr ) return MB_FAILURE; 02768 // Copy the rest of the string to a dummy string 02769 std::string dum_str( type_substr ); 02770 this_record.att_string = dum_str; 02771 } 02772 } 02773 else 02774 { 02775 // Else it's a topological entity, I think 02776 if( ( type_substr = strstr( this_record.att_string.c_str(), "body" ) ) != NULL && 02777 type_substr - this_record.att_string.c_str() < 20 ) 02778 { 02779 this_record.rec_type = Tqdcfr::aBODY; 02780 } 02781 else if( ( type_substr = strstr( this_record.att_string.c_str(), "lump" ) ) != NULL && 02782 type_substr - this_record.att_string.c_str() < 20 ) 02783 { 02784 this_record.rec_type = Tqdcfr::LUMP; 02785 } 02786 else if( ( type_substr = strstr( this_record.att_string.c_str(), "shell" ) ) != NULL && 02787 type_substr - this_record.att_string.c_str() < 20 ) 02788 { 02789 // Don't care about shells 02790 this_record.rec_type = Tqdcfr::UNKNOWN; 02791 } 02792 else if( ( type_substr = strstr( this_record.att_string.c_str(), "surface" ) ) != NULL && 02793 type_substr - this_record.att_string.c_str() < 20 ) 02794 { 02795 // Don't care about surfaces 02796 this_record.rec_type = Tqdcfr::UNKNOWN; 02797 } 02798 else if( ( type_substr = strstr( this_record.att_string.c_str(), "face" ) ) != NULL && 02799 type_substr - this_record.att_string.c_str() < 20 ) 02800 { 02801 this_record.rec_type = Tqdcfr::FACE; 02802 } 02803 else if( ( type_substr = strstr( this_record.att_string.c_str(), "loop" ) ) != NULL && 02804 type_substr - this_record.att_string.c_str() < 20 ) 02805 { 02806 // Don't care about loops 02807 this_record.rec_type = Tqdcfr::UNKNOWN; 02808 } 02809 else if( ( type_substr = strstr( this_record.att_string.c_str(), "coedge" ) ) != NULL && 02810 type_substr - this_record.att_string.c_str() < 20 ) 02811 { 02812 // Don't care about coedges 02813 this_record.rec_type = Tqdcfr::UNKNOWN; 02814 } 02815 else if( ( type_substr = strstr( this_record.att_string.c_str(), "edge" ) ) != NULL && 02816 type_substr - this_record.att_string.c_str() < 20 ) 02817 { 02818 this_record.rec_type = Tqdcfr::aEDGE; 02819 } 02820 else if( ( type_substr = strstr( this_record.att_string.c_str(), "vertex" ) ) != NULL && 02821 type_substr - this_record.att_string.c_str() < 20 ) 02822 { 02823 this_record.rec_type = Tqdcfr::aVERTEX; 02824 } 02825 else 02826 this_record.rec_type = Tqdcfr::UNKNOWN; 02827 02828 if( this_record.rec_type != Tqdcfr::UNKNOWN ) 02829 { 02830 // Print a warning if it looks like there are sequence numbers 02831 if( type_substr != this_record.att_string.c_str() && !printedSeqWarning ) 02832 { 02833 std::cout << "Warning: acis file has sequence numbers!" << std::endl; 02834 printedSeqWarning = true; 02835 } 02836 02837 // Scan ahead to the next white space 02838 type_substr = strchr( type_substr, ' ' ); 02839 if( NULL == type_substr ) return MB_FAILURE; 02840 02841 // Get the id of the first attrib 02842 int num_converted = sscanf( type_substr, " $%d", &( this_record.first_attrib ) ); 02843 if( num_converted != 1 ) return MB_FAILURE; 02844 } 02845 } 02846 02847 return MB_SUCCESS; 02848 } 02849 02850 Tqdcfr::FileTOC::FileTOC() 02851 : fileEndian( 0 ), fileSchema( 0 ), numModels( 0 ), modelTableOffset( 0 ), modelMetaDataOffset( 0 ), 02852 activeFEModel( 0 ) 02853 { 02854 } 02855 02856 void Tqdcfr::FileTOC::print() 02857 { 02858 std::cout << "FileTOC:End, Sch, #Mdl, TabOff, " 02859 << "MdlMDOff, actFEMdl = "; 02860 std::cout << fileEndian << ", " << fileSchema << ", " << numModels << ", " << modelTableOffset << ", " 02861 << modelMetaDataOffset << ", " << activeFEModel << std::endl; 02862 } 02863 02864 Tqdcfr::FEModelHeader::ArrayInfo::ArrayInfo() : numEntities( 0 ), tableOffset( 0 ), metaDataOffset( 0 ) {} 02865 02866 void Tqdcfr::FEModelHeader::ArrayInfo::print() 02867 { 02868 std::cout << "ArrayInfo:numEntities, tableOffset, metaDataOffset = " << numEntities << ", " << tableOffset << ", " 02869 << metaDataOffset << std::endl; 02870 } 02871 02872 void Tqdcfr::FEModelHeader::ArrayInfo::init( const std::vector< unsigned int >& uint_buf_in ) 02873 { 02874 numEntities = uint_buf_in[0]; 02875 tableOffset = uint_buf_in[1]; 02876 metaDataOffset = uint_buf_in[2]; 02877 } 02878 02879 void Tqdcfr::FEModelHeader::print() 02880 { 02881 std::cout << "FEModelHeader:feEndian, feSchema, feCompressFlag, feLength = " << feEndian << ", " << feSchema << ", " 02882 << feCompressFlag << ", " << feLength << std::endl; 02883 std::cout << "geomArray: "; 02884 geomArray.print(); 02885 std::cout << "nodeArray: "; 02886 nodeArray.print(); 02887 std::cout << "elementArray: "; 02888 elementArray.print(); 02889 std::cout << "groupArray: "; 02890 groupArray.print(); 02891 std::cout << "blockArray: "; 02892 blockArray.print(); 02893 std::cout << "nodesetArray: "; 02894 nodesetArray.print(); 02895 std::cout << "sidesetArray: "; 02896 sidesetArray.print(); 02897 } 02898 02899 Tqdcfr::GeomHeader::GeomHeader() 02900 : geomID( 0 ), nodeCt( 0 ), nodeOffset( 0 ), elemCt( 0 ), elemOffset( 0 ), elemTypeCt( 0 ), elemLength( 0 ), 02901 maxDim( 0 ), setHandle( 0 ) 02902 { 02903 } 02904 02905 void Tqdcfr::GeomHeader::print() 02906 { 02907 std::cout << "geomID = " << geomID << std::endl; 02908 std::cout << "nodeCt = " << nodeCt << std::endl; 02909 std::cout << "nodeOffset = " << nodeOffset << std::endl; 02910 std::cout << "elemCt = " << elemCt << std::endl; 02911 std::cout << "elemOffset = " << elemOffset << std::endl; 02912 std::cout << "elemTypeCt = " << elemTypeCt << std::endl; 02913 std::cout << "elemLength = " << elemLength << std::endl; 02914 std::cout << "setHandle = " << setHandle << std::endl; 02915 } 02916 02917 Tqdcfr::GroupHeader::GroupHeader() 02918 : grpID( 0 ), grpType( 0 ), memCt( 0 ), memOffset( 0 ), memTypeCt( 0 ), grpLength( 0 ), setHandle( 0 ) 02919 { 02920 } 02921 02922 void Tqdcfr::GroupHeader::print() 02923 { 02924 std::cout << "grpID = " << grpID << std::endl; 02925 std::cout << "grpType = " << grpType << std::endl; 02926 std::cout << "memCt = " << memCt << std::endl; 02927 std::cout << "memOffset = " << memOffset << std::endl; 02928 std::cout << "memTypeCt = " << memTypeCt << std::endl; 02929 std::cout << "grpLength = " << grpLength << std::endl; 02930 std::cout << "setHandle = " << setHandle << std::endl; 02931 } 02932 02933 Tqdcfr::BlockHeader::BlockHeader() 02934 : blockID( 0 ), blockElemType( 0 ), memCt( 0 ), memOffset( 0 ), memTypeCt( 0 ), attribOrder( 0 ), blockCol( 0 ), 02935 blockMixElemType( 0 ), blockPyrType( 0 ), blockMat( 0 ), blockLength( 0 ), blockDim( 0 ), setHandle( 0 ), 02936 blockEntityType( MBMAXTYPE ) 02937 { 02938 } 02939 02940 void Tqdcfr::BlockHeader::print() 02941 { 02942 std::cout << "blockID = " << blockID << std::endl; 02943 std::cout << "blockElemType = " << blockElemType << std::endl; 02944 std::cout << "memCt = " << memCt << std::endl; 02945 std::cout << "memOffset = " << memOffset << std::endl; 02946 std::cout << "memTypeCt = " << memTypeCt << std::endl; 02947 std::cout << "attribOrder = " << attribOrder << std::endl; 02948 std::cout << "blockCol = " << blockCol << std::endl; 02949 std::cout << "blockMixElemType = " << blockMixElemType << std::endl; 02950 std::cout << "blockPyrType = " << blockPyrType << std::endl; 02951 std::cout << "blockMat = " << blockMat << std::endl; 02952 std::cout << "blockLength = " << blockLength << std::endl; 02953 std::cout << "blockDim = " << blockDim << std::endl; 02954 std::cout << "setHandle = " << setHandle << std::endl; 02955 std::cout << "blockEntityType = " << blockEntityType << std::endl; 02956 } 02957 02958 Tqdcfr::NodesetHeader::NodesetHeader() 02959 : nsID( 0 ), memCt( 0 ), memOffset( 0 ), memTypeCt( 0 ), pointSym( 0 ), nsCol( 0 ), nsLength( 0 ), setHandle( 0 ) 02960 { 02961 } 02962 02963 void Tqdcfr::NodesetHeader::print() 02964 { 02965 std::cout << "nsID = " << nsID << std::endl; 02966 std::cout << "memCt = " << memCt << std::endl; 02967 std::cout << "memOffset = " << memOffset << std::endl; 02968 std::cout << "memTypeCt = " << memTypeCt << std::endl; 02969 std::cout << "pointSym = " << pointSym << std::endl; 02970 std::cout << "nsCol = " << nsCol << std::endl; 02971 std::cout << "nsLength = " << nsLength << std::endl; 02972 std::cout << "setHandle = " << setHandle << std::endl; 02973 } 02974 02975 Tqdcfr::SidesetHeader::SidesetHeader() 02976 : ssID( 0 ), memCt( 0 ), memOffset( 0 ), memTypeCt( 0 ), numDF( 0 ), ssCol( 0 ), useShell( 0 ), ssLength( 0 ), 02977 setHandle( 0 ) 02978 { 02979 } 02980 02981 void Tqdcfr::SidesetHeader::print() 02982 { 02983 std::cout << "ssID = " << ssID << std::endl; 02984 std::cout << "memCt = " << memCt << std::endl; 02985 std::cout << "memOffset = " << memOffset << std::endl; 02986 std::cout << "memTypeCt = " << memTypeCt << std::endl; 02987 std::cout << "numDF = " << numDF << std::endl; 02988 std::cout << "ssCol = " << ssCol << std::endl; 02989 std::cout << "useShell = " << useShell << std::endl; 02990 std::cout << "ssLength = " << ssLength << std::endl; 02991 std::cout << "setHandle = " << setHandle << std::endl; 02992 } 02993 02994 Tqdcfr::MetaDataContainer::MetaDataEntry::MetaDataEntry() 02995 : mdOwner( 0 ), mdDataType( 0 ), mdIntValue( 0 ), mdName( "(uninit)" ), mdStringValue( "(uninit)" ), mdDblValue( 0 ) 02996 { 02997 } 02998 02999 void Tqdcfr::MetaDataContainer::MetaDataEntry::print() 03000 { 03001 std::cout << "MetaDataEntry:own, typ, name, I, D, S = " << mdOwner << ", " << mdDataType << ", " << mdName << ", " 03002 << mdIntValue << ", " << mdDblValue << ", " << mdStringValue; 03003 unsigned int i; 03004 if( mdIntArrayValue.size() ) 03005 { 03006 std::cout << std::endl << "IArray = " << mdIntArrayValue[0]; 03007 for( i = 1; i < mdIntArrayValue.size(); i++ ) 03008 std::cout << ", " << mdIntArrayValue[i]; 03009 } 03010 if( mdDblArrayValue.size() ) 03011 { 03012 std::cout << std::endl << "DArray = " << mdDblArrayValue[0]; 03013 for( i = 1; i < mdDblArrayValue.size(); i++ ) 03014 std::cout << ", " << mdDblArrayValue[i]; 03015 } 03016 std::cout << std::endl; 03017 } 03018 03019 void Tqdcfr::MetaDataContainer::print() 03020 { 03021 std::cout << "MetaDataContainer:mdSchema, compressFlag, numDatums = " << mdSchema << ", " << compressFlag << ", " 03022 << metadataEntries.size() << std::endl; 03023 03024 for( unsigned int i = 0; i < metadataEntries.size(); i++ ) 03025 metadataEntries[i].print(); 03026 } 03027 03028 Tqdcfr::MetaDataContainer::MetaDataContainer() : mdSchema( 0 ), compressFlag( 0 ) {} 03029 03030 int Tqdcfr::MetaDataContainer::get_md_entry( const unsigned int owner, const std::string& name ) 03031 { 03032 for( unsigned int i = 0; i < metadataEntries.size(); i++ ) 03033 { 03034 if( owner == metadataEntries[i].mdOwner && name == metadataEntries[i].mdName ) return i; 03035 } 03036 03037 return -1; 03038 } 03039 03040 Tqdcfr::ModelEntry::ModelEntry() 03041 : modelHandle( 0 ), modelOffset( 0 ), modelLength( 0 ), modelType( 0 ), modelOwner( 0 ), modelPad( 0 ), 03042 feGeomH( NULL ), feGroupH( NULL ), feBlockH( NULL ), feNodeSetH( NULL ), feSideSetH( NULL ) 03043 { 03044 } 03045 03046 Tqdcfr::ModelEntry::~ModelEntry() 03047 { 03048 delete[] feGeomH; 03049 delete[] feGroupH; 03050 delete[] feBlockH; 03051 delete[] feNodeSetH; 03052 delete[] feSideSetH; 03053 } 03054 03055 void Tqdcfr::ModelEntry::print() 03056 { 03057 std::cout << "ModelEntry: Han, Of, Len, Tp, Own, Pd = " << modelHandle << ", " << modelOffset << ", " << modelLength 03058 << ", " << modelType << ", " << modelOwner << ", " << modelPad << std::endl; 03059 } 03060 03061 ErrorCode Tqdcfr::create_set( EntityHandle& h, unsigned int flags ) 03062 { 03063 return mdbImpl->create_meshset( flags, h ); 03064 } 03065 03066 } // namespace moab