diff --git a/Modules/TubeGraph/include/mitkTubeGraphVtkMapper3D.h b/Modules/TubeGraph/include/mitkTubeGraphVtkMapper3D.h index bef19cb3eb..4ba43eee9e 100644 --- a/Modules/TubeGraph/include/mitkTubeGraphVtkMapper3D.h +++ b/Modules/TubeGraph/include/mitkTubeGraphVtkMapper3D.h @@ -1,120 +1,120 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef TubeGraphVtkMapper3D_H_HEADER_INCLUDED #define TubeGraphVtkMapper3D_H_HEADER_INCLUDED #include #include #include "mitkCircularProfileTubeElement.h" #include "mitkTubeGraph.h" #include "mitkTubeGraphProperty.h" -#include "mitkVtkMapper3D.h" +#include "mitkVtkMapper.h" #include #include #include #include #include namespace mitk { /** * 3D Mapper for mitk::Graph< TubeGraphVertex, TubeGraphEdge >. This mapper creates tubes * around each tubular structure by using vtkTubeFilter. * */ - class MITKTUBEGRAPH_EXPORT TubeGraphVtkMapper3D : public VtkMapper3D + class MITKTUBEGRAPH_EXPORT TubeGraphVtkMapper3D : public VtkMapper { public: /* Typedefs */ typedef TubeGraph::EdgeDescriptorType EdgeDescriptorType; typedef TubeGraph::VertexDescriptorType VertexDescriptorType; - mitkClassMacro(TubeGraphVtkMapper3D, VtkMapper3D); + mitkClassMacro(TubeGraphVtkMapper3D, VtkMapper); itkNewMacro(Self); /** * Returns the input data object of the given filter. In this * case, a mitk::Graph< TubeGraphVertex, TubeGraphEdge > is returned. */ virtual const TubeGraph *GetInput(); virtual vtkProp *GetVtkProp(mitk::BaseRenderer *renderer) override; protected: TubeGraphVtkMapper3D(); virtual ~TubeGraphVtkMapper3D(); /** * This method is called, each time a specific renderer is updated. */ virtual void GenerateDataForRenderer(mitk::BaseRenderer *renderer) override; /** * Generate vtkPolyData containing the tube centerlines and * sets these as input for a vtkTubeFilter, which generates tubes * around the edges. Also generates vtkActors for each vertex. Here * the vtkPolyData are vtkSphereSources. All poly data will be clipped * with each other on an furcation. So you get end-caps and connecting * pieces from the spheres. Clipping the tubes with each other avoids * structures within the general view. */ virtual void GenerateTubeGraphData(mitk::BaseRenderer *renderer); /** * Render only the visual information like color or visibility new. */ virtual void RenderTubeGraphPropertyInformation(mitk::BaseRenderer *renderer); /** * Converts a single tube into a vtkPolyData. Each point of the * tube surface is labeled with the tube id. */ void GeneratePolyDataForTube(TubeGraphEdge &edge, const TubeGraph::Pointer &graph, const TubeGraphProperty::Pointer &graphProperty, mitk::BaseRenderer *renderer); void GeneratePolyDataForFurcation(TubeGraphVertex &vertex, const TubeGraph::Pointer &graph, mitk::BaseRenderer *renderer); void ClipPolyData(TubeGraphVertex &vertex, const TubeGraph::Pointer &graph, const TubeGraphProperty::Pointer &graphProperty, mitk::BaseRenderer *renderer); private: bool ClipStructures(); class LocalStorage : public mitk::Mapper::BaseLocalStorage { public: vtkSmartPointer m_vtkTubeGraphAssembly; std::map> m_vtkTubesActorMap; std::map> m_vtkSpheresActorMap; itk::TimeStamp m_lastGenerateDataTime; itk::TimeStamp m_lastRenderDataTime; LocalStorage() { m_vtkTubeGraphAssembly = vtkSmartPointer::New(); } ~LocalStorage() {} }; LocalStorageHandler m_LSH; }; } // namespace #endif diff --git a/Modules/TubeGraph/include/mitkUndirectedGraph.h b/Modules/TubeGraph/include/mitkUndirectedGraph.h index 27f90adffe..85ba99cba0 100644 --- a/Modules/TubeGraph/include/mitkUndirectedGraph.h +++ b/Modules/TubeGraph/include/mitkUndirectedGraph.h @@ -1,178 +1,177 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef _MITK_UndirectedGraph_H #define _MITK_UndirectedGraph_H #include #ifndef Q_MOC_RUN #include #endif /* definition of basic boost::graph properties */ enum vertex_properties_t { vertex_properties }; enum edge_properties_t { edge_properties }; namespace boost { BOOST_INSTALL_PROPERTY(vertex, properties); BOOST_INSTALL_PROPERTY(edge, properties); } namespace mitk { /** * \brief Template class for undirected graphs.Paramters should be the vertex and edge classes, which contains the * information. */ template class UndirectedGraph : public BaseData { public: //--- Typedefs ---// typedef TVertex VertexType; typedef TEdge EdgeType; /** * Creating the graph type * listS: Represents the OutEdgeList as a std::list * vecS: Represents the VertexList as a std::vector * undirectedS: Representation for an undirected graph * VertexProperty: Defines that all vertex are represented by VertexType * EdgeProperty: Defines that all edges are represented by EdgeType */ typedef boost::adjacency_list, boost::property> GraphType; /* a bunch of graph-specific typedefs */ typedef typename boost::graph_traits::vertex_descriptor VertexDescriptorType; typedef typename boost::graph_traits::edge_descriptor EdgeDescriptorType; typedef typename boost::graph_traits::vertex_iterator VertexIteratorType; typedef typename boost::graph_traits::edge_iterator EdgeIteratorType; typedef typename boost::graph_traits::adjacency_iterator AdjacenyIteratorType; typedef typename boost::graph_traits::out_edge_iterator OutEdgeIteratorType; typedef typename boost::graph_traits::in_edge_iterator InEdgeIteratorType; //--- Macros ---// mitkClassMacro(UndirectedGraph, BaseData); itkNewMacro(Self); // virtual methods that need to be implemented virtual void UpdateOutputInformation() override { if (this->GetSource()) this->GetSource()->UpdateOutputInformation(); } virtual void SetRequestedRegionToLargestPossibleRegion() override {} virtual bool RequestedRegionIsOutsideOfTheBufferedRegion() override { return false; } virtual bool VerifyRequestedRegion() override { return true; } - virtual void SetRequestedRegion(const itk::DataObject *data) override {} + virtual void SetRequestedRegion(const itk::DataObject *) override {} /** Add a new vertex to the graph */ VertexDescriptorType AddVertex(const VertexType &vertexData); /** Remove the vertex from the graph */ void RemoveVertex(const VertexDescriptorType &vertex); /** Get the vertex data of the given vertex descriptor */ VertexType GetVertex(const VertexDescriptorType &vertex); /** Set the vertex data of the given vertex descriptor */ void SetVertex(const VertexDescriptorType &vertex, const VertexType &vertexData); /**Returns the descriptor if the vertex exist in the graph, otherwise undefined*/ VertexDescriptorType GetVertexDescriptor(const VertexType &vertexData) const; /** Add a new edge between the given vertices to the graph */ EdgeDescriptorType AddEdge(const VertexDescriptorType &vertexA, const VertexDescriptorType &vertexB, const EdgeType &edgeData); /** Remove the edge from the graph */ void RemoveEdge(const EdgeDescriptorType &edge); /** Get the edge data of the given edge descriptor */ EdgeType GetEdge(const EdgeDescriptorType &edge); /** Set the edge data of the given edge descriptor */ void SetEdge(const EdgeDescriptorType &edge, const EdgeType &edgeData); /**Returns the descriptor if the edge exist in the graph, otherwise undefined*/ EdgeDescriptorType GetEdgeDescriptor(const EdgeType &edgeData) const; /** Get parent and target vertex of the given edge*/ std::pair GetVerticesOfAnEdge(const EdgeDescriptorType &edge) const; /** Returns the edge descriptor from the edge which has the given vertices as source and target */ EdgeDescriptorType GetEdgeDescriptorByVerices(const VertexDescriptorType &vertexA, const VertexDescriptorType &vertexB) const; /** Get all edges of the given vertex */ std::vector GetAllEdgesOfAVertex(const VertexDescriptorType &vertex) const; /** Get overall number of vertices in the graph */ int GetNumberOfVertices() const; /** get overall number of edges in the graph */ int GetNumberOfEdges() const; /** get vector containing all the vertices of the graph*/ std::vector GetVectorOfAllVertices() const; /** get vector containing all the edges of the network */ std::vector GetVectorOfAllEdges() const; /** clear the graph */ void Clear() override; /** get the graph */ const GraphType &GetGraph() const; UndirectedGraph &operator=(const UndirectedGraph &rhs); protected: UndirectedGraph(); - UndirectedGraph(const UndirectedGraph &graph); virtual ~UndirectedGraph(); GraphType m_Graph; private: /** property access for vertices */ VertexType &properties(const VertexDescriptorType &vertex); /** property access for vertices */ const VertexType &properties(const VertexDescriptorType &vertex) const; /** property access for edges */ EdgeType &properties(const EdgeDescriptorType &edge); /** property access for edges */ const EdgeType &properties(const EdgeDescriptorType &edge) const; }; } // namespace mitk #include "mitkUndirectedGraph.txx" #endif /* _MITK_UndirectedGraph_H */ diff --git a/Modules/TubeGraph/include/mitkUndirectedGraph.txx b/Modules/TubeGraph/include/mitkUndirectedGraph.txx index cb36149af2..fbfe84222a 100644 --- a/Modules/TubeGraph/include/mitkUndirectedGraph.txx +++ b/Modules/TubeGraph/include/mitkUndirectedGraph.txx @@ -1,346 +1,340 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef _mitkUndirectedGraph_txx #define _mitkUndirectedGraph_txx namespace mitk { template - UndirectedGraph::UndirectedGraph() : m_Graph(NULL) - { - } - - template - UndirectedGraph::UndirectedGraph(const UndirectedGraph &graph) - : m_Graph(graph.m_Graph) + UndirectedGraph::UndirectedGraph() { } template UndirectedGraph::~UndirectedGraph() { } template typename UndirectedGraph::VertexDescriptorType UndirectedGraph::AddVertex( const typename UndirectedGraph::VertexType &vertexData) { VertexDescriptorType vertex = boost::add_vertex(m_Graph); this->properties(vertex) = vertexData; this->Modified(); return vertex; } template void UndirectedGraph::RemoveVertex( const typename UndirectedGraph::VertexDescriptorType &vertex) { boost::clear_vertex(vertex, m_Graph); boost::remove_vertex(vertex, m_Graph); this->Modified(); } template typename UndirectedGraph::VertexType UndirectedGraph::GetVertex( const typename UndirectedGraph::VertexDescriptorType &vertex) { return this->properties(vertex); } template void UndirectedGraph::SetVertex( const typename UndirectedGraph::VertexDescriptorType &vertex, const typename UndirectedGraph::VertexType &vertexData) { this->properties(vertex) = vertexData; this->Modified(); } template typename UndirectedGraph::VertexDescriptorType UndirectedGraph::GetVertexDescriptor( const typename UndirectedGraph::VertexType &vertexData) const { typename UndirectedGraph::VertexIteratorType iterator, end; boost::tie(iterator, end) = boost::vertices(m_Graph); for (; iterator != end; ++iterator) { typename UndirectedGraph::VertexType tempVertex; // the value of an iterator is a descriptor tempVertex = this->properties(*iterator); if (vertexData == tempVertex) return *iterator; } MITK_ERROR << "Error in mitkUndirectedGraph::GetVertexDescriptor(...): vertex could not be found." << std::endl; throw std::runtime_error( "Exception thrown in mitkUndirectedGraph::GetVertexDescriptor(...): vertex could not be found."); } template typename UndirectedGraph::EdgeDescriptorType UndirectedGraph::AddEdge( const typename UndirectedGraph::VertexDescriptorType &vertexA, const typename UndirectedGraph::VertexDescriptorType &vertexB, const typename UndirectedGraph::EdgeType &edgeData) { EdgeDescriptorType edge; bool inserted = false; boost::tie(edge, inserted) = boost::add_edge(vertexA, vertexB, m_Graph); if (!inserted) { MITK_ERROR << "Error in mitkUndirectedGraph::addEdge(...): edge could not be inserted." << std::endl; throw std::runtime_error("Exception thrown in mitkUndirectedGraph::addEdge(...): edge could not be inserted."); } this->properties(edge) = edgeData; this->Modified(); return edge; } template void UndirectedGraph::RemoveEdge( const typename UndirectedGraph::EdgeDescriptorType &edge) { boost::remove_edge(edge, m_Graph); this->Modified(); } template typename UndirectedGraph::EdgeType UndirectedGraph::GetEdge( const typename UndirectedGraph::EdgeDescriptorType &edge) { return this->properties(edge); } template void UndirectedGraph::SetEdge( const typename UndirectedGraph::EdgeDescriptorType &edge, const typename UndirectedGraph::EdgeType &edgeData) { this->properties(edge) = edgeData; this->Modified(); } template typename UndirectedGraph::EdgeDescriptorType UndirectedGraph::GetEdgeDescriptor( const typename UndirectedGraph::EdgeType &edgeData) const { typename UndirectedGraph::EdgeIteratorType iterator, end; boost::tie(iterator, end) = boost::edges(m_Graph); for (; iterator != end; ++iterator) { typename UndirectedGraph::EdgeType tempEdge; // the value of an iterator is a descriptor tempEdge = this->properties(*iterator); if (edgeData == tempEdge) return iterator.dereference(); } // if no edge match, throw error MITK_ERROR << "Error in mitkUndirectedGraph::GetEdgeDescriptor(...): edge could not be found." << std::endl; throw std::runtime_error( "Exception thrown in mitkUndirectedGraph::GetEdgeDescriptor(...): edge could not be found."); } template std::pair::VertexType, typename UndirectedGraph::VertexType> UndirectedGraph::GetVerticesOfAnEdge( const typename UndirectedGraph::EdgeDescriptorType &edge) const { typename UndirectedGraph::VertexType sourceNode, targetNode; sourceNode = this->properties(boost::source(edge, m_Graph)); targetNode = this->properties(boost::target(edge, m_Graph)); std::pair::VertexType, typename UndirectedGraph::VertexType> nodePair(sourceNode, targetNode); return nodePair; } template typename UndirectedGraph::EdgeDescriptorType UndirectedGraph::GetEdgeDescriptorByVerices( const typename UndirectedGraph::VertexDescriptorType &vertexA, const typename UndirectedGraph::VertexDescriptorType &vertexB) const { typename UndirectedGraph::EdgeDescriptorType edge; bool edgeExists(false); boost::tie(edge, edgeExists) = boost::edge(vertexA, vertexB, m_Graph); if (edgeExists) return edge; else { MITK_ERROR << "Error in mitkUndirectedGraph::GetEdgeDescriptorByVerices(...): edge could not be found." << std::endl; throw std::runtime_error( "Exception thrown in mitkUndirectedGraph::GetEdgeDescriptorByVerices(...): edge could not be found."); } } template std::vector::EdgeType> UndirectedGraph::GetAllEdgesOfAVertex( const typename UndirectedGraph::VertexDescriptorType &vertex) const { typename UndirectedGraph::OutEdgeIteratorType iterator, end; boost::tie(iterator, end) = boost::out_edges(vertex, m_Graph); std::vector::EdgeType> vectorOfEdges; for (; iterator != end; ++iterator) { typename UndirectedGraph::EdgeType tempEdge; // the value of an iterator is a descriptor tempEdge = this->properties(*iterator); vectorOfEdges.push_back(tempEdge); } return vectorOfEdges; } template int UndirectedGraph::GetNumberOfVertices() const { // Returns the number of vertices in the graph return boost::num_vertices(m_Graph); } template int UndirectedGraph::GetNumberOfEdges() const { // Returns the number of edges in the graph return boost::num_edges(m_Graph); } template std::vector::VertexType> UndirectedGraph::GetVectorOfAllVertices() const { typename UndirectedGraph::VertexIteratorType iterator, end; // sets iterator to start end end to end boost::tie(iterator, end) = boost::vertices(m_Graph); std::vector::VertexType> vectorOfNodes; for (; iterator != end; ++iterator) { typename UndirectedGraph::VertexType tempVertex; // the value of an iterator is a descriptor tempVertex = this->properties(*iterator); vectorOfNodes.push_back(tempVertex); } return vectorOfNodes; } template std::vector::EdgeType> UndirectedGraph::GetVectorOfAllEdges() const { typename UndirectedGraph::EdgeIteratorType iterator, end; // sets iterator to start end end to end boost::tie(iterator, end) = boost::edges(m_Graph); std::vector::EdgeType> vectorOfEdges; for (; iterator != end; ++iterator) { typename UndirectedGraph::EdgeType tempEdge; // the value of an iterator is a descriptor tempEdge = this->properties(*iterator); vectorOfEdges.push_back(tempEdge); } return vectorOfEdges; } template void UndirectedGraph::Clear() { m_Graph.clear(); this->Modified(); } template const typename UndirectedGraph::GraphType &UndirectedGraph::GetGraph() const { return m_Graph; } /* operators */ template UndirectedGraph &UndirectedGraph::operator=( const UndirectedGraph &rhs) { m_Graph = rhs.m_Graph; return *this; } template TVertex &UndirectedGraph::properties( const typename UndirectedGraph::VertexDescriptorType &vertex) { typename boost::property_map::type param = boost::get(vertex_properties, m_Graph); return param[vertex]; } template const TVertex &UndirectedGraph::properties( const typename UndirectedGraph::VertexDescriptorType &vertex) const { typename boost::property_map::const_type param = boost::get(vertex_properties, m_Graph); return param[vertex]; } template TEdge &UndirectedGraph::properties( const typename UndirectedGraph::EdgeDescriptorType &edge) { typename boost::property_map::type param = boost::get(edge_properties, m_Graph); return param[edge]; } template const TEdge &UndirectedGraph::properties( const typename UndirectedGraph::EdgeDescriptorType &edge) const { typename boost::property_map::const_type param = boost::get(edge_properties, m_Graph); return param[edge]; } } // namespace mitk #endif //_mitkUndirectedGraph_txx diff --git a/Modules/TubeGraph/src/DataStructure/mitkTubeGraph.cpp b/Modules/TubeGraph/src/DataStructure/mitkTubeGraph.cpp index 8ae4786625..b7c5f4647e 100644 --- a/Modules/TubeGraph/src/DataStructure/mitkTubeGraph.cpp +++ b/Modules/TubeGraph/src/DataStructure/mitkTubeGraph.cpp @@ -1,300 +1,276 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkTubeGraph.h" #include "mitkGeometry3D.h" const mitk::TubeGraph::TubeDescriptorType mitk::TubeGraph::ErrorId = std::pair(boost::graph_traits::null_vertex(), boost::graph_traits::null_vertex()); mitk::TubeGraph::TubeGraph() { } mitk::TubeGraph::TubeGraph(const mitk::TubeGraph &graph) : UndirectedGraph(graph) { } mitk::TubeGraph::~TubeGraph() { } std::vector mitk::TubeGraph::SearchShortestPath( - const TubeDescriptorType &startTube, const TubeDescriptorType &endTube /*, std::vector barrier*/) + const TubeDescriptorType &, const TubeDescriptorType &) { std::vector shortestPath; - /* - EdgeDescriptorType startEdge = boost::edge(startTube.first, startTube.second, m_Graph).first; - - std::vector< DescriptorType > predecessorMap( boost::num_vertices( *boostGraph ) ); - int numberOfNodes( boost::num_vertices( *boostGraph ) ); - - m_DistanceMatrix.resize( numberOfNodes ); - for( int index(0); index < m_DistanceMatrix.size(); index++ ) - { - m_DistanceMatrix[ index ].resize( numberOfNodes ); - } - - IteratorType iterator, end; - boost::tie(iterator, end) = boost::vertices( *boostGraph ); - - for ( int index(0) ; iterator != end; ++iterator, index++) - { - boost::dijkstra_shortest_paths(*boostGraph, *iterator, boost::predecessor_map(&predecessorMap[ 0 - ]).distance_map(&m_DistanceMatrix[ index ][ 0 ]).weight_map( boost::get( - &mitk::ConnectomicsNetwork::NetworkEdge::edge_weight ,*boostGraph ) ) ) ; - } - - - */ return shortestPath; } std::vector mitk::TubeGraph::SearchAllPathBetweenVertices( const mitk::TubeGraph::TubeDescriptorType &startTube, const mitk::TubeGraph::TubeDescriptorType &endTube /*, std::vector barrier*/) { // http://lists.boost.org/boost-users/att-9001/maze.cpp // http://www.boost.org/doc/libs/1_49_0/libs/graph/example/bfs.cpp typedef std::map EdgeMap; typedef boost::associative_property_map PredecessorMap; typedef boost::edge_predecessor_recorder PredecessorVisitor; typedef boost::dfs_visitor> DFSVisitor; EdgeMap edgesMap; PredecessorMap predecessorMap(edgesMap); PredecessorVisitor predecessorVisitor(predecessorMap); boost::null_visitor nullVisitor; DFSVisitor visitor = boost::make_dfs_visitor(std::make_pair(predecessorVisitor, nullVisitor)); std::map vertexColorMap; std::map edgeColorMap; boost::undirected_dfs( m_Graph, visitor, make_assoc_property_map(vertexColorMap), make_assoc_property_map(edgeColorMap), startTube.second); std::vector solutionPath; solutionPath.push_back(endTube); VertexDescriptorType pathEdgeSource = endTube.first; VertexDescriptorType pathEdgeTarget; MITK_INFO << "Source: [" << startTube.first << "," << startTube.second << "] Target: [" << endTube.first << "," << endTube.second << "]"; MITK_INFO << "tube [" << endTube.first << "," << endTube.second << "]"; do { if (pathEdgeSource == 10393696) break; EdgeDescriptorType edge = get(predecessorMap, pathEdgeSource); pathEdgeSource = boost::source(edge, m_Graph); pathEdgeTarget = boost::target(edge, m_Graph); TubeDescriptorType tube(pathEdgeSource, pathEdgeTarget); MITK_INFO << "tube [" << tube.first << "," << tube.second << "]"; solutionPath.push_back(tube); } while (pathEdgeSource != startTube.second); return solutionPath; } std::vector mitk::TubeGraph::SearchPathToPeriphery( const mitk::TubeGraph::TubeDescriptorType &startTube /*, std::vector barrier*/) { std::vector pathToPeriphery; if (m_RootTube == ErrorId) { m_RootTube = this->GetThickestTube(); if (m_Root == m_RootTube.first) m_Root = m_RootTube.second; else m_Root = m_RootTube.first; } // Attention!! No check which one is the right one DirectedGraphType directedGraph = this->GetDirectedGraph(m_Root); // Only the target vertex: it's a directed Graph, and we want only the "after tube" tubes and the clicked ones // this->GetOutEdgesOfAVertex(startTube.first, directedGraph, pathToPeriphery); pathToPeriphery.push_back(startTube); this->GetOutEdgesOfAVertex(startTube.second, directedGraph, pathToPeriphery); return pathToPeriphery; } void mitk::TubeGraph::GetOutEdgesOfAVertex(mitk::TubeGraph::VertexDescriptorType vertex, mitk::TubeGraph::DirectedGraphType &directedGraph, std::vector &pathToPeriphery) { typedef boost::graph_traits::out_edge_iterator OutEdgeIteratorType; std::pair outEdges = boost::out_edges(vertex, directedGraph); for (; outEdges.first != outEdges.second; ++outEdges.first) { TubeDescriptorType tube; tube.first = boost::source(*outEdges.first, directedGraph); tube.second = boost::target(*outEdges.first, directedGraph); if (std::find(pathToPeriphery.begin(), pathToPeriphery.end(), tube) == pathToPeriphery.end()) { pathToPeriphery.push_back(tube); this->GetOutEdgesOfAVertex(tube.second, directedGraph, pathToPeriphery); } } } mitk::TubeGraph::TubeDescriptorType mitk::TubeGraph::GetThickestTube() { TubeDescriptorType thickestTube; float tubeDiameter = 0.0; EdgeIteratorType iterator, end; boost::tie(iterator, end) = boost::edges(m_Graph); for (; iterator != end; ++iterator) { TubeGraphEdge edge = this->GetEdge(*iterator); std::pair soureTargetPair = this->GetVerticesOfAnEdge(*iterator); float tempDiameter = edge.GetEdgeAverageDiameter(soureTargetPair.first, soureTargetPair.second); if (tempDiameter > tubeDiameter) { tubeDiameter = tempDiameter; thickestTube.first = this->GetVertexDescriptor(soureTargetPair.first); thickestTube.second = this->GetVertexDescriptor(soureTargetPair.second); } } return thickestTube; } mitk::TubeGraph::DirectedGraphType mitk::TubeGraph::GetDirectedGraph(VertexDescriptorType startVertex) { DirectedGraphType directedGraph(boost::num_vertices(m_Graph)); DirectedGraphBfsVisitor vis(this, directedGraph); boost::breadth_first_search(m_Graph, startVertex, visitor(vis)); return directedGraph; } mitk::TubeGraph::Pointer mitk::TubeGraph::CreateSubGraph(std::vector subGraphTubes) { TubeGraph::Pointer subGraph = new TubeGraph(); // store the descriptor from origin graph to the correspondent new descriptors std::map vertexDescriptorOldToNewMap; // add a new edge and if necessary also the vertices of each tube to the new sub graph for (auto it = subGraphTubes.begin(); it != subGraphTubes.end(); it++) { // search for the source vertex in the subgraph; if it is already added continue, otherwise add it if (vertexDescriptorOldToNewMap.find(it->first) == vertexDescriptorOldToNewMap.end()) { // add the vertex to the subgraph VertexDescriptorType newVertexDescriptor = subGraph->AddVertex(this->GetVertex(it->first)); // add the pair of descriptor from the origin graph to the descriptor from the subgraph vertexDescriptorOldToNewMap.insert( std::pair(it->first, newVertexDescriptor)); } // and now...search for the target vertex... if (vertexDescriptorOldToNewMap.find(it->second) == vertexDescriptorOldToNewMap.end()) { VertexDescriptorType newVertexDescriptor = subGraph->AddVertex(this->GetVertex(it->second)); vertexDescriptorOldToNewMap.insert( std::pair(it->second, newVertexDescriptor)); } // Get the EdgeDescriptor from origin graph EdgeDescriptorType edgeDescriptor = this->GetEdgeDescriptorByVerices(it->first, it->second); TubeGraphEdge oldEdge = this->GetEdge(edgeDescriptor); // AddEdge needs the source vertex, the target vertex and the edge data // source Vertex: get the subgraph VertexDescriptor by the origin descriptor (tubeDescriptor->first)from the // assigning map // target Vertex: get the subgraph VertexDescriptor by the origin descriptor (tubeDescriptor->second)from the // assigning map // edge data: copy the TubeGraphEdge object using the origin edge desciptor and the origin graph VertexDescriptorType sourceVertex = vertexDescriptorOldToNewMap[it->first]; VertexDescriptorType targetVertex = vertexDescriptorOldToNewMap[it->second]; - EdgeDescriptorType newEdgeDescriptor = subGraph->AddEdge(sourceVertex, targetVertex, this->GetEdge(edgeDescriptor)); + subGraph->AddEdge(sourceVertex, targetVertex, this->GetEdge(edgeDescriptor)); } subGraph->CopyInformation(this); mitk::Geometry3D::Pointer geometry = mitk::Geometry3D::New(); geometry->Initialize(); subGraph->SetGeometry(geometry); this->Modified(); return subGraph; } void mitk::TubeGraph::RemoveSubGraph(std::vector deletedTubes) { for (auto it = deletedTubes.begin(); it != deletedTubes.end(); it++) { VertexDescriptorType source = it->first; VertexDescriptorType target = it->second; EdgeDescriptorType edge = this->GetEdgeDescriptorByVerices(source, target); this->RemoveEdge(edge); if (this->GetAllEdgesOfAVertex(source).size() == 0) { this->RemoveVertex(source); } if (this->GetAllEdgesOfAVertex(target).size() == 0) { this->RemoveVertex(target); } } this->Modified(); } void mitk::TubeGraph::SetRootTube(const TubeDescriptorType &root) { if (root != TubeGraph::ErrorId) { m_RootTube = root; if (m_Root == root.first) m_Root = root.second; else m_Root = root.first; this->Modified(); } } void mitk::TubeGraph::SetRoot(const VertexDescriptorType &root) { if (root != TubeGraph::ErrorId.first) { m_Root = root; } } mitk::TubeGraph::TubeDescriptorType mitk::TubeGraph::GetRootTube() { return m_RootTube; } mitk::TubeGraph::VertexDescriptorType mitk::TubeGraph::GetRootVertex() { return m_Root; } mitk::TubeGraph &mitk::TubeGraph::operator=(const mitk::TubeGraph &rhs) { UndirectedGraph::operator=(rhs); return *this; } diff --git a/Modules/TubeGraph/src/IO/mitkTubeGraphIO.cpp b/Modules/TubeGraph/src/IO/mitkTubeGraphIO.cpp index d8134317b1..61d35234fc 100644 --- a/Modules/TubeGraph/src/IO/mitkTubeGraphIO.cpp +++ b/Modules/TubeGraph/src/IO/mitkTubeGraphIO.cpp @@ -1,609 +1,597 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkTubeGraphIO.h" #include "mitkCircularProfileTubeElement.h" #include "mitkTubeGraphDefinitions.h" #include "mitkTubeGraphProperty.h" #include #include #include #include namespace mitk { TubeGraphIO::TubeGraphIO(const TubeGraphIO &other) : AbstractFileIO(other) {} TubeGraphIO::TubeGraphIO() : AbstractFileIO( mitk::TubeGraph::GetStaticNameOfClass(), mitk::TubeGraphIO::TUBEGRAPH_MIMETYPE(), "Tube Graph Structure File") { this->RegisterService(); } std::vector TubeGraphIO::Read() { std::locale::global(std::locale("C")); std::vector> result; InputStream stream(this); TiXmlDocument doc; stream >> doc; if (!doc.Error()) { TubeGraph::Pointer newTubeGraph = TubeGraph::New(); TiXmlHandle hDoc(&doc); TiXmlElement *pElem; TiXmlHandle hRoot(0); pElem = hDoc.FirstChildElement().Element(); // save this for later hRoot = TiXmlHandle(pElem); pElem = hRoot.FirstChildElement(mitk::TubeGraphDefinitions::XML_GEOMETRY).Element(); // read geometry mitk::Geometry3D::Pointer geometry = mitk::Geometry3D::New(); geometry->Initialize(); // read origin mitk::Point3D origin; double temp = 0; pElem->Attribute(mitk::TubeGraphDefinitions::XML_ORIGIN_X, &temp); origin[0] = temp; pElem->Attribute(mitk::TubeGraphDefinitions::XML_ORIGIN_Y, &temp); origin[1] = temp; pElem->Attribute(mitk::TubeGraphDefinitions::XML_ORIGIN_Z, &temp); origin[2] = temp; geometry->SetOrigin(origin); // read spacing Vector3D spacing; pElem->Attribute(mitk::TubeGraphDefinitions::XML_SPACING_X, &temp); spacing.SetElement(0, temp); pElem->Attribute(mitk::TubeGraphDefinitions::XML_SPACING_Y, &temp); spacing.SetElement(1, temp); pElem->Attribute(mitk::TubeGraphDefinitions::XML_SPACING_Z, &temp); spacing.SetElement(2, temp); geometry->SetSpacing(spacing); // read transform vtkMatrix4x4 *m = vtkMatrix4x4::New(); pElem->Attribute(mitk::TubeGraphDefinitions::XML_MATRIX_XX, &temp); m->SetElement(0, 0, temp); pElem->Attribute(mitk::TubeGraphDefinitions::XML_MATRIX_XY, &temp); m->SetElement(1, 0, temp); pElem->Attribute(mitk::TubeGraphDefinitions::XML_MATRIX_XZ, &temp); m->SetElement(2, 0, temp); pElem->Attribute(mitk::TubeGraphDefinitions::XML_MATRIX_YX, &temp); m->SetElement(0, 1, temp); pElem->Attribute(mitk::TubeGraphDefinitions::XML_MATRIX_YY, &temp); m->SetElement(1, 1, temp); pElem->Attribute(mitk::TubeGraphDefinitions::XML_MATRIX_YZ, &temp); m->SetElement(2, 1, temp); pElem->Attribute(mitk::TubeGraphDefinitions::XML_MATRIX_ZX, &temp); m->SetElement(0, 2, temp); pElem->Attribute(mitk::TubeGraphDefinitions::XML_MATRIX_ZY, &temp); m->SetElement(1, 2, temp); pElem->Attribute(mitk::TubeGraphDefinitions::XML_MATRIX_ZZ, &temp); m->SetElement(2, 2, temp); m->SetElement(0, 3, origin[0]); m->SetElement(1, 3, origin[1]); m->SetElement(2, 3, origin[2]); m->SetElement(3, 3, 1); geometry->SetIndexToWorldTransformByVtkMatrix(m); geometry->SetImageGeometry(false); // read tube graph // read vertices pElem = hRoot.FirstChildElement(mitk::TubeGraphDefinitions::XML_VERTICES).Element(); if (pElem != 0) { // walk through the vertices - TiXmlElement *vertexElement = pElem->FirstChildElement(); - - for (vertexElement; vertexElement; vertexElement = vertexElement->NextSiblingElement()) + for (TiXmlElement *vertexElement = pElem->FirstChildElement(); vertexElement != nullptr; vertexElement = vertexElement->NextSiblingElement()) { int vertexID(0); mitk::Point3D coordinate; coordinate.Fill(0.0); double diameter(0); vertexElement->Attribute(mitk::TubeGraphDefinitions::XML_VERTEX_ID, &vertexID); TiXmlElement *tubeElement = vertexElement->FirstChildElement(); tubeElement->Attribute(mitk::TubeGraphDefinitions::XML_ELEMENT_X, &temp); coordinate[0] = temp; tubeElement->Attribute(mitk::TubeGraphDefinitions::XML_ELEMENT_Y, &temp); coordinate[1] = temp; tubeElement->Attribute(mitk::TubeGraphDefinitions::XML_ELEMENT_Z, &temp); coordinate[2] = temp; tubeElement->Attribute(mitk::TubeGraphDefinitions::XML_ELEMENT_DIAMETER, &diameter); mitk::TubeGraphVertex vertexData; mitk::CircularProfileTubeElement *newElement = new mitk::CircularProfileTubeElement(coordinate, diameter); vertexData.SetTubeElement(newElement); mitk::TubeGraph::VertexDescriptorType newVertex = newTubeGraph->AddVertex(vertexData); - if (newVertex != vertexID) + if (static_cast(newVertex) != vertexID) { MITK_ERROR << "Aborting tube graph creation, different vertex ids."; return result; ; } } } // read edges pElem = hRoot.FirstChildElement(mitk::TubeGraphDefinitions::XML_EDGES).Element(); - if (pElem != 0) + if (pElem != nullptr) { // walk through the edges - TiXmlElement *edgeElement = pElem->FirstChildElement(); - - for (edgeElement; edgeElement; edgeElement = edgeElement->NextSiblingElement()) + auto edgeElement = pElem->FirstChildElement(); + for ( ; edgeElement != nullptr; edgeElement = edgeElement->NextSiblingElement()) { int edgeID(0), edgeSourceID(0), edgeTargetID(0); mitk::Point3D coordinate; double diameter(0); edgeElement->Attribute(mitk::TubeGraphDefinitions::XML_EDGE_ID, &edgeID); edgeElement->Attribute(mitk::TubeGraphDefinitions::XML_EDGE_SOURCE_ID, &edgeSourceID); edgeElement->Attribute(mitk::TubeGraphDefinitions::XML_EDGE_TARGET_ID, &edgeTargetID); mitk::TubeGraphEdge edgeData; - TiXmlElement *tubeElement = edgeElement->FirstChildElement(mitk::TubeGraphDefinitions::XML_ELEMENT); - for (tubeElement; tubeElement; tubeElement = tubeElement->NextSiblingElement()) + for (TiXmlElement *tubeElement = edgeElement->FirstChildElement(mitk::TubeGraphDefinitions::XML_ELEMENT); tubeElement != nullptr; tubeElement = tubeElement->NextSiblingElement()) { tubeElement->Attribute(mitk::TubeGraphDefinitions::XML_ELEMENT_X, &temp); coordinate[0] = temp; tubeElement->Attribute(mitk::TubeGraphDefinitions::XML_ELEMENT_Y, &temp); coordinate[1] = temp; tubeElement->Attribute(mitk::TubeGraphDefinitions::XML_ELEMENT_Z, &temp); coordinate[2] = temp; tubeElement->Attribute(mitk::TubeGraphDefinitions::XML_ELEMENT_DIAMETER, &diameter); mitk::CircularProfileTubeElement *newElement = new mitk::CircularProfileTubeElement(coordinate, diameter); edgeData.AddTubeElement(newElement); } try { newTubeGraph->AddEdge(edgeSourceID, edgeTargetID, edgeData); } catch (const std::runtime_error &error) { MITK_ERROR << error.what(); return result; } } } // Compute bounding box BoundingBox::Pointer bb = this->ComputeBoundingBox(newTubeGraph); geometry->SetBounds(bb->GetBounds()); MITK_INFO << "Tube Graph read"; MITK_INFO << "Edge numb:" << newTubeGraph->GetNumberOfEdges() << " Vertices: " << newTubeGraph->GetNumberOfVertices(); MITK_INFO << "Reading tube graph property"; mitk::TubeGraphProperty::Pointer newProperty = mitk::TubeGraphProperty::New(); // read label groups pElem = hRoot.FirstChildElement(mitk::TubeGraphDefinitions::XML_LABELGROUPS).Element(); if (pElem != 0) { // walk through the label groups - TiXmlElement *labelGroupElement = pElem->FirstChildElement(); - - for (labelGroupElement; labelGroupElement; labelGroupElement = labelGroupElement->NextSiblingElement()) + for (TiXmlElement *labelGroupElement = pElem->FirstChildElement(); labelGroupElement != nullptr; labelGroupElement = labelGroupElement->NextSiblingElement()) { mitk::TubeGraphProperty::LabelGroup *newLabelGroup = new mitk::TubeGraphProperty::LabelGroup(); const char *labelGroupName; labelGroupName = labelGroupElement->Attribute((char *)mitk::TubeGraphDefinitions::XML_LABELGROUP_NAME.c_str()); if (labelGroupName) newLabelGroup->labelGroupName = labelGroupName; - // labelGroupElement->Attribute(mitk::TubeGraphDefinitions::XML_LABELGROUP_NAME, &labelGroupName); - // newLabelGroup.labeGroupName = labelGroupName; - - TiXmlElement *labelElement = labelGroupElement->FirstChildElement(mitk::TubeGraphDefinitions::XML_LABEL); - for (labelElement; labelElement; labelElement = labelElement->NextSiblingElement()) + for (TiXmlElement *labelElement = labelGroupElement->FirstChildElement(mitk::TubeGraphDefinitions::XML_LABEL); labelElement != nullptr; labelElement = labelElement->NextSiblingElement()) { mitk::TubeGraphProperty::LabelGroup::Label *newLabel = new mitk::TubeGraphProperty::LabelGroup::Label(); const char *labelName; bool isVisible = true; Color color; labelName = labelElement->Attribute((char *)mitk::TubeGraphDefinitions::XML_LABEL_NAME.c_str()); if (labelName) newLabel->labelName = labelName; labelElement->Attribute(mitk::TubeGraphDefinitions::XML_LABEL_VISIBILITY, &temp); if (temp == 0) isVisible = false; else isVisible = true; labelElement->Attribute(mitk::TubeGraphDefinitions::XML_LABEL_COLOR_R, &temp); color[0] = temp; labelElement->Attribute(mitk::TubeGraphDefinitions::XML_LABEL_COLOR_G, &temp); color[1] = temp; labelElement->Attribute(mitk::TubeGraphDefinitions::XML_LABEL_COLOR_B, &temp); color[2] = temp; newLabel->isVisible = isVisible; newLabel->labelColor = color; newLabelGroup->labels.push_back(newLabel); } newProperty->AddLabelGroup(newLabelGroup, newProperty->GetLabelGroups().size()); } } // read attributations pElem = hRoot.FirstChildElement(mitk::TubeGraphDefinitions::XML_ATTRIBUTIONS).Element(); if (pElem != 0) { - TiXmlElement *tubeToLabelElement = pElem->FirstChildElement(); std::map tubeToLabelsMap; - for (tubeToLabelElement; tubeToLabelElement; tubeToLabelElement = tubeToLabelElement->NextSiblingElement()) + for (TiXmlElement *tubeToLabelElement = pElem->FirstChildElement(); tubeToLabelElement != nullptr; tubeToLabelElement = tubeToLabelElement->NextSiblingElement()) { TubeGraph::TubeDescriptorType tube; mitk::TubeGraphProperty::LabelGroup *labelGroup = new mitk::TubeGraphProperty::LabelGroup(); mitk::TubeGraphProperty::LabelGroup::Label *label = new mitk::TubeGraphProperty::LabelGroup::Label(); tubeToLabelElement->Attribute(mitk::TubeGraphDefinitions::XML_TUBE_ID_1, &temp); tube.first = temp; tubeToLabelElement->Attribute(mitk::TubeGraphDefinitions::XML_TUBE_ID_2, &temp); tube.second = temp; const char *labelGroupName = tubeToLabelElement->Attribute((char *)mitk::TubeGraphDefinitions::XML_LABELGROUP_NAME.c_str()); if (labelGroupName) labelGroup = newProperty->GetLabelGroupByName(labelGroupName); const char *labelName = tubeToLabelElement->Attribute((char *)mitk::TubeGraphDefinitions::XML_LABEL_NAME.c_str()); if (labelName) label = newProperty->GetLabelByName(labelGroup, labelName); if (tube != TubeGraph::ErrorId && labelGroup != nullptr && label != nullptr) { TubeGraphProperty::TubeToLabelGroupType tubeToLabelGroup(tube, labelGroupName); tubeToLabelsMap.insert( std::pair(tubeToLabelGroup, labelName)); } } if (tubeToLabelsMap.size() > 0) newProperty->SetTubesToLabels(tubeToLabelsMap); } // read annotations pElem = hRoot.FirstChildElement(mitk::TubeGraphDefinitions::XML_ANNOTATIONS).Element(); if (pElem != 0) { - TiXmlElement *annotationElement = pElem->FirstChildElement(); - for (annotationElement; annotationElement; annotationElement = annotationElement->NextSiblingElement()) + for (TiXmlElement *annotationElement = pElem->FirstChildElement(); annotationElement != nullptr; annotationElement = annotationElement->NextSiblingElement()) { mitk::TubeGraphProperty::Annotation *annotation = new mitk::TubeGraphProperty::Annotation(); std::string annotationName; std::string annotationDescription; TubeGraph::TubeDescriptorType tube; annotationName = annotationElement->Attribute((char *)mitk::TubeGraphDefinitions::XML_ANNOTATION_NAME.c_str()); annotation->name = annotationName; annotationDescription = annotationElement->Attribute((char *)mitk::TubeGraphDefinitions::XML_ANNOTATION_DESCRIPTION.c_str()); annotation->description = annotationDescription; annotationElement->Attribute(mitk::TubeGraphDefinitions::XML_TUBE_ID_1, &temp); tube.first = temp; annotationElement->Attribute(mitk::TubeGraphDefinitions::XML_TUBE_ID_2, &temp); tube.second = temp; if (tube != TubeGraph::ErrorId) { annotation->tube = tube; newProperty->AddAnnotation(annotation); } } } MITK_INFO << "Tube Graph Property read"; newTubeGraph->SetGeometry(geometry); newTubeGraph->SetProperty("Tube Graph.Visualization Information", newProperty); result.push_back(newTubeGraph.GetPointer()); } else { mitkThrow() << "Parsing error at line " << doc.ErrorRow() << ", col " << doc.ErrorCol() << ": " << doc.ErrorDesc(); } return result; } AbstractFileIO::ConfidenceLevel TubeGraphIO::GetReaderConfidenceLevel() const { if (AbstractFileIO::GetReaderConfidenceLevel() == Unsupported) return Unsupported; return Supported; } void TubeGraphIO::Write() { OutputStream out(this); if (!out.good()) { mitkThrow() << "Stream not good."; } std::locale previousLocale(out.getloc()); std::locale I("C"); out.imbue(I); const mitk::TubeGraph *tubeGraph = dynamic_cast(this->GetInput()); // Get geometry of the tube graph mitk::Geometry3D::Pointer geometry = dynamic_cast(tubeGraph->GetGeometry()); // Get property of the tube graph mitk::TubeGraphProperty::Pointer tubeGraphProperty = dynamic_cast( tubeGraph->GetProperty("Tube Graph.Visualization Information").GetPointer()); // Create XML document TiXmlDocument documentXML; { // Begin document TiXmlDeclaration *declXML = new TiXmlDeclaration("1.0", "", ""); documentXML.LinkEndChild(declXML); TiXmlElement *mainXML = new TiXmlElement(mitk::TubeGraphDefinitions::XML_TUBEGRAPH_FILE); mainXML->SetAttribute(mitk::TubeGraphDefinitions::XML_FILE_VERSION, mitk::TubeGraphDefinitions::VERSION_STRING); documentXML.LinkEndChild(mainXML); TiXmlElement *geometryXML = new TiXmlElement(mitk::TubeGraphDefinitions::XML_GEOMETRY); { // begin geometry geometryXML->SetDoubleAttribute(mitk::TubeGraphDefinitions::XML_MATRIX_XX, geometry->GetMatrixColumn(0)[0]); geometryXML->SetDoubleAttribute(mitk::TubeGraphDefinitions::XML_MATRIX_XY, geometry->GetMatrixColumn(0)[1]); geometryXML->SetDoubleAttribute(mitk::TubeGraphDefinitions::XML_MATRIX_XZ, geometry->GetMatrixColumn(0)[2]); geometryXML->SetDoubleAttribute(mitk::TubeGraphDefinitions::XML_MATRIX_YX, geometry->GetMatrixColumn(1)[0]); geometryXML->SetDoubleAttribute(mitk::TubeGraphDefinitions::XML_MATRIX_YY, geometry->GetMatrixColumn(1)[1]); geometryXML->SetDoubleAttribute(mitk::TubeGraphDefinitions::XML_MATRIX_YZ, geometry->GetMatrixColumn(1)[2]); geometryXML->SetDoubleAttribute(mitk::TubeGraphDefinitions::XML_MATRIX_ZX, geometry->GetMatrixColumn(2)[0]); geometryXML->SetDoubleAttribute(mitk::TubeGraphDefinitions::XML_MATRIX_ZY, geometry->GetMatrixColumn(2)[1]); geometryXML->SetDoubleAttribute(mitk::TubeGraphDefinitions::XML_MATRIX_ZZ, geometry->GetMatrixColumn(2)[2]); geometryXML->SetDoubleAttribute(mitk::TubeGraphDefinitions::XML_ORIGIN_X, geometry->GetOrigin()[0]); geometryXML->SetDoubleAttribute(mitk::TubeGraphDefinitions::XML_ORIGIN_Y, geometry->GetOrigin()[1]); geometryXML->SetDoubleAttribute(mitk::TubeGraphDefinitions::XML_ORIGIN_Z, geometry->GetOrigin()[2]); geometryXML->SetDoubleAttribute(mitk::TubeGraphDefinitions::XML_SPACING_X, geometry->GetSpacing()[0]); geometryXML->SetDoubleAttribute(mitk::TubeGraphDefinitions::XML_SPACING_Y, geometry->GetSpacing()[1]); geometryXML->SetDoubleAttribute(mitk::TubeGraphDefinitions::XML_SPACING_Z, geometry->GetSpacing()[2]); } // end geometry mainXML->LinkEndChild(geometryXML); TiXmlElement *verticesXML = new TiXmlElement(mitk::TubeGraphDefinitions::XML_VERTICES); { // begin vertices section std::vector vertexVector = tubeGraph->GetVectorOfAllVertices(); for (unsigned int index = 0; index < vertexVector.size(); index++) { TiXmlElement *vertexXML = new TiXmlElement(mitk::TubeGraphDefinitions::XML_VERTEX); vertexXML->SetAttribute(mitk::TubeGraphDefinitions::XML_VERTEX_ID, tubeGraph->GetVertexDescriptor(vertexVector[index])); // element of each vertex const mitk::TubeElement *element = vertexVector[index].GetTubeElement(); TiXmlElement *elementXML = new TiXmlElement(mitk::TubeGraphDefinitions::XML_ELEMENT); elementXML->SetDoubleAttribute(mitk::TubeGraphDefinitions::XML_ELEMENT_X, element->GetCoordinates().GetElement(0)); elementXML->SetDoubleAttribute(mitk::TubeGraphDefinitions::XML_ELEMENT_Y, element->GetCoordinates().GetElement(1)); elementXML->SetDoubleAttribute(mitk::TubeGraphDefinitions::XML_ELEMENT_Z, element->GetCoordinates().GetElement(2)); if (dynamic_cast(element)) elementXML->SetDoubleAttribute( mitk::TubeGraphDefinitions::XML_ELEMENT_DIAMETER, (dynamic_cast(element))->GetDiameter()); else elementXML->SetDoubleAttribute(mitk::TubeGraphDefinitions::XML_ELEMENT_DIAMETER, 2); vertexXML->LinkEndChild(elementXML); verticesXML->LinkEndChild(vertexXML); } } // end vertices section mainXML->LinkEndChild(verticesXML); TiXmlElement *edgesXML = new TiXmlElement(mitk::TubeGraphDefinitions::XML_EDGES); { // begin edges section std::vector edgeVector = tubeGraph->GetVectorOfAllEdges(); for (unsigned int index = 0; index < edgeVector.size(); index++) { TiXmlElement *edgeXML = new TiXmlElement(mitk::TubeGraphDefinitions::XML_EDGE); edgeXML->SetAttribute(mitk::TubeGraphDefinitions::XML_EDGE_ID, index); std::pair soureTargetPair = tubeGraph->GetVerticesOfAnEdge(tubeGraph->GetEdgeDescriptor(edgeVector[index])); edgeXML->SetAttribute(mitk::TubeGraphDefinitions::XML_EDGE_SOURCE_ID, tubeGraph->GetVertexDescriptor(soureTargetPair.first)); edgeXML->SetAttribute(mitk::TubeGraphDefinitions::XML_EDGE_TARGET_ID, tubeGraph->GetVertexDescriptor(soureTargetPair.second)); // begin elements of the edge std::vector elementVector = edgeVector[index].GetElementVector(); for (unsigned int elementIndex = 0; elementIndex < elementVector.size(); elementIndex++) { TiXmlElement *elementXML = new TiXmlElement(mitk::TubeGraphDefinitions::XML_ELEMENT); elementXML->SetDoubleAttribute(mitk::TubeGraphDefinitions::XML_ELEMENT_X, elementVector[elementIndex]->GetCoordinates().GetElement(0)); elementXML->SetDoubleAttribute(mitk::TubeGraphDefinitions::XML_ELEMENT_Y, elementVector[elementIndex]->GetCoordinates().GetElement(1)); elementXML->SetDoubleAttribute(mitk::TubeGraphDefinitions::XML_ELEMENT_Z, elementVector[elementIndex]->GetCoordinates().GetElement(2)); if (dynamic_cast(elementVector[elementIndex])) elementXML->SetDoubleAttribute( mitk::TubeGraphDefinitions::XML_ELEMENT_DIAMETER, (dynamic_cast(elementVector[elementIndex]))->GetDiameter()); else elementXML->SetDoubleAttribute(mitk::TubeGraphDefinitions::XML_ELEMENT_DIAMETER, 2); edgeXML->LinkEndChild(elementXML); // elementsXML->LinkEndChild(elementXML); } edgesXML->LinkEndChild(edgeXML); } } // end edges section mainXML->LinkEndChild(edgesXML); TiXmlElement *labelGroupsXML = new TiXmlElement(mitk::TubeGraphDefinitions::XML_LABELGROUPS); { // begin label group section std::vector labelGroupVector = tubeGraphProperty->GetLabelGroups(); for (unsigned int index = 0; index < labelGroupVector.size(); index++) { TiXmlElement *labelGroupXML = new TiXmlElement(mitk::TubeGraphDefinitions::XML_LABELGROUP); labelGroupXML->SetAttribute(mitk::TubeGraphDefinitions::XML_LABELGROUP_NAME, labelGroupVector[index]->labelGroupName); // begin labels of the label group std::vector labelVector = labelGroupVector[index]->labels; for (unsigned int labelIndex = 0; labelIndex < labelVector.size(); labelIndex++) { TiXmlElement *labelXML = new TiXmlElement(mitk::TubeGraphDefinitions::XML_LABEL); labelXML->SetAttribute(mitk::TubeGraphDefinitions::XML_LABEL_NAME, labelVector[labelIndex]->labelName); labelXML->SetAttribute(mitk::TubeGraphDefinitions::XML_LABEL_VISIBILITY, labelVector[labelIndex]->isVisible); labelXML->SetDoubleAttribute(mitk::TubeGraphDefinitions::XML_LABEL_COLOR_R, labelVector[labelIndex]->labelColor[0]); labelXML->SetDoubleAttribute(mitk::TubeGraphDefinitions::XML_LABEL_COLOR_G, labelVector[labelIndex]->labelColor[1]); labelXML->SetDoubleAttribute(mitk::TubeGraphDefinitions::XML_LABEL_COLOR_B, labelVector[labelIndex]->labelColor[2]); labelGroupXML->LinkEndChild(labelXML); } labelGroupsXML->LinkEndChild(labelGroupXML); } } // end labe group section mainXML->LinkEndChild(labelGroupsXML); TiXmlElement *attributionsXML = new TiXmlElement(mitk::TubeGraphDefinitions::XML_ATTRIBUTIONS); { // begin attributions section std::map tubeToLabelGroup = tubeGraphProperty->GetTubesToLabels(); for (std::map::iterator it = tubeToLabelGroup.begin(); it != tubeToLabelGroup.end(); it++) { TiXmlElement *attributXML = new TiXmlElement(mitk::TubeGraphDefinitions::XML_ATTRIBUTION); attributXML->SetDoubleAttribute(mitk::TubeGraphDefinitions::XML_TUBE_ID_1, it->first.first.first); attributXML->SetDoubleAttribute(mitk::TubeGraphDefinitions::XML_TUBE_ID_2, it->first.first.second); attributXML->SetAttribute(mitk::TubeGraphDefinitions::XML_LABELGROUP_NAME, it->first.second); attributXML->SetAttribute(mitk::TubeGraphDefinitions::XML_LABEL_NAME, it->second); attributionsXML->LinkEndChild(attributXML); } } // end attributions section mainXML->LinkEndChild(attributionsXML); TiXmlElement *annotationsXML = new TiXmlElement(mitk::TubeGraphDefinitions::XML_ANNOTATIONS); { // begin annotations section std::vector annotations = tubeGraphProperty->GetAnnotations(); for (unsigned int index = 0; index < annotations.size(); index++) { TiXmlElement *annotationXML = new TiXmlElement(mitk::TubeGraphDefinitions::XML_ANNOTATION); annotationXML->SetAttribute(mitk::TubeGraphDefinitions::XML_ANNOTATION_NAME, annotations[index]->name); annotationXML->SetAttribute(mitk::TubeGraphDefinitions::XML_ANNOTATION_DESCRIPTION, annotations[index]->description); annotationXML->SetDoubleAttribute(mitk::TubeGraphDefinitions::XML_TUBE_ID_1, annotations[index]->tube.first); annotationXML->SetDoubleAttribute(mitk::TubeGraphDefinitions::XML_TUBE_ID_2, annotations[index]->tube.second); annotationsXML->LinkEndChild(annotationXML); } } // end annotations section mainXML->LinkEndChild(annotationsXML); } // end document TiXmlPrinter printer; printer.SetStreamPrinting(); documentXML.Accept(&printer); out << printer.Str(); } AbstractFileIO::ConfidenceLevel TubeGraphIO::GetWriterConfidenceLevel() const { if (AbstractFileIO::GetWriterConfidenceLevel() == Unsupported) return Unsupported; return Supported; } TubeGraphIO *TubeGraphIO::IOClone() const { return new TubeGraphIO(*this); } } const mitk::BoundingBox::Pointer mitk::TubeGraphIO::ComputeBoundingBox(mitk::TubeGraph::Pointer graph) const { BoundingBox::Pointer boundingBox = BoundingBox::New(); BoundingBox::PointIdentifier pointid = 0; BoundingBox::PointsContainer::Pointer pointscontainer = BoundingBox::PointsContainer::New(); ScalarType nullpoint[] = {0, 0, 0}; BoundingBox::PointType p(nullpoint); // traverse the tree and add each point to the pointscontainer mitk::Point3D pos; std::vector vertexVector = graph->GetVectorOfAllVertices(); for (std::vector::iterator vertex = vertexVector.begin(); vertex != vertexVector.end(); ++vertex) { pos = vertex->GetTubeElement()->GetCoordinates(); p[0] = pos[0]; p[1] = pos[1]; p[2] = pos[2]; pointscontainer->InsertElement(pointid++, p); } std::vector edgeVector = graph->GetVectorOfAllEdges(); for (std::vector::iterator edge = edgeVector.begin(); edge != edgeVector.end(); ++edge) { std::vector allElements = edge->GetElementVector(); for (unsigned int index = 0; index < edge->GetNumberOfElements(); index++) { pos = allElements[index]->GetCoordinates(); p[0] = pos[0]; p[1] = pos[1]; p[2] = pos[2]; pointscontainer->InsertElement(pointid++, p); } } boundingBox->SetPoints(pointscontainer); boundingBox->ComputeBoundingBox(); return boundingBox; } diff --git a/Modules/TubeGraph/src/Interactions/mitkTubeGraphPicker.cpp b/Modules/TubeGraph/src/Interactions/mitkTubeGraphPicker.cpp index 4584deb055..b41c8e6332 100644 --- a/Modules/TubeGraph/src/Interactions/mitkTubeGraphPicker.cpp +++ b/Modules/TubeGraph/src/Interactions/mitkTubeGraphPicker.cpp @@ -1,92 +1,92 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkTubeGraphPicker.h" mitk::TubeGraphPicker::TubeGraphPicker() { m_WorldPosition.Fill(0.0); } mitk::TubeGraphPicker::~TubeGraphPicker() { } void mitk::TubeGraphPicker::SetTubeGraph(const mitk::TubeGraph *tubeGraph) { m_TubeGraph = const_cast(tubeGraph); m_TubeGraphProperty = dynamic_cast(m_TubeGraph->GetProperty("Tube Graph.Visualization Information").GetPointer()); } /** * Implements the picking process */ std::pair mitk::TubeGraphPicker::GetPickedTube( const Point3D pickedPosition) { if (!m_TubeGraph) { MITK_ERROR << "mitk::TubeGraphPicker: No tube graph available. Please set an input!" << std::endl; mitk::TubeElement *nullPointer = nullptr; return std::pair(TubeGraph::ErrorId, nullPointer); } m_WorldPosition = pickedPosition; Point3D currentPosition; ScalarType closestDistance = itk::NumericTraits::max(); ScalarType currentDistance = itk::NumericTraits::max(); float currentRadius = 0; TubeGraph::TubeDescriptorType currentTubeId(TubeGraph::ErrorId); TubeGraph::TubeDescriptorType tubeId(TubeGraph::ErrorId); TubeElement *tubeElement; // iterate over all edges and find the edge, which element is near by the clicked point std::vector allEdges = m_TubeGraph->GetVectorOfAllEdges(); for (auto edge = allEdges.begin(); edge != allEdges.end(); ++edge) { std::pair soureTargetPair = m_TubeGraph->GetVerticesOfAnEdge(m_TubeGraph->GetEdgeDescriptor(*edge)); currentTubeId = TubeGraph::TubeDescriptorType(m_TubeGraph->GetVertexDescriptor(soureTargetPair.first), m_TubeGraph->GetVertexDescriptor(soureTargetPair.second)); // check if the tube is visible, if not pass this tube. User can not choose a tube, which he can't see if (m_TubeGraphProperty->IsTubeVisible(currentTubeId)) { std::vector allElements = edge->GetElementVector(); for (unsigned int index = 0; index < edge->GetNumberOfElements(); index++) { currentPosition = allElements[index]->GetCoordinates(); if (dynamic_cast(allElements[index])) currentRadius = ((dynamic_cast(allElements[index]))->GetDiameter()) / 2; else currentRadius = 0; // calculate point->point distance currentDistance = m_WorldPosition.EuclideanDistanceTo(currentPosition); if (currentDistance < closestDistance && (currentDistance - currentRadius) < 1.0) { closestDistance = currentDistance; tubeId = currentTubeId; tubeElement = allElements[index]; } } } } - std::pair pickedTubeWithElement(tubeId, tubeElement); - return pickedTubeWithElement; + + return std::make_pair(tubeId, tubeElement); } diff --git a/Modules/TubeGraph/src/Rendering/mitkTubeGraphProperty.cpp b/Modules/TubeGraph/src/Rendering/mitkTubeGraphProperty.cpp index e6cebb4712..fc7063afef 100644 --- a/Modules/TubeGraph/src/Rendering/mitkTubeGraphProperty.cpp +++ b/Modules/TubeGraph/src/Rendering/mitkTubeGraphProperty.cpp @@ -1,450 +1,432 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkTubeGraphProperty.h" #include mitk::TubeGraphProperty::TubeGraphProperty() /*: m_LabelGroups(), m_ActiveTubes(), m_TubeToLabelsMap()*/ { } mitk::TubeGraphProperty::TubeGraphProperty(const mitk::TubeGraphProperty &other) : BaseProperty(other), m_ActiveTubes(other.m_ActiveTubes), m_LabelGroups(other.m_LabelGroups), m_TubeToLabelsMap(other.m_TubeToLabelsMap), m_Annotations(other.m_Annotations) { } mitk::TubeGraphProperty::~TubeGraphProperty() { m_ActiveTubes.clear(); m_TubeToLabelsMap.clear(); for (auto it = m_LabelGroups.begin(); it != m_LabelGroups.end(); it++) delete *it; m_LabelGroups.clear(); } bool mitk::TubeGraphProperty::IsTubeVisible(const TubeDescriptorType &tube) { // search for any label settings for the tube if (m_LabelGroups.size() > 0) { for (auto it = m_TubeToLabelsMap.begin(); it != m_TubeToLabelsMap.end(); it++) { if (this->TubeDescriptorsCompare(tube, (*it).first.first)) { // At the moment only the first entry is considered LabelGroup *lg = this->GetLabelGroupByName((*it).first.second); LabelGroup::Label *label = this->GetLabelByName(lg, (*it).second); return label->isVisible; } } // If nothing is found, look if the first labelgroup is visible for "undefined" label LabelGroup::Label *label = this->GetLabelByName((*m_LabelGroups.begin()), "Undefined"); return label->isVisible; } else return true; } void mitk::TubeGraphProperty::SetTubeActive(const TubeDescriptorType &tube, const bool &active) { // set active if (active) { for (std::vector::const_iterator it = m_ActiveTubes.begin(); it != m_ActiveTubes.end(); it++) { if (this->TubeDescriptorsCompare(tube, (*it))) { return; } } // if not found, add it m_ActiveTubes.push_back(tube); this->Modified(); } // set deactive else { for (auto it = m_ActiveTubes.begin(); it != m_ActiveTubes.end(); it++) { if (this->TubeDescriptorsCompare(tube, (*it))) { // if found, delete it m_ActiveTubes.erase(it); this->Modified(); return; } } } //// render new activation // RenderingManager::GetInstance()->RequestUpdateAll(); } void mitk::TubeGraphProperty::SetTubesActive(std::vector &tubes) { for (auto it = tubes.begin(); it != tubes.end(); it++) this->SetTubeActive(*it, true); } bool mitk::TubeGraphProperty::IsTubeActive(const TubeDescriptorType &tube) { for (std::vector::const_iterator it = m_ActiveTubes.begin(); it != m_ActiveTubes.end(); it++) { if (this->TubeDescriptorsCompare((*it), tube)) return true; } return false; } std::vector mitk::TubeGraphProperty::GetActiveTubes() { return m_ActiveTubes; } void mitk::TubeGraphProperty::DeactivateAllTubes() { // if (!m_ActiveTubes.empty()) m_ActiveTubes.clear(); this->Modified(); } void mitk::TubeGraphProperty::AddAnnotation(mitk::TubeGraphProperty::Annotation *annotation) { for (auto it = m_Annotations.begin(); it != m_Annotations.end(); it++) { if ((*it)->name == annotation->name) { MITK_INFO << "An Annotation with this name already exists."; return; } } m_Annotations.push_back(annotation); } mitk::TubeGraphProperty::Annotation *mitk::TubeGraphProperty::GetAnnotationByName(std::string annotation) { for (auto it = m_Annotations.begin(); it != m_Annotations.end(); it++) { if ((*it)->name == annotation) return *it; } return nullptr; } std::vector mitk::TubeGraphProperty::GetAnnotations() { return m_Annotations; } void mitk::TubeGraphProperty::RemoveAnnotation(mitk::TubeGraphProperty::Annotation *annotation) { for (auto it = m_Annotations.begin(); it != m_Annotations.end(); it++) { if ((*it)->name == annotation->name) { m_Annotations.erase(it); return; } } } mitk::Color mitk::TubeGraphProperty::GetColorOfTube(const TubeDescriptorType &tube) { Color color; // grey as default color color[0] = 150; color[1] = 150; color[2] = 150; bool isActive(false); bool hasLabel(false); // search the vector with active tubes first. If the tube is active it can not have another color. for (std::vector::const_iterator it = m_ActiveTubes.begin(); it != m_ActiveTubes.end(); it++) { if (this->TubeDescriptorsCompare(tube, (*it))) { color[0] = 255; color[1] = 255; color[2] = 0; isActive = true; break; } } if (!isActive) { // So let see which label is activ on this tube and which color is set. if (m_LabelGroups.size() > 0) { for (auto it = m_TubeToLabelsMap.begin(); it != m_TubeToLabelsMap.end(); it++) { if (this->TubeDescriptorsCompare(tube, (*it).first.first)) { // At the moment only the first entry is considered LabelGroup *lg = this->GetLabelGroupByName((*it).first.second); LabelGroup::Label *label = this->GetLabelByName(lg, (*it).second); color = label->labelColor; hasLabel = true; } } // If nothing is found, look if the first labelgroup is visible for "undefined" label if (!hasLabel) { LabelGroup::Label *label = this->GetLabelByName(*(m_LabelGroups.begin()), "Undefined"); color = label->labelColor; } } } return color; } void mitk::TubeGraphProperty::SetLabelForActivatedTubes(LabelGroup *labelGroup, LabelGroup::Label *label) { bool isUndefined(label->labelName.compare("Undefined") == 0); for (unsigned int i = 0; i < m_ActiveTubes.size(); i++) { bool isInList(false); for (auto it = m_TubeToLabelsMap.begin(); it != m_TubeToLabelsMap.end(); it++) { if ((this->TubeDescriptorsCompare(it->first.first, m_ActiveTubes[i])) && (labelGroup->labelGroupName.compare(it->first.second) == 0)) { // If tube has a label fromlabel group, deleted if "undefined" is clicked. if (isUndefined) { m_TubeToLabelsMap.erase(it); break; } else { it->second = label->labelName; isInList = true; } } } if (!isInList && !isUndefined) { TubeToLabelGroupType tubeToLabelGroup(m_ActiveTubes[i], labelGroup->labelGroupName); m_TubeToLabelsMap.insert(std::pair(tubeToLabelGroup, label->labelName)); } } this->Modified(); m_ActiveTubes.clear(); } void mitk::TubeGraphProperty::SetTubesToLabels(std::map tubeToLabelMap) { m_TubeToLabelsMap = tubeToLabelMap; } std::map mitk::TubeGraphProperty::GetTubesToLabels() { return m_TubeToLabelsMap; } void mitk::TubeGraphProperty::AddLabelGroup(LabelGroup *labelGroup, unsigned int position) { // Check if the name is unique for (auto it = m_LabelGroups.begin(); it != m_LabelGroups.end(); it++) { if (labelGroup->labelGroupName.compare((*it)->labelGroupName) == 0) { MITK_ERROR << "The label group must be unique! This name already exists!"; return; } } // Add the label group at position, if you can, otherwise put it at the end of the vector if (position < m_LabelGroups.size() - 1) { auto it = m_LabelGroups.begin() + position; m_LabelGroups.insert(it, labelGroup); } else { m_LabelGroups.push_back(labelGroup); // when given position is larger then vector size, the label group will be added at the last position if (position >= m_LabelGroups.size()) MITK_INFO << "Position is out of space. So the label group was added on last position: " << m_LabelGroups.size() - 1; } } void mitk::TubeGraphProperty::RemoveLabelGroup(LabelGroup *labelGroup) { // find labelGroup in vector auto foundElement = std::find(m_LabelGroups.begin(), m_LabelGroups.end(), labelGroup); unsigned int pos = foundElement - m_LabelGroups.begin(); // found it? delete it! if (pos < m_LabelGroups.size()) { // delete every assignment to a tube for (auto it = m_TubeToLabelsMap.begin(); it != m_TubeToLabelsMap.end(); it++) { if (labelGroup->labelGroupName.compare((*it).first.second) == 0) m_TubeToLabelsMap.erase(it); } m_LabelGroups.erase(foundElement); } else { MITK_ERROR << "Could not find the label group!"; return; } } void mitk::TubeGraphProperty::SetLabelColor(LabelGroup::Label *label, mitk::Color color) { // LabelGroup? Check if it is a label in property class if (label) { label->labelColor = color; this->Modified(); } } void mitk::TubeGraphProperty::SetLabelVisibility(LabelGroup::Label *label, bool isVisible) { // LabelGroup? Check if it is a label in property class if (label) { label->isVisible = isVisible; this->Modified(); } } void mitk::TubeGraphProperty::RenameLabel(LabelGroup *labelGroup, LabelGroup::Label *label, std::string newName) { // LabelGroup? Check if it is a label in property class if (label) { // rename the label in the assignement vector for tubes for (auto it = m_TubeToLabelsMap.begin(); it != m_TubeToLabelsMap.end(); it++) { // Label group fit? if (labelGroup->labelGroupName.compare((*it).first.second) == 0) // label fit? if (label->labelName.compare((*it).second) == 0) // rename it (*it).second = newName; } // rename the label in label group label->labelName = newName; } } mitk::TubeGraphProperty::LabelGroupSetType mitk::TubeGraphProperty::GetLabelGroups() { return m_LabelGroups; } unsigned int mitk::TubeGraphProperty::GetNumberOfLabelGroups() { return m_LabelGroups.size(); } unsigned int mitk::TubeGraphProperty::GetIndexOfLabelGroup(mitk::TubeGraphProperty::LabelGroup *labelGroup) { unsigned int pos = std::find(m_LabelGroups.begin(), m_LabelGroups.end(), labelGroup) - m_LabelGroups.begin(); if (pos < m_LabelGroups.size()) return pos; // label group is not in property class else { MITK_ERROR << "Could not find such a label group!"; return m_LabelGroups.size(); } } mitk::TubeGraphProperty::LabelGroup *mitk::TubeGraphProperty::GetLabelGroupByName(std::string labelGroup) { for (auto it = m_LabelGroups.begin(); it != m_LabelGroups.end(); it++) { if (labelGroup.compare((*it)->labelGroupName) == 0) return (*it); } MITK_ERROR << "Could not find such a label group!"; return nullptr; } mitk::TubeGraphProperty::LabelGroup::Label *mitk::TubeGraphProperty::GetLabelByName(LabelGroup *labelGroup, std::string labelName) { for (auto it = labelGroup->labels.begin(); it != labelGroup->labels.end(); it++) { if (labelName.compare((*it)->labelName) == 0) return (*it); } MITK_ERROR << "Could not find such a label!"; return nullptr; } bool mitk::TubeGraphProperty::TubeDescriptorsCompare(const TubeDescriptorType &tube1, const TubeDescriptorType &tube2) { if (((tube1.first == tube2.first) && (tube1.second == tube2.second)) || ((tube1.first == tube2.second) && (tube1.second == tube2.first))) return true; else return false; } -bool mitk::TubeGraphProperty::IsEqual(const BaseProperty &property) const +bool mitk::TubeGraphProperty::IsEqual(const BaseProperty &) const { // TODO see ResectionProposalDescriptorProperty - // const TubeGraphProperty& other = - // static_cast(property); - - return true - // same number of elements, same name and corresponding elements are equal (set datatype stores them sorted!) - /*(m_LDs.size() == other.GetLabelDesriptorSet().size()) - && (m_ResectionProposalName == other.GetResectionProposalName()) - && std::equal(m_LDs.begin(), m_LDs.end(), other.GetLabelDesriptorSet().begin())*/; + return true; } -bool mitk::TubeGraphProperty::Assign(const BaseProperty &property) +bool mitk::TubeGraphProperty::Assign(const BaseProperty &) { // TODO see ResectionProposalDescriptorProperty - // const TubeGraphProperty& other = - // static_cast(property); - /* this->m_LDs = other.m_LDs; - this->m_ResectionProposalName = other.m_ResectionProposalName;*/ return true; } std::string mitk::TubeGraphProperty::GetValueAsString() const { // TODO - std::stringstream result; - /* result << "Tube graph: " << this->GetResectionProposalName(); - result << "\n Number of labels: " << this->GetNumberOfLabels() << "\n"; - for (LabelDesriptorSet::const_iterator it = m_LDs.begin(); it != m_LDs.end(); it++) - result << "Label " << it->m_Name<< ": " - << "Label = " << it->m_Label << ", ResectionType = " << it->m_ResectionType - << ", Volume = " << it->m_Volume << "\n";*/ - return result.str(); + return ""; } itk::LightObject::Pointer mitk::TubeGraphProperty::InternalClone() const { itk::LightObject::Pointer result(new Self(*this)); return result; } diff --git a/Modules/TubeGraph/src/Rendering/mitkTubeGraphVtkMapper3D.cpp b/Modules/TubeGraph/src/Rendering/mitkTubeGraphVtkMapper3D.cpp index 2dd6f343f3..d6a2358b66 100644 --- a/Modules/TubeGraph/src/Rendering/mitkTubeGraphVtkMapper3D.cpp +++ b/Modules/TubeGraph/src/Rendering/mitkTubeGraphVtkMapper3D.cpp @@ -1,758 +1,757 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkTubeGraphVtkMapper3D.h" #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(GetData()); + 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 (std::map>::iterator 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()) { std::map>::iterator 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()) { std::map>::iterator 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::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..."; return; } std::vector allVertices = tubeGraph->GetVectorOfAllVertices(); for (std::vector::iterator 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 (std::vector::iterator 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 (std::vector::iterator edge = allEdges.begin(); edge != allEdges.end(); ++edge) { this->GeneratePolyDataForTube(*edge, tubeGraph, tubeGraphProperty, renderer); } // Generate all vertices as spheres std::vector allVertices = tubeGraph->GetVectorOfAllVertices(); for (std::vector::iterator 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 (std::vector::iterator edge = allEdgesOfVertex.begin(); edge != allEdgesOfVertex.end(); ++edge) { // get edge descriptor EdgeDescriptorType edgeDesc = graph->GetEdgeDescriptor(*edge); // get source and target vertex descriptor - std::pair soureTargetPair = graph->GetVerticesOfAnEdge(edgeDesc); + 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 - unsigned int index = (*edge).GetNumberOfElements() - 1; - for (; index >= 0; index--) + 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 == (*edge).GetNumberOfElements() - 1) + 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 + // 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 (std::map>::iterator 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 (std::map>::iterator 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; }