49 #include <OpenMesh/Core/IO/reader/OBJReader.hh> 50 #include <OpenMesh/Core/IO/IOManager.hh> 51 #include <OpenMesh/Core/Utils/vector_cast.hh> 52 #include <OpenMesh/Core/Utils/color_cast.hh> 54 #if defined(OM_CC_MIPS) 57 #elif defined(_STLPORT_VERSION) && (_STLPORT_VERSION==0x460) 78 _OBJReader_ __OBJReaderInstance;
79 _OBJReader_& OBJReader() {
return __OBJReaderInstance; }
86 void trimString( std::string& _string) {
89 size_t start = _string.find_first_not_of(
" \t\r\n");
90 size_t end = _string.find_last_not_of(
" \t\r\n");
92 if(( std::string::npos == start ) || ( std::string::npos == end))
95 _string = _string.substr( start, end-start+1 );
101 void remove_duplicated_vertices(BaseImporter::VHandles& _indices)
103 BaseImporter::VHandles::iterator endIter = _indices.end();
104 for (BaseImporter::VHandles::iterator iter = _indices.begin(); iter != endIter; ++iter)
105 endIter = std::remove(iter+1, endIter, *(iter));
107 _indices.erase(endIter,_indices.end());
126 std::fstream in( _filename.c_str(), std::ios_base::in );
128 if (!in.is_open() || !in.good())
130 omerr() <<
"[OBJReader] : cannot not open file " 138 std::string::size_type dot_pos = _filename.find_last_of(
"\\/");
140 std::string::size_type dot_pos = _filename.rfind(
"/");
142 path_ = (dot_pos == std::string::npos)
144 : std::string(_filename.substr(0,dot_pos+1));
147 bool result =
read(in, _bi, _opt);
157 read_material(std::fstream& _in)
161 std::string textureName;
163 std::stringstream stream;
175 while( _in && !_in.eof() )
177 std::getline(_in,line);
179 omerr() <<
" Warning! Could not read file properly!\n";
191 if( ( isspace(line[0]) && line[0] !=
'\t' ) || line[0] ==
'#' )
193 if (indef && !key.empty() && mat.is_valid())
195 materials_[key] = mat;
200 else if (keyWrd ==
"newmtl")
206 else if (keyWrd ==
"Kd")
208 stream >> f1; stream >> f2; stream >> f3;
211 mat.set_Kd(f1,f2,f3);
214 else if (keyWrd ==
"Ka")
216 stream >> f1; stream >> f2; stream >> f3;
219 mat.set_Ka(f1,f2,f3);
222 else if (keyWrd ==
"Ks")
224 stream >> f1; stream >> f2; stream >> f3;
227 mat.set_Ks(f1,f2,f3);
230 else if (keyWrd ==
"illum")
235 else if (keyWrd ==
"Ns")
240 else if (keyWrd ==
"map_")
249 else if (keyWrd ==
"map_Kd" ) {
252 std::getline(stream,textureName);
253 trimString(textureName);
254 if ( ! textureName.empty() )
255 mat.set_map_Kd( textureName, textureId++ );
257 else if (keyWrd ==
"Tr")
264 else if (keyWrd ==
"d")
272 if ( _in && indef && mat.is_valid() && !key.empty())
273 materials_[key] = mat;
282 std::vector<Vec3f> & normals,
283 std::vector<Vec3f> & colors,
284 std::vector<Vec3f> & texcoords3d,
285 std::vector<Vec2f> & texcoords,
286 std::vector<VertexHandle> & vertexHandles,
289 float x, y, z, u, v, w;
295 std::stringstream stream;
299 const Options & userOptions = _opt;
301 while( _in && !_in.eof() )
303 std::getline(_in,line);
305 omerr() <<
" Warning! Could not read file properly!\n";
313 if ( line.size() == 0 || line[0] ==
'#' || isspace(line[0]) ) {
325 stream >> x; stream >> y; stream >> z;
327 if ( !stream.fail() )
330 stream >> r; stream >> g; stream >> b;
332 if ( !stream.fail() )
334 if ( userOptions.vertex_has_color() ) {
343 else if (keyWrd ==
"vt")
345 stream >> u; stream >> v;
347 if ( !stream.fail() ){
349 if ( userOptions.vertex_has_texcoord() || userOptions.face_has_texcoord() ) {
358 if ( !stream.fail() )
364 omerr() <<
"Only single 2D or 3D texture coordinate per vertex" 365 <<
"allowed!" << std::endl;
371 else if (keyWrd ==
"vc")
373 stream >> r; stream >> g; stream >> b;
375 if ( !stream.fail() ){
376 if ( userOptions.vertex_has_color() ) {
384 else if (keyWrd ==
"vn")
386 stream >> x; stream >> y; stream >> z;
388 if ( !stream.fail() ) {
389 if (userOptions.vertex_has_normal() ){
409 std::vector<Vec3f> normals;
410 std::vector<Vec3f> colors;
411 std::vector<Vec3f> texcoords3d;
412 std::vector<Vec2f> texcoords;
413 std::vector<VertexHandle> vertexHandles;
415 BaseImporter::VHandles vhandles;
416 std::vector<Vec3f> face_texcoords3d;
417 std::vector<Vec2f> face_texcoords;
421 std::stringstream stream, lineData, tmp;
431 if ( !read_vertices(_in, _bi, _opt,
432 normals, colors, texcoords3d, texcoords,
433 vertexHandles, fileOptions) ){
439 _in.seekg(0, std::ios::beg);
441 int nCurrentPositions = 0,
442 nCurrentTexcoords = 0,
446 while( _in && !_in.eof() )
448 std::getline(_in,line);
450 omerr() <<
" Warning! Could not read file properly!\n";
458 if ( line.size() == 0 || line[0] ==
'#' || isspace(line[0]) ) {
468 if (keyWrd ==
"mtllib")
474 std::getline(stream,matFile);
477 matFile = path_ + matFile;
481 std::fstream matStream( matFile.c_str(), std::ios_base::in );
485 if ( !read_material( matStream ) )
486 omerr() <<
" Warning! Could not read file properly!\n";
490 omerr() <<
" Warning! Material file '" << matFile <<
"' not found!\n";
494 for ( MaterialList::iterator material = materials_.begin(); material != materials_.end(); ++material )
497 if ( (*material).second.has_map_Kd() )
498 _bi.add_texture_information( (*material).second.map_Kd_index() , (*material).second.map_Kd() );
504 else if (keyWrd ==
"usemtl")
507 if (materials_.find(matname)==materials_.end())
509 omerr() <<
"Warning! Material '" << matname
510 <<
"' not defined in material file.\n";
517 else if (keyWrd ==
"v")
521 else if (keyWrd ==
"vt")
525 else if (keyWrd ==
"vn")
531 else if (keyWrd ==
"f")
533 int component(0), nV(0);
537 face_texcoords.clear();
538 face_texcoords3d.clear();
541 std::string faceLine;
542 std::getline(stream,faceLine);
543 lineData.str( faceLine );
547 BaseImporter::VHandles faceVertices;
550 while ( !lineData.eof() )
559 size_t found=vertex.find(
"/");
562 if( found != std::string::npos ){
565 tmp.str( vertex.substr(0,found) );
569 if ( vertex.substr(0,found).empty() ) {
571 vertex = vertex.substr(found+1);
584 vertex = vertex.substr(found+1);
610 value = nCurrentPositions + value + 1;
615 if (fileOptions.vertex_has_color()) {
616 if ((
unsigned int)(value - 1) < colors.size()) {
617 _bi.set_color(vhandles.back(), colors[value - 1]);
620 omerr() <<
"Error setting vertex color" << std::endl;
630 value = nCurrentTexcoords + value + 1;
632 assert(!vhandles.empty());
635 if ( fileOptions.vertex_has_texcoord() && userOptions.vertex_has_texcoord() ) {
637 if (!texcoords.empty() && (
unsigned int) (value - 1) < texcoords.size()) {
639 _bi.set_texcoord(vhandles.back(), texcoords[value - 1]);
640 if(!texcoords3d.empty() && (
unsigned int) (value -1) < texcoords3d.size())
641 _bi.set_texcoord(vhandles.back(), texcoords3d[value - 1]);
643 omerr() <<
"Error setting Texture coordinates" << std::endl;
648 if (fileOptions.face_has_texcoord() && userOptions.face_has_texcoord() ) {
650 if (!texcoords.empty() && (
unsigned int) (value - 1) < texcoords.size()) {
651 face_texcoords.push_back( texcoords[value-1] );
652 if(!texcoords3d.empty() && (
unsigned int) (value -1) < texcoords3d.size())
653 face_texcoords3d.push_back( texcoords3d[value-1] );
655 omerr() <<
"Error setting Texture coordinates" << std::endl;
667 value = nCurrentNormals + value + 1;
671 if (fileOptions.vertex_has_normal() ) {
672 assert(!vhandles.empty());
673 if ((
unsigned int)(value - 1) < normals.size()) {
674 _bi.set_normal(vhandles.back(), normals[value - 1]);
677 omerr() <<
"Error setting vertex normal" << std::endl;
687 }
while ( !vertex.empty() );
696 size_t n_faces = _bi.n_faces();
697 remove_duplicated_vertices(faceVertices);
700 if (faceVertices.size() > 2)
701 fh = _bi.add_face(faceVertices);
703 if (!vhandles.empty() && fh.
is_valid() )
705 _bi.add_face_texcoords(fh, vhandles[0], face_texcoords);
706 _bi.add_face_texcoords(fh, vhandles[0], face_texcoords3d);
709 if ( !matname.empty() )
711 std::vector<FaceHandle> newfaces;
713 for(
size_t i=0; i < _bi.n_faces()-n_faces; ++i )
714 newfaces.push_back(
FaceHandle(
int(n_faces+i)));
716 Material& mat = materials_[matname];
718 if ( mat.has_Kd() ) {
721 if ( userOptions.face_has_color()) {
723 for (std::vector<FaceHandle>::iterator it = newfaces.begin(); it != newfaces.end(); ++it)
724 _bi.set_color(*it, fc);
731 if ( mat.has_map_Kd() ) {
733 if (userOptions.face_has_texcoord()) {
735 for (std::vector<FaceHandle>::iterator it = newfaces.begin(); it != newfaces.end(); ++it)
736 _bi.set_face_texindex(*it, mat.map_Kd_index());
745 if (userOptions.face_has_texcoord()) {
747 for (std::vector<FaceHandle>::iterator it = newfaces.begin(); it != newfaces.end(); ++it)
748 _bi.set_face_texindex(*it, 0);
754 std::vector<FaceHandle> newfaces;
756 for(
size_t i=0; i < _bi.n_faces()-n_faces; ++i )
757 newfaces.push_back(
FaceHandle(
int(n_faces+i)));
760 if ( userOptions.face_has_texcoord() )
761 for (std::vector<FaceHandle>::iterator it = newfaces.begin(); it != newfaces.end(); ++it)
762 _bi.set_face_texindex(*it, 0);
771 if (_bi.n_faces() == 0)
776 if (normals.size() == _bi.n_vertices()) {
777 if ( fileOptions.vertex_has_normal() && userOptions.vertex_has_normal() ) {
778 for (std::vector<VertexHandle>::iterator it = vertexHandles.begin(); it != vertexHandles.end(); ++it, i++)
779 _bi.set_normal(*it, normals[i]);
785 if (colors.size() >= _bi.n_vertices())
786 if (fileOptions.vertex_has_color() && userOptions.vertex_has_color()) {
787 for (std::vector<VertexHandle>::iterator it = vertexHandles.begin(); it != vertexHandles.end(); ++it, i++)
788 _bi.set_color(*it, colors[i]);
bool read(const std::string &_filename, BaseImporter &_bi, Options &_opt) override
Handle for a face entity.
Has (r) / store (w) vertex colors.
void clear(void)
Clear all bits.
Has (r) / store (w) face colors.
Handle for a vertex entity.
bool is_valid() const
The handle is valid iff the index is not negative.
Has (r) / store (w) face texture coordinates.
bool register_module(BaseReader *_bl)
Set options for reader/writer modules.
VectorT< unsigned char, 3 > Vec3uc
Has (r) / store (w) vertex normals.
_IOManager_ & IOManager()
Has (r) / store (w) texture coordinates.