write face normals as double

This commit is contained in:
Max Lyon
2020-02-10 09:19:09 +01:00
parent 27cab45624
commit d1da33cd1d
7 changed files with 78 additions and 14 deletions

View File

@@ -122,6 +122,7 @@ public:
virtual unsigned int virtual unsigned int
get_face_texcoords(std::vector<Vec2f>& _hehandles) const = 0; get_face_texcoords(std::vector<Vec2f>& _hehandles) const = 0;
virtual Vec3f normal(FaceHandle _fh) const = 0; virtual Vec3f normal(FaceHandle _fh) const = 0;
virtual Vec3d normald(FaceHandle _fh) const = 0;
virtual Vec3uc color (FaceHandle _fh) const = 0; virtual Vec3uc color (FaceHandle _fh) const = 0;
virtual Vec4uc colorA(FaceHandle _fh) const = 0; virtual Vec4uc colorA(FaceHandle _fh) const = 0;
virtual Vec3ui colori(FaceHandle _fh) const = 0; virtual Vec3ui colori(FaceHandle _fh) const = 0;

View File

@@ -328,6 +328,13 @@ public:
: Vec3f(0.0f, 0.0f, 0.0f)); : Vec3f(0.0f, 0.0f, 0.0f));
} }
Vec3d normald(FaceHandle _fh) const override
{
return (mesh_.has_face_normals()
? vector_cast<Vec3d>(mesh_.normal(_fh))
: Vec3d(0.0, 0.0, 0.0));
}
Vec3uc color(FaceHandle _fh) const override Vec3uc color(FaceHandle _fh) const override
{ {
return (mesh_.has_face_colors() return (mesh_.has_face_colors()

View File

@@ -126,7 +126,7 @@ public:
virtual void set_normal(VertexHandle _vh, const Vec3f& _normal) = 0; virtual void set_normal(VertexHandle _vh, const Vec3f& _normal) = 0;
// set vertex normal // set vertex normal
virtual void set_normal(VertexHandle _vh, const Vec3d& _normal) { set_normal(_vh, Vec3f(_normal)); } virtual void set_normal(VertexHandle _vh, const Vec3d& _normal) = 0;
// set vertex color // set vertex color
virtual void set_color(VertexHandle _vh, const Vec3uc& _color) = 0; virtual void set_color(VertexHandle _vh, const Vec3uc& _color) = 0;
@@ -182,6 +182,9 @@ public:
// set face normal // set face normal
virtual void set_normal(FaceHandle _fh, const Vec3f& _normal) = 0; virtual void set_normal(FaceHandle _fh, const Vec3f& _normal) = 0;
// set face normal
virtual void set_normal(FaceHandle _fh, const Vec3d& _normal) = 0;
// set face color // set face color
virtual void set_color(FaceHandle _fh, const Vec3uc& _color) = 0; virtual void set_color(FaceHandle _fh, const Vec3uc& _color) = 0;

View File

@@ -352,6 +352,12 @@ public:
mesh_.set_normal(_fh, vector_cast<Normal>(_normal)); mesh_.set_normal(_fh, vector_cast<Normal>(_normal));
} }
virtual void set_normal(FaceHandle _fh, const Vec3d& _normal) override
{
if (mesh_.has_face_normals())
mesh_.set_normal(_fh, vector_cast<Normal>(_normal));
}
virtual void set_color(FaceHandle _fh, const Vec3uc& _color) override virtual void set_color(FaceHandle _fh, const Vec3uc& _color) override
{ {
if (mesh_.has_face_colors()) if (mesh_.has_face_colors())

View File

@@ -355,6 +355,10 @@ bool _OMReader_::read_binary_vertex_chunk(std::istream &_is, BaseImporter &_bi,
_bi.set_normal(VertexHandle(int(vidx)), v3d); _bi.set_normal(VertexHandle(int(vidx)), v3d);
} }
} }
else
{
omerr() << "Unknown vertex normal format" << std::endl;
}
break; break;
case Chunk::Type_Texcoord: case Chunk::Type_Texcoord:
@@ -442,6 +446,7 @@ bool _OMReader_::read_binary_face_chunk(std::istream &_is, BaseImporter &_bi, Op
size_t fidx = 0; size_t fidx = 0;
OpenMesh::Vec3f v3f; // normal OpenMesh::Vec3f v3f; // normal
OpenMesh::Vec3d v3d; // normal as double
OpenMesh::Vec3uc v3uc; // rgb OpenMesh::Vec3uc v3uc; // rgb
OpenMesh::Attributes::StatusInfo status; OpenMesh::Attributes::StatusInfo status;
@@ -496,10 +501,26 @@ bool _OMReader_::read_binary_face_chunk(std::istream &_is, BaseImporter &_bi, Op
assert( OMFormat::dimensions(chunk_header_) == size_t(OpenMesh::Vec3f::dim())); assert( OMFormat::dimensions(chunk_header_) == size_t(OpenMesh::Vec3f::dim()));
fileOptions_ += Options::FaceNormal; fileOptions_ += Options::FaceNormal;
for (; fidx < header_.n_faces_ && !_is.eof(); ++fidx) {
bytes_ += vector_restore(_is, v3f, _swap); if (chunk_header_.bits_ == OMFormat::bits(0.0f)) // read floats
if( fileOptions_.face_has_normal() && _opt.face_has_normal()) {
_bi.set_normal(FaceHandle(int(fidx)), v3f); for (; fidx < header_.n_faces_ && !_is.eof(); ++fidx) {
bytes_ += vector_restore(_is, v3f, _swap);
if( fileOptions_.face_has_normal() && _opt.face_has_normal())
_bi.set_normal(FaceHandle(int(fidx)), v3f);
}
}
else if (chunk_header_.bits_ == OMFormat::bits(0.0)) // read doubles
{
for (; fidx < header_.n_faces_ && !_is.eof(); ++fidx) {
bytes_ += vector_restore(_is, v3d, _swap);
if( fileOptions_.face_has_normal() && _opt.face_has_normal())
_bi.set_normal(FaceHandle(int(fidx)), v3d);
}
}
else
{
omerr() << "Unknown face normal format" << std::endl;
} }
break; break;

View File

@@ -387,19 +387,36 @@ bool _OMWriter_::write_binary(std::ostream& _os, BaseExporter& _be,
{ {
#endif #endif
Vec3f n = _be.normal(FaceHandle(0)); Vec3f n = _be.normal(FaceHandle(0));
Vec3d nd = _be.normald(FaceHandle(0));
chunk_header.name_ = false; chunk_header.name_ = false;
chunk_header.entity_ = OMFormat::Chunk::Entity_Face; chunk_header.entity_ = OMFormat::Chunk::Entity_Face;
chunk_header.type_ = OMFormat::Chunk::Type_Normal; chunk_header.type_ = OMFormat::Chunk::Type_Normal;
chunk_header.signed_ = OMFormat::is_signed(n[0]);
chunk_header.float_ = OMFormat::is_float(n[0]); if (_be.is_normal_double())
chunk_header.dim_ = OMFormat::dim(n); {
chunk_header.bits_ = OMFormat::bits(n[0]); chunk_header.signed_ = OMFormat::is_signed(nd[0]);
chunk_header.float_ = OMFormat::is_float(nd[0]);
chunk_header.dim_ = OMFormat::dim(nd);
chunk_header.bits_ = OMFormat::bits(nd[0]);
}
else
{
chunk_header.signed_ = OMFormat::is_signed(n[0]);
chunk_header.float_ = OMFormat::is_float(n[0]);
chunk_header.dim_ = OMFormat::dim(n);
chunk_header.bits_ = OMFormat::bits(n[0]);
}
bytes += store( _os, chunk_header, swap ); bytes += store( _os, chunk_header, swap );
#if !NEW_STYLE #if !NEW_STYLE
for (i=0, nF=header.n_faces_; i<nF; ++i) if (_be.is_normal_double())
bytes += vector_store( _os, _be.normal(FaceHandle(i)), swap ); for (i=0, nF=header.n_faces_; i<nF; ++i)
bytes += vector_store( _os, _be.normald(FaceHandle(i)), swap );
else
for (i=0, nF=header.n_faces_; i<nF; ++i)
bytes += vector_store( _os, _be.normal(FaceHandle(i)), swap );
#else #else
bytes += bp->store(_os, swap ); bytes += bp->store(_os, swap );
} }

View File

@@ -1482,22 +1482,31 @@ TEST_F(OpenMeshReadWriteOM, WriteAndLoadDoubles) {
DoublePolyMesh mesh; DoublePolyMesh mesh;
mesh.request_vertex_normals(); mesh.request_vertex_normals();
mesh.request_face_normals();
mesh.add_vertex(DoublePolyMesh::Point(1.0/3.0, std::numeric_limits<double>::min(), std::numeric_limits<double>::max())); std::vector<OpenMesh::VertexHandle> vertices;
mesh.set_normal(OpenMesh::VertexHandle(0), DoublePolyMesh::Normal(1.0/3.0, std::numeric_limits<double>::min(), std::numeric_limits<double>::max())); for (int i = 0; i < 3; ++i)
{
vertices.push_back(mesh.add_vertex(DoublePolyMesh::Point(1.0/3.0, std::numeric_limits<double>::min(), std::numeric_limits<double>::max())));
mesh.set_normal(vertices.back(), DoublePolyMesh::Normal(1.0/3.0, std::numeric_limits<double>::min(), std::numeric_limits<double>::max()));
}
auto fh = mesh.add_face(vertices);
mesh.set_normal(fh, DoublePolyMesh::Normal(1.0/3.0, std::numeric_limits<double>::min(), std::numeric_limits<double>::max()));
std::string file_name = "doubles.om"; std::string file_name = "doubles.om";
OpenMesh::IO::Options opt = OpenMesh::IO::Options::VertexNormal; OpenMesh::IO::Options opt = OpenMesh::IO::Options::VertexNormal | OpenMesh::IO::Options::FaceNormal;
ASSERT_TRUE(OpenMesh::IO::write_mesh(mesh, file_name, opt)) << "Could not write file " << file_name; ASSERT_TRUE(OpenMesh::IO::write_mesh(mesh, file_name, opt)) << "Could not write file " << file_name;
DoublePolyMesh mesh2; DoublePolyMesh mesh2;
mesh2.request_vertex_normals(); mesh2.request_vertex_normals();
mesh2.request_face_normals();
ASSERT_TRUE(OpenMesh::IO::read_mesh(mesh2, file_name, opt)) << "Could not read file " << file_name; ASSERT_TRUE(OpenMesh::IO::read_mesh(mesh2, file_name, opt)) << "Could not read file " << file_name;
EXPECT_EQ(mesh.point(OpenMesh::VertexHandle(0)), mesh2.point(OpenMesh::VertexHandle(0))); EXPECT_EQ(mesh.point(OpenMesh::VertexHandle(0)), mesh2.point(OpenMesh::VertexHandle(0)));
EXPECT_EQ(mesh.normal(OpenMesh::VertexHandle(0)), mesh2.normal(OpenMesh::VertexHandle(0))); EXPECT_EQ(mesh.normal(OpenMesh::VertexHandle(0)), mesh2.normal(OpenMesh::VertexHandle(0)));
EXPECT_EQ(mesh.normal(OpenMesh::FaceHandle(0)), mesh2.normal(OpenMesh::FaceHandle(0)));
} }
} }