MOAB: Mesh Oriented datABase  (version 5.4.1)
moab::ReadOBJ Class Reference

#include <ReadOBJ.hpp>

+ Inheritance diagram for moab::ReadOBJ:
+ Collaboration diagram for moab::ReadOBJ:

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.
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.
 ReadOBJ (Interface *impl=NULL)
 Constructor.
virtual ~ReadOBJ ()
 Destructor.

Static Public Member Functions

static ReaderIfacefactory (Interface *)
 factory method

Private Member Functions

keyword_type get_keyword (std::vector< std::string > tokens)
template<typename T >
std::string match (const std::string &token, std::map< std::string, T > &tokenList)
void tokenize (const std::string &str, std::vector< std::string > &tokens, const char *delimiters)
ErrorCode create_new_object (std::string object_name, int object_id, EntityHandle &curr_obj_meshset)
ErrorCode create_new_group (std::string object_name, int curr_object, EntityHandle &object_meshset)
ErrorCode create_new_vertex (std::vector< std::string > v_tokens, EntityHandle &vertex_eh)
ErrorCode create_new_face (std::vector< std::string > f_tokens, const std::vector< EntityHandle > &vertex_list, EntityHandle &face_eh)
ErrorCode split_quad (std::vector< std::string > f_tokens, std::vector< EntityHandle > &vertex_list, Range &face_eh)
ErrorCode create_tri_faces (std::vector< EntityHandle > quad_vert_eh, Range &face_eh)

Private Attributes

ReadUtilIfacereadMeshIface
InterfaceMBI
 interface instance
GeomTopoToolmyGeomTool
Tag geom_tag
Tag id_tag
Tag name_tag
Tag category_tag
Tag faceting_tol_tag
Tag geometry_resabs_tag
Tag obj_name_tag

Static Private Attributes

static const char * delimiters = " "

Detailed Description

Definition at line 119 of file ReadOBJ.hpp.


Constructor & Destructor Documentation

moab::ReadOBJ::ReadOBJ ( Interface impl = NULL)

Constructor.

Definition at line 63 of file ReadOBJ.cpp.

References category_tag, CATEGORY_TAG_NAME, CATEGORY_TAG_SIZE, ErrorCode, faceting_tol_tag, GEOM_DIMENSION_TAG_NAME, geom_tag, geometry_resabs_tag, moab::Interface::globalId_tag(), id_tag, MB_CHK_ERR_RET, MB_TAG_CREAT, MB_TAG_SPARSE, MB_TYPE_DOUBLE, MB_TYPE_INTEGER, MB_TYPE_OPAQUE, MBI, myGeomTool, name_tag, NAME_TAG_NAME, NAME_TAG_SIZE, obj_name_tag, moab::Interface::query_interface(), readMeshIface, and moab::Interface::tag_get_handle().

Referenced by factory().

moab::ReadOBJ::~ReadOBJ ( ) [virtual]

Destructor.

Definition at line 94 of file ReadOBJ.cpp.

References MBI, myGeomTool, readMeshIface, and moab::Interface::release_interface().


Member Function Documentation

ErrorCode moab::ReadOBJ::create_new_face ( std::vector< std::string >  f_tokens,
const std::vector< EntityHandle > &  vertex_list,
EntityHandle face_eh 
) [private]

Definition at line 458 of file ReadOBJ.cpp.

References face::conn, moab::Interface::create_element(), ErrorCode, MB_CHK_SET_ERR, MBI, and MBTRI.

Referenced by load_file().

{
    face next_face;
    ErrorCode rval;

    for( int i = 1; i < 4; i++ )
    {
        int vertex_id = atoi( f_tokens[i].c_str() );

        // Some faces contain format 'vertex/texture'
        // Remove the '/texture' and add the vertex to the list
        std::size_t slash = f_tokens[i].find( '/' );
        if( slash != std::string::npos )
        {
            std::string face = f_tokens[i].substr( 0, slash );
            vertex_id        = atoi( face.c_str() );
        }

        next_face.conn[i - 1] = vertex_list[vertex_id - 1];
    }

    rval = MBI->create_element( MBTRI, next_face.conn, 3, face_eh );MB_CHK_SET_ERR( rval, "Unable to create new face." );

    return rval;
}
ErrorCode moab::ReadOBJ::create_new_group ( std::string  object_name,
int  curr_object,
EntityHandle object_meshset 
) [private]

Definition at line 420 of file ReadOBJ.cpp.

References moab::Interface::create_meshset(), ErrorCode, id_tag, MB_CHK_SET_ERR, MBI, MESHSET_SET, name_tag, and moab::Interface::tag_set_data().

Referenced by load_file().

{
    ErrorCode rval;

    // Create meshset to store group
    rval = MBI->create_meshset( MESHSET_SET, group_meshset );MB_CHK_SET_ERR( rval, "Failed to generate group mesh set." );

    // Set meshset tags
    rval = MBI->tag_set_data( name_tag, &group_meshset, 1, group_name.c_str() );MB_CHK_SET_ERR( rval, "Failed to set mesh set name tag." );

    rval = MBI->tag_set_data( id_tag, &group_meshset, 1, &( curr_group ) );MB_CHK_SET_ERR( rval, "Failed to set mesh set ID tag." );

    return rval;
}
ErrorCode moab::ReadOBJ::create_new_object ( std::string  object_name,
int  object_id,
EntityHandle curr_obj_meshset 
) [private]

Definition at line 369 of file ReadOBJ.cpp.

References moab::Interface::add_parent_child(), category_tag, moab::Interface::create_meshset(), dim, ErrorCode, moab::geom_category, moab::geom_name, geom_tag, id_tag, MB_CHK_SET_ERR, MBI, MESHSET_SET, myGeomTool, name_tag, obj_name_tag, SENSE_FORWARD, moab::GeomTopoTool::set_sense(), and moab::Interface::tag_set_data().

Referenced by load_file().

{
    ErrorCode rval;

    // Create meshset to store object
    // This is also referred to as the surface meshset
    rval = MBI->create_meshset( MESHSET_SET, object_meshset );MB_CHK_SET_ERR( rval, "Failed to generate object mesh set." );

    // Set surface meshset tags
    rval = MBI->tag_set_data( name_tag, &object_meshset, 1, object_name.c_str() );MB_CHK_SET_ERR( rval, "Failed to set mesh set name tag." );

    rval = MBI->tag_set_data( id_tag, &object_meshset, 1, &( curr_object ) );MB_CHK_SET_ERR( rval, "Failed to set mesh set ID tag." );

    int dim = 2;
    rval    = MBI->tag_set_data( geom_tag, &object_meshset, 1, &( dim ) );MB_CHK_SET_ERR( rval, "Failed to set mesh set dim tag." );

    rval = MBI->tag_set_data( category_tag, &object_meshset, 1, geom_category[2] );MB_CHK_SET_ERR( rval, "Failed to set mesh set category tag." );

    /* Create volume entity set corresponding to surface
       The volume meshset will have one child--
       the meshset of the surface that bounds the object.
     */
    EntityHandle vol_meshset;
    rval = MBI->create_meshset( MESHSET_SET, vol_meshset );MB_CHK_SET_ERR( rval, "Failed to create volume mesh set." );

    rval = MBI->add_parent_child( vol_meshset, object_meshset );MB_CHK_SET_ERR( rval, "Failed to add object mesh set as child of volume mesh set." );

    /* Set volume meshset tags
       The volume meshset is tagged with the same name as the surface meshset
       for each object because of the direct relation between these entities.
     */
    rval = MBI->tag_set_data( obj_name_tag, &vol_meshset, 1, object_name.c_str() );MB_CHK_SET_ERR( rval, "Failed to set mesh set name tag." );

    rval = MBI->tag_set_data( id_tag, &vol_meshset, 1, &( curr_object ) );MB_CHK_SET_ERR( rval, "Failed to set mesh set ID tag." );

    dim  = 3;
    rval = MBI->tag_set_data( geom_tag, &vol_meshset, 1, &( dim ) );MB_CHK_SET_ERR( rval, "Failed to set mesh set dim tag." );

    rval = MBI->tag_set_data( name_tag, &vol_meshset, 1, geom_name[3] );MB_CHK_SET_ERR( rval, "Failed to set mesh set name tag." );

    rval = MBI->tag_set_data( category_tag, &vol_meshset, 1, geom_category[3] );MB_CHK_SET_ERR( rval, "Failed to set mesh set category tag." );

    rval = myGeomTool->set_sense( object_meshset, vol_meshset, SENSE_FORWARD );MB_CHK_SET_ERR( rval, "Failed to set surface sense." );

    return rval;
}
ErrorCode moab::ReadOBJ::create_new_vertex ( std::vector< std::string >  v_tokens,
EntityHandle vertex_eh 
) [private]

Definition at line 440 of file ReadOBJ.cpp.

References vertex::coord, moab::Interface::create_vertex(), ErrorCode, MB_CHK_SET_ERR, and MBI.

Referenced by load_file().

{
    ErrorCode rval;
    vertex next_vertex;

    for( int i = 1; i < 4; i++ )
        next_vertex.coord[i - 1] = atof( v_tokens[i].c_str() );

    rval = MBI->create_vertex( next_vertex.coord, vertex_eh );MB_CHK_SET_ERR( rval, "Unbale to create vertex." );

    return rval;
}
ErrorCode moab::ReadOBJ::create_tri_faces ( std::vector< EntityHandle quad_vert_eh,
Range face_eh 
) [private]

Definition at line 514 of file ReadOBJ.cpp.

References moab::Interface::create_element(), ErrorCode, moab::Range::insert(), MBI, and MBTRI.

Referenced by split_quad().

{
    ErrorCode rval;
    EntityHandle connectivity[3];
    EntityHandle new_face;

    connectivity[0] = quad_vert_eh[0];
    connectivity[1] = quad_vert_eh[1];
    connectivity[2] = quad_vert_eh[2];
    rval            = MBI->create_element( MBTRI, connectivity, 3, new_face );
    face_eh.insert( new_face );

    connectivity[0] = quad_vert_eh[2];
    connectivity[1] = quad_vert_eh[3];
    connectivity[2] = quad_vert_eh[0];
    rval            = MBI->create_element( MBTRI, connectivity, 3, new_face );
    face_eh.insert( new_face );

    return rval;
}
ReaderIface * moab::ReadOBJ::factory ( Interface iface) [static]

factory method

Definition at line 41 of file ReadOBJ.cpp.

References ReadOBJ().

Referenced by moab::ReaderWriterSet::ReaderWriterSet().

{
    return new ReadOBJ( iface );
}
keyword_type moab::ReadOBJ::get_keyword ( std::vector< std::string >  tokens) [private]

Definition at line 297 of file ReadOBJ.cpp.

References moab::face_start, moab::group_start, match(), moab::object_start, moab::valid_unsupported, and moab::vertex_start.

Referenced by load_file().

{
    std::map< std::string, keyword_type > keywords;

    // currently supported
    keywords["o"] = object_start;
    keywords["g"] = group_start;
    keywords["f"] = face_start;
    keywords["v"] = vertex_start;

    // not currently supported, will be ignored
    keywords["vn"]         = valid_unsupported;
    keywords["vt"]         = valid_unsupported;
    keywords["vp"]         = valid_unsupported;
    keywords["s"]          = valid_unsupported;
    keywords["mtllib"]     = valid_unsupported;
    keywords["usemtl"]     = valid_unsupported;
    keywords["#"]          = valid_unsupported;
    keywords["cstype"]     = valid_unsupported;
    keywords["deg"]        = valid_unsupported;
    keywords["bmat"]       = valid_unsupported;
    keywords["step"]       = valid_unsupported;
    keywords["p"]          = valid_unsupported;
    keywords["l"]          = valid_unsupported;
    keywords["curv"]       = valid_unsupported;
    keywords["curv2"]      = valid_unsupported;
    keywords["surf"]       = valid_unsupported;
    keywords["parm"]       = valid_unsupported;
    keywords["trim"]       = valid_unsupported;
    keywords["hole"]       = valid_unsupported;
    keywords["scrv"]       = valid_unsupported;
    keywords["sp"]         = valid_unsupported;
    keywords["end"]        = valid_unsupported;
    keywords["mg"]         = valid_unsupported;
    keywords["bevel"]      = valid_unsupported;
    keywords["c_interp"]   = valid_unsupported;
    keywords["d_interp"]   = valid_unsupported;
    keywords["lod"]        = valid_unsupported;
    keywords["shadow_obj"] = valid_unsupported;
    keywords["trace_obj"]  = valid_unsupported;
    keywords["ctech"]      = valid_unsupported;
    keywords["stech"]      = valid_unsupported;

    return keywords[match( tokens[0], keywords )];
}
ErrorCode moab::ReadOBJ::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.

Parameters:
file_nameThe file to read.
file_setOptional 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_listAn optional struct pointer specifying the tags identifying entity sets to be read.
file_id_tagIf specified, reader should store for each entity it reads, a unique integer ID for this tag.
Author:
Jason Kraftcheck

Implements moab::ReaderIface.

Definition at line 115 of file ReadOBJ.cpp.

References moab::Interface::add_entities(), moab::Interface::create_meshset(), create_new_face(), create_new_group(), create_new_object(), create_new_vertex(), delimiters, ErrorCode, moab::face_start, get_keyword(), moab::group_start, input_file, MB_CHK_ERR, MB_CHK_SET_ERR, MB_FILE_DOES_NOT_EXIST, MB_SET_ERR, MB_SUCCESS, MB_UNSUPPORTED_OPERATION, MBI, MESHSET_SET, moab::object_start, split_quad(), tokenize(), moab::valid_unsupported, and moab::vertex_start.

{
    ErrorCode rval;
    int ignored = 0;   // Number of lines not beginning with o, v, or f
    std::string line;  // The current line being read
    EntityHandle vert_meshset;
    EntityHandle curr_meshset;  // Current object meshset
    std::string object_name;
    std::vector< EntityHandle > vertex_list;
    int object_id = 0, group_id = 0;  // ID number for each volume/surface
    int num_groups;

    // 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 OBJ." );
    }

    std::ifstream input_file( filename );  // Filestream for OBJ file

    // Check that the file can be read
    if( !input_file.good() )
    {
        std::cout << "Problems reading file = " << filename << std::endl;
        return MB_FILE_DOES_NOT_EXIST;
    }

    // If the file can be read
    if( input_file.is_open() )
    {

        // create meshset for global vertices
        rval = MBI->create_meshset( MESHSET_SET, vert_meshset );MB_CHK_SET_ERR( rval, "Failed to create global vert meshset." );

        while( std::getline( input_file, line ) )
        {
            // Skip blank lines in file
            if( line.length() == 0 ) continue;

            // Tokenize the line
            std::vector< std::string > tokens;
            tokenize( line, tokens, delimiters );

            // Each group and object line must have a name, token size is at least 2
            // Each vertex and face line should have token size of at least 4
            if( tokens.size() < 2 ) continue;

            switch( get_keyword( tokens ) )
            {
                // Object line
                case object_start: {
                    object_id++;
                    object_name = tokens[1];  // Get name of object

                    // Create new meshset for object
                    rval = create_new_object( object_name, object_id, curr_meshset );MB_CHK_ERR( rval );
                    break;
                }

                // Group line
                case group_start: {
                    group_id++;
                    num_groups             = tokens.size() - 1;
                    std::string group_name = "Group";
                    for( int i = 0; i < num_groups; i++ )
                    {
                        group_name = group_name + '_' + tokens[i + 1];
                    }

                    // Create new meshset for group
                    rval = create_new_group( group_name, group_id, curr_meshset );MB_CHK_ERR( rval );
                    break;
                }

                // Vertex line
                case vertex_start: {
                    // Read vertex and return EH
                    EntityHandle new_vertex_eh;
                    rval = create_new_vertex( tokens, new_vertex_eh );MB_CHK_ERR( rval );

                    // Add new vertex EH to list
                    vertex_list.push_back( new_vertex_eh );

                    // Add new vertex EH to the meshset
                    MBI->add_entities( vert_meshset, &new_vertex_eh, 1 );MB_CHK_SET_ERR( rval, "Failed to add vertex to global meshset." );
                    break;
                }

                // Face line
                case face_start: {
                    // Faces in .obj file can have 2, 3, or 4 vertices. If the face has
                    // 3 vertices, the EH will be immediately added to the meshset.
                    // If 4, face is split into triangles.  Anything else is ignored.
                    EntityHandle new_face_eh;

                    if( tokens.size() == 4 )
                    {
                        rval = create_new_face( tokens, vertex_list, new_face_eh );MB_CHK_ERR( rval );

                        if( rval == MB_SUCCESS )
                        {
                            // Add new face EH to the meshset
                            MBI->add_entities( curr_meshset, &new_face_eh, 1 );
                        }
                    }

                    else if( tokens.size() == 5 )
                    {
                        // Split_quad fxn will create 2 new triangles from 1 quad
                        Range new_faces_eh;
                        rval = split_quad( tokens, vertex_list, new_faces_eh );MB_CHK_ERR( rval );

                        // Add new faces created by split quad to meshset
                        if( rval == MB_SUCCESS )
                        {
                            MBI->add_entities( curr_meshset, new_faces_eh );
                        }
                    }

                    else
                    {
                        std::cout << "Neither tri nor a quad: " << line << std::endl;
                    }

                    break;
                }

                case valid_unsupported: {
                    // First token is not recognized as a supported character
                    ++ignored;
                    break;
                }

                default: {
                    MB_SET_ERR( MB_FAILURE, "Invalid/unrecognized line" );
                }
            }
        }
    }

    // If no object lines are read (those beginning w/ 'o'), file is not obj type
    if( object_id == 0 && group_id == 0 )
    {
        MB_SET_ERR( MB_FAILURE, "This is not an obj file. " );
    }

    std::cout << "There were " << ignored << " ignored lines in this file." << std::endl;

    input_file.close();

    return MB_SUCCESS;
}
template<typename T >
std::string moab::ReadOBJ::match ( const std::string &  token,
std::map< std::string, T > &  tokenList 
) [private]

Definition at line 344 of file ReadOBJ.cpp.

References OBJ_UNDEFINED.

Referenced by get_keyword().

{
    // Initialize with no match and obj_undefined as return string
    std::string best_match = OBJ_UNDEFINED;

    // Search the map
    for( typename std::map< std::string, T >::iterator thisToken = tokenList.begin(); thisToken != tokenList.end();
         ++thisToken )
    {
        // If a perfect match break the loop (assume keyword list is unambiguous)
        if( token == ( *thisToken ).first )
        {
            best_match = token;
            break;
        }
    }

    // Possible return values: OBJ_UNDEFINED, keyword from list
    return best_match;
}
ErrorCode moab::ReadOBJ::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 105 of file ReadOBJ.cpp.

References MB_NOT_IMPLEMENTED.

{
    return MB_NOT_IMPLEMENTED;
}
ErrorCode moab::ReadOBJ::split_quad ( std::vector< std::string >  f_tokens,
std::vector< EntityHandle > &  vertex_list,
Range face_eh 
) [private]

Definition at line 487 of file ReadOBJ.cpp.

References create_tri_faces(), ErrorCode, and MB_CHK_SET_ERR.

Referenced by load_file().

{
    ErrorCode rval;
    std::vector< EntityHandle > quad_vert_eh;

    // Loop over quad connectivity getting vertex EHs
    for( int i = 1; i < 5; i++ )
    {
        int vertex_id     = atoi( f_tokens[i].c_str() );
        std::size_t slash = f_tokens[i].find( '/' );
        if( slash != std::string::npos )
        {
            std::string face = f_tokens[i].substr( 0, slash );
            vertex_id        = atoi( face.c_str() );
        }

        quad_vert_eh.push_back( vertex_list[vertex_id - 1] );
    }

    // Create new tri faces
    rval = create_tri_faces( quad_vert_eh, face_eh );MB_CHK_SET_ERR( rval, "Failed to create triangles when splitting quad." );

    return rval;
}
void moab::ReadOBJ::tokenize ( const std::string &  str,
std::vector< std::string > &  tokens,
const char *  delimiters 
) [private]

Definition at line 275 of file ReadOBJ.cpp.

Referenced by load_file().

{
    tokens.clear();

    std::string::size_type next_token_end, next_token_start = str.find_first_not_of( delimiters2, 0 );

    while( std::string::npos != next_token_start )
    {
        next_token_end = str.find_first_of( delimiters2, next_token_start );
        if( std::string::npos == next_token_end )
        {
            tokens.push_back( str.substr( next_token_start ) );
            next_token_start = std::string::npos;
        }
        else
        {
            tokens.push_back( str.substr( next_token_start, next_token_end - next_token_start ) );
            next_token_start = str.find_first_not_of( delimiters2, next_token_end );
        }
    }
}

Member Data Documentation

Definition at line 152 of file ReadOBJ.hpp.

Referenced by create_new_object(), and ReadOBJ().

const char * moab::ReadOBJ::delimiters = " " [static, private]

Definition at line 167 of file ReadOBJ.hpp.

Referenced by load_file().

Definition at line 152 of file ReadOBJ.hpp.

Referenced by ReadOBJ().

Definition at line 152 of file ReadOBJ.hpp.

Referenced by create_new_object(), and ReadOBJ().

Definition at line 152 of file ReadOBJ.hpp.

Referenced by ReadOBJ().

Definition at line 152 of file ReadOBJ.hpp.

Referenced by create_new_group(), create_new_object(), and ReadOBJ().

Definition at line 150 of file ReadOBJ.hpp.

Referenced by create_new_object(), ReadOBJ(), and ~ReadOBJ().

Definition at line 152 of file ReadOBJ.hpp.

Referenced by create_new_group(), create_new_object(), and ReadOBJ().

Definition at line 152 of file ReadOBJ.hpp.

Referenced by create_new_object(), and ReadOBJ().

Definition at line 145 of file ReadOBJ.hpp.

Referenced by ReadOBJ(), and ~ReadOBJ().

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