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;
287 std::vector<Vec3f> & normals,
288 std::vector<Vec3f> & colors,
289 std::vector<Vec3f> & texcoords3d,
290 std::vector<Vec2f> & texcoords,
291 std::vector<VertexHandle> & vertexHandles,
294 float x, y, z, u, v, w;
300 std::stringstream stream;
304 const Options & userOptions = _opt;
306 while( _in && !_in.eof() )
308 std::getline(_in,line);
310 omerr() <<
" Warning! Could not read file properly!\n";
318 if ( line.size() == 0 || line[0] ==
'#' || isspace(line[0]) ) {
330 stream >> x; stream >> y; stream >> z;
332 if ( !stream.fail() )
335 stream >> r; stream >> g; stream >> b;
337 if ( !stream.fail() )
339 if ( userOptions.vertex_has_color() ) {
348 else if (keyWrd ==
"vt")
350 stream >> u; stream >> v;
352 if ( !stream.fail() ){
354 if ( userOptions.vertex_has_texcoord() || userOptions.face_has_texcoord() ) {
363 if ( !stream.fail() )
369 omerr() <<
"Only single 2D or 3D texture coordinate per vertex" 370 <<
"allowed!" << std::endl;
376 else if (keyWrd ==
"vc")
378 stream >> r; stream >> g; stream >> b;
380 if ( !stream.fail() ){
381 if ( userOptions.vertex_has_color() ) {
389 else if (keyWrd ==
"vn")
391 stream >> x; stream >> y; stream >> z;
393 if ( !stream.fail() ) {
394 if (userOptions.vertex_has_normal() ){
414 std::vector<Vec3f> normals;
415 std::vector<Vec3f> colors;
416 std::vector<Vec3f> texcoords3d;
417 std::vector<Vec2f> texcoords;
418 std::vector<VertexHandle> vertexHandles;
420 BaseImporter::VHandles vhandles;
421 std::vector<Vec3f> face_texcoords3d;
422 std::vector<Vec2f> face_texcoords;
426 std::stringstream stream, lineData, tmp;
436 if ( !read_vertices(_in, _bi, _opt,
437 normals, colors, texcoords3d, texcoords,
438 vertexHandles, fileOptions) ){
444 _in.seekg(0, std::ios::beg);
446 int nCurrentPositions = 0,
447 nCurrentTexcoords = 0,
451 while( _in && !_in.eof() )
453 std::getline(_in,line);
455 omerr() <<
" Warning! Could not read file properly!\n";
463 if ( line.size() == 0 || line[0] ==
'#' || isspace(line[0]) ) {
473 if (keyWrd ==
"mtllib")
479 std::getline(stream,matFile);
482 matFile = path_ + matFile;
486 std::fstream matStream( matFile.c_str(), std::ios_base::in );
490 if ( !read_material( matStream ) )
491 omerr() <<
" Warning! Could not read file properly!\n";
495 omerr() <<
" Warning! Material file '" << matFile <<
"' not found!\n";
499 for ( MaterialList::iterator material = materials_.begin(); material != materials_.end(); ++material )
502 if ( (*material).second.has_map_Kd() )
503 _bi.add_texture_information( (*material).second.map_Kd_index() , (*material).second.map_Kd() );
509 else if (keyWrd ==
"usemtl")
512 if (materials_.find(matname)==materials_.end())
514 omerr() <<
"Warning! Material '" << matname
515 <<
"' not defined in material file.\n";
522 else if (keyWrd ==
"v")
526 else if (keyWrd ==
"vt")
530 else if (keyWrd ==
"vn")
536 else if (keyWrd ==
"f")
538 int component(0), nV(0);
542 face_texcoords.clear();
545 std::string faceLine;
546 std::getline(stream,faceLine);
547 lineData.str( faceLine );
551 BaseImporter::VHandles faceVertices;
554 while ( !lineData.eof() )
563 size_t found=vertex.find(
"/");
566 if( found != std::string::npos ){
569 tmp.str( vertex.substr(0,found) );
573 if ( vertex.substr(0,found).empty() ) {
575 vertex = vertex.substr(found+1);
588 vertex = vertex.substr(found+1);
614 value = nCurrentPositions + value + 1;
619 if (fileOptions.vertex_has_color()) {
620 if ((
unsigned int)(value - 1) < colors.size()) {
621 _bi.set_color(vhandles.back(), colors[value - 1]);
624 omerr() <<
"Error setting vertex color" << std::endl;
634 value = nCurrentTexcoords + value + 1;
636 assert(!vhandles.empty());
639 if ( fileOptions.vertex_has_texcoord() && userOptions.vertex_has_texcoord() ) {
641 if (!texcoords.empty() && (
unsigned int) (value - 1) < texcoords.size()) {
643 _bi.set_texcoord(vhandles.back(), texcoords[value - 1]);
644 if(!texcoords3d.empty() && (
unsigned int) (value -1) < texcoords3d.size())
645 _bi.set_texcoord(vhandles.back(), texcoords3d[value - 1]);
647 omerr() <<
"Error setting Texture coordinates" << std::endl;
652 if (fileOptions.face_has_texcoord() && userOptions.face_has_texcoord() ) {
654 if (!texcoords.empty() && (
unsigned int) (value - 1) < texcoords.size()) {
655 face_texcoords.push_back( texcoords[value-1] );
656 if(!texcoords3d.empty() && (
unsigned int) (value -1) < texcoords3d.size())
657 face_texcoords3d.push_back( texcoords3d[value-1] );
659 omerr() <<
"Error setting Texture coordinates" << std::endl;
671 value = nCurrentNormals + value + 1;
675 if (fileOptions.vertex_has_normal() ) {
676 assert(!vhandles.empty());
677 if ((
unsigned int)(value - 1) < normals.size()) {
678 _bi.set_normal(vhandles.back(), normals[value - 1]);
681 omerr() <<
"Error setting vertex normal" << std::endl;
691 }
while ( !vertex.empty() );
700 size_t n_faces = _bi.n_faces();
701 remove_duplicated_vertices(faceVertices);
704 if (faceVertices.size() > 2)
705 fh = _bi.add_face(faceVertices);
707 if (!vhandles.empty() && fh.
is_valid() )
709 _bi.add_face_texcoords(fh, vhandles[0], face_texcoords);
710 _bi.add_face_texcoords(fh, vhandles[0], face_texcoords3d);
713 if ( !matname.empty() )
715 std::vector<FaceHandle> newfaces;
717 for(
size_t i=0; i < _bi.n_faces()-n_faces; ++i )
718 newfaces.push_back(
FaceHandle(
int(n_faces+i)));
720 Material& mat = materials_[matname];
722 if ( mat.has_Kd() ) {
725 if ( userOptions.face_has_color()) {
727 for (std::vector<FaceHandle>::iterator it = newfaces.begin(); it != newfaces.end(); ++it)
728 _bi.set_color(*it, fc);
735 if ( mat.has_map_Kd() ) {
737 if (userOptions.face_has_texcoord()) {
739 for (std::vector<FaceHandle>::iterator it = newfaces.begin(); it != newfaces.end(); ++it)
740 _bi.set_face_texindex(*it, mat.map_Kd_index());
749 if (userOptions.face_has_texcoord()) {
751 for (std::vector<FaceHandle>::iterator it = newfaces.begin(); it != newfaces.end(); ++it)
752 _bi.set_face_texindex(*it, 0);
758 std::vector<FaceHandle> newfaces;
760 for(
size_t i=0; i < _bi.n_faces()-n_faces; ++i )
761 newfaces.push_back(
FaceHandle(
int(n_faces+i)));
764 if ( userOptions.face_has_texcoord() )
765 for (std::vector<FaceHandle>::iterator it = newfaces.begin(); it != newfaces.end(); ++it)
766 _bi.set_face_texindex(*it, 0);
775 if (_bi.n_faces() == 0)
780 if (normals.size() == _bi.n_vertices()) {
781 if ( fileOptions.vertex_has_normal() && userOptions.vertex_has_normal() ) {
782 for (std::vector<VertexHandle>::iterator it = vertexHandles.begin(); it != vertexHandles.end(); ++it, i++)
783 _bi.set_normal(*it, normals[i]);
789 if (colors.size() >= _bi.n_vertices())
790 if (fileOptions.vertex_has_color() && userOptions.vertex_has_color()) {
791 for (std::vector<VertexHandle>::iterator it = vertexHandles.begin(); it != vertexHandles.end(); ++it, i++)
792 _bi.set_color(*it, colors[i]);
Has (r) / store (w) texture coordinates.
Has (r) / store (w) vertex normals.
void clear(void)
Clear all bits.
bool is_valid() const
The handle is valid iff the index is not equal to -1.
Set options for reader/writer modules.
Handle for a vertex entity.
bool register_module(BaseReader *_bl)
osg::Vec3f::ValueType dot(const osg::Vec3f &_v1, const osg::Vec3f &_v2)
Adapter for osg vector member computing a scalar product.
Handle for a face entity.
Has (r) / store (w) face texture coordinates.
Has (r) / store (w) face colors.
Has (r) / store (w) vertex colors.
_IOManager_ & IOManager()
VectorT< unsigned char, 3 > Vec3uc
bool read(const std::string &_filename, BaseImporter &_bi, Options &_opt)