Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
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)