From 80192d945bbab9f63c5a9b85b0f3d3b3a1ad8079 Mon Sep 17 00:00:00 2001 From: Martin Schultz Date: Wed, 29 Jun 2016 16:58:59 +0200 Subject: [PATCH] added code to write faceTexCoords to obj writer. fixes #25 --- src/OpenMesh/Core/IO/exporter/BaseExporter.hh | 11 ++++ src/OpenMesh/Core/IO/exporter/ExporterT.hh | 32 ++++++++++ src/OpenMesh/Core/IO/writer/OBJWriter.cc | 59 ++++++++++++++++--- src/Unittests/unittests_read_write_OBJ.cc | 56 ++++++++++++++++++ 4 files changed, 150 insertions(+), 8 deletions(-) diff --git a/src/OpenMesh/Core/IO/exporter/BaseExporter.hh b/src/OpenMesh/Core/IO/exporter/BaseExporter.hh index b4717b8d..477d95a1 100644 --- a/src/OpenMesh/Core/IO/exporter/BaseExporter.hh +++ b/src/OpenMesh/Core/IO/exporter/BaseExporter.hh @@ -103,12 +103,23 @@ public: virtual Vec3f colorf(VertexHandle _vh) const = 0; virtual Vec4f colorAf(VertexHandle _vh) const = 0; virtual Vec2f texcoord(VertexHandle _vh) const = 0; + virtual Vec2f texcoord(HalfedgeHandle _heh) const = 0; // get face data virtual unsigned int get_vhandles(FaceHandle _fh, std::vector& _vhandles) const=0; + /// + /// \brief getHeh returns the HalfEdgeHandle that belongs to the face + /// specified by _fh and has a toVertexHandle that corresponds to _vh. + /// \param _fh FaceHandle that is used to search for the half edge handle + /// \param _vh to_vertex_handle of the searched heh + /// \return HalfEdgeHandle or invalid HalfEdgeHandle if none is found. + /// + virtual HalfedgeHandle getHeh(FaceHandle _fh, VertexHandle _vh) const = 0; + virtual unsigned int + get_face_texcoords(std::vector& _hehandles) const = 0; virtual Vec3f normal(FaceHandle _fh) const = 0; virtual Vec3uc color (FaceHandle _fh) const = 0; virtual Vec4uc colorA(FaceHandle _fh) const = 0; diff --git a/src/OpenMesh/Core/IO/exporter/ExporterT.hh b/src/OpenMesh/Core/IO/exporter/ExporterT.hh index d4276d14..9a9d9b3f 100644 --- a/src/OpenMesh/Core/IO/exporter/ExporterT.hh +++ b/src/OpenMesh/Core/IO/exporter/ExporterT.hh @@ -164,6 +164,13 @@ public: #endif } + Vec2f texcoord(HalfedgeHandle _heh) const + { + return (mesh_.has_halfedge_texcoords2D() + ? vector_cast(mesh_.texcoord2D(_heh)) + : Vec2f(0.0f, 0.0f)); + } + // get edge data Vec3uc color(EdgeHandle _eh) const @@ -223,6 +230,31 @@ public: return count; } + unsigned int get_face_texcoords(std::vector& _hehandles) const + { + unsigned int count(0); + _hehandles.clear(); + for(typename Mesh::CHIter he_it=mesh_.halfedges_begin(); + he_it != mesh_.halfedges_end(); ++he_it) + { + _hehandles.push_back(vector_cast(mesh_.texcoord2D( *he_it))); + ++count; + } + + return count; + } + + HalfedgeHandle getHeh(FaceHandle _fh, VertexHandle _vh) const + { + typename Mesh::ConstFaceHalfedgeIter fh_it; + for(fh_it = mesh_.cfh_iter(_fh); fh_it.is_valid();++fh_it) + { + if(mesh_.to_vertex_handle(*fh_it) == _vh) + return *fh_it; + } + return *fh_it; + } + Vec3f normal(FaceHandle _fh) const { return (mesh_.has_face_normals() diff --git a/src/OpenMesh/Core/IO/writer/OBJWriter.cc b/src/OpenMesh/Core/IO/writer/OBJWriter.cc index b1e8838a..d2f22e9a 100644 --- a/src/OpenMesh/Core/IO/writer/OBJWriter.cc +++ b/src/OpenMesh/Core/IO/writer/OBJWriter.cc @@ -257,6 +257,42 @@ write(std::ostream& _out, BaseExporter& _be, Options _opt, std::streamsize _prec if (useMatrial && _opt.check(Options::FaceColor) ) _out << "mtllib " << objName_ << ".mat" << '\n'; + std::map texMap; + //collect Texturevertices from halfedges + if(_opt.check(Options::FaceTexCoord)) + { + std::vector texCoords; + //add all texCoords to map + unsigned int num = _be.get_face_texcoords(texCoords); + for(unsigned int i = 0; i < num ; ++i) + { + texMap[texCoords[i]] = i; + } + } + + //collect Texturevertices from vertices + if(_opt.check(Options::VertexTexCoord)) + { + for (int i=0, nF=_be.n_faces(); i::iterator it = texMap.begin(); it != texMap.end() ; ++it) + { + _out << "vt " << it->first[0] << " " << it->first[1] << '\n'; + it->second = ++texCount; + } + } + // vertex data (point, normals, texcoords) for (i=0, nV=_be.n_vertices(); i::max(); // we do not want to write seperators if we only write vertex indices bool onlyVertices = !_opt.check(Options::VertexTexCoord) - && !_opt.check(Options::VertexNormal); + && !_opt.check(Options::VertexNormal) + && !_opt.check(Options::FaceTexCoord); // faces (indices starting at 1 not 0) for (i=0, nF=_be.n_faces(); i