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; }
86void 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 );
101void 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);
157read_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 (keyWrd ==
"newmtl")
197 if (indef && !key.empty() && mat.is_valid())
199 materials_[key] = mat;
207 else if (keyWrd ==
"Kd")
209 stream >> f1; stream >> f2; stream >> f3;
212 mat.set_Kd(f1,f2,f3);
215 else if (keyWrd ==
"Ka")
217 stream >> f1; stream >> f2; stream >> f3;
220 mat.set_Ka(f1,f2,f3);
223 else if (keyWrd ==
"Ks")
225 stream >> f1; stream >> f2; stream >> f3;
228 mat.set_Ks(f1,f2,f3);
231 else if (keyWrd ==
"illum")
236 else if (keyWrd ==
"Ns")
241 else if (keyWrd ==
"map_")
250 else if (keyWrd ==
"map_Kd" ) {
253 std::getline(stream,textureName);
254 trimString(textureName);
255 if ( ! textureName.empty() )
256 mat.set_map_Kd( textureName, textureId++ );
258 else if (keyWrd ==
"Tr")
265 else if (keyWrd ==
"d")
273 if ( _in && indef && mat.is_valid() && !key.empty())
274 materials_[key] = mat;
282read_vertices(std::istream& _in,
BaseImporter& _bi, Options& _opt,
283 std::vector<Vec3f> & normals,
284 std::vector<Vec3f> & colors,
285 std::vector<Vec3f> & texcoords3d,
286 std::vector<Vec2f> & texcoords,
287 std::vector<VertexHandle> & vertexHandles,
288 Options & fileOptions)
290 double x, y, z, u, v, w;
296 std::stringstream stream;
300 const Options & userOptions = _opt;
302 while( _in && !_in.eof() )
304 std::getline(_in,line);
306 omerr() <<
" Warning! Could not read file properly!\n";
314 if ( line.size() == 0 || line[0] ==
'#' || isspace(line[0]) ) {
326 stream >> x; stream >> y; stream >> z;
328 if ( !stream.fail() )
331 stream >> r; stream >> g; stream >> b;
333 if ( !stream.fail() )
335 if ( userOptions.vertex_has_color() ) {
344 else if (keyWrd ==
"vt")
346 stream >> u; stream >> v;
348 if ( !stream.fail() ){
350 if ( userOptions.vertex_has_texcoord() || userOptions.face_has_texcoord() ) {
359 if ( !stream.fail() )
365 omerr() <<
"Only single 2D or 3D texture coordinate per vertex"
366 <<
"allowed!" << std::endl;
372 else if (keyWrd ==
"vc")
374 stream >> r; stream >> g; stream >> b;
376 if ( !stream.fail() ){
377 if ( userOptions.vertex_has_color() ) {
385 else if (keyWrd ==
"vn")
387 stream >> x; stream >> y; stream >> z;
389 if ( !stream.fail() ) {
390 if (userOptions.vertex_has_normal() ){
410 std::vector<Vec3f> normals;
411 std::vector<Vec3f> colors;
412 std::vector<Vec3f> texcoords3d;
413 std::vector<Vec2f> texcoords;
414 std::vector<VertexHandle> vertexHandles;
416 BaseImporter::VHandles vhandles;
417 std::vector<Vec3f> face_texcoords3d;
418 std::vector<Vec2f> face_texcoords;
422 std::stringstream stream, lineData, tmp;
432 if ( !read_vertices(_in, _bi, _opt,
433 normals, colors, texcoords3d, texcoords,
434 vertexHandles, fileOptions) ){
440 _in.seekg(0, std::ios::beg);
442 int nCurrentPositions = 0,
443 nCurrentTexcoords = 0,
447 while( _in && !_in.eof() )
449 std::getline(_in,line);
451 omerr() <<
" Warning! Could not read file properly!\n";
459 if ( line.size() == 0 || line[0] ==
'#' || isspace(line[0]) ) {
469 if (keyWrd ==
"mtllib")
475 std::getline(stream,matFile);
478 matFile = path_ + matFile;
482 std::fstream matStream( matFile.c_str(), std::ios_base::in );
486 if ( !read_material( matStream ) )
487 omerr() <<
" Warning! Could not read file properly!\n";
491 omerr() <<
" Warning! Material file '" << matFile <<
"' not found!\n";
495 for ( MaterialList::iterator material = materials_.begin(); material != materials_.end(); ++material )
498 if ( (*material).second.has_map_Kd() )
499 _bi.add_texture_information( (*material).second.map_Kd_index() , (*material).second.map_Kd() );
505 else if (keyWrd ==
"usemtl")
508 if (materials_.find(matname)==materials_.end())
510 omerr() <<
"Warning! Material '" << matname
511 <<
"' not defined in material file.\n";
518 else if (keyWrd ==
"v")
522 else if (keyWrd ==
"vt")
526 else if (keyWrd ==
"vn")
532 else if (keyWrd ==
"f")
534 int component(0), nV(0);
538 face_texcoords.clear();
539 face_texcoords3d.clear();
542 std::string faceLine;
543 std::getline(stream,faceLine);
544 lineData.str( faceLine );
548 BaseImporter::VHandles faceVertices;
551 while ( !lineData.eof() )
560 size_t found=vertex.find(
"/");
563 if( found != std::string::npos ){
566 tmp.str( vertex.substr(0,found) );
570 if ( vertex.substr(0,found).empty() ) {
572 vertex = vertex.substr(found+1);
585 vertex = vertex.substr(found+1);
611 value = nCurrentPositions + value + 1;
616 if (fileOptions.vertex_has_color()) {
617 if ((
unsigned int)(value - 1) < colors.
size()) {
618 _bi.set_color(vhandles.back(), colors[value - 1]);
621 omerr() <<
"Error setting vertex color" << std::endl;
631 value = nCurrentTexcoords + value + 1;
633 assert(!vhandles.empty());
636 if ( fileOptions.vertex_has_texcoord() && userOptions.vertex_has_texcoord() ) {
638 if (!texcoords.empty() && (
unsigned int) (value - 1) < texcoords.size()) {
640 _bi.set_texcoord(vhandles.back(), texcoords[value - 1]);
641 if(!texcoords3d.empty() && (
unsigned int) (value -1) < texcoords3d.size())
642 _bi.set_texcoord(vhandles.back(), texcoords3d[value - 1]);
644 omerr() <<
"Error setting Texture coordinates" << std::endl;
649 if (fileOptions.face_has_texcoord() && userOptions.face_has_texcoord() ) {
651 if (!texcoords.empty() && (
unsigned int) (value - 1) < texcoords.size()) {
652 face_texcoords.push_back( texcoords[value-1] );
653 if(!texcoords3d.empty() && (
unsigned int) (value -1) < texcoords3d.size())
654 face_texcoords3d.push_back( texcoords3d[value-1] );
656 omerr() <<
"Error setting Texture coordinates" << std::endl;
668 value = nCurrentNormals + value + 1;
672 if (fileOptions.vertex_has_normal() ) {
673 assert(!vhandles.empty());
674 if ((
unsigned int)(value - 1) < normals.size()) {
675 _bi.set_normal(vhandles.back(), normals[value - 1]);
678 omerr() <<
"Error setting vertex normal" << std::endl;
688 }
while ( !vertex.empty() );
697 size_t n_faces = _bi.n_faces();
698 remove_duplicated_vertices(faceVertices);
701 if (faceVertices.size() > 2)
702 fh = _bi.add_face(faceVertices);
704 if (!vhandles.empty() && fh.
is_valid() )
706 _bi.add_face_texcoords(fh, vhandles[0], face_texcoords);
707 _bi.add_face_texcoords(fh, vhandles[0], face_texcoords3d);
710 if ( !matname.empty() )
712 std::vector<FaceHandle> newfaces;
714 for(
size_t i=0; i < _bi.n_faces()-n_faces; ++i )
715 newfaces.push_back(
FaceHandle(
int(n_faces+i)));
717 Material& mat = materials_[matname];
719 if ( mat.has_Kd() ) {
720 Vec3uc fc = color_cast<Vec3uc, Vec3f>(mat.Kd());
722 if ( userOptions.face_has_color()) {
724 for (std::vector<FaceHandle>::iterator it = newfaces.begin(); it != newfaces.end(); ++it)
725 _bi.set_color(*it, fc);
732 if ( mat.has_map_Kd() ) {
734 if (userOptions.face_has_texcoord()) {
736 for (std::vector<FaceHandle>::iterator it = newfaces.begin(); it != newfaces.end(); ++it)
737 _bi.set_face_texindex(*it, mat.map_Kd_index());
746 if (userOptions.face_has_texcoord()) {
748 for (std::vector<FaceHandle>::iterator it = newfaces.begin(); it != newfaces.end(); ++it)
749 _bi.set_face_texindex(*it, 0);
755 std::vector<FaceHandle> newfaces;
757 for(
size_t i=0; i < _bi.n_faces()-n_faces; ++i )
758 newfaces.push_back(
FaceHandle(
int(n_faces+i)));
761 if ( userOptions.face_has_texcoord() )
762 for (std::vector<FaceHandle>::iterator it = newfaces.begin(); it != newfaces.end(); ++it)
763 _bi.set_face_texindex(*it, 0);
772 if (_bi.n_faces() == 0)
777 if (normals.size() == _bi.n_vertices()) {
778 if ( fileOptions.vertex_has_normal() && userOptions.vertex_has_normal() ) {
779 for (std::vector<VertexHandle>::iterator it = vertexHandles.begin(); it != vertexHandles.end(); ++it, i++)
780 _bi.set_normal(*it, normals[i]);
786 if (colors.
size() >= _bi.n_vertices())
787 if (fileOptions.vertex_has_color() && userOptions.vertex_has_color()) {
788 for (std::vector<VertexHandle>::iterator it = vertexHandles.begin(); it != vertexHandles.end(); ++it, i++)
789 _bi.set_color(*it, colors[i]);
bool is_valid() const
The handle is valid iff the index is not negative.
Set options for reader/writer modules.
void clear(void)
Clear all bits.
@ FaceColor
Has (r) / store (w) face colors.
@ FaceTexCoord
Has (r) / store (w) face texture coordinates.
@ VertexNormal
Has (r) / store (w) vertex normals.
@ VertexTexCoord
Has (r) / store (w) texture coordinates.
@ VertexColor
Has (r) / store (w) vertex colors.
bool register_module(BaseReader *_bl)
bool read(const std::string &_filename, BaseImporter &_bi, Options &_opt) override
static constexpr size_t size()
returns dimension of the vector
_IOManager_ & IOManager()
Handle for a face entity.
Handle for a vertex entity.