@@ -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<VertexHandle>& _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<Vec2f>& _hehandles) const = 0;
|
||||
virtual Vec3f normal(FaceHandle _fh) const = 0;
|
||||
virtual Vec3uc color (FaceHandle _fh) const = 0;
|
||||
virtual Vec4uc colorA(FaceHandle _fh) const = 0;
|
||||
|
||||
@@ -164,6 +164,13 @@ public:
|
||||
#endif
|
||||
}
|
||||
|
||||
Vec2f texcoord(HalfedgeHandle _heh) const
|
||||
{
|
||||
return (mesh_.has_halfedge_texcoords2D()
|
||||
? vector_cast<Vec2f>(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<Vec2f>& _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<Vec2f>(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()
|
||||
|
||||
@@ -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<Vec2f,int> texMap;
|
||||
//collect Texturevertices from halfedges
|
||||
if(_opt.check(Options::FaceTexCoord))
|
||||
{
|
||||
std::vector<Vec2f> 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<nF; ++i)
|
||||
{
|
||||
vh = VertexHandle(int(i));
|
||||
t = _be.texcoord(vh);
|
||||
texMap[t] = i;
|
||||
}
|
||||
}
|
||||
|
||||
// assign each texcoord in the map its id
|
||||
// and write the vt entries
|
||||
if(_opt.check(Options::VertexTexCoord) || _opt.check(Options::FaceTexCoord))
|
||||
{
|
||||
int texCount = 0;
|
||||
for(std::map<Vec2f,int>::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<nV; ++i)
|
||||
{
|
||||
@@ -269,16 +305,14 @@ write(std::ostream& _out, BaseExporter& _be, Options _opt, std::streamsize _prec
|
||||
|
||||
if (_opt.check(Options::VertexNormal))
|
||||
_out << "vn " << n[0] <<" "<< n[1] <<" "<< n[2] << '\n';
|
||||
|
||||
if (_opt.check(Options::VertexTexCoord))
|
||||
_out << "vt " << t[0] <<" "<< t[1] << '\n';
|
||||
}
|
||||
|
||||
size_t lastMat = std::numeric_limits<std::size_t>::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<nF; ++i)
|
||||
@@ -319,9 +353,18 @@ write(std::ostream& _out, BaseExporter& _be, Options _opt, std::streamsize _prec
|
||||
// write separator
|
||||
_out << "/" ;
|
||||
|
||||
//write texCoords index from halfedge
|
||||
if(_opt.check(Options::FaceTexCoord))
|
||||
{
|
||||
_out << texMap[_be.texcoord(_be.getHeh(FaceHandle(int(i)),vhandles[j]))];
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
// write vertex texture coordinate index
|
||||
if (_opt.check(Options::VertexTexCoord))
|
||||
_out << idx;
|
||||
_out << texMap[_be.texcoord(vh)];
|
||||
}
|
||||
|
||||
// write vertex normal index
|
||||
if ( _opt.check(Options::VertexNormal) ) {
|
||||
|
||||
@@ -202,6 +202,62 @@ TEST_F(OpenMeshReadWriteOBJ, LoadSimpleOBJCheckTexCoords) {
|
||||
mesh_.release_halfedge_texcoords2D();
|
||||
}
|
||||
|
||||
/*
|
||||
* Just load and store obj file of a cube and checks the halfedge texCoords
|
||||
*/
|
||||
TEST_F(OpenMeshReadWriteOBJ, LoadStoreSimpleOBJCheckTexCoords) {
|
||||
|
||||
mesh_.clear();
|
||||
|
||||
mesh_.request_halfedge_texcoords2D();
|
||||
|
||||
OpenMesh::IO::Options options;
|
||||
options += OpenMesh::IO::Options::FaceTexCoord;
|
||||
|
||||
std::string file_name = "cube-minimal-texCoords.obj";
|
||||
|
||||
bool ok = OpenMesh::IO::read_mesh(mesh_, file_name,options);
|
||||
|
||||
EXPECT_TRUE(ok) << file_name;
|
||||
|
||||
|
||||
|
||||
options.clear();
|
||||
options += OpenMesh::IO::Options::FaceTexCoord;
|
||||
bool writeOk = OpenMesh::IO::write_mesh(mesh_,"writeTest.obj",options);
|
||||
EXPECT_TRUE(writeOk) << "writeTest.obj";
|
||||
mesh_.release_halfedge_texcoords2D();
|
||||
|
||||
Mesh loadedMesh_;
|
||||
loadedMesh_.clear();
|
||||
|
||||
loadedMesh_.request_halfedge_texcoords2D();
|
||||
|
||||
options.clear();
|
||||
options += OpenMesh::IO::Options::FaceTexCoord;
|
||||
bool readOk = OpenMesh::IO::read_mesh(loadedMesh_, "writeTest.obj",options);
|
||||
EXPECT_TRUE(readOk) << file_name;
|
||||
EXPECT_EQ(1, loadedMesh_.texcoord2D(mesh_.halfedge_handle(0))[0] ) << "Wrong texCoord at halfedge 0 component 0";
|
||||
EXPECT_EQ(1, loadedMesh_.texcoord2D(mesh_.halfedge_handle(0))[1] ) << "Wrong texCoord at halfedge 0 component 1";
|
||||
|
||||
EXPECT_EQ(3, loadedMesh_.texcoord2D(mesh_.halfedge_handle(10))[0] ) << "Wrong texCoord at halfedge 1 component 0";
|
||||
EXPECT_EQ(3, loadedMesh_.texcoord2D(mesh_.halfedge_handle(10))[1] ) << "Wrong texCoord at halfedge 1 component 1";
|
||||
|
||||
EXPECT_EQ(6, loadedMesh_.texcoord2D(mesh_.halfedge_handle(19))[0] ) << "Wrong texCoord at halfedge 4 component 0";
|
||||
EXPECT_EQ(6, loadedMesh_.texcoord2D(mesh_.halfedge_handle(19))[1] ) << "Wrong texCoord at halfedge 4 component 1";
|
||||
|
||||
EXPECT_EQ(7, loadedMesh_.texcoord2D(mesh_.halfedge_handle(24))[0] ) << "Wrong texCoord at halfedge 7 component 0";
|
||||
EXPECT_EQ(7, loadedMesh_.texcoord2D(mesh_.halfedge_handle(24))[1] ) << "Wrong texCoord at halfedge 7 component 1";
|
||||
|
||||
EXPECT_EQ(9, loadedMesh_.texcoord2D(mesh_.halfedge_handle(30))[0] ) << "Wrong texCoord at halfedge 9 component 0";
|
||||
EXPECT_EQ(9, loadedMesh_.texcoord2D(mesh_.halfedge_handle(30))[1] ) << "Wrong texCoord at halfedge 9 component 1";
|
||||
|
||||
EXPECT_EQ(12, loadedMesh_.texcoord2D(mesh_.halfedge_handle(35))[0] ) << "Wrong texCoord at halfedge 11 component 0";
|
||||
EXPECT_EQ(12, loadedMesh_.texcoord2D(mesh_.halfedge_handle(35))[1] ) << "Wrong texCoord at halfedge 11 component 1";
|
||||
|
||||
loadedMesh_.release_halfedge_texcoords2D();
|
||||
}
|
||||
|
||||
/*
|
||||
* Just load a obj file of a cube and checks the 3d halfedge texCoords
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user