![]() |
Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
#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 49 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 44 of file ReadNASTRAN.cpp.
References MBI, moab::Interface::query_interface(), and readMeshIface.
Referenced by factory().
: MBI( impl )
{
assert( NULL != impl );
MBI->query_interface( readMeshIface );
assert( NULL != readMeshIface );
}
moab::ReadNASTRAN::~ReadNASTRAN | ( | ) | [virtual] |
Definition at line 52 of file ReadNASTRAN.cpp.
References MBI, readMeshIface, and moab::Interface::release_interface().
{
if( readMeshIface )
{
MBI->release_interface( readMeshIface );
readMeshIface = 0;
}
}
ErrorCode moab::ReadNASTRAN::assign_ids | ( | const Tag * | file_id_tag | ) | [private] |
Definition at line 460 of file ReadNASTRAN.cpp.
References moab::ReadUtilIface::assign_ids(), moab::RangeMap< KeyType, ValType, NullVal >::begin(), elemIdMap, moab::RangeMap< KeyType, ValType, NullVal >::end(), ErrorCode, moab::Interface::globalId_tag(), MB_SUCCESS, MBI, nodeIdMap, readMeshIface, and t.
Referenced by load_file().
{
// Create tag
ErrorCode result;
Tag id_tag = MBI->globalId_tag();
RangeMap< int, EntityHandle >::iterator i;
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 428 of file ReadNASTRAN.cpp.
References moab::Interface::add_entities(), moab::Interface::create_meshset(), ErrorCode, MATERIAL_SET_TAG_NAME, MB_SUCCESS, MB_TAG_CREAT, MB_TAG_SPARSE, MB_TYPE_INTEGER, MBI, MESHSET_SET, moab::Interface::tag_get_handle(), and moab::Interface::tag_set_data().
Referenced by load_file().
{
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 252 of file ReadNASTRAN.cpp.
References MB_NOT_IMPLEMENTED, MB_SUCCESS, MBHEX, MBPRISM, MBTET, and MBVERTEX.
Referenced by load_file().
{
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 198 of file ReadNASTRAN.cpp.
References FREE_FIELD, LARGE_FIELD, MB_SUCCESS, and SMALL_FIELD.
Referenced by load_file().
{
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 38 of file ReadNASTRAN.cpp.
References ReadNASTRAN().
Referenced by moab::ReaderWriterSet::ReaderWriterSet().
{
return new ReadNASTRAN( iface );
}
ErrorCode moab::ReadNASTRAN::get_real | ( | const std::string & | token, |
double & | real | ||
) | [private] |
Definition at line 283 of file ReadNASTRAN.cpp.
References MB_SUCCESS.
Referenced by read_node().
{
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 71 of file ReadNASTRAN.cpp.
References assign_ids(), moab::RangeMap< KeyType, ValType, NullVal >::clear(), create_materials(), moab::debug, determine_entity_type(), determine_line_format(), elemIdMap, ErrorCode, moab::ReadUtilIface::get_node_coords(), moab::RangeMap< KeyType, ValType, NullVal >::insert(), MB_FILE_DOES_NOT_EXIST, MB_SET_ERR, MB_START_ID, MB_SUCCESS, MB_UNSUPPORTED_OPERATION, MBMAXTYPE, MBVERTEX, nodeIdMap, read_element(), read_node(), readMeshIface, and tokenize_line().
{
// At this time there is no support for reading a subset of the file
if( subset_list )
{
MB_SET_ERR( MB_UNSUPPORTED_OPERATION, "Reading subset of files not supported for NASTRAN" );
}
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.empty() ) ? "" : 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 379 of file ReadNASTRAN.cpp.
References moab::Interface::create_element(), elemIdMap, ErrorCode, moab::RangeMap< KeyType, ValType, NullVal >::find(), moab::RangeMap< KeyType, ValType, NullVal >::insert(), MB_SUCCESS, MBI, nodeIdMap, and moab::CN::VerticesPerEntity().
Referenced by load_file().
{
// 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 347 of file ReadNASTRAN.cpp.
References ErrorCode, get_real(), MB_NOT_IMPLEMENTED, and MB_SUCCESS.
Referenced by load_file().
{
// 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 61 of file ReadNASTRAN.cpp.
References MB_NOT_IMPLEMENTED.
{
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 223 of file ReadNASTRAN.cpp.
References FREE_FIELD, LARGE_FIELD, MB_NOT_IMPLEMENTED, MB_SUCCESS, and SMALL_FIELD.
Referenced by load_file().
{
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.
Referenced by assign_ids(), load_file(), and read_element().
Interface* moab::ReadNASTRAN::MBI [private] |
Definition at line 79 of file ReadNASTRAN.hpp.
Referenced by assign_ids(), create_materials(), read_element(), ReadNASTRAN(), and ~ReadNASTRAN().
RangeMap< int, EntityHandle > moab::ReadNASTRAN::nodeIdMap [private] |
Definition at line 81 of file ReadNASTRAN.hpp.
Referenced by assign_ids(), load_file(), and read_element().
ReadUtilIface* moab::ReadNASTRAN::readMeshIface [private] |
Definition at line 76 of file ReadNASTRAN.hpp.
Referenced by assign_ids(), load_file(), ReadNASTRAN(), and ~ReadNASTRAN().