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
mitkTubeGraphVtkMapper3D.cpp
Go to the documentation of this file.
1 /*===================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 
18 
19 #include <mitkColorProperty.h>
20 
21 #include <vtkCellArray.h>
22 #include <vtkClipPolyData.h>
23 #include <vtkContourFilter.h>
24 #include <vtkCylinder.h>
25 #include <vtkFloatArray.h>
26 #include <vtkGeneralTransform.h>
27 #include <vtkImplicitBoolean.h>
28 #include <vtkImplicitModeller.h>
29 #include <vtkPlane.h>
30 #include <vtkPointData.h>
31 #include <vtkPoints.h>
32 #include <vtkPolyDataMapper.h>
33 #include <vtkProperty.h>
34 #include <vtkRenderer.h>
35 #include <vtkSampleFunction.h>
36 #include <vtkSphereSource.h>
37 #include <vtkTubeFilter.h>
38 #include <vtkUnsignedIntArray.h>
39 
41 {
42 }
43 
45 {
46 }
47 
49 {
50  return dynamic_cast<const TubeGraph *>(GetData());
51 }
52 
54 {
55  return m_LSH.GetLocalStorage(renderer)->m_vtkTubeGraphAssembly;
56 }
57 
59 {
60  bool renderTubeGraph(false);
61  LocalStorage *ls = m_LSH.GetLocalStorage(renderer);
62 
63  TubeGraph::Pointer tubeGraph = const_cast<mitk::TubeGraph *>(this->GetInput());
64  TubeGraphProperty::Pointer tubeGraphProperty =
65  dynamic_cast<TubeGraphProperty *>(tubeGraph->GetProperty("Tube Graph.Visualization Information").GetPointer());
66 
67  if (tubeGraph.IsNull() || tubeGraphProperty.IsNull())
68  {
69  itkWarningMacro(<< "Input of tube graph mapper is NULL!");
70  return;
71  }
72  // Check if the tube graph has changed; if the data has changed, generate the spheres and tubes new;
73  if (tubeGraph->GetMTime() > ls->m_lastGenerateDataTime)
74  {
75  this->GenerateTubeGraphData(renderer);
76  renderTubeGraph = true;
77  }
78  else
79  {
80  // Check if the tube graph property has changed; if the property has changed, render the visualization information
81  // new;
82  if (tubeGraphProperty->GetMTime() > ls->m_lastRenderDataTime)
83  {
84  this->RenderTubeGraphPropertyInformation(renderer);
85  renderTubeGraph = true;
86  }
87  }
88 
89  if (renderTubeGraph)
90  {
91  std::vector<TubeGraph::VertexDescriptorType> alreadyRenderedVertexList;
92  // don't render the sphere which is the root of the graph; so add it to the list before;
93  // TODO check both spheres
94  TubeGraph::VertexDescriptorType root = tubeGraph->GetRootVertex();
95  alreadyRenderedVertexList.push_back(root);
96 
97  for (std::map<TubeGraph::TubeDescriptorType, vtkSmartPointer<vtkActor>>::iterator itTubes =
98  ls->m_vtkTubesActorMap.begin();
99  itTubes != ls->m_vtkTubesActorMap.end();
100  itTubes++)
101  {
102  if (tubeGraphProperty->IsTubeVisible(itTubes->first))
103  {
104  // add tube actor to assembly
105  ls->m_vtkTubeGraphAssembly->AddPart(itTubes->second);
106 
107  // render the clipped spheres as end-cups of a tube and connections between tubes
108  if (std::find(alreadyRenderedVertexList.begin(), alreadyRenderedVertexList.end(), itTubes->first.first) ==
109  alreadyRenderedVertexList.end())
110  {
111  std::map<TubeGraph::VertexDescriptorType, vtkSmartPointer<vtkActor>>::iterator itSourceSphere =
112  ls->m_vtkSpheresActorMap.find(itTubes->first.first);
113  if (itSourceSphere != ls->m_vtkSpheresActorMap.end())
114  ls->m_vtkTubeGraphAssembly->AddPart(itSourceSphere->second);
115  alreadyRenderedVertexList.push_back(itSourceSphere->first);
116  }
117  if (std::find(alreadyRenderedVertexList.begin(), alreadyRenderedVertexList.end(), itTubes->first.second) ==
118  alreadyRenderedVertexList.end())
119  {
120  std::map<TubeGraph::VertexDescriptorType, vtkSmartPointer<vtkActor>>::iterator itTargetSphere =
121  ls->m_vtkSpheresActorMap.find(itTubes->first.second);
122  if (itTargetSphere != ls->m_vtkSpheresActorMap.end())
123  ls->m_vtkTubeGraphAssembly->AddPart(itTargetSphere->second);
124  alreadyRenderedVertexList.push_back(itTargetSphere->first);
125  }
126  }
127  }
128  }
129 
131  //{
132  // float opacity = 1.0f;
133  // if( this->GetDataNode()->GetOpacity(opacity,renderer) )
134  // ls->m_vtkTubesActor->GetProperty()->SetOpacity( opacity );
135  //}
136 }
137 
139 {
140  MITK_INFO << "Render tube graph property information!";
141  LocalStorage *ls = m_LSH.GetLocalStorage(renderer);
142  TubeGraph::Pointer tubeGraph = const_cast<mitk::TubeGraph *>(this->GetInput());
143  TubeGraphProperty::Pointer tubeGraphProperty =
144  dynamic_cast<TubeGraphProperty *>(tubeGraph->GetProperty("Tube Graph.Visualization Information").GetPointer());
145 
146  if (tubeGraphProperty.IsNull())
147  {
148  MITK_INFO << "No tube graph property!! So no special render information...";
149  return;
150  }
151 
152  std::vector<TubeGraphVertex> allVertices = tubeGraph->GetVectorOfAllVertices();
153  for (std::vector<TubeGraphVertex>::iterator vertex = allVertices.begin(); vertex != allVertices.end(); ++vertex)
154  {
155  TubeGraph::VertexDescriptorType vertexDesc = tubeGraph->GetVertexDescriptor(*vertex);
156 
157  double sphereColorR = 0;
158  double sphereColorG = 0;
159  double sphereColorB = 0;
160 
161  int numberOfVisibleEdges = 0;
162  std::vector<TubeGraphEdge> allEdgesOfVertex = tubeGraph->GetAllEdgesOfAVertex(vertexDesc);
163  for (std::vector<TubeGraphEdge>::iterator edge = allEdgesOfVertex.begin(); edge != allEdgesOfVertex.end(); ++edge)
164  {
165  // get edge descriptor
166  EdgeDescriptorType edgeDesc = tubeGraph->GetEdgeDescriptor(*edge);
167 
168  // get source and target vertex descriptor
169  std::pair<TubeGraphVertex, TubeGraphVertex> soureTargetPair = tubeGraph->GetVerticesOfAnEdge(edgeDesc);
170  TubeGraphVertex source = soureTargetPair.first;
171  TubeGraphVertex target = soureTargetPair.second;
172 
173  // build tube descriptor [sourceId,targetId]
175  tube.first = tubeGraph->GetVertexDescriptor(source);
176  tube.second = tubeGraph->GetVertexDescriptor(target);
177 
178  if (tubeGraphProperty->IsTubeVisible(tube))
179  {
180  mitk::Color tubeColor = tubeGraphProperty->GetColorOfTube(tube);
181 
182  vtkSmartPointer<vtkDataArray> scalars =
183  ls->m_vtkTubesActorMap[tube]->GetMapper()->GetInput()->GetPointData()->GetScalars();
184  double color[3];
185  scalars->GetTuple(0, color);
186 
187  if (color[0] != tubeColor[0] || color[1] != tubeColor[1] || color[2] != tubeColor[2])
188  {
189  int numberOfPoints = scalars->GetSize();
190 
191  vtkSmartPointer<vtkUnsignedCharArray> colorScalars = vtkSmartPointer<vtkUnsignedCharArray>::New();
192  colorScalars->SetName("colorScalars");
193  colorScalars->SetNumberOfComponents(3);
194  colorScalars->SetNumberOfTuples(numberOfPoints);
195  for (int i = 0; i < numberOfPoints; i++)
196  {
197  scalars->InsertTuple3(i, tubeColor[0], tubeColor[1], tubeColor[2]);
198  }
199  ls->m_vtkTubesActorMap[tube]->GetMapper()->GetInput()->GetPointData()->SetActiveScalars("colorScalars");
200  }
201 
202  sphereColorR += tubeColor[0];
203  sphereColorG += tubeColor[1];
204  sphereColorB += tubeColor[2];
205  numberOfVisibleEdges++;
206  }
207  }
208  if (numberOfVisibleEdges > 0)
209  {
210  sphereColorR /= 255 * numberOfVisibleEdges;
211  sphereColorG /= 255 * numberOfVisibleEdges;
212  sphereColorB /= 255 * numberOfVisibleEdges;
213  }
214 
215  ls->m_vtkSpheresActorMap[vertexDesc]->GetProperty()->SetColor(sphereColorR, sphereColorG, sphereColorB);
216  }
217  ls->m_lastRenderDataTime.Modified();
218 }
219 
221 {
222  MITK_INFO << "Render tube graph!";
223  LocalStorage *ls = m_LSH.GetLocalStorage(renderer);
224 
225  ls->m_vtkTubesActorMap.clear();
226  ls->m_vtkSpheresActorMap.clear();
227 
228  TubeGraph::Pointer tubeGraph = const_cast<mitk::TubeGraph *>(this->GetInput());
229  TubeGraphProperty::Pointer tubeGraphProperty =
230  dynamic_cast<TubeGraphProperty *>(tubeGraph->GetProperty("Tube Graph.Visualization Information").GetPointer());
231  if (tubeGraphProperty.IsNull())
232  MITK_INFO << "No tube graph property!! So no special render information...";
233 
234  // render all edges as tubular structures using the vtkTubeFilter
235  std::vector<TubeGraphEdge> allEdges = tubeGraph->GetVectorOfAllEdges();
236  for (std::vector<TubeGraphEdge>::iterator edge = allEdges.begin(); edge != allEdges.end(); ++edge)
237  {
238  this->GeneratePolyDataForTube(*edge, tubeGraph, tubeGraphProperty, renderer);
239  }
240 
241  // Generate all vertices as spheres
242  std::vector<TubeGraphVertex> allVertices = tubeGraph->GetVectorOfAllVertices();
243  for (std::vector<TubeGraphVertex>::iterator vertex = allVertices.begin(); vertex != allVertices.end(); ++vertex)
244  {
245  this->GeneratePolyDataForFurcation(*vertex, tubeGraph, renderer);
246  if (this->ClipStructures())
247  {
248  this->ClipPolyData(*vertex, tubeGraph, tubeGraphProperty, renderer);
249  }
250 
251  ls->m_lastGenerateDataTime.Modified();
252  }
253 }
254 
256  const mitk::TubeGraph::Pointer &graph,
257  mitk::BaseRenderer *renderer)
258 {
259  LocalStorage *ls = this->m_LSH.GetLocalStorage(renderer);
260 
261  mitk::Point3D coordinates;
262  float diameter = 2;
263 
264  coordinates = (vertex.GetTubeElement())->GetCoordinates();
265  if (dynamic_cast<const mitk::CircularProfileTubeElement *>(vertex.GetTubeElement()))
266  {
267  diameter = (dynamic_cast<const mitk::CircularProfileTubeElement *>(vertex.GetTubeElement()))->GetDiameter();
268  }
269  vtkSmartPointer<vtkSphereSource> sphereSource = vtkSmartPointer<vtkSphereSource>::New();
270  sphereSource->SetCenter(coordinates[0], coordinates[1], coordinates[2]);
271  sphereSource->SetRadius(diameter / 2.0f);
272  sphereSource->SetThetaResolution(12);
273  sphereSource->SetPhiResolution(12);
274  sphereSource->Update();
275 
276  // generate a actor with a mapper for the sphere
277  vtkSmartPointer<vtkPolyDataMapper> sphereMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
278  vtkSmartPointer<vtkActor> sphereActor = vtkSmartPointer<vtkActor>::New();
279 
280  sphereMapper->SetInputConnection(sphereSource->GetOutputPort());
281  sphereActor->SetMapper(sphereMapper);
282 
283  ls->m_vtkSpheresActorMap.insert(std::make_pair(graph->GetVertexDescriptor(vertex), sphereActor));
284 }
285 
287  const mitk::TubeGraph::Pointer &graph,
288  const mitk::TubeGraphProperty::Pointer &graphProperty,
289  mitk::BaseRenderer *renderer)
290 {
291  LocalStorage *ls = this->m_LSH.GetLocalStorage(renderer);
292 
293  // get edge descriptor
294  EdgeDescriptorType edgeDesc = graph->GetEdgeDescriptor(edge);
295 
296  // get source and target vertex descriptor
297  std::pair<TubeGraphVertex, TubeGraphVertex> soureTargetPair = graph->GetVerticesOfAnEdge(edgeDesc);
298  TubeGraphVertex source = soureTargetPair.first;
299  TubeGraphVertex target = soureTargetPair.second;
300 
301  // build tube descriptor [sourceId,targetId]
303  tube.first = graph->GetVertexDescriptor(source);
304  tube.second = graph->GetVertexDescriptor(target);
305 
306  Color color;
307  if (graphProperty.IsNotNull())
308  {
309  color = graphProperty->GetColorOfTube(tube);
310  }
311  else
312  {
313  color[0] = 150;
314  color[1] = 150;
315  color[2] = 150;
316  }
317 
318  // add 2 points for the source and target vertices.
319  unsigned int numberOfPoints = edge.GetNumberOfElements() + 2;
320 
321  // Initialize the required data-structures for building
322  // an appropriate input to the tube filter
323  vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
324  points->SetNumberOfPoints(numberOfPoints);
325 
326  vtkSmartPointer<vtkFloatArray> radii = vtkSmartPointer<vtkFloatArray>::New();
327  radii->SetName("radii");
328  radii->SetNumberOfComponents(1);
329 
330  vtkSmartPointer<vtkCellArray> lines = vtkSmartPointer<vtkCellArray>::New();
331 
332  vtkSmartPointer<vtkUnsignedCharArray> colorScalars = vtkSmartPointer<vtkUnsignedCharArray>::New();
333  colorScalars->SetName("colorScalars");
334  colorScalars->SetNumberOfComponents(3);
335 
336  // resize the data-arrays
337  radii->SetNumberOfTuples(numberOfPoints);
338  colorScalars->SetNumberOfTuples(numberOfPoints);
339  lines->InsertNextCell(numberOfPoints);
340 
341  // Add the positions of the source node, the elements along the edge and
342  // the target node as lines to a cell. This cell is used as input
343  // for a Tube Filter
344  mitk::Point3D coordinates;
345  float diameter = 2;
346  unsigned int id = 0;
347 
348  // Source Node
349  coordinates = (source.GetTubeElement())->GetCoordinates();
350  if (dynamic_cast<const mitk::CircularProfileTubeElement *>(source.GetTubeElement()))
351  {
352  diameter = (dynamic_cast<const mitk::CircularProfileTubeElement *>(source.GetTubeElement()))->GetDiameter();
353  }
354  points->InsertPoint(id, coordinates[0], coordinates[1], coordinates[2]);
355  radii->InsertTuple1(id, diameter / 2.0f);
356 
357  colorScalars->InsertTuple3(id, color[0], color[1], color[2]);
358  lines->InsertCellPoint(id);
359  ++id;
360 
361  // Iterate along the edge
362  std::vector<mitk::TubeElement *> allElements = edge.GetElementVector();
363  for (unsigned int index = 0; index < edge.GetNumberOfElements(); index++)
364  {
365  coordinates = allElements[index]->GetCoordinates();
366  if (dynamic_cast<mitk::CircularProfileTubeElement *>(allElements[index]))
367  {
368  diameter = (dynamic_cast<mitk::CircularProfileTubeElement *>(allElements[index]))->GetDiameter();
369  }
370  points->InsertPoint(id, coordinates[0], coordinates[1], coordinates[2]);
371  radii->InsertTuple1(id, diameter / 2.0f);
372  colorScalars->InsertTuple3(id, color[0], color[1], color[2]);
373  lines->InsertCellPoint(id);
374  ++id;
375  }
376 
377  // Target Node
378  coordinates = (target.GetTubeElement())->GetCoordinates();
379  if (dynamic_cast<const mitk::CircularProfileTubeElement *>(target.GetTubeElement()))
380  {
381  diameter = (dynamic_cast<const mitk::CircularProfileTubeElement *>(target.GetTubeElement()))->GetDiameter();
382  }
383  points->InsertPoint(id, coordinates[0], coordinates[1], coordinates[2]);
384  radii->InsertTuple1(id, diameter / 2.0f);
385  colorScalars->InsertTuple3(id, color[0], color[1], color[2]);
386  lines->InsertCellPoint(id);
387  ++id;
388 
389  // Initialize poly data from the point set and the cell array
390  // (representing topology)
391  vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
392  polyData->SetPoints(points);
393  polyData->SetLines(lines);
394  polyData->GetPointData()->AddArray(radii);
395  polyData->GetPointData()->AddArray(colorScalars);
396  polyData->GetPointData()->SetActiveScalars(radii->GetName());
397 
398  // Generate a tube for all lines in the polydata object
399  double *range = radii->GetRange();
400 
401  assert(range[0] != 0.0f && range[1] != 0.0f);
402 
403  vtkSmartPointer<vtkTubeFilter> tubeFilter = vtkSmartPointer<vtkTubeFilter>::New();
404  tubeFilter->SetInputData(polyData);
405  tubeFilter->SetRadius(range[0]);
406  tubeFilter->SetRadiusFactor(range[1] / range[0]);
407 
408  if (range[0] != range[1])
409  tubeFilter->SetVaryRadiusToVaryRadiusByScalar();
410 
411  tubeFilter->SetNumberOfSides(9);
412  tubeFilter->SidesShareVerticesOn();
413  tubeFilter->CappingOff();
414  tubeFilter->Update();
415 
416  tubeFilter->GetOutput()->GetPointData()->SetActiveScalars("colorScalars");
417 
418  // generate a actor with a mapper for the
419  vtkSmartPointer<vtkPolyDataMapper> tubeMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
420  vtkSmartPointer<vtkActor> tubeActor = vtkSmartPointer<vtkActor>::New();
421 
422  tubeMapper->SetInputConnection(tubeFilter->GetOutputPort());
423  tubeActor->SetMapper(tubeMapper);
424  tubeActor->GetProperty()->SetColor(color[0], color[1], color[2]);
425 
426  ls->m_vtkTubesActorMap.insert(std::pair<TubeGraph::TubeDescriptorType, vtkSmartPointer<vtkActor>>(tube, tubeActor));
427 }
428 
430  const mitk::TubeGraph::Pointer &graph,
431  const mitk::TubeGraphProperty::Pointer &graphProperty,
432  mitk::BaseRenderer *renderer)
433 {
434  LocalStorage *ls = this->m_LSH.GetLocalStorage(renderer);
435 
436  mitk::Point3D centerVertex = vertex.GetTubeElement()->GetCoordinates();
437  float diameter = 2;
438  if (dynamic_cast<const mitk::CircularProfileTubeElement *>(vertex.GetTubeElement()))
439  {
440  diameter = (dynamic_cast<const mitk::CircularProfileTubeElement *>(vertex.GetTubeElement()))->GetDiameter();
441  }
442 
443  TubeGraph::VertexDescriptorType vertexDesc = graph->GetVertexDescriptor(vertex);
444 
445  std::map<TubeGraph::TubeDescriptorType, vtkSmartPointer<vtkImplicitBoolean>> cylinderForClipping;
446 
447  // generate for all edges/tubes cylinders. With this structure you can clip the sphere and the other tubes, so that no
448  // fragments are shown in the tube.
449  std::vector<TubeGraphEdge> allEdgesOfVertex = graph->GetAllEdgesOfAVertex(vertexDesc);
450  for (std::vector<TubeGraphEdge>::iterator edge = allEdgesOfVertex.begin(); edge != allEdgesOfVertex.end(); ++edge)
451  {
452  // get edge descriptor
453  EdgeDescriptorType edgeDesc = graph->GetEdgeDescriptor(*edge);
454 
455  // get source and target vertex descriptor
456  std::pair<TubeGraphVertex, TubeGraphVertex> soureTargetPair = graph->GetVerticesOfAnEdge(edgeDesc);
457  TubeGraphVertex source = soureTargetPair.first;
458  TubeGraphVertex target = soureTargetPair.second;
459 
460  // build tube descriptor [sourceId,targetId]
462  tube.first = graph->GetVertexDescriptor(source);
463  tube.second = graph->GetVertexDescriptor(target);
464 
465  // get reference point in the tube for the direction
466  mitk::Point3D edgeDirectionPoint;
467  // get reference diameter
468  double cylinderDiameter = diameter;
469  float radius = diameter / 2;
470  // if the vertex is the source vertex of the edge get the first element of elementVector; otherwise get the last
471  // element.
472  if (source == vertex)
473  {
474  // if the edge has no element get the other vertex
475  if ((*edge).GetNumberOfElements() != 0)
476  {
477  double lastDistance = 0, distance = 0;
478 
479  unsigned int index = 0;
480  // Get the first element behind the radius of the sphere
481  for (; index < (*edge).GetNumberOfElements(); index++)
482  {
483  mitk::Vector3D diffVec = (*edge).GetTubeElement(index)->GetCoordinates() - centerVertex;
484  distance = std::sqrt(pow(diffVec[0], 2) + pow(diffVec[1], 2) + pow(diffVec[2], 2));
485  if (distance > radius)
486  break;
487  lastDistance = distance;
488  }
489  // if the last element is not inside the sphere
490  if (index < (*edge).GetNumberOfElements())
491  {
492  double withinSphereDiameter = diameter, outsideSphereDiameter = diameter, interpolationValue = 0.5;
493 
494  interpolationValue = (radius - lastDistance) / (distance - lastDistance);
495  // if first element is outside of the sphere use sphere diameter and the element diameter for interpolation
496  if (index == 0)
497  {
498  if (dynamic_cast<mitk::CircularProfileTubeElement *>((*edge).GetTubeElement(0)))
499  outsideSphereDiameter =
500  (dynamic_cast<mitk::CircularProfileTubeElement *>((*edge).GetTubeElement(0)))->GetDiameter();
501  }
502  else
503  {
504  if (dynamic_cast<mitk::CircularProfileTubeElement *>((*edge).GetTubeElement(index - 1)))
505  withinSphereDiameter =
506  (dynamic_cast<mitk::CircularProfileTubeElement *>((*edge).GetTubeElement(index - 1)))->GetDiameter();
507 
508  if (dynamic_cast<mitk::CircularProfileTubeElement *>((*edge).GetTubeElement(index)))
509  outsideSphereDiameter =
510  (dynamic_cast<mitk::CircularProfileTubeElement *>((*edge).GetTubeElement(index)))->GetDiameter();
511  }
512  // interpolate the diameter for clipping
513  cylinderDiameter =
514  (1 - interpolationValue) * withinSphereDiameter + interpolationValue * outsideSphereDiameter;
515  }
516  // Get the reference point, so the direction of the tube can be calculated
517  edgeDirectionPoint = (*edge).GetTubeElement(0)->GetCoordinates();
518  }
519  else
520  {
521  // Get the reference point, so the direction of the tube can be calculated
522  edgeDirectionPoint = target.GetTubeElement()->GetCoordinates();
523  }
524  }
525 
526  // if vertex is target of the tube
527  else
528  {
529  // if the edge has no element, get the other vertex
530  if ((*edge).GetNumberOfElements() != 0)
531  {
532  double lastDistance = 0, distance = 0;
533  // Get the first element behind the radius of the sphere; now backwards through the element list
534  unsigned int index = (*edge).GetNumberOfElements() - 1;
535  for (; index >= 0; index--)
536  {
537  mitk::Vector3D diffVec = (*edge).GetTubeElement(index)->GetCoordinates() - centerVertex;
538  distance = std::sqrt(pow(diffVec[0], 2) + pow(diffVec[1], 2) + pow(diffVec[2], 2));
539  if (distance > radius)
540  break;
541  lastDistance = distance;
542  }
543 
544  if (index >= 0)
545  {
546  double withinSphereDiameter = diameter, outsideSphereDiameter = diameter, interpolationValue = 0.5;
547 
548  interpolationValue = (radius - lastDistance) / (distance - lastDistance);
549 
550  if (index == (*edge).GetNumberOfElements() - 1)
551  {
552  if (dynamic_cast<mitk::CircularProfileTubeElement *>(
553  (*edge).GetTubeElement((*edge).GetNumberOfElements() - 1)))
554  outsideSphereDiameter = (dynamic_cast<mitk::CircularProfileTubeElement *>(
555  (*edge).GetTubeElement((*edge).GetNumberOfElements() - 1)))
556  ->GetDiameter();
557  }
558  else
559  {
560  if (dynamic_cast<mitk::CircularProfileTubeElement *>((*edge).GetTubeElement(index + 1)))
561  withinSphereDiameter =
562  (dynamic_cast<mitk::CircularProfileTubeElement *>((*edge).GetTubeElement(index + 1)))->GetDiameter();
563 
564  if (dynamic_cast<mitk::CircularProfileTubeElement *>((*edge).GetTubeElement(index)))
565  outsideSphereDiameter =
566  (dynamic_cast<mitk::CircularProfileTubeElement *>((*edge).GetTubeElement(index)))->GetDiameter();
567  }
568  // interpolate the diameter for clipping
569  cylinderDiameter =
570  (1 - interpolationValue) * withinSphereDiameter + interpolationValue * outsideSphereDiameter;
571  }
572 
573  // Get the reference point, so the direction of the tube can be calculated
574  edgeDirectionPoint = (*edge).GetTubeElement((*edge).GetNumberOfElements() - 1)->GetCoordinates();
575  }
576  else
577  {
578  // Get the reference point, so the direction of the tube can be calculated
579  edgeDirectionPoint = source.GetTubeElement()->GetCoordinates();
580  }
581  }
582 
584  // get the normalized vector for the orientation (tube element direction)
585  mitk::Vector3D vecOrientation;
586  mitk::FillVector3D(vecOrientation,
587  (edgeDirectionPoint[0] - centerVertex[0]),
588  (edgeDirectionPoint[1] - centerVertex[1]),
589  (edgeDirectionPoint[2] - centerVertex[2]));
590  vecOrientation.Normalize();
591 
592  // generate a random vector
593  mitk::Vector3D vecRandom;
594  mitk::FillVector3D(vecRandom, (rand() % 100 - 50), (rand() % 100 - 50), (rand() % 100 - 50));
595  // project the random vector on the plane-->orthogonal vector to plane normal; normalize it!
596  mitk::Vector3D vecOrthoToOrientation;
597  vecOrthoToOrientation = vecRandom - (vecRandom * vecOrientation) * vecOrientation;
598  vecOrthoToOrientation.Normalize();
599 
600  // get the cross product of both orthogonale vectors to get a third one
601  mitk::Vector3D vecCrossProduct;
602  vecCrossProduct = itk::CrossProduct(vecOrientation, vecOrthoToOrientation);
603  vecCrossProduct.Normalize();
604 
605  // Fill matrix
606  vtkSmartPointer<vtkMatrix4x4> vtkTransformMatrix = vtkSmartPointer<vtkMatrix4x4>::New();
607  vtkTransformMatrix->Identity();
608  // 1. column
609  vtkTransformMatrix->SetElement(0, 0, vecOrthoToOrientation[0]);
610  vtkTransformMatrix->SetElement(1, 0, vecOrthoToOrientation[1]);
611  vtkTransformMatrix->SetElement(2, 0, vecOrthoToOrientation[2]);
612  // 2. column
613  vtkTransformMatrix->SetElement(0, 1, vecOrientation[0]);
614  vtkTransformMatrix->SetElement(1, 1, vecOrientation[1]);
615  vtkTransformMatrix->SetElement(2, 1, vecOrientation[2]);
616  // 3. column
617  vtkTransformMatrix->SetElement(0, 2, vecCrossProduct[0]);
618  vtkTransformMatrix->SetElement(1, 2, vecCrossProduct[1]);
619  vtkTransformMatrix->SetElement(2, 2, vecCrossProduct[2]);
620  // 4. column
621  vtkTransformMatrix->SetElement(0, 3, centerVertex[0]);
622  vtkTransformMatrix->SetElement(1, 3, centerVertex[1]);
623  vtkTransformMatrix->SetElement(2, 3, centerVertex[2]);
624 
625  vtkSmartPointer<vtkGeneralTransform> transform = vtkSmartPointer<vtkGeneralTransform>::New();
626  transform->Concatenate(vtkTransformMatrix);
627  // transform->Translate(centerVertex[0],centerVertex[1],centerVertex[2]);
628 
629  transform->Inverse();
630  transform->Update();
631 
632  // Generate plane in center [0,0,0] with n= (0,1,0) as normal vector
633  vtkSmartPointer<vtkPlane> plane = vtkSmartPointer<vtkPlane>::New();
634  plane->SetOrigin(0, 0, 0);
635  plane->SetNormal(0, 1, 0);
636 
637  // Generate a cylinder in center [0,0,0] and the axes of rotation is along the y-axis; radius is vertex diameter/2;
638  vtkSmartPointer<vtkCylinder> cylinder = vtkSmartPointer<vtkCylinder>::New();
639  cylinder->SetCenter(0, 0, 0);
640  cylinder->SetRadius(cylinderDiameter / 2);
641  // cylinder->SetTransform(transform);
642 
643  // Truncate the infinite cylinder with the plane
644  vtkSmartPointer<vtkImplicitBoolean> cutCylinder = vtkSmartPointer<vtkImplicitBoolean>::New();
645  cutCylinder->SetOperationTypeToDifference();
646  cutCylinder->SetTransform(transform);
647  cutCylinder->AddFunction(cylinder);
648  cutCylinder->AddFunction(plane);
649 
650  cylinderForClipping.insert(
651  std::pair<TubeGraph::TubeDescriptorType, vtkSmartPointer<vtkImplicitBoolean>>(tube, cutCylinder));
652 
654  // vtkSmartPointer<vtkSampleFunction> sample = vtkSmartPointer<vtkSampleFunction>::New();
655  // sample->SetSampleDimensions(100,100,100);
656  // sample->SetImplicitFunction(cutCylinder);
658  // double xmin = centerVertex[0]-(2*diameter), xmax = centerVertex[0]+(2*diameter),
659  // ymin = centerVertex[1]-(2*diameter), ymax = centerVertex[1]+(2*diameter),
660  // zmin = centerVertex[2]-(2*diameter), zmax = centerVertex[2]+(2*diameter);
661  // sample->SetModelBounds(xmin, xmax, ymin, ymax, zmin, zmax);
662 
663  // vtkSmartPointer<vtkContourFilter> contour =vtkSmartPointer<vtkContourFilter>::New();
664  // contour->SetInputConnection(sample->GetOutputPort());
665  // contour->SetValue( 0, 0.25);
666 
667  // vtkSmartPointer<vtkPolyDataMapper> impMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
668  // impMapper->SetInputConnection (contour->GetOutputPort());
669  // impMapper->ScalarVisibilityOff();
670  // vtkSmartPointer<vtkActor> impActor = vtkSmartPointer<vtkActor>::New();
671  // impActor->SetMapper(impMapper);
672 
673  // ls->m_vtkTubeGraphAssembly->AddPart(impActor);
674  }
675 
676  double sphereColorR = 0;
677  double sphereColorG = 0;
678  double sphereColorB = 0;
679 
680  for (std::map<TubeGraph::TubeDescriptorType, vtkSmartPointer<vtkImplicitBoolean>>::iterator itClipStructure =
681  cylinderForClipping.begin();
682  itClipStructure != cylinderForClipping.end();
683  itClipStructure++)
684  {
685  vtkSmartPointer<vtkPolyDataMapper> sphereMapper =
686  dynamic_cast<vtkPolyDataMapper *>(ls->m_vtkSpheresActorMap[vertexDesc]->GetMapper());
687 
688  if (sphereMapper != NULL)
689  {
690  // first clip the sphere with the cylinder
691  vtkSmartPointer<vtkClipPolyData> clipperSphere = vtkSmartPointer<vtkClipPolyData>::New();
692  clipperSphere->SetInputData(sphereMapper->GetInput());
693  clipperSphere->SetClipFunction(itClipStructure->second);
694  clipperSphere->GenerateClippedOutputOn();
695  clipperSphere->Update();
696 
697  sphereMapper->SetInputConnection(clipperSphere->GetOutputPort());
698  sphereMapper->Update();
699  }
700 
701  mitk::Color tubeColor = graphProperty->GetColorOfTube(itClipStructure->first);
702  sphereColorR += tubeColor[0];
703  sphereColorG += tubeColor[1];
704  sphereColorB += tubeColor[2];
705 
706  // than clip with all other tubes
707  for (std::map<TubeGraph::TubeDescriptorType, vtkSmartPointer<vtkImplicitBoolean>>::iterator itTobBeClipped =
708  cylinderForClipping.begin();
709  itTobBeClipped != cylinderForClipping.end();
710  itTobBeClipped++)
711  {
712  TubeGraph::TubeDescriptorType toBeClippedTube = itTobBeClipped->first;
713 
714  if (itClipStructure->first != toBeClippedTube)
715  {
716  vtkSmartPointer<vtkPolyDataMapper> tubeMapper =
717  dynamic_cast<vtkPolyDataMapper *>(ls->m_vtkTubesActorMap[toBeClippedTube]->GetMapper());
718 
719  if (tubeMapper != NULL)
720  {
721  // first clip the sphere with the cylinder
722  vtkSmartPointer<vtkClipPolyData> clipperTube = vtkSmartPointer<vtkClipPolyData>::New();
723  tubeMapper->Update();
724  clipperTube->SetInputData(tubeMapper->GetInput());
725  clipperTube->SetClipFunction(itClipStructure->second);
726  clipperTube->GenerateClippedOutputOn();
727  clipperTube->Update();
728 
729  tubeMapper->SetInputConnection(clipperTube->GetOutputPort());
730  tubeMapper->Update();
731  }
732  }
733  }
734  }
735  if (cylinderForClipping.size() != 0)
736  {
737  sphereColorR /= 255 * cylinderForClipping.size();
738  sphereColorG /= 255 * cylinderForClipping.size();
739  sphereColorB /= 255 * cylinderForClipping.size();
740  }
741 
742  ls->m_vtkSpheresActorMap[vertexDesc]->GetProperty()->SetColor(sphereColorR, sphereColorG, sphereColorB);
743 }
744 
745 bool mitk::TubeGraphVtkMapper3D::ClipStructures()
746 {
747  DataNode::Pointer node = this->GetDataNode();
748  if (node.IsNull())
749  {
750  itkWarningMacro(<< "associated node is NULL!");
751  return false;
752  }
753 
754  bool clipStructures = false;
755  node->GetBoolProperty("Tube Graph.Clip Structures", clipStructures);
756 
757  return clipStructures;
758 }
virtual void GenerateDataForRenderer(mitk::BaseRenderer *renderer) override
unsigned int GetNumberOfElements() const
void GeneratePolyDataForTube(TubeGraphEdge &edge, const TubeGraph::Pointer &graph, const TubeGraphProperty::Pointer &graphProperty, mitk::BaseRenderer *renderer)
void ClipPolyData(TubeGraphVertex &vertex, const TubeGraph::Pointer &graph, const TubeGraphProperty::Pointer &graphProperty, mitk::BaseRenderer *renderer)
#define MITK_INFO
Definition: mitkLogMacros.h:22
Base Class for Tube Graphs.
Definition: mitkTubeGraph.h:37
virtual void GenerateTubeGraphData(mitk::BaseRenderer *renderer)
Base Class for Tube Graph Vertices.
Organizes the rendering process.
void GeneratePolyDataForFurcation(TubeGraphVertex &vertex, const TubeGraph::Pointer &graph, mitk::BaseRenderer *renderer)
void FillVector3D(Tout &out, mitk::ScalarType x, mitk::ScalarType y, mitk::ScalarType z)
Definition: mitkArray.h:110
T::Pointer GetData(const std::string &name)
virtual void RenderTubeGraphPropertyInformation(mitk::BaseRenderer *renderer)
TubeGraph::EdgeDescriptorType EdgeDescriptorType
std::pair< VertexDescriptorType, VertexDescriptorType > TubeDescriptorType
Definition: mitkTubeGraph.h:43
Property for tube graphs.
Class for elements which describes tubular structur with a circular cross section.
Base Class for Tube Graph Edges.
virtual const TubeGraph * GetInput()
itk::RGBPixel< float > Color
Color Standard RGB color typedef (float)
virtual vtkProp * GetVtkProp(mitk::BaseRenderer *renderer) override
const TubeElement * GetTubeElement() const
boost::graph_traits< GraphType >::vertex_descriptor VertexDescriptorType
virtual const Point3D & GetCoordinates() const =0
MITKMATCHPOINTREGISTRATION_EXPORT ResultImageType::Pointer map(const InputImageType *input, const RegistrationType *registration, bool throwOnOutOfInputAreaError=false, const double &paddingValue=0, const ResultImageGeometryType *resultGeometry=NULL, bool throwOnMappingError=true, const double &errorValue=0, mitk::ImageMappingInterpolator::Type interpolatorType=mitk::ImageMappingInterpolator::Linear)
std::vector< TubeElement * > GetElementVector()
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.