Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
mitkTubeGraph.cpp
Go to the documentation of this file.
1 /*===================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 Copyright (c) German Cancer Research Center,
5 Division of Medical and Biological Informatics.
6 All rights reserved.
7 
8 This software is distributed WITHOUT ANY WARRANTY; without
9 even the implied warranty of MERCHANTABILITY or FITNESS FOR
10 A PARTICULAR PURPOSE.
11 
12 See LICENSE.txt or http://www.mitk.org for details.
13 
14 ===================================================================*/
15 
16 #include "mitkTubeGraph.h"
17 #include "mitkGeometry3D.h"
18 
20  std::pair<VertexDescriptorType, VertexDescriptorType>(boost::graph_traits<GraphType>::null_vertex(),
21  boost::graph_traits<GraphType>::null_vertex());
22 
24 {
25 }
26 
28 {
29 }
30 
32 {
33 }
34 
35 std::vector<mitk::TubeGraph::TubeDescriptorType> mitk::TubeGraph::SearchShortestPath(
36  const TubeDescriptorType &startTube, const TubeDescriptorType &endTube /*, std::vector<unsigned long> barrier*/)
37 {
38  std::vector<TubeDescriptorType> shortestPath;
39  /*
40  EdgeDescriptorType startEdge = boost::edge(startTube.first, startTube.second, m_Graph).first;
41 
42  std::vector< DescriptorType > predecessorMap( boost::num_vertices( *boostGraph ) );
43  int numberOfNodes( boost::num_vertices( *boostGraph ) );
44 
45  m_DistanceMatrix.resize( numberOfNodes );
46  for( int index(0); index < m_DistanceMatrix.size(); index++ )
47  {
48  m_DistanceMatrix[ index ].resize( numberOfNodes );
49  }
50 
51  IteratorType iterator, end;
52  boost::tie(iterator, end) = boost::vertices( *boostGraph );
53 
54  for ( int index(0) ; iterator != end; ++iterator, index++)
55  {
56  boost::dijkstra_shortest_paths(*boostGraph, *iterator, boost::predecessor_map(&predecessorMap[ 0
57  ]).distance_map(&m_DistanceMatrix[ index ][ 0 ]).weight_map( boost::get(
58  &mitk::ConnectomicsNetwork::NetworkEdge::edge_weight ,*boostGraph ) ) ) ;
59  }
60 
61 
62  */
63  return shortestPath;
64 }
65 
66 std::vector<mitk::TubeGraph::TubeDescriptorType> mitk::TubeGraph::SearchAllPathBetweenVertices(
67  const mitk::TubeGraph::TubeDescriptorType &startTube,
68  const mitk::TubeGraph::TubeDescriptorType &endTube /*, std::vector<unsigned long> barrier*/)
69 { // http://lists.boost.org/boost-users/att-9001/maze.cpp
70  // http://www.boost.org/doc/libs/1_49_0/libs/graph/example/bfs.cpp
71 
72  typedef std::map<VertexDescriptorType, EdgeDescriptorType> EdgeMap;
73  typedef boost::associative_property_map<EdgeMap> PredecessorMap;
74  typedef boost::edge_predecessor_recorder<PredecessorMap, boost::on_tree_edge> PredecessorVisitor;
75  typedef boost::dfs_visitor<std::pair<PredecessorVisitor, boost::null_visitor>> DFSVisitor;
76 
77  EdgeMap edgesMap;
78  PredecessorMap predecessorMap(edgesMap);
79 
80  PredecessorVisitor predecessorVisitor(predecessorMap);
81  boost::null_visitor nullVisitor;
82  DFSVisitor visitor = boost::make_dfs_visitor(std::make_pair(predecessorVisitor, nullVisitor));
83 
84  std::map<VertexDescriptorType, boost::default_color_type> vertexColorMap;
85  std::map<EdgeDescriptorType, boost::default_color_type> edgeColorMap;
86 
87  boost::undirected_dfs(
88  m_Graph, visitor, make_assoc_property_map(vertexColorMap), make_assoc_property_map(edgeColorMap), startTube.second);
89 
90  std::vector<TubeDescriptorType> solutionPath;
91  solutionPath.push_back(endTube);
92  VertexDescriptorType pathEdgeSource = endTube.first;
93  VertexDescriptorType pathEdgeTarget;
94 
95  MITK_INFO << "Source: [" << startTube.first << "," << startTube.second << "] Target: [" << endTube.first << ","
96  << endTube.second << "]";
97  MITK_INFO << "tube [" << endTube.first << "," << endTube.second << "]";
98  do
99  {
100  if (pathEdgeSource == 10393696)
101  break;
102  EdgeDescriptorType edge = get(predecessorMap, pathEdgeSource);
103  pathEdgeSource = boost::source(edge, m_Graph);
104  pathEdgeTarget = boost::target(edge, m_Graph);
105  TubeDescriptorType tube(pathEdgeSource, pathEdgeTarget);
106  MITK_INFO << "tube [" << tube.first << "," << tube.second << "]";
107  solutionPath.push_back(tube);
108  } while (pathEdgeSource != startTube.second);
109 
110  return solutionPath;
111 }
112 
113 std::vector<mitk::TubeGraph::TubeDescriptorType> mitk::TubeGraph::SearchPathToPeriphery(
114  const mitk::TubeGraph::TubeDescriptorType &startTube /*, std::vector<unsigned long> barrier*/)
115 {
116  std::vector<mitk::TubeGraph::TubeDescriptorType> pathToPeriphery;
117 
118  if (m_RootTube == ErrorId)
119  {
120  m_RootTube = this->GetThickestTube();
121  if (m_Root == m_RootTube.first)
122  m_Root = m_RootTube.second;
123  else
124  m_Root = m_RootTube.first;
125  }
126 
127  // Attention!! No check which one is the right one
128  DirectedGraphType directedGraph = this->GetDirectedGraph(m_Root);
129 
130  // Only the target vertex: it's a directed Graph, and we want only the "after tube" tubes and the clicked ones
131  // this->GetOutEdgesOfAVertex(startTube.first, directedGraph, pathToPeriphery);
132  pathToPeriphery.push_back(startTube);
133  this->GetOutEdgesOfAVertex(startTube.second, directedGraph, pathToPeriphery);
134 
135  return pathToPeriphery;
136 }
137 
138 void mitk::TubeGraph::GetOutEdgesOfAVertex(mitk::TubeGraph::VertexDescriptorType vertex,
139  mitk::TubeGraph::DirectedGraphType &directedGraph,
140  std::vector<mitk::TubeGraph::TubeDescriptorType> &pathToPeriphery)
141 {
142  typedef boost::graph_traits<DirectedGraphType>::out_edge_iterator OutEdgeIteratorType;
143  std::pair<OutEdgeIteratorType, OutEdgeIteratorType> outEdges = boost::out_edges(vertex, directedGraph);
144  for (; outEdges.first != outEdges.second; ++outEdges.first)
145  {
146  TubeDescriptorType tube;
147  tube.first = boost::source(*outEdges.first, directedGraph);
148  tube.second = boost::target(*outEdges.first, directedGraph);
149 
150  if (std::find(pathToPeriphery.begin(), pathToPeriphery.end(), tube) == pathToPeriphery.end())
151  {
152  pathToPeriphery.push_back(tube);
153  this->GetOutEdgesOfAVertex(tube.second, directedGraph, pathToPeriphery);
154  }
155  }
156 }
157 
159 {
160  TubeDescriptorType thickestTube;
161  float tubeDiameter = 0.0;
162 
163  EdgeIteratorType iterator, end;
164 
165  boost::tie(iterator, end) = boost::edges(m_Graph);
166 
167  for (; iterator != end; ++iterator)
168  {
169  TubeGraphEdge edge = this->GetEdge(*iterator);
170 
171  std::pair<TubeGraphVertex, TubeGraphVertex> soureTargetPair = this->GetVerticesOfAnEdge(*iterator);
172 
173  float tempDiameter = edge.GetEdgeAverageDiameter(soureTargetPair.first, soureTargetPair.second);
174  if (tempDiameter > tubeDiameter)
175  {
176  tubeDiameter = tempDiameter;
177  thickestTube.first = this->GetVertexDescriptor(soureTargetPair.first);
178  thickestTube.second = this->GetVertexDescriptor(soureTargetPair.second);
179  }
180  }
181  return thickestTube;
182 }
183 
185 {
186  DirectedGraphType directedGraph(boost::num_vertices(m_Graph));
187  DirectedGraphBfsVisitor vis(this, directedGraph);
188  boost::breadth_first_search(m_Graph, startVertex, visitor(vis));
189  return directedGraph;
190 }
191 
192 mitk::TubeGraph::Pointer mitk::TubeGraph::CreateSubGraph(std::vector<TubeDescriptorType> subGraphTubes)
193 {
194  TubeGraph::Pointer subGraph = new TubeGraph();
195  // store the descriptor from origin graph to the correspondent new descriptors
196  std::map<VertexDescriptorType, VertexDescriptorType> vertexDescriptorOldToNewMap;
197 
198  // add a new edge and if necessary also the vertices of each tube to the new sub graph
199  for (auto it = subGraphTubes.begin(); it != subGraphTubes.end(); it++)
200  {
201  // search for the source vertex in the subgraph; if it is already added continue, otherwise add it
202  if (vertexDescriptorOldToNewMap.find(it->first) == vertexDescriptorOldToNewMap.end())
203  {
204  // add the vertex to the subgraph
205  VertexDescriptorType newVertexDescriptor = subGraph->AddVertex(this->GetVertex(it->first));
206  // add the pair of descriptor from the origin graph to the descriptor from the subgraph
207  vertexDescriptorOldToNewMap.insert(
208  std::pair<VertexDescriptorType, VertexDescriptorType>(it->first, newVertexDescriptor));
209  }
210  // and now...search for the target vertex...
211  if (vertexDescriptorOldToNewMap.find(it->second) == vertexDescriptorOldToNewMap.end())
212  {
213  VertexDescriptorType newVertexDescriptor = subGraph->AddVertex(this->GetVertex(it->second));
214  vertexDescriptorOldToNewMap.insert(
215  std::pair<VertexDescriptorType, VertexDescriptorType>(it->second, newVertexDescriptor));
216  }
217  // Get the EdgeDescriptor from origin graph
218  EdgeDescriptorType edgeDescriptor = this->GetEdgeDescriptorByVerices(it->first, it->second);
219 
220  TubeGraphEdge oldEdge = this->GetEdge(edgeDescriptor);
221 
222  // AddEdge needs the source vertex, the target vertex and the edge data
223  // source Vertex: get the subgraph VertexDescriptor by the origin descriptor (tubeDescriptor->first)from the
224  // assigning map
225  // target Vertex: get the subgraph VertexDescriptor by the origin descriptor (tubeDescriptor->second)from the
226  // assigning map
227  // edge data: copy the TubeGraphEdge object using the origin edge desciptor and the origin graph
228  VertexDescriptorType sourceVertex = vertexDescriptorOldToNewMap[it->first];
229  VertexDescriptorType targetVertex = vertexDescriptorOldToNewMap[it->second];
230  EdgeDescriptorType newEdgeDescriptor = subGraph->AddEdge(sourceVertex, targetVertex, this->GetEdge(edgeDescriptor));
231  }
232  subGraph->CopyInformation(this);
233 
235  geometry->Initialize();
236  subGraph->SetGeometry(geometry);
237 
238  this->Modified();
239 
240  return subGraph;
241 }
242 
243 void mitk::TubeGraph::RemoveSubGraph(std::vector<TubeDescriptorType> deletedTubes)
244 {
245  for (auto it = deletedTubes.begin(); it != deletedTubes.end(); it++)
246  {
247  VertexDescriptorType source = it->first;
248  VertexDescriptorType target = it->second;
249 
250  EdgeDescriptorType edge = this->GetEdgeDescriptorByVerices(source, target);
251  this->RemoveEdge(edge);
252 
253  if (this->GetAllEdgesOfAVertex(source).size() == 0)
254  {
255  this->RemoveVertex(source);
256  }
257  if (this->GetAllEdgesOfAVertex(target).size() == 0)
258  {
259  this->RemoveVertex(target);
260  }
261  }
262  this->Modified();
263 }
264 
266 {
267  if (root != TubeGraph::ErrorId)
268  {
269  m_RootTube = root;
270  if (m_Root == root.first)
271  m_Root = root.second;
272  else
273  m_Root = root.first;
274  this->Modified();
275  }
276 }
277 
279 {
280  if (root != TubeGraph::ErrorId.first)
281  {
282  m_Root = root;
283  }
284 }
285 
287 {
288  return m_RootTube;
289 }
290 
292 {
293  return m_Root;
294 }
295 
297 {
299  return *this;
300 }
boost::adjacency_list< boost::vecS, boost::vecS, boost::directedS > DirectedGraphType
Definition: mitkTubeGraph.h:49
static const TubeDescriptorType ErrorId
Definition: mitkTubeGraph.h:55
#define MITK_INFO
Definition: mitkLogMacros.h:22
void RemoveSubGraph(std::vector< TubeDescriptorType > deletedTubes)
Base Class for Tube Graphs.
Definition: mitkTubeGraph.h:37
Base Class for Tube Graph Vertices.
static Pointer New()
void SetRoot(const VertexDescriptorType &root)
virtual ~TubeGraph()
std::vector< TubeDescriptorType > SearchAllPathBetweenVertices(const TubeDescriptorType &startTube, const TubeDescriptorType &endTube)
float GetEdgeAverageDiameter(TubeGraphVertex &source, TubeGraphVertex &target)
std::vector< TubeDescriptorType > SearchPathToPeriphery(const TubeDescriptorType &startTube)
boost::graph_traits< GraphType >::edge_descriptor EdgeDescriptorType
std::pair< VertexDescriptorType, VertexDescriptorType > TubeDescriptorType
Definition: mitkTubeGraph.h:43
TubeGraph::Pointer CreateSubGraph(std::vector< TubeDescriptorType > subGraphTubes)
TubeDescriptorType GetThickestTube()
boost::graph_traits< GraphType >::edge_iterator EdgeIteratorType
TubeDescriptorType GetRootTube()
Base Class for Tube Graph Edges.
DirectedGraphType GetDirectedGraph(VertexDescriptorType startVertex)
Template class for undirected graphs.Paramters should be the vertex and edge classes, which contains the information.
boost::graph_traits< GraphType >::vertex_descriptor VertexDescriptorType
UndirectedGraph< VertexType, EdgeType > & operator=(const UndirectedGraph< VertexType, EdgeType > &rhs)
std::vector< TubeDescriptorType > SearchShortestPath(const TubeDescriptorType &startTube, const TubeDescriptorType &endTube)
void SetRootTube(const TubeDescriptorType &root)
VertexDescriptorType GetRootVertex()
TubeGraph & operator=(const TubeGraph &rhs)