Mesh Oriented datABase  (version 5.4.1)
Array-based unstructured mesh datastructure
moab::ReadTetGen Class Reference

#include <ReadTetGen.hpp>

+ Inheritance diagram for moab::ReadTetGen:
+ Collaboration diagram for moab::ReadTetGen:

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 ReaderIfacefactory (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

InterfacembIface
ReadUtilIfacereadTool

Detailed Description

Definition at line 36 of file ReadTetGen.hpp.


Constructor & Destructor Documentation

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 );
}

Destructor.

Definition at line 26 of file ReadTetGen.cpp.

References mbIface, readTool, and moab::Interface::release_interface().


Member Function Documentation

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.

Parameters:
input_file_nameThe file name as passed in by the application
input_name_baseIf 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_suffixIf the input file name ends with a known suffix, the suffix. Otherwise empty.
file_type_suffixThe suffix for the file type that is to be opened.
file_name_optionThe FileOptions option name specifying the file name to open.
optsInput options list.
file_streamThe 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.

Parameters:
option_strInput: The option string to parse.
tag_listOutput: 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_listOutput: 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_designatorInput: 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.

Parameters:
fileThe stream to read from
lineOutput: the line read from the stream
linenoIncremented 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.

Parameters:
file_nameThe file to read.
tag_nameThe tag for which to read values
tag_values_outOutput: The list of tag values.
subset_listAn 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_lengthThe 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;
}

Member Data Documentation

List of all members.


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines