MEPP2 Project
Spanning_tree_vertex_edge_comparator.hpp
Go to the documentation of this file.
1 // Copyright (c) 2012-2022 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.
11 
12 #pragma once
13 
16 
17 #include <CGAL/boost/graph/iterator.h>
18 #include <CGAL/boost/graph/helpers.h>
19 
20 #include <limits>
21 #include <iterator>
22 #include <map>
23 #include <set>
24 
25 #include <stack>
26 
27 namespace FEVV {
28 namespace Comparator
29 {
30  template<typename Graph>
33  const Graph& g)
34  {
35  typedef boost::graph_traits<Graph> GraphTraits;
37 
38  std::list<vertex_descriptor> adjacent_vertices;
39  auto vertices_range = CGAL::vertices_around_target(v, g); // works with two-manifold data structures
40  for (auto v : vertices_range) {
41  adjacent_vertices.push_back(v);
42  }
43 
44  return adjacent_vertices;
45  }
46 
47  template<typename Graph>
50  const Graph& g,
51  std::map<typename boost::graph_traits<Graph>::vertex_descriptor, bool>& processed_vertices,
52  typename boost::graph_traits<Graph>::edge_descriptor min_e)
53  {
54  typedef boost::graph_traits<Graph> GraphTraits;
56  typedef typename GraphTraits::halfedge_descriptor halfedge_descriptor;
57 
58  std::list<vertex_descriptor> adjacent_vertices;
59  if (min_e != edge(GraphTraits::null_halfedge(), g))
60  {
61  // find the (second) edge that separates old region and new region
62  halfedge_descriptor h = halfedge(min_e, g);
63  if (target(h, g) != v)
64  h = opposite(h, g);
65 
66  halfedge_descriptor h_end = h;
67  do
68  {
69  vertex_descriptor v_adj = source(h, g);
70  auto it_res = processed_vertices.find(v_adj);
71  if ((it_res == processed_vertices.end()) || !it_res->second)
72  { // not yet processed
73  if (it_res != processed_vertices.end())
74  it_res->second = true;
75  else
76  processed_vertices[v_adj] = true;
77  adjacent_vertices.push_back(source(h, g));
78  }
79 
80  h = opposite(next(h, g), g);
81  } while (!(h == h_end));
82  }
83  else
84  {
85  auto vertices_range = CGAL::vertices_around_target(v, g); // works with two-manifold data structures
86  for (auto v_adj : vertices_range) {
87  auto it_res = processed_vertices.find(v_adj);
88  if ((it_res != processed_vertices.end()) && it_res->second)
89  continue;
90  else {
91  if (it_res != processed_vertices.end())
92  it_res->second = true;
93  else
94  processed_vertices[v_adj] = true;
95  adjacent_vertices.push_back(v_adj);
96  }
97  }
98  }
99  return adjacent_vertices;
100  }
101 
113  template< typename GeometryTraits >
114  double neighbor_regularity( const typename GeometryTraits::Point& v_s_pos,
115  const typename GeometryTraits::Point& v_t_pos,
116  const typename GeometryTraits::Point& v_s_t_kept_neighbor_pos,
117  const GeometryTraits& gt)
118  {
119  double prec = 1e-8;
120  double perim = FEVV::Operators::Geometry::triangle_perimeter<GeometryTraits>(v_s_t_kept_neighbor_pos, v_s_pos, v_t_pos, gt);
121  double area = 0.;
122  if (gt.length(v_s_pos, v_t_pos) < prec)
123  {
124  area = 0.f;
125  }
126  else
127  area = FEVV::Operators::Geometry::triangle_area<GeometryTraits>(v_s_t_kept_neighbor_pos, v_s_pos, v_t_pos, gt);
128  double res = ((perim < prec)? area:area/perim);
129  static double min_res = 0., max_res = 1024. * 2.;
130  size_t nb_bit_quantization = static_cast<size_t>(log2(max_res) + 2);
131  if (max_res < res)
132  {
133  max_res = res;
134  std::cout << "max_res = " << max_res << std::endl;
135  }
136  if (nb_bit_quantization > 32)
137  nb_bit_quantization = 32;
138  size_t two_power_nb_bit = std::pow(2, nb_bit_quantization);
139  double delta = (max_res - min_res) / two_power_nb_bit;
140 
141  res = std::floor(res / delta) * delta + 0.5 * delta;
142 
143  return res;
144  }
145 
147  template<typename Graph, typename PointMap, typename GeometryTraits = FEVV::Geometry_traits<Graph> >
148  void
149  stable_sort_adjacent_vertices(const Graph& /*g*/,
150  const PointMap& pm,
152  std::list< typename boost::graph_traits<Graph>::vertex_descriptor>& adjacent2v,
153  const typename GeometryTraits::Point& v_s_pos,
154  const typename GeometryTraits::Point& v_t_pos,
155  const GeometryTraits& gt)
156  {
157  typedef boost::graph_traits<Graph> GraphTraits;
159  if (gt.length(v_s_pos, v_t_pos) > 1e-8)
160  { // sorting is done only when v_s_pos and v_t_pos are different from each other
161  std::map< vertex_descriptor, double > vertex_priority;
162 
163  auto it = adjacent2v.begin(), it_e = adjacent2v.end();
164  for (; it != it_e; ++it)
165  {
166  const auto& pos_n = get(pm, *it);
167  vertex_priority[*it] = neighbor_regularity(v_s_pos, v_t_pos, pos_n, gt);
168  }
169  adjacent2v.sort([&vertex_priority](vertex_descriptor v1, vertex_descriptor v2) {
170  return (vertex_priority[v1] > vertex_priority[v2]);
171  });
172  }
173  }
176  template<typename Graph, typename PointMap, typename GeometryTraits = FEVV::Geometry_traits<Graph> >
177  void
179  const PointMap& pm,
181  std::list< typename boost::graph_traits<Graph>::vertex_descriptor>& adjacent2v,
182  const GeometryTraits& gt)
183  {
184  typedef boost::graph_traits<Graph> GraphTraits;
186  typedef typename GraphTraits::halfedge_descriptor halfedge_descriptor;
187  // sorting is done only when v_s_pos and v_t_pos are different from each other
188  std::map< vertex_descriptor, double > vertex_priority;
189 
190  // 1) Search for the two furthest vertices
191  vertex_descriptor first = GraphTraits::null_vertex(), second = GraphTraits::null_vertex();
192  bool find_a_border = false;
193  double d_max = -1.0;
194  const auto& pos_v = get(pm, v);
195  auto it = adjacent2v.begin(), it_e = adjacent2v.end();
196  for (; it != it_e; ++it) // find the first intesting vertex (furthest from v) for the border case
197  {
198  halfedge_descriptor h = halfedge(*it, v, g).first;
199  if (CGAL::is_border(h, g))
200  find_a_border = true;
201  const auto& pos_n = get(pm, *it);
202  double d_tmp = gt.length(pos_v, pos_n);
203  if (d_tmp > d_max)
204  {
205  d_max = d_tmp;
206  first = *it;
207  }
208  }
209 
210  if (!find_a_border)
211  {
212  // for interior v search for the furthest 2 vertices
213  d_max = -1.0;
214  it = adjacent2v.begin();
215  for (; it != it_e; ++it)
216  {
217  const auto& pos_n1 = get(pm, *it);
218  auto it2 = it;
219  ++it2;
220  for (; it2 != it_e; ++it2)
221  {
222  const auto& pos_n2 = get(pm, *it2);
223  double d_tmp = gt.length(pos_n1, pos_n2);
224  if (d_tmp > d_max)
225  {
226  d_max = d_tmp;
227  first = *it;
228  second = *it2;
229  }
230  }
231  }
232  }
233  const auto& pos_first = get(pm, first);
234 
235  // 2) Compute the plane bisector a.x+b.y+c.z+d=0
236  const auto& pos_second = ((find_a_border)? pos_v :get(pm, second));
237  auto normal = gt.sub_p(pos_second, pos_first);
238  auto plane_point = ((find_a_border) ? pos_v:gt.add_pv(pos_first, gt.scalar_mult(normal, 0.5f)));
239  normal = gt.normalize(normal); // found (a,b,c)
240  //double d = -gt.dot_product(normal, gt.sub_p(plane_point,gt.ORIGIN));
241 
242  // 3) Compute the priority and then do a stable sort
243  it = adjacent2v.begin();
244  for (; it != it_e; ++it)
245  {
246  const auto& pos_n = get(pm, *it);
247  double d_tmp = std::abs( gt.dot_product(normal, gt.sub_p(pos_n, plane_point)) );
248  vertex_priority[*it] = -d_tmp; // the shortest distance, the higher the priority
249  }
250  adjacent2v.sort([&vertex_priority](vertex_descriptor v1, vertex_descriptor v2) {
251  return (vertex_priority[v1] > vertex_priority[v2]);
252  });
253 
254  }
255 
256  template <typename Graph, typename PointMap, typename GeometryTraits = FEVV::Geometry_traits<Graph> >
258  {
259  public:
260  typedef std::size_t IndexType;
265 
266  typedef boost::graph_traits<Graph> GraphTraits;
268  typedef typename GraphTraits::edge_descriptor edge_descriptor;
269  typedef typename GeometryTraits::Scalar Scalar;
270  typedef typename GeometryTraits::Point Point;
271  private:
272  const Graph& _g;
273  const PointMap& _pm;
274  const GeometryTraits _gt;
275  VertexIndexMapType _vim_st; // spanning tree vertex indices (different from current mesh vertex indices)
276  EdgeIndexMapType _eim_st; // spanning tree edge indices
277 
278  std::list<vertex_descriptor> _first_vertex_of_each_component;
279  std::list<vertex_descriptor> _st_vertices;
280  std::list<edge_descriptor> _st_edges;
281  std::set<edge_descriptor> _has_been_added; // to speed up requests on added edges to the spanning tree
282 
284  // with vertex degree, then mean of
285  // adjacent vertex degree
286 
287  // Tie-break management
288  bool _vertex_tie_break_detected; // will be a root tie-break for 2-manifold meshes
290  std::set<vertex_descriptor> _tie_break_vertices; // use set to make sure each tie-break vertex
291  // will be processed only once
292  void compute_first_vertex_connected_component(bool tie_break_detection)
293  {
296  _tie_break_vertices.clear();
298  auto vertices_range_pair = vertices(_g);
299  std::set<vertex_descriptor> remaining_mesh_vertices(vertices_range_pair.first, vertices_range_pair.second);
301  // Extraction of connected components
302  std::list< std::list<vertex_descriptor> > connected_components;
303  if (!remaining_mesh_vertices.empty())
304  {
305  do
306  {
307  std::map< vertex_descriptor, bool > already_stacked;
308  std::list<vertex_descriptor> component; // current connected component
309  vertex_descriptor v_current = *(remaining_mesh_vertices.begin());
310 
311  {
312  std::list< vertex_descriptor > list_v_around = get_adjacent_vertices(v_current, _g);
313 
314  // check if v_current is an isolated vertex (should not happen)
315  if (list_v_around.empty())
316  {
317  already_stacked[v_current] = true;
318  component.push_back(v_current);
319  remaining_mesh_vertices.erase(v_current);
320  }
321  else
322  {
323  std::stack<vertex_descriptor> component_stack;
324  component_stack.push(v_current);
325 
326  while (!component_stack.empty())
327  {
328  vertex_descriptor v = component_stack.top();
329  component_stack.pop();
330 
331  already_stacked[v] = true;
332  component.push_back(v); // v is added to current connected component
333 
334  list_v_around = get_not_processed_adjacent_vertices(v, _g, already_stacked, edge(GraphTraits::null_halfedge(), _g));
335  //list_v_around = get_adjacent_vertices(v, _g);
336  for (auto v_around : list_v_around)
337  {
338  typename std::set<vertex_descriptor>::iterator it = remaining_mesh_vertices.find(v_around);
339  if (it != remaining_mesh_vertices.end()) // vertex has not been inserted yet
340  {
341  already_stacked[v_around] = true;
342  component_stack.push(v_around);
343  }
344  else
345  continue;
346  }
347 
348  remaining_mesh_vertices.erase(v); // v is removed from remaining vertices
349  }
350  }
351  }
352 
353  connected_components.push_back(component);
354  component.clear();
355  } while (!remaining_mesh_vertices.empty());
356  }
358  // for each component, find its vertex with smallest coordinates
359  typename std::list< std::list<vertex_descriptor> >::iterator it_list = connected_components.begin();
360  for (; it_list != connected_components.end(); ++it_list)
361  {
362  assert(!it_list->empty());
363  auto iter_v = it_list->begin(),
364  iter_v_e = it_list->end();
365  vertex_descriptor best_root = *iter_v; // Must select the vertex with min coordinates as root to ensure the same MST construction
366  // if several root exist (2 or more min coord vertices), write a warning
367  ++iter_v;
368  for (; iter_v != iter_v_e; ++iter_v)
369  {
370  if (_cmp_v(*iter_v, best_root))
371  {
372  best_root = *iter_v;
373  }
374  }
375  if (tie_break_detection) {
376  iter_v = it_list->begin();
377  while (iter_v != iter_v_e)
378  {
379  if ((*iter_v != best_root) && !_cmp_v(*iter_v, best_root) && !_cmp_v(best_root, *iter_v))
380  {
382  _tie_break_vertices.insert(best_root);
383 
384  std::list<vertex_descriptor> root_candidates;
385  while (iter_v != iter_v_e)
386  {
387  if (*iter_v != best_root)
388  {
389  if (!_cmp_v(*iter_v, best_root) && !_cmp_v(best_root, *iter_v))
390  _tie_break_vertices.insert(*iter_v);
391  else
392  {
393  auto iter_v2 = iter_v;
394  ++iter_v2;
395 
396  while (iter_v2 != iter_v_e)
397  {
398  //while ((iter_v2 != iter_v_e) && (!_cmp_v(*iter_v2, best_root) && !_cmp_v(best_root, *iter_v2))) ++iter_v2; // not needed
399 
400  if ((iter_v2 != iter_v_e) && (!_cmp_v(*iter_v, *iter_v2) && !_cmp_v(*iter_v2, *iter_v)))
401  {
402  _tie_break_vertices.insert(*iter_v);
403  while (iter_v2 != iter_v_e)
404  {
405  if (!_cmp_v(*iter_v, *iter_v2) && !_cmp_v(*iter_v2, *iter_v))
406  _tie_break_vertices.insert(*iter_v2);
407  ++iter_v2;
408  }
409  break;
410  }
411  ++iter_v2;
412  }
413  if (iter_v2 == iter_v_e)
414  root_candidates.push_back(*iter_v); // no tie-break for this candidate
415  }
416  }
417  ++iter_v;
418  }
419  root_candidates.sort(_cmp_v);
420  if (!root_candidates.empty())
421  best_root = *(root_candidates.begin());
422  else
423  {
424  std::cerr << "Spanning_tree_vertex_edge_comparator: compute_first_vertex_connected_component (find the root(s)): tie-break detected!" << std::endl;
425  }
426  break;
427  }
428  else
429  ++iter_v;
430  }
431  }
433  _first_vertex_of_each_component.push_back(best_root);
434 
435  }
437  // order all the smallest vertices
438  _first_vertex_of_each_component.sort(_cmp_v); // (stable sorting: https://www.cplusplus.com/reference/list/list/sort/)
439  }
440 
441  void compute_st(bool tie_break_detection)
442  {
443  compute_first_vertex_connected_component(tie_break_detection);
444 
445  auto vertices_range_pair = vertices(_g);
446  auto vi = vertices_range_pair.first;
447  auto vi_end = vertices_range_pair.second;
449  std::map<vertex_descriptor, bool> processed_vertices;
450  for (; vi != vi_end; ++vi)
451  processed_vertices.insert(std::make_pair(*vi, false));
453  auto edges_range_pair = edges(_g);
454  auto iter_e = edges_range_pair.first;
455  auto dist = std::distance(edges_range_pair.first, edges_range_pair.second);
456  for( ;iter_e != edges_range_pair.second; ++iter_e)
457  put(_eim_st, *iter_e, dist);
459  auto it_root_vertices = _first_vertex_of_each_component.begin(),
460  it_root_vertices_e = _first_vertex_of_each_component.end();
461  _st_vertices.clear(); _st_edges.clear(); _has_been_added.clear();
462  _st_vertices.push_back(*it_root_vertices);
463  processed_vertices.find(*it_root_vertices)->second = true;
464  auto current_st_it = _st_vertices.begin();
465  IndexType cpt = 0, cpt_e=0;
466  bool first = true;
467  for (; it_root_vertices != it_root_vertices_e; ++it_root_vertices)
468  {
469  vertex_descriptor current_v = *it_root_vertices;
470  assert(current_v != GraphTraits::null_vertex());
471  if (!first)
472  {
473  _st_vertices.push_back(current_v);
474  processed_vertices.find(current_v)->second = true;
475  }
476  else
477  first = false;
478 
479  do
480  {
481  // get one ring adjacent vertices
482  // make sure min edge ordering of adjacent vertices is used
483  // indeed, min edge index ordering is not sensitive to tie_break in 2-manifold
484  std::list<vertex_descriptor> adjacent_vertices =
485  get_not_processed_adjacent_vertices(current_v, _g, processed_vertices,
486  //this->get_spanning_tree_min_incident_edge(current_v) // can be an issue
487  this->get_spanning_tree_min_index_incident_edge(current_v) // avoid tie-break issue for 2-manifold (but not for a root and its adjacent vertices)
488  );
489  if (!adjacent_vertices.empty())
490  {
491  if (degree(current_v, _g) == adjacent_vertices.size())
492  { // case of a new region growing start
493  adjacent_vertices.sort(_cmp_v); // can be an issue if 2 adjacent vertices have the same coordinates +
494  // same degree + same mean degree of adjacent vertices
495  // (stable sorting: https://www.cplusplus.com/reference/list/list/sort/)
496  if (tie_break_detection) {
497  auto it_v_debug = adjacent_vertices.begin(), it_v_debug_e = adjacent_vertices.end();
498  for (; it_v_debug != it_v_debug_e; ++it_v_debug)
499  {
500  auto it_v2_debug = it_v_debug;
501  if (it_v2_debug != it_v_debug_e)
502  ++it_v2_debug;
503  else
504  continue;
505  if ((it_v2_debug != it_v_debug_e) && !_cmp_v(*it_v_debug, *it_v2_debug) && !_cmp_v(*it_v2_debug, *it_v_debug))
506  {
508  _tie_break_vertices.insert(*it_v_debug);
509  for (; it_v2_debug != it_v_debug_e; ++it_v2_debug)
510  {
511  if (!_cmp_v(*it_v_debug, *it_v2_debug) && !_cmp_v(*it_v2_debug, *it_v_debug))
512  {
513  _tie_break_vertices.insert(*it_v2_debug);
514  std::cerr << "Spanning_tree_vertex_edge_comparator: compute_st: new region growing start: tie-break detected!" << std::endl;
515  }
516  else
517  break;
518  }
519  }
520  else
521  break;
522  }
523  }
524  }
525  // update spanning tree vertices
526  _st_vertices.insert(_st_vertices.end(), adjacent_vertices.begin(), adjacent_vertices.end());
527  // update spanning tree edges
528  auto it_v = adjacent_vertices.begin(), it_v_e = adjacent_vertices.end();
529  //std::cout << "START debug adjacent_vertices" << std::endl;
530  for (; it_v != it_v_e; ++it_v)
531  {
532  //std::cout << "(" << get(_pm, *it_v) << ") ;";
533  auto res = edge(current_v, *it_v, _g);
534  if (res.second)
535  {
536  put(_eim_st, res.first, cpt_e++);
537  _st_edges.push_back(res.first);
538  _has_been_added.insert(res.first);
539  }
540  }
541  //std::cout << "\n END debug adjacent_vertices" << std::endl;
542  adjacent_vertices.clear();
543  }
544  put(_vim_st, *current_st_it, cpt++);
545  ++current_st_it;
546  if (current_st_it == _st_vertices.end())
547  {
548  --current_st_it;
549  break;
550  }
551 
552  current_v = *current_st_it;
553  } while (true);
554  }
555  }
556  public:
557  Spanning_tree_vertex_edge_comparator(const Graph& g, const PointMap& pm, bool tie_break_detection=true) :_g(g),
558  _pm(pm),
559  _gt(GeometryTraits(g)),
561  _st_vertices(),
562  _st_edges(),
563  _has_been_added(),
564  _cmp_v(FEVV::Comparator::get_vertex_comparator<Graph, PointMap, GeometryTraits>(g, pm)),
570  compute_st(tie_break_detection); }
571  Spanning_tree_vertex_edge_comparator(const Graph& g, const PointMap& pm, bool tie_break_detection, const GeometryTraits& gt) :_g(g),
572  _pm(pm),
573  _gt(gt),
575  _st_vertices(),
576  _st_edges(),
577  _has_been_added(),
578  _cmp_v(g, pm, gt),
584  compute_st(tie_break_detection); }
586  {
587  if (v1 == v2)
588  return false;
589  return get(_vim_st, v1) < get(_vim_st, v2);
590  }
591 
593  {
594  if (e1 == e2)
595  return false;
596 
597  if(_has_been_added.find(e1) == _has_been_added.end())
598  return false;
599  if (_has_been_added.find(e2) == _has_been_added.end())
600  return false;
601 
602  return get(_eim_st, e1) < get(_eim_st, e2);
603  }
604 
605 
606  const std::list<vertex_descriptor>& get_first_vertex_of_each_component() const { return _first_vertex_of_each_component; }
608  const std::list<vertex_descriptor>& get_spanning_tree_vertices() const { return _st_vertices; }
609  const std::list<edge_descriptor>& get_spanning_tree_edges() const { return _st_edges; }
612  {
613  if (degree(v, _g) == 0)
614  return edge(GraphTraits::null_halfedge(), _g); // GraphTraits::null_edge() is not defined for all mesh data structures
615 
616  std::list< vertex_descriptor >&& list_v_around = get_adjacent_vertices(v, _g);
617  vertex_descriptor min_v = *std::min_element(list_v_around.begin(), list_v_around.end(), _cmp_v);
618  auto pair_e_bool = edge(min_v, v, _g);
619  return pair_e_bool.first;
620  }
625  {
626  if (degree(v, _g) == 0)
627  return edge(GraphTraits::null_halfedge(), _g); // GraphTraits::null_edge() is not defined for all mesh data structures
628 
629  edge_descriptor selected_min_edge = edge(GraphTraits::null_halfedge(), _g);
630  std::list< vertex_descriptor >&& list_v_around = get_adjacent_vertices(v, _g);
631  auto it_v = list_v_around.begin(),
632  it_v_e = list_v_around.end();
633  for (; it_v != it_v_e; ++it_v)
634  {
635  auto pair_e_bool = edge(v, *it_v, _g);
636  if ( _has_been_added.find( pair_e_bool.first ) != _has_been_added.end() )
637  {
638  if (selected_min_edge == edge(GraphTraits::null_halfedge(), _g))
639  selected_min_edge = pair_e_bool.first;
640  else if (get(_eim_st, pair_e_bool.first) < get(_eim_st, selected_min_edge))
641  selected_min_edge = pair_e_bool.first;
642  }
643  }
644  if (selected_min_edge == edge(GraphTraits::null_halfedge(), _g))
646  else
647  return selected_min_edge;
648  }
649  const Graph &get_spanning_tree_input_graph() const { return _g; }
650  const PointMap &get_spanning_tree_vertex_point_map() const { return _pm; }
653 
656  }
657  const std::set<vertex_descriptor>& get_tie_break_vertices() const { return _tie_break_vertices; }
658  };
660  template <typename Graph, typename PointMap, typename GeometryTraits = FEVV::Geometry_traits<Graph> >
661  static
662  Spanning_tree_vertex_edge_comparator<Graph, PointMap, GeometryTraits>
663  get_spanning_tree_comparator(const Graph& g, const PointMap& pm, bool tie_break_detection=true) { return Spanning_tree_vertex_edge_comparator<Graph, PointMap, GeometryTraits>(g, pm, tie_break_detection); }
664 } // namespace Comparator
665 } // namespace FEVV
666 
FEVV::DataStructures::AIF::vertices
std::pair< typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::vertex_iterator, typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::vertex_iterator > vertices(const FEVV::DataStructures::AIF::AIFMesh &sm)
Returns the iterator range of the vertices of the mesh.
Definition: Graph_traits_aif.h:172
FEVV::Comparator::Spanning_tree_vertex_edge_comparator::_vertex_tie_break_detected
bool _vertex_tie_break_detected
Definition: Spanning_tree_vertex_edge_comparator.hpp:288
FEVV::Comparator::Spanning_tree_vertex_edge_comparator::get_nb_of_connected_components
size_t get_nb_of_connected_components() const
Definition: Spanning_tree_vertex_edge_comparator.hpp:607
FEVV::Comparator::Spanning_tree_vertex_edge_comparator::get_tie_break_vertices
const std::set< vertex_descriptor > & get_tie_break_vertices() const
Definition: Spanning_tree_vertex_edge_comparator.hpp:657
FEVV::Comparator::Spanning_tree_vertex_edge_comparator::_gt
const GeometryTraits _gt
Definition: Spanning_tree_vertex_edge_comparator.hpp:274
FEVV::DataStructures::AIF::next
boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::halfedge_descriptor next(typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::halfedge_descriptor h, const FEVV::DataStructures::AIF::AIFMesh &sm)
Returns the next halfedge around its face.
Definition: Graph_traits_aif.h:599
FEVV::DataStructures::AIF::degree
boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::degree_size_type degree(typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::vertex_descriptor u, const FEVV::DataStructures::AIF::AIFMesh &)
Definition: Graph_traits_aif.h:548
FEVV::Comparator::get_vertex_comparator
static Vertex_comparator< Graph, PointMap, GeometryTraits > get_vertex_comparator(const Graph &g, const PointMap &pm)
Definition: Vertex_comparators.hpp:114
FEVV::Comparator::Spanning_tree_vertex_edge_comparator::get_spanning_tree_vertex_index_map
const VertexIndexMapType & get_spanning_tree_vertex_index_map() const
Definition: Spanning_tree_vertex_edge_comparator.hpp:652
FEVV::Comparator::Spanning_tree_vertex_edge_comparator::_st_vertices
std::list< vertex_descriptor > _st_vertices
the first vertex of each connected component
Definition: Spanning_tree_vertex_edge_comparator.hpp:279
FEVV::Comparator::Spanning_tree_vertex_edge_comparator::Spanning_tree_vertex_edge_comparator
Spanning_tree_vertex_edge_comparator(const Graph &g, const PointMap &pm, bool tie_break_detection=true)
Definition: Spanning_tree_vertex_edge_comparator.hpp:557
FEVV::Comparator::get_adjacent_vertices
std::list< typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::vertex_descriptor > get_adjacent_vertices(typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::vertex_descriptor v, const FEVV::DataStructures::AIF::AIFMesh &)
Definition: Spanning_tree_vertex_edge_comparator.hpp:28
FEVV::Comparator::Spanning_tree_vertex_edge_comparator::_tie_break_vertices
std::set< vertex_descriptor > _tie_break_vertices
Definition: Spanning_tree_vertex_edge_comparator.hpp:290
FEVV::Comparator::Spanning_tree_vertex_edge_comparator::_st_edges
std::list< edge_descriptor > _st_edges
all vertices in the spanning tree order of traversal
Definition: Spanning_tree_vertex_edge_comparator.hpp:280
FEVV::Comparator::Spanning_tree_vertex_edge_comparator::get_spanning_tree_min_incident_edge
edge_descriptor get_spanning_tree_min_incident_edge(vertex_descriptor v) const
returns the min incident edge according to Vertex_comparator
Definition: Spanning_tree_vertex_edge_comparator.hpp:611
FEVV::DataStructures::AIF::edges
std::pair< typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::edge_iterator, typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::edge_iterator > edges(const FEVV::DataStructures::AIF::AIFMesh &sm)
Returns the iterator range of the edges of the mesh.
Definition: Graph_traits_aif.h:238
FEVV::Comparator::Spanning_tree_vertex_edge_comparator::vertex_descriptor
GraphTraits::vertex_descriptor vertex_descriptor
Definition: Spanning_tree_vertex_edge_comparator.hpp:267
FEVV::Comparator::Spanning_tree_vertex_edge_comparator::_eim_st
EdgeIndexMapType _eim_st
Definition: Spanning_tree_vertex_edge_comparator.hpp:276
FEVV::Edge_pmap_traits::create
static pmap_type create(const MeshT &)
Definition: properties.h:349
FEVV::Comparator::Spanning_tree_vertex_edge_comparator::GraphTraits
boost::graph_traits< Graph > GraphTraits
Definition: Spanning_tree_vertex_edge_comparator.hpp:266
FEVV::Comparator::Vertex_comparator
Definition: Vertex_comparators.hpp:26
FEVV::DataStructures::AIF::opposite
boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::halfedge_descriptor opposite(typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::halfedge_descriptor h, const FEVV::DataStructures::AIF::AIFMesh &sm)
Returns the halfedge with source and target swapped.
Definition: Graph_traits_aif.h:625
FEVV::Comparator::Spanning_tree_vertex_edge_comparator::_min_edge_tie_break_detected
bool _min_edge_tie_break_detected
Definition: Spanning_tree_vertex_edge_comparator.hpp:289
FEVV::Comparator::Spanning_tree_vertex_edge_comparator::Spanning_tree_vertex_edge_comparator
Spanning_tree_vertex_edge_comparator(const Graph &g, const PointMap &pm, bool tie_break_detection, const GeometryTraits &gt)
Definition: Spanning_tree_vertex_edge_comparator.hpp:571
Point
AIFMesh::Point Point
Definition: Graph_properties_aif.h:21
FEVV::Comparator::Spanning_tree_vertex_edge_comparator::Point
GeometryTraits::Point Point
Definition: Spanning_tree_vertex_edge_comparator.hpp:270
FEVV::Comparator::Spanning_tree_vertex_edge_comparator::EdgeIndexMapType
FEVV::Edge_pmap_traits< Graph, IndexType >::pmap_type EdgeIndexMapType
Definition: Spanning_tree_vertex_edge_comparator.hpp:264
FEVV::Comparator::Spanning_tree_vertex_edge_comparator::_has_been_added
std::set< edge_descriptor > _has_been_added
all edges in the spanning tree order of traversal
Definition: Spanning_tree_vertex_edge_comparator.hpp:281
FEVV::Comparator::Spanning_tree_vertex_edge_comparator::get_spanning_tree_vertices
const std::list< vertex_descriptor > & get_spanning_tree_vertices() const
Definition: Spanning_tree_vertex_edge_comparator.hpp:608
FEVV::DataStructures::AIF::source
boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::vertex_descriptor source(typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::edge_descriptor e, const FEVV::DataStructures::AIF::AIFMesh &)
Returns the source vertex of e.
Definition: Graph_traits_aif.h:387
FEVV::Vertex_pmap_traits::create
static pmap_type create(const MeshT &)
Definition: properties.h:321
FEVV::DataStructures::AIF::edge
boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::edge_descriptor edge(typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::halfedge_descriptor h, const FEVV::DataStructures::AIF::AIFMesh &sm)
Returns the edge corresponding to h and opposite(h).
Definition: Graph_traits_aif.h:345
FEVV::Assoc_property_map
Definition: properties.h:236
FEVV::get
FEVV::PCLPointCloudPointMap::value_type get(const FEVV::PCLPointCloudPointMap &pm, FEVV::PCLPointCloudPointMap::key_type key)
Specialization of get(point_map, key) for PCLPointCloud.
Definition: Graph_properties_pcl_point_cloud.h:117
FEVV::Comparator::Spanning_tree_vertex_edge_comparator
Definition: Spanning_tree_vertex_edge_comparator.hpp:258
FEVV
Interfaces for plugins These interfaces will be used for different plugins.
Definition: Assert.h:16
FEVV::Comparator::Spanning_tree_vertex_edge_comparator::_first_vertex_of_each_component
std::list< vertex_descriptor > _first_vertex_of_each_component
Definition: Spanning_tree_vertex_edge_comparator.hpp:278
FEVV::Comparator::Spanning_tree_vertex_edge_comparator::get_spanning_tree_min_index_incident_edge
edge_descriptor get_spanning_tree_min_index_incident_edge(vertex_descriptor v) const
Definition: Spanning_tree_vertex_edge_comparator.hpp:624
FEVV::Comparator::get_spanning_tree_comparator
static Spanning_tree_vertex_edge_comparator< Graph, PointMap, GeometryTraits > get_spanning_tree_comparator(const Graph &g, const PointMap &pm, bool tie_break_detection=true)
Definition: Spanning_tree_vertex_edge_comparator.hpp:663
FEVV::DataStructures::AIF::halfedge
boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::halfedge_descriptor halfedge(typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::vertex_descriptor v, const FEVV::DataStructures::AIF::AIFMesh &sm)
Returns a halfedge with target v.
Definition: Graph_traits_aif.h:296
FEVV::Comparator::Spanning_tree_vertex_edge_comparator::edge_descriptor
GraphTraits::edge_descriptor edge_descriptor
Definition: Spanning_tree_vertex_edge_comparator.hpp:268
FEVV::DataStructures::AIF::target
boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::vertex_descriptor target(typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::edge_descriptor e, const FEVV::DataStructures::AIF::AIFMesh &)
Returns the target vertex of e.
Definition: Graph_traits_aif.h:400
FEVV::Comparator::Spanning_tree_vertex_edge_comparator::get_spanning_tree_edges
const std::list< edge_descriptor > & get_spanning_tree_edges() const
Definition: Spanning_tree_vertex_edge_comparator.hpp:609
FEVV::Comparator::Spanning_tree_vertex_edge_comparator::get_tie_break_detected_after_spanning_tree_computation
bool get_tie_break_detected_after_spanning_tree_computation() const
Definition: Spanning_tree_vertex_edge_comparator.hpp:654
FEVV::Comparator::Spanning_tree_vertex_edge_comparator::VertexIndexMapType
FEVV::Vertex_pmap_traits< Graph, IndexType >::pmap_type VertexIndexMapType
Definition: Spanning_tree_vertex_edge_comparator.hpp:262
FEVV::Comparator::Spanning_tree_vertex_edge_comparator::IndexType
std::size_t IndexType
Definition: Spanning_tree_vertex_edge_comparator.hpp:260
FEVV::Comparator::Spanning_tree_vertex_edge_comparator::operator()
bool operator()(edge_descriptor e1, edge_descriptor e2) const
Definition: Spanning_tree_vertex_edge_comparator.hpp:592
triangles.hpp
FEVV::Comparator::neighbor_regularity
double neighbor_regularity(const typename GeometryTraits::Point &v_s_pos, const typename GeometryTraits::Point &v_t_pos, const typename GeometryTraits::Point &v_s_t_kept_neighbor_pos, const GeometryTraits &gt)
Compute the regularity/priority of a neighbor/adjacent point. To use to identify pivot points.
Definition: Spanning_tree_vertex_edge_comparator.hpp:114
FEVV::Comparator::Spanning_tree_vertex_edge_comparator::compute_first_vertex_connected_component
void compute_first_vertex_connected_component(bool tie_break_detection)
Definition: Spanning_tree_vertex_edge_comparator.hpp:292
Vertex_comparators.hpp
FEVV::Comparator::Spanning_tree_vertex_edge_comparator::compute_st
void compute_st(bool tie_break_detection)
Definition: Spanning_tree_vertex_edge_comparator.hpp:441
FEVV::Comparator::Spanning_tree_vertex_edge_comparator::_pm
const PointMap & _pm
Definition: Spanning_tree_vertex_edge_comparator.hpp:273
FEVV::Comparator::Spanning_tree_vertex_edge_comparator::get_spanning_tree_vertex_index
IndexType get_spanning_tree_vertex_index(const vertex_descriptor v) const
Definition: Spanning_tree_vertex_edge_comparator.hpp:651
msdm2::vertex_descriptor
boost::graph_traits< MeshT >::vertex_descriptor vertex_descriptor
Definition: msdm2_surfacemesh.h:33
FEVV::DataStructures::AIF::adjacent_vertices
std::pair< typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::adjacency_iterator, typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::adjacency_iterator > adjacent_vertices(typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::vertex_descriptor v, const FEVV::DataStructures::AIF::AIFMesh &)
Definition: Graph_traits_aif.h:217
FEVV::Comparator::Spanning_tree_vertex_edge_comparator::get_spanning_tree_input_graph
const Graph & get_spanning_tree_input_graph() const
Definition: Spanning_tree_vertex_edge_comparator.hpp:649
FEVV::put
void put(FEVV::PCLPointCloudPointMap &pm, FEVV::PCLPointCloudPointMap::key_type key, const FEVV::PCLPointCloudPointMap::value_type &value)
Specialization of put(point_map, key, value) for PCLPointCloud.
Definition: Graph_properties_pcl_point_cloud.h:126
FEVV::Comparator::Spanning_tree_vertex_edge_comparator::_g
const Graph & _g
Definition: Spanning_tree_vertex_edge_comparator.hpp:272
FEVV::Comparator::get_not_processed_adjacent_vertices
std::list< typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::vertex_descriptor > get_not_processed_adjacent_vertices(typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::vertex_descriptor v, const FEVV::DataStructures::AIF::AIFMesh &g, std::map< typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::vertex_descriptor, bool > &processed_vertices, typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::edge_descriptor min_e)
Definition: Spanning_tree_vertex_edge_comparator.hpp:38
FEVV::Comparator::Spanning_tree_vertex_edge_comparator::Scalar
GeometryTraits::Scalar Scalar
Definition: Spanning_tree_vertex_edge_comparator.hpp:269
FEVV::Comparator::Spanning_tree_vertex_edge_comparator::get_spanning_tree_vertex_point_map
const PointMap & get_spanning_tree_vertex_point_map() const
Definition: Spanning_tree_vertex_edge_comparator.hpp:650
FEVV::Comparator::stable_sort_adjacent_vertices
void stable_sort_adjacent_vertices(const Graph &, const PointMap &pm, typename boost::graph_traits< Graph >::vertex_descriptor, std::list< typename boost::graph_traits< Graph >::vertex_descriptor > &adjacent2v, const typename GeometryTraits::Point &v_s_pos, const typename GeometryTraits::Point &v_t_pos, const GeometryTraits &gt)
stable_sort_adjacent_vertices based on true source and target positions
Definition: Spanning_tree_vertex_edge_comparator.hpp:149
FEVV::Comparator::Spanning_tree_vertex_edge_comparator::get_first_vertex_of_each_component
const std::list< vertex_descriptor > & get_first_vertex_of_each_component() const
Definition: Spanning_tree_vertex_edge_comparator.hpp:606
FEVV::Comparator::Spanning_tree_vertex_edge_comparator::operator()
bool operator()(vertex_descriptor v1, vertex_descriptor v2) const
Definition: Spanning_tree_vertex_edge_comparator.hpp:585
FEVV::Comparator::Spanning_tree_vertex_edge_comparator::_vim_st
VertexIndexMapType _vim_st
Definition: Spanning_tree_vertex_edge_comparator.hpp:275
FEVV::Comparator::Spanning_tree_vertex_edge_comparator::_cmp_v
FEVV::Comparator::Vertex_comparator< Graph, PointMap, GeometryTraits > _cmp_v
Definition: Spanning_tree_vertex_edge_comparator.hpp:283