17 #include <vtkCellArray.h> 18 #include <vtkClipPolyData.h> 19 #include <vtkContourFilter.h> 20 #include <vtkCylinder.h> 21 #include <vtkFloatArray.h> 22 #include <vtkGeneralTransform.h> 23 #include <vtkImplicitBoolean.h> 24 #include <vtkImplicitModeller.h> 26 #include <vtkPointData.h> 27 #include <vtkPoints.h> 28 #include <vtkPolyDataMapper.h> 29 #include <vtkProperty.h> 30 #include <vtkRenderer.h> 31 #include <vtkSampleFunction.h> 32 #include <vtkSphereSource.h> 33 #include <vtkTubeFilter.h> 34 #include <vtkUnsignedIntArray.h> 56 bool renderTubeGraph(
false);
61 dynamic_cast<TubeGraphProperty *
>(tubeGraph->GetProperty(
"Tube Graph.Visualization Information").GetPointer());
63 if (tubeGraph.IsNull() || tubeGraphProperty.IsNull())
65 itkWarningMacro(<<
"Input of tube graph mapper is nullptr!");
69 if (tubeGraph->GetMTime() > ls->m_lastGenerateDataTime)
72 renderTubeGraph =
true;
78 if (tubeGraphProperty->GetMTime() > ls->m_lastRenderDataTime)
81 renderTubeGraph =
true;
87 std::vector<TubeGraph::VertexDescriptorType> alreadyRenderedVertexList;
91 alreadyRenderedVertexList.push_back(root);
94 ls->m_vtkTubesActorMap.begin();
95 itTubes != ls->m_vtkTubesActorMap.end();
98 if (tubeGraphProperty->IsTubeVisible(itTubes->first))
101 ls->m_vtkTubeGraphAssembly->AddPart(itTubes->second);
104 if (std::find(alreadyRenderedVertexList.begin(), alreadyRenderedVertexList.end(), itTubes->first.first) ==
105 alreadyRenderedVertexList.end())
107 auto itSourceSphere =
108 ls->m_vtkSpheresActorMap.find(itTubes->first.first);
109 if (itSourceSphere != ls->m_vtkSpheresActorMap.end())
110 ls->m_vtkTubeGraphAssembly->AddPart(itSourceSphere->second);
111 alreadyRenderedVertexList.push_back(itSourceSphere->first);
113 if (std::find(alreadyRenderedVertexList.begin(), alreadyRenderedVertexList.end(), itTubes->first.second) ==
114 alreadyRenderedVertexList.end())
116 auto itTargetSphere =
117 ls->m_vtkSpheresActorMap.find(itTubes->first.second);
118 if (itTargetSphere != ls->m_vtkSpheresActorMap.end())
119 ls->m_vtkTubeGraphAssembly->AddPart(itTargetSphere->second);
120 alreadyRenderedVertexList.push_back(itTargetSphere->first);
136 MITK_INFO <<
"Render tube graph property information!";
140 dynamic_cast<TubeGraphProperty *
>(tubeGraph->GetProperty(
"Tube Graph.Visualization Information").GetPointer());
142 if (tubeGraphProperty.IsNull())
144 MITK_INFO <<
"No tube graph property!! So no special render information...";
148 std::vector<TubeGraphVertex> allVertices = tubeGraph->GetVectorOfAllVertices();
149 for (
auto vertex = allVertices.begin(); vertex != allVertices.end(); ++vertex)
153 double sphereColorR = 0;
154 double sphereColorG = 0;
155 double sphereColorB = 0;
157 int numberOfVisibleEdges = 0;
158 std::vector<TubeGraphEdge> allEdgesOfVertex = tubeGraph->GetAllEdgesOfAVertex(vertexDesc);
159 for (
auto edge = allEdgesOfVertex.begin(); edge != allEdgesOfVertex.end(); ++edge)
165 std::pair<TubeGraphVertex, TubeGraphVertex> soureTargetPair = tubeGraph->GetVerticesOfAnEdge(edgeDesc);
171 tube.first = tubeGraph->GetVertexDescriptor(source);
172 tube.second = tubeGraph->GetVertexDescriptor(target);
174 if (tubeGraphProperty->IsTubeVisible(tube))
176 mitk::Color tubeColor = tubeGraphProperty->GetColorOfTube(tube);
178 vtkSmartPointer<vtkDataArray> scalars =
179 ls->m_vtkTubesActorMap[tube]->GetMapper()->GetInput()->GetPointData()->GetScalars();
181 scalars->GetTuple(0, color);
183 if (color[0] != tubeColor[0] || color[1] != tubeColor[1] || color[2] != tubeColor[2])
185 int numberOfPoints = scalars->GetSize();
187 vtkSmartPointer<vtkUnsignedCharArray> colorScalars = vtkSmartPointer<vtkUnsignedCharArray>::New();
188 colorScalars->SetName(
"colorScalars");
189 colorScalars->SetNumberOfComponents(3);
190 colorScalars->SetNumberOfTuples(numberOfPoints);
191 for (
int i = 0; i < numberOfPoints; i++)
193 scalars->InsertTuple3(i, tubeColor[0], tubeColor[1], tubeColor[2]);
195 ls->m_vtkTubesActorMap[tube]->GetMapper()->GetInput()->GetPointData()->SetActiveScalars(
"colorScalars");
198 sphereColorR += tubeColor[0];
199 sphereColorG += tubeColor[1];
200 sphereColorB += tubeColor[2];
201 numberOfVisibleEdges++;
204 if (numberOfVisibleEdges > 0)
206 sphereColorR /= 255 * numberOfVisibleEdges;
207 sphereColorG /= 255 * numberOfVisibleEdges;
208 sphereColorB /= 255 * numberOfVisibleEdges;
211 ls->m_vtkSpheresActorMap[vertexDesc]->GetProperty()->SetColor(sphereColorR, sphereColorG, sphereColorB);
213 ls->m_lastRenderDataTime.Modified();
221 ls->m_vtkTubesActorMap.clear();
222 ls->m_vtkSpheresActorMap.clear();
226 dynamic_cast<TubeGraphProperty *
>(tubeGraph->GetProperty(
"Tube Graph.Visualization Information").GetPointer());
227 if (tubeGraphProperty.IsNull())
228 MITK_INFO <<
"No tube graph property!! So no special render information...";
231 std::vector<TubeGraphEdge> allEdges = tubeGraph->GetVectorOfAllEdges();
232 for (
auto edge = allEdges.begin(); edge != allEdges.end(); ++edge)
238 std::vector<TubeGraphVertex> allVertices = tubeGraph->GetVectorOfAllVertices();
239 for (
auto vertex = allVertices.begin(); vertex != allVertices.end(); ++vertex)
242 if (this->ClipStructures())
244 this->
ClipPolyData(*vertex, tubeGraph, tubeGraphProperty, renderer);
247 ls->m_lastGenerateDataTime.Modified();
261 if (dynamic_cast<const mitk::CircularProfileTubeElement *>(vertex.
GetTubeElement()))
265 vtkSmartPointer<vtkSphereSource> sphereSource = vtkSmartPointer<vtkSphereSource>::New();
266 sphereSource->SetCenter(coordinates[0], coordinates[1], coordinates[2]);
267 sphereSource->SetRadius(diameter / 2.0f);
268 sphereSource->SetThetaResolution(12);
269 sphereSource->SetPhiResolution(12);
270 sphereSource->Update();
273 vtkSmartPointer<vtkPolyDataMapper> sphereMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
274 vtkSmartPointer<vtkActor> sphereActor = vtkSmartPointer<vtkActor>::New();
276 sphereMapper->SetInputConnection(sphereSource->GetOutputPort());
277 sphereActor->SetMapper(sphereMapper);
279 ls->m_vtkSpheresActorMap.insert(std::make_pair(graph->GetVertexDescriptor(vertex), sphereActor));
293 std::pair<TubeGraphVertex, TubeGraphVertex> soureTargetPair = graph->GetVerticesOfAnEdge(edgeDesc);
299 tube.first = graph->GetVertexDescriptor(source);
300 tube.second = graph->GetVertexDescriptor(target);
303 if (graphProperty.IsNotNull())
305 color = graphProperty->GetColorOfTube(tube);
319 vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
320 points->SetNumberOfPoints(numberOfPoints);
322 vtkSmartPointer<vtkFloatArray> radii = vtkSmartPointer<vtkFloatArray>::New();
323 radii->SetName(
"radii");
324 radii->SetNumberOfComponents(1);
326 vtkSmartPointer<vtkCellArray> lines = vtkSmartPointer<vtkCellArray>::New();
328 vtkSmartPointer<vtkUnsignedCharArray> colorScalars = vtkSmartPointer<vtkUnsignedCharArray>::New();
329 colorScalars->SetName(
"colorScalars");
330 colorScalars->SetNumberOfComponents(3);
333 radii->SetNumberOfTuples(numberOfPoints);
334 colorScalars->SetNumberOfTuples(numberOfPoints);
335 lines->InsertNextCell(numberOfPoints);
346 if (dynamic_cast<const mitk::CircularProfileTubeElement *>(source.
GetTubeElement()))
350 points->InsertPoint(
id, coordinates[0], coordinates[1], coordinates[2]);
351 radii->InsertTuple1(
id, diameter / 2.0f);
353 colorScalars->InsertTuple3(
id, color[0], color[1], color[2]);
354 lines->InsertCellPoint(
id);
361 coordinates = allElements[index]->GetCoordinates();
362 if (dynamic_cast<mitk::CircularProfileTubeElement *>(allElements[index]))
366 points->InsertPoint(
id, coordinates[0], coordinates[1], coordinates[2]);
367 radii->InsertTuple1(
id, diameter / 2.0f);
368 colorScalars->InsertTuple3(
id, color[0], color[1], color[2]);
369 lines->InsertCellPoint(
id);
375 if (dynamic_cast<const mitk::CircularProfileTubeElement *>(target.
GetTubeElement()))
379 points->InsertPoint(
id, coordinates[0], coordinates[1], coordinates[2]);
380 radii->InsertTuple1(
id, diameter / 2.0f);
381 colorScalars->InsertTuple3(
id, color[0], color[1], color[2]);
382 lines->InsertCellPoint(
id);
387 vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
388 polyData->SetPoints(points);
389 polyData->SetLines(lines);
390 polyData->GetPointData()->AddArray(radii);
391 polyData->GetPointData()->AddArray(colorScalars);
392 polyData->GetPointData()->SetActiveScalars(radii->GetName());
395 double *range = radii->GetRange();
397 assert(range[0] != 0.0f && range[1] != 0.0f);
399 vtkSmartPointer<vtkTubeFilter> tubeFilter = vtkSmartPointer<vtkTubeFilter>::New();
400 tubeFilter->SetInputData(polyData);
401 tubeFilter->SetRadius(range[0]);
402 tubeFilter->SetRadiusFactor(range[1] / range[0]);
404 if (range[0] != range[1])
405 tubeFilter->SetVaryRadiusToVaryRadiusByScalar();
407 tubeFilter->SetNumberOfSides(9);
408 tubeFilter->SidesShareVerticesOn();
409 tubeFilter->CappingOff();
410 tubeFilter->Update();
412 tubeFilter->GetOutput()->GetPointData()->SetActiveScalars(
"colorScalars");
415 vtkSmartPointer<vtkPolyDataMapper> tubeMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
416 vtkSmartPointer<vtkActor> tubeActor = vtkSmartPointer<vtkActor>::New();
418 tubeMapper->SetInputConnection(tubeFilter->GetOutputPort());
419 tubeActor->SetMapper(tubeMapper);
420 tubeActor->GetProperty()->SetColor(color[0], color[1], color[2]);
434 if (dynamic_cast<const mitk::CircularProfileTubeElement *>(vertex.
GetTubeElement()))
441 std::map<TubeGraph::TubeDescriptorType, vtkSmartPointer<vtkImplicitBoolean>> cylinderForClipping;
445 std::vector<TubeGraphEdge> allEdgesOfVertex = graph->GetAllEdgesOfAVertex(vertexDesc);
446 for (
auto edge = allEdgesOfVertex.begin(); edge != allEdgesOfVertex.end(); ++edge)
452 auto soureTargetPair = graph->GetVerticesOfAnEdge(edgeDesc);
458 tube.first = graph->GetVertexDescriptor(source);
459 tube.second = graph->GetVertexDescriptor(target);
464 double cylinderDiameter = diameter;
465 float radius = diameter / 2;
468 if (source == vertex)
471 if ((*edge).GetNumberOfElements() != 0)
473 double lastDistance = 0, distance = 0;
475 unsigned int index = 0;
477 for (; index < (*edge).GetNumberOfElements(); index++)
479 mitk::Vector3D diffVec = (*edge).GetTubeElement(index)->GetCoordinates() - centerVertex;
480 distance = std::sqrt(pow(diffVec[0], 2) + pow(diffVec[1], 2) + pow(diffVec[2], 2));
481 if (distance > radius)
483 lastDistance = distance;
486 if (index < (*edge).GetNumberOfElements())
488 double withinSphereDiameter = diameter, outsideSphereDiameter = diameter, interpolationValue = 0.5;
490 interpolationValue = (radius - lastDistance) / (distance - lastDistance);
494 if (dynamic_cast<mitk::CircularProfileTubeElement *>((*edge).GetTubeElement(0)))
495 outsideSphereDiameter =
500 if (dynamic_cast<mitk::CircularProfileTubeElement *>((*edge).GetTubeElement(index - 1)))
501 withinSphereDiameter =
504 if (dynamic_cast<mitk::CircularProfileTubeElement *>((*edge).GetTubeElement(index)))
505 outsideSphereDiameter =
510 (1 - interpolationValue) * withinSphereDiameter + interpolationValue * outsideSphereDiameter;
513 edgeDirectionPoint = (*edge).GetTubeElement(0)->GetCoordinates();
526 if ((*edge).GetNumberOfElements() != 0)
528 double lastDistance = 0, distance = 0;
530 int index = (*edge).GetNumberOfElements();
531 for ( ; index >= 0; --index)
533 mitk::Vector3D diffVec = (*edge).GetTubeElement(index)->GetCoordinates() - centerVertex;
534 distance = std::sqrt(pow(diffVec[0], 2) + pow(diffVec[1], 2) + pow(diffVec[2], 2));
535 if (distance > radius)
537 lastDistance = distance;
542 double withinSphereDiameter = diameter, outsideSphereDiameter = diameter, interpolationValue = 0.5;
544 interpolationValue = (radius - lastDistance) / (distance - lastDistance);
546 if (index == static_cast<int>((*edge).GetNumberOfElements() - 1))
548 if (dynamic_cast<mitk::CircularProfileTubeElement *>(
549 (*edge).GetTubeElement((*edge).GetNumberOfElements() - 1)))
550 outsideSphereDiameter = (dynamic_cast<mitk::CircularProfileTubeElement *>(
551 (*edge).GetTubeElement((*edge).GetNumberOfElements() - 1)))
556 if (dynamic_cast<mitk::CircularProfileTubeElement *>((*edge).GetTubeElement(index + 1)))
557 withinSphereDiameter =
560 if (dynamic_cast<mitk::CircularProfileTubeElement *>((*edge).GetTubeElement(index)))
561 outsideSphereDiameter =
566 (1 - interpolationValue) * withinSphereDiameter + interpolationValue * outsideSphereDiameter;
569 edgeDirectionPoint = (*edge).GetTubeElement((*edge).GetNumberOfElements() - 1)->GetCoordinates();
582 (edgeDirectionPoint[0] - centerVertex[0]),
583 (edgeDirectionPoint[1] - centerVertex[1]),
584 (edgeDirectionPoint[2] - centerVertex[2]));
585 vecOrientation.Normalize();
589 mitk::FillVector3D(vecRandom, (rand() % 100 - 50), (rand() % 100 - 50), (rand() % 100 - 50));
592 vecOrthoToOrientation = vecRandom - (vecRandom * vecOrientation) * vecOrientation;
593 vecOrthoToOrientation.Normalize();
597 vecCrossProduct = itk::CrossProduct(vecOrientation, vecOrthoToOrientation);
598 vecCrossProduct.Normalize();
601 vtkSmartPointer<vtkMatrix4x4> vtkTransformMatrix = vtkSmartPointer<vtkMatrix4x4>::New();
602 vtkTransformMatrix->Identity();
604 vtkTransformMatrix->SetElement(0, 0, vecOrthoToOrientation[0]);
605 vtkTransformMatrix->SetElement(1, 0, vecOrthoToOrientation[1]);
606 vtkTransformMatrix->SetElement(2, 0, vecOrthoToOrientation[2]);
608 vtkTransformMatrix->SetElement(0, 1, vecOrientation[0]);
609 vtkTransformMatrix->SetElement(1, 1, vecOrientation[1]);
610 vtkTransformMatrix->SetElement(2, 1, vecOrientation[2]);
612 vtkTransformMatrix->SetElement(0, 2, vecCrossProduct[0]);
613 vtkTransformMatrix->SetElement(1, 2, vecCrossProduct[1]);
614 vtkTransformMatrix->SetElement(2, 2, vecCrossProduct[2]);
616 vtkTransformMatrix->SetElement(0, 3, centerVertex[0]);
617 vtkTransformMatrix->SetElement(1, 3, centerVertex[1]);
618 vtkTransformMatrix->SetElement(2, 3, centerVertex[2]);
620 vtkSmartPointer<vtkGeneralTransform> transform = vtkSmartPointer<vtkGeneralTransform>::New();
621 transform->Concatenate(vtkTransformMatrix);
624 transform->Inverse();
628 vtkSmartPointer<vtkPlane> plane = vtkSmartPointer<vtkPlane>::New();
629 plane->SetOrigin(0, 0, 0);
630 plane->SetNormal(0, 1, 0);
633 vtkSmartPointer<vtkCylinder> cylinder = vtkSmartPointer<vtkCylinder>::New();
634 cylinder->SetCenter(0, 0, 0);
635 cylinder->SetRadius(cylinderDiameter / 2);
639 vtkSmartPointer<vtkImplicitBoolean> cutCylinder = vtkSmartPointer<vtkImplicitBoolean>::New();
640 cutCylinder->SetOperationTypeToDifference();
641 cutCylinder->SetTransform(transform);
642 cutCylinder->AddFunction(cylinder);
643 cutCylinder->AddFunction(plane);
645 cylinderForClipping.insert(
671 double sphereColorR = 0;
672 double sphereColorG = 0;
673 double sphereColorB = 0;
675 for (
auto itClipStructure =
676 cylinderForClipping.begin();
677 itClipStructure != cylinderForClipping.end();
680 vtkSmartPointer<vtkPolyDataMapper> sphereMapper =
681 dynamic_cast<vtkPolyDataMapper *
>(ls->m_vtkSpheresActorMap[vertexDesc]->GetMapper());
683 if (sphereMapper !=
nullptr)
686 vtkSmartPointer<vtkClipPolyData> clipperSphere = vtkSmartPointer<vtkClipPolyData>::New();
687 clipperSphere->SetInputData(sphereMapper->GetInput());
688 clipperSphere->SetClipFunction(itClipStructure->second);
689 clipperSphere->GenerateClippedOutputOn();
690 clipperSphere->Update();
692 sphereMapper->SetInputConnection(clipperSphere->GetOutputPort());
693 sphereMapper->Update();
696 mitk::Color tubeColor = graphProperty->GetColorOfTube(itClipStructure->first);
697 sphereColorR += tubeColor[0];
698 sphereColorG += tubeColor[1];
699 sphereColorB += tubeColor[2];
702 for (
auto itTobBeClipped =
703 cylinderForClipping.begin();
704 itTobBeClipped != cylinderForClipping.end();
709 if (itClipStructure->first != toBeClippedTube)
711 vtkSmartPointer<vtkPolyDataMapper> tubeMapper =
712 dynamic_cast<vtkPolyDataMapper *
>(ls->m_vtkTubesActorMap[toBeClippedTube]->GetMapper());
714 if (tubeMapper !=
nullptr)
717 vtkSmartPointer<vtkClipPolyData> clipperTube = vtkSmartPointer<vtkClipPolyData>::New();
718 tubeMapper->Update();
719 clipperTube->SetInputData(tubeMapper->GetInput());
720 clipperTube->SetClipFunction(itClipStructure->second);
721 clipperTube->GenerateClippedOutputOn();
722 clipperTube->Update();
724 tubeMapper->SetInputConnection(clipperTube->GetOutputPort());
725 tubeMapper->Update();
730 if (cylinderForClipping.size() != 0)
732 sphereColorR /= 255 * cylinderForClipping.size();
733 sphereColorG /= 255 * cylinderForClipping.size();
734 sphereColorB /= 255 * cylinderForClipping.size();
737 ls->m_vtkSpheresActorMap[vertexDesc]->GetProperty()->SetColor(sphereColorR, sphereColorG, sphereColorB);
740 bool mitk::TubeGraphVtkMapper3D::ClipStructures()
745 itkWarningMacro(<<
"associated node is nullptr!");
749 bool clipStructures =
false;
750 node->GetBoolProperty(
"Tube Graph.Clip Structures", clipStructures);
752 return clipStructures;
L * GetLocalStorage(mitk::BaseRenderer *forRenderer)
Retrieves a LocalStorage for a specific BaseRenderer.
void GenerateDataForRenderer(mitk::BaseRenderer *renderer) override
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)
virtual DataNode * GetDataNode() const
Get the DataNode containing the data to map. Method only returns valid DataNode Pointer if the mapper...
Base Class for Tube Graphs.
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)
virtual void RenderTubeGraphPropertyInformation(mitk::BaseRenderer *renderer)
BaseData * GetData() const
Get the data object (instance of BaseData, e.g., an Image) managed by this DataNode.
TubeGraph::EdgeDescriptorType EdgeDescriptorType
std::pair< VertexDescriptorType, VertexDescriptorType > TubeDescriptorType
Property for tube graphs.
~TubeGraphVtkMapper3D() override
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)
const TubeElement * GetTubeElement() const
vtkProp * GetVtkProp(mitk::BaseRenderer *renderer) override
boost::graph_traits< GraphType >::vertex_descriptor VertexDescriptorType
virtual const Point3D & GetCoordinates() const =0
std::vector< TubeElement * > GetElementVector()
unsigned int GetNumberOfElements() const