diff --git a/Modules/TubeGraph/src/Rendering/mitkTubeGraphVtkMapper3D.cpp b/Modules/TubeGraph/src/Rendering/mitkTubeGraphVtkMapper3D.cpp index a93bfd5371..864d163416 100644 --- a/Modules/TubeGraph/src/Rendering/mitkTubeGraphVtkMapper3D.cpp +++ b/Modules/TubeGraph/src/Rendering/mitkTubeGraphVtkMapper3D.cpp @@ -1,753 +1,753 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkTubeGraphVtkMapper3D.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include -#include +#include mitk::TubeGraphVtkMapper3D::TubeGraphVtkMapper3D() { } mitk::TubeGraphVtkMapper3D::~TubeGraphVtkMapper3D() { } const mitk::TubeGraph *mitk::TubeGraphVtkMapper3D::GetInput() { return dynamic_cast(GetDataNode()->GetData()); } vtkProp *mitk::TubeGraphVtkMapper3D::GetVtkProp(mitk::BaseRenderer *renderer) { return m_LSH.GetLocalStorage(renderer)->m_vtkTubeGraphAssembly; } void mitk::TubeGraphVtkMapper3D::GenerateDataForRenderer(mitk::BaseRenderer *renderer) { bool renderTubeGraph(false); LocalStorage *ls = m_LSH.GetLocalStorage(renderer); TubeGraph::Pointer tubeGraph = const_cast(this->GetInput()); TubeGraphProperty::Pointer tubeGraphProperty = dynamic_cast(tubeGraph->GetProperty("Tube Graph.Visualization Information").GetPointer()); if (tubeGraph.IsNull() || tubeGraphProperty.IsNull()) { itkWarningMacro(<< "Input of tube graph mapper is nullptr!"); return; } // Check if the tube graph has changed; if the data has changed, generate the spheres and tubes new; if (tubeGraph->GetMTime() > ls->m_lastGenerateDataTime) { this->GenerateTubeGraphData(renderer); renderTubeGraph = true; } else { // Check if the tube graph property has changed; if the property has changed, render the visualization information // new; if (tubeGraphProperty->GetMTime() > ls->m_lastRenderDataTime) { this->RenderTubeGraphPropertyInformation(renderer); renderTubeGraph = true; } } if (renderTubeGraph) { std::vector alreadyRenderedVertexList; // don't render the sphere which is the root of the graph; so add it to the list before; // TODO check both spheres TubeGraph::VertexDescriptorType root = tubeGraph->GetRootVertex(); alreadyRenderedVertexList.push_back(root); for (auto itTubes = ls->m_vtkTubesActorMap.begin(); itTubes != ls->m_vtkTubesActorMap.end(); itTubes++) { if (tubeGraphProperty->IsTubeVisible(itTubes->first)) { // add tube actor to assembly ls->m_vtkTubeGraphAssembly->AddPart(itTubes->second); // render the clipped spheres as end-cups of a tube and connections between tubes if (std::find(alreadyRenderedVertexList.begin(), alreadyRenderedVertexList.end(), itTubes->first.first) == alreadyRenderedVertexList.end()) { auto itSourceSphere = ls->m_vtkSpheresActorMap.find(itTubes->first.first); if (itSourceSphere != ls->m_vtkSpheresActorMap.end()) ls->m_vtkTubeGraphAssembly->AddPart(itSourceSphere->second); alreadyRenderedVertexList.push_back(itSourceSphere->first); } if (std::find(alreadyRenderedVertexList.begin(), alreadyRenderedVertexList.end(), itTubes->first.second) == alreadyRenderedVertexList.end()) { auto itTargetSphere = ls->m_vtkSpheresActorMap.find(itTubes->first.second); if (itTargetSphere != ls->m_vtkSpheresActorMap.end()) ls->m_vtkTubeGraphAssembly->AddPart(itTargetSphere->second); alreadyRenderedVertexList.push_back(itTargetSphere->first); } } } } //// Opacity TODO //{ // float opacity = 1.0f; // if( this->GetDataNode()->GetOpacity(opacity,renderer) ) // ls->m_vtkTubesActor->GetProperty()->SetOpacity( opacity ); //} } void mitk::TubeGraphVtkMapper3D::RenderTubeGraphPropertyInformation(mitk::BaseRenderer *renderer) { MITK_INFO << "Render tube graph property information!"; LocalStorage *ls = m_LSH.GetLocalStorage(renderer); TubeGraph::ConstPointer tubeGraph = this->GetInput(); TubeGraphProperty::Pointer tubeGraphProperty = dynamic_cast(tubeGraph->GetProperty("Tube Graph.Visualization Information").GetPointer()); if (tubeGraphProperty.IsNull()) { MITK_INFO << "No tube graph property!! So no special render information..."; return; } std::vector allVertices = tubeGraph->GetVectorOfAllVertices(); for (auto vertex = allVertices.begin(); vertex != allVertices.end(); ++vertex) { TubeGraph::VertexDescriptorType vertexDesc = tubeGraph->GetVertexDescriptor(*vertex); double sphereColorR = 0; double sphereColorG = 0; double sphereColorB = 0; int numberOfVisibleEdges = 0; std::vector allEdgesOfVertex = tubeGraph->GetAllEdgesOfAVertex(vertexDesc); for (auto edge = allEdgesOfVertex.begin(); edge != allEdgesOfVertex.end(); ++edge) { // get edge descriptor EdgeDescriptorType edgeDesc = tubeGraph->GetEdgeDescriptor(*edge); // get source and target vertex descriptor std::pair soureTargetPair = tubeGraph->GetVerticesOfAnEdge(edgeDesc); TubeGraphVertex source = soureTargetPair.first; TubeGraphVertex target = soureTargetPair.second; // build tube descriptor [sourceId,targetId] TubeGraph::TubeDescriptorType tube; tube.first = tubeGraph->GetVertexDescriptor(source); tube.second = tubeGraph->GetVertexDescriptor(target); if (tubeGraphProperty->IsTubeVisible(tube)) { mitk::Color tubeColor = tubeGraphProperty->GetColorOfTube(tube); vtkSmartPointer scalars = ls->m_vtkTubesActorMap[tube]->GetMapper()->GetInput()->GetPointData()->GetScalars(); double color[3]; scalars->GetTuple(0, color); if (color[0] != tubeColor[0] || color[1] != tubeColor[1] || color[2] != tubeColor[2]) { int numberOfPoints = scalars->GetSize(); vtkSmartPointer colorScalars = vtkSmartPointer::New(); colorScalars->SetName("colorScalars"); colorScalars->SetNumberOfComponents(3); colorScalars->SetNumberOfTuples(numberOfPoints); for (int i = 0; i < numberOfPoints; i++) { scalars->InsertTuple3(i, tubeColor[0], tubeColor[1], tubeColor[2]); } ls->m_vtkTubesActorMap[tube]->GetMapper()->GetInput()->GetPointData()->SetActiveScalars("colorScalars"); } sphereColorR += tubeColor[0]; sphereColorG += tubeColor[1]; sphereColorB += tubeColor[2]; numberOfVisibleEdges++; } } if (numberOfVisibleEdges > 0) { sphereColorR /= 255 * numberOfVisibleEdges; sphereColorG /= 255 * numberOfVisibleEdges; sphereColorB /= 255 * numberOfVisibleEdges; } ls->m_vtkSpheresActorMap[vertexDesc]->GetProperty()->SetColor(sphereColorR, sphereColorG, sphereColorB); } ls->m_lastRenderDataTime.Modified(); } void mitk::TubeGraphVtkMapper3D::GenerateTubeGraphData(mitk::BaseRenderer *renderer) { MITK_INFO << "Render tube graph!"; LocalStorage *ls = m_LSH.GetLocalStorage(renderer); ls->m_vtkTubesActorMap.clear(); ls->m_vtkSpheresActorMap.clear(); TubeGraph::Pointer tubeGraph = const_cast(this->GetInput()); TubeGraphProperty::Pointer tubeGraphProperty = dynamic_cast(tubeGraph->GetProperty("Tube Graph.Visualization Information").GetPointer()); if (tubeGraphProperty.IsNull()) MITK_INFO << "No tube graph property!! So no special render information..."; // render all edges as tubular structures using the vtkTubeFilter std::vector allEdges = tubeGraph->GetVectorOfAllEdges(); for (auto edge = allEdges.begin(); edge != allEdges.end(); ++edge) { this->GeneratePolyDataForTube(*edge, tubeGraph, tubeGraphProperty, renderer); } // Generate all vertices as spheres std::vector allVertices = tubeGraph->GetVectorOfAllVertices(); for (auto vertex = allVertices.begin(); vertex != allVertices.end(); ++vertex) { this->GeneratePolyDataForFurcation(*vertex, tubeGraph, renderer); if (this->ClipStructures()) { this->ClipPolyData(*vertex, tubeGraph, tubeGraphProperty, renderer); } ls->m_lastGenerateDataTime.Modified(); } } void mitk::TubeGraphVtkMapper3D::GeneratePolyDataForFurcation(mitk::TubeGraphVertex &vertex, const mitk::TubeGraph::Pointer &graph, mitk::BaseRenderer *renderer) { LocalStorage *ls = this->m_LSH.GetLocalStorage(renderer); mitk::Point3D coordinates; float diameter = 2; coordinates = (vertex.GetTubeElement())->GetCoordinates(); if (dynamic_cast(vertex.GetTubeElement())) { diameter = (dynamic_cast(vertex.GetTubeElement()))->GetDiameter(); } vtkSmartPointer sphereSource = vtkSmartPointer::New(); sphereSource->SetCenter(coordinates[0], coordinates[1], coordinates[2]); sphereSource->SetRadius(diameter / 2.0f); sphereSource->SetThetaResolution(12); sphereSource->SetPhiResolution(12); sphereSource->Update(); // generate a actor with a mapper for the sphere vtkSmartPointer sphereMapper = vtkSmartPointer::New(); vtkSmartPointer sphereActor = vtkSmartPointer::New(); sphereMapper->SetInputConnection(sphereSource->GetOutputPort()); sphereActor->SetMapper(sphereMapper); ls->m_vtkSpheresActorMap.insert(std::make_pair(graph->GetVertexDescriptor(vertex), sphereActor)); } void mitk::TubeGraphVtkMapper3D::GeneratePolyDataForTube(mitk::TubeGraphEdge &edge, const mitk::TubeGraph::Pointer &graph, const mitk::TubeGraphProperty::Pointer &graphProperty, mitk::BaseRenderer *renderer) { LocalStorage *ls = this->m_LSH.GetLocalStorage(renderer); // get edge descriptor EdgeDescriptorType edgeDesc = graph->GetEdgeDescriptor(edge); // get source and target vertex descriptor std::pair soureTargetPair = graph->GetVerticesOfAnEdge(edgeDesc); TubeGraphVertex source = soureTargetPair.first; TubeGraphVertex target = soureTargetPair.second; // build tube descriptor [sourceId,targetId] TubeGraph::TubeDescriptorType tube; tube.first = graph->GetVertexDescriptor(source); tube.second = graph->GetVertexDescriptor(target); Color color; if (graphProperty.IsNotNull()) { color = graphProperty->GetColorOfTube(tube); } else { color[0] = 150; color[1] = 150; color[2] = 150; } // add 2 points for the source and target vertices. unsigned int numberOfPoints = edge.GetNumberOfElements() + 2; // Initialize the required data-structures for building // an appropriate input to the tube filter vtkSmartPointer points = vtkSmartPointer::New(); points->SetNumberOfPoints(numberOfPoints); vtkSmartPointer radii = vtkSmartPointer::New(); radii->SetName("radii"); radii->SetNumberOfComponents(1); vtkSmartPointer lines = vtkSmartPointer::New(); vtkSmartPointer colorScalars = vtkSmartPointer::New(); colorScalars->SetName("colorScalars"); colorScalars->SetNumberOfComponents(3); // resize the data-arrays radii->SetNumberOfTuples(numberOfPoints); colorScalars->SetNumberOfTuples(numberOfPoints); lines->InsertNextCell(numberOfPoints); // Add the positions of the source node, the elements along the edge and // the target node as lines to a cell. This cell is used as input // for a Tube Filter mitk::Point3D coordinates; float diameter = 2; unsigned int id = 0; // Source Node coordinates = (source.GetTubeElement())->GetCoordinates(); if (dynamic_cast(source.GetTubeElement())) { diameter = (dynamic_cast(source.GetTubeElement()))->GetDiameter(); } points->InsertPoint(id, coordinates[0], coordinates[1], coordinates[2]); radii->InsertTuple1(id, diameter / 2.0f); colorScalars->InsertTuple3(id, color[0], color[1], color[2]); lines->InsertCellPoint(id); ++id; // Iterate along the edge std::vector allElements = edge.GetElementVector(); for (unsigned int index = 0; index < edge.GetNumberOfElements(); index++) { coordinates = allElements[index]->GetCoordinates(); if (dynamic_cast(allElements[index])) { diameter = (dynamic_cast(allElements[index]))->GetDiameter(); } points->InsertPoint(id, coordinates[0], coordinates[1], coordinates[2]); radii->InsertTuple1(id, diameter / 2.0f); colorScalars->InsertTuple3(id, color[0], color[1], color[2]); lines->InsertCellPoint(id); ++id; } // Target Node coordinates = (target.GetTubeElement())->GetCoordinates(); if (dynamic_cast(target.GetTubeElement())) { diameter = (dynamic_cast(target.GetTubeElement()))->GetDiameter(); } points->InsertPoint(id, coordinates[0], coordinates[1], coordinates[2]); radii->InsertTuple1(id, diameter / 2.0f); colorScalars->InsertTuple3(id, color[0], color[1], color[2]); lines->InsertCellPoint(id); ++id; // Initialize poly data from the point set and the cell array // (representing topology) vtkSmartPointer polyData = vtkSmartPointer::New(); polyData->SetPoints(points); polyData->SetLines(lines); polyData->GetPointData()->AddArray(radii); polyData->GetPointData()->AddArray(colorScalars); polyData->GetPointData()->SetActiveScalars(radii->GetName()); // Generate a tube for all lines in the polydata object double *range = radii->GetRange(); assert(range[0] != 0.0f && range[1] != 0.0f); vtkSmartPointer tubeFilter = vtkSmartPointer::New(); tubeFilter->SetInputData(polyData); tubeFilter->SetRadius(range[0]); tubeFilter->SetRadiusFactor(range[1] / range[0]); if (range[0] != range[1]) tubeFilter->SetVaryRadiusToVaryRadiusByScalar(); tubeFilter->SetNumberOfSides(9); tubeFilter->SidesShareVerticesOn(); tubeFilter->CappingOff(); tubeFilter->Update(); tubeFilter->GetOutput()->GetPointData()->SetActiveScalars("colorScalars"); // generate a actor with a mapper for the vtkSmartPointer tubeMapper = vtkSmartPointer::New(); vtkSmartPointer tubeActor = vtkSmartPointer::New(); tubeMapper->SetInputConnection(tubeFilter->GetOutputPort()); tubeActor->SetMapper(tubeMapper); tubeActor->GetProperty()->SetColor(color[0], color[1], color[2]); ls->m_vtkTubesActorMap.insert(std::pair>(tube, tubeActor)); } void mitk::TubeGraphVtkMapper3D::ClipPolyData(mitk::TubeGraphVertex &vertex, const mitk::TubeGraph::Pointer &graph, const mitk::TubeGraphProperty::Pointer &graphProperty, mitk::BaseRenderer *renderer) { LocalStorage *ls = this->m_LSH.GetLocalStorage(renderer); mitk::Point3D centerVertex = vertex.GetTubeElement()->GetCoordinates(); float diameter = 2; if (dynamic_cast(vertex.GetTubeElement())) { diameter = (dynamic_cast(vertex.GetTubeElement()))->GetDiameter(); } TubeGraph::VertexDescriptorType vertexDesc = graph->GetVertexDescriptor(vertex); std::map> cylinderForClipping; // generate for all edges/tubes cylinders. With this structure you can clip the sphere and the other tubes, so that no // fragments are shown in the tube. std::vector allEdgesOfVertex = graph->GetAllEdgesOfAVertex(vertexDesc); for (auto edge = allEdgesOfVertex.begin(); edge != allEdgesOfVertex.end(); ++edge) { // get edge descriptor EdgeDescriptorType edgeDesc = graph->GetEdgeDescriptor(*edge); // get source and target vertex descriptor auto soureTargetPair = graph->GetVerticesOfAnEdge(edgeDesc); TubeGraphVertex source = soureTargetPair.first; TubeGraphVertex target = soureTargetPair.second; // build tube descriptor [sourceId,targetId] TubeGraph::TubeDescriptorType tube; tube.first = graph->GetVertexDescriptor(source); tube.second = graph->GetVertexDescriptor(target); // get reference point in the tube for the direction mitk::Point3D edgeDirectionPoint; // get reference diameter double cylinderDiameter = diameter; float radius = diameter / 2; // if the vertex is the source vertex of the edge get the first element of elementVector; otherwise get the last // element. if (source == vertex) { // if the edge has no element get the other vertex if ((*edge).GetNumberOfElements() != 0) { double lastDistance = 0, distance = 0; unsigned int index = 0; // Get the first element behind the radius of the sphere for (; index < (*edge).GetNumberOfElements(); index++) { mitk::Vector3D diffVec = (*edge).GetTubeElement(index)->GetCoordinates() - centerVertex; distance = std::sqrt(pow(diffVec[0], 2) + pow(diffVec[1], 2) + pow(diffVec[2], 2)); if (distance > radius) break; lastDistance = distance; } // if the last element is not inside the sphere if (index < (*edge).GetNumberOfElements()) { double withinSphereDiameter = diameter, outsideSphereDiameter = diameter, interpolationValue = 0.5; interpolationValue = (radius - lastDistance) / (distance - lastDistance); // if first element is outside of the sphere use sphere diameter and the element diameter for interpolation if (index == 0) { if (dynamic_cast((*edge).GetTubeElement(0))) outsideSphereDiameter = (dynamic_cast((*edge).GetTubeElement(0)))->GetDiameter(); } else { if (dynamic_cast((*edge).GetTubeElement(index - 1))) withinSphereDiameter = (dynamic_cast((*edge).GetTubeElement(index - 1)))->GetDiameter(); if (dynamic_cast((*edge).GetTubeElement(index))) outsideSphereDiameter = (dynamic_cast((*edge).GetTubeElement(index)))->GetDiameter(); } // interpolate the diameter for clipping cylinderDiameter = (1 - interpolationValue) * withinSphereDiameter + interpolationValue * outsideSphereDiameter; } // Get the reference point, so the direction of the tube can be calculated edgeDirectionPoint = (*edge).GetTubeElement(0)->GetCoordinates(); } else { // Get the reference point, so the direction of the tube can be calculated edgeDirectionPoint = target.GetTubeElement()->GetCoordinates(); } } // if vertex is target of the tube else { // if the edge has no element, get the other vertex if ((*edge).GetNumberOfElements() != 0) { double lastDistance = 0, distance = 0; // Get the first element behind the radius of the sphere; now backwards through the element list int index = (*edge).GetNumberOfElements(); for ( ; index >= 0; --index) { mitk::Vector3D diffVec = (*edge).GetTubeElement(index)->GetCoordinates() - centerVertex; distance = std::sqrt(pow(diffVec[0], 2) + pow(diffVec[1], 2) + pow(diffVec[2], 2)); if (distance > radius) break; lastDistance = distance; } if (index >= 0) { double withinSphereDiameter = diameter, outsideSphereDiameter = diameter, interpolationValue = 0.5; interpolationValue = (radius - lastDistance) / (distance - lastDistance); if (index == static_cast((*edge).GetNumberOfElements() - 1)) { if (dynamic_cast( (*edge).GetTubeElement((*edge).GetNumberOfElements() - 1))) outsideSphereDiameter = (dynamic_cast( (*edge).GetTubeElement((*edge).GetNumberOfElements() - 1))) ->GetDiameter(); } else { if (dynamic_cast((*edge).GetTubeElement(index + 1))) withinSphereDiameter = (dynamic_cast((*edge).GetTubeElement(index + 1)))->GetDiameter(); if (dynamic_cast((*edge).GetTubeElement(index))) outsideSphereDiameter = (dynamic_cast((*edge).GetTubeElement(index)))->GetDiameter(); } // interpolate the diameter for clipping cylinderDiameter = (1 - interpolationValue) * withinSphereDiameter + interpolationValue * outsideSphereDiameter; } // Get the reference point, so the direction of the tube can be calculated edgeDirectionPoint = (*edge).GetTubeElement((*edge).GetNumberOfElements() - 1)->GetCoordinates(); } else { // Get the reference point, so the direction of the tube can be calculated edgeDirectionPoint = source.GetTubeElement()->GetCoordinates(); } } //////Calculate the matrix for rotation and translation//// // get the normalized vector for the orientation (tube element direction) mitk::Vector3D vecOrientation; mitk::FillVector3D(vecOrientation, (edgeDirectionPoint[0] - centerVertex[0]), (edgeDirectionPoint[1] - centerVertex[1]), (edgeDirectionPoint[2] - centerVertex[2])); vecOrientation.Normalize(); // generate a random vector mitk::Vector3D vecRandom; mitk::FillVector3D(vecRandom, (rand() % 100 - 50), (rand() % 100 - 50), (rand() % 100 - 50)); // project the random vector on the plane-->orthogonal vector to plane normal; normalize it! mitk::Vector3D vecOrthoToOrientation; vecOrthoToOrientation = vecRandom - (vecRandom * vecOrientation) * vecOrientation; vecOrthoToOrientation.Normalize(); // get the cross product of both orthogonale vectors to get a third one mitk::Vector3D vecCrossProduct; vecCrossProduct = itk::CrossProduct(vecOrientation, vecOrthoToOrientation); vecCrossProduct.Normalize(); // Fill matrix vtkSmartPointer vtkTransformMatrix = vtkSmartPointer::New(); vtkTransformMatrix->Identity(); // 1. column vtkTransformMatrix->SetElement(0, 0, vecOrthoToOrientation[0]); vtkTransformMatrix->SetElement(1, 0, vecOrthoToOrientation[1]); vtkTransformMatrix->SetElement(2, 0, vecOrthoToOrientation[2]); // 2. column vtkTransformMatrix->SetElement(0, 1, vecOrientation[0]); vtkTransformMatrix->SetElement(1, 1, vecOrientation[1]); vtkTransformMatrix->SetElement(2, 1, vecOrientation[2]); // 3. column vtkTransformMatrix->SetElement(0, 2, vecCrossProduct[0]); vtkTransformMatrix->SetElement(1, 2, vecCrossProduct[1]); vtkTransformMatrix->SetElement(2, 2, vecCrossProduct[2]); // 4. column vtkTransformMatrix->SetElement(0, 3, centerVertex[0]); vtkTransformMatrix->SetElement(1, 3, centerVertex[1]); vtkTransformMatrix->SetElement(2, 3, centerVertex[2]); vtkSmartPointer transform = vtkSmartPointer::New(); transform->Concatenate(vtkTransformMatrix); // transform->Translate(centerVertex[0],centerVertex[1],centerVertex[2]); transform->Inverse(); transform->Update(); // Generate plane in center [0,0,0] with n= (0,1,0) as normal vector vtkSmartPointer plane = vtkSmartPointer::New(); plane->SetOrigin(0, 0, 0); plane->SetNormal(0, 1, 0); // Generate a cylinder in center [0,0,0] and the axes of rotation is along the y-axis; radius is vertex diameter/2; vtkSmartPointer cylinder = vtkSmartPointer::New(); cylinder->SetCenter(0, 0, 0); cylinder->SetRadius(cylinderDiameter / 2); // cylinder->SetTransform(transform); // Truncate the infinite cylinder with the plane vtkSmartPointer cutCylinder = vtkSmartPointer::New(); cutCylinder->SetOperationTypeToDifference(); cutCylinder->SetTransform(transform); cutCylinder->AddFunction(cylinder); cutCylinder->AddFunction(plane); cylinderForClipping.insert( std::pair>(tube, cutCylinder)); //// Sample the function // vtkSmartPointer sample = vtkSmartPointer::New(); // sample->SetSampleDimensions(100,100,100); // sample->SetImplicitFunction(cutCylinder); ////double value = 200.0; // double xmin = centerVertex[0]-(2*diameter), xmax = centerVertex[0]+(2*diameter), // ymin = centerVertex[1]-(2*diameter), ymax = centerVertex[1]+(2*diameter), // zmin = centerVertex[2]-(2*diameter), zmax = centerVertex[2]+(2*diameter); // sample->SetModelBounds(xmin, xmax, ymin, ymax, zmin, zmax); // vtkSmartPointer contour =vtkSmartPointer::New(); // contour->SetInputConnection(sample->GetOutputPort()); // contour->SetValue( 0, 0.25); // vtkSmartPointer impMapper = vtkSmartPointer::New(); // impMapper->SetInputConnection (contour->GetOutputPort()); // impMapper->ScalarVisibilityOff(); // vtkSmartPointer impActor = vtkSmartPointer::New(); // impActor->SetMapper(impMapper); // ls->m_vtkTubeGraphAssembly->AddPart(impActor); } double sphereColorR = 0; double sphereColorG = 0; double sphereColorB = 0; for (auto itClipStructure = cylinderForClipping.begin(); itClipStructure != cylinderForClipping.end(); itClipStructure++) { vtkSmartPointer sphereMapper = dynamic_cast(ls->m_vtkSpheresActorMap[vertexDesc]->GetMapper()); if (sphereMapper != nullptr) { // first clip the sphere with the cylinder vtkSmartPointer clipperSphere = vtkSmartPointer::New(); clipperSphere->SetInputData(sphereMapper->GetInput()); clipperSphere->SetClipFunction(itClipStructure->second); clipperSphere->GenerateClippedOutputOn(); clipperSphere->Update(); sphereMapper->SetInputConnection(clipperSphere->GetOutputPort()); sphereMapper->Update(); } mitk::Color tubeColor = graphProperty->GetColorOfTube(itClipStructure->first); sphereColorR += tubeColor[0]; sphereColorG += tubeColor[1]; sphereColorB += tubeColor[2]; // than clip with all other tubes for (auto itTobBeClipped = cylinderForClipping.begin(); itTobBeClipped != cylinderForClipping.end(); itTobBeClipped++) { TubeGraph::TubeDescriptorType toBeClippedTube = itTobBeClipped->first; if (itClipStructure->first != toBeClippedTube) { vtkSmartPointer tubeMapper = dynamic_cast(ls->m_vtkTubesActorMap[toBeClippedTube]->GetMapper()); if (tubeMapper != nullptr) { // first clip the sphere with the cylinder vtkSmartPointer clipperTube = vtkSmartPointer::New(); tubeMapper->Update(); clipperTube->SetInputData(tubeMapper->GetInput()); clipperTube->SetClipFunction(itClipStructure->second); clipperTube->GenerateClippedOutputOn(); clipperTube->Update(); tubeMapper->SetInputConnection(clipperTube->GetOutputPort()); tubeMapper->Update(); } } } } if (cylinderForClipping.size() != 0) { sphereColorR /= 255 * cylinderForClipping.size(); sphereColorG /= 255 * cylinderForClipping.size(); sphereColorB /= 255 * cylinderForClipping.size(); } ls->m_vtkSpheresActorMap[vertexDesc]->GetProperty()->SetColor(sphereColorR, sphereColorG, sphereColorB); } bool mitk::TubeGraphVtkMapper3D::ClipStructures() { DataNode::Pointer node = this->GetDataNode(); if (node.IsNull()) { itkWarningMacro(<< "associated node is nullptr!"); return false; } bool clipStructures = false; node->GetBoolProperty("Tube Graph.Clip Structures", clipStructures); return clipStructures; }