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