moab
|
#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 35 of file ReadTetGen.hpp.
moab::ReadTetGen::ReadTetGen | ( | Interface * | impl = NULL | ) |
Constructor.
Definition at line 18 of file ReadTetGen.cpp.
moab::ReadTetGen::~ReadTetGen | ( | ) | [virtual] |
Destructor.
Definition at line 24 of file ReadTetGen.cpp.
{ if (mbIface && readTool) mbIface->release_interface( readTool ); }
ReaderIface * moab::ReadTetGen::factory | ( | Interface * | moab | ) | [static] |
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.
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 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.
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 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.
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 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.
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 64 of file ReadTetGen.cpp.
{ return MB_NOT_IMPLEMENTED; }
Interface* moab::ReadTetGen::mbIface [private] |
Definition at line 63 of file ReadTetGen.hpp.
ReadUtilIface* moab::ReadTetGen::readTool [private] |
Definition at line 64 of file ReadTetGen.hpp.