diff --git a/Core/IO/importer/BaseImporter.hh b/Core/IO/importer/BaseImporter.hh index 119f60de..756f040b 100644 --- a/Core/IO/importer/BaseImporter.hh +++ b/Core/IO/importer/BaseImporter.hh @@ -80,6 +80,9 @@ public: // add texture coordinates per face, _vh references the first texcoord virtual void add_face_texcoords( FaceHandle _fh, VertexHandle _vh, const std::vector& _face_texcoords) = 0; + // Set the texture index for a face + virtual void set_face_texindex( FaceHandle _fh, int _texId ) = 0; + // set vertex normal virtual void set_normal(VertexHandle _vh, const Vec3f& _normal) = 0; @@ -104,6 +107,10 @@ public: // set face color virtual void set_color(FaceHandle _fh, const Vec4uc& _color) = 0; + // Store a property in the mesh mapping from an int to a texture file + // Use set_face_texindex to set the index for each face + virtual void add_texture_information( int _id , std::string _name ) = 0; + // get reference to base kernel virtual BaseKernel* kernel() { return 0; } diff --git a/Core/IO/importer/ImporterT.hh b/Core/IO/importer/ImporterT.hh index d813d786..3bfcd20e 100644 --- a/Core/IO/importer/ImporterT.hh +++ b/Core/IO/importer/ImporterT.hh @@ -120,25 +120,6 @@ public: return fh; } - - virtual void add_face_texcoords( FaceHandle _fh, VertexHandle _vh, const std::vector& _face_texcoords) - { - // get first halfedge handle - HalfedgeHandle cur_heh = mesh_.halfedge_handle(_fh); - HalfedgeHandle end_heh = mesh_.prev_halfedge_handle(cur_heh); - - // find start heh - while( mesh_.to_vertex_handle(cur_heh) != _vh && cur_heh != end_heh ) - cur_heh = mesh_.next_halfedge_handle( cur_heh); - - for(unsigned int i=0; i<_face_texcoords.size(); ++i) - { - set_texcoord( cur_heh, _face_texcoords[i]); - cur_heh = mesh_.next_halfedge_handle( cur_heh); - } - } - - // vertex attributes virtual void set_normal(VertexHandle _vh, const Vec3f& _normal) @@ -193,6 +174,40 @@ public: mesh_.set_color(_fh, color_cast(_color)); } + virtual void add_face_texcoords( FaceHandle _fh, VertexHandle _vh, const std::vector& _face_texcoords) + { + // get first halfedge handle + HalfedgeHandle cur_heh = mesh_.halfedge_handle(_fh); + HalfedgeHandle end_heh = mesh_.prev_halfedge_handle(cur_heh); + + // find start heh + while( mesh_.to_vertex_handle(cur_heh) != _vh && cur_heh != end_heh ) + cur_heh = mesh_.next_halfedge_handle( cur_heh); + + for(unsigned int i=0; i<_face_texcoords.size(); ++i) + { + set_texcoord( cur_heh, _face_texcoords[i]); + cur_heh = mesh_.next_halfedge_handle( cur_heh); + } + } + + virtual void set_face_texindex( FaceHandle _fh, int _texId ) { + if ( mesh_.has_face_texture_index() ) { + mesh_.set_texture_index(_fh , _texId); + } + } + + virtual void add_texture_information( int _id , std::string _name ) { + OpenMesh::MPropHandleT< std::map< int, std::string > > property; + + if ( !mesh_.get_property_handle(property,"TextureMapping") ) { + mesh_.add_property(property,"TextureMapping"); + } + + if ( mesh_.property(property).find( _id ) == mesh_.property(property).end() ) + mesh_.property(property)[_id] = _name; + } + // low-level access to mesh virtual BaseKernel* kernel() { return &mesh_; } diff --git a/Core/IO/reader/OBJReader.cc b/Core/IO/reader/OBJReader.cc index d5ed6f50..746bd0ca 100644 --- a/Core/IO/reader/OBJReader.cc +++ b/Core/IO/reader/OBJReader.cc @@ -64,6 +64,21 @@ _OBJReader_& OBJReader() { return __OBJReaderInstance; } //=== IMPLEMENTATION ========================================================== +//----------------------------------------------------------------------------- + +void trimString( std::string& _string) { + // Trim Both leading and trailing spaces + + size_t start = _string.find_first_not_of(" \t"); + size_t end = _string.find_last_not_of(" \t"); + + if(( std::string::npos == start ) || ( std::string::npos == end)) + _string = ""; + else + _string = _string.substr( start, end-start+1 ); +} + +//----------------------------------------------------------------------------- _OBJReader_:: _OBJReader_() @@ -115,11 +130,13 @@ read_material(std::fstream& _in) { std::string line; std::string keyWrd; + std::string textureName; std::string key; Material mat; float f1,f2,f3; bool indef = false; + int textureId = 1; mat.cleanup(); @@ -190,7 +207,6 @@ read_material(std::fstream& _in) else if (keyWrd == "map_") // map images { - // map_Kd, diffuse map // map_Ks, specular map // map_Ka, ambient map // map_Bump, bump map @@ -198,7 +214,12 @@ read_material(std::fstream& _in) ; // just skip this } #endif - + else if (keyWrd == "map_Kd" ) { + // Get the rest of the line, removeing leading or trailing spaces + std::getline(stream,textureName); + trimString(textureName); + mat.set_map_Kd( textureName, textureId++ ); + } else if (keyWrd == "Tr") // transparency value { stream >> f1; @@ -222,7 +243,6 @@ read_material(std::fstream& _in) //----------------------------------------------------------------------------- - bool _OBJReader_:: read(std::fstream& _in, BaseImporter& _bi, Options& _opt) @@ -238,10 +258,8 @@ read(std::fstream& _in, BaseImporter& _bi, Options& _opt) BaseImporter::VHandles vhandles; std::vector normals; std::vector texcoords; - std::vector face_texcoords; - std::map materials; std::string matname; @@ -254,14 +272,7 @@ read(std::fstream& _in, BaseImporter& _bi, Options& _opt) } // Trim Both leading and trailing spaces - - size_t start = line.find_first_not_of(" \t"); - size_t end = line.find_last_not_of(" \t"); - - if(( std::string::npos == start ) || ( std::string::npos == end)) - line = ""; - else - line = line.substr( start, end-start+1 ); + trimString(line); // comment if ( line.size() == 0 || line[0] == '#' || isspace(line[0]) ) { @@ -290,10 +301,22 @@ read(std::fstream& _in, BaseImporter& _bi, Options& _opt) if ( !read_material( matStream ) ) omerr() << " Warning! Could not read file properly!\n"; matStream.close(); - omlog() << " " << materials_.size() << " materials loaded.\n"; }else omerr() << " Warning! Material file '" << matFile << "' not found!\n"; + + omlog() << " " << materials_.size() << " materials loaded.\n"; + + for ( MaterialList::iterator material = materials_.begin(); material != materials_.end(); material++ ) + { + + if ( (*material).second.has_map_Kd() ) { + std::string filename = path_ + (*material).second.map_Kd(); + _bi.add_texture_information( (*material).second.map_Kd_index() , filename ); + } + } + +// mat.has_map_Kd(); } // usemtl @@ -467,24 +490,53 @@ read(std::fstream& _in, BaseImporter& _bi, Options& _opt) if( !vhandles.empty() ) _bi.add_face_texcoords( fh, vhandles[0], face_texcoords ); - if ( !matname.empty() && materials_[matname].has_Kd() ) + if ( !matname.empty() ) { std::vector newfaces; for( size_t i=0; i < _bi.n_faces()-n_faces; ++i ) newfaces.push_back(FaceHandle(n_faces+i)); - Material & mat = materials_[matname]; + Material& mat = materials_[matname]; - Vec3uc fc = color_cast(mat.Kd()); + if ( mat.has_Kd() ) { + Vec3uc fc = color_cast(mat.Kd()); - for (std::vector::iterator it = newfaces.begin(); - it != newfaces.end(); ++it) - _bi.set_color( *it, fc ); + for (std::vector::iterator it = newfaces.begin(); + it != newfaces.end(); ++it) + _bi.set_color( *it, fc ); - _opt += Options::FaceColor; + _opt += Options::FaceColor; + } + + // Set the texture index in the face index property + if ( mat.has_map_Kd() ) { + + for (std::vector::iterator it = newfaces.begin(); + it != newfaces.end(); ++it) + _bi.set_face_texindex( *it, mat.map_Kd_index() ); + + } else { + // If we don't have the info, set it to no texture + for (std::vector::iterator it = newfaces.begin(); + it != newfaces.end(); ++it) + _bi.set_face_texindex( *it, 0 ); + } + + } else { + std::vector newfaces; + + for( size_t i=0; i < _bi.n_faces()-n_faces; ++i ) + newfaces.push_back(FaceHandle(n_faces+i)); + + // Set the texture index to zero as we don't have any information + for (std::vector::iterator it = newfaces.begin(); + it != newfaces.end(); ++it) + _bi.set_face_texindex( *it, 0 ); } + } + } return true; diff --git a/Core/IO/reader/OBJReader.hh b/Core/IO/reader/OBJReader.hh index c2e3efba..91dc1f60 100644 --- a/Core/IO/reader/OBJReader.hh +++ b/Core/IO/reader/OBJReader.hh @@ -4,7 +4,7 @@ * Copyright (C) 2003 by Computer Graphics Group, RWTH Aachen * * www.openmesh.org * * * - *---------------------------------------------------------------------------* + *---------------------------------------------------------------------------* * * * License * * * @@ -60,7 +60,7 @@ namespace IO { //== IMPLEMENTATION =========================================================== -/** +/** Implementation of the OBJ format reader. */ class _OBJReader_ : public BaseReader @@ -73,9 +73,9 @@ public: std::string get_description() const { return "Alias/Wavefront"; } std::string get_extensions() const { return "obj"; } - - bool read(const std::string& _filename, - BaseImporter& _bi, + + bool read(const std::string& _filename, + BaseImporter& _bi, Options& _opt); private: @@ -89,43 +89,53 @@ private: void cleanup() { - Kd_is_set_ = false; - Ka_is_set_ = false; - Ks_is_set_ = false; - Tr_is_set_ = false; + Kd_is_set_ = false; + Ka_is_set_ = false; + Ks_is_set_ = false; + Tr_is_set_ = false; + map_Kd_is_set_ = false; } - bool is_valid(void) const + bool is_valid(void) const { return Kd_is_set_ || Ka_is_set_ || Ks_is_set_ || Tr_is_set_; } - bool has_Kd(void) { return Kd_is_set_; } - bool has_Ka(void) { return Ka_is_set_; } - bool has_Ks(void) { return Ks_is_set_; } - bool has_Tr(void) { return Tr_is_set_; } - - void set_Kd( float r, float g, float b ) + bool has_Kd(void) { return Kd_is_set_; } + bool has_Ka(void) { return Ka_is_set_; } + bool has_Ks(void) { return Ks_is_set_; } + bool has_Tr(void) { return Tr_is_set_; } + bool has_map_Kd(void) { return map_Kd_is_set_; } + + void set_Kd( float r, float g, float b ) { Kd_=Vec3f(r,g,b); Kd_is_set_=true; } - void set_Ka( float r, float g, float b ) + void set_Ka( float r, float g, float b ) { Ka_=Vec3f(r,g,b); Ka_is_set_=true; } - void set_Ks( float r, float g, float b ) + void set_Ks( float r, float g, float b ) { Ks_=Vec3f(r,g,b); Ks_is_set_=true; } - + void set_Tr( float t ) { Tr_=t; Tr_is_set_=true; } - + + void set_map_Kd( std::string _name, int _index_Kd ) + { map_Kd_ = _name, index_Kd_ = _index_Kd; map_Kd_is_set_ = true; }; + const Vec3f& Kd( void ) const { return Kd_; } const Vec3f& Ka( void ) const { return Ka_; } const Vec3f& Ks( void ) const { return Ks_; } float Tr( void ) const { return Tr_; } - + const std::string& map_Kd( void ) { return map_Kd_ ; } + const int& map_Kd_index( void ) { return index_Kd_ ; } + private: - Vec3f Kd_; bool Kd_is_set_; // diffuse - Vec3f Ka_; bool Ka_is_set_; // ambient - Vec3f Ks_; bool Ks_is_set_; // specular - float Tr_; bool Tr_is_set_; // transperency + Vec3f Kd_; bool Kd_is_set_; // diffuse + Vec3f Ka_; bool Ka_is_set_; // ambient + Vec3f Ks_; bool Ks_is_set_; // specular + float Tr_; bool Tr_is_set_; // transperency + + std::string map_Kd_; int index_Kd_; bool map_Kd_is_set_; // Texture + }; #endif