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