moab
|
#include <ReadNASTRAN.hpp>
Public Member Functions | |
ErrorCode | load_file (const char *file_name, const EntityHandle *file_set, const FileOptions &opts, const SubsetList *subset_list=0, const Tag *file_id_tag=0) |
Load mesh from a file. | |
ReadNASTRAN (Interface *impl=NULL) | |
virtual | ~ReadNASTRAN () |
ErrorCode | read_tag_values (const char *file_name, const char *tag_name, const FileOptions &opts, std::vector< int > &tag_values_out, const SubsetList *subset_list=0) |
Read tag values from a file. | |
Static Public Member Functions | |
static ReaderIface * | factory (Interface *) |
Private Types | |
enum | line_format { SMALL_FIELD, LARGE_FIELD, FREE_FIELD } |
Private Member Functions | |
ErrorCode | determine_line_format (const std::string line, line_format &format) |
ErrorCode | tokenize_line (const std::string line, const line_format format, std::vector< std::string > &tokens) |
ErrorCode | determine_entity_type (const std::string token, EntityType &type) |
ErrorCode | get_real (const std::string, double &real) |
ErrorCode | read_node (const std::vector< std::string > tokens, const bool debug, double *coord_arrays[3], int &node_id) |
ErrorCode | read_element (const std::vector< std::string > tokens, std::vector< Range > &materials, const EntityType element_type, const bool debug) |
ErrorCode | create_materials (const std::vector< Range > &materials) |
ErrorCode | assign_ids (const Tag *file_id_tag) |
Private Attributes | |
ReadUtilIface * | readMeshIface |
Interface * | MBI |
RangeMap< int, EntityHandle > | nodeIdMap |
RangeMap< int, EntityHandle > | elemIdMap |
Definition at line 48 of file ReadNASTRAN.hpp.
enum moab::ReadNASTRAN::line_format [private] |
Definition at line 83 of file ReadNASTRAN.hpp.
{ SMALL_FIELD, LARGE_FIELD, FREE_FIELD };
moab::ReadNASTRAN::ReadNASTRAN | ( | Interface * | impl = NULL | ) |
Definition at line 42 of file ReadNASTRAN.cpp.
: MBI(impl) { assert(NULL != impl); MBI->query_interface(readMeshIface); assert(NULL != readMeshIface); }
moab::ReadNASTRAN::~ReadNASTRAN | ( | ) | [virtual] |
Definition at line 50 of file ReadNASTRAN.cpp.
{ if (readMeshIface) { MBI->release_interface(readMeshIface); readMeshIface = 0; } }
ErrorCode moab::ReadNASTRAN::assign_ids | ( | const Tag * | file_id_tag | ) | [private] |
Definition at line 423 of file ReadNASTRAN.cpp.
{ // create tag ErrorCode result; Tag id_tag; int zero = 0; result = MBI->tag_get_handle(GLOBAL_ID_TAG_NAME, 1, MB_TYPE_INTEGER, id_tag, MB_TAG_DENSE|MB_TAG_CREAT, &zero); if(MB_SUCCESS!=result && MB_ALREADY_ALLOCATED!=result) return result; RangeMap<int,EntityHandle>::iterator i; std::vector<int> ids; for (int t = 0; t < 2; ++t) { RangeMap<int,EntityHandle>& fileIdMap = t ? elemIdMap : nodeIdMap; for (i = fileIdMap.begin(); i != fileIdMap.end(); ++i) { Range range( i->value, i->value + i->count - 1 ); result = readMeshIface->assign_ids( id_tag, range, i->begin ); if (MB_SUCCESS != result) return result; if (file_id_tag && *file_id_tag != id_tag) { result = readMeshIface->assign_ids( *file_id_tag, range, i->begin ); if (MB_SUCCESS != result) return result; } } } return MB_SUCCESS; }
ErrorCode moab::ReadNASTRAN::create_materials | ( | const std::vector< Range > & | materials | ) | [private] |
Definition at line 388 of file ReadNASTRAN.cpp.
{ ErrorCode result; Tag material_tag; int negone = -1; result = MBI->tag_get_handle(MATERIAL_SET_TAG_NAME, 1, MB_TYPE_INTEGER, material_tag, MB_TAG_SPARSE|MB_TAG_CREAT, &negone); if(MB_SUCCESS!=result) return result; for (size_t i = 0; i < materials.size(); ++i) { if (materials[i].empty()) continue; // Merge with existing or create new? Original code effectively // created new by only merging with existing in current file set, // so do the same here. - j.kraftcheck EntityHandle handle; result = MBI->create_meshset( MESHSET_SET, handle ); if (MB_SUCCESS != result) return result; result = MBI->add_entities( handle, materials[i] ); if (MB_SUCCESS != result) return result; int id = i; result = MBI->tag_set_data( material_tag, &handle, 1, &id ); if (MB_SUCCESS != result) return result; } return MB_SUCCESS; }
ErrorCode moab::ReadNASTRAN::determine_entity_type | ( | const std::string | token, |
EntityType & | type | ||
) | [private] |
Definition at line 232 of file ReadNASTRAN.cpp.
{ if (0==first_token.compare("GRID ")) type = MBVERTEX; else if(0==first_token.compare("CTETRA ")) type = MBTET; else if(0==first_token.compare("CPENTA ")) type = MBPRISM; else if(0==first_token.compare("CHEXA ")) type = MBHEX; else return MB_NOT_IMPLEMENTED; return MB_SUCCESS; }
ErrorCode moab::ReadNASTRAN::determine_line_format | ( | const std::string | line, |
line_format & | format | ||
) | [private] |
Definition at line 189 of file ReadNASTRAN.cpp.
{ std::string::size_type found_asterisk = line.find("*"); if(std::string::npos != found_asterisk) { format = LARGE_FIELD; return MB_SUCCESS; } else { std::string::size_type found_comma = line.find(","); if(std::string::npos != found_comma) { format = FREE_FIELD; return MB_SUCCESS; } else { format = SMALL_FIELD; return MB_SUCCESS; } } }
ReaderIface * moab::ReadNASTRAN::factory | ( | Interface * | iface | ) | [static] |
Definition at line 37 of file ReadNASTRAN.cpp.
{ return new ReadNASTRAN( iface ); }
ErrorCode moab::ReadNASTRAN::get_real | ( | const std::string | token, |
double & | real | ||
) | [private] |
Definition at line 258 of file ReadNASTRAN.cpp.
{ std::string significand = token; std::string exponent = "0"; // Cut off the first digit because a "-" could be here indicating a negative // number. Instead we are looking for a negative exponent. std::string back_token = token.substr(1); // A minus that is not the first digit is always a negative exponent std::string::size_type found_minus = back_token.find("-"); if(std::string::npos != found_minus) { // separate the significand from the exponent at the "-" exponent = token.substr( found_minus+1 ); significand = token.substr( 0, found_minus+1 ); // if the significand has an "E", remove it if(std::string::npos != significand.find("E")) // Assume the "E" is at the end of the significand. significand = significand.substr( 1, significand.size()-2 ); // If a minus does not exist past the 1st digit, but an "E" or "+" does, then // it is a positive exponent. First look for an "E", } else { std::string::size_type found_E = token.find("E"); if(std::string::npos != found_E) { significand = token.substr(0, found_E-1); exponent = token.substr(found_E+1); // if there is a "+" on the exponent, cut it off std::size_t found_plus = exponent.find("+"); if(std::string::npos != found_plus) { exponent = exponent.substr(found_plus+1); } } else { // if there is a "+" on the exponent, cut it off std::size_t found_plus = token.find("+"); if(std::string::npos != found_plus) { significand = token.substr(0, found_plus-1); exponent = token.substr(found_plus+1); } } } // now assemble the real number double signi = atof(significand.c_str()); double expon = atof(exponent.c_str()); if(HUGE_VAL==signi || HUGE_VAL==expon) return MB_FAILURE; real = signi * pow( 10, expon ); return MB_SUCCESS; }
ErrorCode moab::ReadNASTRAN::load_file | ( | const char * | file_name, |
const EntityHandle * | file_set, | ||
const FileOptions & | opts, | ||
const SubsetList * | subset_list = 0 , |
||
const Tag * | file_id_tag = 0 |
||
) | [virtual] |
Load mesh from a file.
Method all readers must provide to import a mesh.
file_name | The file to read. |
file_set | Optional pointer to entity set representing file. If this is not NULL, reader may optionally tag the pointed-to set with format-specific meta-data. |
subset_list | An optional struct pointer specifying the tags identifying entity sets to be read. |
file_id_tag | If specified, reader should store for each entity it reads, a unique integer ID for this tag. |
Implements moab::ReaderIface.
Definition at line 67 of file ReadNASTRAN.cpp.
{ // at this time there is no support for reading a subset of the file if (subset_list) { readMeshIface->report_error( "Reading subset of files not supported for NASTRAN." ); return MB_UNSUPPORTED_OPERATION; } nodeIdMap.clear(); elemIdMap.clear(); bool debug = false; if (debug) std::cout << "begin ReadNASTRAN::load_file" << std::endl; ErrorCode result; // Count the entities of each type in the file. This is used to allocate the node array. int entity_count[MBMAXTYPE]; for(int i=0; i<MBMAXTYPE; i++) entity_count[i] = 0; /* Determine the line_format of the first line. Assume that the entire file has the same format. */ std::string line; std::ifstream file (filename); if (!getline(file,line)) return MB_FILE_DOES_NOT_EXIST; line_format format; result = determine_line_format( line, format ); if(MB_SUCCESS != result) return result; /* Count the number of each entity in the file. This allows one to allocate a sequential array of vertex handles. */ while(!file.eof()) { // Cut the line into fields as determined by the line format. // Use a vector to allow for an unknown number of tokens (continue lines). // Continue lines are not implemented. std::vector<std::string> tokens; tokens.reserve(10); // assume 10 fields to avoid extra vector resizing result = tokenize_line( line, format, tokens ); if(MB_SUCCESS != result) return result; // Process the tokens of the line. The first token describes the entity type. EntityType type; result = determine_entity_type( tokens.front(), type ); if(MB_SUCCESS != result) return result; entity_count[type]++; getline(file,line); } if(debug) { for(int i=0; i<MBMAXTYPE; i++) { std::cout << "entity_count[" << i << "]=" << entity_count[i] << std::endl; } } // Keep list of material sets std::vector<Range> materials; // Now that the number of vertices is known, create the vertices. EntityHandle start_vert = 0; std::vector<double*> coord_arrays(3); result = readMeshIface->get_node_coords( 3, entity_count[0], MB_START_ID, start_vert, coord_arrays ); if(MB_SUCCESS != result) return result; if(0 == start_vert) return MB_FAILURE; // check for NULL int id, vert_index = 0; if(debug) std::cout << "allocated coord arrays" << std::endl; // Read the file again to create the entities. file.clear(); // clear eof state from object file.seekg(0); // rewind file while (!file.eof()) { getline(file,line); // Cut the line into fields as determined by the line format. // Use a vector to allow for an unknown number of tokens (continue lines). // Continue lines are not implemented. std::vector<std::string> tokens; tokens.reserve(10); // assume 10 fields to avoid extra vector resizing result = tokenize_line( line, format, tokens ); if(MB_SUCCESS != result) return result; // Process the tokens of the line. The first token describes the entity type. EntityType type; result = determine_entity_type( tokens.front(), type ); if(MB_SUCCESS != result) return result; // Create the entity. if(MBVERTEX == type) { double* coords[3] = { coord_arrays[0] + vert_index, coord_arrays[1] + vert_index, coord_arrays[2] + vert_index }; result = read_node(tokens, debug, coords, id ); if(MB_SUCCESS != result) return result; if (!nodeIdMap.insert( id, start_vert + vert_index, 1 ).second) return MB_FAILURE; // duplicate IDs! ++vert_index; } else { result = read_element( tokens, materials, type, debug ); if(MB_SUCCESS != result) return result; } } result = create_materials( materials ); if(MB_SUCCESS != result) return result; result = assign_ids( file_id_tag ); if(MB_SUCCESS != result) return result; file.close(); nodeIdMap.clear(); elemIdMap.clear(); return MB_SUCCESS; }
ErrorCode moab::ReadNASTRAN::read_element | ( | const std::vector< std::string > | tokens, |
std::vector< Range > & | materials, | ||
const EntityType | element_type, | ||
const bool | debug | ||
) | [private] |
Definition at line 341 of file ReadNASTRAN.cpp.
{ // read the element's id (unique) and material set ErrorCode result; int id = atoi(tokens[1].c_str()); int material = atoi(tokens[2].c_str()); // Resize materials list if necessary. This code is somewhat complicated // so as to avoid copying of Ranges if (material >= (int)materials.size()) { if ((int)materials.capacity() < material) materials.resize( material+1 ); else { std::vector<Range> new_mat( material+1 ); for (size_t i = 0; i < materials.size(); ++i) new_mat[i].swap( materials[i] ); materials.swap( new_mat ); } } // the size of the connectivity array depends on the element type int n_conn = CN::VerticesPerEntity(element_type); EntityHandle conn_verts[27]; assert(n_conn <= (int)(sizeof(conn_verts)/sizeof(EntityHandle))); // read the connected node ids from the file for(int i=0; i<n_conn; i++) { int n = atoi(tokens[3+i].c_str()); conn_verts[i] = nodeIdMap.find( n ); if (!conn_verts[i]) // invalid vertex id return MB_FAILURE; } // Create the element and set the global id from the NASTRAN file EntityHandle element; result = MBI->create_element( element_type, conn_verts, n_conn, element ); if(MB_SUCCESS != result) return result; elemIdMap.insert( id, element, 1 ); materials[material].insert( element ); return MB_SUCCESS; }
ErrorCode moab::ReadNASTRAN::read_node | ( | const std::vector< std::string > | tokens, |
const bool | debug, | ||
double * | coord_arrays[3], | ||
int & | node_id | ||
) | [private] |
Definition at line 311 of file ReadNASTRAN.cpp.
{ // read the node's id (unique) ErrorCode result; id = atoi(tokens[1].c_str()); // read the node's coordinate system number // "0" or blank refers to the basic coordinate system. int coord_system = atoi(tokens[2].c_str()); if(0 != coord_system) { std::cerr << "ReadNASTRAN: alternative coordinate systems not implemented" << std::endl; return MB_NOT_IMPLEMENTED; } // read the coordinates for(unsigned int i=0; i<3; i++) { result = get_real( tokens[i+3], *coords[i] ); if(MB_SUCCESS != result) return result; if(debug) std::cout << "read_node: coords[" << i << "]=" << coords[i] << std::endl; } return MB_SUCCESS; }
ErrorCode moab::ReadNASTRAN::read_tag_values | ( | const char * | file_name, |
const char * | tag_name, | ||
const FileOptions & | opts, | ||
std::vector< int > & | tag_values_out, | ||
const SubsetList * | subset_list = 0 |
||
) | [virtual] |
Read tag values from a file.
Read the list if all integer tag values from the file for a tag that is a single integer value per entity.
file_name | The file to read. |
tag_name | The tag for which to read values |
tag_values_out | Output: The list of tag values. |
subset_list | An array of tag name and value sets specifying the subset of the file to read. If multiple tags are specified, the sets that match all tags (intersection) should be read. |
subset_list_length | The length of the 'subset_list' array. |
Implements moab::ReaderIface.
Definition at line 57 of file ReadNASTRAN.cpp.
{ return MB_NOT_IMPLEMENTED; }
ErrorCode moab::ReadNASTRAN::tokenize_line | ( | const std::string | line, |
const line_format | format, | ||
std::vector< std::string > & | tokens | ||
) | [private] |
Definition at line 208 of file ReadNASTRAN.cpp.
{ size_t line_size = line.size(); switch(format) { case SMALL_FIELD: { // Expect 10 fields of 8 characters. // The sample file does not have all 10 fields in each line const int field_length = 8; unsigned int n_tokens = line_size / field_length; for(unsigned int i=0; i<n_tokens; i++) { tokens.push_back( line.substr(i*field_length,field_length) ); } break; } case LARGE_FIELD: return MB_NOT_IMPLEMENTED; case FREE_FIELD: return MB_NOT_IMPLEMENTED; default: return MB_FAILURE; } return MB_SUCCESS; }
RangeMap<int, EntityHandle> moab::ReadNASTRAN::elemIdMap [private] |
Definition at line 81 of file ReadNASTRAN.hpp.
Interface* moab::ReadNASTRAN::MBI [private] |
Definition at line 79 of file ReadNASTRAN.hpp.
RangeMap<int, EntityHandle> moab::ReadNASTRAN::nodeIdMap [private] |
Definition at line 81 of file ReadNASTRAN.hpp.
ReadUtilIface* moab::ReadNASTRAN::readMeshIface [private] |
Definition at line 76 of file ReadNASTRAN.hpp.