moab
moab::ReadTetGen Class Reference

#include <ReadTetGen.hpp>

Inheritance diagram for moab::ReadTetGen:
moab::ReaderIface

List of all members.

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 35 of file ReadTetGen.hpp.


Constructor & Destructor Documentation

Constructor.

Definition at line 18 of file ReadTetGen.cpp.

  : mbIface(moab), readTool(0)
{
  moab->query_interface(readTool);
}

Destructor.

Definition at line 24 of file ReadTetGen.cpp.


Member Function Documentation

Definition at line 15 of file ReadTetGen.cpp.

  { 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 74 of file ReadTetGen.cpp.

{
  std::ifstream node_file, ele_file, face_file, edge_file;
  ErrorCode rval;
  
  if (subset_list) {
    readTool->report_error( "Reading subset of files not supported for TetGen." );
    return MB_UNSUPPORTED_OPERATION;
  }
  
  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) {
      readTool->report_error( "%s: invalid option value.", option_names[i] );
      return MB_TYPE_OUT_OF_RANGE;
    }
  }
  
  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 30 of file ReadTetGen.cpp.

{
  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()) {
    readTool->report_error( "%s: cannot read file.", real_file_name.c_str() );
    return MB_FILE_DOES_NOT_EXIST;
  }
  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 157 of file ReadTetGen.cpp.

{
  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 362 of file ReadTetGen.cpp.

{
  int lineno = 0;
  std::string line;
  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) {
    readTool->report_error( "Invalid header line for element data." );
    return MB_FAILURE;
  }
  
    // create group map
  std::map<double,EntityHandle> groups;
  Tag dim_tag, id_tag;
  rval = mbIface->tag_get_handle( GLOBAL_ID_TAG_NAME, 1, MB_TYPE_INTEGER, id_tag );
  if (MB_SUCCESS != rval)
    return rval;
  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 198 of file ReadTetGen.cpp.

{
    // 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 224 of file ReadTetGen.cpp.

{
    // 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)) {
      readTool->report_error( "Error reading node data at line %d.", lineno );
      return MB_FAILURE;
    }
    values_out[i] = v;
  }
  
    // check that we're at the end of the line
  int junk;
  if ((str >> junk) || !str.eof()) {
    readTool->report_error( "Unexpected trailing data for line %d of node data", lineno );
    return MB_FAILURE;
  }
  
  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 256 of file ReadTetGen.cpp.

{
  int lineno = 0;
  std::string line;
  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) {
    readTool->report_error( "Invalid header line for node data." );
    return MB_FAILURE;
  }
  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 coordiantes
    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];
    
      // disgard 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;
  rval = mbIface->tag_get_handle( GLOBAL_ID_TAG_NAME, 1, MB_TYPE_INTEGER, idtag );
  if (MB_SUCCESS == rval) {
    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 64 of file ReadTetGen.cpp.

{
  return MB_NOT_IMPLEMENTED;
}

Member Data Documentation

Definition at line 63 of file ReadTetGen.hpp.

Definition at line 64 of file ReadTetGen.hpp.


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