Commit b6dcb8ad authored by Matthias Möller's avatar Matthias Möller

add unittest for vdpm (read and write/read)

closes #2263

git-svn-id: http://www.openmesh.org/svnrepo/OpenMesh/trunk@1179 fdac6126-5c0c-442c-9429-916003d36597
parent a505d427
#include <gtest/gtest.h>
#include <Unittests/unittests_common.hh>
#include <OpenMesh/Tools/Decimater/DecimaterT.hh>
#include <OpenMesh/Tools/Decimater/ModProgMeshT.hh>
#include <OpenMesh/Tools/Decimater/ModQuadricT.hh>
#include <OpenMesh/Tools/VDPM/VHierarchy.hh>
#include <OpenMesh/Tools/VDPM/VHierarchyNode.hh>
#include <OpenMesh/Tools/VDPM/VHierarchyNodeIndex.hh>
namespace {
class OpenMeshVDPM : public OpenMeshBase {
protected:
// This function is called before each test is run
virtual void SetUp() {
}
// This function is called after all tests are through
virtual void TearDown() {
// Do some final stuff with the member data here...
}
// Member already defined in OpenMeshBase
//Mesh mesh_;
};
/*
* ====================================================================
* Define tests below
* ====================================================================
*/
/*
* 2 tests, one is creating a pm file (cube1.pm) and the second test loads and analyze the readings.
*/
struct PMInfo
{
Mesh::Point p0;
Mesh::VertexHandle v0, v1, vl, vr;
};
struct VDPMTraits : public OpenMesh::DefaultTraits
{
typedef OpenMesh::VDPM::VHierarchyNodeHandle VHierarchyNodeHandle;
typedef OpenMesh::VDPM::VHierarchyNodeHandle VHierarchyNodeIndex;
VertexTraits
{
public:
VHierarchyNodeHandle vhierarchy_node_handle()
{
return node_handle_;
}
void set_vhierarchy_node_handle(VHierarchyNodeHandle _node_handle)
{
node_handle_ = _node_handle;
}
bool is_ancestor(const VHierarchyNodeIndex &_other)
{
return false;
}
private:
VHierarchyNodeHandle node_handle_;
};
HalfedgeTraits
{
public:
VHierarchyNodeHandle
vhierarchy_leaf_node_handle()
{
return leaf_node_handle_;
}
void
set_vhierarchy_leaf_node_handle(VHierarchyNodeHandle _leaf_node_handle)
{
leaf_node_handle_ = _leaf_node_handle;
}
private:
VHierarchyNodeHandle leaf_node_handle_;
};
VertexAttributes(OpenMesh::Attributes::Status |
OpenMesh::Attributes::Normal);
HalfedgeAttributes(OpenMesh::Attributes::PrevHalfedge);
EdgeAttributes(OpenMesh::Attributes::Status);
FaceAttributes(OpenMesh::Attributes::Status |
OpenMesh::Attributes::Normal);
};
typedef OpenMesh::TriMesh_ArrayKernelT<VDPMTraits> VDPMMesh;
struct LoadInfo
{
unsigned n_base_vertices;
unsigned n_base_faces;
unsigned n_details;
std::vector<PMInfo> pm_infos;
OpenMesh::VDPM::VHierarchy vhierarchy;
VDPMMesh mesh;
};
LoadInfo open_progresult_mesh(const std::string& _filename)
{
VDPMMesh::Point p;
unsigned int i, i0, i1, i2;
unsigned int v1, vl, vr;
char c[10];
VDPMMesh::VertexHandle vertex_handle;
OpenMesh::VDPM::VHierarchyNodeHandle node_handle, lchild_handle, rchild_handle;
OpenMesh::VDPM::VHierarchyNodeIndex node_index;
LoadInfo result;
std::ifstream ifs(_filename.c_str(), std::ios::binary);
if (!ifs)
{
EXPECT_TRUE(false) << "Could not open file";
return result;
}
//
bool swap = OpenMesh::Endian::local() != OpenMesh::Endian::LSB;
// read header
ifs.read(c, 8); c[8] = '\0';
if (std::string(c) != std::string("ProgMesh"))
{
EXPECT_TRUE(false) << "Wrong file format";
return result;
}
OpenMesh::IO::restore(ifs, result.n_base_vertices, swap);
OpenMesh::IO::restore(ifs, result.n_base_faces, swap);
OpenMesh::IO::restore(ifs, result.n_details, swap);
result.vhierarchy.set_num_roots(result.n_base_vertices);
for (i = 0; i<result.n_base_vertices; ++i)
{
OpenMesh::IO::restore(ifs, p, swap);
vertex_handle = result.mesh.add_vertex(p);
node_index = result.vhierarchy.generate_node_index(i, 1);
node_handle = result.vhierarchy.add_node();
result.vhierarchy.node(node_handle).set_index(node_index);
result.vhierarchy.node(node_handle).set_vertex_handle(vertex_handle);
result.mesh.data(vertex_handle).set_vhierarchy_node_handle(node_handle);
}
for (i = 0; i<result.n_base_faces; ++i)
{
OpenMesh::IO::restore(ifs, i0, swap);
OpenMesh::IO::restore(ifs, i1, swap);
OpenMesh::IO::restore(ifs, i2, swap);
result.mesh.add_face(result.mesh.vertex_handle(i0),
result.mesh.vertex_handle(i1),
result.mesh.vertex_handle(i2));
}
// load progressive detail
for (i = 0; i<result.n_details; ++i)
{
OpenMesh::IO::restore(ifs, p, swap);
OpenMesh::IO::restore(ifs, v1, swap);
OpenMesh::IO::restore(ifs, vl, swap);
OpenMesh::IO::restore(ifs, vr, swap);
PMInfo pminfo;
pminfo.p0 = p;
pminfo.v0 = result.mesh.add_vertex(p);
pminfo.v1 = Mesh::VertexHandle(v1);
pminfo.vl = Mesh::VertexHandle(vl);
pminfo.vr = Mesh::VertexHandle(vr);
result.pm_infos.push_back(pminfo);
node_handle = result.mesh.data(pminfo.v1).vhierarchy_node_handle();
result.vhierarchy.make_children(node_handle);
lchild_handle = result.vhierarchy.lchild_handle(node_handle);
rchild_handle = result.vhierarchy.rchild_handle(node_handle);
result.mesh.data(pminfo.v0).set_vhierarchy_node_handle(lchild_handle);
result.mesh.data(pminfo.v1).set_vhierarchy_node_handle(rchild_handle);
result.vhierarchy.node(lchild_handle).set_vertex_handle(pminfo.v0);
result.vhierarchy.node(rchild_handle).set_vertex_handle(pminfo.v1);
}
ifs.close();
// recover mapping between basemesh vertices to roots of vertex hierarchy
for (i = 0; i<result.n_base_vertices; ++i)
{
node_handle = result.vhierarchy.root_handle(i);
vertex_handle = result.vhierarchy.node(node_handle).vertex_handle();
result.mesh.data(vertex_handle).set_vhierarchy_node_handle(node_handle);
}
return result;
}
/*
* Reads and checks the progressive mesh file
*/
TEST_F(OpenMeshVDPM, ReadPM)
{
LoadInfo info = open_progresult_mesh("cube1.pm");
EXPECT_EQ(7526, info.mesh.n_vertices()) << "Vertices differ";
EXPECT_EQ(6, info.mesh.n_edges()) << "Edges differ";
EXPECT_EQ(4, info.mesh.n_faces()) << "Faces differ";
EXPECT_EQ(7522, info.n_details) << "Details differ";
}
/*
* Creates a progressive mesh
*/
TEST_F(OpenMeshVDPM, WriteReadPM)
{
Mesh mesh;
bool ok = OpenMesh::IO::read_mesh(mesh, "cube1.off");
ASSERT_TRUE(ok);
typedef OpenMesh::Decimater::DecimaterT< Mesh > Decimater;
typedef OpenMesh::Decimater::ModProgMeshT< Mesh >::Handle HModProg;
typedef OpenMesh::Decimater::ModQuadricT< Mesh >::Handle HModQuadric;
Decimater decimater(mesh);
HModProg hModProg;
HModQuadric hModQuadric;
decimater.add(hModQuadric);
decimater.add(hModProg);
decimater.initialize();
size_t removedVertices = 0;
removedVertices = decimater.decimate(0);
std::string filename = "vdpm_test_file.pm";
EXPECT_TRUE(decimater.module(hModProg).write(filename)) << "Could not write PM file.";
LoadInfo info = open_progresult_mesh(filename);
EXPECT_EQ(7526, info.mesh.n_vertices()) << "Vertices differ";
EXPECT_EQ(6, info.mesh.n_edges()) << "Edges differ";
EXPECT_EQ(4, info.mesh.n_faces()) << "Faces differ";
EXPECT_EQ(7522, info.n_details) << "Details differ";
remove(filename.c_str());
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment