...
 
......@@ -107,7 +107,7 @@ int main(int argc, char **argv)
opt += OpenMesh::IO::Options::VertexTexCoord;
opt += OpenMesh::IO::Options::FaceColor;
opt += OpenMesh::IO::Options::FaceNormal;
opt += OpenMesh::IO::Options::FaceTexCoord;
opt += OpenMesh::IO::Options::HalfedgeTexCoord;
// create widget
QMainWindow mainWin;
......
......@@ -101,21 +101,25 @@ public:
/// Definitions of %Options for reading and writing. The options can be
/// or'ed.
enum Flag {
Default = 0x0000, ///< No options
Binary = 0x0001, ///< Set binary mode for r/w
MSB = 0x0002, ///< Assume big endian byte ordering
LSB = 0x0004, ///< Assume little endian byte ordering
Swap = 0x0008, ///< Swap byte order in binary mode
VertexNormal = 0x0010, ///< Has (r) / store (w) vertex normals
VertexColor = 0x0020, ///< Has (r) / store (w) vertex colors
VertexTexCoord = 0x0040, ///< Has (r) / store (w) texture coordinates
EdgeColor = 0x0080, ///< Has (r) / store (w) edge colors
FaceNormal = 0x0100, ///< Has (r) / store (w) face normals
FaceColor = 0x0200, ///< Has (r) / store (w) face colors
FaceTexCoord = 0x0400, ///< Has (r) / store (w) face texture coordinates
ColorAlpha = 0x0800, ///< Has (r) / store (w) alpha values for colors
ColorFloat = 0x1000, ///< Has (r) / store (w) float values for colors (currently only implemented for PLY and OFF files)
Custom = 0x2000 ///< Has (r) custom properties (currently only implemented in PLY Reader ASCII version)
Default = 0x0000, ///< No options
Binary = 0x0001, ///< Set binary mode for r/w
MSB = 0x0002, ///< Assume big endian byte ordering
LSB = 0x0004, ///< Assume little endian byte ordering
Swap = 0x0008, ///< Swap byte order in binary mode
VertexNormal = 0x0010, ///< Has (r) / store (w) vertex normals
VertexColor = 0x0020, ///< Has (r) / store (w) vertex colors
VertexTexCoord = 0x0040, ///< Has (r) / store (w) texture coordinates
HalfedgeTexCoord = 0x0080, ///< Has (r) / store (w) face texture coordinates
HalfedgeNormal = 0x0100, ///< Has (r) / store (w) half-edge (per-wedge) normals
EdgeColor = 0x0200, ///< Has (r) / store (w) edge colors
FaceNormal = 0x0400, ///< Has (r) / store (w) face normals
FaceColor = 0x0800, ///< Has (r) / store (w) face colors
FaceTextureIndex = 0x1000, ///< Has (r) / store (w) face texture index
ColorAlpha = 0x2000, ///< Has (r) / store (w) alpha values for colors
ColorFloat = 0x4000, ///< Has (r) / store (w) float values for colors (currently only implemented for PLY and OFF files)
Custom = 0x8000, ///< Has (r) custom properties (currently only implemented in PLY Reader ASCII version)
// deprecated:
FaceTexCoord = HalfedgeTexCoord ///< legacy alias for "HalfedgeTexCoord"
};
public:
......@@ -202,17 +206,19 @@ public:
return (flags_ & _rhs)==_rhs;
}
bool is_binary() const { return check(Binary); }
bool vertex_has_normal() const { return check(VertexNormal); }
bool vertex_has_color() const { return check(VertexColor); }
bool vertex_has_texcoord() const { return check(VertexTexCoord); }
bool edge_has_color() const { return check(EdgeColor); }
bool face_has_normal() const { return check(FaceNormal); }
bool face_has_color() const { return check(FaceColor); }
bool face_has_texcoord() const { return check(FaceTexCoord); }
bool color_has_alpha() const { return check(ColorAlpha); }
bool color_is_float() const { return check(ColorFloat); }
bool is_binary() const { return check(Binary); }
bool vertex_has_normal() const { return check(VertexNormal); }
bool vertex_has_color() const { return check(VertexColor); }
bool vertex_has_texcoord() const { return check(VertexTexCoord); }
bool halfedge_has_normal() const { return check(HalfedgeNormal); }
bool halfedge_has_texcoord() const { return check(HalfedgeTexCoord); }
bool face_has_texcoord() const { return check(HalfedgeTexCoord); } // deprecated
bool edge_has_color() const { return check(EdgeColor); }
bool face_has_normal() const { return check(FaceNormal); }
bool face_has_color() const { return check(FaceColor); }
bool face_has_texture_index() const { return check(FaceTextureIndex); }
bool color_has_alpha() const { return check(ColorAlpha); }
bool color_is_float() const { return check(ColorFloat); }
/// Returns true if _rhs has the same options enabled.
bool operator == (const value_type _rhs) const
......
......@@ -62,6 +62,7 @@
// STL
#include <string>
#include <vector>
// OpenMesh
......@@ -103,8 +104,6 @@ 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
......@@ -118,8 +117,6 @@ public:
/// \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;
......@@ -127,6 +124,7 @@ public:
virtual Vec4ui colorAi(FaceHandle _fh) const = 0;
virtual Vec3f colorf(FaceHandle _fh) const = 0;
virtual Vec4f colorAf(FaceHandle _fh) const = 0;
virtual int face_texindex(FaceHandle _fh) const = 0;
// get edge data
virtual Vec3uc color(EdgeHandle _eh) const = 0;
......@@ -136,6 +134,15 @@ public:
virtual Vec3f colorf(EdgeHandle _eh) const = 0;
virtual Vec4f colorAf(EdgeHandle _eh) const = 0;
// get halfedge data
virtual Vec3f normal(HalfedgeHandle _heh) const = 0;
virtual Vec2f texcoord(HalfedgeHandle _heh) const = 0;
virtual unsigned int
get_halfedge_texcoords(std::vector<Vec2f>& _texcoords) const = 0;
// material attributes
virtual std::string texture_name(int _index) const = 0;
// get reference to base kernel
virtual const BaseKernel* kernel() { return 0; }
......@@ -147,13 +154,16 @@ public:
// property information
virtual bool is_triangle_mesh() const { return false; }
virtual bool has_vertex_normals() const { return false; }
virtual bool has_vertex_colors() const { return false; }
virtual bool has_vertex_texcoords() const { return false; }
virtual bool has_edge_colors() const { return false; }
virtual bool has_face_normals() const { return false; }
virtual bool has_face_colors() const { return false; }
virtual bool is_triangle_mesh() const { return false; }
virtual bool has_vertex_normals() const { return false; }
virtual bool has_vertex_colors() const { return false; }
virtual bool has_vertex_texcoords() const { return false; }
virtual bool has_edge_colors() const { return false; }
virtual bool has_face_normals() const { return false; }
virtual bool has_face_colors() const { return false; }
virtual bool has_face_texture_index() const { return false; }
virtual bool has_halfedge_normals() const { return false; }
virtual bool has_halfedge_texcoords() const { return false; }
};
......
......@@ -61,6 +61,7 @@
//=== INCLUDES ================================================================
// C++
#include <string>
#include <vector>
// OpenMesh
......@@ -164,13 +165,6 @@ 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
......@@ -215,32 +209,59 @@ public:
: Vec4f(0, 0, 0, 0));
}
// get face data
// Halfedge data
unsigned int get_vhandles(FaceHandle _fh,
std::vector<VertexHandle>& _vhandles) const
Vec3f normal(HalfedgeHandle _heh) const
{
return (mesh_.has_halfedge_normals()
? vector_cast<Vec3f>(mesh_.normal(_heh))
: Vec3f(0.0f, 0.0f, 0.0f));
}
Vec2f texcoord(HalfedgeHandle _heh) const
{
return (mesh_.has_halfedge_texcoords2D()
? vector_cast<Vec2f>(mesh_.texcoord2D(_heh))
: Vec2f(0.0f, 0.0f));
}
unsigned int get_halfedge_texcoords(std::vector<Vec2f>& _texcoords) const
{
unsigned int count(0);
_vhandles.clear();
for (typename Mesh::CFVIter fv_it=mesh_.cfv_iter(_fh); fv_it.is_valid(); ++fv_it)
_texcoords.clear();
if (!mesh_.has_halfedge_texcoords2D())
{
_vhandles.push_back(*fv_it);
++count;
return count;
}
for(typename Mesh::CHIter he_it=mesh_.halfedges_begin();
he_it != mesh_.halfedges_end(); ++he_it)
{
// Only store texture coordinates for faces which have a texture assigned
if (!mesh_.has_face_texture_index() || (mesh_.face_handle(*he_it).is_valid() && (mesh_.texture_index(mesh_.face_handle(*he_it))) > 0))
{
_texcoords.push_back(vector_cast<Vec2f>(mesh_.texcoord2D( *he_it)));
++count;
}
}
return count;
}
unsigned int get_face_texcoords(std::vector<Vec2f>& _hehandles) const
// get face data
unsigned int get_vhandles(FaceHandle _fh,
std::vector<VertexHandle>& _vhandles) const
{
unsigned int count(0);
_hehandles.clear();
for(typename Mesh::CHIter he_it=mesh_.halfedges_begin();
he_it != mesh_.halfedges_end(); ++he_it)
_vhandles.clear();
for (typename Mesh::CFVIter fv_it=mesh_.cfv_iter(_fh); fv_it.is_valid(); ++fv_it)
{
_hehandles.push_back(vector_cast<Vec2f>(mesh_.texcoord2D( *he_it)));
_vhandles.push_back(*fv_it);
++count;
}
return count;
}
......@@ -304,6 +325,26 @@ public:
: Vec4f(0, 0, 0, 0));
}
int face_texindex(FaceHandle _fh) const
{
return mesh_.has_face_texture_index() ? mesh_.texture_index(_fh) : -1;
}
// Material attributes
std::string texture_name(int _index) const
{
OpenMesh::MPropHandleT< std::map< int, std::string > > property;
if ( !mesh_.get_property_handle(property,"TextureMapping") ) {
return std::string();
}
const auto it = mesh_.property(property).find( _index );
if ( it != mesh_.property(property).end() ) {
return it->second;
}
return std::string();
}
virtual const BaseKernel* kernel() { return &mesh_; }
......@@ -317,13 +358,14 @@ public:
bool is_triangle_mesh() const
{ return Mesh::is_triangles(); }
bool has_vertex_normals() const { return mesh_.has_vertex_normals(); }
bool has_vertex_colors() const { return mesh_.has_vertex_colors(); }
bool has_vertex_texcoords() const { return mesh_.has_vertex_texcoords2D(); }
bool has_edge_colors() const { return mesh_.has_edge_colors(); }
bool has_face_normals() const { return mesh_.has_face_normals(); }
bool has_face_colors() const { return mesh_.has_face_colors(); }
bool has_vertex_normals() const { return mesh_.has_vertex_normals(); }
bool has_vertex_colors() const { return mesh_.has_vertex_colors(); }
bool has_vertex_texcoords() const { return mesh_.has_vertex_texcoords2D(); }
bool has_edge_colors() const { return mesh_.has_edge_colors(); }
bool has_face_normals() const { return mesh_.has_face_normals(); }
bool has_face_colors() const { return mesh_.has_face_colors(); }
bool has_face_texture_index() const { return mesh_.has_face_texture_index(); }
bool has_halfedge_normals() const { return mesh_.has_halfedge_normals(); }
private:
const Mesh& mesh_;
......
......@@ -193,17 +193,14 @@ read_material(std::fstream& _in)
stream >> keyWrd;
if( ( isspace(line[0]) && line[0] != '\t' ) || line[0] == '#' )
if ( !keyWrd.empty() && keyWrd[0] == '#' ) // skip comments
{
if (indef && !key.empty() && mat.is_valid())
{
materials_[key] = mat;
mat.cleanup();
}
continue;
}
else if (keyWrd == "newmtl") // begin new material definition
{
mat.cleanup();
stream >> key;
indef = true;
}
......@@ -356,7 +353,7 @@ read_vertices(std::istream& _in, BaseImporter& _bi, Options& _opt,
// Can be used for both!
fileOptions += Options::VertexTexCoord;
fileOptions += Options::FaceTexCoord;
fileOptions += Options::HalfedgeTexCoord;
// try to read the w component as it is optional
stream >> w;
......@@ -391,9 +388,10 @@ read_vertices(std::istream& _in, BaseImporter& _bi, Options& _opt,
stream >> x; stream >> y; stream >> z;
if ( !stream.fail() ) {
if (userOptions.vertex_has_normal() ){
if (userOptions.vertex_has_normal() || userOptions.halfedge_has_normal()) {
normals.push_back(OpenMesh::Vec3f(x,y,z));
fileOptions += Options::VertexNormal;
fileOptions += Options::HalfedgeNormal;
}
}
}
......@@ -420,6 +418,7 @@ read(std::istream& _in, BaseImporter& _bi, Options& _opt)
BaseImporter::VHandles vhandles;
std::vector<Vec3f> face_texcoords3d;
std::vector<Vec2f> face_texcoords;
std::vector<Vec3f> halfedge_normals;
std::string matname;
......@@ -540,6 +539,7 @@ read(std::istream& _in, BaseImporter& _bi, Options& _opt)
vhandles.clear();
face_texcoords.clear();
halfedge_normals.clear();
// read full line after detecting a face
std::string faceLine;
......@@ -674,13 +674,22 @@ read(std::istream& _in, BaseImporter& _bi, Options& _opt)
// Obj counts from 1 and not zero .. array counts from zero therefore -1
if (fileOptions.vertex_has_normal() ) {
assert(!vhandles.empty());
if ((unsigned int)(value - 1) < normals.size()) {
if (value > 0 && std::size_t(value) <= normals.size()) {
_bi.set_normal(vhandles.back(), normals[value - 1]);
}
else {
omerr() << "Error setting vertex normal" << std::endl;
}
}
if (fileOptions.halfedge_has_normal() && userOptions.halfedge_has_normal() ) {
if (!normals.empty() && value > 0 && std::size_t(value) <= normals.size()) {
halfedge_normals.push_back( normals[value-1] );
} else {
omerr() << "Error setting per-halfedge normal" << std::endl;
}
}
break;
}
......@@ -739,7 +748,7 @@ read(std::istream& _in, BaseImporter& _bi, Options& _opt)
for (std::vector<FaceHandle>::iterator it = newfaces.begin(); it != newfaces.end(); ++it)
_bi.set_face_texindex(*it, mat.map_Kd_index());
fileOptions += Options::FaceTexCoord;
fileOptions += Options::HalfedgeTexCoord;
}
......
......@@ -138,11 +138,12 @@ protected:
bool check(BaseExporter& _be, Options _opt) const
{
return (_opt.check(Options::VertexNormal ) <= _be.has_vertex_normals())
&& (_opt.check(Options::VertexTexCoord)<= _be.has_vertex_texcoords())
&& (_opt.check(Options::VertexColor) <= _be.has_vertex_colors())
&& (_opt.check(Options::FaceNormal) <= _be.has_face_normals())
&& (_opt.check(Options::FaceColor) <= _be.has_face_colors());
return (_opt.check(Options::VertexNormal) <= _be.has_vertex_normals())
&& (_opt.check(Options::HalfedgeNormal) <= _be.has_halfedge_normals())
&& (_opt.check(Options::VertexTexCoord) <= _be.has_vertex_texcoords())
&& (_opt.check(Options::VertexColor) <= _be.has_vertex_colors())
&& (_opt.check(Options::FaceNormal) <= _be.has_face_normals())
&& (_opt.check(Options::FaceColor) <= _be.has_face_colors());
}
};
......
This diff is collapsed.
......@@ -107,12 +107,36 @@ private:
mutable std::string path_;
mutable std::string objName_;
mutable std::vector< OpenMesh::Vec3f > material_;
mutable std::vector< OpenMesh::Vec4f > materialA_;
size_t getMaterial(OpenMesh::Vec3f _color) const;
size_t getMaterial(OpenMesh::Vec4f _color) const;
struct Material {
Material()
{
hasColor = false;
hasTextureIndex = false;
}
bool operator ==(const Material& other) const
{
if (hasColor != other.hasColor) return false;
if (hasColor && color != other.color) return false;
if (hasTextureIndex != other.hasTextureIndex) return false;
if (hasTextureIndex && textureIndex != other.textureIndex) return false;
return true;
}
bool is_valid() const
{
return hasColor || hasTextureIndex;
}
OpenMesh::Vec4f color;
bool hasColor;
int textureIndex;
bool hasTextureIndex;
};
mutable std::vector< Material > material_;
size_t getCachedMaterial(const Material&) const;
Material getMaterialDescription(FaceHandle _f, BaseExporter& _be, Options _opt) const;
bool writeMaterial(std::ostream& _out, BaseExporter&, Options) const;
......