Developer Documentation
unittests_vdpm.cc
1 #include <gtest/gtest.h>
2 #include <Unittests/unittests_common.hh>
3 
7 
8 #include <OpenMesh/Tools/VDPM/VHierarchy.hh>
9 #include <OpenMesh/Tools/VDPM/VHierarchyNode.hh>
10 #include <OpenMesh/Tools/VDPM/VHierarchyNodeIndex.hh>
11 
12 namespace {
13 
14  class OpenMeshVDPM : public OpenMeshBase {
15 
16  protected:
17 
18  // This function is called before each test is run
19  virtual void SetUp() {
20  }
21 
22  // This function is called after all tests are through
23  virtual void TearDown() {
24 
25  // Do some final stuff with the member data here...
26  }
27 
28  // Member already defined in OpenMeshBase
29  //Mesh mesh_;
30  };
31 
32 /*
33 * ====================================================================
34 * Define tests below
35 * ====================================================================
36 */
37 
38 /*
39  * 2 tests, one is creating a pm file (cube1.pm) and the second test loads and analyze the readings.
40  */
41 
42 struct PMInfo
43 {
44  Mesh::Point p0;
45  Mesh::VertexHandle v0, v1, vl, vr;
46 };
47 
48 struct VDPMTraits : public OpenMesh::DefaultTraits
49 {
50  typedef OpenMesh::VDPM::VHierarchyNodeHandle VHierarchyNodeHandle;
51  typedef OpenMesh::VDPM::VHierarchyNodeHandle VHierarchyNodeIndex;
53  {
54  public:
55 
56  VHierarchyNodeHandle vhierarchy_node_handle()
57  {
58  return node_handle_;
59  }
60 
61  void set_vhierarchy_node_handle(VHierarchyNodeHandle _node_handle)
62  {
63  node_handle_ = _node_handle;
64  }
65 
66  bool is_ancestor(const VHierarchyNodeIndex &_other)
67  {
68  return false;
69  }
70 
71  private:
72 
73  VHierarchyNodeHandle node_handle_;
74 
75  };
76 
77 
79  {
80  public:
81 
82  VHierarchyNodeHandle
83  vhierarchy_leaf_node_handle()
84  {
85  return leaf_node_handle_;
86  }
87 
88  void
89  set_vhierarchy_leaf_node_handle(VHierarchyNodeHandle _leaf_node_handle)
90  {
91  leaf_node_handle_ = _leaf_node_handle;
92  }
93 
94  private:
95 
96  VHierarchyNodeHandle leaf_node_handle_;
97 
98  };
99 
106 
107 };
108 
110 
111 struct LoadInfo
112 {
113  unsigned n_base_vertices;
114  unsigned n_base_faces;
115  unsigned n_details;
116  std::vector<PMInfo> pm_infos;
117  OpenMesh::VDPM::VHierarchy vhierarchy;
118  VDPMMesh mesh;
119 };
120 
121 LoadInfo open_progresult_mesh(const std::string& _filename)
122 {
123  VDPMMesh::Point p;
124  unsigned int i, i0, i1, i2;
125  unsigned int v1, vl, vr;
126  char c[10];
127  VDPMMesh::VertexHandle vertex_handle;
128  OpenMesh::VDPM::VHierarchyNodeHandle node_handle, lchild_handle, rchild_handle;
130  LoadInfo result;
131 
132  std::ifstream ifs(_filename.c_str(), std::ios::binary);
133  if (!ifs)
134  {
135  EXPECT_TRUE(false) << "Could not open file";
136  return result;
137  }
138 
139  //
141 
142  // read header
143  ifs.read(c, 8); c[8] = '\0';
144  if (std::string(c) != std::string("ProgMesh"))
145  {
146  EXPECT_TRUE(false) << "Wrong file format";
147  return result;
148  }
149 
150  OpenMesh::IO::restore(ifs, result.n_base_vertices, swap);
151  OpenMesh::IO::restore(ifs, result.n_base_faces, swap);
152  OpenMesh::IO::restore(ifs, result.n_details, swap);
153 
154  result.vhierarchy.set_num_roots(result.n_base_vertices);
155 
156  for (i = 0; i<result.n_base_vertices; ++i)
157  {
158  OpenMesh::IO::restore(ifs, p, swap);
159 
160  vertex_handle = result.mesh.add_vertex(p);
161  node_index = result.vhierarchy.generate_node_index(i, 1);
162  node_handle = result.vhierarchy.add_node();
163 
164  result.vhierarchy.node(node_handle).set_index(node_index);
165  result.vhierarchy.node(node_handle).set_vertex_handle(vertex_handle);
166  result.mesh.data(vertex_handle).set_vhierarchy_node_handle(node_handle);
167  }
168 
169  for (i = 0; i<result.n_base_faces; ++i)
170  {
171  OpenMesh::IO::restore(ifs, i0, swap);
172  OpenMesh::IO::restore(ifs, i1, swap);
173  OpenMesh::IO::restore(ifs, i2, swap);
174  result.mesh.add_face(result.mesh.vertex_handle(i0),
175  result.mesh.vertex_handle(i1),
176  result.mesh.vertex_handle(i2));
177  }
178 
179  // load progressive detail
180  for (i = 0; i<result.n_details; ++i)
181  {
182  OpenMesh::IO::restore(ifs, p, swap);
183  OpenMesh::IO::restore(ifs, v1, swap);
184  OpenMesh::IO::restore(ifs, vl, swap);
185  OpenMesh::IO::restore(ifs, vr, swap);
186 
187  PMInfo pminfo;
188  pminfo.p0 = p;
189  pminfo.v0 = result.mesh.add_vertex(p);
190  pminfo.v1 = Mesh::VertexHandle(v1);
191  pminfo.vl = Mesh::VertexHandle(vl);
192  pminfo.vr = Mesh::VertexHandle(vr);
193  result.pm_infos.push_back(pminfo);
194 
195  node_handle = result.mesh.data(pminfo.v1).vhierarchy_node_handle();
196 
197  result.vhierarchy.make_children(node_handle);
198  lchild_handle = result.vhierarchy.lchild_handle(node_handle);
199  rchild_handle = result.vhierarchy.rchild_handle(node_handle);
200 
201  result.mesh.data(pminfo.v0).set_vhierarchy_node_handle(lchild_handle);
202  result.mesh.data(pminfo.v1).set_vhierarchy_node_handle(rchild_handle);
203  result.vhierarchy.node(lchild_handle).set_vertex_handle(pminfo.v0);
204  result.vhierarchy.node(rchild_handle).set_vertex_handle(pminfo.v1);
205  }
206 
207  ifs.close();
208 
209 
210  // recover mapping between basemesh vertices to roots of vertex hierarchy
211  for (i = 0; i<result.n_base_vertices; ++i)
212  {
213  node_handle = result.vhierarchy.root_handle(i);
214  vertex_handle = result.vhierarchy.node(node_handle).vertex_handle();
215 
216  result.mesh.data(vertex_handle).set_vhierarchy_node_handle(node_handle);
217  }
218 
219  return result;
220 }
221 
222 /*
223 * Reads and checks the progressive mesh file
224 */
225 
226 TEST_F(OpenMeshVDPM, ReadPM)
227 {
228  LoadInfo info = open_progresult_mesh("cube1.pm");
229 
230  EXPECT_EQ(7526u, info.mesh.n_vertices()) << "Vertices differ";
231  EXPECT_EQ(6u, info.mesh.n_edges()) << "Edges differ";
232  EXPECT_EQ(4u, info.mesh.n_faces()) << "Faces differ";
233  EXPECT_EQ(7522u, info.n_details) << "Details differ";
234 }
235 
236 /*
237 * Creates a progressive mesh
238 */
239 TEST_F(OpenMeshVDPM, WriteReadPM)
240 {
241  Mesh mesh;
242  bool ok = OpenMesh::IO::read_mesh(mesh, "cube1.off");
243 
244  ASSERT_TRUE(ok);
245 
246  typedef OpenMesh::Decimater::DecimaterT< Mesh > Decimater;
249 
250  Decimater decimater(mesh);
251  HModProg hModProg;
252  HModQuadric hModQuadric;
253  decimater.add(hModQuadric);
254  decimater.add(hModProg);
255  decimater.initialize();
256  decimater.decimate(0);
257 
258  std::string filename = "vdpm_test_file.pm";
259 
260  EXPECT_TRUE(decimater.module(hModProg).write(filename)) << "Could not write PM file.";
261 
262  LoadInfo info = open_progresult_mesh(filename);
263  EXPECT_EQ(7526u, info.mesh.n_vertices()) << "Vertices differ";
264  EXPECT_EQ(6u, info.mesh.n_edges()) << "Edges differ";
265  EXPECT_EQ(4u, info.mesh.n_faces()) << "Faces differ";
266  EXPECT_EQ(7522u, info.n_details) << "Details differ";
267 
268  remove(filename.c_str());
269 }
270 
271 
272 
273 
274 
275 }
Little endian (Intel family and clones)
Definition: Endian.hh:83
Add storage for previous halfedge (halfedges). The bit is set by default in the DefaultTraits.
Definition: Attributes.hh:89
#define VertexTraits
Macro for defining the vertex traits. See Specifying your MyMesh.
Definition: Traits.hh:96
size_t restore(std::istream &_is, T &_v, bool _swap=false)
Add normals to mesh item (vertices/faces)
Definition: Attributes.hh:87
#define HalfedgeAttributes(_i)
Macro for defining the halfedge attributes. See Specifying your MyMesh.
Definition: Traits.hh:87
#define VertexAttributes(_i)
Macro for defining the vertex attributes. See Specifying your MyMesh.
Definition: Traits.hh:84
bool read_mesh(Mesh &_mesh, const std::string &_filename)
Read a mesh from file _filename.
Definition: MeshIO.hh:104
Mesh decimation module computing collapse priority based on error quadrics.
Definition: ModQuadricT.hh:83
Add status to mesh item (all items)
Definition: Attributes.hh:90
Kernel::VertexHandle VertexHandle
Handle for referencing the corresponding item.
Definition: PolyMeshT.hh:139
#define HalfedgeTraits
Macro for defining the halfedge traits. See Specifying your MyMesh.
Definition: Traits.hh:100
#define FaceAttributes(_i)
Macro for defining the face attributes. See Specifying your MyMesh.
Definition: Traits.hh:93
Kernel::Point Point
Coordinate type.
Definition: PolyMeshT.hh:115
#define EdgeAttributes(_i)
Macro for defining the edge attributes. See Specifying your MyMesh.
Definition: Traits.hh:90
static Type local()
Return endian type of host system.
Definition: Endian.hh:88