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
39
41typedef ml::Graph* ml_graph_ptr;
42
43namespace 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
75
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
122class 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
131
132public:
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)
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
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
168protected:
169 ml::VesselNode* _vertex;
170 std::vector<ml::VesselEdge*>::iterator _edgeIter;
171 std::vector<ml::VesselEdge*>::iterator _edgeIterEnd;
172};
173
174
175namespace boost {
176
177 // --- functions required by boost::IncidenceGraph ---
178
179
181 inline boost::graph_traits<ml_graph_ptr>::vertex_descriptor
182 source(graph_traits<ml_graph_ptr>::edge_descriptor e,
183 const ml_graph_ptr)
184 {
185 return e->predNode();
186 }
187
189 inline boost::graph_traits<ml_graph_ptr>::vertex_descriptor
190 target(graph_traits<ml_graph_ptr>::edge_descriptor e,
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,
209 boost::graph_traits<ml_graph_ptr>::out_edge_iterator>
210 out_edges(boost::graph_traits<ml_graph_ptr>::vertex_descriptor vertex,
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
222 inline boost::graph_traits<ml_graph_ptr>::degree_size_type
223 out_degree(boost::graph_traits<ml_graph_ptr>::vertex_descriptor vertex,
224 const ml_graph_ptr )
225 {
226 boost::graph_traits<ml_graph_ptr>::degree_size_type count = 0;
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,
247 boost::graph_traits<ml_graph_ptr>::vertex_iterator>
249 {
250 return std::make_pair( g->beginNode(),
251 g->endNode() );
252 }
253
255 inline boost::graph_traits<ml_graph_ptr>::vertices_size_type
257 {
258 return static_cast<long> (g->numNodes());
259 }
260
261
263 inline boost::graph_traits<ml_graph_ptr>::vertex_descriptor
264 vertex(boost::graph_traits<ml_graph_ptr>::degree_size_type arrayIndex, const ml_graph_ptr g)
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
290 unsigned int operator[](ml::VesselNode* vertex) const { return static_cast<unsigned int>(_g->getIndex(vertex)); }
291
292 protected:
294 };
295
299 {
300 return ml_vertex_id_map(g);
301 }
302
303 // --- Property Map Traits classes ---
304 template<>
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
335
336 // --- Property Map Traits classes ---
337 template<>
343
344
345} // namespace boost
346
347
348
351template<class T, class ValueType>
353{
355 typedef std::random_access_iterator_tag iterator_category;
356 typedef ValueType value_type;
358 typedef ValueType* pointer;
359 typedef ValueType& reference;
360};
361
362
363namespace boost {
364
379template <class IteratorTraits, class IDMap>
381{
382public:
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;
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;
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
403template <class IteratorTraits, class IDMap>
404typename IteratorTraits::value_type
406 typename property_traits<IDMap>::key_type key)
407{
408 return i.m_iter[i.m_id[key]];
409}
410template <class IteratorTraits, class IDMap>
411void
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
420template <class IteratorTraits, class IDMap>
421typename 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
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
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::VesselEdge * operator*()
ml::Graph * ml_graph_ptr
typedef for use with graph_traits<>
Target mlrange_cast(Source arg)
Generic version of checked ML casts.
Forward declaration for the boost::mutex class.
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.
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 (...
void put(const ml_iterator_map< IteratorTraits, IDMap > &i, typename property_traits< IDMap >::key_type key, const typename IteratorTraits::value_type &value)
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.
IteratorTraits::value_type & at(const ml_iterator_map< IteratorTraits, IDMap > &i, typename property_traits< IDMap >::key_type key)
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 >::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 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...
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.
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