![]() |
Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
#include <ReadTetGen.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 a file | |
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. | |
ReadTetGen (Interface *impl=NULL) | |
Constructor. | |
virtual | ~ReadTetGen () |
Destructor. | |
Static Public Member Functions | |
static ReaderIface * | factory (Interface *) |
Private Member Functions | |
ErrorCode | open_file (const std::string &input_file_name, const std::string &input_name_base, const std::string &input_name_suffix, const char *file_type_suffix, const char *file_name_option, const FileOptions &opts, std::ifstream &file_stream, bool file_required=false) |
Try to open one of several input files. | |
ErrorCode | read_line (std::istream &file, std::string &line, int &lineno) |
Read a line from a file. | |
ErrorCode | read_line (std::istream &file, double *values_out, int num_values, int &lineno) |
Read a line of double values from a file. | |
ErrorCode | parse_attr_list (const std::string &option_str, std::vector< Tag > &tag_list, std::vector< int > &index_list, const char *group_designator=0) |
Parse option string specifying mapping from attributes to tags. | |
ErrorCode | read_node_file (std::istream &file, const Tag *attr_tag_list, const int *attr_tag_index, int attr_tag_list_len, std::vector< EntityHandle > &nodes) |
ErrorCode | read_elem_file (EntityType type, std::istream &file, const std::vector< EntityHandle > &nodes, Range &elems) |
Private Attributes | |
Interface * | mbIface |
ReadUtilIface * | readTool |
Definition at line 36 of file ReadTetGen.hpp.
moab::ReadTetGen::ReadTetGen | ( | Interface * | impl = NULL | ) |
Constructor.
Definition at line 21 of file ReadTetGen.cpp.
References moab::Interface::query_interface(), and readTool.
Referenced by factory().
: mbIface( moab ), readTool( 0 )
{
moab->query_interface( readTool );
}
moab::ReadTetGen::~ReadTetGen | ( | ) | [virtual] |
Destructor.
Definition at line 26 of file ReadTetGen.cpp.
References mbIface, readTool, and moab::Interface::release_interface().
{
if( mbIface && readTool ) mbIface->release_interface( readTool );
}
ReaderIface * moab::ReadTetGen::factory | ( | Interface * | moab | ) | [static] |
Definition at line 16 of file ReadTetGen.cpp.
References ReadTetGen().
Referenced by moab::ReaderWriterSet::ReaderWriterSet().
{
return new ReadTetGen( moab );
}
ErrorCode moab::ReadTetGen::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 a file
Implements moab::ReaderIface.
Definition at line 75 of file ReadTetGen.cpp.
References moab::ReadUtilIface::assign_ids(), ErrorCode, moab::FileOptions::get_str_option(), MB_SET_ERR, MB_SUCCESS, MB_TYPE_OUT_OF_RANGE, MB_UNSUPPORTED_OPERATION, MBEDGE, MBTET, MBTRI, open_file(), parse_attr_list(), read_elem_file(), read_node_file(), readTool, and size.
{
std::ifstream node_file, ele_file, face_file, edge_file;
ErrorCode rval;
if( subset_list )
{
MB_SET_ERR( MB_UNSUPPORTED_OPERATION, "Reading subset of files not supported for TetGen" );
}
std::string suffix, base, filename( file_name_c );
size_t dot_idx = filename.find_last_of( '.' );
if( dot_idx == std::string::npos )
{
base = filename;
}
else
{
suffix = filename.substr( dot_idx + 1 );
for( size_t i = 0; i < suffix.length(); ++i )
suffix[i] = (char)tolower( suffix[i] );
if( suffix == "node" || suffix == "ele" || suffix == "face" || suffix == "edge" )
{
base = filename.substr( 0, dot_idx );
}
else
{
base = filename;
suffix.clear();
}
}
rval = open_file( filename, base, suffix, "node", "NODE_FILE", opts, node_file, true );
if( MB_SUCCESS != rval ) return rval;
rval = open_file( filename, base, suffix, "ele", "ELE_FILE", opts, ele_file );
if( MB_SUCCESS != rval ) return rval;
rval = open_file( filename, base, suffix, "face", "FACE_FILE", opts, face_file );
if( MB_SUCCESS != rval ) return rval;
rval = open_file( filename, base, suffix, "edge", "EDGE_FILE", opts, edge_file );
if( MB_SUCCESS != rval ) return rval;
std::vector< Tag > attr_tags[4];
std::vector< int > attr_idx[4];
const char* option_names[4] = { "NODE_ATTR_LIST", "EDGE_ATTR_LIST", "TRI_ATTR_LIST", "TET_ATTR_LIST" };
const char* group_names[4] = { 0, "CURVE_ID", "SURFACE_ID", "VOLUME_ID" };
for( int i = 0; i < 4; ++i )
{
std::string opt_str;
rval = opts.get_str_option( option_names[i], opt_str );
if( MB_SUCCESS != rval ) continue;
rval = parse_attr_list( opt_str, attr_tags[i], attr_idx[i], group_names[i] );
if( MB_SUCCESS != rval )
{
MB_SET_ERR( MB_TYPE_OUT_OF_RANGE, option_names[i] << ": invalid option value" );
}
}
Range tets, tris, edges;
std::vector< EntityHandle > nodes;
rval = read_node_file( node_file, &attr_tags[0][0], &attr_idx[0][0], attr_tags[0].size(), nodes );
if( MB_SUCCESS == rval && ele_file.is_open() ) rval = read_elem_file( MBTET, ele_file, nodes, tets );
if( MB_SUCCESS == rval && face_file.is_open() ) rval = read_elem_file( MBTRI, face_file, nodes, tris );
if( MB_SUCCESS == rval && edge_file.is_open() ) rval = read_elem_file( MBEDGE, edge_file, nodes, edges );
if( file_id_tag && MB_SUCCESS == rval ) rval = readTool->assign_ids( *file_id_tag, &nodes[0], nodes.size() );
if( file_id_tag && MB_SUCCESS == rval ) rval = readTool->assign_ids( *file_id_tag, edges );
if( file_id_tag && MB_SUCCESS == rval ) rval = readTool->assign_ids( *file_id_tag, tris );
if( file_id_tag && MB_SUCCESS == rval ) rval = readTool->assign_ids( *file_id_tag, tets );
return rval;
}
ErrorCode moab::ReadTetGen::open_file | ( | const std::string & | input_file_name, |
const std::string & | input_name_base, | ||
const std::string & | input_name_suffix, | ||
const char * | file_type_suffix, | ||
const char * | file_name_option, | ||
const FileOptions & | opts, | ||
std::ifstream & | file_stream, | ||
bool | file_required = false |
||
) | [private] |
Try to open one of several input files.
input_file_name | The file name as passed in by the application |
input_name_base | If the input file name ends with a known suffix, the portition of the input file without the suffix. Otherwise equal to input_file_name. |
input_file_suffix | If the input file name ends with a known suffix, the suffix. Otherwise empty. |
file_type_suffix | The suffix for the file type that is to be opened. |
file_name_option | The FileOptions option name specifying the file name to open. |
opts | Input options list. |
file_stream | The stream to open for the file. |
Definition at line 31 of file ReadTetGen.cpp.
References ErrorCode, moab::FileOptions::get_option(), MB_ENTITY_NOT_FOUND, MB_FILE_DOES_NOT_EXIST, MB_SET_ERR, and MB_SUCCESS.
Referenced by load_file().
{
std::string real_file_name;
ErrorCode rval = opts.get_option( opt_name, real_file_name );
if( MB_ENTITY_NOT_FOUND == rval || real_file_name.empty() )
{
if( MB_SUCCESS == rval ) file_required = true;
if( suffix == exp_suffix )
{
real_file_name = filename;
}
else
{
real_file_name = basename;
real_file_name += ".";
real_file_name += exp_suffix;
}
}
if( !real_file_name.empty() ) file_stream.open( real_file_name.c_str(), std::ios::in );
if( file_required && !file_stream.is_open() )
{
MB_SET_ERR( MB_FILE_DOES_NOT_EXIST, real_file_name << ": cannot read file" );
}
return MB_SUCCESS;
}
ErrorCode moab::ReadTetGen::parse_attr_list | ( | const std::string & | option_str, |
std::vector< Tag > & | tag_list, | ||
std::vector< int > & | index_list, | ||
const char * | group_designator = 0 |
||
) | [private] |
Parse option string specifying mapping from attributes to tags.
Given a file option string describing the mapping from tetgen attributes to MOAB tags, parse it and populate the passed vectors.
option_str | Input: The option string to parse. |
tag_list | Output: A list tag handles, one for each attribute. Tag handle value will be zero if the attribute is to be interpreted as a group id. |
index_list | Output: Which array index to store the attribute value at for a multi-valued tag. Zero for single- valued tags. -1 if the corresponding attribute value is to be interpreted as a group ID. |
group_designator | Input: special tag name used to designate an attribute as the group (surface or volume) ID. |
Definition at line 151 of file ReadTetGen.cpp.
References ErrorCode, MB_SUCCESS, MB_TAG_CREAT, MB_TAG_DENSE, MB_TYPE_DOUBLE, mbIface, and moab::Interface::tag_get_handle().
Referenced by load_file().
{
std::vector< std::string > name_list;
size_t prev_pos = 0;
while( prev_pos != std::string::npos )
{
size_t pos = option_str.find_first_of( ',', prev_pos );
name_list.push_back( option_str.substr( prev_pos, pos ) );
prev_pos = pos + 1;
}
index_list.resize( name_list.size() );
std::map< std::string, int > name_count;
for( size_t i = 0; i < name_list.size(); ++i )
index_list[i] = name_count[name_list[i]]++;
for( size_t i = 0; i < name_list.size(); ++i )
{
if( group_designator && name_list[i] == group_designator )
{
tag_list[i] = 0;
index_list[i] = -1;
}
else if( name_list.empty() )
{
tag_list[i] = 0;
index_list[i] = 0;
}
else
{
ErrorCode rval = mbIface->tag_get_handle( name_list[i].c_str(), name_count[name_list[i]], MB_TYPE_DOUBLE,
tag_list[i], MB_TAG_DENSE | MB_TAG_CREAT );
if( MB_SUCCESS != rval ) return rval;
}
}
return MB_SUCCESS;
}
ErrorCode moab::ReadTetGen::read_elem_file | ( | EntityType | type, |
std::istream & | file, | ||
const std::vector< EntityHandle > & | nodes, | ||
Range & | elems | ||
) | [private] |
Definition at line 345 of file ReadTetGen.cpp.
References moab::Interface::add_entities(), moab::Interface::create_meshset(), dim, ErrorCode, GEOM_DIMENSION_TAG_NAME, moab::ReadUtilIface::get_element_connect(), moab::Interface::globalId_tag(), moab::Range::insert(), MB_SET_ERR, MB_SUCCESS, MB_TAG_CREAT, MB_TAG_SPARSE, MB_TYPE_INTEGER, MBEDGE, mbIface, MBTET, MBTRI, MESHSET_SET, read_line(), readTool, moab::Interface::tag_get_handle(), and moab::Interface::tag_set_data().
Referenced by load_file().
{
int lineno = 0;
ErrorCode rval;
int node_per_elem, have_group_id, dim;
double header_vals[3];
switch( type )
{
case MBTET:
rval = read_line( file, header_vals, 3, lineno );
node_per_elem = (int)header_vals[1];
have_group_id = (int)header_vals[2];
dim = 3;
break;
case MBTRI:
rval = read_line( file, header_vals, 2, lineno );
node_per_elem = 3;
have_group_id = (int)header_vals[1];
dim = 2;
break;
case MBEDGE:
rval = read_line( file, header_vals, 1, lineno );
node_per_elem = 2;
have_group_id = 0;
dim = 1;
break;
default:
rval = MB_FAILURE;
break;
}
if( MB_SUCCESS != rval ) return rval;
const int num_elem = (int)header_vals[0];
if( num_elem < 1 || node_per_elem < 2 || have_group_id < 0 || have_group_id > 1 )
{
MB_SET_ERR( MB_FAILURE, "Invalid header line for element data" );
}
// Create group map
std::map< double, EntityHandle > groups;
Tag dim_tag, id_tag;
id_tag = mbIface->globalId_tag();
const int negone = -1;
rval = mbIface->tag_get_handle( GEOM_DIMENSION_TAG_NAME, 1, MB_TYPE_INTEGER, dim_tag, MB_TAG_SPARSE | MB_TAG_CREAT,
&negone );
if( MB_SUCCESS != rval ) return rval;
// Allocate elements
EntityHandle start_handle, *conn_array;
rval = readTool->get_element_connect( num_elem, node_per_elem, type, 1, start_handle, conn_array );
if( MB_SUCCESS != rval ) return rval;
elems.insert( start_handle, start_handle + num_elem - 1 );
// Read data line for each node
std::vector< double > data( 1 + node_per_elem + have_group_id );
std::vector< int > ids( num_elem );
for( int i = 0; i < num_elem; ++i )
{
rval = read_line( file, &data[0], data.size(), lineno );
if( MB_SUCCESS != rval ) return rval;
// Get ID
ids[i] = (int)data[0];
// Get connectivity
for( int j = 0; j < node_per_elem; ++j )
conn_array[node_per_elem * i + j] = nodes[(int)data[j + 1]];
// Grouping
if( have_group_id && 0.0 != data[node_per_elem + 1] )
{
double id = data[node_per_elem + 1];
EntityHandle grp = groups[id];
if( 0 == grp )
{
rval = mbIface->create_meshset( MESHSET_SET, grp );
if( MB_SUCCESS != rval ) return rval;
elems.insert( grp );
rval = mbIface->tag_set_data( dim_tag, &grp, 1, &dim );
if( MB_SUCCESS != rval ) return rval;
int iid = (int)id;
rval = mbIface->tag_set_data( id_tag, &grp, 1, &iid );
if( MB_SUCCESS != rval ) return rval;
groups[id] = grp;
}
EntityHandle handle = start_handle + i;
rval = mbIface->add_entities( grp, &handle, 1 );
if( MB_SUCCESS != rval ) return rval;
}
}
// Store id data
Range elems2;
elems2.insert( start_handle, start_handle + num_elem - 1 );
rval = mbIface->tag_set_data( id_tag, elems2, &ids[0] );
if( MB_SUCCESS != rval ) return rval;
return MB_SUCCESS;
}
ErrorCode moab::ReadTetGen::read_line | ( | std::istream & | file, |
std::string & | line, | ||
int & | lineno | ||
) | [private] |
Read a line from a file.
Read the next non-empty line. Strips comments.
file | The stream to read from |
line | Output: the line read from the stream |
lineno | Incremented for each real line read from the stream (including disgarded empty and comment lines.) |
Definition at line 193 of file ReadTetGen.cpp.
References MB_FILE_WRITE_ERROR, and MB_SUCCESS.
Referenced by read_elem_file(), read_line(), and read_node_file().
{
// Loop until we find a non-empty line
do
{
// Read a line
line.clear();
if( !getline( file, line ) ) return MB_FILE_WRITE_ERROR;
++lineno;
// Strip comments from line
size_t pos = line.find_first_of( '#' );
if( pos != std::string::npos ) line = line.substr( 0, pos );
// Strip leading whitespace from line
for( pos = 0; pos < line.length() && isspace( line[pos] ); ++pos )
;
if( pos == line.length() )
line.clear();
else if( pos != 0 )
line = line.substr( pos );
} while( line.empty() );
return MB_SUCCESS;
}
ErrorCode moab::ReadTetGen::read_line | ( | std::istream & | file, |
double * | values_out, | ||
int | num_values, | ||
int & | lineno | ||
) | [private] |
Read a line of double values from a file.
Definition at line 217 of file ReadTetGen.cpp.
References ErrorCode, MB_SET_ERR, MB_SUCCESS, and read_line().
{
// Get a line of text
std::string line;
ErrorCode rval = read_line( file, line, lineno );
if( MB_SUCCESS != rval ) return rval;
// Tokenize line as doubles
std::stringstream str( line );
for( int i = 0; i < num_values; ++i )
{
double v;
if( !( str >> v ) )
{
MB_SET_ERR( MB_FAILURE, "Error reading node data at line " << lineno );
}
values_out[i] = v;
}
// Check that we're at the end of the line
int junk;
if( ( str >> junk ) || !str.eof() )
{
MB_SET_ERR( MB_FAILURE, "Unexpected trailing data for line " << lineno << " of node data" );
}
return MB_SUCCESS;
}
ErrorCode moab::ReadTetGen::read_node_file | ( | std::istream & | file, |
const Tag * | attr_tag_list, | ||
const int * | attr_tag_index, | ||
int | attr_tag_list_len, | ||
std::vector< EntityHandle > & | nodes | ||
) | [private] |
Definition at line 246 of file ReadTetGen.cpp.
References dim, ErrorCode, moab::ReadUtilIface::get_node_coords(), moab::Interface::globalId_tag(), moab::Range::insert(), MB_SET_ERR, MB_SUCCESS, mbIface, read_line(), readTool, and moab::Interface::tag_set_data().
Referenced by load_file().
{
int lineno = 0;
ErrorCode rval;
double header_vals[4];
rval = read_line( file, header_vals, 4, lineno );
if( MB_SUCCESS != rval ) return rval;
const int num_vtx = (int)header_vals[0];
const int dim = (int)header_vals[1];
const int num_attr = (int)header_vals[2];
const int bdry_flag = (int)header_vals[3];
if( num_vtx < 1 || dim < 2 || dim > 3 || num_attr < 0 || bdry_flag < 0 || bdry_flag > 1 )
{
MB_SET_ERR( MB_FAILURE, "Invalid header line for node data" );
}
if( attr_tag_list_len > num_attr ) attr_tag_list_len = num_attr;
// Allocate space for tag data
std::map< Tag, int > tag_size;
std::map< Tag, std::vector< double > > tag_data;
for( int i = 0; i < attr_tag_list_len; ++i )
{
if( !attr_tag_list[i] || attr_tag_index[i] < 0 ) continue;
std::vector< double >& data = tag_data[attr_tag_list[i]];
// Increase tag size by one value per vertex for each time
// we encounter it in the list.
data.resize( data.size() + num_vtx );
++tag_size[attr_tag_list[i]];
}
std::vector< double* > attr_data( attr_tag_list_len );
std::vector< int > attr_size( attr_tag_list_len );
for( int i = 0; i < attr_tag_list_len; ++i )
{
if( !attr_tag_list[i] || attr_tag_index[i] < 0 )
{
attr_data[i] = 0;
attr_size[i] = 0;
}
else
{
attr_data[i] = &( tag_data[attr_tag_list[i]] )[0];
attr_size[i] = tag_size[attr_tag_list[i]];
}
}
// Allocate vertices
std::vector< double* > coords;
EntityHandle start_handle;
rval = readTool->get_node_coords( dim, num_vtx, 1, start_handle, coords );
if( MB_SUCCESS != rval ) return rval;
// Read data line for each node
nodes.reserve( num_vtx );
std::vector< double > data( 1 + dim + num_attr + bdry_flag );
std::vector< int > ids( num_vtx );
for( int i = 0; i < num_vtx; ++i )
{
rval = read_line( file, &data[0], data.size(), lineno );
if( MB_SUCCESS != rval ) return rval;
// Get ID
ids[i] = (int)data[0];
if( ids[i] >= (int)nodes.size() ) nodes.resize( ids[i] + 1 );
nodes[ids[i]] = start_handle + i;
// Get coordinates
// Cppcheck warning (false positive): variable coords is assigned a value that is never used
for( int j = 0; j < dim; ++j )
coords[j][i] = data[j + 1];
// Get attribute data
for( int j = 0; j < attr_tag_list_len; ++j )
if( attr_data[j] ) attr_data[j][i * attr_size[j] + attr_tag_index[j]] = data[j + 1 + dim];
// Discard boundary bit
}
// Store tag data
Range node_range;
node_range.insert( start_handle, start_handle + num_vtx - 1 );
for( std::map< Tag, std::vector< double > >::iterator i = tag_data.begin(); i != tag_data.end(); ++i )
{
rval = mbIface->tag_set_data( i->first, node_range, &i->second[0] );
if( MB_SUCCESS != rval ) return rval;
}
Tag idtag = mbIface->globalId_tag();
rval = mbIface->tag_set_data( idtag, node_range, &ids[0] );
if( MB_SUCCESS != rval ) return rval;
return MB_SUCCESS;
}
ErrorCode moab::ReadTetGen::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 66 of file ReadTetGen.cpp.
References MB_NOT_IMPLEMENTED.
{
return MB_NOT_IMPLEMENTED;
}
Interface* moab::ReadTetGen::mbIface [private] |
Definition at line 62 of file ReadTetGen.hpp.
Referenced by parse_attr_list(), read_elem_file(), read_node_file(), and ~ReadTetGen().
ReadUtilIface* moab::ReadTetGen::readTool [private] |
Definition at line 63 of file ReadTetGen.hpp.
Referenced by load_file(), read_elem_file(), read_node_file(), ReadTetGen(), and ~ReadTetGen().