MEPP2 Project
test_one_ring_aif.cpp
Go to the documentation of this file.
1 // Copyright (c) 2012-2019 University of Lyon and CNRS (France).
2 // All rights reserved.
3 //
4 // This file is part of MEPP2; you can redistribute it and/or modify
5 // it under the terms of the GNU Lesser General Public License as
6 // published by the Free Software Foundation; either version 3 of
7 // the License, or (at your option) any later version.
8 //
9 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
10 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13 
14 #include "FEVV/Wrappings/Geometry_traits_aif.h" // for k_ring testing
15 #include "FEVV/Operators/Generic/Manifold/k_ring.hpp" // for k_ring testing
16 
17 #include <algorithm>
18 
19 // must be the last include to avoid side effect of disabling NDEBUG
20 #undef NDEBUG
21 #include <cassert>
22 
23 using namespace FEVV; // for k_ring testing
24 
25 //------------------------------------------------------------------------------
26 
27 /*
28  * Display container or range content.
29  */
30 template< typename T >
31 void
32 display_container(const T &container, const char *title)
33 {
34  std::cout << title << " =" << std::endl;
35  for(auto element : container)
36  std::cout << " " << element << std::endl;
37  std::cout << std::endl;
38 }
39 
40 //------------------------------------------------------------------------------
41 
42 const bool VERBOSE = false;
43 
44 /*
45  * Returns true if 2 containers are equal by rotation.
46  */
47 template< typename T >
48 bool
49 rotationally_equal(const T &v1, T v2, bool test_in_reverse_order_too = true)
50 {
51  bool are_equal = false;
52 
53  while(true)
54  {
55  for(size_t i = 0; i < v1.size(); i++)
56  {
57  if(VERBOSE)
58  {
59  std::cout << "rotate number = " << i << std::endl;
60  display_container(v1, "v1");
61  display_container(v2, "v2");
62  }
63 
64  if(v1 == v2)
65  {
66  if(VERBOSE)
67  std::cout << "v1 == v2" << std::endl;
68  are_equal = true;
69  break;
70  }
71  else
72  {
73  if(VERBOSE)
74  std::cout << "v1 != v2" << std::endl;
75  }
76 
77  // rotate v2 and test again
78  std::rotate(v2.begin(), v2.begin() + 1, v2.end());
79  }
80 
81  if(are_equal == false && test_in_reverse_order_too)
82  {
83  if(VERBOSE)
84  std::cout << "reverse v2" << std::endl;
85  std::reverse(v2.begin(), v2.end());
86  test_in_reverse_order_too = false;
87  }
88  else
89  break;
90  }
91 
92  return are_equal;
93 }
94 
95 //------------------------------------------------------------------------------
96 
97 int
98 main(void)
99 {
101  //typedef FEVV::DataStructures::AIF::AIFVertex AIFVertex;
102  //typedef FEVV::DataStructures::AIF::AIFEdge AIFEdge;
103  //typedef FEVV::DataStructures::AIF::AIFFace AIFFace;
105  //typedef helpers::AIFHalfEdge AIFHalfEdge;
106  typedef helpers::smart_ptr_mesh smart_ptr_mesh;
109  typedef helpers::halfedge_descriptor halfedge_descriptor;
110  typedef helpers::face_descriptor face_descriptor;
111 
112 
113  // build mesh
114  /*
115  v2 ----------- v6
116  /|\ e14 \
117  / | \ \
118  / | \ \
119  / | \ \
120  / | \ \e0
121  e4/ |e15 \e5 \
122  / | \ \
123  / | \ \
124  / | \ \ v9
125  / | \ \ / \
126  / | \ \ / \
127  / f4 | f3 \ f2 \ e3/ \e1
128  / | \ \ / f5 \
129  / e13 | e9 \ \ / \
130 v1 ---------- v0 ----------- v3 v7 --------- v8
131  \ | | / e7
132  \ | | /
133  \ | | /
134  \ | | /
135  \ f0 | f1 | /
136  \ | | /
137  \ | | / v11 (isolated)
138  e12\ |e11 e6| e2/ X
139  \ | | /
140  \ | | /
141  \ | | /
142  \ | | /
143  \ | | /
144  \| e10 |/ e8
145  v5 ----------- v4 ----------- v10
146  */
147 
148  smart_ptr_mesh m = AIFMesh::New();
149 
150  // add vertices
163 
164  // add edges
166  helpers::link_vertex_and_edge(v6, e0, helpers::vertex_pos::FIRST);
167  helpers::link_vertex_and_edge(v7, e0, helpers::vertex_pos::SECOND);
169  helpers::link_vertex_and_edge(v8, e1, helpers::vertex_pos::FIRST);
170  helpers::link_vertex_and_edge(v9, e1, helpers::vertex_pos::SECOND);
172  helpers::link_vertex_and_edge(v4, e2, helpers::vertex_pos::FIRST);
173  helpers::link_vertex_and_edge(v7, e2, helpers::vertex_pos::SECOND);
175  helpers::link_vertex_and_edge(v7, e3, helpers::vertex_pos::FIRST);
176  helpers::link_vertex_and_edge(v9, e3, helpers::vertex_pos::SECOND);
178  helpers::link_vertex_and_edge(v1, e4, helpers::vertex_pos::FIRST);
179  helpers::link_vertex_and_edge(v2, e4, helpers::vertex_pos::SECOND);
181  helpers::link_vertex_and_edge(v2, e5, helpers::vertex_pos::FIRST);
182  helpers::link_vertex_and_edge(v3, e5, helpers::vertex_pos::SECOND);
184  helpers::link_vertex_and_edge(v3, e6, helpers::vertex_pos::FIRST);
185  helpers::link_vertex_and_edge(v4, e6, helpers::vertex_pos::SECOND);
187  helpers::link_vertex_and_edge(v7, e7, helpers::vertex_pos::FIRST);
188  helpers::link_vertex_and_edge(v8, e7, helpers::vertex_pos::SECOND);
190  helpers::link_vertex_and_edge(v4, e8, helpers::vertex_pos::FIRST);
191  helpers::link_vertex_and_edge(v10, e8, helpers::vertex_pos::SECOND);
193  helpers::link_vertex_and_edge(v0, e9, helpers::vertex_pos::FIRST);
194  helpers::link_vertex_and_edge(v3, e9, helpers::vertex_pos::SECOND);
196  helpers::link_vertex_and_edge(v4, e10, helpers::vertex_pos::FIRST);
197  helpers::link_vertex_and_edge(v5, e10, helpers::vertex_pos::SECOND);
199  helpers::link_vertex_and_edge(v5, e11, helpers::vertex_pos::FIRST);
200  helpers::link_vertex_and_edge(v0, e11, helpers::vertex_pos::SECOND);
202  helpers::link_vertex_and_edge(v1, e12, helpers::vertex_pos::FIRST);
203  helpers::link_vertex_and_edge(v5, e12, helpers::vertex_pos::SECOND);
205  helpers::link_vertex_and_edge(v1, e13, helpers::vertex_pos::FIRST);
206  helpers::link_vertex_and_edge(v0, e13, helpers::vertex_pos::SECOND);
208  helpers::link_vertex_and_edge(v6, e14, helpers::vertex_pos::FIRST);
209  helpers::link_vertex_and_edge(v2, e14, helpers::vertex_pos::SECOND);
211  helpers::link_vertex_and_edge(v0, e15, helpers::vertex_pos::FIRST);
212  helpers::link_vertex_and_edge(v2, e15, helpers::vertex_pos::SECOND);
213 
214  // add faces [counter-clockwise oriented]
215  face_descriptor f0 = helpers::add_face(m);
219  face_descriptor f1 = helpers::add_face(m);
224  face_descriptor f2 = helpers::add_face(m);
230  face_descriptor f3 = helpers::add_face(m);
234  face_descriptor f4 = helpers::add_face(m);
238  face_descriptor f5 = helpers::add_face(m);
242 
243  // display mesh informations
244  std::cout << "Input mesh:\n";
245  m->Print();
246 
247  //---------------------- Tests ---------------------
248 
249  // unordered one ring edges of vertex
250 
251  std::cout << "testing get_unordered_one_ring_edges(v0)" << std::endl;
252  // display_container(helpers::get_unordered_one_ring_edges(v0),
253  // "get_unordered_one_ring_edges(v0)");
254  // display_container(std::set<edge_descriptor>{e4, e5, e12, e6, e10},
255  // "std::set<edge_descriptor>{e4, e5, e12, e6, e10}");
257  std::set< edge_descriptor >{e4, e5, e12, e6, e10}));
258 
259  std::cout << "testing get_unordered_one_ring_edges(v1)" << std::endl;
261  std::set< edge_descriptor >{e11, e15}));
262 
263  std::cout << "testing get_unordered_one_ring_edges(v2)" << std::endl;
265  std::set< edge_descriptor >{e9, e13, e6, e2, e0}));
266 
267  std::cout << "testing get_unordered_one_ring_edges(v11)" << std::endl;
269  std::set< edge_descriptor >{}));
270 
271 
272  // ordered one ring edges of vertex
273 
274  std::cout << "testing get_ordered_one_ring_edges(v0)" << std::endl;
275  assert(
277  std::vector< edge_descriptor >{e5, e6, e10, e12, e4}));
278 
279  // display_container(helpers::get_ordered_one_ring_edges(v1),
280  // "get_ordered_one_ring_edges(v1)");
281  std::cout << "testing get_ordered_one_ring_edges(v1)" << std::endl;
283  std::vector< edge_descriptor >{e15, e11}));
284 
285  // display_container(helpers::get_ordered_one_ring_edges(v2),
286  // "get_ordered_one_ring_edges(v2)");
287  std::cout << "testing get_ordered_one_ring_edges(v2)" << std::endl;
288  assert(
290  std::vector< edge_descriptor >{e0, e2, e6, e9, e13}));
291 
292  std::cout << "testing get_ordered_one_ring_edges(v11)" << std::endl;
294  std::vector< edge_descriptor >{}));
295 
296 
297  // ordered one ring of vertices of vertex
298 
299  std::cout << "testing get_ordered_one_ring_vertices(v0)" << std::endl;
300  assert(
302  std::vector< vertex_descriptor >{v2, v3, v4, v5, v1}));
303 
304  std::cout << "testing get_ordered_one_ring_vertices(v1)" << std::endl;
306  std::vector< vertex_descriptor >{v2, v0, v5}));
307 
308  std::cout << "testing get_ordered_one_ring_vertices(v2)" << std::endl;
309  assert(rotationally_equal(
311  std::vector< vertex_descriptor >{v6, v7, v4, v3, v0, v1}));
312 
313  std::cout << "testing get_ordered_one_ring_vertices(v11)" << std::endl;
315  std::vector< vertex_descriptor >{}));
316 
317 
318  // ordered one ring of adjacent vertices of vertex
319 
320  std::cout << "testing get_ordered_one_ring_of_adjacent_vertices(v0)"
321  << std::endl;
322  assert(
324  std::vector< vertex_descriptor >{v1, v2, v3, v5}));
325 
326  std::cout << "testing get_ordered_one_ring_of_adjacent_vertices(v1)"
327  << std::endl;
328  assert(
330  std::vector< vertex_descriptor >{v2, v0, v5}));
331 
332  std::cout << "testing get_ordered_one_ring_of_adjacent_vertices(v2)"
333  << std::endl;
334  assert(
336  std::vector< vertex_descriptor >{v6, v3, v0, v1}));
337 
338  std::cout << "testing get_ordered_one_ring_of_adjacent_vertices(v11)"
339  << std::endl;
341  std::vector< vertex_descriptor >{}));
342 
343  // test one-ring-vertices cache
344 
345  std::cout << "testing one-ring-vertices cache" << std::endl;
346  auto one_r1 = helpers::get_ordered_one_ring_vertices(v2);
347  helpers::remove_face(f4, m);
348  auto one_r2 = helpers::get_ordered_one_ring_vertices(v2);
349  assert(one_r1 != one_r2);
350 
351  // test extract_k_ring [k_ring.h]
352 
353  std::cout << "testing extract_k_ring" << std::endl;
354  std::vector< vertex_descriptor > qv;
355  Operators::extract_k_ring(v0, *m, 0, qv);
356  assert((qv == std::vector< vertex_descriptor >{v0}));
357  qv.clear();
359  v0,
360  *m,
361  1,
362  qv); // be careful face f4 has been removed before this current test
363  assert((qv == std::vector< vertex_descriptor >{v0, v3, v5, v1, v2}));
364  qv.clear();
365  Operators::extract_k_ring(v0, *m, 2, qv);
366  assert((qv == std::vector< vertex_descriptor >{v0, v3, v5, v1, v2, v4, v6}));
367  helpers::remove_edge(e8, m); // remove e8 to ensure 2-manifoldness (else
368  // extract_k_ring will throw an exception)
369  qv.clear();
370  Operators::extract_k_ring(v0, *m, 3, qv);
371  assert(
372  (qv == std::vector< vertex_descriptor >{v0, v3, v5, v1, v2, v4, v6, v7}));
373  // cannot go further away, because v7 is not a manifold vertex (cut-vertex)
374 
375  qv.clear();
376  Operators::extract_k_ring(v8, *m, 1, qv);
377  assert((qv == std::vector< vertex_descriptor >{v8, v9, v7}));
378  qv.clear();
379  Operators::extract_k_ring(v9, *m, 1, qv);
380  assert((qv == std::vector< vertex_descriptor >{v9, v8, v7}));
381 
382  // test extract_vertex_star [k_ring.h]
383 
384  std::cout << "testing extract_vertex_star" << std::endl;
385  std::vector< halfedge_descriptor > qh;
386  Operators::extract_vertex_star(v0, *m, qh);
387  assert((qh == std::vector< halfedge_descriptor >{
388  halfedge_descriptor(v3, v0, f1, e9, false),
389  halfedge_descriptor(v5, v0, f0, e11, false),
390  halfedge_descriptor(
391  v0, v1, f0, e13, false), // f4 has been removed
392  halfedge_descriptor(v2, v0, f3, e15, false)}));
393  qh.clear();
394 
395  Operators::extract_vertex_star(v6, *m, qh);
396  assert((qh == std::vector< halfedge_descriptor >{
397  halfedge_descriptor(v7, v6, f2, e0, false),
398  halfedge_descriptor(v6, v2, f2, e14, false)}));
399  qh.clear();
400 
401  std::cout << "Test passed.\n";
402  return 0; // all tests passed
403 }
helpers
AIFTopologyHelpers helpers
Definition: test_helpers_aif.cpp:16
FEVV::DataStructures::AIF::AIFTopologyHelpers::add_face
static face_descriptor add_face(ptr_mesh mesh)
Definition: AIFTopologyHelpers.h:2887
FEVV::DataStructures::AIF::AIFTopologyHelpers::AIFHalfEdge
Definition: AIFTopologyHelpers.h:4748
FEVV::DataStructures::AIF::AIFTopologyHelpers::link_edge_and_face
static void link_edge_and_face(edge_descriptor edge, face_descriptor face)
Definition: AIFTopologyHelpers.h:1305
FEVV::DataStructures::AIF::AIFTopologyHelpers::vertex_descriptor
vertex_type::ptr vertex_descriptor
Definition: AIFTopologyHelpers.h:70
FEVV::DataStructures::AIF::AIFTopologyHelpers::get_ordered_one_ring_edges
static edge_container_in_vertex get_ordered_one_ring_edges(vertex_descriptor v)
Definition: AIFTopologyHelpers.h:3644
GraphConcept::edge_descriptor
boost::graph_traits< G >::edge_descriptor edge_descriptor
Definition: test_boost_graph_concept_aif.cpp:23
rotationally_equal
bool rotationally_equal(const T &v1, T v2, bool test_in_reverse_order_too=true)
Definition: test_one_ring_aif.cpp:49
FEVV::DataStructures::AIF::AIFTopologyHelpers::remove_face
static void remove_face(face_descriptor face, ptr_mesh mesh)
Definition: AIFTopologyHelpers.h:3120
FEVV::DataStructures::AIF::AIFTopologyHelpers::edge_descriptor
edge_type::ptr edge_descriptor
Definition: AIFTopologyHelpers.h:71
FEVV::DataStructures::AIF::AIFMesh::New
static ptr_mesh New()
Definition: AIFMesh.inl:720
FEVV::DataStructures::AIF::AIFTopologyHelpers::face_descriptor
face_type::ptr face_descriptor
Definition: AIFTopologyHelpers.h:72
FEVV::DataStructures::AIF::AIFTopologyHelpers::add_edge
static edge_descriptor add_edge(ptr_mesh mesh)
Definition: AIFTopologyHelpers.h:2772
k_ring.hpp
FEVV::Operators::extract_k_ring
void extract_k_ring(typename boost::graph_traits< FaceGraph >::vertex_descriptor v, const FaceGraph &g, int k, std::vector< typename boost::graph_traits< FaceGraph >::vertex_descriptor > &qv)
Extract vertices which are at most k (inclusive) far from vertex v in the graph of edges.
Definition: k_ring.hpp:41
FEVV::DataStructures::AIF::AIFTopologyHelpers::link_vertex_and_edge
static void link_vertex_and_edge(vertex_descriptor vertex, edge_descriptor edge, vertex_pos position)
Definition: AIFTopologyHelpers.h:515
display_container
void display_container(const T &container, const char *title)
Definition: test_one_ring_aif.cpp:32
FEVV::DataStructures::AIF::AIFTopologyHelpers::remove_edge
static void remove_edge(edge_descriptor edge, ptr_mesh mesh)
Definition: AIFTopologyHelpers.h:3012
FEVV
Interfaces for plugins These interfaces will be used for different plugins.
Definition: Assert.h:16
AIFMesh.hpp
Graph_traits_aif.h
FEVV::DataStructures::AIF::AIFTopologyHelpers::get_unordered_one_ring_edges
static std::set< edge_descriptor > get_unordered_one_ring_edges(vertex_descriptor v)
Definition: AIFTopologyHelpers.h:3481
FEVV::DataStructures::AIF::AIFTopologyHelpers::get_ordered_one_ring_vertices
static vertex_container_in_vertex get_ordered_one_ring_vertices(vertex_descriptor v)
Definition: AIFTopologyHelpers.h:4035
Geometry_traits_aif.h
main
int main(void)
Definition: test_one_ring_aif.cpp:98
msdm2::vertex_descriptor
boost::graph_traits< MeshT >::vertex_descriptor vertex_descriptor
Definition: msdm2_surfacemesh.h:33
FEVV::DataStructures::AIF::AIFTopologyHelpers::smart_ptr_mesh
mesh_type::ptr smart_ptr_mesh
Definition: AIFTopologyHelpers.h:64
FEVV::DataStructures::AIF::AIFTopologyHelpers
This class is an helper class associated to the AIFMesh structure. AIFTopologyHelpers implements all ...
Definition: AIFTopologyHelpers.h:57
FEVV::DataStructures::AIF::AIFMesh
This class represents an AIF structure. AIF structure can deal with both manifold and non-manifold su...
Definition: AIFMesh.hpp:47
VERBOSE
const bool VERBOSE
Definition: test_one_ring_aif.cpp:42
FEVV::DataStructures::AIF::AIFTopologyHelpers::add_vertex
static vertex_descriptor add_vertex(ptr_mesh mesh)
Definition: AIFTopologyHelpers.h:2709
FEVV::Operators::extract_vertex_star
void extract_vertex_star(typename boost::graph_traits< FaceGraph >::vertex_descriptor v, const FaceGraph &g, std::vector< typename boost::graph_traits< FaceGraph >::halfedge_descriptor > &qh)
Extract halfedges which have v as target vertex. All extracted halfedges are associated to a face,...
Definition: k_ring.hpp:106
AIFMesh
FEVV::DataStructures::AIF::AIFMesh AIFMesh
Definition: Graph_properties_aif.h:19
FEVV::DataStructures::AIF::AIFTopologyHelpers::get_ordered_one_ring_of_adjacent_vertices
static vertex_container_in_vertex get_ordered_one_ring_of_adjacent_vertices(vertex_descriptor v)
Definition: AIFTopologyHelpers.h:4305