54 #include <OpenMesh/Core/IO/reader/OBJReader.hh>
55 #include <OpenMesh/Core/IO/IOManager.hh>
56 #include <OpenMesh/Core/Utils/vector_cast.hh>
57 #include <OpenMesh/Core/Utils/color_cast.hh>
59 #if defined(OM_CC_MIPS)
62 #elif defined(_STLPORT_VERSION) && (_STLPORT_VERSION==0x460)
83 _OBJReader_ __OBJReaderInstance;
84 _OBJReader_& OBJReader() {
return __OBJReaderInstance; }
91 void trimString( std::string& _string) {
94 size_t start = _string.find_first_not_of(
" \t\r\n");
95 size_t end = _string.find_last_not_of(
" \t\r\n");
97 if(( std::string::npos == start ) || ( std::string::npos == end))
100 _string = _string.substr( start, end-start+1 );
106 void remove_duplicated_vertices(BaseImporter::VHandles& _indices)
108 BaseImporter::VHandles::iterator endIter = _indices.end();
109 for (BaseImporter::VHandles::iterator iter = _indices.begin(); iter != endIter; ++iter)
110 endIter = std::remove(iter+1, endIter, *(iter));
112 _indices.erase(endIter,_indices.end());
131 std::fstream in( _filename.c_str(), std::ios_base::in );
133 if (!in.is_open() || !in.good())
135 omerr() <<
"[OBJReader] : cannot not open file "
143 std::string::size_type
dot = _filename.find_last_of(
"\\/");
145 std::string::size_type dot = _filename.rfind(
"/");
147 path_ = (dot == std::string::npos)
149 : std::string(_filename.substr(0,dot+1));
152 bool result =
read(in, _bi, _opt);
162 read_material(std::fstream& _in)
166 std::string textureName;
168 std::stringstream stream;
180 while( _in && !_in.eof() )
182 std::getline(_in,line);
184 omerr() <<
" Warning! Could not read file properly!\n";
196 if( ( isspace(line[0]) && line[0] !=
'\t' ) || line[0] ==
'#' )
198 if (indef && !key.empty() && mat.is_valid())
200 materials_[key] = mat;
205 else if (keyWrd ==
"newmtl")
211 else if (keyWrd ==
"Kd")
213 stream >> f1; stream >> f2; stream >> f3;
216 mat.set_Kd(f1,f2,f3);
219 else if (keyWrd ==
"Ka")
221 stream >> f1; stream >> f2; stream >> f3;
224 mat.set_Ka(f1,f2,f3);
227 else if (keyWrd ==
"Ks")
229 stream >> f1; stream >> f2; stream >> f3;
232 mat.set_Ks(f1,f2,f3);
235 else if (keyWrd ==
"illum")
240 else if (keyWrd ==
"Ns")
245 else if (keyWrd ==
"map_")
254 else if (keyWrd ==
"map_Kd" ) {
257 std::getline(stream,textureName);
258 trimString(textureName);
259 if ( ! textureName.empty() )
260 mat.set_map_Kd( textureName, textureId++ );
262 else if (keyWrd ==
"Tr")
269 else if (keyWrd ==
"d")
277 if ( _in && indef && mat.is_valid() && !key.empty())
278 materials_[key] = mat;
293 float x, y, z, u, v, w;
295 BaseImporter::VHandles vhandles;
296 std::vector<Vec3f> normals;
297 std::vector<Vec3f> colors;
298 std::vector<Vec3f> texcoords3d, face_texcoords3d;
299 std::vector<Vec2f> texcoords, face_texcoords;
300 std::vector<VertexHandle> vertexHandles;
304 std::stringstream stream, lineData, tmp;
314 while( _in && !_in.eof() )
316 std::getline(_in,line);
318 omerr() <<
" Warning! Could not read file properly!\n";
326 if ( line.size() == 0 || line[0] ==
'#' || isspace(line[0]) ) {
336 if (keyWrd ==
"mtllib")
342 std::getline(stream,matFile);
345 matFile = path_ + matFile;
349 std::fstream matStream( matFile.c_str(), std::ios_base::in );
353 if ( !read_material( matStream ) )
354 omerr() <<
" Warning! Could not read file properly!\n";
358 omerr() <<
" Warning! Material file '" << matFile <<
"' not found!\n";
362 for ( MaterialList::iterator material = materials_.begin(); material != materials_.end(); ++material )
365 if ( (*material).second.has_map_Kd() )
366 _bi.add_texture_information( (*material).second.map_Kd_index() , (*material).second.map_Kd() );
372 else if (keyWrd ==
"usemtl")
375 if (materials_.find(matname)==materials_.end())
377 omerr() <<
"Warning! Material '" << matname
378 <<
"' not defined in material file.\n";
384 else if (keyWrd ==
"v")
386 stream >> x; stream >> y; stream >> z;
388 if ( !stream.fail() )
391 stream >> r; stream >> g; stream >> b;
393 if ( !stream.fail() )
395 if ( userOptions.vertex_has_color() ) {
404 else if (keyWrd ==
"vt")
406 stream >> u; stream >> v;
408 if ( !stream.fail() ){
410 if ( userOptions.vertex_has_texcoord() || userOptions.face_has_texcoord() ) {
419 if ( !stream.fail() )
425 omerr() <<
"Only single 2D or 3D texture coordinate per vertex"
426 <<
"allowed!" << std::endl;
432 else if (keyWrd ==
"vc")
434 stream >> r; stream >> g; stream >> b;
436 if ( !stream.fail() ){
437 if ( userOptions.vertex_has_color() ) {
445 else if (keyWrd ==
"vn")
447 stream >> x; stream >> y; stream >> z;
449 if ( !stream.fail() ) {
450 if (userOptions.vertex_has_normal() ){
459 else if (keyWrd ==
"f")
461 int component(0), nV(0);
465 face_texcoords.clear();
468 std::string faceLine;
469 std::getline(stream,faceLine);
470 lineData.str( faceLine );
474 BaseImporter::VHandles faceVertices;
477 while ( !lineData.eof() )
486 size_t found=vertex.find(
"/");
489 if( found != std::string::npos ){
492 tmp.str( vertex.substr(0,found) );
496 if ( vertex.substr(0,found).empty() ) {
498 vertex = vertex.substr(found+1);
511 vertex = vertex.substr(found+1);
537 value = int(_bi.n_vertices() + value + 1);
542 if (fileOptions.vertex_has_color() )
543 _bi.set_color(vhandles.back(), colors[value-1]);
551 value = int(texcoords.size()) + value + 1;
553 assert(!vhandles.empty());
556 if ( fileOptions.vertex_has_texcoord() && userOptions.vertex_has_texcoord() ) {
558 if (!texcoords.empty() && (
unsigned int) (value - 1) < texcoords.size()) {
560 _bi.set_texcoord(vhandles.back(), texcoords[value - 1]);
561 if(!texcoords3d.empty() && (
unsigned int) (value -1) < texcoords3d.size())
562 _bi.set_texcoord(vhandles.back(), texcoords3d[value - 1]);
564 omerr() <<
"Error setting Texture coordinates" << std::endl;
569 if (fileOptions.face_has_texcoord() && userOptions.face_has_texcoord() ) {
571 if (!texcoords.empty() && (
unsigned int) (value - 1) < texcoords.size()) {
572 face_texcoords.push_back( texcoords[value-1] );
573 if(!texcoords3d.empty() && (
unsigned int) (value -1) < texcoords3d.size())
574 face_texcoords3d.push_back( texcoords3d[value-1] );
576 omerr() <<
"Error setting Texture coordinates" << std::endl;
588 value = int(normals.size()) + value + 1;
592 if (fileOptions.vertex_has_normal() ) {
593 assert(!vhandles.empty());
594 assert((
unsigned int)(value-1) < normals.size());
595 _bi.set_normal(vhandles.back(), normals[value-1]);
604 }
while ( !vertex.empty() );
613 size_t n_faces = _bi.n_faces();
614 remove_duplicated_vertices(faceVertices);
617 if (faceVertices.size() > 2)
618 fh = _bi.add_face(faceVertices);
620 if (!vhandles.empty() && fh.
is_valid() )
622 _bi.add_face_texcoords(fh, vhandles[0], face_texcoords);
623 _bi.add_face_texcoords(fh, vhandles[0], face_texcoords3d);
626 if ( !matname.empty() )
628 std::vector<FaceHandle> newfaces;
630 for(
size_t i=0; i < _bi.n_faces()-n_faces; ++i )
631 newfaces.push_back(
FaceHandle(
int(n_faces+i)));
633 Material& mat = materials_[matname];
635 if ( mat.has_Kd() ) {
638 if ( userOptions.face_has_color()) {
640 for (std::vector<FaceHandle>::iterator it = newfaces.begin(); it != newfaces.end(); ++it)
641 _bi.set_color(*it, fc);
648 if ( mat.has_map_Kd() ) {
650 if (userOptions.face_has_texcoord()) {
652 for (std::vector<FaceHandle>::iterator it = newfaces.begin(); it != newfaces.end(); ++it)
653 _bi.set_face_texindex(*it, mat.map_Kd_index());
662 if (userOptions.face_has_texcoord()) {
664 for (std::vector<FaceHandle>::iterator it = newfaces.begin(); it != newfaces.end(); ++it)
665 _bi.set_face_texindex(*it, 0);
671 std::vector<FaceHandle> newfaces;
673 for(
size_t i=0; i < _bi.n_faces()-n_faces; ++i )
674 newfaces.push_back(
FaceHandle(
int(n_faces+i)));
677 if ( userOptions.face_has_texcoord() )
678 for (std::vector<FaceHandle>::iterator it = newfaces.begin(); it != newfaces.end(); ++it)
679 _bi.set_face_texindex(*it, 0);
688 if (_bi.n_faces() == 0)
693 if (normals.size() == _bi.n_vertices()) {
694 if ( fileOptions.vertex_has_normal() && userOptions.vertex_has_normal() ) {
695 for (std::vector<VertexHandle>::iterator it = vertexHandles.begin(); it != vertexHandles.end(); ++it, i++)
696 _bi.set_normal(*it, normals[i]);
702 if (colors.size() >= _bi.n_vertices())
703 if (fileOptions.vertex_has_color() && userOptions.vertex_has_color()) {
704 for (std::vector<VertexHandle>::iterator it = vertexHandles.begin(); it != vertexHandles.end(); ++it, i++)
705 _bi.set_color(*it, colors[i]);
Has (r) / store (w) vertex normals.
bool register_module(BaseReader *_bl)
Has (r) / store (w) face colors.
bool is_valid() const
The handle is valid iff the index is not equal to -1.
Has (r) / store (w) texture coordinates.
Set options for reader/writer modules.
bool read(const std::string &_filename, BaseImporter &_bi, Options &_opt)
Has (r) / store (w) face texture coordinates.
Handle for a vertex entity.
Handle for a face entity.
osg::Vec3f::ValueType dot(const osg::Vec3f &_v1, const osg::Vec3f &_v2)
Adapter for osg vector member computing a scalar product.
VectorT< unsigned char, 3 > Vec3uc
Has (r) / store (w) vertex colors.
_IOManager_ & IOManager()