MeVisLab Toolbox Reference
mlGraphToBoostGraph.h
Go to the documentation of this file.
1 /*************************************************************************************
2 **
3 ** Copyright 2012, MeVis Medical Solutions AG
4 **
5 ** The user may use this file in accordance with the license agreement provided with
6 ** the Software or, alternatively, in accordance with the terms contained in a
7 ** written agreement between the user and MeVis Medical Solutions AG.
8 **
9 ** For further information use the contact form at https://www.mevislab.de/contact
10 **
11 **************************************************************************************/
12 
13 #ifndef ML_GRAPH_TO_BOOST_GRAPH_H
14 #define ML_GRAPH_TO_BOOST_GRAPH_H
15 
16 
18 
19 #include <iterator>
20 #include <boost/version.hpp>
21 #include <boost/config.hpp>
22 #include <boost/operators.hpp>
23 #include <boost/graph/graph_traits.hpp>
24 #include <boost/graph/properties.hpp>
25 #include <boost/property_map/property_map.hpp>
26 
27 #include "mlGraphComponents.h"
28 #include "mlGraph.h"
29 #include <mlVesselEdge.h>
30 
32 //
33 // Functions and traits for the plain ml::Graph class
34 //
36 
38 class ml_vertex_iterator;
39 
41 typedef ml::Graph* ml_graph_ptr;
42 
43 namespace boost {
44 
45  // typedef const UndirectedVesselGraph* ml_const_uv_graph_ptr;
46 
56  public virtual incidence_graph_tag, // Graph is of type IncidenceGraph
57  // public virtual adjacency_graph_tag,
58  public virtual vertex_list_graph_tag // Graph is of type IncidenceGraph
59  { };
60 
61 
63  template <> struct graph_traits<ml_graph_ptr> {
64 
65  // --- typedefs for boost::Graph ---
66 
68  typedef ml::VesselNode* vertex_descriptor;
69 
71  typedef ml::VesselEdge* edge_descriptor;
72 
74  typedef directed_tag directed_category;
75 
79  typedef allow_parallel_edge_tag edge_parallel_category;
80 
83 
84  // --- typedefs for boost::IncidenceGraph ---
85 
88  typedef long degree_size_type;
89 
90  // An out-edge iterator for a vertex v provides access to the out-edges of the vertex. As such,
91  // the value type of an out-edge iterator is the edge descriptor type of its graph.
93 
94  // --- typedefs for boost::VertexListGraph ---
95 
98  typedef ml::Graph::NodeIterator vertex_iterator;
99 
101  typedef long vertices_size_type;
102 
103  // to do: add missing functions/traits for other boost graph models
104  /*
105  typedef void in_edge_iterator;
106  typedef sgb_adj_iterator adjacency_iterator;
107  typedef void edge_iterator;
108  typedef long edge_size_type;
109  */
110  };
111 
112 
113 
114 } // namespace boost
115 
116 
117 // Iterator class to iterate over all out edges of a vertex (out_edge_iterator)
118 
119 // ml::VesselNode stores all edges in a std::vector but has no information which edges are
120 // directed from this node to another; this must be looked up in the edges itself
121 // see comment at out_edges
122 class ml_out_edge_iterator : public boost::forward_iterator_helper<
123  ml_out_edge_iterator, // operand type
124  ml::VesselEdge*, // value type
125  std::ptrdiff_t, // difference type
126  ml::VesselEdge**, // pointer type
127  ml::VesselEdge*> // reference type
128 {
129 
130 typedef ml_out_edge_iterator self;
131 
132 public:
133 
135 
136  ml_out_edge_iterator(ml::VesselNode* vertex,
137  std::vector<ml::VesselEdge*>::iterator edgeIter,
138  std::vector<ml::VesselEdge*>::iterator edgeIterEnd)
139  :_vertex(vertex)
140  ,_edgeIter(edgeIter),
141  _edgeIterEnd(edgeIterEnd)
142  {
143  // set edgeIter to first out edge, skip all edges which predecessor is
144  // not the vertex
145  while ( (_edgeIter!=_edgeIterEnd) &&
146  !((*_edgeIter)->isPred(_vertex)) )
147  {
148  ++_edgeIter;
149  }
150  }
151 
152  ml::VesselEdge* operator*() { return *_edgeIter; }
153 
154  self& operator++()
155  {
156  do // skip in-edges
157  {
158  // must check if iterator is already at the end, otherwise loop might become endless
159  if (_edgeIter != _edgeIterEnd) { ++_edgeIter; };
160  }
161  while ( (_edgeIter != _edgeIterEnd) && !((*_edgeIter)->isPred(_vertex)) );
162  return *this;
163  }
164 
165  friend bool operator==(const self& x, const self& y) {
166  return x._edgeIter == y._edgeIter; }
167 
168 protected:
169  ml::VesselNode* _vertex;
170  std::vector<ml::VesselEdge*>::iterator _edgeIter;
171  std::vector<ml::VesselEdge*>::iterator _edgeIterEnd;
172 };
173 
174 
175 namespace boost {
176 
177  // --- functions required by boost::IncidenceGraph ---
178 
179 
183  const ml_graph_ptr)
184  {
185  return e->predNode();
186  }
187 
191  const ml_graph_ptr)
192  {
193  return e->succNode();
194  }
195 
208  inline std::pair<boost::graph_traits<ml_graph_ptr>::out_edge_iterator,
211  const ml_graph_ptr)
212  {
213  return std::make_pair(
214  ml_out_edge_iterator(vertex, vertex->edges()->begin(), vertex->edges()->end()),
215  ml_out_edge_iterator(vertex, vertex->edges()->end(), vertex->edges()->end()) );
216  }
217 
218 
224  const ml_graph_ptr )
225  {
227 
228  std::vector<ml::VesselEdge*>::iterator edgeIter = vertex->edges()->begin();
229  std::vector<ml::VesselEdge*>::iterator edgeIterEnd = vertex->edges()->end();
230 
231  while (edgeIter != edgeIterEnd)
232  {
233  if ((*edgeIter)->isPred(vertex))
234  {
235  ++count;
236  }
237  ++edgeIter;
238  }
239  return count;
240  }
241 
242 
243  // --- functions required by boost::VertexListGraph ---
244 
246  inline std::pair<boost::graph_traits<ml_graph_ptr>::vertex_iterator,
249  {
250  return std::make_pair( g->beginNode(),
251  g->endNode() );
252  }
253 
257  {
258  return static_cast<long> (g->numNodes());
259  }
260 
261 
265  {
266  return g->getNode(arrayIndex);
267  }
268 
269  // --- Property maps ---
270  // put_get_helper<class Reference, class LvaluePropertyMap> is a helper template which
271  // automatically generates the put() and get() functions for a property map
272 
275  class ml_vertex_id_map : public boost::put_get_helper<unsigned int, ml_vertex_id_map>
276  {
277  public:
278  // readonly property
279  typedef boost::readable_property_map_tag category;
280 
281  // vertex index is of type long
282  typedef unsigned int value_type;
283  typedef unsigned int reference;
284 
285  // key = Vertex
286  typedef ml::VesselNode* key_type;
287 
288  ml_vertex_id_map() : _g(nullptr) {}
290  unsigned int operator[](ml::VesselNode* vertex) const { return static_cast<unsigned int>(_g->getIndex(vertex)); }
291 
292  protected:
294  };
295 
298  inline ml_vertex_id_map get(vertex_index_t, ml_graph_ptr g)
299  {
300  return ml_vertex_id_map(g);
301  }
302 
303  // --- Property Map Traits classes ---
304  template<>
305  struct property_map<ml_graph_ptr, vertex_index_t>
306  {
309  };
310 
311 
312  class ml_edge_weight_map : public boost::put_get_helper<double, ml_edge_weight_map>
313  {
314  public:
315  // readonly property
316  typedef boost::lvalue_property_map_tag category;
317 
318  // vertex index is of type long
319  typedef double value_type;
320  using reference = double const&;
321 
322  // key = edge
323  typedef ml::VesselEdge* key_type;
324 
325  value_type operator[](ml::VesselEdge* edge) const {
326  std::cout << "edge.getWeight() = " << edge->getWeight() << std::endl;
327  return edge->getWeight();
328  }
329  };
330 
331  inline ml_edge_weight_map get(edge_weight_t, ml_graph_ptr)
332  {
333  return ml_edge_weight_map();
334  }
335 
336  // --- Property Map Traits classes ---
337  template<>
338  struct property_map<ml_graph_ptr, edge_weight_t>
339  {
342  };
343 
344 
345 } // namespace boost
346 
347 
348 
351 template<class T, class ValueType>
353 {
354  typedef T iterator_type;
355  typedef std::random_access_iterator_tag iterator_category;
356  typedef ValueType value_type;
357  typedef ptrdiff_t difference_type;
358  typedef ValueType* pointer;
359  typedef ValueType& reference;
360 };
361 
362 
363 namespace boost {
364 
379 template <class IteratorTraits, class IDMap>
381 {
382 public:
383 
384  typedef typename property_traits<IDMap>::key_type key_type;
385  typedef typename IteratorTraits::value_type value_type;
386  typedef typename IteratorTraits::value_type& reference;
387  typedef lvalue_property_map_tag category;
388 
392  ml_iterator_map(typename IteratorTraits::iterator_type i = IteratorTraits::iterator_type(),
393  const IDMap& id = IDMap())
394  : m_iter(i), m_id(id) { }
395  typename IteratorTraits::iterator_type m_iter;
396  IDMap m_id;
397 };
398 
399 // Next we implement the three property map functions, get(), put(), and at(). In each of the
400 // functions, the key object is converted to an integer offset using the m_id property map, and
401 // then that is used as an offset to the random access iterator m_iter.
402 
403 template <class IteratorTraits, class IDMap>
404 typename IteratorTraits::value_type
406  typename property_traits<IDMap>::key_type key)
407 {
408  return i.m_iter[i.m_id[key]];
409 }
410 template <class IteratorTraits, class IDMap>
411 void
413  typename property_traits<IDMap>::key_type key,
414  const typename IteratorTraits::value_type& value)
415 {
416  // std::cout << "put(" << key <<", " << value <<" )" << std::endl;
417  i.m_iter[i.m_id[key]] = value;
418 }
419 
420 template <class IteratorTraits, class IDMap>
421 typename IteratorTraits::value_type&
423  typename property_traits<IDMap>::key_type key)
424 {
425  return i.m_iter[i.m_id[key]];
426 }
427 
428 
429 
430 } // namespace boost
431 
432 
433 #endif
434 
@ T
Definition: SoKeyGrabber.h:71
value_type operator[](ml::VesselEdge *edge) const
boost::lvalue_property_map_tag category
This is a helper template to create an external property map for an std random access container.
property_traits< IDMap >::key_type key_type
ml_iterator_map(typename IteratorTraits::iterator_type i=IteratorTraits::iterator_type(), const IDMap &id=IDMap())
Constructor, takes an iterator to the beginning of a container, for example std::vector<>....
IteratorTraits::value_type value_type
IteratorTraits::iterator_type m_iter
lvalue_property_map_tag category
IteratorTraits::value_type & reference
Vertex id Maps each vertex to a unique id.
boost::readable_property_map_tag category
unsigned int operator[](ml::VesselNode *vertex) const
ml_vertex_id_map(ml_graph_ptr g)
std::vector< ml::VesselEdge * >::iterator _edgeIter
std::vector< ml::VesselEdge * >::iterator _edgeIterEnd
ml_out_edge_iterator(ml::VesselNode *vertex, std::vector< ml::VesselEdge * >::iterator edgeIter, std::vector< ml::VesselEdge * >::iterator edgeIterEnd)
friend bool operator==(const self &x, const self &y)
ml::VesselNode * _vertex
ml::VesselEdge * operator*()
ml::Graph * ml_graph_ptr
typedef for use with graph_traits<>
Forward declaration for the boost::mutex class.
void put(const ml_iterator_map< IteratorTraits, IDMap > &i, typename property_traits< IDMap >::key_type key, const typename IteratorTraits::value_type &value)
IteratorTraits::value_type & at(const ml_iterator_map< IteratorTraits, IDMap > &i, typename property_traits< IDMap >::key_type key)
boost::graph_traits< ml_graph_ptr >::vertex_descriptor vertex(boost::graph_traits< ml_graph_ptr >::degree_size_type arrayIndex, const ml_graph_ptr g)
Returns the vertex at internal index.
ml_vertex_id_map get(vertex_index_t, ml_graph_ptr g)
get() function for vertex id property map vertex_index_t just necessary for overloading
std::pair< boost::graph_traits< ml_graph_ptr >::out_edge_iterator, boost::graph_traits< ml_graph_ptr >::out_edge_iterator > out_edges(boost::graph_traits< ml_graph_ptr >::vertex_descriptor vertex, const ml_graph_ptr)
Returns an iterator-range providing access to the out-edges (for directed graphs) or incident edges (...
boost::graph_traits< ml_graph_ptr >::vertex_descriptor source(graph_traits< ml_graph_ptr >::edge_descriptor e, const ml_graph_ptr)
Returns the vertex descriptor for u of the edge (u,v) represented by e.
boost::graph_traits< ml_graph_ptr >::degree_size_type out_degree(boost::graph_traits< ml_graph_ptr >::vertex_descriptor vertex, const ml_graph_ptr)
Returns the number of out-edges (for directed graphs) or the number of incident edges (for undirected...
std::pair< boost::graph_traits< ml_graph_ptr >::vertex_iterator, boost::graph_traits< ml_graph_ptr >::vertex_iterator > vertices(ml_graph_ptr g)
Returns an iterator-range providing access to all the vertices in the graph g.
boost::graph_traits< ml_graph_ptr >::vertex_descriptor target(graph_traits< ml_graph_ptr >::edge_descriptor e, const ml_graph_ptr)
Returns the vertex descriptor for v of the edge (u,v) represented by e.
boost::graph_traits< ml_graph_ptr >::vertices_size_type num_vertices(const ml_graph_ptr g)
Returns the number of vertices in the graph g.
ml_graph_traversal_tag traversal_category
This describes the ways in which the vertices and edges of the graph can be visited.
ml::Graph::NodeIterator vertex_iterator
A vertex iterator (obtained via vertices(g)) provides access to all of the vertices in a graph.
ml::VesselNode * vertex_descriptor
The type for vertex representative objects.
long vertices_size_type
The unsigned integer type used to represent the number of vertices in the graph.
allow_parallel_edge_tag edge_parallel_category
This describes whether the graph class allows the insertion of parallel edges (edges with the same so...
ml::VesselEdge * edge_descriptor
The type for edge representative objects.
long degree_size_type
The unsigned intergral type used for representing the number out-edges or incident edges of a vertex.
directed_tag directed_category
This type shall be convertible to directed_tag or undirected_tag.
This describes the ways in which the vertices and edges of the graph can be visited.
Since the correct std::iterator_traits rely on partial template specialization which is not supported...
std::random_access_iterator_tag iterator_category