diff --git a/Examples/Tutorial/Step7.cpp b/Examples/Tutorial/Step7.cpp index fe41471750..0cf5fec474 100644 --- a/Examples/Tutorial/Step7.cpp +++ b/Examples/Tutorial/Step7.cpp @@ -1,72 +1,72 @@ /*=================================================================== 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 "Step7.h" #include #include #include #include #include #include #include #include //##Documentation //## @brief Convert result of region-grower into a surface //## by means of a VTK filter Step7::Step7( int argc, char* argv[], QWidget *parent ) : Step6( argc, argv, parent ) { } void Step7::StartRegionGrowing() { Step6::StartRegionGrowing(); std::cout << "7"; if(m_ResultImage.IsNotNull()) { m_ResultNode->SetProperty("volumerendering", mitk::BoolProperty::New(false)); vtkMarchingCubes* surfaceCreator = vtkMarchingCubes::New(); - surfaceCreator->SetInput(m_ResultImage->GetVtkImageData()); + surfaceCreator->SetInputData(m_ResultImage->GetVtkImageData()); surfaceCreator->SetValue(0, 1); mitk::Surface::Pointer surface = mitk::Surface::New(); surface->SetVtkPolyData(surfaceCreator->GetOutput()); mitk::DataNode::Pointer surfaceNode = mitk::DataNode::New(); surfaceNode->SetData(surface); m_DataStorage->Add(surfaceNode); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); std::cout << "8"; surfaceCreator->Delete(); } std::cout << "9"; } /** \example Step7.cpp */ diff --git a/Examples/Tutorial/mitkWithITKAndVTK.cpp b/Examples/Tutorial/mitkWithITKAndVTK.cpp index 70ea904780..b4111d6105 100644 --- a/Examples/Tutorial/mitkWithITKAndVTK.cpp +++ b/Examples/Tutorial/mitkWithITKAndVTK.cpp @@ -1,82 +1,82 @@ /*=================================================================== 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 #include #include #include #include #include #include #include #include /// /// Small application for demonstrating the interaction between MITK, /// ITK and VTK (not necessarily useful). /// int main( int /*argc*/, char ** argv ) { // MITK: Read a .pic.gz file, e.g. Core/Code/Testing/Data/Pic3D.pic.gz from // disk mitk::PicFileReader::Pointer reader = mitk::PicFileReader::New(); const char * filename = argv[1]; try { reader->SetFileName(filename); reader->Update(); } catch(...) { fprintf( stderr, "Could not open file %s \n\n", filename ); return EXIT_FAILURE; } mitk::Image::Pointer mitkImage = reader->GetOutput(); // ITK: Image smoothing // Create ITK image, cast from MITK image typedef itk::Image< short , 3 > ImageType; ImageType::Pointer itkImage = ImageType::New(); mitk::CastToItkImage( mitkImage, itkImage ); typedef itk::DiscreteGaussianImageFilter FilterType; FilterType::Pointer filter = FilterType::New(); filter->SetInput( itkImage ); filter->SetVariance( 2 ); filter->SetMaximumKernelWidth( 5 ); filter->Update(); // run filter // reimport filtered image data mitk::CastToMitkImage( filter->GetOutput(), mitkImage ); // VTK: Show result in renderwindow vtkImageViewer *viewer=vtkImageViewer::New(); vtkRenderWindowInteractor* renderWindowInteractor =vtkRenderWindowInteractor ::New(); viewer->SetupInteractor(renderWindowInteractor); - viewer->SetInput(mitkImage->GetVtkImageData()); + viewer->SetInputData(mitkImage->GetVtkImageData()); viewer->Render(); viewer->SetColorWindow(255); viewer->SetColorLevel(128); renderWindowInteractor->Start(); renderWindowInteractor->Delete(); viewer->Delete(); return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/Connectomics/Rendering/mitkConnectomicsNetworkMapper3D.cpp b/Modules/DiffusionImaging/Connectomics/Rendering/mitkConnectomicsNetworkMapper3D.cpp index 0ecc6babbd..404d56f5ec 100644 --- a/Modules/DiffusionImaging/Connectomics/Rendering/mitkConnectomicsNetworkMapper3D.cpp +++ b/Modules/DiffusionImaging/Connectomics/Rendering/mitkConnectomicsNetworkMapper3D.cpp @@ -1,757 +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 "mitkConnectomicsNetworkMapper3D.h" #include #include "vtkGraphLayout.h" #include #include "vtkGraphToPolyData.h" #include #include "vtkGlyph3D.h" #include "vtkGlyphSource2D.h" #include "mitkConnectomicsRenderingProperties.h" #include "mitkConnectomicsRenderingSchemeProperty.h" #include "mitkConnectomicsRenderingEdgeFilteringProperty.h" #include "mitkConnectomicsRenderingNodeFilteringProperty.h" #include "mitkConnectomicsRenderingNodeColorParameterProperty.h" #include "mitkConnectomicsRenderingNodeRadiusParameterProperty.h" #include "mitkConnectomicsRenderingEdgeColorParameterProperty.h" #include "mitkConnectomicsRenderingEdgeRadiusParameterProperty.h" #include "mitkConnectomicsRenderingNodeThresholdParameterProperty.h" #include "mitkConnectomicsRenderingEdgeThresholdParameterProperty.h" #include mitk::ConnectomicsNetworkMapper3D::ConnectomicsNetworkMapper3D() { m_NetworkAssembly = vtkPropAssembly::New(); } mitk::ConnectomicsNetworkMapper3D:: ~ConnectomicsNetworkMapper3D() { m_NetworkAssembly->Delete(); } void mitk::ConnectomicsNetworkMapper3D::GenerateDataForRenderer(mitk::BaseRenderer* renderer) { if( this->GetInput() == NULL ) { return; } bool propertiesHaveChanged = this->PropertiesChanged(); if( this->GetInput()->GetIsModified( ) || propertiesHaveChanged ) { m_NetworkAssembly->Delete(); m_NetworkAssembly = vtkPropAssembly::New(); // Here is the part where a graph is given and converted to points and connections between points... std::vector< mitk::ConnectomicsNetwork::NetworkNode > vectorOfNodes = this->GetInput()->GetVectorOfAllNodes(); std::vector< std::pair< std::pair< mitk::ConnectomicsNetwork::NetworkNode, mitk::ConnectomicsNetwork::NetworkNode > , mitk::ConnectomicsNetwork::NetworkEdge > > vectorOfEdges = this->GetInput()->GetVectorOfAllEdges(); // Decide on the style of rendering due to property if( m_ChosenRenderingScheme == connectomicsRenderingMITKScheme ) { mitk::Point3D tempWorldPoint, tempCNFGeometryPoint; //////////////////////Prepare coloring and radius//////////// std::vector< double > vectorOfNodeRadiusParameterValues; vectorOfNodeRadiusParameterValues.resize( vectorOfNodes.size() ); double maxNodeRadiusParameterValue( FillNodeParameterVector( &vectorOfNodeRadiusParameterValues, m_NodeRadiusParameter ) ); std::vector< double > vectorOfNodeColorParameterValues; vectorOfNodeColorParameterValues.resize( vectorOfNodes.size() ); double maxNodeColorParameterValue( FillNodeParameterVector( &vectorOfNodeColorParameterValues, m_NodeColorParameter ) ); std::vector< double > vectorOfEdgeRadiusParameterValues; vectorOfEdgeRadiusParameterValues.resize( vectorOfEdges.size() ); double maxEdgeRadiusParameterValue( FillEdgeParameterVector( &vectorOfEdgeRadiusParameterValues, m_EdgeRadiusParameter ) ); std::vector< double > vectorOfEdgeColorParameterValues; vectorOfEdgeColorParameterValues.resize( vectorOfEdges.size() ); double maxEdgeColorParameterValue( FillEdgeParameterVector( &vectorOfEdgeColorParameterValues, m_EdgeColorParameter ) ); //////////////////////Prepare Filtering////////////////////// // true will be rendered std::vector< bool > vectorOfNodeFilterBools( vectorOfNodes.size(), true ); if( m_ChosenNodeFilter == connectomicsRenderingNodeThresholdingFilter ) { FillNodeFilterBoolVector( &vectorOfNodeFilterBools, m_NodeThresholdParameter ); } std::vector< bool > vectorOfEdgeFilterBools( vectorOfEdges.size(), true ); if( m_ChosenEdgeFilter == connectomicsRenderingEdgeThresholdFilter ) { FillEdgeFilterBoolVector( &vectorOfEdgeFilterBools, m_EdgeThresholdParameter ); } //////////////////////Create Spheres///////////////////////// for(unsigned int i = 0; i < vectorOfNodes.size(); i++) { vtkSmartPointer sphereSource = vtkSmartPointer::New(); for(unsigned int dimension = 0; dimension < 3; dimension++) { tempCNFGeometryPoint.SetElement( dimension , vectorOfNodes[i].coordinates[dimension] ); } GetDataNode()->GetData()->GetGeometry()->IndexToWorld( tempCNFGeometryPoint, tempWorldPoint ); sphereSource->SetCenter( tempWorldPoint[0] , tempWorldPoint[1], tempWorldPoint[2] ); // determine radius double radiusFactor = vectorOfNodeRadiusParameterValues[i] / maxNodeRadiusParameterValue; double radius = m_NodeRadiusStart + ( m_NodeRadiusEnd - m_NodeRadiusStart) * radiusFactor; sphereSource->SetRadius( radius ); vtkSmartPointer mapper = vtkSmartPointer::New(); - mapper->SetInput(sphereSource->GetOutput()); + mapper->SetInputData(sphereSource->GetOutput()); vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); // determine color double colorFactor = vectorOfNodeColorParameterValues[i] / maxNodeColorParameterValue; double redStart = m_NodeColorStart.GetElement( 0 ); double greenStart = m_NodeColorStart.GetElement( 1 ); double blueStart = m_NodeColorStart.GetElement( 2 ); double redEnd = m_NodeColorEnd.GetElement( 0 ); double greenEnd = m_NodeColorEnd.GetElement( 1 ); double blueEnd = m_NodeColorEnd.GetElement( 2 ); double red = redStart + ( redEnd - redStart ) * colorFactor; double green = greenStart + ( greenEnd - greenStart ) * colorFactor; double blue = blueStart + ( blueEnd - blueStart ) * colorFactor; actor->GetProperty()->SetColor( red, green, blue); if( vectorOfNodeFilterBools[i] ) { m_NetworkAssembly->AddPart(actor); } } //////////////////////Create Tubes///////////////////////// double maxWeight = (double) this->GetInput()->GetMaximumWeight(); for(unsigned int i = 0; i < vectorOfEdges.size(); i++) { vtkSmartPointer lineSource = vtkSmartPointer::New(); for(unsigned int dimension = 0; dimension < 3; dimension++) { tempCNFGeometryPoint[ dimension ] = vectorOfEdges[i].first.first.coordinates[dimension]; } GetDataNode()->GetData()->GetGeometry()->IndexToWorld( tempCNFGeometryPoint, tempWorldPoint ); lineSource->SetPoint1(tempWorldPoint[0], tempWorldPoint[1],tempWorldPoint[2] ); for(unsigned int dimension = 0; dimension < 3; dimension++) { tempCNFGeometryPoint[ dimension ] = vectorOfEdges[i].first.second.coordinates[dimension]; } GetDataNode()->GetData()->GetGeometry()->IndexToWorld( tempCNFGeometryPoint, tempWorldPoint ); lineSource->SetPoint2(tempWorldPoint[0], tempWorldPoint[1], tempWorldPoint[2] ); vtkSmartPointer tubes = vtkSmartPointer::New(); - tubes->SetInput( lineSource->GetOutput() ); + tubes->SetInputData( lineSource->GetOutput() ); tubes->SetNumberOfSides( 12 ); // determine radius double radiusFactor = vectorOfEdgeRadiusParameterValues[i] / maxEdgeRadiusParameterValue; double radius = m_EdgeRadiusStart + ( m_EdgeRadiusEnd - m_EdgeRadiusStart) * radiusFactor; tubes->SetRadius( radius ); // originally we used a logarithmic scaling, // double radiusFactor = 1.0 + ((double) vectorOfEdges[i].second.weight) / 10.0 ; // tubes->SetRadius( std::log10( radiusFactor ) ); vtkSmartPointer mapper2 = vtkSmartPointer::New(); - mapper2->SetInput( tubes->GetOutput() ); + mapper2->SetInputData( tubes->GetOutput() ); vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper2); // determine color double colorFactor = vectorOfEdgeColorParameterValues[i] / maxEdgeColorParameterValue; double redStart = m_EdgeColorStart.GetElement( 0 ); double greenStart = m_EdgeColorStart.GetElement( 1 ); double blueStart = m_EdgeColorStart.GetElement( 2 ); double redEnd = m_EdgeColorEnd.GetElement( 0 ); double greenEnd = m_EdgeColorEnd.GetElement( 1 ); double blueEnd = m_EdgeColorEnd.GetElement( 2 ); double red = redStart + ( redEnd - redStart ) * colorFactor; double green = greenStart + ( greenEnd - greenStart ) * colorFactor; double blue = blueStart + ( blueEnd - blueStart ) * colorFactor; actor->GetProperty()->SetColor( red, green, blue); if( vectorOfEdgeFilterBools[i] ) { m_NetworkAssembly->AddPart(actor); } } } else if( m_ChosenRenderingScheme == connectomicsRenderingVTKScheme ) { vtkSmartPointer graph = vtkSmartPointer::New(); std::vector< vtkIdType > networkToVTKvector; networkToVTKvector.resize(vectorOfNodes.size()); for(unsigned int i = 0; i < vectorOfNodes.size(); i++) { networkToVTKvector[vectorOfNodes[i].id] = graph->AddVertex(); } for(unsigned int i = 0; i < vectorOfEdges.size(); i++) { graph->AddEdge(networkToVTKvector[vectorOfEdges[i].first.first.id], networkToVTKvector[vectorOfEdges[i].first.second.id]); } vtkSmartPointer points = vtkSmartPointer::New(); for(unsigned int i = 0; i < vectorOfNodes.size(); i++) { double x = vectorOfNodes[i].coordinates[0]; double y = vectorOfNodes[i].coordinates[1]; double z = vectorOfNodes[i].coordinates[2]; points->InsertNextPoint( x, y, z); } graph->SetPoints(points); vtkGraphLayout* layout = vtkGraphLayout::New(); - layout->SetInput(graph); + layout->SetInputData(graph); vtkPassThroughLayoutStrategy* ptls = vtkPassThroughLayoutStrategy::New(); layout->SetLayoutStrategy( ptls ); vtkGraphToPolyData* graphToPoly = vtkGraphToPolyData::New(); graphToPoly->SetInputConnection(layout->GetOutputPort()); // Create the standard VTK polydata mapper and actor // for the connections (edges) in the tree. vtkPolyDataMapper* edgeMapper = vtkPolyDataMapper::New(); edgeMapper->SetInputConnection(graphToPoly->GetOutputPort()); vtkActor* edgeActor = vtkActor::New(); edgeActor->SetMapper(edgeMapper); edgeActor->GetProperty()->SetColor(0.0, 0.5, 1.0); // Glyph the points of the tree polydata to create // VTK_VERTEX cells at each vertex in the tree. vtkGlyph3D* vertGlyph = vtkGlyph3D::New(); vertGlyph->SetInputConnection(0, graphToPoly->GetOutputPort()); vtkGlyphSource2D* glyphSource = vtkGlyphSource2D::New(); glyphSource->SetGlyphTypeToVertex(); vertGlyph->SetInputConnection(1, glyphSource->GetOutputPort()); // Create a mapper for the vertices, and tell the mapper // to use the specified color array. vtkPolyDataMapper* vertMapper = vtkPolyDataMapper::New(); vertMapper->SetInputConnection(vertGlyph->GetOutputPort()); /*if (colorArray) { vertMapper->SetScalarModeToUsePointFieldData(); vertMapper->SelectColorArray(colorArray); vertMapper->SetScalarRange(colorRange); }*/ // Create an actor for the vertices. Move the actor forward // in the z direction so it is drawn on top of the edge actor. vtkActor* vertActor = vtkActor::New(); vertActor->SetMapper(vertMapper); vertActor->GetProperty()->SetPointSize(5); vertActor->SetPosition(0, 0, 0.001); m_NetworkAssembly->AddPart(edgeActor); m_NetworkAssembly->AddPart(vertActor); } (static_cast ( GetDataNode()->GetData() ) )->SetIsModified( false ); } } const mitk::ConnectomicsNetwork* mitk::ConnectomicsNetworkMapper3D::GetInput() { return static_cast ( GetDataNode()->GetData() ); } void mitk::ConnectomicsNetworkMapper3D::SetDefaultProperties(DataNode* node, BaseRenderer* renderer , bool overwrite) { // Initialize enumeration properties mitk::ConnectomicsRenderingSchemeProperty::Pointer connectomicsRenderingScheme = mitk::ConnectomicsRenderingSchemeProperty::New(); mitk::ConnectomicsRenderingEdgeFilteringProperty::Pointer connectomicsRenderingEdgeFiltering = mitk::ConnectomicsRenderingEdgeFilteringProperty::New(); mitk::ConnectomicsRenderingNodeFilteringProperty::Pointer connectomicsRenderingNodeFiltering = mitk::ConnectomicsRenderingNodeFilteringProperty::New(); mitk::ConnectomicsRenderingNodeColorParameterProperty::Pointer connectomicsRenderingNodeGradientColorParameter = mitk::ConnectomicsRenderingNodeColorParameterProperty::New(); mitk::ConnectomicsRenderingNodeRadiusParameterProperty::Pointer connectomicsRenderingNodeRadiusParameter = mitk::ConnectomicsRenderingNodeRadiusParameterProperty::New(); mitk::ConnectomicsRenderingEdgeColorParameterProperty::Pointer connectomicsRenderingEdgeGradientColorParameter = mitk::ConnectomicsRenderingEdgeColorParameterProperty::New(); mitk::ConnectomicsRenderingEdgeRadiusParameterProperty::Pointer connectomicsRenderingEdgeRadiusParameter = mitk::ConnectomicsRenderingEdgeRadiusParameterProperty::New(); mitk::ConnectomicsRenderingNodeThresholdParameterProperty::Pointer connectomicsRenderingNodeThresholdParameter = mitk::ConnectomicsRenderingNodeThresholdParameterProperty::New(); mitk::ConnectomicsRenderingEdgeThresholdParameterProperty::Pointer connectomicsRenderingEdgeThresholdParameter = mitk::ConnectomicsRenderingEdgeThresholdParameterProperty::New(); // set the properties node->AddProperty( connectomicsRenderingSchemePropertyName.c_str(), connectomicsRenderingScheme, renderer, overwrite ); node->AddProperty( connectomicsRenderingEdgeFilteringPropertyName.c_str(), connectomicsRenderingEdgeFiltering, renderer, overwrite ); node->AddProperty( connectomicsRenderingEdgeThresholdFilterParameterName.c_str(), connectomicsRenderingEdgeThresholdParameter, renderer, overwrite ); node->AddProperty( connectomicsRenderingEdgeThresholdFilterThresholdName.c_str(), connectomicsRenderingEdgeThresholdFilterThresholdDefault, renderer, overwrite ); node->AddProperty( connectomicsRenderingNodeFilteringPropertyName.c_str(), connectomicsRenderingNodeFiltering, renderer, overwrite ); node->AddProperty( connectomicsRenderingNodeThresholdFilterParameterName.c_str(), connectomicsRenderingNodeThresholdParameter, renderer, overwrite ); node->AddProperty( connectomicsRenderingNodeThresholdFilterThresholdName.c_str(), connectomicsRenderingNodeThresholdFilterThresholdDefault, renderer, overwrite ); node->AddProperty( connectomicsRenderingNodeGradientStartColorName.c_str(), connectomicsRenderingNodeGradientStartColorDefault, renderer, overwrite ); node->AddProperty( connectomicsRenderingNodeGradientEndColorName.c_str(), connectomicsRenderingNodeGradientEndColorDefault, renderer, overwrite ); node->AddProperty( connectomicsRenderingNodeGradientColorParameterName.c_str(), connectomicsRenderingNodeGradientColorParameter, renderer, overwrite ); node->AddProperty( connectomicsRenderingNodeRadiusStartName.c_str(), connectomicsRenderingNodeRadiusStartDefault, renderer, overwrite ); node->AddProperty( connectomicsRenderingNodeRadiusEndName.c_str(), connectomicsRenderingNodeRadiusEndDefault, renderer, overwrite ); node->AddProperty( connectomicsRenderingNodeRadiusParameterName.c_str(), connectomicsRenderingNodeRadiusParameter, renderer, overwrite ); node->AddProperty( connectomicsRenderingNodeChosenNodeName.c_str(), connectomicsRenderingNodeChosenNodeDefault, renderer, overwrite ); node->AddProperty( connectomicsRenderingEdgeGradientStartColorName.c_str(), connectomicsRenderingEdgeGradientStartColorDefault, renderer, overwrite ); node->AddProperty( connectomicsRenderingEdgeGradientEndColorName.c_str(), connectomicsRenderingEdgeGradientEndColorDefault, renderer, overwrite ); node->AddProperty( connectomicsRenderingEdgeGradientColorParameterName.c_str(), connectomicsRenderingEdgeGradientColorParameter, renderer, overwrite ); node->AddProperty( connectomicsRenderingEdgeRadiusStartName.c_str(), connectomicsRenderingEdgeRadiusStartDefault, renderer, overwrite ); node->AddProperty( connectomicsRenderingEdgeRadiusEndName.c_str(), connectomicsRenderingEdgeRadiusEndDefault, renderer, overwrite ); node->AddProperty( connectomicsRenderingEdgeRadiusParameterName.c_str(), connectomicsRenderingEdgeRadiusParameter, renderer, overwrite ); Superclass::SetDefaultProperties(node, renderer, overwrite); } void mitk::ConnectomicsNetworkMapper3D::ApplyProperties(mitk::BaseRenderer* renderer) { //TODO: implement } void mitk::ConnectomicsNetworkMapper3D::SetVtkMapperImmediateModeRendering(vtkMapper *mapper) { //TODO: implement } void mitk::ConnectomicsNetworkMapper3D::UpdateVtkObjects() { //TODO: implement } vtkProp* mitk::ConnectomicsNetworkMapper3D::GetVtkProp(mitk::BaseRenderer *renderer) { return m_NetworkAssembly; } bool mitk::ConnectomicsNetworkMapper3D::PropertiesChanged() { mitk::ConnectomicsRenderingSchemeProperty * renderingScheme = static_cast< mitk::ConnectomicsRenderingSchemeProperty * > ( this->GetDataNode()->GetProperty( connectomicsRenderingSchemePropertyName.c_str() ) ); mitk::ConnectomicsRenderingEdgeFilteringProperty * edgeFilter = static_cast< mitk::ConnectomicsRenderingEdgeFilteringProperty * > ( this->GetDataNode()->GetProperty( connectomicsRenderingEdgeFilteringPropertyName.c_str() ) ); mitk::FloatProperty * edgeThreshold = static_cast< mitk::FloatProperty * > ( this->GetDataNode()->GetProperty( connectomicsRenderingEdgeThresholdFilterThresholdName.c_str() ) ); mitk::ConnectomicsRenderingNodeFilteringProperty * nodeFilter = static_cast< mitk::ConnectomicsRenderingNodeFilteringProperty * > ( this->GetDataNode()->GetProperty( connectomicsRenderingNodeFilteringPropertyName.c_str() ) ); mitk::ConnectomicsRenderingNodeThresholdParameterProperty * nodeThresholdParameter = static_cast< mitk::ConnectomicsRenderingNodeThresholdParameterProperty * > ( this->GetDataNode()->GetProperty( connectomicsRenderingNodeThresholdFilterParameterName.c_str() ) ); mitk::ConnectomicsRenderingEdgeThresholdParameterProperty * edgeThresholdParameter = static_cast< mitk::ConnectomicsRenderingEdgeThresholdParameterProperty * > ( this->GetDataNode()->GetProperty( connectomicsRenderingEdgeThresholdFilterParameterName.c_str() ) ); mitk::FloatProperty * nodeThreshold = static_cast< mitk::FloatProperty * > ( this->GetDataNode()->GetProperty( connectomicsRenderingNodeThresholdFilterThresholdName.c_str() ) ); mitk::ColorProperty * nodeColorStart = static_cast< mitk::ColorProperty * > ( this->GetDataNode()->GetProperty( connectomicsRenderingNodeGradientStartColorName.c_str() ) ); mitk::ColorProperty * nodeColorEnd = static_cast< mitk::ColorProperty * > ( this->GetDataNode()->GetProperty( connectomicsRenderingNodeGradientEndColorName.c_str() ) ); mitk::FloatProperty * nodeRadiusStart = static_cast< mitk::FloatProperty * > ( this->GetDataNode()->GetProperty( connectomicsRenderingNodeRadiusStartName.c_str() ) ); mitk::FloatProperty * nodeRadiusEnd = static_cast< mitk::FloatProperty * > ( this->GetDataNode()->GetProperty( connectomicsRenderingNodeRadiusEndName.c_str() ) ); mitk::StringProperty * chosenNode = static_cast< mitk::StringProperty * > ( this->GetDataNode()->GetProperty( connectomicsRenderingNodeChosenNodeName.c_str() ) ); mitk::ColorProperty * edgeColorStart = static_cast< mitk::ColorProperty * > ( this->GetDataNode()->GetProperty( connectomicsRenderingEdgeGradientStartColorName.c_str() ) ); mitk::ColorProperty * edgeColorEnd = static_cast< mitk::ColorProperty * > ( this->GetDataNode()->GetProperty( connectomicsRenderingEdgeGradientEndColorName.c_str() ) ); mitk::FloatProperty * edgeRadiusStart = static_cast< mitk::FloatProperty * > ( this->GetDataNode()->GetProperty( connectomicsRenderingEdgeRadiusStartName.c_str() ) ); mitk::FloatProperty * edgeRadiusEnd = static_cast< mitk::FloatProperty * > ( this->GetDataNode()->GetProperty( connectomicsRenderingEdgeRadiusEndName.c_str() ) ); mitk::ConnectomicsRenderingNodeColorParameterProperty * nodeColorParameter = static_cast< mitk::ConnectomicsRenderingNodeColorParameterProperty * > ( this->GetDataNode()->GetProperty( connectomicsRenderingNodeGradientColorParameterName.c_str() ) ); mitk::ConnectomicsRenderingNodeRadiusParameterProperty * nodeRadiusParameter = static_cast< mitk::ConnectomicsRenderingNodeRadiusParameterProperty * > ( this->GetDataNode()->GetProperty( connectomicsRenderingNodeRadiusParameterName.c_str() ) ); mitk::ConnectomicsRenderingEdgeColorParameterProperty * edgeColorParameter = static_cast< mitk::ConnectomicsRenderingEdgeColorParameterProperty * > ( this->GetDataNode()->GetProperty( connectomicsRenderingEdgeGradientColorParameterName.c_str() ) ); mitk::ConnectomicsRenderingEdgeRadiusParameterProperty * edgeRadiusParameter = static_cast< mitk::ConnectomicsRenderingEdgeRadiusParameterProperty * > ( this->GetDataNode()->GetProperty( connectomicsRenderingEdgeRadiusParameterName.c_str() ) ); if( m_ChosenRenderingScheme != renderingScheme->GetValueAsString() || m_ChosenEdgeFilter != edgeFilter->GetValueAsString() || m_EdgeThreshold != edgeThreshold->GetValue() || m_EdgeThresholdParameter != edgeThresholdParameter->GetValueAsString() || m_ChosenNodeFilter != nodeFilter->GetValueAsString() || m_NodeThreshold != nodeThreshold->GetValue() || m_NodeThresholdParameter != nodeThresholdParameter->GetValueAsString() || m_NodeColorStart != nodeColorStart->GetValue() || m_NodeColorEnd != nodeColorEnd->GetValue() || m_NodeRadiusStart != nodeRadiusStart->GetValue() || m_NodeRadiusEnd != nodeRadiusEnd->GetValue() || m_ChosenNodeLabel != chosenNode->GetValueAsString() || m_EdgeColorStart != edgeColorStart->GetValue() || m_EdgeColorEnd != edgeColorEnd->GetValue() || m_EdgeRadiusStart != edgeRadiusStart->GetValue() || m_EdgeRadiusEnd != edgeRadiusEnd->GetValue() || m_NodeColorParameter != nodeColorParameter->GetValueAsString() || m_NodeRadiusParameter != nodeRadiusParameter->GetValueAsString() || m_EdgeColorParameter != edgeColorParameter->GetValueAsString() || m_EdgeRadiusParameter != edgeRadiusParameter->GetValueAsString() ) { m_ChosenRenderingScheme = renderingScheme->GetValueAsString(); m_ChosenEdgeFilter = edgeFilter->GetValueAsString(); m_EdgeThreshold = edgeThreshold->GetValue(); m_EdgeThresholdParameter = edgeThresholdParameter->GetValueAsString(); m_ChosenNodeFilter = nodeFilter->GetValueAsString(); m_NodeThreshold = nodeThreshold->GetValue(); m_NodeThresholdParameter = nodeThresholdParameter->GetValueAsString(); m_NodeColorStart = nodeColorStart->GetValue(); m_NodeColorEnd = nodeColorEnd->GetValue(); m_NodeRadiusStart = nodeRadiusStart->GetValue(); m_NodeRadiusEnd = nodeRadiusEnd->GetValue(); m_ChosenNodeLabel = chosenNode->GetValueAsString(); m_EdgeColorStart = edgeColorStart->GetValue(); m_EdgeColorEnd = edgeColorEnd->GetValue(); m_EdgeRadiusStart = edgeRadiusStart->GetValue(); m_EdgeRadiusEnd = edgeRadiusEnd->GetValue(); m_NodeColorParameter = nodeColorParameter->GetValueAsString(); m_NodeRadiusParameter = nodeRadiusParameter->GetValueAsString(); m_EdgeColorParameter = edgeColorParameter->GetValueAsString(); m_EdgeRadiusParameter = edgeRadiusParameter->GetValueAsString(); return true; } return false; } double mitk::ConnectomicsNetworkMapper3D::FillNodeParameterVector( std::vector< double > * parameterVector, std::string parameterName ) { int end( parameterVector->size() ); // constant parameter - uniform style if( parameterName == connectomicsRenderingNodeParameterConstant ) { for(int index(0); index < end; index++) { parameterVector->at( index ) = 1.0; } return 1.0; } double maximum( 0.0 ); // using the degree as parameter if( parameterName == connectomicsRenderingNodeParameterDegree ) { std::vector< int > vectorOfDegree = this->GetInput()->GetDegreeOfNodes(); for(int index(0); index < end; index++) { parameterVector->at( index ) = vectorOfDegree[ index ]; } maximum = *std::max_element( parameterVector->begin(), parameterVector->end() ); } // using betweenness centrality as parameter if( parameterName == connectomicsRenderingNodeParameterBetweenness ) { std::vector< double > vectorOfBetweenness = this->GetInput()->GetNodeBetweennessVector(); for(int index(0); index < end; index++) { parameterVector->at( index ) = vectorOfBetweenness[index]; } maximum = *std::max_element( parameterVector->begin(), parameterVector->end() ); } // using clustering coefficient as parameter if( parameterName == connectomicsRenderingNodeParameterClustering ) { const std::vector< double > vectorOfClustering = this->GetInput()->GetLocalClusteringCoefficients(); for(int index(0); index < end; index++) { parameterVector->at( index ) = vectorOfClustering[index]; } maximum = *std::max_element( parameterVector->begin(), parameterVector->end() ); } // using distance to a specific node as parameter if( parameterName == connectomicsRenderingNodeParameterColoringShortestPath ) { bool labelFound( this->GetInput()->CheckForLabel( m_ChosenNodeLabel ) ); // check whether the chosen node is valid if( !labelFound ) { MITK_WARN << "Node chosen for rendering is not valid."; for(int index(0); index < end; index++) { parameterVector->at( index ) = 1.0; } return 1.0; } else { const std::vector< double > distanceVector = this->GetInput()->GetShortestDistanceVectorFromLabel( m_ChosenNodeLabel ); for(int index(0); index < end; index++) { parameterVector->at( index ) = distanceVector[index]; } maximum = *std::max_element( parameterVector->begin(), parameterVector->end() ); } } // if the maximum is nearly zero if( std::abs( maximum ) < mitk::eps ) { maximum = 1.0; } return maximum; } double mitk::ConnectomicsNetworkMapper3D::FillEdgeParameterVector( std::vector< double > * parameterVector, std::string parameterName ) { int end( parameterVector->size() ); // constant parameter - uniform style if( parameterName == connectomicsRenderingEdgeParameterConstant ) { for(int index(0); index < end; index++) { parameterVector->at( index ) = 1.0; } return 1.0; } double maximum( 0.0 ); // using the weight as parameter if( parameterName == connectomicsRenderingEdgeParameterWeight ) { std::vector< std::pair< std::pair< mitk::ConnectomicsNetwork::NetworkNode, mitk::ConnectomicsNetwork::NetworkNode > , mitk::ConnectomicsNetwork::NetworkEdge > > vectorOfEdges = this->GetInput()->GetVectorOfAllEdges(); for(int index(0); index < end; index++) { parameterVector->at( index ) = vectorOfEdges[ index ].second.weight; } maximum = *std::max_element( parameterVector->begin(), parameterVector->end() ); } // using the edge centrality as parameter if( parameterName == connectomicsRenderingEdgeParameterCentrality ) { const std::vector< double > vectorOfCentrality = this->GetInput()->GetEdgeBetweennessVector(); for(int index(0); index < end; index++) { parameterVector->at( index ) = vectorOfCentrality[index]; } maximum = *std::max_element( parameterVector->begin(), parameterVector->end() ); } // if the maximum is nearly zero if( std::abs( maximum ) < mitk::eps ) { maximum = 1.0; } return maximum; } void mitk::ConnectomicsNetworkMapper3D::FillNodeFilterBoolVector( std::vector< bool > * boolVector, std::string parameterName ) { std::vector< double > parameterVector; parameterVector.resize( boolVector->size() ); int end( parameterVector.size() ); // using the degree as parameter if( parameterName == connectomicsRenderingNodeParameterDegree ) { std::vector< int > vectorOfDegree = this->GetInput()->GetDegreeOfNodes(); for(int index(0); index < end; index++) { parameterVector.at( index ) = vectorOfDegree[ index ]; } } // using betweenness centrality as parameter if( parameterName == connectomicsRenderingNodeParameterBetweenness ) { std::vector< double > vectorOfBetweenness = this->GetInput()->GetNodeBetweennessVector(); for(int index(0); index < end; index++) { parameterVector.at( index ) = vectorOfBetweenness[index]; } } // using clustering coefficient as parameter if( parameterName == connectomicsRenderingNodeParameterClustering ) { const std::vector< double > vectorOfClustering = this->GetInput()->GetLocalClusteringCoefficients(); for(int index(0); index < end; index++) { parameterVector.at( index ) = vectorOfClustering[index]; } } for( int index( 0 ), end( boolVector->size() ); index < end; index++ ) { if( parameterVector.at( index ) >= m_NodeThreshold ) { boolVector->at( index ) = true; } else { boolVector->at( index ) = false; } } return; } void mitk::ConnectomicsNetworkMapper3D::FillEdgeFilterBoolVector( std::vector< bool > * boolVector, std::string parameterName ) { std::vector< double > parameterVector; parameterVector.resize( boolVector->size() ); int end( parameterVector.size() ); // using the weight as parameter if( parameterName == connectomicsRenderingEdgeParameterWeight ) { std::vector< std::pair< std::pair< mitk::ConnectomicsNetwork::NetworkNode, mitk::ConnectomicsNetwork::NetworkNode > , mitk::ConnectomicsNetwork::NetworkEdge > > vectorOfEdges = this->GetInput()->GetVectorOfAllEdges(); for(int index(0); index < end; index++) { parameterVector.at( index ) = vectorOfEdges[ index ].second.weight; } } // using the edge centrality as parameter if( parameterName == connectomicsRenderingEdgeParameterCentrality ) { const std::vector< double > vectorOfCentrality = this->GetInput()->GetEdgeBetweennessVector(); for(int index(0); index < end; index++) { parameterVector.at( index ) = vectorOfCentrality[index]; } } for( int index( 0 ), end( boolVector->size() ); index < end; index++ ) { if( parameterVector.at( index ) >= m_EdgeThreshold ) { boolVector->at( index ) = true; } else { boolVector->at( index ) = false; } } return; } diff --git a/Modules/DiffusionImaging/DiffusionCore/Algorithms/Reconstruction/itkOrientationDistributionFunction.txx b/Modules/DiffusionImaging/DiffusionCore/Algorithms/Reconstruction/itkOrientationDistributionFunction.txx index c7f3464b5d..6c3a17ed2c 100644 --- a/Modules/DiffusionImaging/DiffusionCore/Algorithms/Reconstruction/itkOrientationDistributionFunction.txx +++ b/Modules/DiffusionImaging/DiffusionCore/Algorithms/Reconstruction/itkOrientationDistributionFunction.txx @@ -1,1220 +1,1220 @@ /*=================================================================== 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 _itkOrientationDistributionFunction_txx #define _itkOrientationDistributionFunction_txx #include #include #include #include #include #include #include "itkPointShell.h" #define _USE_MATH_DEFINES #include namespace itk { template vtkPolyData* itk::OrientationDistributionFunction::m_BaseMesh = NULL; template double itk::OrientationDistributionFunction::m_MaxChordLength = -1.0; template vnl_matrix_fixed* itk::OrientationDistributionFunction::m_Directions = itk::PointShell >::DistributePointShell(); template std::vector< std::vector* >* itk::OrientationDistributionFunction::m_NeighborIdxs = NULL; template std::vector< std::vector* >* itk::OrientationDistributionFunction::m_AngularRangeIdxs = NULL; template std::vector* itk::OrientationDistributionFunction::m_HalfSphereIdxs = NULL; template itk::SimpleFastMutexLock itk::OrientationDistributionFunction::m_MutexBaseMesh; template itk::SimpleFastMutexLock itk::OrientationDistributionFunction::m_MutexHalfSphereIdxs; template itk::SimpleFastMutexLock itk::OrientationDistributionFunction::m_MutexNeighbors; template itk::SimpleFastMutexLock itk::OrientationDistributionFunction::m_MutexAngularRange; #define ODF_PI M_PI /** * Assignment Operator */ template OrientationDistributionFunction& OrientationDistributionFunction ::operator= (const Self& r) { BaseArray::operator=(r); return *this; } /** * Assignment Operator from a scalar constant */ template OrientationDistributionFunction& OrientationDistributionFunction ::operator= (const ComponentType & r) { BaseArray::operator=(&r); return *this; } /** * Assigment from a plain array */ template OrientationDistributionFunction& OrientationDistributionFunction ::operator= (const ComponentArrayType r ) { BaseArray::operator=(r); return *this; } /** * Returns a temporary copy of a vector */ template OrientationDistributionFunction OrientationDistributionFunction ::operator+(const Self & r) const { Self result; for( unsigned int i=0; i OrientationDistributionFunction OrientationDistributionFunction ::operator-(const Self & r) const { Self result; for( unsigned int i=0; i const OrientationDistributionFunction & OrientationDistributionFunction ::operator+=(const Self & r) { for( unsigned int i=0; i const OrientationDistributionFunction & OrientationDistributionFunction ::operator-=(const Self & r) { for( unsigned int i=0; i const OrientationDistributionFunction & OrientationDistributionFunction ::operator*=(const RealValueType & r) { for( unsigned int i=0; i const OrientationDistributionFunction & OrientationDistributionFunction ::operator/=(const RealValueType & r) { for( unsigned int i=0; i OrientationDistributionFunction OrientationDistributionFunction ::operator*(const RealValueType & r) const { Self result; for( unsigned int i=0; i OrientationDistributionFunction OrientationDistributionFunction ::operator/(const RealValueType & r) const { Self result; for( unsigned int i=0; i const typename OrientationDistributionFunction::ValueType & OrientationDistributionFunction ::operator()(unsigned int row, unsigned int col) const { unsigned int k; if( row < col ) { k = row * InternalDimension + col - row * ( row + 1 ) / 2; } else { k = col * InternalDimension + row - col * ( col + 1 ) / 2; } if( k >= InternalDimension ) { k = 0; } return (*this)[k]; } /** * Matrix notation access to elements */ template typename OrientationDistributionFunction::ValueType & OrientationDistributionFunction ::operator()(unsigned int row, unsigned int col) { unsigned int k; if( row < col ) { k = row * InternalDimension + col - row * ( row + 1 ) / 2; } else { k = col * InternalDimension + row - col * ( col + 1 ) / 2; } if( k >= InternalDimension ) { k = 0; } return (*this)[k]; } /** * Set the Tensor to an Identity. * Set ones in the diagonal and zeroes every where else. */ template void OrientationDistributionFunction ::SetIsotropic() { this->Fill(NumericTraits< T >::One / NOdfDirections); } /** * Set the Tensor to an Identity. * Set ones in the diagonal and zeroes every where else. */ template void OrientationDistributionFunction ::InitFromTensor(itk::DiffusionTensor3D tensor) { for(unsigned int i=0; i void OrientationDistributionFunction ::L2Normalize() { T sum = 0; for( unsigned int i=0; i void OrientationDistributionFunction ::Normalize() { T sum = 0; for( unsigned int i=0; i0) { for( unsigned int i=0; i OrientationDistributionFunction OrientationDistributionFunction ::MinMaxNormalize() const { T max = NumericTraits::NonpositiveMin(); T min = NumericTraits::max(); for( unsigned int i=0; i max ? (*this)[i] : max; min = (*this)[i] < min ? (*this)[i] : min; } Self retval; for( unsigned int i=0; i OrientationDistributionFunction OrientationDistributionFunction ::MaxNormalize() const { T max = NumericTraits::NonpositiveMin(); for( unsigned int i=0; i max ? (*this)[i] : max; } Self retval; for( unsigned int i=0; i T OrientationDistributionFunction ::GetMaxValue() const { T max = NumericTraits::NonpositiveMin(); for( unsigned int i=0; i= max ) { max = (*this)[i]; } } return max; } template T OrientationDistributionFunction ::GetMinValue() const { T min = NumericTraits::max(); for( unsigned int i=0; i= min ) { min = (*this)[i]; } } return min; } template T OrientationDistributionFunction ::GetMeanValue() const { T sum = 0; for( unsigned int i=0; i double OrientationDistributionFunction ::GetMaxChordLength() { if(m_MaxChordLength<0.0) { ComputeBaseMesh(); double max_dist = -1; vtkPoints* points = m_BaseMesh->GetPoints(); for(int i=0; iGetPoint(i,p); std::vector neighbors = GetNeighbors(i); for(int j=0; jGetPoint(neighbors[j],n); double d = sqrt( (p[0]-n[0])*(p[0]-n[0]) + (p[1]-n[1])*(p[1]-n[1]) + (p[2]-n[2])*(p[2]-n[2])); max_dist = d>max_dist ? d : max_dist; } } m_MaxChordLength = max_dist; } return m_MaxChordLength; } template void OrientationDistributionFunction ::ComputeBaseMesh() { m_MutexBaseMesh.Lock(); if(m_BaseMesh == NULL) { vtkPoints* points = vtkPoints::New(); for(unsigned int j=0; jInsertNextPoint(az,elev,r); } vtkPolyData* polydata = vtkPolyData::New(); polydata->SetPoints( points ); vtkDelaunay2D *delaunay = vtkDelaunay2D::New(); - delaunay->SetInput( polydata ); + delaunay->SetInputData( polydata ); delaunay->Update(); vtkCellArray* vtkpolys = delaunay->GetOutput()->GetPolys(); vtkCellArray* vtknewpolys = vtkCellArray::New(); vtkIdType npts; vtkIdType *pts; while(vtkpolys->GetNextCell(npts,pts)) { bool insert = true; for(int i=0; iGetPoint(pts[i]); double az = tmpPoint[0]; double elev = tmpPoint[1]; if((abs(az)>ODF_PI-0.5) || (abs(elev)>ODF_PI/2-0.5)) insert = false; } if(insert) vtknewpolys->InsertNextCell(npts, pts); } vtkPoints* points2 = vtkPoints::New(); for(unsigned int j=0; jInsertNextPoint(az,elev,r); } vtkPolyData* polydata2 = vtkPolyData::New(); polydata2->SetPoints( points2 ); vtkDelaunay2D *delaunay2 = vtkDelaunay2D::New(); - delaunay2->SetInput( polydata2 ); + delaunay2->SetInputData( polydata2 ); delaunay2->Update(); vtkpolys = delaunay2->GetOutput()->GetPolys(); while(vtkpolys->GetNextCell(npts,pts)) { bool insert = true; for(int i=0; iGetPoint(pts[i]); double az = tmpPoint[0]; double elev = tmpPoint[1]; if((abs(az)>ODF_PI-0.5) || (abs(elev)>ODF_PI/2-0.5)) insert = false; } if(insert) vtknewpolys->InsertNextCell(npts, pts); } polydata->SetPolys(vtknewpolys); for (vtkIdType p = 0; p < NOdfDirections; p++) { points->SetPoint(p,m_Directions->get_column(p).data_block()); } polydata->SetPoints( points ); m_BaseMesh = polydata; } m_MutexBaseMesh.Unlock(); } /** * Extract the principle diffusion direction */ template int OrientationDistributionFunction ::GetPrincipleDiffusionDirection() const { T max = NumericTraits::NonpositiveMin(); int maxidx = -1; for( unsigned int i=0; i= max ) { max = (*this)[i]; maxidx = i; } } return maxidx; } template std::vector OrientationDistributionFunction ::GetNeighbors(int idx) { ComputeBaseMesh(); m_MutexNeighbors.Lock(); if(m_NeighborIdxs == NULL) { m_NeighborIdxs = new std::vector< std::vector* >(); vtkCellArray* polys = m_BaseMesh->GetPolys(); for(unsigned int i=0; i *idxs = new std::vector(); polys->InitTraversal(); vtkIdType npts; vtkIdType *pts; while(polys->GetNextCell(npts,pts)) { if( pts[0] == i ) { idxs->push_back(pts[1]); idxs->push_back(pts[2]); } else if( pts[1] == i ) { idxs->push_back(pts[0]); idxs->push_back(pts[2]); } else if( pts[2] == i ) { idxs->push_back(pts[0]); idxs->push_back(pts[1]); } } std::sort(idxs->begin(), idxs->end()); std::vector< int >::iterator endLocation; endLocation = std::unique( idxs->begin(), idxs->end() ); idxs->erase(endLocation, idxs->end()); m_NeighborIdxs->push_back(idxs); } } m_MutexNeighbors.Unlock(); return *m_NeighborIdxs->at(idx); } /** * Extract the n-th diffusion direction */ template int OrientationDistributionFunction ::GetNthDiffusionDirection(int n, vnl_vector_fixed rndVec) const { if( n == 0 ) return GetPrincipleDiffusionDirection(); m_MutexHalfSphereIdxs.Lock(); if( !m_HalfSphereIdxs ) { m_HalfSphereIdxs = new std::vector(); for( unsigned int i=0; iget_column(i),rndVec) > 0.0) { m_HalfSphereIdxs->push_back(i); } } } m_MutexHalfSphereIdxs.Unlock(); // collect indices of directions // that are local maxima std::vector localMaxima; std::vector::iterator it; for( it=m_HalfSphereIdxs->begin(); it!=m_HalfSphereIdxs->end(); it++) { std::vector nbs = GetNeighbors(*it); std::vector::iterator it2; bool max = true; for(it2 = nbs.begin(); it2 != nbs.end(); it2++) { if((*this)[*it2] > (*this)[*it]) { max = false; break; } } if(max) localMaxima.push_back(*it); } // delete n highest local maxima from list // and return remaining highest int maxidx = -1; std::vector::iterator itMax; for( int i=0; i<=n; i++ ) { maxidx = -1; T max = NumericTraits::NonpositiveMin(); for(it = localMaxima.begin(); it != localMaxima.end(); it++) { if((*this)[*it]>max) { max = (*this)[*it]; maxidx = *it; } } it = find(localMaxima.begin(), localMaxima.end(), maxidx); if(it!=localMaxima.end()) localMaxima.erase(it); } return maxidx; } template < typename TComponent, unsigned int NOdfDirections > vnl_vector_fixed itk::OrientationDistributionFunction ::GetDirection( int i ) { return m_Directions->get_column(i); } /** * Interpolate a position between sampled directions */ template T OrientationDistributionFunction ::GetInterpolatedComponent(vnl_vector_fixed dir, InterpolationMethods method) const { ComputeBaseMesh(); double retval = -1.0; switch(method) { case ODF_NEAREST_NEIGHBOR_INTERP: { vtkPoints* points = m_BaseMesh->GetPoints(); double current_min = NumericTraits::max(); int current_min_idx = -1; for(int i=0; i P(points->GetPoint(i)); double dist = (dir-P).two_norm(); current_min_idx = distGetNthComponent(current_min_idx); break; } case ODF_TRILINEAR_BARYCENTRIC_INTERP: { double maxChordLength = GetMaxChordLength(); vtkCellArray* polys = m_BaseMesh->GetPolys(); vtkPoints* points = m_BaseMesh->GetPoints(); vtkIdType npts; vtkIdType *pts; double current_min = NumericTraits::max(); polys->InitTraversal(); while(polys->GetNextCell(npts,pts)) { vnl_vector_fixed A(points->GetPoint(pts[0])); vnl_vector_fixed B(points->GetPoint(pts[1])); vnl_vector_fixed C(points->GetPoint(pts[2])); vnl_vector_fixed d1; d1.put(0,(dir-A).two_norm()); d1.put(1,(dir-B).two_norm()); d1.put(2,(dir-C).two_norm()); double maxval = d1.max_value(); if(maxval>maxChordLength) { continue; } // Compute vectors vnl_vector_fixed v0 = C - A; vnl_vector_fixed v1 = B - A; // Project direction to plane ABC vnl_vector_fixed v6 = dir; vnl_vector_fixed cross = vnl_cross_3d(v0, v1); cross = cross.normalize(); vtkPlane::ProjectPoint(v6.data_block(),A.data_block(),cross.data_block(),v6.data_block()); v6 = v6-A; // Calculate barycentric coords vnl_matrix_fixed mat; mat.set_column(0, v0); mat.set_column(1, v1); vnl_matrix_inverse inv(mat); vnl_matrix_fixed inver = inv.pinverse(); vnl_vector uv = inv.pinverse()*v6; // Check if point is in triangle double eps = 0.01; if( (uv(0) >= 0-eps) && (uv(1) >= 0-eps) && (uv(0) + uv(1) <= 1+eps) ) { // check if minimum angle is the max so far if(d1.two_norm() < current_min) { current_min = d1.two_norm(); vnl_vector barycentricCoords(3); barycentricCoords[2] = uv[0]<0 ? 0 : (uv[0]>1?1:uv[0]); barycentricCoords[1] = uv[1]<0 ? 0 : (uv[1]>1?1:uv[1]); barycentricCoords[0] = 1-(barycentricCoords[1]+barycentricCoords[2]); retval = barycentricCoords[0]*this->GetNthComponent(pts[0]) + barycentricCoords[1]*this->GetNthComponent(pts[1]) + barycentricCoords[2]*this->GetNthComponent(pts[2]); } } } break; } case ODF_SPHERICAL_GAUSSIAN_BASIS_FUNCTIONS: { double maxChordLength = GetMaxChordLength(); double sigma = asin(maxChordLength/2); // this is the contribution of each kernel to each sampling point on the // equator vnl_vector contrib; contrib.set_size(NOdfDirections); vtkPoints* points = m_BaseMesh->GetPoints(); double sum = 0; for(int i=0; i P(points->GetPoint(i)); double stv = dir[0]*P[0] + dir[1]*P[1] + dir[2]*P[2]; stv = (stv<-1.0) ? -1.0 : ( (stv>1.0) ? 1.0 : stv); double x = acos(stv); contrib[i] = (1.0/(sigma*sqrt(2.0*ODF_PI))) *exp((-x*x)/(2*sigma*sigma)); sum += contrib[i]; } retval = 0; for(int i=0; iGetNthComponent(i); } break; } } if(retval==-1) { std::cout << "Interpolation failed" << std::endl; return 0; } return retval; } /** * Calculate Generalized Fractional Anisotropy */ template T OrientationDistributionFunction ::GetGeneralizedFractionalAnisotropy() const { double mean = 0; double std = 0; double rms = 0; for( unsigned int i=0; i T itk::OrientationDistributionFunction ::GetGeneralizedGFA( int k, int p ) const { double mean = 0; double std = 0; double rms = 0; double max = NumericTraits::NonpositiveMin(); for( unsigned int i=0; i max ? val : max; } max = pow(max,(double)p); mean /= N; for( unsigned int i=0; i0) { rms += pow(val,(double)(p*k)); } } std /= N - 1; std = sqrt(std); if(k>0) { rms /= N; rms = pow(rms,(double)(1.0/k)); } else if(k<0) // lim k->inf gives us the maximum { rms = max; } else // k==0 undefined, we define zeros root from 1 as 1 { rms = 1; } if(rms == 0) { return 0; } else { return (T)(std/rms); } } /** * Calculate Nematic Order Parameter */ template < typename T, unsigned int N > T itk::OrientationDistributionFunction ::GetNematicOrderParameter() const { // not yet implemented return 0; } /** * Calculate StdDev by MaxValue */ template < typename T, unsigned int N > T itk::OrientationDistributionFunction ::GetStdDevByMaxValue() const { double mean = 0; double std = 0; T max = NumericTraits::NonpositiveMin(); for( unsigned int i=0; i max ? (*this)[i] : max; } mean /= InternalDimension; for( unsigned int i=0; i T itk::OrientationDistributionFunction ::GetPrincipleCurvature(double alphaMinDegree, double alphaMaxDegree, int invert) const { // following loop only performed once // (computing indices of each angular range) m_MutexAngularRange.Lock(); if(m_AngularRangeIdxs == NULL) { m_AngularRangeIdxs = new std::vector< std::vector* >(); for(unsigned int i=0; i pDir = GetDirection(i); std::vector *idxs = new std::vector(); for(unsigned int j=0; j cDir = GetDirection(j); double angle = ( 180 / ODF_PI ) * acos( dot_product(pDir, cDir) ); if( (angle < alphaMaxDegree) && (angle > alphaMinDegree) ) { idxs->push_back(j); } } m_AngularRangeIdxs->push_back(idxs); } } m_MutexAngularRange.Unlock(); // find the maximum (or minimum) direction (remember index and value) T mode; int pIdx = -1; if(invert == 0) { pIdx = GetPrincipleDiffusionDirection(); mode = (*this)[pIdx]; } else { mode = NumericTraits::max(); for( unsigned int i=0; i nbs = GetNeighbors(pIdx); //////std::vector modeAndNeighborVals; //////modeAndNeighborVals.push_back(mode); //////int numNeighbors = nbs.size(); //////for(int i=0; i odfValuesInAngularRange; int numInRange = m_AngularRangeIdxs->at(pIdx)->size(); for(int i=0; iat(pIdx))[i] ]); } // sort them by value std::sort( odfValuesInAngularRange.begin(), odfValuesInAngularRange.end() ); // median of angular range T median = odfValuesInAngularRange[floor(quantile*(double)numInRange+0.5)]; // compute and return final value if(mode > median) { return mode/median - 1.0; } else { return median/mode - 1.0; } } /** * Calculate Normalized Entropy */ template < typename T, unsigned int N > T itk::OrientationDistributionFunction ::GetNormalizedEntropy() const { double mean = 0; for( unsigned int i=0; i OrientationDistributionFunction OrientationDistributionFunction ::PreMultiply( const MatrixType & m ) const { Self result; typedef typename NumericTraits::AccumulateType AccumulateType; for(unsigned int r=0; r::ZeroValue(); for(unsigned int t=0; t( sum ); } } return result; } /** * Post-multiply the Tensor by a Matrix */ template OrientationDistributionFunction OrientationDistributionFunction ::PostMultiply( const MatrixType & m ) const { Self result; typedef typename NumericTraits::AccumulateType AccumulateType; for(unsigned int r=0; r::ZeroValue(); for(unsigned int t=0; t( sum ); } } return result; } /** * Print content to an ostream */ template std::ostream & operator<<(std::ostream& os,const OrientationDistributionFunction & c ) { for(unsigned int i=0; i::PrintType>(c[i]) << " "; } return os; } /** * Read content from an istream */ template std::istream & operator>>(std::istream& is, OrientationDistributionFunction & dt ) { for(unsigned int i=0; i < dt.GetNumberOfComponents(); i++) { is >> dt[i]; } return is; } } // end namespace itk #endif diff --git a/Modules/DiffusionImaging/DiffusionCore/Algorithms/mitkPartialVolumeAnalysisHistogramCalculator.cpp b/Modules/DiffusionImaging/DiffusionCore/Algorithms/mitkPartialVolumeAnalysisHistogramCalculator.cpp index c7e397bba0..5bf001d9f6 100644 --- a/Modules/DiffusionImaging/DiffusionCore/Algorithms/mitkPartialVolumeAnalysisHistogramCalculator.cpp +++ b/Modules/DiffusionImaging/DiffusionCore/Algorithms/mitkPartialVolumeAnalysisHistogramCalculator.cpp @@ -1,1254 +1,1254 @@ /*=================================================================== 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 "mitkPartialVolumeAnalysisHistogramCalculator.h" #include "mitkImageAccessByItk.h" #include "mitkExtractImageFilter.h" #include #include #include #include #include #include "itkResampleImageFilter.h" #include "itkGaussianInterpolateImageFunction.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "itkGaussianInterpolateImageFunction.h" #include "itkBSplineInterpolateImageFunction.h" #include "itkNearestNeighborInterpolateImageFunction.h" #include "itkImageMaskSpatialObject.h" #include "itkRegionOfInterestImageFilter.h" #include "itkListSample.h" #include #include namespace mitk { PartialVolumeAnalysisHistogramCalculator::PartialVolumeAnalysisHistogramCalculator() : m_MaskingMode( MASKING_MODE_NONE ), m_MaskingModeChanged( false ), m_NumberOfBins(256), m_UpsamplingFactor(1), m_GaussianSigma(0), m_ForceUpdate(false), m_PlanarFigureThickness(0) { m_EmptyHistogram = HistogramType::New(); m_EmptyHistogram->SetMeasurementVectorSize(1); HistogramType::SizeType histogramSize(1); histogramSize.Fill( 256 ); m_EmptyHistogram->Initialize( histogramSize ); m_EmptyStatistics.Reset(); } PartialVolumeAnalysisHistogramCalculator::~PartialVolumeAnalysisHistogramCalculator() { } void PartialVolumeAnalysisHistogramCalculator::SetImage( const mitk::Image *image ) { if ( m_Image != image ) { m_Image = image; this->Modified(); m_ImageStatisticsTimeStamp.Modified(); m_ImageStatisticsCalculationTriggerBool = true; } } void PartialVolumeAnalysisHistogramCalculator::AddAdditionalResamplingImage( const mitk::Image *image ) { m_AdditionalResamplingImages.push_back(image); this->Modified(); m_ImageStatisticsTimeStamp.Modified(); m_ImageStatisticsCalculationTriggerBool = true; } void PartialVolumeAnalysisHistogramCalculator::SetModified( ) { this->Modified(); m_ImageStatisticsTimeStamp.Modified(); m_ImageStatisticsCalculationTriggerBool = true; m_MaskedImageStatisticsTimeStamp.Modified(); m_MaskedImageStatisticsCalculationTriggerBool = true; m_PlanarFigureStatisticsTimeStamp.Modified(); m_PlanarFigureStatisticsCalculationTriggerBool = true; } void PartialVolumeAnalysisHistogramCalculator::SetImageMask( const mitk::Image *imageMask ) { if ( m_Image.IsNull() ) { itkExceptionMacro( << "Image needs to be set first!" ); } if ( m_Image->GetTimeSteps() != imageMask->GetTimeSteps() ) { itkExceptionMacro( << "Image and image mask need to have equal number of time steps!" ); } if ( m_ImageMask != imageMask ) { m_ImageMask = imageMask; this->Modified(); m_MaskedImageStatisticsTimeStamp.Modified(); m_MaskedImageStatisticsCalculationTriggerBool = true; } } void PartialVolumeAnalysisHistogramCalculator::SetPlanarFigure( const mitk::PlanarFigure *planarFigure ) { if ( m_Image.IsNull() ) { itkExceptionMacro( << "Image needs to be set first!" ); } if ( m_PlanarFigure != planarFigure ) { m_PlanarFigure = planarFigure; this->Modified(); m_PlanarFigureStatisticsTimeStamp.Modified(); m_PlanarFigureStatisticsCalculationTriggerBool = true; } } void PartialVolumeAnalysisHistogramCalculator::SetMaskingMode( unsigned int mode ) { if ( m_MaskingMode != mode ) { m_MaskingMode = mode; m_MaskingModeChanged = true; this->Modified(); } } void PartialVolumeAnalysisHistogramCalculator::SetMaskingModeToNone() { if ( m_MaskingMode != MASKING_MODE_NONE ) { m_MaskingMode = MASKING_MODE_NONE; m_MaskingModeChanged = true; this->Modified(); } } void PartialVolumeAnalysisHistogramCalculator::SetMaskingModeToImage() { if ( m_MaskingMode != MASKING_MODE_IMAGE ) { m_MaskingMode = MASKING_MODE_IMAGE; m_MaskingModeChanged = true; this->Modified(); } } void PartialVolumeAnalysisHistogramCalculator::SetMaskingModeToPlanarFigure() { if ( m_MaskingMode != MASKING_MODE_PLANARFIGURE ) { m_MaskingMode = MASKING_MODE_PLANARFIGURE; m_MaskingModeChanged = true; this->Modified(); } } bool PartialVolumeAnalysisHistogramCalculator::ComputeStatistics() { MITK_DEBUG << "ComputeStatistics() start"; if ( m_Image.IsNull() ) { itkExceptionMacro( << "Image not set!" ); } if ( m_Image->GetReferenceCount() == 1 ) { MITK_DEBUG << "No Stats calculated; no one else holds a reference on it"; return false; } // If a mask was set but we are the only ones to still hold a reference on // it, delete it. if ( m_ImageMask.IsNotNull() && (m_ImageMask->GetReferenceCount() == 1) ) { m_ImageMask = NULL; } // Check if statistics is already up-to-date unsigned long imageMTime = m_ImageStatisticsTimeStamp.GetMTime(); unsigned long maskedImageMTime = m_MaskedImageStatisticsTimeStamp.GetMTime(); unsigned long planarFigureMTime = m_PlanarFigureStatisticsTimeStamp.GetMTime(); bool imageStatisticsCalculationTrigger = m_ImageStatisticsCalculationTriggerBool; bool maskedImageStatisticsCalculationTrigger = m_MaskedImageStatisticsCalculationTriggerBool; bool planarFigureStatisticsCalculationTrigger = m_PlanarFigureStatisticsCalculationTriggerBool; if ( /*prevent calculation without mask*/!m_ForceUpdate &&( m_MaskingMode == MASKING_MODE_NONE || ( ((m_MaskingMode != MASKING_MODE_NONE) || (imageMTime > m_Image->GetMTime() && !imageStatisticsCalculationTrigger)) && ((m_MaskingMode != MASKING_MODE_IMAGE) || (m_ImageMask.IsNotNull() && maskedImageMTime > m_ImageMask->GetMTime() && !maskedImageStatisticsCalculationTrigger)) && ((m_MaskingMode != MASKING_MODE_PLANARFIGURE) || (m_PlanarFigure.IsNotNull() && planarFigureMTime > m_PlanarFigure->GetMTime() && !planarFigureStatisticsCalculationTrigger)) ) ) ) { MITK_DEBUG << "Returning, statistics already up to date!"; if ( m_MaskingModeChanged ) { m_MaskingModeChanged = false; return true; } else { return false; } } // Reset state changed flag m_MaskingModeChanged = false; // Depending on masking mode, extract and/or generate the required image // and mask data from the user input this->ExtractImageAndMask( ); Statistics *statistics; HistogramType::ConstPointer *histogram; switch ( m_MaskingMode ) { case MASKING_MODE_NONE: default: statistics = &m_ImageStatistics; histogram = &m_ImageHistogram; m_ImageStatisticsTimeStamp.Modified(); m_ImageStatisticsCalculationTriggerBool = false; break; case MASKING_MODE_IMAGE: statistics = &m_MaskedImageStatistics; histogram = &m_MaskedImageHistogram; m_MaskedImageStatisticsTimeStamp.Modified(); m_MaskedImageStatisticsCalculationTriggerBool = false; break; case MASKING_MODE_PLANARFIGURE: statistics = &m_PlanarFigureStatistics; histogram = &m_PlanarFigureHistogram; m_PlanarFigureStatisticsTimeStamp.Modified(); m_PlanarFigureStatisticsCalculationTriggerBool = false; break; } // Calculate statistics and histogram(s) if ( m_InternalImage->GetDimension() == 3 ) { if ( m_MaskingMode == MASKING_MODE_NONE ) { // Reset state changed flag AccessFixedDimensionByItk_2( m_InternalImage, InternalCalculateStatisticsUnmasked, 3, *statistics, histogram ); } else { AccessFixedDimensionByItk_3( m_InternalImage, InternalCalculateStatisticsMasked, 3, m_InternalImageMask3D.GetPointer(), *statistics, histogram ); } } else if ( m_InternalImage->GetDimension() == 2 ) { if ( m_MaskingMode == MASKING_MODE_NONE ) { AccessFixedDimensionByItk_2( m_InternalImage, InternalCalculateStatisticsUnmasked, 2, *statistics, histogram ); } else { AccessFixedDimensionByItk_3( m_InternalImage, InternalCalculateStatisticsMasked, 2, m_InternalImageMask2D.GetPointer(), *statistics, histogram ); } } else { MITK_ERROR << "ImageStatistics: Image dimension not supported!"; } // Release unused image smart pointers to free memory // m_InternalImage = mitk::Image::Pointer(); m_InternalImageMask3D = MaskImage3DType::Pointer(); m_InternalImageMask2D = MaskImage2DType::Pointer(); return true; } const PartialVolumeAnalysisHistogramCalculator::HistogramType * PartialVolumeAnalysisHistogramCalculator::GetHistogram( ) const { if ( m_Image.IsNull() ) { return NULL; } switch ( m_MaskingMode ) { case MASKING_MODE_NONE: default: return m_ImageHistogram; case MASKING_MODE_IMAGE: return m_MaskedImageHistogram; case MASKING_MODE_PLANARFIGURE: return m_PlanarFigureHistogram; } } const PartialVolumeAnalysisHistogramCalculator::Statistics & PartialVolumeAnalysisHistogramCalculator::GetStatistics( ) const { if ( m_Image.IsNull() ) { return m_EmptyStatistics; } switch ( m_MaskingMode ) { case MASKING_MODE_NONE: default: return m_ImageStatistics; case MASKING_MODE_IMAGE: return m_MaskedImageStatistics; case MASKING_MODE_PLANARFIGURE: return m_PlanarFigureStatistics; } } void PartialVolumeAnalysisHistogramCalculator::ExtractImageAndMask( ) { MITK_DEBUG << "ExtractImageAndMask( ) start"; if ( m_Image.IsNull() ) { throw std::runtime_error( "Error: image empty!" ); } mitk::Image *timeSliceImage = const_cast(m_Image.GetPointer());//imageTimeSelector->GetOutput(); switch ( m_MaskingMode ) { case MASKING_MODE_NONE: { m_InternalImage = timeSliceImage; int s = m_AdditionalResamplingImages.size(); m_InternalAdditionalResamplingImages.resize(s); for(int i=0; i(m_AdditionalResamplingImages[i].GetPointer()); } m_InternalImageMask2D = NULL; m_InternalImageMask3D = NULL; break; } case MASKING_MODE_IMAGE: { if ( m_ImageMask.IsNotNull() && (m_ImageMask->GetReferenceCount() > 1) ) { ImageTimeSelector::Pointer maskedImageTimeSelector = ImageTimeSelector::New(); maskedImageTimeSelector->SetInput( m_ImageMask ); maskedImageTimeSelector->SetTimeNr( 0 ); maskedImageTimeSelector->UpdateLargestPossibleRegion(); mitk::Image *timeSliceMaskedImage = maskedImageTimeSelector->GetOutput(); InternalMaskImage(timeSliceMaskedImage); if(m_UpsamplingFactor != 1) { InternalResampleImage(m_InternalImageMask3D); } AccessFixedDimensionByItk_1( timeSliceImage, InternalResampleImageFromMask, 3, -1 ); int s = m_AdditionalResamplingImages.size(); m_InternalAdditionalResamplingImages.resize(s); for(int i=0; iIsClosed() ) { throw std::runtime_error( "Masking not possible for non-closed figures" ); } const Geometry3D *imageGeometry = timeSliceImage->GetUpdatedGeometry(); if ( imageGeometry == NULL ) { throw std::runtime_error( "Image geometry invalid!" ); } const Geometry2D *planarFigureGeometry2D = m_PlanarFigure->GetGeometry2D(); if ( planarFigureGeometry2D == NULL ) { throw std::runtime_error( "Planar-Figure not yet initialized!" ); } const PlaneGeometry *planarFigureGeometry = dynamic_cast< const PlaneGeometry * >( planarFigureGeometry2D ); if ( planarFigureGeometry == NULL ) { throw std::runtime_error( "Non-planar planar figures not supported!" ); } // unsigned int axis = 2; // unsigned int slice = 0; AccessFixedDimensionByItk_3( timeSliceImage, InternalReorientImagePlane, 3, timeSliceImage->GetGeometry(), m_PlanarFigure->GetGeometry(), -1 ); AccessFixedDimensionByItk_1( m_InternalImage, InternalCalculateMaskFromPlanarFigure, 3, 2 ); int s = m_AdditionalResamplingImages.size(); for(int i=0; iGetGeometry(), m_PlanarFigure->GetGeometry(), i ); AccessFixedDimensionByItk_1( m_InternalAdditionalResamplingImages[i], InternalCropAdditionalImage, 3, i ); } } } } bool PartialVolumeAnalysisHistogramCalculator::GetPrincipalAxis( const Geometry3D *geometry, Vector3D vector, unsigned int &axis ) { vector.Normalize(); for ( unsigned int i = 0; i < 3; ++i ) { Vector3D axisVector = geometry->GetAxisVector( i ); axisVector.Normalize(); if ( fabs( fabs( axisVector * vector ) - 1.0) < mitk::eps ) { axis = i; return true; } } return false; } void PartialVolumeAnalysisHistogramCalculator::InternalMaskImage( mitk::Image *image ) { typedef itk::ImageMaskSpatialObject<3> ImageMaskSpatialObject; typedef itk::Image< unsigned char, 3 > ImageType; typedef itk::ImageRegion<3> RegionType; typedef mitk::ImageToItk CastType; CastType::Pointer caster = CastType::New(); caster->SetInput(image); caster->Update(); ImageMaskSpatialObject::Pointer maskSO = ImageMaskSpatialObject::New(); maskSO->SetImage ( caster->GetOutput() ); m_InternalMask3D = maskSO->GetAxisAlignedBoundingBoxRegion(); // check if bounding box is empty, if so set it to 1,1,1 // to prevent empty mask image if (m_InternalMask3D.GetSize()[0] == 0 ) { m_InternalMask3D.SetSize(0,1); m_InternalMask3D.SetSize(1,1); m_InternalMask3D.SetSize(2,1); } MITK_DEBUG << "Bounding Box Region: " << m_InternalMask3D; typedef itk::RegionOfInterestImageFilter< ImageType, MaskImage3DType > ROIFilterType; ROIFilterType::Pointer roi = ROIFilterType::New(); roi->SetRegionOfInterest(m_InternalMask3D); roi->SetInput(caster->GetOutput()); roi->Update(); m_InternalImageMask3D = roi->GetOutput(); MITK_DEBUG << "Created m_InternalImageMask3D"; } template < typename TPixel, unsigned int VImageDimension > void PartialVolumeAnalysisHistogramCalculator::InternalReorientImagePlane( const itk::Image< TPixel, VImageDimension > *image, mitk::Geometry3D* imggeo, mitk::Geometry3D* planegeo3D, int additionalIndex ) { MITK_DEBUG << "InternalReorientImagePlane() start"; typedef itk::Image< TPixel, VImageDimension > ImageType; typedef itk::Image< float, VImageDimension > FloatImageType; typedef itk::ResampleImageFilter ResamplerType; typename ResamplerType::Pointer resampler = ResamplerType::New(); mitk::PlaneGeometry* planegeo = dynamic_cast(planegeo3D); float upsamp = m_UpsamplingFactor; float gausssigma = m_GaussianSigma; // Spacing typename ResamplerType::SpacingType spacing = planegeo->GetSpacing(); spacing[0] = image->GetSpacing()[0] / upsamp; spacing[1] = image->GetSpacing()[1] / upsamp; spacing[2] = image->GetSpacing()[2]; if(m_PlanarFigureThickness) { spacing[2] = image->GetSpacing()[2] / upsamp; } resampler->SetOutputSpacing( spacing ); // Size typename ResamplerType::SizeType size; size[0] = planegeo->GetParametricExtentInMM(0) / spacing[0]; size[1] = planegeo->GetParametricExtentInMM(1) / spacing[1]; size[2] = 1+2*m_PlanarFigureThickness; // klaus add +2*m_PlanarFigureThickness MITK_DEBUG << "setting size2:="<SetSize( size ); // Origin typename mitk::Point3D orig = planegeo->GetOrigin(); typename mitk::Point3D corrorig; planegeo3D->WorldToIndex(orig,corrorig); corrorig[0] += 0.5/upsamp; corrorig[1] += 0.5/upsamp; if(m_PlanarFigureThickness) { float thickyyy = m_PlanarFigureThickness; thickyyy/=upsamp; corrorig[2] -= thickyyy; // klaus add -= (float)m_PlanarFigureThickness/upsamp statt += 0 } planegeo3D->IndexToWorld(corrorig,corrorig); resampler->SetOutputOrigin(corrorig ); // Direction typename ResamplerType::DirectionType direction; typename mitk::AffineTransform3D::MatrixType matrix = planegeo->GetIndexToWorldTransform()->GetMatrix(); for(int c=0; cSetOutputDirection( direction ); // Gaussian interpolation if(gausssigma != 0) { double sigma[3]; for( unsigned int d = 0; d < 3; d++ ) { sigma[d] = gausssigma * image->GetSpacing()[d]; } double alpha = 2.0; typedef itk::GaussianInterpolateImageFunction GaussianInterpolatorType; typename GaussianInterpolatorType::Pointer interpolator = GaussianInterpolatorType::New(); interpolator->SetInputImage( image ); interpolator->SetParameters( sigma, alpha ); resampler->SetInterpolator( interpolator ); } else { // typedef typename itk::BSplineInterpolateImageFunction // InterpolatorType; typedef typename itk::LinearInterpolateImageFunction InterpolatorType; typename InterpolatorType::Pointer interpolator = InterpolatorType::New(); interpolator->SetInputImage( image ); resampler->SetInterpolator( interpolator ); } // Other resampling options resampler->SetInput( image ); resampler->SetDefaultPixelValue(0); MITK_DEBUG << "Resampling requested image plane ... "; resampler->Update(); MITK_DEBUG << " ... done"; if(additionalIndex < 0) { this->m_InternalImage = mitk::Image::New(); this->m_InternalImage->InitializeByItk( resampler->GetOutput() ); this->m_InternalImage->SetVolume( resampler->GetOutput()->GetBufferPointer() ); } else { unsigned int myIndex = additionalIndex; this->m_InternalAdditionalResamplingImages.push_back(mitk::Image::New()); this->m_InternalAdditionalResamplingImages[myIndex]->InitializeByItk( resampler->GetOutput() ); this->m_InternalAdditionalResamplingImages[myIndex]->SetVolume( resampler->GetOutput()->GetBufferPointer() ); } } template < typename TPixel, unsigned int VImageDimension > void PartialVolumeAnalysisHistogramCalculator::InternalResampleImageFromMask( const itk::Image< TPixel, VImageDimension > *image, int additionalIndex ) { typedef itk::Image< TPixel, VImageDimension > ImageType; typename ImageType::Pointer outImage = ImageType::New(); outImage->SetSpacing( m_InternalImageMask3D->GetSpacing() ); // Set the image spacing outImage->SetOrigin( m_InternalImageMask3D->GetOrigin() ); // Set the image origin outImage->SetDirection( m_InternalImageMask3D->GetDirection() ); // Set the image direction outImage->SetRegions( m_InternalImageMask3D->GetLargestPossibleRegion() ); outImage->Allocate(); outImage->FillBuffer(0); typedef itk::InterpolateImageFunction BaseInterpType; typedef itk::GaussianInterpolateImageFunction GaussianInterpolatorType; typedef itk::LinearInterpolateImageFunction LinearInterpolatorType; typename BaseInterpType::Pointer interpolator; if(m_GaussianSigma != 0) { double sigma[3]; for( unsigned int d = 0; d < 3; d++ ) { sigma[d] = m_GaussianSigma * image->GetSpacing()[d]; } double alpha = 2.0; interpolator = GaussianInterpolatorType::New(); dynamic_cast(interpolator.GetPointer())->SetParameters( sigma, alpha ); } else { interpolator = LinearInterpolatorType::New(); } interpolator->SetInputImage( image ); itk::ImageRegionConstIterator itmask(m_InternalImageMask3D, m_InternalImageMask3D->GetLargestPossibleRegion()); itk::ImageRegionIterator itimage(outImage, outImage->GetLargestPossibleRegion()); itmask = itmask.Begin(); itimage = itimage.Begin(); itk::Point< double, 3 > point; itk::ContinuousIndex< double, 3 > index; while( !itmask.IsAtEnd() ) { if(itmask.Get() != 0) { outImage->TransformIndexToPhysicalPoint (itimage.GetIndex(), point); image->TransformPhysicalPointToContinuousIndex(point, index); itimage.Set(interpolator->EvaluateAtContinuousIndex(index)); } ++itmask; ++itimage; } if(additionalIndex < 0) { this->m_InternalImage = mitk::Image::New(); this->m_InternalImage->InitializeByItk( outImage.GetPointer() ); this->m_InternalImage->SetVolume( outImage->GetBufferPointer() ); } else { this->m_InternalAdditionalResamplingImages[additionalIndex] = mitk::Image::New(); this->m_InternalAdditionalResamplingImages[additionalIndex]->InitializeByItk( outImage.GetPointer() ); this->m_InternalAdditionalResamplingImages[additionalIndex]->SetVolume( outImage->GetBufferPointer() ); } } void PartialVolumeAnalysisHistogramCalculator::InternalResampleImage( const MaskImage3DType *image ) { typedef itk::ResampleImageFilter ResamplerType; ResamplerType::Pointer resampler = ResamplerType::New(); // Size ResamplerType::SizeType size; size[0] = m_UpsamplingFactor * image->GetLargestPossibleRegion().GetSize()[0]; size[1] = m_UpsamplingFactor * image->GetLargestPossibleRegion().GetSize()[1]; size[2] = m_UpsamplingFactor * image->GetLargestPossibleRegion().GetSize()[2];; resampler->SetSize( size ); // Origin mitk::Point3D orig = image->GetOrigin(); resampler->SetOutputOrigin(orig ); // Spacing ResamplerType::SpacingType spacing; spacing[0] = image->GetSpacing()[0] / m_UpsamplingFactor; spacing[1] = image->GetSpacing()[1] / m_UpsamplingFactor; spacing[2] = image->GetSpacing()[2] / m_UpsamplingFactor; resampler->SetOutputSpacing( spacing ); resampler->SetOutputDirection( image->GetDirection() ); typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType; InterpolatorType::Pointer interpolator = InterpolatorType::New(); interpolator->SetInputImage( image ); resampler->SetInterpolator( interpolator ); // Other resampling options resampler->SetInput( image ); resampler->SetDefaultPixelValue(0); resampler->Update(); m_InternalImageMask3D = resampler->GetOutput(); } template < typename TPixel, unsigned int VImageDimension > void PartialVolumeAnalysisHistogramCalculator::InternalCalculateStatisticsUnmasked( const itk::Image< TPixel, VImageDimension > *image, Statistics &statistics, typename HistogramType::ConstPointer *histogram ) { MITK_DEBUG << "InternalCalculateStatisticsUnmasked()"; typedef itk::Image< TPixel, VImageDimension > ImageType; typedef itk::Image< unsigned char, VImageDimension > MaskImageType; typedef typename ImageType::IndexType IndexType; // Progress listening... typedef itk::SimpleMemberCommand< PartialVolumeAnalysisHistogramCalculator > ITKCommandType; ITKCommandType::Pointer progressListener; progressListener = ITKCommandType::New(); progressListener->SetCallbackFunction( this, &PartialVolumeAnalysisHistogramCalculator::UnmaskedStatisticsProgressUpdate ); // Issue 100 artificial progress events since ScalarIMageToHistogramGenerator // does not (yet?) support progress reporting this->InvokeEvent( itk::StartEvent() ); for ( unsigned int i = 0; i < 100; ++i ) { this->UnmaskedStatisticsProgressUpdate(); } // Calculate statistics (separate filter) typedef itk::StatisticsImageFilter< ImageType > StatisticsFilterType; typename StatisticsFilterType::Pointer statisticsFilter = StatisticsFilterType::New(); statisticsFilter->SetInput( image ); unsigned long observerTag = statisticsFilter->AddObserver( itk::ProgressEvent(), progressListener ); statisticsFilter->Update(); statisticsFilter->RemoveObserver( observerTag ); this->InvokeEvent( itk::EndEvent() ); statistics.N = image->GetBufferedRegion().GetNumberOfPixels(); statistics.Min = statisticsFilter->GetMinimum(); statistics.Max = statisticsFilter->GetMaximum(); statistics.Mean = statisticsFilter->GetMean(); statistics.Median = 0.0; statistics.Sigma = statisticsFilter->GetSigma(); statistics.RMS = sqrt( statistics.Mean * statistics.Mean + statistics.Sigma * statistics.Sigma ); typename ImageType::Pointer inImage = const_cast(image); // Calculate histogram typedef itk::Statistics::ScalarImageToHistogramGenerator< ImageType > HistogramGeneratorType; typename HistogramGeneratorType::Pointer histogramGenerator = HistogramGeneratorType::New(); histogramGenerator->SetInput( inImage ); histogramGenerator->SetMarginalScale( 10 ); // Defines y-margin width of histogram histogramGenerator->SetNumberOfBins( m_NumberOfBins ); // CT range [-1024, +2048] --> bin size 4 values histogramGenerator->SetHistogramMin( statistics.Min ); histogramGenerator->SetHistogramMax( statistics.Max ); histogramGenerator->Compute(); *histogram = histogramGenerator->GetOutput(); } template < typename TPixel, unsigned int VImageDimension > void PartialVolumeAnalysisHistogramCalculator::InternalCalculateStatisticsMasked( const itk::Image< TPixel, VImageDimension > *image, itk::Image< unsigned char, VImageDimension > *maskImage, Statistics &statistics, typename HistogramType::ConstPointer *histogram ) { MITK_DEBUG << "InternalCalculateStatisticsMasked() start"; typedef itk::Image< TPixel, VImageDimension > ImageType; typedef itk::Image< unsigned char, VImageDimension > MaskImageType; typedef typename ImageType::IndexType IndexType; // generate a list sample of angles at positions // where the fiber-prob is higher than .2*maxprob typedef TPixel MeasurementType; const unsigned int MeasurementVectorLength = 1; typedef itk::Vector< MeasurementType , MeasurementVectorLength > MeasurementVectorType; typedef itk::Statistics::ListSample< MeasurementVectorType > ListSampleType; typename ListSampleType::Pointer listSample = ListSampleType::New(); listSample->SetMeasurementVectorSize( MeasurementVectorLength ); itk::ImageRegionConstIterator itmask(maskImage, maskImage->GetLargestPossibleRegion()); itk::ImageRegionConstIterator itimage(image, image->GetLargestPossibleRegion()); itmask = itmask.Begin(); itimage = itimage.Begin(); while( !itmask.IsAtEnd() ) { if(itmask.Get() != 0) { // apend to list MeasurementVectorType mv; mv[0] = ( MeasurementType ) itimage.Get(); listSample->PushBack(mv); } ++itmask; ++itimage; } // generate a histogram from the list sample typedef double HistogramMeasurementType; typedef itk::Statistics::Histogram< HistogramMeasurementType, itk::Statistics::DenseFrequencyContainer2 > HistogramType; typedef itk::Statistics::SampleToHistogramFilter< ListSampleType, HistogramType > GeneratorType; typename GeneratorType::Pointer generator = GeneratorType::New(); typename GeneratorType::HistogramType::SizeType size(MeasurementVectorLength); size.Fill(m_NumberOfBins); generator->SetHistogramSize( size ); generator->SetInput( listSample ); generator->SetMarginalScale( 10.0 ); generator->Update(); *histogram = generator->GetOutput(); } template < typename TPixel, unsigned int VImageDimension > void PartialVolumeAnalysisHistogramCalculator::InternalCropAdditionalImage( itk::Image< TPixel, VImageDimension > *image, int additionalIndex ) { typedef itk::Image< TPixel, VImageDimension > ImageType; typedef itk::RegionOfInterestImageFilter< ImageType, ImageType > ROIFilterType; typename ROIFilterType::Pointer roi = ROIFilterType::New(); roi->SetRegionOfInterest(m_CropRegion); roi->SetInput(image); roi->Update(); m_InternalAdditionalResamplingImages[additionalIndex] = mitk::Image::New(); m_InternalAdditionalResamplingImages[additionalIndex]->InitializeByItk(roi->GetOutput()); m_InternalAdditionalResamplingImages[additionalIndex]->SetVolume(roi->GetOutput()->GetBufferPointer()); } template < typename TPixel, unsigned int VImageDimension > void PartialVolumeAnalysisHistogramCalculator::InternalCalculateMaskFromPlanarFigure( itk::Image< TPixel, VImageDimension > *image, unsigned int axis ) { MITK_DEBUG << "InternalCalculateMaskFromPlanarFigure() start"; typedef itk::Image< TPixel, VImageDimension > ImageType; typedef itk::CastImageFilter< ImageType, MaskImage3DType > CastFilterType; // Generate mask image as new image with same header as input image and // initialize with "1". MaskImage3DType::Pointer newMaskImage = MaskImage3DType::New(); newMaskImage->SetSpacing( image->GetSpacing() ); // Set the image spacing newMaskImage->SetOrigin( image->GetOrigin() ); // Set the image origin newMaskImage->SetDirection( image->GetDirection() ); // Set the image direction newMaskImage->SetRegions( image->GetLargestPossibleRegion() ); newMaskImage->Allocate(); newMaskImage->FillBuffer( 1 ); // Generate VTK polygon from (closed) PlanarFigure polyline // (The polyline points are shifted by -0.5 in z-direction to make sure // that the extrusion filter, which afterwards elevates all points by +0.5 // in z-direction, creates a 3D object which is cut by the the plane z=0) const mitk::Geometry2D *planarFigureGeometry2D = m_PlanarFigure->GetGeometry2D(); const typename PlanarFigure::PolyLineType planarFigurePolyline = m_PlanarFigure->GetPolyLine( 0 ); const mitk::Geometry3D *imageGeometry3D = m_InternalImage->GetGeometry( 0 ); vtkPolyData *polyline = vtkPolyData::New(); polyline->Allocate( 1, 1 ); // Determine x- and y-dimensions depending on principal axis int i0, i1; switch ( axis ) { case 0: i0 = 1; i1 = 2; break; case 1: i0 = 0; i1 = 2; break; case 2: default: i0 = 0; i1 = 1; break; } // Create VTK polydata object of polyline contour bool outOfBounds = false; vtkPoints *points = vtkPoints::New(); typename PlanarFigure::PolyLineType::const_iterator it; for ( it = planarFigurePolyline.begin(); it != planarFigurePolyline.end(); ++it ) { Point3D point3D; // Convert 2D point back to the local index coordinates of the selected // image mitk::Point2D point2D = it->Point; planarFigureGeometry2D->WorldToIndex(point2D, point2D); point2D[0] -= 0.5/m_UpsamplingFactor; point2D[1] -= 0.5/m_UpsamplingFactor; planarFigureGeometry2D->IndexToWorld(point2D, point2D); planarFigureGeometry2D->Map( point2D, point3D ); // Polygons (partially) outside of the image bounds can not be processed // further due to a bug in vtkPolyDataToImageStencil if ( !imageGeometry3D->IsInside( point3D ) ) { outOfBounds = true; } imageGeometry3D->WorldToIndex( point3D, point3D ); point3D[i0] += 0.5; point3D[i1] += 0.5; // Add point to polyline array points->InsertNextPoint( point3D[i0], point3D[i1], -0.5 ); } polyline->SetPoints( points ); points->Delete(); if ( outOfBounds ) { polyline->Delete(); throw std::runtime_error( "Figure at least partially outside of image bounds!" ); } unsigned int numberOfPoints = planarFigurePolyline.size(); vtkIdType *ptIds = new vtkIdType[numberOfPoints]; for ( vtkIdType i = 0; i < numberOfPoints; ++i ) { ptIds[i] = i; } polyline->InsertNextCell( VTK_POLY_LINE, numberOfPoints, ptIds ); // Extrude the generated contour polygon vtkLinearExtrusionFilter *extrudeFilter = vtkLinearExtrusionFilter::New(); - extrudeFilter->SetInput( polyline ); + extrudeFilter->SetInputData( polyline ); extrudeFilter->SetScaleFactor( 1 ); extrudeFilter->SetExtrusionTypeToNormalExtrusion(); extrudeFilter->SetVector( 0.0, 0.0, 1.0 ); // Make a stencil from the extruded polygon vtkPolyDataToImageStencil *polyDataToImageStencil = vtkPolyDataToImageStencil::New(); - polyDataToImageStencil->SetInput( extrudeFilter->GetOutput() ); + polyDataToImageStencil->SetInputData( extrudeFilter->GetOutput() ); // Export from ITK to VTK (to use a VTK filter) typedef itk::VTKImageImport< MaskImage3DType > ImageImportType; typedef itk::VTKImageExport< MaskImage3DType > ImageExportType; typename ImageExportType::Pointer itkExporter = ImageExportType::New(); itkExporter->SetInput( newMaskImage ); vtkImageImport *vtkImporter = vtkImageImport::New(); this->ConnectPipelines( itkExporter, vtkImporter ); vtkImporter->Update(); // Apply the generated image stencil to the input image vtkImageStencil *imageStencilFilter = vtkImageStencil::New(); - imageStencilFilter->SetInput( vtkImporter->GetOutput() ); - imageStencilFilter->SetStencil( polyDataToImageStencil->GetOutput() ); + imageStencilFilter->SetInputData( vtkImporter->GetOutput() ); + imageStencilFilter->SetStencilData(polyDataToImageStencil->GetOutput() ); imageStencilFilter->ReverseStencilOff(); imageStencilFilter->SetBackgroundValue( 0 ); imageStencilFilter->Update(); // Export from VTK back to ITK vtkImageExport *vtkExporter = vtkImageExport::New(); - vtkExporter->SetInput( imageStencilFilter->GetOutput() ); + vtkExporter->SetInputData( imageStencilFilter->GetOutput() ); vtkExporter->Update(); typename ImageImportType::Pointer itkImporter = ImageImportType::New(); this->ConnectPipelines( vtkExporter, itkImporter ); itkImporter->Update(); // calculate cropping bounding box m_InternalImageMask3D = itkImporter->GetOutput(); m_InternalImageMask3D->SetDirection(image->GetDirection()); itk::ImageRegionIterator itmask(m_InternalImageMask3D, m_InternalImageMask3D->GetLargestPossibleRegion()); itmask = itmask.Begin(); while( !itmask.IsAtEnd() ) { if(itmask.Get() != 0) { typename ImageType::IndexType index = itmask.GetIndex(); for(int thick=0; thick<2*m_PlanarFigureThickness+1; thick++) { index[axis] = thick; m_InternalImageMask3D->SetPixel(index, itmask.Get()); } } ++itmask; } itmask = itmask.Begin(); itk::ImageRegionIterator itimage(image, image->GetLargestPossibleRegion()); itimage = itimage.Begin(); typename ImageType::SizeType lowersize = {{9999999999.0,9999999999.0,9999999999.0}}; typename ImageType::SizeType uppersize = {{0,0,0}}; while( !itmask.IsAtEnd() ) { if(itmask.Get() == 0) { itimage.Set(0); } else { typename ImageType::IndexType index = itimage.GetIndex(); typename ImageType::SizeType signedindex; signedindex[0] = index[0]; signedindex[1] = index[1]; signedindex[2] = index[2]; lowersize[0] = signedindex[0] < lowersize[0] ? signedindex[0] : lowersize[0]; lowersize[1] = signedindex[1] < lowersize[1] ? signedindex[1] : lowersize[1]; lowersize[2] = signedindex[2] < lowersize[2] ? signedindex[2] : lowersize[2]; uppersize[0] = signedindex[0] > uppersize[0] ? signedindex[0] : uppersize[0]; uppersize[1] = signedindex[1] > uppersize[1] ? signedindex[1] : uppersize[1]; uppersize[2] = signedindex[2] > uppersize[2] ? signedindex[2] : uppersize[2]; } ++itmask; ++itimage; } typename ImageType::IndexType index; index[0] = lowersize[0]; index[1] = lowersize[1]; index[2] = lowersize[2]; typename ImageType::SizeType size; size[0] = uppersize[0] - lowersize[0] + 1; size[1] = uppersize[1] - lowersize[1] + 1; size[2] = uppersize[2] - lowersize[2] + 1; m_CropRegion = itk::ImageRegion<3>(index, size); // crop internal image typedef itk::RegionOfInterestImageFilter< ImageType, ImageType > ROIFilterType; typename ROIFilterType::Pointer roi = ROIFilterType::New(); roi->SetRegionOfInterest(m_CropRegion); roi->SetInput(image); roi->Update(); m_InternalImage = mitk::Image::New(); m_InternalImage->InitializeByItk(roi->GetOutput()); m_InternalImage->SetVolume(roi->GetOutput()->GetBufferPointer()); // crop internal mask typedef itk::RegionOfInterestImageFilter< MaskImage3DType, MaskImage3DType > ROIMaskFilterType; typename ROIMaskFilterType::Pointer roi2 = ROIMaskFilterType::New(); roi2->SetRegionOfInterest(m_CropRegion); roi2->SetInput(m_InternalImageMask3D); roi2->Update(); m_InternalImageMask3D = roi2->GetOutput(); // Clean up VTK objects polyline->Delete(); extrudeFilter->Delete(); polyDataToImageStencil->Delete(); vtkImporter->Delete(); imageStencilFilter->Delete(); //vtkExporter->Delete(); // TODO: crashes when outcommented; memory leak?? delete[] ptIds; } void PartialVolumeAnalysisHistogramCalculator::UnmaskedStatisticsProgressUpdate() { // Need to throw away every second progress event to reach a final count of // 100 since two consecutive filters are used in this case static int updateCounter = 0; if ( updateCounter++ % 2 == 0 ) { this->InvokeEvent( itk::ProgressEvent() ); } } void PartialVolumeAnalysisHistogramCalculator::MaskedStatisticsProgressUpdate() { this->InvokeEvent( itk::ProgressEvent() ); } } diff --git a/Modules/DiffusionImaging/DiffusionCore/Rendering/mitkOdfVtkMapper2D.txx b/Modules/DiffusionImaging/DiffusionCore/Rendering/mitkOdfVtkMapper2D.txx index f7a58dcb56..c977771161 100644 --- a/Modules/DiffusionImaging/DiffusionCore/Rendering/mitkOdfVtkMapper2D.txx +++ b/Modules/DiffusionImaging/DiffusionCore/Rendering/mitkOdfVtkMapper2D.txx @@ -1,885 +1,885 @@ /*=================================================================== 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 __mitkOdfVtkMapper2D_txx__ #define __mitkOdfVtkMapper2D_txx__ #include "mitkOdfVtkMapper2D.h" #include "mitkDataNode.h" #include "mitkBaseRenderer.h" #include "mitkMatrixConvert.h" #include "mitkGeometry3D.h" #include "mitkTimeGeometry.h" #include "mitkOdfNormalizationMethodProperty.h" #include "mitkOdfScaleByProperty.h" #include "mitkProperties.h" #include "mitkTensorImage.h" #include "vtkSphereSource.h" #include "vtkPropCollection.h" #include "vtkMaskedGlyph3D.h" #include "vtkGlyph2D.h" #include "vtkGlyph3D.h" #include "vtkMaskedProgrammableGlyphFilter.h" #include "vtkImageData.h" #include "vtkLinearTransform.h" #include "vtkCamera.h" #include "vtkPointData.h" #include "vtkTransformPolyDataFilter.h" #include "vtkTransform.h" #include "vtkOdfSource.h" #include "vtkDoubleArray.h" #include "vtkLookupTable.h" #include "vtkProperty.h" #include "vtkPolyDataNormals.h" #include "vtkLight.h" #include "vtkLightCollection.h" #include "vtkMath.h" #include "vtkFloatArray.h" #include "vtkDelaunay2D.h" #include "vtkMapper.h" #include "vtkRenderer.h" #include "itkOrientationDistributionFunction.h" #include "itkFixedArray.h" #include #include "vtkOpenGLRenderer.h" #define _USE_MATH_DEFINES #include template vtkSmartPointer mitk::OdfVtkMapper2D::m_OdfTransform = vtkSmartPointer::New(); template vtkSmartPointer mitk::OdfVtkMapper2D::m_OdfSource = vtkSmartPointer::New(); template float mitk::OdfVtkMapper2D::m_Scaling; template int mitk::OdfVtkMapper2D::m_Normalization; template int mitk::OdfVtkMapper2D::m_ScaleBy; template float mitk::OdfVtkMapper2D::m_IndexParam1; template float mitk::OdfVtkMapper2D::m_IndexParam2; #define ODF_MAPPER_PI M_PI template mitk::OdfVtkMapper2D::LocalStorage::LocalStorage() { m_PropAssemblies.push_back(vtkPropAssembly::New()); m_PropAssemblies.push_back(vtkPropAssembly::New()); m_PropAssemblies.push_back(vtkPropAssembly::New()); m_OdfsPlanes.push_back(vtkAppendPolyData::New()); m_OdfsPlanes.push_back(vtkAppendPolyData::New()); m_OdfsPlanes.push_back(vtkAppendPolyData::New()); - m_OdfsPlanes[0]->AddInput(vtkPolyData::New()); - m_OdfsPlanes[1]->AddInput(vtkPolyData::New()); - m_OdfsPlanes[2]->AddInput(vtkPolyData::New()); + m_OdfsPlanes[0]->AddInputData(vtkPolyData::New()); + m_OdfsPlanes[1]->AddInputData(vtkPolyData::New()); + m_OdfsPlanes[2]->AddInputData(vtkPolyData::New()); m_OdfsActors.push_back(vtkActor::New()); m_OdfsActors.push_back(vtkActor::New()); m_OdfsActors.push_back(vtkActor::New()); m_OdfsActors[0]->GetProperty()->SetInterpolationToGouraud(); m_OdfsActors[1]->GetProperty()->SetInterpolationToGouraud(); m_OdfsActors[2]->GetProperty()->SetInterpolationToGouraud(); m_OdfsMappers.push_back(vtkPolyDataMapper::New()); m_OdfsMappers.push_back(vtkPolyDataMapper::New()); m_OdfsMappers.push_back(vtkPolyDataMapper::New()); vtkLookupTable *lut = vtkLookupTable::New(); m_OdfsMappers[0]->SetLookupTable(lut); m_OdfsMappers[1]->SetLookupTable(lut); m_OdfsMappers[2]->SetLookupTable(lut); m_OdfsActors[0]->SetMapper(m_OdfsMappers[0]); m_OdfsActors[1]->SetMapper(m_OdfsMappers[1]); m_OdfsActors[2]->SetMapper(m_OdfsMappers[2]); } template mitk::OdfVtkMapper2D ::OdfVtkMapper2D() { m_Planes.push_back(vtkPlane::New()); m_Planes.push_back(vtkPlane::New()); m_Planes.push_back(vtkPlane::New()); m_Cutters.push_back(vtkCutter::New()); m_Cutters.push_back(vtkCutter::New()); m_Cutters.push_back(vtkCutter::New()); m_Cutters[0]->SetCutFunction( m_Planes[0] ); m_Cutters[0]->GenerateValues( 1, 0, 1 ); m_Cutters[1]->SetCutFunction( m_Planes[1] ); m_Cutters[1]->GenerateValues( 1, 0, 1 ); m_Cutters[2]->SetCutFunction( m_Planes[2] ); m_Cutters[2]->GenerateValues( 1, 0, 1 ); // Windowing the cutted planes in direction 1 m_ThickPlanes1.push_back(vtkThickPlane::New()); m_ThickPlanes1.push_back(vtkThickPlane::New()); m_ThickPlanes1.push_back(vtkThickPlane::New()); m_Clippers1.push_back(vtkClipPolyData::New()); m_Clippers1.push_back(vtkClipPolyData::New()); m_Clippers1.push_back(vtkClipPolyData::New()); m_Clippers1[0]->SetClipFunction( m_ThickPlanes1[0] ); m_Clippers1[1]->SetClipFunction( m_ThickPlanes1[1] ); m_Clippers1[2]->SetClipFunction( m_ThickPlanes1[2] ); // Windowing the cutted planes in direction 2 m_ThickPlanes2.push_back(vtkThickPlane::New()); m_ThickPlanes2.push_back(vtkThickPlane::New()); m_ThickPlanes2.push_back(vtkThickPlane::New()); m_Clippers2.push_back(vtkClipPolyData::New()); m_Clippers2.push_back(vtkClipPolyData::New()); m_Clippers2.push_back(vtkClipPolyData::New()); m_Clippers2[0]->SetClipFunction( m_ThickPlanes2[0] ); m_Clippers2[1]->SetClipFunction( m_ThickPlanes2[1] ); m_Clippers2[2]->SetClipFunction( m_ThickPlanes2[2] ); m_ShowMaxNumber = 500; } template mitk::OdfVtkMapper2D ::~OdfVtkMapper2D() { } template mitk::Image* mitk::OdfVtkMapper2D ::GetInput() { return static_cast ( m_DataNode->GetData() ); } template vtkProp* mitk::OdfVtkMapper2D ::GetVtkProp(mitk::BaseRenderer* renderer) { LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer); return localStorage->m_PropAssemblies[GetIndex(renderer)]; } template int mitk::OdfVtkMapper2D ::GetIndex(mitk::BaseRenderer* renderer) { if(!strcmp(renderer->GetName(),"stdmulti.widget1")) return 0; if(!strcmp(renderer->GetName(),"stdmulti.widget2")) return 1; if(!strcmp(renderer->GetName(),"stdmulti.widget3")) return 2; return 0; } template void mitk::OdfVtkMapper2D ::GlyphMethod(void *arg) { vtkMaskedProgrammableGlyphFilter* pfilter=(vtkMaskedProgrammableGlyphFilter*)arg; double point[3]; double debugpoint[3]; pfilter->GetPoint(point); pfilter->GetPoint(debugpoint); itk::Point p(point); Vector3D spacing = pfilter->GetGeometry()->GetSpacing(); p[0] /= spacing[0]; p[1] /= spacing[1]; p[2] /= spacing[2]; mitk::Point3D p2; pfilter->GetGeometry()->IndexToWorld( p, p2 ); point[0] = p2[0]; point[1] = p2[1]; point[2] = p2[2]; vtkPointData* data = pfilter->GetPointData(); vtkDataArray* odfvals = data->GetArray("vector"); vtkIdType id = pfilter->GetPointId(); m_OdfTransform->Identity(); m_OdfTransform->Translate(point[0],point[1],point[2]); typedef itk::OrientationDistributionFunction OdfType; OdfType odf; if(odfvals->GetNumberOfComponents()==6) { float tensorelems[6] = { (float)odfvals->GetComponent(id,0), (float)odfvals->GetComponent(id,1), (float)odfvals->GetComponent(id,2), (float)odfvals->GetComponent(id,3), (float)odfvals->GetComponent(id,4), (float)odfvals->GetComponent(id,5), }; itk::DiffusionTensor3D tensor(tensorelems); odf.InitFromTensor(tensor); } else { for(int i=0; iGetComponent(id,i); } switch(m_ScaleBy) { case ODFSB_NONE: m_OdfSource->SetScale(m_Scaling); break; case ODFSB_GFA: m_OdfSource->SetScale(m_Scaling*odf.GetGeneralizedGFA(m_IndexParam1, m_IndexParam2)); break; case ODFSB_PC: m_OdfSource->SetScale(m_Scaling*odf.GetPrincipleCurvature(m_IndexParam1, m_IndexParam2, 0)); break; } m_OdfSource->SetNormalization(m_Normalization); m_OdfSource->SetOdf(odf); m_OdfSource->Modified(); } template typename mitk::OdfVtkMapper2D::OdfDisplayGeometry mitk::OdfVtkMapper2D ::MeasureDisplayedGeometry(mitk::BaseRenderer* renderer) { Geometry2D::ConstPointer worldGeometry = renderer->GetCurrentWorldGeometry2D(); PlaneGeometry::ConstPointer worldPlaneGeometry = dynamic_cast( worldGeometry.GetPointer() ); // set up the cutter orientation according to the current geometry of // the renderers plane double vp[ 3 ], vnormal[ 3 ]; Point3D point = worldPlaneGeometry->GetOrigin(); Vector3D normal = worldPlaneGeometry->GetNormal(); normal.Normalize(); vnl2vtk( point.Get_vnl_vector(), vp ); vnl2vtk( normal.Get_vnl_vector(), vnormal ); mitk::DisplayGeometry::Pointer dispGeometry = renderer->GetDisplayGeometry(); mitk::Vector2D size = dispGeometry->GetSizeInMM(); mitk::Vector2D origin = dispGeometry->GetOriginInMM(); // // |------O------| // | d2 | // L d1 M | // | | // |-------------| // mitk::Vector2D M; mitk::Vector2D L; mitk::Vector2D O; M[0] = origin[0] + size[0]/2; M[1] = origin[1] + size[1]/2; L[0] = origin[0]; L[1] = origin[1] + size[1]/2; O[0] = origin[0] + size[0]/2; O[1] = origin[1] + size[1]; mitk::Point2D point1; point1[0] = M[0]; point1[1] = M[1]; mitk::Point3D M3D; dispGeometry->Map(point1, M3D); point1[0] = L[0]; point1[1] = L[1]; mitk::Point3D L3D; dispGeometry->Map(point1, L3D); point1[0] = O[0]; point1[1] = O[1]; mitk::Point3D O3D; dispGeometry->Map(point1, O3D); double d1 = sqrt((M3D[0]-L3D[0])*(M3D[0]-L3D[0]) + (M3D[1]-L3D[1])*(M3D[1]-L3D[1]) + (M3D[2]-L3D[2])*(M3D[2]-L3D[2])); double d2 = sqrt((M3D[0]-O3D[0])*(M3D[0]-O3D[0]) + (M3D[1]-O3D[1])*(M3D[1]-O3D[1]) + (M3D[2]-O3D[2])*(M3D[2]-O3D[2])); double d = d1>d2 ? d1 : d2; d = d2; OdfDisplayGeometry retval; retval.vp[0] = vp[0]; retval.vp[1] = vp[1]; retval.vp[2] = vp[2]; retval.vnormal[0] = vnormal[0]; retval.vnormal[1] = vnormal[1]; retval.vnormal[2] = vnormal[2]; retval.normal[0] = normal[0]; retval.normal[1] = normal[1]; retval.normal[2] = normal[2]; retval.d = d; retval.d1 = d1; retval.d2 = d2; retval.M3D[0] = M3D[0]; retval.M3D[1] = M3D[1]; retval.M3D[2] = M3D[2]; retval.L3D[0] = L3D[0]; retval.L3D[1] = L3D[1]; retval.L3D[2] = L3D[2]; retval.O3D[0] = O3D[0]; retval.O3D[1] = O3D[1]; retval.O3D[2] = O3D[2]; retval.vp_original[0] = vp[0]; retval.vp_original[1] = vp[1]; retval.vp_original[2] = vp[2]; retval.vnormal_original[0] = vnormal[0]; retval.vnormal_original[1] = vnormal[1]; retval.vnormal_original[2] = vnormal[2]; retval.size[0] = size[0]; retval.size[1] = size[1]; retval.origin[0] = origin[0]; retval.origin[1] = origin[1]; return retval; } template void mitk::OdfVtkMapper2D ::Slice(mitk::BaseRenderer* renderer, OdfDisplayGeometry dispGeo) { LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer); vtkLinearTransform * vtktransform = this->GetDataNode()->GetVtkTransform(this->GetTimestep()); int index = GetIndex(renderer); vtkSmartPointer inversetransform = vtkSmartPointer::New(); inversetransform->Identity(); inversetransform->Concatenate(vtktransform->GetLinearInverse()); double myscale[3]; ((vtkTransform*)vtktransform)->GetScale(myscale); inversetransform->PostMultiply(); inversetransform->Scale(1*myscale[0],1*myscale[1],1*myscale[2]); inversetransform->TransformPoint( dispGeo.vp, dispGeo.vp ); inversetransform->TransformNormalAtPoint( dispGeo.vp, dispGeo.vnormal, dispGeo.vnormal ); // vtk works in axis align coords // thus the normal also must be axis align, since // we do not allow arbitrary cutting through volume // // vnormal should already be axis align, but in order // to get rid of precision effects, we set the two smaller // components to zero here int dims[3]; m_VtkImage->GetDimensions(dims); double spac[3]; m_VtkImage->GetSpacing(spac); if(fabs(dispGeo.vnormal[0]) > fabs(dispGeo.vnormal[1]) && fabs(dispGeo.vnormal[0]) > fabs(dispGeo.vnormal[2]) ) { if(fabs(dispGeo.vp[0]/spac[0]) < 0.4) dispGeo.vp[0] = 0.4*spac[0]; if(fabs(dispGeo.vp[0]/spac[0]) > (dims[0]-1)-0.4) dispGeo.vp[0] = ((dims[0]-1)-0.4)*spac[0]; dispGeo.vnormal[1] = 0; dispGeo.vnormal[2] = 0; } if(fabs(dispGeo.vnormal[1]) > fabs(dispGeo.vnormal[0]) && fabs(dispGeo.vnormal[1]) > fabs(dispGeo.vnormal[2]) ) { if(fabs(dispGeo.vp[1]/spac[1]) < 0.4) dispGeo.vp[1] = 0.4*spac[1]; if(fabs(dispGeo.vp[1]/spac[1]) > (dims[1]-1)-0.4) dispGeo.vp[1] = ((dims[1]-1)-0.4)*spac[1]; dispGeo.vnormal[0] = 0; dispGeo.vnormal[2] = 0; } if(fabs(dispGeo.vnormal[2]) > fabs(dispGeo.vnormal[1]) && fabs(dispGeo.vnormal[2]) > fabs(dispGeo.vnormal[0]) ) { if(fabs(dispGeo.vp[2]/spac[2]) < 0.4) dispGeo.vp[2] = 0.4*spac[2]; if(fabs(dispGeo.vp[2]/spac[2]) > (dims[2]-1)-0.4) dispGeo.vp[2] = ((dims[2]-1)-0.4)*spac[2]; dispGeo.vnormal[0] = 0; dispGeo.vnormal[1] = 0; } m_Planes[index]->SetTransform( (vtkAbstractTransform*)NULL ); m_Planes[index]->SetOrigin( dispGeo.vp ); m_Planes[index]->SetNormal( dispGeo.vnormal ); vtkSmartPointer points; vtkSmartPointer tmppoints; vtkSmartPointer polydata; vtkSmartPointer pointdata; vtkSmartPointer delaunay; vtkSmartPointer cuttedPlane; // the cutter only works if we do not have a 2D-image // or if we have a 2D-image and want to see the whole image. // // for side views of 2D-images, we need some special treatment if(!( (dims[0] == 1 && dispGeo.vnormal[0] != 0) || (dims[1] == 1 && dispGeo.vnormal[1] != 0) || (dims[2] == 1 && dispGeo.vnormal[2] != 0) )) { m_Cutters[index]->SetCutFunction( m_Planes[index] ); - m_Cutters[index]->SetInput( m_VtkImage ); + m_Cutters[index]->SetInputData( m_VtkImage ); m_Cutters[index]->Update(); cuttedPlane = m_Cutters[index]->GetOutput(); } else { // cutting of a 2D-Volume does not work, // so we have to build up our own polydata object cuttedPlane = vtkPolyData::New(); points = vtkPoints::New(); points->SetNumberOfPoints(m_VtkImage->GetNumberOfPoints()); for(int i=0; iGetNumberOfPoints(); i++) { points->SetPoint(i, m_VtkImage->GetPoint(i)); } cuttedPlane->SetPoints(points); pointdata = vtkFloatArray::New(); int comps = m_VtkImage->GetPointData()->GetScalars()->GetNumberOfComponents(); pointdata->SetNumberOfComponents(comps); int tuples = m_VtkImage->GetPointData()->GetScalars()->GetNumberOfTuples(); pointdata->SetNumberOfTuples(tuples); for(int i=0; iSetTuple(i,m_VtkImage->GetPointData()->GetScalars()->GetTuple(i)); pointdata->SetName( "vector" ); cuttedPlane->GetPointData()->AddArray(pointdata); int nZero1, nZero2; if(dims[0]==1) { nZero1 = 1; nZero2 = 2; } else if(dims[1]==1) { nZero1 = 0; nZero2 = 2; } else { nZero1 = 0; nZero2 = 1; } tmppoints = vtkPoints::New(); for(int j=0; jGetNumberOfPoints(); j++){ double pt[3]; m_VtkImage->GetPoint(j,pt); tmppoints->InsertNextPoint(pt[nZero1],pt[nZero2],0); } polydata = vtkPolyData::New(); polydata->SetPoints( tmppoints ); delaunay = vtkDelaunay2D::New(); - delaunay->SetInput( polydata ); + delaunay->SetInputData( polydata ); delaunay->Update(); vtkCellArray* polys = delaunay->GetOutput()->GetPolys(); cuttedPlane->SetPolys(polys); } if(cuttedPlane->GetNumberOfPoints()) { // WINDOWING HERE inversetransform = vtkTransform::New(); inversetransform->Identity(); inversetransform->Concatenate(vtktransform->GetLinearInverse()); double myscale[3]; ((vtkTransform*)vtktransform)->GetScale(myscale); inversetransform->PostMultiply(); inversetransform->Scale(1*myscale[0],1*myscale[1],1*myscale[2]); dispGeo.vnormal[0] = dispGeo.M3D[0]-dispGeo.O3D[0]; dispGeo.vnormal[1] = dispGeo.M3D[1]-dispGeo.O3D[1]; dispGeo.vnormal[2] = dispGeo.M3D[2]-dispGeo.O3D[2]; vtkMath::Normalize(dispGeo.vnormal); dispGeo.vp[0] = dispGeo.M3D[0]; dispGeo.vp[1] = dispGeo.M3D[1]; dispGeo.vp[2] = dispGeo.M3D[2]; inversetransform->TransformPoint( dispGeo.vp, dispGeo.vp ); inversetransform->TransformNormalAtPoint( dispGeo.vp, dispGeo.vnormal, dispGeo.vnormal ); m_ThickPlanes1[index]->count = 0; m_ThickPlanes1[index]->SetTransform((vtkAbstractTransform*)NULL ); m_ThickPlanes1[index]->SetPose( dispGeo.vnormal, dispGeo.vp ); m_ThickPlanes1[index]->SetThickness(dispGeo.d2); m_Clippers1[index]->SetClipFunction( m_ThickPlanes1[index] ); - m_Clippers1[index]->SetInput( cuttedPlane ); + m_Clippers1[index]->SetInputData( cuttedPlane ); m_Clippers1[index]->SetInsideOut(1); m_Clippers1[index]->Update(); dispGeo.vnormal[0] = dispGeo.M3D[0]-dispGeo.L3D[0]; dispGeo.vnormal[1] = dispGeo.M3D[1]-dispGeo.L3D[1]; dispGeo.vnormal[2] = dispGeo.M3D[2]-dispGeo.L3D[2]; vtkMath::Normalize(dispGeo.vnormal); dispGeo.vp[0] = dispGeo.M3D[0]; dispGeo.vp[1] = dispGeo.M3D[1]; dispGeo.vp[2] = dispGeo.M3D[2]; inversetransform->TransformPoint( dispGeo.vp, dispGeo.vp ); inversetransform->TransformNormalAtPoint( dispGeo.vp, dispGeo.vnormal, dispGeo.vnormal ); m_ThickPlanes2[index]->count = 0; m_ThickPlanes2[index]->SetTransform((vtkAbstractTransform*)NULL ); m_ThickPlanes2[index]->SetPose( dispGeo.vnormal, dispGeo.vp ); m_ThickPlanes2[index]->SetThickness(dispGeo.d1); m_Clippers2[index]->SetClipFunction( m_ThickPlanes2[index] ); - m_Clippers2[index]->SetInput( m_Clippers1[index]->GetOutput() ); + m_Clippers2[index]->SetInputData( m_Clippers1[index]->GetOutput() ); m_Clippers2[index]->SetInsideOut(1); m_Clippers2[index]->Update(); cuttedPlane = m_Clippers2[index]->GetOutput (); if(cuttedPlane->GetNumberOfPoints()) { localStorage->m_OdfsPlanes[index]->RemoveAllInputs(); vtkSmartPointer normals = vtkSmartPointer::New(); normals->SetInputConnection( m_OdfSource->GetOutputPort() ); normals->SplittingOff(); normals->ConsistencyOff(); normals->AutoOrientNormalsOff(); normals->ComputePointNormalsOn(); normals->ComputeCellNormalsOff(); normals->FlipNormalsOff(); normals->NonManifoldTraversalOff(); vtkSmartPointer trans = vtkSmartPointer::New(); trans->SetInputConnection( normals->GetOutputPort() ); trans->SetTransform(m_OdfTransform); vtkSmartPointer glyphGenerator = vtkSmartPointer::New(); glyphGenerator->SetMaximumNumberOfPoints(std::min(m_ShowMaxNumber,(int)cuttedPlane->GetNumberOfPoints())); glyphGenerator->SetRandomMode(0); glyphGenerator->SetUseMaskPoints(1); - glyphGenerator->SetSource( trans->GetOutput() ); + glyphGenerator->SetSourceData(trans->GetOutput() ); glyphGenerator->SetInput(cuttedPlane); glyphGenerator->SetColorModeToColorBySource(); glyphGenerator->SetInputArrayToProcess(0,0,0, vtkDataObject::FIELD_ASSOCIATION_POINTS , "vector"); glyphGenerator->SetGeometry(this->GetDataNode()->GetData()->GetGeometry()); glyphGenerator->SetGlyphMethod(&(GlyphMethod),(void *)glyphGenerator); try { glyphGenerator->Update(); } catch( itk::ExceptionObject& err ) { std::cout << err << std::endl; } - localStorage->m_OdfsPlanes[index]->AddInput(glyphGenerator->GetOutput()); + localStorage->m_OdfsPlanes[index]->AddInputData(glyphGenerator->GetOutput()); localStorage->m_OdfsPlanes[index]->Update(); } } localStorage->m_PropAssemblies[index]->VisibilityOn(); if(localStorage->m_PropAssemblies[index]->GetParts()->IsItemPresent(localStorage->m_OdfsActors[index])) localStorage->m_PropAssemblies[index]->RemovePart(localStorage->m_OdfsActors[index]); - localStorage->m_OdfsMappers[index]->SetInput(localStorage->m_OdfsPlanes[index]->GetOutput()); + localStorage->m_OdfsMappers[index]->SetInputData(localStorage->m_OdfsPlanes[index]->GetOutput()); localStorage->m_PropAssemblies[index]->AddPart(localStorage->m_OdfsActors[index]); } template bool mitk::OdfVtkMapper2D ::IsVisibleOdfs(mitk::BaseRenderer* renderer) { mitk::Image::Pointer input = const_cast(this->GetInput()); const TimeGeometry *inputTimeGeometry = input->GetTimeGeometry(); if(inputTimeGeometry==NULL || inputTimeGeometry->CountTimeSteps()==0 || !inputTimeGeometry->IsValidTimeStep(this->GetTimestep())) return false; if(this->IsPlaneRotated(renderer)) return false; bool retval = false; switch(GetIndex(renderer)) { case 0: GetDataNode()->GetVisibility(retval, renderer, "VisibleOdfs_T"); break; case 1: GetDataNode()->GetVisibility(retval, renderer, "VisibleOdfs_S"); break; case 2: GetDataNode()->GetVisibility(retval, renderer, "VisibleOdfs_C"); break; } return retval; } template void mitk::OdfVtkMapper2D ::MitkRenderOverlay(mitk::BaseRenderer* renderer) { if ( this->IsVisibleOdfs(renderer)==false ) return; if ( this->GetVtkProp(renderer)->GetVisibility() ) this->GetVtkProp(renderer)->RenderOverlay(renderer->GetVtkRenderer()); } template void mitk::OdfVtkMapper2D ::MitkRenderOpaqueGeometry(mitk::BaseRenderer* renderer) { if ( this->IsVisibleOdfs( renderer )==false ) return; if ( this->GetVtkProp(renderer)->GetVisibility() ) { // adapt cam pos OdfDisplayGeometry dispGeo = MeasureDisplayedGeometry( renderer); this->GetVtkProp(renderer)->RenderOpaqueGeometry( renderer->GetVtkRenderer() ); } } template void mitk::OdfVtkMapper2D ::MitkRenderTranslucentGeometry(mitk::BaseRenderer* renderer) { if ( this->IsVisibleOdfs(renderer)==false ) return; if ( this->GetVtkProp(renderer)->GetVisibility() ) this->GetVtkProp(renderer)->RenderTranslucentPolygonalGeometry(renderer->GetVtkRenderer()); } template void mitk::OdfVtkMapper2D ::Update(mitk::BaseRenderer* renderer) { bool visible = true; GetDataNode()->GetVisibility(visible, renderer, "visible"); if ( !visible ) return; mitk::Image::Pointer input = const_cast( this->GetInput() ); if ( input.IsNull() ) return ; std::string classname("TensorImage"); if(classname.compare(input->GetNameOfClass())==0) m_VtkImage = dynamic_cast( this->GetInput() )->GetNonRgbVtkImageData(); std::string qclassname("QBallImage"); if(qclassname.compare(input->GetNameOfClass())==0) m_VtkImage = dynamic_cast( this->GetInput() )->GetNonRgbVtkImageData(); if( m_VtkImage ) { // make sure, that we have point data with more than 1 component (as vectors) vtkPointData* pointData = m_VtkImage->GetPointData(); if ( pointData == NULL ) { itkWarningMacro( << "m_VtkImage->GetPointData() returns NULL!" ); return ; } if ( pointData->GetNumberOfArrays() == 0 ) { itkWarningMacro( << "m_VtkImage->GetPointData()->GetNumberOfArrays() is 0!" ); return ; } else if ( pointData->GetArray(0)->GetNumberOfComponents() != N && pointData->GetArray(0)->GetNumberOfComponents() != 6 /*for tensor visualization*/) { itkWarningMacro( << "number of components != number of directions in ODF!" ); return; } else if ( pointData->GetArrayName( 0 ) == NULL ) { m_VtkImage->GetPointData()->GetArray(0)->SetName("vector"); } GenerateDataForRenderer(renderer); } else { itkWarningMacro( << "m_VtkImage is NULL!" ); return ; } } template void mitk::OdfVtkMapper2D ::GenerateDataForRenderer( mitk::BaseRenderer *renderer ) { LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer); OdfDisplayGeometry dispGeo = MeasureDisplayedGeometry( renderer); if ( (localStorage->m_LastUpdateTime >= m_DataNode->GetMTime()) //was the node modified? && (localStorage->m_LastUpdateTime >= m_DataNode->GetPropertyList()->GetMTime()) //was a property modified? && (localStorage->m_LastUpdateTime >= m_DataNode->GetPropertyList(renderer)->GetMTime()) && dispGeo.Equals(m_LastDisplayGeometry)) return; localStorage->m_LastUpdateTime.Modified(); if(!IsVisibleOdfs(renderer)) { localStorage->m_OdfsActors[0]->VisibilityOff(); localStorage->m_OdfsActors[1]->VisibilityOff(); localStorage->m_OdfsActors[2]->VisibilityOff(); } else { localStorage->m_OdfsActors[0]->VisibilityOn(); localStorage->m_OdfsActors[1]->VisibilityOn(); localStorage->m_OdfsActors[2]->VisibilityOn(); m_OdfSource->SetAdditionalScale(GetMinImageSpacing(GetIndex(renderer))); ApplyPropertySettings(); Slice(renderer, dispGeo); m_LastDisplayGeometry = dispGeo; } } template double mitk::OdfVtkMapper2D::GetMinImageSpacing( int index ) { // Spacing adapted scaling double spacing[3]; m_VtkImage->GetSpacing(spacing); double min; if(index==0) { min = spacing[0]; min = min > spacing[1] ? spacing[1] : min; } if(index==1) { min = spacing[1]; min = min > spacing[2] ? spacing[2] : min; } if(index==2) { min = spacing[0]; min = min > spacing[2] ? spacing[2] : min; } return min; } template void mitk::OdfVtkMapper2D ::ApplyPropertySettings() { this->GetDataNode()->GetFloatProperty( "Scaling", m_Scaling ); this->GetDataNode()->GetIntProperty( "ShowMaxNumber", m_ShowMaxNumber ); OdfNormalizationMethodProperty* nmp = dynamic_cast(this->GetDataNode()->GetProperty( "Normalization" )); if(nmp) m_Normalization = nmp->GetNormalization(); OdfScaleByProperty* sbp = dynamic_cast(this->GetDataNode()->GetProperty( "ScaleBy" )); if(sbp) m_ScaleBy = sbp->GetScaleBy(); this->GetDataNode()->GetFloatProperty( "IndexParam1", m_IndexParam1); this->GetDataNode()->GetFloatProperty( "IndexParam2", m_IndexParam2); } template bool mitk::OdfVtkMapper2D ::IsPlaneRotated(mitk::BaseRenderer* renderer) { Geometry2D::ConstPointer worldGeometry = renderer->GetCurrentWorldGeometry2D(); PlaneGeometry::ConstPointer worldPlaneGeometry = dynamic_cast( worldGeometry.GetPointer() ); double vnormal[ 3 ]; Vector3D normal = worldPlaneGeometry->GetNormal(); normal.Normalize(); vnl2vtk( normal.Get_vnl_vector(), vnormal ); vtkLinearTransform * vtktransform = this->GetDataNode()->GetVtkTransform(this->GetTimestep()); vtkSmartPointer inversetransform = vtkSmartPointer::New(); inversetransform->Identity(); inversetransform->Concatenate(vtktransform->GetLinearInverse()); double* n = inversetransform->TransformNormal(vnormal); int nonZeros = 0; for (int j=0; j<3; j++) { if (fabs(n[j])>mitk::eps){ nonZeros++; } } if(nonZeros>1) return true; return false; } template void mitk::OdfVtkMapper2D ::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* /*renderer*/, bool /*overwrite*/) { node->SetProperty( "ShowMaxNumber", mitk::IntProperty::New( 150 ) ); node->SetProperty( "Scaling", mitk::FloatProperty::New( 1.0 ) ); node->SetProperty( "Normalization", mitk::OdfNormalizationMethodProperty::New()); node->SetProperty( "ScaleBy", mitk::OdfScaleByProperty::New()); node->SetProperty( "IndexParam1", mitk::FloatProperty::New(2)); node->SetProperty( "IndexParam2", mitk::FloatProperty::New(1)); node->SetProperty( "visible", mitk::BoolProperty::New( true ) ); node->SetProperty( "VisibleOdfs_T", mitk::BoolProperty::New( false ) ); node->SetProperty( "VisibleOdfs_C", mitk::BoolProperty::New( false ) ); node->SetProperty( "VisibleOdfs_S", mitk::BoolProperty::New( false ) ); node->SetProperty ("layer", mitk::IntProperty::New(100)); node->SetProperty( "DoRefresh", mitk::BoolProperty::New( true ) ); } #endif // __mitkOdfVtkMapper2D_txx__ diff --git a/Modules/DiffusionImaging/DiffusionCore/Rendering/mitkPlanarFigureMapper3D.cpp b/Modules/DiffusionImaging/DiffusionCore/Rendering/mitkPlanarFigureMapper3D.cpp index 825d657a22..74589f3f81 100644 --- a/Modules/DiffusionImaging/DiffusionCore/Rendering/mitkPlanarFigureMapper3D.cpp +++ b/Modules/DiffusionImaging/DiffusionCore/Rendering/mitkPlanarFigureMapper3D.cpp @@ -1,121 +1,121 @@ /*=================================================================== 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 "mitkPlanarFigureMapper3D.h" #include #include #include #include mitk::PlanarFigureMapper3D::PlanarFigureMapper3D() : m_points(vtkPoints::New()) , m_polygon(vtkPolygon::New()) , m_polygonPolyData(vtkPolyData::New()) , m_polygonsCell(vtkCellArray::New()) , m_VtkPolygonDataMapperGL(vtkOpenGLPolyDataMapper::New()) , m_PolygonActor(vtkOpenGLActor::New()) , m_PolygonAssembly(vtkPropAssembly::New()) { } //template mitk::PlanarFigureMapper3D::~PlanarFigureMapper3D() { } const mitk::PlanarFigure* mitk::PlanarFigureMapper3D::GetInput() { return static_cast ( GetDataNode()->GetData() ); } void mitk::PlanarFigureMapper3D::GenerateDataForRenderer( mitk::BaseRenderer *renderer ) { try { mitk::PlanarFigure* pf = dynamic_cast< mitk::PlanarFigure* > (GetDataNode()->GetData()); const mitk::Geometry2D* pfgeometry = pf->GetGeometry2D(); const mitk::PlaneGeometry* planeGeo = dynamic_cast(pfgeometry); mitk::Point3D wp; mitk::PlanarFigure::PolyLineType line = pf->GetPolyLine(0); if (line.size() <= 2) return; m_points->SetNumberOfPoints(line.size()); m_polygon->GetPointIds()->SetNumberOfIds(line.size()); int i=0; for (mitk::PlanarFigure::PolyLineType::iterator it = line.begin(); it!=line.end(); ++it) { mitk::PlanarFigure::PolyLineElement elem = *it; planeGeo->Map(elem.Point, wp); m_points->InsertPoint(i,(double)wp[0], (double)wp[1], (double)wp[2] ); m_polygon->GetPointIds()->SetId(i, i); i++; } m_polygonsCell->Reset(); m_polygonsCell->InsertNextCell(m_polygon); m_polygonPolyData->SetPoints(m_points); m_polygonPolyData->SetPolys(m_polygonsCell); - m_VtkPolygonDataMapperGL->SetInput(m_polygonPolyData); + m_VtkPolygonDataMapperGL->SetInputData(m_polygonPolyData); m_PolygonActor->SetMapper(m_VtkPolygonDataMapperGL); m_PolygonAssembly->AddPart(m_PolygonActor); //updates all polygon pipeline m_VtkPolygonDataMapperGL->Modified(); float polyOpaq; this->GetDataNode()->GetOpacity(polyOpaq, NULL); m_PolygonActor->GetProperty()->SetOpacity((double) polyOpaq); float temprgb[3]; this->GetDataNode()->GetColor( temprgb, NULL ); double trgb[3] = { (double) temprgb[0], (double) temprgb[1], (double) temprgb[2] }; m_PolygonActor->GetProperty()->SetColor(trgb); } catch (...) { } } void mitk::PlanarFigureMapper3D::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite) { Superclass::SetDefaultProperties(node, renderer, overwrite); } vtkProp* mitk::PlanarFigureMapper3D::GetVtkProp(mitk::BaseRenderer *renderer) { return m_PolygonAssembly; } void mitk::PlanarFigureMapper3D::UpdateVtkObjects() { } void mitk::PlanarFigureMapper3D::SetVtkMapperImmediateModeRendering(vtkMapper *) { } diff --git a/Modules/DiffusionImaging/DiffusionCore/Rendering/mitkVectorImageVtkGlyphMapper3D.cpp b/Modules/DiffusionImaging/DiffusionCore/Rendering/mitkVectorImageVtkGlyphMapper3D.cpp index 1391c0aabf..2878c867d5 100644 --- a/Modules/DiffusionImaging/DiffusionCore/Rendering/mitkVectorImageVtkGlyphMapper3D.cpp +++ b/Modules/DiffusionImaging/DiffusionCore/Rendering/mitkVectorImageVtkGlyphMapper3D.cpp @@ -1,219 +1,219 @@ /*=================================================================== 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 "mitkVectorImageVtkGlyphMapper3D.h" #include #include #include #include #include #include #include #include #include #include #include /* * Constructor. Doesn't do anything... */ mitk::VectorImageVtkGlyphMapper3D::VectorImageVtkGlyphMapper3D() { m_RandomMode = true; m_UseMaskPoints = true; m_MaximumNumberOfPoints = 5000; m_GlyphType = ArrowGlyph; m_Glyph3DGenerator = vtkMaskedGlyph3D::New(); m_Glyph3DMapper = vtkPolyDataMapper::New(); m_Glyph3DActor = vtkActor::New(); } vtkProp* mitk::VectorImageVtkGlyphMapper3D::GetVtkProp(mitk::BaseRenderer* /*renderer*/) { return m_Glyph3DActor; } /* * Destructor */ mitk::VectorImageVtkGlyphMapper3D::~VectorImageVtkGlyphMapper3D() { if ( m_Glyph3DMapper != NULL ) m_Glyph3DMapper->Delete(); if ( m_Glyph3DGenerator != NULL ) m_Glyph3DGenerator->Delete(); } /* * Generate a vtkPolyData by creating vectors as glyphs * This method is called, each time a specific renderer is updated. */ void mitk::VectorImageVtkGlyphMapper3D::GenerateDataForRenderer( mitk::BaseRenderer* renderer ) { bool visible = true; GetDataNode()->GetVisibility(visible, renderer, "visible"); if ( !visible ) { if ( m_Glyph3DActor != NULL ) m_Glyph3DActor->VisibilityOff(); return ; } else { if ( m_Glyph3DActor != NULL ) m_Glyph3DActor->VisibilityOn(); } BaseLocalStorage *ls = m_LSH.GetLocalStorage(renderer); bool needGenerateData = ls->IsGenerateDataRequired( renderer, this, GetDataNode() ); if(!needGenerateData) { return; } ls->UpdateGenerateDataTime(); // // get the input image... // mitk::Image::Pointer mitkImage = this->GetInput(); if ( mitkImage.GetPointer() == NULL ) { itkWarningMacro( << "VectorImage is null !" ); return; } // // make sure, that the input image is an vector image // if ( mitkImage->GetPixelType().GetNumberOfComponents() <= 1 ) { itkWarningMacro( << "VectorImage has only one scalar component!" ); return ; } vtkImageData* vtkImage = mitkImage->GetVtkImageData(); // // make sure, that we have point data with more than 1 component (as vectors) // vtkPointData* pointData = vtkImage->GetPointData(); if ( pointData == NULL ) { itkWarningMacro( << "vtkImage->GetPointData() returns NULL!" ); return ; } if ( pointData->GetNumberOfArrays() == 0 ) { itkWarningMacro( << "vtkImage->GetPointData()->GetNumberOfArrays() is 0!" ); return ; } else if ( pointData->GetArrayName( 0 ) == NULL ) { vtkImage->GetPointData() ->GetArray( 0 ) ->SetName( "vector" ); } if ( vtkImage->GetNumberOfPoints() != 0 ) { // // create the glyph, which has to be shown at each point // of the masked image // vtkPolyData* glyph; if ( m_GlyphType == LineGlyph ) { vtkLineSource * lineSource = vtkLineSource::New(); lineSource->Update(); glyph = lineSource->GetOutput(); } else if ( m_GlyphType == ArrowGlyph ) { vtkArrowSource * arrowSource = vtkArrowSource::New(); arrowSource->Update(); glyph = arrowSource->GetOutput(); } else { // Use a vtkLineSource as default, if the GlyphType is // unknown itkWarningMacro( << "unknown glyph type!" ); vtkLineSource * lineSource = vtkLineSource::New(); lineSource->Update(); glyph = lineSource->GetOutput(); } m_RandomMode = false; m_UseMaskPoints = false; m_MaximumNumberOfPoints = 80*80*80; // // set up the actual glyphing filter // - m_Glyph3DGenerator->SetSource( glyph ); + m_Glyph3DGenerator->SetSourceData( glyph ); m_Glyph3DGenerator->SetInput( vtkImage ); //m_Glyph3DGenerator->SetInputConnection(m_Cutter->GetOutputPort()); m_Glyph3DGenerator->SetInputArrayToProcess (1, 0,0, vtkDataObject::FIELD_ASSOCIATION_POINTS , "vector"); //m_Glyph3DGenerator->SelectInputVectors( vtkImage->GetPointData() ->GetArray( 0 ) ->GetName() ); m_Glyph3DGenerator->OrientOn(); m_Glyph3DGenerator->SetVectorModeToUseVector(); m_Glyph3DGenerator->SetScaleFactor( 0.00392156862745 ); m_Glyph3DGenerator->SetScaleModeToScaleByVector(); m_Glyph3DGenerator->SetUseMaskPoints( m_UseMaskPoints ); m_Glyph3DGenerator->SetRandomMode( m_RandomMode ); m_Glyph3DGenerator->SetMaximumNumberOfPoints( m_MaximumNumberOfPoints ); m_Glyph3DGenerator->Update(); - m_Glyph3DMapper->SetInput( m_Glyph3DGenerator->GetOutput() ); + m_Glyph3DMapper->SetInputData( m_Glyph3DGenerator->GetOutput() ); m_Glyph3DActor->SetMapper( m_Glyph3DMapper ); if (GetDataNode()->GetProperty("LookupTable")) { mitk::LookupTable::Pointer mitkLookupTable = mitk::LookupTable::New(); m_Glyph3DMapper->Update(); mitkLookupTable->SetVtkLookupTable(dynamic_cast(m_Glyph3DMapper->GetLookupTable())); mitk::LookupTableProperty::Pointer LookupTableProp = mitk::LookupTableProperty::New( mitkLookupTable ); GetDataNode()->SetProperty( "LookupTable", LookupTableProp ); } else { mitk::LookupTableProperty::Pointer mitkLutProp = dynamic_cast(GetDataNode()->GetProperty("LookupTable")); if (mitkLutProp.IsNotNull()) m_Glyph3DMapper->SetLookupTable( mitkLutProp->GetLookupTable()->GetVtkLookupTable() ); } //vtkDataSetWriter* writer = vtkDataSetWriter::New(); //writer->SetInput( vtkImage ); //writer->SetFileName( "out.vtk" ); //writer->Update(); } } /* * Returns the input data object of the given filter. In this * case, a mitk::Image is returned. */ mitk::Image* mitk::VectorImageVtkGlyphMapper3D::GetInput() { return const_cast( dynamic_cast( GetDataNode()->GetData() ) ); } diff --git a/Modules/DiffusionImaging/DiffusionCore/Rendering/vtkMaskedProgrammableGlyphFilter.cpp b/Modules/DiffusionImaging/DiffusionCore/Rendering/vtkMaskedProgrammableGlyphFilter.cpp index 44fa3df9fa..28f2134a61 100644 --- a/Modules/DiffusionImaging/DiffusionCore/Rendering/vtkMaskedProgrammableGlyphFilter.cpp +++ b/Modules/DiffusionImaging/DiffusionCore/Rendering/vtkMaskedProgrammableGlyphFilter.cpp @@ -1,119 +1,100 @@ /*=================================================================== 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 "vtkMaskedProgrammableGlyphFilter.h" #include "vtkMaskPoints.h" #include "vtkObjectFactory.h" #include "vtkPolyData.h" vtkStandardNewMacro(vtkMaskedProgrammableGlyphFilter); vtkMaskedProgrammableGlyphFilter::vtkMaskedProgrammableGlyphFilter() { //this->SetColorModeToColorByScalar(); //this->SetScaleModeToScaleByVector(); this->MaskPoints = vtkMaskPoints::New(); this->MaximumNumberOfPoints = 5000; this->UseMaskPoints = 1; } vtkMaskedProgrammableGlyphFilter::~vtkMaskedProgrammableGlyphFilter() { if(this->MaskPoints) { this->MaskPoints->Delete(); } } void vtkMaskedProgrammableGlyphFilter::SetInput(vtkDataSet *input) { - this->MaskPoints->SetInput(input); - this->Superclass::SetInput(this->MaskPoints->GetOutput()); + this->MaskPoints->SetInputData(input); + this->Superclass::SetInputData(this->MaskPoints->GetOutput()); } void vtkMaskedProgrammableGlyphFilter::SetRandomMode(int mode) { this->MaskPoints->SetRandomMode(mode); } int vtkMaskedProgrammableGlyphFilter::GetRandomMode() { return this->MaskPoints->GetRandomMode(); } -void vtkMaskedProgrammableGlyphFilter::Execute() -{ - if (this->UseMaskPoints) - { - this->Superclass::SetInput(this->MaskPoints->GetOutput()); - vtkIdType numPts = this->MaskPoints->GetPolyDataInput(0)->GetNumberOfPoints(); - this->MaskPoints->SetMaximumNumberOfPoints(MaximumNumberOfPoints); - double onRatio = MaximumNumberOfPoints != 0.0 ? numPts / MaximumNumberOfPoints : 1.0; - this->MaskPoints->SetOnRatio(onRatio); - this->MaskPoints->Update(); - } - else - { - this->Superclass::SetInput(this->MaskPoints->GetInput()); - } - - this->Superclass::Execute(); -} - int vtkMaskedProgrammableGlyphFilter::RequestData( vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector) { if (this->UseMaskPoints) { - this->Superclass::SetInput(this->MaskPoints->GetOutput()); + this->Superclass::SetInputData(this->MaskPoints->GetOutput()); vtkIdType numPts = this->MaskPoints->GetPolyDataInput(0)->GetNumberOfPoints(); this->MaskPoints->SetMaximumNumberOfPoints(MaximumNumberOfPoints); this->MaskPoints->SetOnRatio(numPts / MaximumNumberOfPoints); this->MaskPoints->Update(); } else { - this->Superclass::SetInput(this->MaskPoints->GetInput()); + this->Superclass::SetInputData(this->MaskPoints->GetInput()); } return this->Superclass::RequestData( request,inputVector,outputVector); } void vtkMaskedProgrammableGlyphFilter::PrintSelf(ostream& os, vtkIndent indent) { this->Superclass::PrintSelf(os,indent); //os << indent << "InputScalarsSelection: " // << (this->InputScalarsSelection ? this->InputScalarsSelection : "(none)") // << endl; //os << indent << "InputVectorsSelection: " // << (this->InputVectorsSelection ? this->InputVectorsSelection : "(none)") // << endl; //os << indent << "InputNormalsSelection: " // << (this->InputNormalsSelection ? this->InputNormalsSelection : "(none)") // << endl; os << indent << "MaximumNumberOfPoints: " << this->GetMaximumNumberOfPoints() << endl; os << indent << "UseMaskPoints: " << (this->UseMaskPoints?"on":"off") << endl; } diff --git a/Modules/DiffusionImaging/DiffusionCore/Rendering/vtkMaskedProgrammableGlyphFilter.h b/Modules/DiffusionImaging/DiffusionCore/Rendering/vtkMaskedProgrammableGlyphFilter.h index df5866cbe9..42ba45a541 100644 --- a/Modules/DiffusionImaging/DiffusionCore/Rendering/vtkMaskedProgrammableGlyphFilter.h +++ b/Modules/DiffusionImaging/DiffusionCore/Rendering/vtkMaskedProgrammableGlyphFilter.h @@ -1,115 +1,114 @@ /*=================================================================== 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 __vtkMaskedProgrammableGlyphFilter_h #define __vtkMaskedProgrammableGlyphFilter_h #include "DiffusionCoreExports.h" #include "vtkProgrammableGlyphFilter.h" #include "mitkGeometry3D.h" class vtkMaskPoints; /** * This class masked points of the input data set and glyphs * only the selected poitns. Points may be selected either by * random or by ratio. * Additionally, this class allows to set the InputScalars, * InputVectors and InputNormals by their field name in the * input dataset. */ class DiffusionCore_EXPORT vtkMaskedProgrammableGlyphFilter : public vtkProgrammableGlyphFilter { public: vtkTypeMacro(vtkMaskedProgrammableGlyphFilter,vtkProgrammableGlyphFilter); void PrintSelf(ostream& os, vtkIndent indent); /** * Constructor */ static vtkMaskedProgrammableGlyphFilter *New(); /** * Limit the number of points to glyph */ vtkSetMacro(MaximumNumberOfPoints, int); vtkGetMacro(MaximumNumberOfPoints, int); /** * Set the input to this filter. */ virtual void SetInput(vtkDataSet *input); /** * Set/get whether to mask points */ vtkSetMacro(UseMaskPoints, int); vtkGetMacro(UseMaskPoints, int); /** * Set/get flag to cause randomization of which points to mask. */ void SetRandomMode(int mode); int GetRandomMode(); ///** // * If you want to use an arbitrary scalars array, then set its name here. // * By default this in NULL and the filter will use the active scalar array. // */ //vtkGetStringMacro(InputScalarsSelection); //void SelectInputScalars(const char *fieldName) // {this->SetInputScalarsSelection(fieldName);} ///** // * If you want to use an arbitrary vectors array, then set its name here. // * By default this in NULL and the filter will use the active vector array. // */ //vtkGetStringMacro(InputVectorsSelection); //void SelectInputVectors(const char *fieldName) // {this->SetInputVectorsSelection(fieldName);} ///** // * If you want to use an arbitrary normals array, then set its name here. // * By default this in NULL and the filter will use the active normal array. // */ //vtkGetStringMacro(InputNormalsSelection); //void SelectInputNormals(const char *fieldName) // {this->SetInputNormalsSelection(fieldName);} void SetGeometry(mitk::Geometry3D::Pointer geo) { this->m_Geometry = geo; } mitk::Geometry3D::Pointer GetGeometry() { return this->m_Geometry; } protected: vtkMaskedProgrammableGlyphFilter(); ~vtkMaskedProgrammableGlyphFilter(); - virtual void Execute(); virtual int RequestData(vtkInformation *, vtkInformationVector **, vtkInformationVector *); vtkMaskPoints *MaskPoints; int MaximumNumberOfPoints; int UseMaskPoints; mitk::Geometry3D::Pointer m_Geometry; private: vtkMaskedProgrammableGlyphFilter(const vtkMaskedProgrammableGlyphFilter&); // Not implemented. void operator=(const vtkMaskedProgrammableGlyphFilter&); // Not implemented. }; #endif diff --git a/Modules/DiffusionImaging/FiberTracking/IODataStructures/FiberBundleX/mitkFiberBundleX.cpp b/Modules/DiffusionImaging/FiberTracking/IODataStructures/FiberBundleX/mitkFiberBundleX.cpp index 48edf72753..92904a0661 100755 --- a/Modules/DiffusionImaging/FiberTracking/IODataStructures/FiberBundleX/mitkFiberBundleX.cpp +++ b/Modules/DiffusionImaging/FiberTracking/IODataStructures/FiberBundleX/mitkFiberBundleX.cpp @@ -1,1799 +1,1799 @@ /*=================================================================== 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. ===================================================================*/ #define _USE_MATH_DEFINES #include "mitkFiberBundleX.h" #include #include #include #include "mitkImagePixelReadAccessor.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include const char* mitk::FiberBundleX::COLORCODING_ORIENTATION_BASED = "Color_Orient"; //const char* mitk::FiberBundleX::COLORCODING_FA_AS_OPACITY = "Color_Orient_FA_Opacity"; const char* mitk::FiberBundleX::COLORCODING_FA_BASED = "FA_Values"; const char* mitk::FiberBundleX::COLORCODING_CUSTOM = "custom"; const char* mitk::FiberBundleX::FIBER_ID_ARRAY = "Fiber_IDs"; using namespace std; mitk::FiberBundleX::FiberBundleX( vtkPolyData* fiberPolyData ) : m_CurrentColorCoding(NULL) , m_NumFibers(0) , m_FiberSampling(0) { m_FiberPolyData = vtkSmartPointer::New(); if (fiberPolyData != NULL) { m_FiberPolyData = fiberPolyData; //m_FiberPolyData->DeepCopy(fiberPolyData); this->DoColorCodingOrientationBased(); } this->UpdateFiberGeometry(); this->SetColorCoding(COLORCODING_ORIENTATION_BASED); this->GenerateFiberIds(); } mitk::FiberBundleX::~FiberBundleX() { } mitk::FiberBundleX::Pointer mitk::FiberBundleX::GetDeepCopy() { mitk::FiberBundleX::Pointer newFib = mitk::FiberBundleX::New(m_FiberPolyData); newFib->SetColorCoding(m_CurrentColorCoding); return newFib; } vtkSmartPointer mitk::FiberBundleX::GeneratePolyDataByIds(std::vector fiberIds) { MITK_DEBUG << "\n=====FINAL RESULT: fib_id ======\n"; MITK_DEBUG << "Number of new Fibers: " << fiberIds.size(); // iterate through the vectorcontainer hosting all desired fiber Ids vtkSmartPointer newFiberPolyData = vtkSmartPointer::New(); vtkSmartPointer newLineSet = vtkSmartPointer::New(); vtkSmartPointer newPointSet = vtkSmartPointer::New(); // if FA array available, initialize fa double array // if color orient array is available init color array vtkSmartPointer faValueArray; vtkSmartPointer colorsT; //colors and alpha value for each single point, RGBA = 4 components unsigned char rgba[4] = {0,0,0,0}; int componentSize = sizeof(rgba); if (m_FiberIdDataSet->GetPointData()->HasArray(COLORCODING_FA_BASED)){ MITK_DEBUG << "FA VALUES AVAILABLE, init array for new fiberbundle"; faValueArray = vtkSmartPointer::New(); } if (m_FiberIdDataSet->GetPointData()->HasArray(COLORCODING_ORIENTATION_BASED)){ MITK_DEBUG << "colorValues available, init array for new fiberbundle"; colorsT = vtkUnsignedCharArray::New(); colorsT->SetNumberOfComponents(componentSize); colorsT->SetName(COLORCODING_ORIENTATION_BASED); } std::vector::iterator finIt = fiberIds.begin(); while ( finIt != fiberIds.end() ) { if (*finIt < 0 || *finIt>GetNumFibers()){ MITK_INFO << "FiberID can not be negative or >NumFibers!!! check id Extraction!" << *finIt; break; } vtkSmartPointer fiber = m_FiberIdDataSet->GetCell(*finIt);//->DeepCopy(fiber); vtkSmartPointer fibPoints = fiber->GetPoints(); vtkSmartPointer newFiber = vtkSmartPointer::New(); newFiber->GetPointIds()->SetNumberOfIds( fibPoints->GetNumberOfPoints() ); for(int i=0; iGetNumberOfPoints(); i++) { // MITK_DEBUG << "id: " << fiber->GetPointId(i); // MITK_DEBUG << fibPoints->GetPoint(i)[0] << " | " << fibPoints->GetPoint(i)[1] << " | " << fibPoints->GetPoint(i)[2]; newFiber->GetPointIds()->SetId(i, newPointSet->GetNumberOfPoints()); newPointSet->InsertNextPoint(fibPoints->GetPoint(i)[0], fibPoints->GetPoint(i)[1], fibPoints->GetPoint(i)[2]); if (m_FiberIdDataSet->GetPointData()->HasArray(COLORCODING_FA_BASED)){ // MITK_DEBUG << m_FiberIdDataSet->GetPointData()->GetArray(FA_VALUE_ARRAY)->GetTuple(fiber->GetPointId(i)); } if (m_FiberIdDataSet->GetPointData()->HasArray(COLORCODING_ORIENTATION_BASED)){ // MITK_DEBUG << "ColorValue: " << m_FiberIdDataSet->GetPointData()->GetArray(COLORCODING_ORIENTATION_BASED)->GetTuple(fiber->GetPointId(i))[0]; } } newLineSet->InsertNextCell(newFiber); ++finIt; } newFiberPolyData->SetPoints(newPointSet); newFiberPolyData->SetLines(newLineSet); MITK_DEBUG << "new fiberbundle polydata points: " << newFiberPolyData->GetNumberOfPoints(); MITK_DEBUG << "new fiberbundle polydata lines: " << newFiberPolyData->GetNumberOfLines(); MITK_DEBUG << "=====================\n"; // mitk::FiberBundleX::Pointer newFib = mitk::FiberBundleX::New(newFiberPolyData); return newFiberPolyData; } // merge two fiber bundles mitk::FiberBundleX::Pointer mitk::FiberBundleX::AddBundle(mitk::FiberBundleX* fib) { if (fib==NULL) { MITK_WARN << "trying to call AddBundle with NULL argument"; return NULL; } MITK_INFO << "Adding fibers"; vtkSmartPointer vNewPolyData = vtkSmartPointer::New(); vtkSmartPointer vNewLines = vtkSmartPointer::New(); vtkSmartPointer vNewPoints = vtkSmartPointer::New(); // add current fiber bundle for (int i=0; iGetNumberOfCells(); i++) { vtkCell* cell = m_FiberPolyData->GetCell(i); int numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); vtkSmartPointer container = vtkSmartPointer::New(); for (int j=0; jGetPoint(j, p); vtkIdType id = vNewPoints->InsertNextPoint(p); container->GetPointIds()->InsertNextId(id); } vNewLines->InsertNextCell(container); } // add new fiber bundle for (int i=0; iGetFiberPolyData()->GetNumberOfCells(); i++) { vtkCell* cell = fib->GetFiberPolyData()->GetCell(i); int numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); vtkSmartPointer container = vtkSmartPointer::New(); for (int j=0; jGetPoint(j, p); vtkIdType id = vNewPoints->InsertNextPoint(p); container->GetPointIds()->InsertNextId(id); } vNewLines->InsertNextCell(container); } // initialize polydata vNewPolyData->SetPoints(vNewPoints); vNewPolyData->SetLines(vNewLines); // initialize fiber bundle mitk::FiberBundleX::Pointer newFib = mitk::FiberBundleX::New(vNewPolyData); return newFib; } // subtract two fiber bundles mitk::FiberBundleX::Pointer mitk::FiberBundleX::SubtractBundle(mitk::FiberBundleX* fib) { MITK_INFO << "Subtracting fibers"; vtkSmartPointer vNewPolyData = vtkSmartPointer::New(); vtkSmartPointer vNewLines = vtkSmartPointer::New(); vtkSmartPointer vNewPoints = vtkSmartPointer::New(); // iterate over current fibers int numFibers = GetNumFibers(); boost::progress_display disp(numFibers); for( int i=0; iGetCell(i); int numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); if (points==NULL || numPoints<=0) continue; int numFibers2 = fib->GetNumFibers(); bool contained = false; for( int i2=0; i2GetFiberPolyData()->GetCell(i2); int numPoints2 = cell2->GetNumberOfPoints(); vtkPoints* points2 = cell2->GetPoints(); if (points2==NULL || numPoints2<=0) continue; // check endpoints itk::Point point_start = GetItkPoint(points->GetPoint(0)); itk::Point point_end = GetItkPoint(points->GetPoint(numPoints-1)); itk::Point point2_start = GetItkPoint(points2->GetPoint(0)); itk::Point point2_end = GetItkPoint(points2->GetPoint(numPoints2-1)); if (point_start.SquaredEuclideanDistanceTo(point2_start)<=mitk::eps && point_end.SquaredEuclideanDistanceTo(point2_end)<=mitk::eps || point_start.SquaredEuclideanDistanceTo(point2_end)<=mitk::eps && point_end.SquaredEuclideanDistanceTo(point2_start)<=mitk::eps) { // further checking ??? if (numPoints2==numPoints) contained = true; } } // add to result because fiber is not subtracted if (!contained) { vtkSmartPointer container = vtkSmartPointer::New(); for( int j=0; jInsertNextPoint(points->GetPoint(j)); container->GetPointIds()->InsertNextId(id); } vNewLines->InsertNextCell(container); } } if(vNewLines->GetNumberOfCells()==0) return NULL; // initialize polydata vNewPolyData->SetPoints(vNewPoints); vNewPolyData->SetLines(vNewLines); // initialize fiber bundle mitk::FiberBundleX::Pointer newFib = mitk::FiberBundleX::New(vNewPolyData); return newFib; } itk::Point mitk::FiberBundleX::GetItkPoint(double point[3]) { itk::Point itkPoint; itkPoint[0] = point[0]; itkPoint[1] = point[1]; itkPoint[2] = point[2]; return itkPoint; } /* * set polydata (additional flag to recompute fiber geometry, default = true) */ void mitk::FiberBundleX::SetFiberPolyData(vtkSmartPointer fiberPD, bool updateGeometry) { if (fiberPD == NULL) this->m_FiberPolyData = vtkSmartPointer::New(); else { m_FiberPolyData->DeepCopy(fiberPD); DoColorCodingOrientationBased(); } m_NumFibers = m_FiberPolyData->GetNumberOfLines(); if (updateGeometry) UpdateFiberGeometry(); SetColorCoding(COLORCODING_ORIENTATION_BASED); GenerateFiberIds(); } /* * return vtkPolyData */ vtkSmartPointer mitk::FiberBundleX::GetFiberPolyData() { return m_FiberPolyData; } void mitk::FiberBundleX::DoColorCodingOrientationBased() { //===== FOR WRITING A TEST ======================== // colorT size == tupelComponents * tupelElements // compare color results // to cover this code 100% also polydata needed, where colorarray already exists // + one fiber with exactly 1 point // + one fiber with 0 points //================================================= /* make sure that processing colorcoding is only called when necessary */ if ( m_FiberPolyData->GetPointData()->HasArray(COLORCODING_ORIENTATION_BASED) && m_FiberPolyData->GetNumberOfPoints() == m_FiberPolyData->GetPointData()->GetArray(COLORCODING_ORIENTATION_BASED)->GetNumberOfTuples() ) { // fiberstructure is already colorcoded MITK_DEBUG << " NO NEED TO REGENERATE COLORCODING! " ; this->ResetFiberOpacity(); this->SetColorCoding(COLORCODING_ORIENTATION_BASED); return; } /* Finally, execute color calculation */ vtkPoints* extrPoints = NULL; extrPoints = m_FiberPolyData->GetPoints(); int numOfPoints = 0; if (extrPoints!=NULL) numOfPoints = extrPoints->GetNumberOfPoints(); //colors and alpha value for each single point, RGBA = 4 components unsigned char rgba[4] = {0,0,0,0}; // int componentSize = sizeof(rgba); int componentSize = 4; vtkSmartPointer colorsT = vtkSmartPointer::New(); colorsT->Allocate(numOfPoints * componentSize); colorsT->SetNumberOfComponents(componentSize); colorsT->SetName(COLORCODING_ORIENTATION_BASED); /* checkpoint: does polydata contain any fibers */ int numOfFibers = m_FiberPolyData->GetNumberOfLines(); if (numOfFibers < 1) { MITK_DEBUG << "\n ========= Number of Fibers is 0 and below ========= \n"; return; } /* extract single fibers of fiberBundle */ vtkCellArray* fiberList = m_FiberPolyData->GetLines(); fiberList->InitTraversal(); for (int fi=0; fiGetNextCell(pointsPerFiber, idList); // MITK_DEBUG << "Fib#: " << fi << " of " << numOfFibers << " pnts in fiber: " << pointsPerFiber ; /* single fiber checkpoints: is number of points valid */ if (pointsPerFiber > 1) { /* operate on points of single fiber */ for (int i=0; i 0) { /* The color value of the current point is influenced by the previous point and next point. */ vnl_vector_fixed< double, 3 > currentPntvtk(extrPoints->GetPoint(idList[i])[0], extrPoints->GetPoint(idList[i])[1],extrPoints->GetPoint(idList[i])[2]); vnl_vector_fixed< double, 3 > nextPntvtk(extrPoints->GetPoint(idList[i+1])[0], extrPoints->GetPoint(idList[i+1])[1], extrPoints->GetPoint(idList[i+1])[2]); vnl_vector_fixed< double, 3 > prevPntvtk(extrPoints->GetPoint(idList[i-1])[0], extrPoints->GetPoint(idList[i-1])[1], extrPoints->GetPoint(idList[i-1])[2]); vnl_vector_fixed< double, 3 > diff1; diff1 = currentPntvtk - nextPntvtk; vnl_vector_fixed< double, 3 > diff2; diff2 = currentPntvtk - prevPntvtk; vnl_vector_fixed< double, 3 > diff; diff = (diff1 - diff2) / 2.0; diff.normalize(); rgba[0] = (unsigned char) (255.0 * std::fabs(diff[0])); rgba[1] = (unsigned char) (255.0 * std::fabs(diff[1])); rgba[2] = (unsigned char) (255.0 * std::fabs(diff[2])); rgba[3] = (unsigned char) (255.0); } else if (i==0) { /* First point has no previous point, therefore only diff1 is taken */ vnl_vector_fixed< double, 3 > currentPntvtk(extrPoints->GetPoint(idList[i])[0], extrPoints->GetPoint(idList[i])[1],extrPoints->GetPoint(idList[i])[2]); vnl_vector_fixed< double, 3 > nextPntvtk(extrPoints->GetPoint(idList[i+1])[0], extrPoints->GetPoint(idList[i+1])[1], extrPoints->GetPoint(idList[i+1])[2]); vnl_vector_fixed< double, 3 > diff1; diff1 = currentPntvtk - nextPntvtk; diff1.normalize(); rgba[0] = (unsigned char) (255.0 * std::fabs(diff1[0])); rgba[1] = (unsigned char) (255.0 * std::fabs(diff1[1])); rgba[2] = (unsigned char) (255.0 * std::fabs(diff1[2])); rgba[3] = (unsigned char) (255.0); } else if (i==pointsPerFiber-1) { /* Last point has no next point, therefore only diff2 is taken */ vnl_vector_fixed< double, 3 > currentPntvtk(extrPoints->GetPoint(idList[i])[0], extrPoints->GetPoint(idList[i])[1],extrPoints->GetPoint(idList[i])[2]); vnl_vector_fixed< double, 3 > prevPntvtk(extrPoints->GetPoint(idList[i-1])[0], extrPoints->GetPoint(idList[i-1])[1], extrPoints->GetPoint(idList[i-1])[2]); vnl_vector_fixed< double, 3 > diff2; diff2 = currentPntvtk - prevPntvtk; diff2.normalize(); rgba[0] = (unsigned char) (255.0 * std::fabs(diff2[0])); rgba[1] = (unsigned char) (255.0 * std::fabs(diff2[1])); rgba[2] = (unsigned char) (255.0 * std::fabs(diff2[2])); rgba[3] = (unsigned char) (255.0); } colorsT->InsertTupleValue(idList[i], rgba); } //end for loop } else if (pointsPerFiber == 1) { /* a single point does not define a fiber (use vertex mechanisms instead */ continue; // colorsT->InsertTupleValue(0, rgba); } else { MITK_DEBUG << "Fiber with 0 points detected... please check your tractography algorithm!" ; continue; } }//end for loop m_FiberPolyData->GetPointData()->AddArray(colorsT); /*========================= - this is more relevant for renderer than for fiberbundleX datastructure - think about sourcing this to a explicit method which coordinates colorcoding */ this->SetColorCoding(COLORCODING_ORIENTATION_BASED); // =========================== //mini test, shall be ported to MITK TESTINGS! if (colorsT->GetSize() != numOfPoints*componentSize) MITK_DEBUG << "ALLOCATION ERROR IN INITIATING COLOR ARRAY"; } void mitk::FiberBundleX::DoColorCodingFaBased() { if(m_FiberPolyData->GetPointData()->HasArray(COLORCODING_FA_BASED) != 1 ) return; this->SetColorCoding(COLORCODING_FA_BASED); MITK_DEBUG << "FBX: done CC FA based"; this->GenerateFiberIds(); } void mitk::FiberBundleX::DoUseFaFiberOpacity() { if(m_FiberPolyData->GetPointData()->HasArray(COLORCODING_FA_BASED) != 1 ) return; if(m_FiberPolyData->GetPointData()->HasArray(COLORCODING_ORIENTATION_BASED) != 1 ) return; vtkDoubleArray* FAValArray = (vtkDoubleArray*) m_FiberPolyData->GetPointData()->GetArray(COLORCODING_FA_BASED); vtkUnsignedCharArray* ColorArray = dynamic_cast (m_FiberPolyData->GetPointData()->GetArray(COLORCODING_ORIENTATION_BASED)); for(long i=0; iGetNumberOfTuples(); i++) { double faValue = FAValArray->GetValue(i); faValue = faValue * 255.0; ColorArray->SetComponent(i,3, (unsigned char) faValue ); } this->SetColorCoding(COLORCODING_ORIENTATION_BASED); MITK_DEBUG << "FBX: done CC OPACITY"; this->GenerateFiberIds(); } void mitk::FiberBundleX::ResetFiberOpacity() { vtkUnsignedCharArray* ColorArray = dynamic_cast (m_FiberPolyData->GetPointData()->GetArray(COLORCODING_ORIENTATION_BASED)); if (ColorArray==NULL) return; for(long i=0; iGetNumberOfTuples(); i++) ColorArray->SetComponent(i,3, 255.0 ); } void mitk::FiberBundleX::SetFAMap(mitk::Image::Pointer FAimage) { mitkPixelTypeMultiplex1( SetFAMap, FAimage->GetPixelType(), FAimage ); } template void mitk::FiberBundleX::SetFAMap(const mitk::PixelType pixelType, mitk::Image::Pointer FAimage) { MITK_DEBUG << "SetFAMap"; vtkSmartPointer faValues = vtkSmartPointer::New(); faValues->SetName(COLORCODING_FA_BASED); faValues->Allocate(m_FiberPolyData->GetNumberOfPoints()); faValues->SetNumberOfValues(m_FiberPolyData->GetNumberOfPoints()); mitk::ImagePixelReadAccessor readFAimage (FAimage, FAimage->GetVolumeData(0)); vtkPoints* pointSet = m_FiberPolyData->GetPoints(); for(long i=0; iGetNumberOfPoints(); ++i) { Point3D px; px[0] = pointSet->GetPoint(i)[0]; px[1] = pointSet->GetPoint(i)[1]; px[2] = pointSet->GetPoint(i)[2]; double faPixelValue = 1-readFAimage.GetPixelByWorldCoordinates(px); faValues->InsertValue(i, faPixelValue); } m_FiberPolyData->GetPointData()->AddArray(faValues); this->GenerateFiberIds(); if(m_FiberPolyData->GetPointData()->HasArray(COLORCODING_FA_BASED)) MITK_DEBUG << "FA VALUE ARRAY SET"; } void mitk::FiberBundleX::GenerateFiberIds() { if (m_FiberPolyData == NULL) return; vtkSmartPointer idFiberFilter = vtkSmartPointer::New(); - idFiberFilter->SetInput(m_FiberPolyData); + idFiberFilter->SetInputData(m_FiberPolyData); idFiberFilter->CellIdsOn(); // idFiberFilter->PointIdsOn(); // point id's are not needed idFiberFilter->SetIdsArrayName(FIBER_ID_ARRAY); idFiberFilter->FieldDataOn(); idFiberFilter->Update(); m_FiberIdDataSet = idFiberFilter->GetOutput(); MITK_DEBUG << "Generating Fiber Ids...[done] | " << m_FiberIdDataSet->GetNumberOfCells(); } mitk::FiberBundleX::Pointer mitk::FiberBundleX::ExtractFiberSubset(ItkUcharImgType* mask, bool anyPoint) { vtkSmartPointer polyData = m_FiberPolyData; if (anyPoint) { float minSpacing = 1; if(mask->GetSpacing()[0]GetSpacing()[1] && mask->GetSpacing()[0]GetSpacing()[2]) minSpacing = mask->GetSpacing()[0]; else if (mask->GetSpacing()[1] < mask->GetSpacing()[2]) minSpacing = mask->GetSpacing()[1]; else minSpacing = mask->GetSpacing()[2]; mitk::FiberBundleX::Pointer fibCopy = this->GetDeepCopy(); fibCopy->ResampleFibers(minSpacing/10); polyData = fibCopy->GetFiberPolyData(); } vtkSmartPointer vtkNewPoints = vtkSmartPointer::New(); vtkSmartPointer vtkNewCells = vtkSmartPointer::New(); MITK_INFO << "Extracting fibers"; boost::progress_display disp(m_NumFibers); for (int i=0; iGetCell(i); int numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); vtkCell* cellOriginal = m_FiberPolyData->GetCell(i); int numPointsOriginal = cellOriginal->GetNumberOfPoints(); vtkPoints* pointsOriginal = cellOriginal->GetPoints(); vtkSmartPointer container = vtkSmartPointer::New(); if (numPoints>1 && numPointsOriginal) { if (anyPoint) { for (int j=0; jGetPoint(j); itk::Point itkP; itkP[0] = p[0]; itkP[1] = p[1]; itkP[2] = p[2]; itk::Index<3> idx; mask->TransformPhysicalPointToIndex(itkP, idx); if ( mask->GetPixel(idx)>0 && mask->GetLargestPossibleRegion().IsInside(idx) ) { for (int k=0; kGetPoint(k); vtkIdType id = vtkNewPoints->InsertNextPoint(p); container->GetPointIds()->InsertNextId(id); } break; } } } else { double* start = pointsOriginal->GetPoint(0); itk::Point itkStart; itkStart[0] = start[0]; itkStart[1] = start[1]; itkStart[2] = start[2]; itk::Index<3> idxStart; mask->TransformPhysicalPointToIndex(itkStart, idxStart); double* end = pointsOriginal->GetPoint(numPointsOriginal-1); itk::Point itkEnd; itkEnd[0] = end[0]; itkEnd[1] = end[1]; itkEnd[2] = end[2]; itk::Index<3> idxEnd; mask->TransformPhysicalPointToIndex(itkEnd, idxEnd); if ( mask->GetPixel(idxStart)>0 && mask->GetPixel(idxEnd)>0 && mask->GetLargestPossibleRegion().IsInside(idxStart) && mask->GetLargestPossibleRegion().IsInside(idxEnd) ) { for (int j=0; jGetPoint(j); vtkIdType id = vtkNewPoints->InsertNextPoint(p); container->GetPointIds()->InsertNextId(id); } } } } vtkNewCells->InsertNextCell(container); } if (vtkNewCells->GetNumberOfCells()<=0) return NULL; vtkSmartPointer newPolyData = vtkSmartPointer::New(); newPolyData->SetPoints(vtkNewPoints); newPolyData->SetLines(vtkNewCells); return mitk::FiberBundleX::New(newPolyData); } mitk::FiberBundleX::Pointer mitk::FiberBundleX::RemoveFibersOutside(ItkUcharImgType* mask, bool invert) { float minSpacing = 1; if(mask->GetSpacing()[0]GetSpacing()[1] && mask->GetSpacing()[0]GetSpacing()[2]) minSpacing = mask->GetSpacing()[0]; else if (mask->GetSpacing()[1] < mask->GetSpacing()[2]) minSpacing = mask->GetSpacing()[1]; else minSpacing = mask->GetSpacing()[2]; mitk::FiberBundleX::Pointer fibCopy = this->GetDeepCopy(); fibCopy->ResampleFibers(minSpacing/10); vtkSmartPointer polyData =fibCopy->GetFiberPolyData(); vtkSmartPointer vtkNewPoints = vtkSmartPointer::New(); vtkSmartPointer vtkNewCells = vtkSmartPointer::New(); MITK_INFO << "Cutting fibers"; boost::progress_display disp(m_NumFibers); for (int i=0; iGetCell(i); int numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); vtkSmartPointer container = vtkSmartPointer::New(); if (numPoints>1) { int newNumPoints = 0; for (int j=0; jGetPoint(j); itk::Point itkP; itkP[0] = p[0]; itkP[1] = p[1]; itkP[2] = p[2]; itk::Index<3> idx; mask->TransformPhysicalPointToIndex(itkP, idx); if ( mask->GetPixel(idx)>0 && mask->GetLargestPossibleRegion().IsInside(idx) && !invert ) { vtkIdType id = vtkNewPoints->InsertNextPoint(p); container->GetPointIds()->InsertNextId(id); newNumPoints++; } else if ( (mask->GetPixel(idx)<=0 || !mask->GetLargestPossibleRegion().IsInside(idx)) && invert ) { vtkIdType id = vtkNewPoints->InsertNextPoint(p); container->GetPointIds()->InsertNextId(id); newNumPoints++; } else if (newNumPoints>0) { vtkNewCells->InsertNextCell(container); newNumPoints = 0; container = vtkSmartPointer::New(); } } if (newNumPoints>0) vtkNewCells->InsertNextCell(container); } } if (vtkNewCells->GetNumberOfCells()<=0) return NULL; vtkSmartPointer newPolyData = vtkSmartPointer::New(); newPolyData->SetPoints(vtkNewPoints); newPolyData->SetLines(vtkNewCells); return mitk::FiberBundleX::New(newPolyData); } mitk::FiberBundleX::Pointer mitk::FiberBundleX::ExtractFiberSubset(mitk::PlanarFigure* pf) { if (pf==NULL) return NULL; std::vector tmp = ExtractFiberIdSubset(pf); if (tmp.size()<=0) return mitk::FiberBundleX::New(); vtkSmartPointer pTmp = GeneratePolyDataByIds(tmp); return mitk::FiberBundleX::New(pTmp); } std::vector mitk::FiberBundleX::ExtractFiberIdSubset(mitk::PlanarFigure* pf) { MITK_DEBUG << "Extracting fibers!"; // vector which is returned, contains all extracted FiberIds std::vector FibersInROI; if (pf==NULL) return FibersInROI; /* Handle type of planarfigure */ // if incoming pf is a pfc mitk::PlanarFigureComposite::Pointer pfcomp= dynamic_cast(pf); if (!pfcomp.IsNull()) { // process requested boolean operation of PFC switch (pfcomp->getOperationType()) { case 0: { MITK_DEBUG << "AND PROCESSING"; //AND //temporarly store results of the child in this vector, we need that to accumulate the std::vector childResults = this->ExtractFiberIdSubset(pfcomp->getChildAt(0)); MITK_DEBUG << "first roi got fibers in ROI: " << childResults.size(); MITK_DEBUG << "sorting..."; std::sort(childResults.begin(), childResults.end()); MITK_DEBUG << "sorting done"; std::vector AND_Assamblage(childResults.size()); //std::vector AND_Assamblage; fill(AND_Assamblage.begin(), AND_Assamblage.end(), -1); //AND_Assamblage.reserve(childResults.size()); //max size AND can reach anyway std::vector::iterator it; for (int i=1; igetNumberOfChildren(); ++i) { std::vector tmpChild = this->ExtractFiberIdSubset(pfcomp->getChildAt(i)); MITK_DEBUG << "ROI " << i << " has fibers in ROI: " << tmpChild.size(); sort(tmpChild.begin(), tmpChild.end()); it = std::set_intersection(childResults.begin(), childResults.end(), tmpChild.begin(), tmpChild.end(), AND_Assamblage.begin() ); } MITK_DEBUG << "resize Vector"; long i=0; while (i < AND_Assamblage.size() && AND_Assamblage[i] != -1){ //-1 represents a placeholder in the array ++i; } AND_Assamblage.resize(i); MITK_DEBUG << "returning AND vector, size: " << AND_Assamblage.size(); return AND_Assamblage; // break; } case 1: { //OR std::vector OR_Assamblage = this->ExtractFiberIdSubset(pfcomp->getChildAt(0)); std::vector::iterator it; MITK_DEBUG << OR_Assamblage.size(); for (int i=1; igetNumberOfChildren(); ++i) { it = OR_Assamblage.end(); std::vector tmpChild = this->ExtractFiberIdSubset(pfcomp->getChildAt(i)); OR_Assamblage.insert(it, tmpChild.begin(), tmpChild.end()); MITK_DEBUG << "ROI " << i << " has fibers in ROI: " << tmpChild.size() << " OR Assamblage: " << OR_Assamblage.size(); } sort(OR_Assamblage.begin(), OR_Assamblage.end()); it = unique(OR_Assamblage.begin(), OR_Assamblage.end()); OR_Assamblage.resize( it - OR_Assamblage.begin() ); MITK_DEBUG << "returning OR vector, size: " << OR_Assamblage.size(); return OR_Assamblage; } case 2: { //NOT //get IDs of all fibers std::vector childResults; childResults.reserve(this->GetNumFibers()); vtkSmartPointer idSet = m_FiberIdDataSet->GetCellData()->GetArray(FIBER_ID_ARRAY); MITK_DEBUG << "m_NumOfFib: " << this->GetNumFibers() << " cellIdNum: " << idSet->GetNumberOfTuples(); for(long i=0; iGetNumFibers(); i++) { MITK_DEBUG << "i: " << i << " idset: " << idSet->GetTuple(i)[0]; childResults.push_back(idSet->GetTuple(i)[0]); } std::sort(childResults.begin(), childResults.end()); std::vector NOT_Assamblage(childResults.size()); //fill it with -1, otherwise 0 will be stored and 0 can also be an ID of fiber! fill(NOT_Assamblage.begin(), NOT_Assamblage.end(), -1); std::vector::iterator it; for (long i=0; igetNumberOfChildren(); ++i) { std::vector tmpChild = ExtractFiberIdSubset(pfcomp->getChildAt(i)); sort(tmpChild.begin(), tmpChild.end()); it = std::set_difference(childResults.begin(), childResults.end(), tmpChild.begin(), tmpChild.end(), NOT_Assamblage.begin() ); } MITK_DEBUG << "resize Vector"; long i=0; while (NOT_Assamblage[i] != -1){ //-1 represents a placeholder in the array ++i; } NOT_Assamblage.resize(i); return NOT_Assamblage; } default: MITK_DEBUG << "we have an UNDEFINED composition... ERROR" ; break; } } else { mitk::Geometry2D::ConstPointer pfgeometry = pf->GetGeometry2D(); const mitk::PlaneGeometry* planeGeometry = dynamic_cast (pfgeometry.GetPointer()); Vector3D planeNormal = planeGeometry->GetNormal(); planeNormal.Normalize(); Point3D planeOrigin = planeGeometry->GetOrigin(); MITK_DEBUG << "planeOrigin: " << planeOrigin[0] << " | " << planeOrigin[1] << " | " << planeOrigin[2] << endl; MITK_DEBUG << "planeNormal: " << planeNormal[0] << " | " << planeNormal[1] << " | " << planeNormal[2] << endl; std::vector PointsOnPlane; // contains all pointIds which are crossing the cutting plane std::vector PointsInROI; // based on PointsOnPlane, all ROI relevant point IDs are stored here /* Define cutting plane by ROI (PlanarFigure) */ vtkSmartPointer plane = vtkSmartPointer::New(); plane->SetOrigin(planeOrigin[0],planeOrigin[1],planeOrigin[2]); plane->SetNormal(planeNormal[0],planeNormal[1],planeNormal[2]); /* get all points/fibers cutting the plane */ MITK_DEBUG << "start clipping"; vtkSmartPointer clipper = vtkSmartPointer::New(); - clipper->SetInput(m_FiberIdDataSet); + clipper->SetInputData(m_FiberIdDataSet); clipper->SetClipFunction(plane); clipper->GenerateClipScalarsOn(); clipper->GenerateClippedOutputOn(); vtkSmartPointer clipperout = clipper->GetClippedOutput(); MITK_DEBUG << "end clipping"; MITK_DEBUG << "init and update clipperoutput"; clipperout->GetPointData()->Initialize(); - clipperout->Update(); +// clipperout->Update(); //VTK6_TODO MITK_DEBUG << "init and update clipperoutput completed"; MITK_DEBUG << "STEP 1: find all points which have distance 0 to the given plane"; /*======STEP 1====== * extract all points, which are crossing the plane */ // Scalar values describe the distance between each remaining point to the given plane. Values sorted by point index vtkSmartPointer distanceList = clipperout->GetPointData()->GetScalars(); vtkIdType sizeOfList = distanceList->GetNumberOfTuples(); PointsOnPlane.reserve(sizeOfList); /* use reserve for high-performant push_back, no hidden copy procedures are processed then! * size of list can be optimized by reducing allocation, but be aware of iterator and vector size*/ for (int i=0; iGetTuple(i); // check if point is on plane. // 0.01 due to some approximation errors when calculating distance if (distance[0] >= -0.01 && distance[0] <= 0.01) PointsOnPlane.push_back(i); } MITK_DEBUG << "Num Of points on plane: " << PointsOnPlane.size(); MITK_DEBUG << "Step 2: extract Interesting points with respect to given extraction planarFigure"; PointsInROI.reserve(PointsOnPlane.size()); /*=======STEP 2===== * extract ROI relevant pointIds */ mitk::PlanarCircle::Pointer circleName = mitk::PlanarCircle::New(); mitk::PlanarPolygon::Pointer polyName = mitk::PlanarPolygon::New(); if ( pf->GetNameOfClass() == circleName->GetNameOfClass() ) { //calculate circle radius mitk::Point3D V1w = pf->GetWorldControlPoint(0); //centerPoint mitk::Point3D V2w = pf->GetWorldControlPoint(1); //radiusPoint double distPF = V1w.EuclideanDistanceTo(V2w); for (int i=0; iGetPoint(PointsOnPlane[i])[0] - V1w[0]) * (clipperout->GetPoint(PointsOnPlane[i])[0] - V1w[0]) + (clipperout->GetPoint(PointsOnPlane[i])[1] - V1w[1]) * (clipperout->GetPoint(PointsOnPlane[i])[1] - V1w[1]) + (clipperout->GetPoint(PointsOnPlane[i])[2] - V1w[2]) * (clipperout->GetPoint(PointsOnPlane[i])[2] - V1w[2])) ; if( XdistPnt <= distPF) PointsInROI.push_back(PointsOnPlane[i]); } } else if ( pf->GetNameOfClass() == polyName->GetNameOfClass() ) { //create vtkPolygon using controlpoints from planarFigure polygon vtkSmartPointer polygonVtk = vtkSmartPointer::New(); //get the control points from pf and insert them to vtkPolygon unsigned int nrCtrlPnts = pf->GetNumberOfControlPoints(); for (int i=0; iGetPoints()->InsertNextPoint((double)pf->GetWorldControlPoint(i)[0], (double)pf->GetWorldControlPoint(i)[1], (double)pf->GetWorldControlPoint(i)[2] ); } //prepare everything for using pointInPolygon function double n[3]; polygonVtk->ComputeNormal(polygonVtk->GetPoints()->GetNumberOfPoints(), static_cast(polygonVtk->GetPoints()->GetData()->GetVoidPointer(0)), n); double bounds[6]; polygonVtk->GetPoints()->GetBounds(bounds); for (int i=0; iGetPoint(PointsOnPlane[i])[0], clipperout->GetPoint(PointsOnPlane[i])[1], clipperout->GetPoint(PointsOnPlane[i])[2]}; int isInPolygon = polygonVtk->PointInPolygon(checkIn, polygonVtk->GetPoints()->GetNumberOfPoints() , static_cast(polygonVtk->GetPoints()->GetData()->GetVoidPointer(0)), bounds, n); if( isInPolygon ) PointsInROI.push_back(PointsOnPlane[i]); } } MITK_DEBUG << "Step3: Identify fibers"; // we need to access the fiberId Array, so make sure that this array is available if (!clipperout->GetCellData()->HasArray(FIBER_ID_ARRAY)) { MITK_DEBUG << "ERROR: FiberID array does not exist, no correlation between points and fiberIds possible! Make sure calling GenerateFiberIds()"; return FibersInROI; // FibersInRoi is empty then } if (PointsInROI.size()<=0) return FibersInROI; // prepare a structure where each point id is represented as an indexId. // vector looks like: | pntId | fiberIdx | std::vector< long > pointindexFiberMap; // walk through the whole subline section and create an vector sorted by point index vtkCellArray *clipperlines = clipperout->GetLines(); clipperlines->InitTraversal(); long numOfLineCells = clipperlines->GetNumberOfCells(); long numofClippedPoints = clipperout->GetNumberOfPoints(); pointindexFiberMap.resize(numofClippedPoints); //prepare resulting vector FibersInROI.reserve(PointsInROI.size()); MITK_DEBUG << "\n===== Pointindex based structure initialized ======\n"; // go through resulting "sub"lines which are stored as cells, "i" corresponds to current line id. for (int i=0, ic=0 ; iGetCell(ic, npts, pts); // go through point ids in hosting subline, "j" corresponds to current pointindex in current line i. eg. idx[0]=45; idx[1]=46 for (long j=0; jGetCellData()->GetArray(FIBER_ID_ARRAY)->GetTuple(i)[0] << " to pointId: " << pts[j]; pointindexFiberMap[ pts[j] ] = clipperout->GetCellData()->GetArray(FIBER_ID_ARRAY)->GetTuple(i)[0]; // MITK_DEBUG << "in array: " << pointindexFiberMap[ pts[j] ]; } } MITK_DEBUG << "\n===== Pointindex based structure finalized ======\n"; // get all Points in ROI with according fiberID for (long k = 0; k < PointsInROI.size(); k++) { //MITK_DEBUG << "point " << PointsInROI[k] << " belongs to fiber " << pointindexFiberMap[ PointsInROI[k] ]; if (pointindexFiberMap[ PointsInROI[k] ]<=GetNumFibers() && pointindexFiberMap[ PointsInROI[k] ]>=0) FibersInROI.push_back(pointindexFiberMap[ PointsInROI[k] ]); else MITK_INFO << "ERROR in ExtractFiberIdSubset; impossible fiber id detected"; } m_PointsRoi = PointsInROI; } // detecting fiberId duplicates MITK_DEBUG << "check for duplicates"; sort(FibersInROI.begin(), FibersInROI.end()); bool hasDuplicats = false; for(long i=0; i::iterator it; it = unique (FibersInROI.begin(), FibersInROI.end()); FibersInROI.resize( it - FibersInROI.begin() ); } return FibersInROI; } void mitk::FiberBundleX::UpdateFiberGeometry() { vtkSmartPointer cleaner = vtkSmartPointer::New(); - cleaner->SetInput(m_FiberPolyData); + cleaner->SetInputData(m_FiberPolyData); cleaner->PointMergingOff(); cleaner->Update(); m_FiberPolyData = cleaner->GetOutput(); m_FiberLengths.clear(); m_MeanFiberLength = 0; m_MedianFiberLength = 0; m_LengthStDev = 0; m_NumFibers = m_FiberPolyData->GetNumberOfCells(); if (m_NumFibers<=0) // no fibers present; apply default geometry { m_MinFiberLength = 0; m_MaxFiberLength = 0; mitk::Geometry3D::Pointer geometry = mitk::Geometry3D::New(); geometry->SetImageGeometry(true); float b[] = {0, 1, 0, 1, 0, 1}; geometry->SetFloatBounds(b); SetGeometry(geometry); return; } float min = itk::NumericTraits::NonpositiveMin(); float max = itk::NumericTraits::max(); float b[] = {max, min, max, min, max, min}; for (int i=0; iGetNumberOfCells(); i++) { vtkCell* cell = m_FiberPolyData->GetCell(i); int p = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); float length = 0; for (int j=0; jGetPoint(j, p1); if (p1[0]b[1]) b[1]=p1[0]; if (p1[1]b[3]) b[3]=p1[1]; if (p1[2]b[5]) b[5]=p1[2]; // calculate statistics if (jGetPoint(j+1, p2); float dist = std::sqrt((p1[0]-p2[0])*(p1[0]-p2[0])+(p1[1]-p2[1])*(p1[1]-p2[1])+(p1[2]-p2[2])*(p1[2]-p2[2])); length += dist; } } m_FiberLengths.push_back(length); m_MeanFiberLength += length; if (i==0) { m_MinFiberLength = length; m_MaxFiberLength = length; } else { if (lengthm_MaxFiberLength) m_MaxFiberLength = length; } } m_MeanFiberLength /= m_NumFibers; std::vector< float > sortedLengths = m_FiberLengths; std::sort(sortedLengths.begin(), sortedLengths.end()); for (int i=0; i1) m_LengthStDev /= (m_NumFibers-1); else m_LengthStDev = 0; m_LengthStDev = std::sqrt(m_LengthStDev); m_MedianFiberLength = sortedLengths.at(m_NumFibers/2); // provide some border margin for(int i=0; i<=4; i+=2) b[i] -=10; for(int i=1; i<=5; i+=2) b[i] +=10; mitk::Geometry3D::Pointer geometry = mitk::Geometry3D::New(); geometry->SetFloatBounds(b); this->SetGeometry(geometry); } std::vector mitk::FiberBundleX::GetAvailableColorCodings() { std::vector availableColorCodings; int numColors = m_FiberPolyData->GetPointData()->GetNumberOfArrays(); for(int i=0; iGetPointData()->GetArrayName(i)); } //this controlstructure shall be implemented by the calling method if (availableColorCodings.empty()) MITK_DEBUG << "no colorcodings available in fiberbundleX"; return availableColorCodings; } char* mitk::FiberBundleX::GetCurrentColorCoding() { return m_CurrentColorCoding; } void mitk::FiberBundleX::SetColorCoding(const char* requestedColorCoding) { if (requestedColorCoding==NULL) return; MITK_DEBUG << "SetColorCoding:" << requestedColorCoding; if( strcmp (COLORCODING_ORIENTATION_BASED,requestedColorCoding) == 0 ) { this->m_CurrentColorCoding = (char*) COLORCODING_ORIENTATION_BASED; } else if( strcmp (COLORCODING_FA_BASED,requestedColorCoding) == 0 ) { this->m_CurrentColorCoding = (char*) COLORCODING_FA_BASED; } else if( strcmp (COLORCODING_CUSTOM,requestedColorCoding) == 0 ) { this->m_CurrentColorCoding = (char*) COLORCODING_CUSTOM; } else { MITK_DEBUG << "FIBERBUNDLE X: UNKNOWN COLORCODING in FIBERBUNDLEX Datastructure"; this->m_CurrentColorCoding = (char*) COLORCODING_CUSTOM; //will cause blank colorcoding of fibers } } void mitk::FiberBundleX::RotateAroundAxis(double x, double y, double z) { MITK_INFO << "Rotating fibers"; x = x*M_PI/180; y = y*M_PI/180; z = z*M_PI/180; vnl_matrix_fixed< double, 3, 3 > rotX; rotX.set_identity(); rotX[1][1] = cos(x); rotX[2][2] = rotX[1][1]; rotX[1][2] = -sin(x); rotX[2][1] = -rotX[1][2]; vnl_matrix_fixed< double, 3, 3 > rotY; rotY.set_identity(); rotY[0][0] = cos(y); rotY[2][2] = rotY[0][0]; rotY[0][2] = sin(y); rotY[2][0] = -rotY[0][2]; vnl_matrix_fixed< double, 3, 3 > rotZ; rotZ.set_identity(); rotZ[0][0] = cos(z); rotZ[1][1] = rotZ[0][0]; rotZ[0][1] = -sin(z); rotZ[1][0] = -rotZ[0][1]; mitk::Geometry3D::Pointer geom = this->GetGeometry(); mitk::Point3D center = geom->GetCenter(); boost::progress_display disp(m_NumFibers); vtkSmartPointer vtkNewPoints = vtkSmartPointer::New(); vtkSmartPointer vtkNewCells = vtkSmartPointer::New(); for (int i=0; iGetCell(i); int numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); vtkSmartPointer container = vtkSmartPointer::New(); for (int j=0; jGetPoint(j); vnl_vector_fixed< double, 3 > dir; dir[0] = p[0]-center[0]; dir[1] = p[1]-center[1]; dir[2] = p[2]-center[2]; dir = rotZ*rotY*rotX*dir; dir[0] += center[0]; dir[1] += center[1]; dir[2] += center[2]; vtkIdType id = vtkNewPoints->InsertNextPoint(dir.data_block()); container->GetPointIds()->InsertNextId(id); } vtkNewCells->InsertNextCell(container); } m_FiberPolyData = vtkSmartPointer::New(); m_FiberPolyData->SetPoints(vtkNewPoints); m_FiberPolyData->SetLines(vtkNewCells); UpdateColorCoding(); UpdateFiberGeometry(); } void mitk::FiberBundleX::ScaleFibers(double x, double y, double z) { MITK_INFO << "Scaling fibers"; boost::progress_display disp(m_NumFibers); mitk::Geometry3D* geom = this->GetGeometry(); mitk::Point3D c = geom->GetCenter(); vtkSmartPointer vtkNewPoints = vtkSmartPointer::New(); vtkSmartPointer vtkNewCells = vtkSmartPointer::New(); for (int i=0; iGetCell(i); int numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); vtkSmartPointer container = vtkSmartPointer::New(); for (int j=0; jGetPoint(j); p[0] -= c[0]; p[1] -= c[1]; p[2] -= c[2]; p[0] *= x; p[1] *= y; p[2] *= z; p[0] += c[0]; p[1] += c[1]; p[2] += c[2]; vtkIdType id = vtkNewPoints->InsertNextPoint(p); container->GetPointIds()->InsertNextId(id); } vtkNewCells->InsertNextCell(container); } m_FiberPolyData = vtkSmartPointer::New(); m_FiberPolyData->SetPoints(vtkNewPoints); m_FiberPolyData->SetLines(vtkNewCells); UpdateColorCoding(); UpdateFiberGeometry(); } void mitk::FiberBundleX::TranslateFibers(double x, double y, double z) { MITK_INFO << "Translating fibers"; boost::progress_display disp(m_NumFibers); vtkSmartPointer vtkNewPoints = vtkSmartPointer::New(); vtkSmartPointer vtkNewCells = vtkSmartPointer::New(); for (int i=0; iGetCell(i); int numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); vtkSmartPointer container = vtkSmartPointer::New(); for (int j=0; jGetPoint(j); p[0] += x; p[1] += y; p[2] += z; vtkIdType id = vtkNewPoints->InsertNextPoint(p); container->GetPointIds()->InsertNextId(id); } vtkNewCells->InsertNextCell(container); } m_FiberPolyData = vtkSmartPointer::New(); m_FiberPolyData->SetPoints(vtkNewPoints); m_FiberPolyData->SetLines(vtkNewCells); UpdateColorCoding(); UpdateFiberGeometry(); } void mitk::FiberBundleX::MirrorFibers(unsigned int axis) { if (axis>2) return; MITK_INFO << "Mirroring fibers"; boost::progress_display disp(m_NumFibers); vtkSmartPointer vtkNewPoints = vtkSmartPointer::New(); vtkSmartPointer vtkNewCells = vtkSmartPointer::New(); for (int i=0; iGetCell(i); int numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); vtkSmartPointer container = vtkSmartPointer::New(); for (int j=0; jGetPoint(j); p[axis] = -p[axis]; vtkIdType id = vtkNewPoints->InsertNextPoint(p); container->GetPointIds()->InsertNextId(id); } vtkNewCells->InsertNextCell(container); } m_FiberPolyData = vtkSmartPointer::New(); m_FiberPolyData->SetPoints(vtkNewPoints); m_FiberPolyData->SetLines(vtkNewCells); UpdateColorCoding(); UpdateFiberGeometry(); } bool mitk::FiberBundleX::ApplyCurvatureThreshold(float minRadius, bool deleteFibers) { if (minRadius<0) return true; vtkSmartPointer vtkNewPoints = vtkSmartPointer::New(); vtkSmartPointer vtkNewCells = vtkSmartPointer::New(); MITK_INFO << "Applying curvature threshold"; boost::progress_display disp(m_FiberPolyData->GetNumberOfCells()); for (int i=0; iGetNumberOfCells(); i++) { ++disp ; vtkCell* cell = m_FiberPolyData->GetCell(i); int numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); // calculate curvatures vtkSmartPointer container = vtkSmartPointer::New(); for (int j=0; jGetPoint(j, p1); double p2[3]; points->GetPoint(j+1, p2); double p3[3]; points->GetPoint(j+2, p3); vnl_vector_fixed< float, 3 > v1, v2, v3; v1[0] = p2[0]-p1[0]; v1[1] = p2[1]-p1[1]; v1[2] = p2[2]-p1[2]; v2[0] = p3[0]-p2[0]; v2[1] = p3[1]-p2[1]; v2[2] = p3[2]-p2[2]; v3[0] = p1[0]-p3[0]; v3[1] = p1[1]-p3[1]; v3[2] = p1[2]-p3[2]; float a = v1.magnitude(); float b = v2.magnitude(); float c = v3.magnitude(); float r = a*b*c/std::sqrt((a+b+c)*(a+b-c)*(b+c-a)*(a-b+c)); // radius of triangle via Heron's formula (area of triangle) vtkIdType id = vtkNewPoints->InsertNextPoint(p1); container->GetPointIds()->InsertNextId(id); if (deleteFibers && rInsertNextCell(container); container = vtkSmartPointer::New(); } else if (j==numPoints-3) { id = vtkNewPoints->InsertNextPoint(p2); container->GetPointIds()->InsertNextId(id); id = vtkNewPoints->InsertNextPoint(p3); container->GetPointIds()->InsertNextId(id); vtkNewCells->InsertNextCell(container); } } } if (vtkNewCells->GetNumberOfCells()<=0) return false; m_FiberPolyData = vtkSmartPointer::New(); m_FiberPolyData->SetPoints(vtkNewPoints); m_FiberPolyData->SetLines(vtkNewCells); UpdateColorCoding(); UpdateFiberGeometry(); return true; } bool mitk::FiberBundleX::RemoveShortFibers(float lengthInMM) { MITK_INFO << "Removing short fibers"; if (lengthInMM<=0 || lengthInMMm_MaxFiberLength) // can't remove all fibers { MITK_WARN << "Process aborted. No fibers would be left!"; return false; } vtkSmartPointer vtkNewPoints = vtkSmartPointer::New(); vtkSmartPointer vtkNewCells = vtkSmartPointer::New(); float min = m_MaxFiberLength; boost::progress_display disp(m_NumFibers); for (int i=0; iGetCell(i); int numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); if (m_FiberLengths.at(i)>=lengthInMM) { vtkSmartPointer container = vtkSmartPointer::New(); for (int j=0; jGetPoint(j); vtkIdType id = vtkNewPoints->InsertNextPoint(p); container->GetPointIds()->InsertNextId(id); } vtkNewCells->InsertNextCell(container); if (m_FiberLengths.at(i)GetNumberOfCells()<=0) return false; m_FiberPolyData = vtkSmartPointer::New(); m_FiberPolyData->SetPoints(vtkNewPoints); m_FiberPolyData->SetLines(vtkNewCells); UpdateColorCoding(); UpdateFiberGeometry(); return true; } bool mitk::FiberBundleX::RemoveLongFibers(float lengthInMM) { if (lengthInMM<=0 || lengthInMM>m_MaxFiberLength) return true; if (lengthInMM vtkNewPoints = vtkSmartPointer::New(); vtkSmartPointer vtkNewCells = vtkSmartPointer::New(); MITK_INFO << "Removing long fibers"; boost::progress_display disp(m_NumFibers); for (int i=0; iGetCell(i); int numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); if (m_FiberLengths.at(i)<=lengthInMM) { vtkSmartPointer container = vtkSmartPointer::New(); for (int j=0; jGetPoint(j); vtkIdType id = vtkNewPoints->InsertNextPoint(p); container->GetPointIds()->InsertNextId(id); } vtkNewCells->InsertNextCell(container); } } if (vtkNewCells->GetNumberOfCells()<=0) return false; m_FiberPolyData = vtkSmartPointer::New(); m_FiberPolyData->SetPoints(vtkNewPoints); m_FiberPolyData->SetLines(vtkNewCells); UpdateColorCoding(); UpdateFiberGeometry(); return true; } void mitk::FiberBundleX::DoFiberSmoothing(float pointDistance, double tension, double continuity, double bias ) { if (pointDistance<=0) return; vtkSmartPointer vtkSmoothPoints = vtkSmartPointer::New(); //in smoothpoints the interpolated points representing a fiber are stored. //in vtkcells all polylines are stored, actually all id's of them are stored vtkSmartPointer vtkSmoothCells = vtkSmartPointer::New(); //cellcontainer for smoothed lines vtkIdType pointHelperCnt = 0; MITK_INFO << "Smoothing fibers"; boost::progress_display disp(m_NumFibers); for (int i=0; iGetCell(i); int numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); vtkSmartPointer newPoints = vtkSmartPointer::New(); for (int j=0; jInsertNextPoint(points->GetPoint(j)); float length = m_FiberLengths.at(i); int sampling = std::ceil(length/pointDistance); vtkSmartPointer xSpline = vtkSmartPointer::New(); vtkSmartPointer ySpline = vtkSmartPointer::New(); vtkSmartPointer zSpline = vtkSmartPointer::New(); xSpline->SetDefaultBias(bias); xSpline->SetDefaultTension(tension); xSpline->SetDefaultContinuity(continuity); ySpline->SetDefaultBias(bias); ySpline->SetDefaultTension(tension); ySpline->SetDefaultContinuity(continuity); zSpline->SetDefaultBias(bias); zSpline->SetDefaultTension(tension); zSpline->SetDefaultContinuity(continuity); vtkSmartPointer spline = vtkSmartPointer::New(); spline->SetXSpline(xSpline); spline->SetYSpline(ySpline); spline->SetZSpline(zSpline); spline->SetPoints(newPoints); vtkSmartPointer functionSource = vtkSmartPointer::New(); functionSource->SetParametricFunction(spline); functionSource->SetUResolution(sampling); functionSource->SetVResolution(sampling); functionSource->SetWResolution(sampling); functionSource->Update(); vtkPolyData* outputFunction = functionSource->GetOutput(); vtkPoints* tmpSmoothPnts = outputFunction->GetPoints(); //smoothPoints of current fiber vtkSmartPointer smoothLine = vtkSmartPointer::New(); smoothLine->GetPointIds()->SetNumberOfIds(tmpSmoothPnts->GetNumberOfPoints()); for (int j=0; jGetNumberOfPoints(); j++) { smoothLine->GetPointIds()->SetId(j, j+pointHelperCnt); vtkSmoothPoints->InsertNextPoint(tmpSmoothPnts->GetPoint(j)); } vtkSmoothCells->InsertNextCell(smoothLine); pointHelperCnt += tmpSmoothPnts->GetNumberOfPoints(); } m_FiberPolyData = vtkSmartPointer::New(); m_FiberPolyData->SetPoints(vtkSmoothPoints); m_FiberPolyData->SetLines(vtkSmoothCells); UpdateColorCoding(); UpdateFiberGeometry(); m_FiberSampling = 10/pointDistance; } void mitk::FiberBundleX::DoFiberSmoothing(float pointDistance) { DoFiberSmoothing(pointDistance, 0, 0, 0 ); } // Resample fiber to get equidistant points void mitk::FiberBundleX::ResampleFibers(float pointDistance) { if (pointDistance<=0.00001) return; vtkSmartPointer newPoly = vtkSmartPointer::New(); vtkSmartPointer newCellArray = vtkSmartPointer::New(); vtkSmartPointer newPoints = vtkSmartPointer::New(); int numberOfLines = m_NumFibers; MITK_INFO << "Resampling fibers"; boost::progress_display disp(m_NumFibers); for (int i=0; iGetCell(i); int numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); vtkSmartPointer container = vtkSmartPointer::New(); double* point = points->GetPoint(0); vtkIdType pointId = newPoints->InsertNextPoint(point); container->GetPointIds()->InsertNextId(pointId); float dtau = 0; int cur_p = 1; itk::Vector dR; float normdR = 0; for (;;) { while (dtau <= pointDistance && cur_p < numPoints) { itk::Vector v1; point = points->GetPoint(cur_p-1); v1[0] = point[0]; v1[1] = point[1]; v1[2] = point[2]; itk::Vector v2; point = points->GetPoint(cur_p); v2[0] = point[0]; v2[1] = point[1]; v2[2] = point[2]; dR = v2 - v1; normdR = std::sqrt(dR.GetSquaredNorm()); dtau += normdR; cur_p++; } if (dtau >= pointDistance) { itk::Vector v1; point = points->GetPoint(cur_p-1); v1[0] = point[0]; v1[1] = point[1]; v1[2] = point[2]; itk::Vector v2 = v1 - dR*( (dtau-pointDistance)/normdR ); pointId = newPoints->InsertNextPoint(v2.GetDataPointer()); container->GetPointIds()->InsertNextId(pointId); } else { point = points->GetPoint(numPoints-1); pointId = newPoints->InsertNextPoint(point); container->GetPointIds()->InsertNextId(pointId); break; } dtau = dtau-pointDistance; } newCellArray->InsertNextCell(container); } newPoly->SetPoints(newPoints); newPoly->SetLines(newCellArray); m_FiberPolyData = newPoly; UpdateFiberGeometry(); UpdateColorCoding(); m_FiberSampling = 10/pointDistance; } // reapply selected colorcoding in case polydata structure has changed void mitk::FiberBundleX::UpdateColorCoding() { char* cc = GetCurrentColorCoding(); if( strcmp (COLORCODING_ORIENTATION_BASED,cc) == 0 ) DoColorCodingOrientationBased(); else if( strcmp (COLORCODING_FA_BASED,cc) == 0 ) DoColorCodingFaBased(); } // reapply selected colorcoding in case polydata structure has changed bool mitk::FiberBundleX::Equals(mitk::FiberBundleX* fib) { if (fib==NULL) return false; mitk::FiberBundleX::Pointer tempFib = this->SubtractBundle(fib); mitk::FiberBundleX::Pointer tempFib2 = fib->SubtractBundle(this); if (tempFib.IsNull() && tempFib2.IsNull()) return true; return false; } /* ESSENTIAL IMPLEMENTATION OF SUPERCLASS METHODS */ void mitk::FiberBundleX::UpdateOutputInformation() { } void mitk::FiberBundleX::SetRequestedRegionToLargestPossibleRegion() { } bool mitk::FiberBundleX::RequestedRegionIsOutsideOfTheBufferedRegion() { return false; } bool mitk::FiberBundleX::VerifyRequestedRegion() { return true; } void mitk::FiberBundleX::SetRequestedRegion(const itk::DataObject *data ) { } diff --git a/Modules/DiffusionImaging/FiberTracking/IODataStructures/FiberBundleX/mitkFiberBundleXReader.cpp b/Modules/DiffusionImaging/FiberTracking/IODataStructures/FiberBundleX/mitkFiberBundleXReader.cpp index 749c4f70f8..a8de912a66 100644 --- a/Modules/DiffusionImaging/FiberTracking/IODataStructures/FiberBundleX/mitkFiberBundleXReader.cpp +++ b/Modules/DiffusionImaging/FiberTracking/IODataStructures/FiberBundleX/mitkFiberBundleXReader.cpp @@ -1,302 +1,302 @@ /*=================================================================== 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 "mitkFiberBundleXReader.h" #include #include #include #include #include #include #include #include #include #include #include namespace mitk { void FiberBundleXReader ::GenerateData() { if ( ( ! m_OutputCache ) ) { Superclass::SetNumberOfRequiredOutputs(0); this->GenerateOutputInformation(); } if (!m_OutputCache) { itkWarningMacro("Output cache is empty!"); } Superclass::SetNumberOfRequiredOutputs(1); Superclass::SetNthOutput(0, m_OutputCache.GetPointer()); } void FiberBundleXReader::GenerateOutputInformation() { try { const std::string& locale = "C"; const std::string& currLocale = setlocale( LC_ALL, NULL ); setlocale(LC_ALL, locale.c_str()); std::string ext = itksys::SystemTools::GetFilenameLastExtension(m_FileName); ext = itksys::SystemTools::LowerCase(ext); if (ext==".trk") { MITK_INFO << "Importing fiber bundle from TrackVis ..."; m_OutputCache = OutputType::New(); TrackVis trk; trk.open(m_FileName); trk.read(m_OutputCache); MITK_INFO << "... done"; return; } vtkSmartPointer chooser=vtkSmartPointer::New(); chooser->SetFileName(m_FileName.c_str() ); if( chooser->IsFilePolyData()) { MITK_INFO << "Reading vtk fiber bundle"; vtkSmartPointer reader = vtkSmartPointer::New(); reader->SetFileName( m_FileName.c_str() ); reader->Update(); if ( reader->GetOutput() != NULL ) { vtkSmartPointer fiberPolyData = reader->GetOutput(); m_OutputCache = OutputType::New(fiberPolyData); } } else // try to read deprecated fiber bundle file format { MITK_INFO << "Reading xml fiber bundle"; vtkSmartPointer fiberPolyData = vtkSmartPointer::New(); vtkSmartPointer cellArray = vtkSmartPointer::New(); vtkSmartPointer points = vtkSmartPointer::New(); TiXmlDocument doc( m_FileName ); if(doc.LoadFile()) { TiXmlHandle hDoc(&doc); TiXmlElement* pElem; TiXmlHandle hRoot(0); pElem = hDoc.FirstChildElement().Element(); // save this for later hRoot = TiXmlHandle(pElem); pElem = hRoot.FirstChildElement("geometry").Element(); // read geometry mitk::Geometry3D::Pointer geometry = mitk::Geometry3D::New(); // read origin mitk::Point3D origin; double temp = 0; pElem->Attribute("origin_x", &temp); origin[0] = temp; pElem->Attribute("origin_y", &temp); origin[1] = temp; pElem->Attribute("origin_z", &temp); origin[2] = temp; geometry->SetOrigin(origin); // read spacing float spacing[3]; pElem->Attribute("spacing_x", &temp); spacing[0] = temp; pElem->Attribute("spacing_y", &temp); spacing[1] = temp; pElem->Attribute("spacing_z", &temp); spacing[2] = temp; geometry->SetSpacing(spacing); // read transform vtkMatrix4x4* m = vtkMatrix4x4::New(); pElem->Attribute("xx", &temp); m->SetElement(0,0,temp); pElem->Attribute("xy", &temp); m->SetElement(1,0,temp); pElem->Attribute("xz", &temp); m->SetElement(2,0,temp); pElem->Attribute("yx", &temp); m->SetElement(0,1,temp); pElem->Attribute("yy", &temp); m->SetElement(1,1,temp); pElem->Attribute("yz", &temp); m->SetElement(2,1,temp); pElem->Attribute("zx", &temp); m->SetElement(0,2,temp); pElem->Attribute("zy", &temp); m->SetElement(1,2,temp); pElem->Attribute("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); // read bounds float bounds[] = {0, 0, 0, 0, 0, 0}; pElem->Attribute("size_x", &temp); bounds[1] = temp; pElem->Attribute("size_y", &temp); bounds[3] = temp; pElem->Attribute("size_z", &temp); bounds[5] = temp; geometry->SetFloatBounds(bounds); geometry->SetImageGeometry(true); pElem = hRoot.FirstChildElement("fiber_bundle").FirstChild().Element(); for( pElem; pElem; pElem=pElem->NextSiblingElement()) { TiXmlElement* pElem2 = pElem->FirstChildElement(); vtkSmartPointer container = vtkSmartPointer::New(); for( pElem2; pElem2; pElem2=pElem2->NextSiblingElement()) { itk::Point point; pElem2->Attribute("pos_x", &temp); point[0] = temp; pElem2->Attribute("pos_y", &temp); point[1] = temp; pElem2->Attribute("pos_z", &temp); point[2] = temp; geometry->IndexToWorld(point, point); vtkIdType id = points->InsertNextPoint(point.GetDataPointer()); container->GetPointIds()->InsertNextId(id); } cellArray->InsertNextCell(container); } fiberPolyData->SetPoints(points); fiberPolyData->SetLines(cellArray); vtkSmartPointer cleaner = vtkSmartPointer::New(); - cleaner->SetInput(fiberPolyData); + cleaner->SetInputData(fiberPolyData); cleaner->Update(); fiberPolyData = cleaner->GetOutput(); m_OutputCache = OutputType::New(fiberPolyData); } else { MITK_INFO << "could not open xml file"; throw "could not open xml file"; } } setlocale(LC_ALL, currLocale.c_str()); MITK_INFO << "Fiber bundle read"; } catch(...) { throw; } } void FiberBundleXReader::Update() { this->GenerateData(); } const char* FiberBundleXReader ::GetFileName() const { return m_FileName.c_str(); } void FiberBundleXReader ::SetFileName(const char* aFileName) { m_FileName = aFileName; } const char* FiberBundleXReader ::GetFilePrefix() const { return m_FilePrefix.c_str(); } void FiberBundleXReader ::SetFilePrefix(const char* aFilePrefix) { m_FilePrefix = aFilePrefix; } const char* FiberBundleXReader ::GetFilePattern() const { return m_FilePattern.c_str(); } void FiberBundleXReader ::SetFilePattern(const char* aFilePattern) { m_FilePattern = aFilePattern; } bool FiberBundleXReader ::CanReadFile(const std::string filename, const std::string /*filePrefix*/, const std::string /*filePattern*/) { // First check the extension if( filename == "" ) { return false; } std::string ext = itksys::SystemTools::GetFilenameLastExtension(filename); ext = itksys::SystemTools::LowerCase(ext); if (ext == ".fib" || ext == ".trk") { return true; } return false; } BaseDataSource::DataObjectPointer FiberBundleXReader::MakeOutput(const DataObjectIdentifierType &name) { itkDebugMacro("MakeOutput(" << name << ")"); if( this->IsIndexedOutputName(name) ) { return this->MakeOutput( this->MakeIndexFromOutputName(name) ); } return static_cast(OutputType::New().GetPointer()); } BaseDataSource::DataObjectPointer FiberBundleXReader::MakeOutput(DataObjectPointerArraySizeType /*idx*/) { return OutputType::New().GetPointer(); } } //namespace MITK diff --git a/Modules/DiffusionImaging/FiberTracking/IODataStructures/FiberBundleX/mitkFiberBundleXWriter.cpp b/Modules/DiffusionImaging/FiberTracking/IODataStructures/FiberBundleX/mitkFiberBundleXWriter.cpp index 60b1d0dc4b..0435c576a5 100644 --- a/Modules/DiffusionImaging/FiberTracking/IODataStructures/FiberBundleX/mitkFiberBundleXWriter.cpp +++ b/Modules/DiffusionImaging/FiberTracking/IODataStructures/FiberBundleX/mitkFiberBundleXWriter.cpp @@ -1,139 +1,139 @@ /*=================================================================== 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 "mitkFiberBundleXWriter.h" #include #include #include #include #include mitk::FiberBundleXWriter::FiberBundleXWriter() : m_FileName(""), m_FilePrefix(""), m_FilePattern(""), m_Success(false) { this->SetNumberOfRequiredInputs( 1 ); } mitk::FiberBundleXWriter::~FiberBundleXWriter() {} void mitk::FiberBundleXWriter::GenerateData() { try { const std::string& locale = "C"; const std::string& currLocale = setlocale( LC_ALL, NULL ); setlocale(LC_ALL, locale.c_str()); m_Success = false; InputType* input = this->GetInput(); if (input == NULL) { itkWarningMacro(<<"Sorry, input to FiberBundleXWriter is NULL!"); return; } else if ( m_FileName == "" ) { itkWarningMacro( << "Sorry, filename has not been set!" ); return ; } std::string ext = itksys::SystemTools::GetFilenameLastExtension(m_FileName); if (ext==".fib" || ext==".vtk") { MITK_INFO << "Writing fiber bundle as binary VTK"; vtkSmartPointer writer = vtkSmartPointer::New(); - writer->SetInput(input->GetFiberPolyData()); + writer->SetInputData(input->GetFiberPolyData()); writer->SetFileName(m_FileName.c_str()); writer->SetFileTypeToBinary(); writer->Write(); } else if (ext==".afib") { itksys::SystemTools::ReplaceString(m_FileName,".afib",".fib"); MITK_INFO << "Writing fiber bundle as ascii VTK"; vtkSmartPointer writer = vtkSmartPointer::New(); - writer->SetInput(input->GetFiberPolyData()); + writer->SetInputData(input->GetFiberPolyData()); writer->SetFileName(m_FileName.c_str()); writer->SetFileTypeToASCII(); writer->Write(); } else if (ext==".avtk") { itksys::SystemTools::ReplaceString(m_FileName,".avtk",".vtk"); MITK_INFO << "Writing fiber bundle as ascii VTK"; vtkSmartPointer writer = vtkSmartPointer::New(); - writer->SetInput(input->GetFiberPolyData()); + writer->SetInputData(input->GetFiberPolyData()); writer->SetFileName(m_FileName.c_str()); writer->SetFileTypeToASCII(); writer->Write(); } else if (ext==".trk") { MITK_INFO << "Writing fiber bundle as TRK"; TrackVis trk; itk::Size<3> size; size.SetElement(0,input->GetGeometry()->GetExtent(0)); size.SetElement(1,input->GetGeometry()->GetExtent(1)); size.SetElement(2,input->GetGeometry()->GetExtent(2)); trk.create(m_FileName,size,input->GetGeometry()->GetOrigin()); trk.writeHdr(); trk.append(input); } setlocale(LC_ALL, currLocale.c_str()); m_Success = true; MITK_INFO << "Fiber bundle written"; } catch(...) { throw; } } void mitk::FiberBundleXWriter::SetInputFiberBundleX( InputType* diffVolumes ) { this->ProcessObject::SetNthInput( 0, diffVolumes ); } mitk::FiberBundleX* mitk::FiberBundleXWriter::GetInput() { if ( this->GetNumberOfInputs() < 1 ) { return NULL; } else { return dynamic_cast ( this->ProcessObject::GetInput( 0 ) ); } } std::vector mitk::FiberBundleXWriter::GetPossibleFileExtensions() { std::vector possibleFileExtensions; possibleFileExtensions.push_back(".fib"); possibleFileExtensions.push_back(".afib"); possibleFileExtensions.push_back(".vtk"); possibleFileExtensions.push_back(".avtk"); possibleFileExtensions.push_back(".trk"); return possibleFileExtensions; } diff --git a/Modules/DiffusionImaging/FiberTracking/Rendering/mitkFiberBundleXMapper2D.cpp b/Modules/DiffusionImaging/FiberTracking/Rendering/mitkFiberBundleXMapper2D.cpp index d69195196f..96e5537a1d 100644 --- a/Modules/DiffusionImaging/FiberTracking/Rendering/mitkFiberBundleXMapper2D.cpp +++ b/Modules/DiffusionImaging/FiberTracking/Rendering/mitkFiberBundleXMapper2D.cpp @@ -1,248 +1,248 @@ /*=================================================================== 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. ===================================================================*/ /* * mitkFiberBundleMapper2D.cpp * mitk-all * * Created by HAL9000 on 1/17/11. * Copyright 2011 __MyCompanyName__. All rights reserved. * */ #include "mitkFiberBundleXMapper2D.h" #include #include #include #include #include //#include //#include #include #include #include #include #include #include #include #include //#include #include #include #include #include #include mitk::FiberBundleXMapper2D::FiberBundleXMapper2D() { m_lut = vtkLookupTable::New(); m_lut->Build(); } mitk::FiberBundleXMapper2D::~FiberBundleXMapper2D() { } mitk::FiberBundleX* mitk::FiberBundleXMapper2D::GetInput() { return dynamic_cast< mitk::FiberBundleX * > ( GetDataNode()->GetData() ); } void mitk::FiberBundleXMapper2D::Update(mitk::BaseRenderer * renderer) { bool visible = true; GetDataNode()->GetVisibility(visible, renderer, "visible"); if ( !visible ) return; MITK_DEBUG << "MapperFBX 2D update: "; // Calculate time step of the input data for the specified renderer (integer value) // this method is implemented in mitkMapper this->CalculateTimeStep( renderer ); //check if updates occured in the node or on the display FBXLocalStorage *localStorage = m_LSH.GetLocalStorage(renderer); const DataNode *node = this->GetDataNode(); if ( (localStorage->m_LastUpdateTime < node->GetMTime()) || (localStorage->m_LastUpdateTime < node->GetPropertyList()->GetMTime()) //was a property modified? || (localStorage->m_LastUpdateTime < node->GetPropertyList(renderer)->GetMTime()) ) { // MITK_INFO << "UPDATE NEEDED FOR _ " << renderer->GetName(); this->GenerateDataForRenderer( renderer ); } if ((localStorage->m_LastUpdateTime < renderer->GetDisplayGeometry()->GetMTime()) ) //was the display geometry modified? e.g. zooming, panning) { this->UpdateShaderParameter(renderer); } } void mitk::FiberBundleXMapper2D::UpdateShaderParameter(mitk::BaseRenderer * renderer) { FBXLocalStorage *localStorage = m_LSH.GetLocalStorage(renderer); //get information about current position of views mitk::SliceNavigationController::Pointer sliceContr = renderer->GetSliceNavigationController(); mitk::PlaneGeometry::ConstPointer planeGeo = sliceContr->GetCurrentPlaneGeometry(); //generate according cutting planes based on the view position float sliceN[3], planeOrigin[3]; // since shader uses camera coordinates, transform origin and normal from worldcoordinates to cameracoordinates planeOrigin[0] = (float) planeGeo->GetOrigin()[0]; planeOrigin[1] = (float) planeGeo->GetOrigin()[1]; planeOrigin[2] = (float) planeGeo->GetOrigin()[2]; sliceN[0] = planeGeo->GetNormal()[0]; sliceN[1] = planeGeo->GetNormal()[1]; sliceN[2] = planeGeo->GetNormal()[2]; float tmp1 = planeOrigin[0] * sliceN[0]; float tmp2 = planeOrigin[1] * sliceN[1]; float tmp3 = planeOrigin[2] * sliceN[2]; float d1 = tmp1 + tmp2 + tmp3; //attention, correct normalvector float plane1[4]; plane1[0] = sliceN[0]; plane1[1] = sliceN[1]; plane1[2] = sliceN[2]; plane1[3] = d1; float thickness = 2.0; if(!this->GetDataNode()->GetPropertyValue("Fiber2DSliceThickness",thickness)) MITK_INFO << "FIBER2D SLICE THICKNESS PROPERTY ERROR"; bool fiberfading = false; if(!this->GetDataNode()->GetPropertyValue("Fiber2DfadeEFX",fiberfading)) MITK_INFO << "FIBER2D SLICE FADE EFX PROPERTY ERROR"; int fiberfading_i = 1; if (!fiberfading) fiberfading_i = 0; // set Opacity float fiberOpacity; this->GetDataNode()->GetOpacity(fiberOpacity, NULL); localStorage->m_PointActor->GetProperty()->AddShaderVariable("slicingPlane",4, plane1); localStorage->m_PointActor->GetProperty()->AddShaderVariable("fiberThickness",1, &thickness); localStorage->m_PointActor->GetProperty()->AddShaderVariable("fiberFadingON",1, &fiberfading_i); localStorage->m_PointActor->GetProperty()->AddShaderVariable("fiberOpacity", 1, &fiberOpacity); } // ALL RAW DATA FOR VISUALIZATION IS GENERATED HERE. // vtkActors and Mappers are feeded here void mitk::FiberBundleXMapper2D::GenerateDataForRenderer(mitk::BaseRenderer *renderer) { //the handler of local storage gets feeded in this method with requested data for related renderwindow FBXLocalStorage *localStorage = m_LSH.GetLocalStorage(renderer); //this procedure is depricated, //not needed after initializaton anymore mitk::DataNode* node = this->GetDataNode(); if ( node == NULL ) return; ///THIS GET INPUT mitk::FiberBundleX* fbx = this->GetInput(); localStorage->m_PointMapper->ScalarVisibilityOn(); localStorage->m_PointMapper->SetScalarModeToUsePointFieldData(); localStorage->m_PointMapper->SetLookupTable(m_lut); //apply the properties after the slice was set localStorage->m_PointActor->GetProperty()->SetOpacity(0.999); // set color if (fbx->GetCurrentColorCoding() != NULL){ // localStorage->m_PointMapper->SelectColorArray(""); localStorage->m_PointMapper->SelectColorArray(fbx->GetCurrentColorCoding()); MITK_DEBUG << "MapperFBX 2D: " << fbx->GetCurrentColorCoding(); if(fbx->GetCurrentColorCoding() == fbx->COLORCODING_CUSTOM){ float temprgb[3]; this->GetDataNode()->GetColor( temprgb, NULL ); double trgb[3] = { (double) temprgb[0], (double) temprgb[1], (double) temprgb[2] }; localStorage->m_PointActor->GetProperty()->SetColor(trgb); } } int lineWidth = 1; node->GetIntProperty("LineWidth",lineWidth); - localStorage->m_PointMapper->SetInput(fbx->GetFiberPolyData()); + localStorage->m_PointMapper->SetInputData(fbx->GetFiberPolyData()); localStorage->m_PointActor->SetMapper(localStorage->m_PointMapper); localStorage->m_PointActor->GetProperty()->ShadingOn(); localStorage->m_PointActor->GetProperty()->SetLineWidth(lineWidth); // Applying shading properties CoreServicePointer shaderRepo(CoreServices::GetShaderRepository()); shaderRepo->ApplyProperties(this->GetDataNode(),localStorage->m_PointActor,renderer, localStorage->m_LastUpdateTime); this->UpdateShaderParameter(renderer); // We have been modified => save this for next Update() localStorage->m_LastUpdateTime.Modified(); } vtkProp* mitk::FiberBundleXMapper2D::GetVtkProp(mitk::BaseRenderer *renderer) { //MITK_INFO << "FiberBundleMapper2D GetVtkProp(renderer)"; this->Update(renderer); return m_LSH.GetLocalStorage(renderer)->m_PointActor; } void mitk::FiberBundleXMapper2D::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite) { //add shader to datano node->SetProperty("shader",mitk::ShaderProperty::New("mitkShaderFiberClipping")); CoreServicePointer shaderRepo(CoreServices::GetShaderRepository()); shaderRepo->AddDefaultProperties(node,renderer,overwrite); //add other parameters to propertylist node->AddProperty( "Fiber2DSliceThickness", mitk::FloatProperty::New(2.0f), renderer, overwrite ); node->AddProperty( "Fiber2DfadeEFX", mitk::BoolProperty::New(true), renderer, overwrite ); Superclass::SetDefaultProperties(node, renderer, overwrite); } mitk::FiberBundleXMapper2D::FBXLocalStorage::FBXLocalStorage() { m_PointActor = vtkSmartPointer::New(); m_PointMapper = vtkSmartPointer::New(); } diff --git a/Modules/DiffusionImaging/FiberTracking/Rendering/mitkFiberBundleXMapper3D.cpp b/Modules/DiffusionImaging/FiberTracking/Rendering/mitkFiberBundleXMapper3D.cpp index ac73b86c33..8dae9ba932 100644 --- a/Modules/DiffusionImaging/FiberTracking/Rendering/mitkFiberBundleXMapper3D.cpp +++ b/Modules/DiffusionImaging/FiberTracking/Rendering/mitkFiberBundleXMapper3D.cpp @@ -1,191 +1,191 @@ /*=================================================================== 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 "mitkFiberBundleXMapper3D.h" #include //#include //#include #include #include #include #include //not essential for mapper // #include mitk::FiberBundleXMapper3D::FiberBundleXMapper3D() { m_lut = vtkLookupTable::New(); m_lut->Build(); } mitk::FiberBundleXMapper3D::~FiberBundleXMapper3D() { } const mitk::FiberBundleX* mitk::FiberBundleXMapper3D::GetInput() { return static_cast ( GetDataNode()->GetData() ); } /* This method is called once the mapper gets new input, for UI rotation or changes in colorcoding this method is NOT called */ void mitk::FiberBundleXMapper3D::GenerateData(mitk::BaseRenderer *renderer) { mitk::FiberBundleX* FBX = dynamic_cast (GetDataNode()->GetData()); if (FBX == NULL) return; vtkSmartPointer FiberData = FBX->GetFiberPolyData(); if (FiberData == NULL) return; FBXLocalStorage3D *localStorage = m_LSH.GetLocalStorage(renderer); - localStorage->m_FiberMapper->SetInput(FiberData); + localStorage->m_FiberMapper->SetInputData(FiberData); if ( FiberData->GetPointData()->GetNumberOfArrays() > 0 ) localStorage->m_FiberMapper->SelectColorArray( FBX->GetCurrentColorCoding() ); localStorage->m_FiberMapper->ScalarVisibilityOn(); localStorage->m_FiberMapper->SetScalarModeToUsePointFieldData(); localStorage->m_FiberActor->SetMapper(localStorage->m_FiberMapper); localStorage->m_FiberMapper->SetLookupTable(m_lut); // set Opacity float tmpopa; this->GetDataNode()->GetOpacity(tmpopa, NULL); localStorage->m_FiberActor->GetProperty()->SetOpacity((double) tmpopa); int lineWidth = 1; this->GetDataNode()->GetIntProperty("LineWidth",lineWidth); localStorage->m_FiberActor->GetProperty()->SetLineWidth(lineWidth); // set color if (FBX->GetCurrentColorCoding() != NULL){ // localStorage->m_FiberMapper->SelectColorArray(""); localStorage->m_FiberMapper->SelectColorArray(FBX->GetCurrentColorCoding()); MITK_DEBUG << "MapperFBX: " << FBX->GetCurrentColorCoding(); if(FBX->GetCurrentColorCoding() == FBX->COLORCODING_CUSTOM) { float temprgb[3]; this->GetDataNode()->GetColor( temprgb, NULL ); double trgb[3] = { (double) temprgb[0], (double) temprgb[1], (double) temprgb[2] }; localStorage->m_FiberActor->GetProperty()->SetColor(trgb); } } localStorage->m_FiberAssembly->AddPart(localStorage->m_FiberActor); localStorage->m_LastUpdateTime.Modified(); //since this method is called after generating all necessary data for fiber visualization, all modifications are represented so far. } void mitk::FiberBundleXMapper3D::GenerateDataForRenderer( mitk::BaseRenderer *renderer ) { bool visible = true; GetDataNode()->GetVisibility(visible, renderer, "visible"); if ( !visible ) return; // Calculate time step of the input data for the specified renderer (integer value) // this method is implemented in mitkMapper this->CalculateTimeStep( renderer ); //check if updates occured in the node or on the display FBXLocalStorage3D *localStorage = m_LSH.GetLocalStorage(renderer); const DataNode *node = this->GetDataNode(); if ( (localStorage->m_LastUpdateTime < node->GetMTime()) || (localStorage->m_LastUpdateTime < node->GetPropertyList()->GetMTime()) //was a property modified? || (localStorage->m_LastUpdateTime < node->GetPropertyList(renderer)->GetMTime()) ) { MITK_DEBUG << "UPDATE NEEDED FOR _ " << renderer->GetName(); this->GenerateData(renderer); } } void mitk::FiberBundleXMapper3D::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite) { // MITK_INFO << "FiberBundleXxXXMapper3D()SetDefaultProperties"; //MITK_INFO << "FiberBundleMapperX3D SetDefault Properties(...)"; // node->AddProperty( "DisplayChannel", mitk::IntProperty::New( true ), renderer, overwrite ); node->AddProperty( "LineWidth", mitk::IntProperty::New( true ), renderer, overwrite ); node->AddProperty( "opacity", mitk::FloatProperty::New( 1.0 ), renderer, overwrite); // node->AddProperty( "VertexOpacity_1", mitk::BoolProperty::New( false ), renderer, overwrite); // node->AddProperty( "Set_FA_VertexAlpha", mitk::BoolProperty::New( false ), renderer, overwrite); // node->AddProperty( "pointSize", mitk::FloatProperty::New(0.5), renderer, overwrite); // node->AddProperty( "setShading", mitk::IntProperty::New(1), renderer, overwrite); // node->AddProperty( "Xmove", mitk::IntProperty::New( 0 ), renderer, overwrite); // node->AddProperty( "Ymove", mitk::IntProperty::New( 0 ), renderer, overwrite); // node->AddProperty( "Zmove", mitk::IntProperty::New( 0 ), renderer, overwrite); // node->AddProperty( "RepPoints", mitk::BoolProperty::New( false ), renderer, overwrite); // node->AddProperty( "TubeSides", mitk::IntProperty::New( 8 ), renderer, overwrite); // node->AddProperty( "TubeRadius", mitk::FloatProperty::New( 0.15 ), renderer, overwrite); // node->AddProperty( "TubeOpacity", mitk::FloatProperty::New( 1.0 ), renderer, overwrite); node->AddProperty( "pickable", mitk::BoolProperty::New( true ), renderer, overwrite); Superclass::SetDefaultProperties(node, renderer, overwrite); } vtkProp* mitk::FiberBundleXMapper3D::GetVtkProp(mitk::BaseRenderer *renderer) { //MITK_INFO << "FiberBundleXxXXMapper3D()GetVTKProp"; //this->GenerateData(); return m_LSH.GetLocalStorage(renderer)->m_FiberAssembly; } void mitk::FiberBundleXMapper3D::ApplyProperties(mitk::BaseRenderer* renderer) { } void mitk::FiberBundleXMapper3D::UpdateVtkObjects() { } void mitk::FiberBundleXMapper3D::SetVtkMapperImmediateModeRendering(vtkMapper *) { } mitk::FiberBundleXMapper3D::FBXLocalStorage3D::FBXLocalStorage3D() { m_FiberActor = vtkSmartPointer::New(); m_FiberMapper = vtkSmartPointer::New(); m_FiberAssembly = vtkSmartPointer::New(); } diff --git a/Modules/MitkExt/Rendering/mitkGPUVolumeMapper3D.cpp b/Modules/MitkExt/Rendering/mitkGPUVolumeMapper3D.cpp index 5e766956b9..18be376462 100644 --- a/Modules/MitkExt/Rendering/mitkGPUVolumeMapper3D.cpp +++ b/Modules/MitkExt/Rendering/mitkGPUVolumeMapper3D.cpp @@ -1,712 +1,713 @@ /*=================================================================== 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. ===================================================================*/ #define GPU_INFO MITK_INFO("mapper.vr") #define GPU_WARN MITK_WARN("mapper.vr") #define GPU_ERROR MITK_ERROR("mapper.vr") #include "mitkGPUVolumeMapper3D.h" #include "mitkDataNode.h" #include "mitkProperties.h" #include "mitkLevelWindow.h" #include "mitkColorProperty.h" #include "mitkLevelWindowProperty.h" #include "mitkLookupTableProperty.h" #include "mitkTransferFunctionProperty.h" #include "mitkTransferFunctionInitializer.h" #include "mitkColorProperty.h" #include "mitkVtkPropRenderer.h" #include "mitkRenderingManager.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include + // Only with VTK 5.6 or above #if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION==5) && (VTK_MINOR_VERSION>=6) )) #include "vtkMitkGPUVolumeRayCastMapper.h" #endif #include "vtkOpenGLGPUVolumeRayCastMapper.h" #include "vtkMitkOpenGLVolumeTextureMapper3D.h" const mitk::Image* mitk::GPUVolumeMapper3D::GetInput() { return static_cast ( GetDataNode()->GetData() ); } void mitk::GPUVolumeMapper3D::MitkRenderVolumetricGeometry(mitk::BaseRenderer* renderer) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); VtkMapper::MitkRenderVolumetricGeometry(renderer); if(ls->m_gpuInitialized) ls->m_MapperGPU->UpdateMTime(); } bool mitk::GPUVolumeMapper3D::InitGPU(mitk::BaseRenderer* renderer) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); if(ls->m_gpuInitialized) return ls->m_gpuSupported; ls->m_VtkRenderWindow = renderer->GetVtkRenderer()->GetRenderWindow(); GPU_INFO << "initializing gpu-slicing-vr (vtkMitkOpenGLVolumeTextureMapper3D)"; ls->m_MapperGPU = vtkSmartPointer::New(); ls->m_MapperGPU->SetUseCompressedTexture(false); ls->m_MapperGPU->SetSampleDistance(1.0); ls->m_VolumePropertyGPU = vtkSmartPointer::New(); ls->m_VolumePropertyGPU->ShadeOn(); ls->m_VolumePropertyGPU->SetAmbient (0.25f); //0.05f ls->m_VolumePropertyGPU->SetDiffuse (0.50f); //0.45f ls->m_VolumePropertyGPU->SetSpecular(0.40f); //0.50f ls->m_VolumePropertyGPU->SetSpecularPower(16.0f); ls->m_VolumePropertyGPU->SetInterpolationTypeToLinear(); ls->m_VolumeGPU = vtkSmartPointer::New(); ls->m_VolumeGPU->SetMapper( ls->m_MapperGPU ); ls->m_VolumeGPU->SetProperty( ls->m_VolumePropertyGPU ); ls->m_VolumeGPU->VisibilityOn(); ls->m_MapperGPU->SetInputData( this->m_UnitSpacingImageFilter->GetOutput() ); ls->m_gpuSupported = ls->m_MapperGPU->IsRenderSupported(renderer->GetVtkRenderer(),ls->m_VolumePropertyGPU); ls->m_gpuInitialized = true; return ls->m_gpuSupported; } void mitk::GPUVolumeMapper3D::InitCPU(mitk::BaseRenderer* renderer) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); if(ls->m_cpuInitialized) return; ls->m_VtkRenderWindow = renderer->GetVtkRenderer()->GetRenderWindow(); ls->m_MapperCPU = vtkSmartPointer::New(); int numThreads = ls->m_MapperCPU->GetNumberOfThreads( ); GPU_INFO << "initializing cpu-raycast-vr (vtkFixedPointVolumeRayCastMapper) (" << numThreads << " threads)"; ls->m_MapperCPU->SetSampleDistance(1.0); // ls->m_MapperCPU->LockSampleDistanceToInputSpacingOn(); ls->m_MapperCPU->SetImageSampleDistance(1.0); ls->m_MapperCPU->IntermixIntersectingGeometryOn(); ls->m_MapperCPU->SetAutoAdjustSampleDistances(0); ls->m_VolumePropertyCPU = vtkSmartPointer::New(); ls->m_VolumePropertyCPU->ShadeOn(); ls->m_VolumePropertyCPU->SetAmbient (0.10f); //0.05f ls->m_VolumePropertyCPU->SetDiffuse (0.50f); //0.45f ls->m_VolumePropertyCPU->SetSpecular(0.40f); //0.50f ls->m_VolumePropertyCPU->SetSpecularPower(16.0f); ls->m_VolumePropertyCPU->SetInterpolationTypeToLinear(); ls->m_VolumeCPU = vtkSmartPointer::New(); ls->m_VolumeCPU->SetMapper( ls->m_MapperCPU ); ls->m_VolumeCPU->SetProperty( ls->m_VolumePropertyCPU ); ls->m_VolumeCPU->VisibilityOn(); ls->m_MapperCPU->SetInputData( m_UnitSpacingImageFilter->GetOutput() );//m_Resampler->GetOutput()); ls->m_cpuInitialized=true; } void mitk::GPUVolumeMapper3D::DeinitGPU(mitk::BaseRenderer* renderer) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); if(ls->m_gpuInitialized) { GPU_INFO << "deinitializing gpu-slicing-vr"; // deinit renderwindow, this is needed to release the memory allocated on the gpu // to prevent leaking memory on the gpu ls->m_MapperGPU->ReleaseGraphicsResources(renderer->GetVtkRenderer()->GetVTKWindow()); ls->m_VolumePropertyGPU = NULL; ls->m_MapperGPU = NULL; ls->m_VolumeGPU = NULL; ls->m_gpuInitialized=false; } } void mitk::GPUVolumeMapper3D::DeinitCPU(mitk::BaseRenderer* renderer) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); if(!ls->m_cpuInitialized) return; GPU_INFO << "deinitializing cpu-raycast-vr"; ls->m_VolumePropertyCPU = NULL; ls->m_MapperCPU = NULL; ls->m_VolumeCPU = NULL; ls->m_cpuInitialized=false; } mitk::GPUVolumeMapper3D::GPUVolumeMapper3D() { m_VolumeNULL=0; m_commonInitialized=false; } mitk::GPUVolumeMapper3D::~GPUVolumeMapper3D() { DeinitCommon(); } void mitk::GPUVolumeMapper3D::InitCommon() { if(m_commonInitialized) return; m_UnitSpacingImageFilter = vtkSmartPointer::New(); m_UnitSpacingImageFilter->SetOutputSpacing( 1.0, 1.0, 1.0 ); CreateDefaultTransferFunctions(); m_commonInitialized=true; } void mitk::GPUVolumeMapper3D::DeinitCommon() { if(!m_commonInitialized) return; m_commonInitialized=false; } bool mitk::GPUVolumeMapper3D::IsRenderable(mitk::BaseRenderer* renderer) { if(!GetDataNode()) return false; DataNode* node = GetDataNode(); bool visible = true; node->GetVisibility(visible, renderer, "visible"); if(!visible) return false; bool value = false; if(!node->GetBoolProperty("volumerendering",value,renderer)) return false; if(!value) return false; mitk::Image *input = const_cast< mitk::Image * >( this->GetInput() ); if ( !input || !input->IsInitialized() ) return false; vtkImageData *inputData = input->GetVtkImageData( this->GetTimestep() ); if(inputData==NULL) return false; return true; } void mitk::GPUVolumeMapper3D::InitVtkMapper(mitk::BaseRenderer* renderer) { // Only with VTK 5.6 or above #if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION==5) && (VTK_MINOR_VERSION>=6) )) if(IsRAYEnabled(renderer)) { DeinitCPU(renderer); DeinitGPU(renderer); if(!InitRAY(renderer)) { GPU_WARN << "hardware renderer can't initialize ... falling back to software renderer"; goto fallback; } } else #endif if(IsGPUEnabled(renderer)) { DeinitCPU(renderer); // Only with VTK 5.6 or above #if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION==5) && (VTK_MINOR_VERSION>=6) )) DeinitRAY(renderer); #endif if(!InitGPU(renderer)) { GPU_WARN << "hardware renderer can't initialize ... falling back to software renderer"; goto fallback; } } else { fallback: DeinitGPU(renderer); // Only with VTK 5.6 or above #if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION==5) && (VTK_MINOR_VERSION>=6) )) DeinitRAY(renderer); #endif InitCPU(renderer); } } vtkProp *mitk::GPUVolumeMapper3D::GetVtkProp(mitk::BaseRenderer *renderer) { if(!IsRenderable(renderer)) { if(!m_VolumeNULL) { m_VolumeNULL = vtkSmartPointer::New(); m_VolumeNULL->VisibilityOff(); } return m_VolumeNULL; } InitCommon(); InitVtkMapper( renderer ); LocalStorage *ls = m_LSH.GetLocalStorage(renderer); // Only with VTK 5.6 or above #if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION==5) && (VTK_MINOR_VERSION>=6) )) if(ls->m_rayInitialized) return ls->m_VolumeRAY; #endif if(ls->m_gpuInitialized) return ls->m_VolumeGPU; return ls->m_VolumeCPU; } void mitk::GPUVolumeMapper3D::GenerateDataForRenderer( mitk::BaseRenderer *renderer ) { if(!IsRenderable(renderer)) return; InitCommon(); InitVtkMapper( renderer ); mitk::Image *input = const_cast< mitk::Image * >( this->GetInput() ); vtkImageData *inputData = input->GetVtkImageData( this->GetTimestep() ); m_UnitSpacingImageFilter->SetInputData( inputData ); LocalStorage *ls = m_LSH.GetLocalStorage(renderer); // Only with VTK 5.6 or above #if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION==5) && (VTK_MINOR_VERSION>=6) )) if(ls->m_rayInitialized) { GenerateDataRAY(renderer); } else #endif if(ls->m_gpuInitialized) { GenerateDataGPU(renderer); } else { GenerateDataCPU(renderer); } // UpdateTransferFunctions UpdateTransferFunctions( renderer ); } void mitk::GPUVolumeMapper3D::GenerateDataGPU( mitk::BaseRenderer *renderer ) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); bool useCompression = false; GetDataNode()->GetBoolProperty("volumerendering.gpu.usetexturecompression",useCompression,renderer); ls->m_MapperGPU->SetUseCompressedTexture(useCompression); if( IsLODEnabled(renderer) && mitk::RenderingManager::GetInstance()->GetNextLOD( renderer ) == 0 ) ls->m_MapperGPU->SetSampleDistance(2.0); else ls->m_MapperGPU->SetSampleDistance(1.0); // Updating shadings { float value=0; if(GetDataNode()->GetFloatProperty("volumerendering.gpu.ambient",value,renderer)) ls->m_VolumePropertyGPU->SetAmbient(value); if(GetDataNode()->GetFloatProperty("volumerendering.gpu.diffuse",value,renderer)) ls->m_VolumePropertyGPU->SetDiffuse(value); if(GetDataNode()->GetFloatProperty("volumerendering.gpu.specular",value,renderer)) ls->m_VolumePropertyGPU->SetSpecular(value); if(GetDataNode()->GetFloatProperty("volumerendering.gpu.specular.power",value,renderer)) ls->m_VolumePropertyGPU->SetSpecularPower(value); } } void mitk::GPUVolumeMapper3D::GenerateDataCPU( mitk::BaseRenderer *renderer ) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); int nextLod = mitk::RenderingManager::GetInstance()->GetNextLOD( renderer ); if( IsLODEnabled(renderer) && nextLod == 0 ) { ls->m_MapperCPU->SetImageSampleDistance(3.5); ls->m_MapperCPU->SetSampleDistance(1.25); ls->m_VolumePropertyCPU->SetInterpolationTypeToNearest(); } else { ls->m_MapperCPU->SetImageSampleDistance(1.0); ls->m_MapperCPU->SetSampleDistance(1.0); ls->m_VolumePropertyCPU->SetInterpolationTypeToLinear(); } // Check raycasting mode if(IsMIPEnabled(renderer)) ls->m_MapperCPU->SetBlendModeToMaximumIntensity(); else ls->m_MapperCPU->SetBlendModeToComposite(); // Updating shadings { float value=0; if(GetDataNode()->GetFloatProperty("volumerendering.cpu.ambient",value,renderer)) ls->m_VolumePropertyCPU->SetAmbient(value); if(GetDataNode()->GetFloatProperty("volumerendering.cpu.diffuse",value,renderer)) ls->m_VolumePropertyCPU->SetDiffuse(value); if(GetDataNode()->GetFloatProperty("volumerendering.cpu.specular",value,renderer)) ls->m_VolumePropertyCPU->SetSpecular(value); if(GetDataNode()->GetFloatProperty("volumerendering.cpu.specular.power",value,renderer)) ls->m_VolumePropertyCPU->SetSpecularPower(value); } } void mitk::GPUVolumeMapper3D::CreateDefaultTransferFunctions() { m_DefaultOpacityTransferFunction = vtkSmartPointer::New(); m_DefaultOpacityTransferFunction->AddPoint( 0.0, 0.0 ); m_DefaultOpacityTransferFunction->AddPoint( 255.0, 0.8 ); m_DefaultOpacityTransferFunction->ClampingOn(); m_DefaultGradientTransferFunction = vtkSmartPointer::New(); m_DefaultGradientTransferFunction->AddPoint( 0.0, 0.0 ); m_DefaultGradientTransferFunction->AddPoint( 255.0, 0.8 ); m_DefaultGradientTransferFunction->ClampingOn(); m_DefaultColorTransferFunction = vtkSmartPointer::New(); m_DefaultColorTransferFunction->AddRGBPoint( 0.0, 0.0, 0.0, 0.0 ); m_DefaultColorTransferFunction->AddRGBPoint( 127.5, 1, 1, 0.0 ); m_DefaultColorTransferFunction->AddRGBPoint( 255.0, 0.8, 0.2, 0 ); m_DefaultColorTransferFunction->ClampingOn(); m_BinaryOpacityTransferFunction = vtkSmartPointer::New(); m_BinaryOpacityTransferFunction->AddPoint( 0, 0.0 ); m_BinaryOpacityTransferFunction->AddPoint( 1, 1.0 ); m_BinaryGradientTransferFunction = vtkSmartPointer::New(); m_BinaryGradientTransferFunction->AddPoint( 0.0, 1.0 ); m_BinaryColorTransferFunction = vtkSmartPointer::New(); } void mitk::GPUVolumeMapper3D::UpdateTransferFunctions( mitk::BaseRenderer * renderer ) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); vtkPiecewiseFunction *opacityTransferFunction = m_DefaultOpacityTransferFunction; vtkPiecewiseFunction *gradientTransferFunction = m_DefaultGradientTransferFunction; vtkColorTransferFunction *colorTransferFunction = m_DefaultColorTransferFunction; bool isBinary = false; GetDataNode()->GetBoolProperty("binary", isBinary, renderer); if(isBinary) { opacityTransferFunction = m_BinaryOpacityTransferFunction; gradientTransferFunction = m_BinaryGradientTransferFunction; colorTransferFunction = m_BinaryColorTransferFunction; colorTransferFunction->RemoveAllPoints(); float rgb[3]; if( !GetDataNode()->GetColor( rgb,renderer ) ) rgb[0]=rgb[1]=rgb[2]=1; colorTransferFunction->AddRGBPoint( 0,rgb[0],rgb[1],rgb[2] ); colorTransferFunction->Modified(); } else { mitk::TransferFunctionProperty *transferFunctionProp = dynamic_cast(this->GetDataNode()->GetProperty("TransferFunction",renderer)); if( transferFunctionProp ) { opacityTransferFunction = transferFunctionProp->GetValue()->GetScalarOpacityFunction(); gradientTransferFunction = transferFunctionProp->GetValue()->GetGradientOpacityFunction(); colorTransferFunction = transferFunctionProp->GetValue()->GetColorTransferFunction(); } } if(ls->m_gpuInitialized) { ls->m_VolumePropertyGPU->SetColor( colorTransferFunction ); ls->m_VolumePropertyGPU->SetScalarOpacity( opacityTransferFunction ); ls->m_VolumePropertyGPU->SetGradientOpacity( gradientTransferFunction ); } // Only with VTK 5.6 or above #if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION==5) && (VTK_MINOR_VERSION>=6) )) if(ls->m_rayInitialized) { ls->m_VolumePropertyRAY->SetColor( colorTransferFunction ); ls->m_VolumePropertyRAY->SetScalarOpacity( opacityTransferFunction ); ls->m_VolumePropertyRAY->SetGradientOpacity( gradientTransferFunction ); } #endif if(ls->m_cpuInitialized) { ls->m_VolumePropertyCPU->SetColor( colorTransferFunction ); ls->m_VolumePropertyCPU->SetScalarOpacity( opacityTransferFunction ); ls->m_VolumePropertyCPU->SetGradientOpacity( gradientTransferFunction ); } } void mitk::GPUVolumeMapper3D::ApplyProperties(vtkActor* /*actor*/, mitk::BaseRenderer* /*renderer*/) { //GPU_INFO << "ApplyProperties"; } void mitk::GPUVolumeMapper3D::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite) { //GPU_INFO << "SetDefaultProperties"; node->AddProperty( "volumerendering", mitk::BoolProperty::New( false ), renderer, overwrite ); node->AddProperty( "volumerendering.usemip", mitk::BoolProperty::New( false ), renderer, overwrite ); node->AddProperty( "volumerendering.uselod", mitk::BoolProperty::New( false ), renderer, overwrite ); node->AddProperty( "volumerendering.cpu.ambient", mitk::FloatProperty::New( 0.10f ), renderer, overwrite ); node->AddProperty( "volumerendering.cpu.diffuse", mitk::FloatProperty::New( 0.50f ), renderer, overwrite ); node->AddProperty( "volumerendering.cpu.specular", mitk::FloatProperty::New( 0.40f ), renderer, overwrite ); node->AddProperty( "volumerendering.cpu.specular.power", mitk::FloatProperty::New( 16.0f ), renderer, overwrite ); bool usegpu = true; #ifdef __APPLE__ usegpu = false; node->AddProperty( "volumerendering.uselod", mitk::BoolProperty::New( true ), renderer, overwrite ); #endif node->AddProperty( "volumerendering.usegpu", mitk::BoolProperty::New( usegpu ), renderer, overwrite ); // Only with VTK 5.6 or above #if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION==5) && (VTK_MINOR_VERSION>=6) )) node->AddProperty( "volumerendering.useray", mitk::BoolProperty::New( false ), renderer, overwrite ); node->AddProperty( "volumerendering.ray.ambient", mitk::FloatProperty::New( 0.25f ), renderer, overwrite ); node->AddProperty( "volumerendering.ray.diffuse", mitk::FloatProperty::New( 0.50f ), renderer, overwrite ); node->AddProperty( "volumerendering.ray.specular", mitk::FloatProperty::New( 0.40f ), renderer, overwrite ); node->AddProperty( "volumerendering.ray.specular.power", mitk::FloatProperty::New( 16.0f ), renderer, overwrite ); #endif node->AddProperty( "volumerendering.gpu.ambient", mitk::FloatProperty::New( 0.25f ), renderer, overwrite ); node->AddProperty( "volumerendering.gpu.diffuse", mitk::FloatProperty::New( 0.50f ), renderer, overwrite ); node->AddProperty( "volumerendering.gpu.specular", mitk::FloatProperty::New( 0.40f ), renderer, overwrite ); node->AddProperty( "volumerendering.gpu.specular.power", mitk::FloatProperty::New( 16.0f ), renderer, overwrite ); node->AddProperty( "volumerendering.gpu.usetexturecompression", mitk::BoolProperty ::New( false ), renderer, overwrite ); node->AddProperty( "volumerendering.gpu.reducesliceartifacts" , mitk::BoolProperty ::New( false ), renderer, overwrite ); node->AddProperty( "binary", mitk::BoolProperty::New( false ), renderer, overwrite ); mitk::Image::Pointer image = dynamic_cast(node->GetData()); if(image.IsNotNull() && image->IsInitialized()) { if((overwrite) || (node->GetProperty("levelwindow", renderer)==NULL)) { mitk::LevelWindowProperty::Pointer levWinProp = mitk::LevelWindowProperty::New(); mitk::LevelWindow levelwindow; levelwindow.SetAuto( image ); levWinProp->SetLevelWindow( levelwindow ); node->SetProperty( "levelwindow", levWinProp, renderer ); } if((overwrite) || (node->GetProperty("TransferFunction", renderer)==NULL)) { // add a default transfer function mitk::TransferFunction::Pointer tf = mitk::TransferFunction::New(); mitk::TransferFunctionInitializer::Pointer tfInit = mitk::TransferFunctionInitializer::New(tf); tfInit->SetTransferFunctionMode(0); node->SetProperty ( "TransferFunction", mitk::TransferFunctionProperty::New ( tf.GetPointer() ) ); } } Superclass::SetDefaultProperties(node, renderer, overwrite); } bool mitk::GPUVolumeMapper3D::IsLODEnabled( mitk::BaseRenderer * renderer ) const { bool value = false; return GetDataNode()->GetBoolProperty("volumerendering.uselod",value,renderer) && value; } bool mitk::GPUVolumeMapper3D::IsMIPEnabled( mitk::BaseRenderer * renderer ) { bool value = false; return GetDataNode()->GetBoolProperty("volumerendering.usemip",value,renderer) && value; } bool mitk::GPUVolumeMapper3D::IsGPUEnabled( mitk::BaseRenderer * renderer ) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); bool value = false; return ls->m_gpuSupported && GetDataNode()->GetBoolProperty("volumerendering.usegpu",value,renderer) && value; } // Only with VTK 5.6 or above #if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION==5) && (VTK_MINOR_VERSION>=6) )) bool mitk::GPUVolumeMapper3D::InitRAY(mitk::BaseRenderer* renderer) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); if(ls->m_rayInitialized) return ls->m_raySupported; ls->m_VtkRenderWindow = renderer->GetVtkRenderer()->GetRenderWindow(); GPU_INFO << "initializing gpu-raycast-vr (vtkOpenGLGPUVolumeRayCastMapper)"; ls->m_MapperRAY = vtkSmartPointer::New(); ls->m_MapperRAY->SetAutoAdjustSampleDistances(0); ls->m_MapperRAY->SetSampleDistance(1.0); ls->m_VolumePropertyRAY = vtkSmartPointer::New(); ls->m_VolumePropertyRAY->ShadeOn(); ls->m_VolumePropertyRAY->SetAmbient (0.25f); //0.05f ls->m_VolumePropertyRAY->SetDiffuse (0.50f); //0.45f ls->m_VolumePropertyRAY->SetSpecular(0.40f); //0.50f ls->m_VolumePropertyRAY->SetSpecularPower(16.0f); ls->m_VolumePropertyRAY->SetInterpolationTypeToLinear(); ls->m_VolumeRAY = vtkSmartPointer::New(); ls->m_VolumeRAY->SetMapper( ls->m_MapperRAY ); ls->m_VolumeRAY->SetProperty( ls->m_VolumePropertyRAY ); ls->m_VolumeRAY->VisibilityOn(); - ls->m_MapperRAY->SetInput( this->m_UnitSpacingImageFilter->GetOutput() ); + ls->m_MapperRAY->SetInputData( this->m_UnitSpacingImageFilter->GetOutput() ); ls->m_raySupported = ls->m_MapperRAY->IsRenderSupported(renderer->GetRenderWindow(),ls->m_VolumePropertyRAY); ls->m_rayInitialized = true; return ls->m_raySupported; } void mitk::GPUVolumeMapper3D::DeinitRAY(mitk::BaseRenderer* renderer) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); if(ls->m_rayInitialized) { GPU_INFO << "deinitializing gpu-raycast-vr"; ls->m_MapperRAY = NULL; ls->m_VolumePropertyRAY = NULL; //Here ReleaseGraphicsResources has to be called to avoid VTK error messages. //This seems like a VTK bug, because ReleaseGraphicsResources() is ment for internal use, //but you cannot just delete the object (last smartpointer reference) without getting the //VTK error. ls->m_VolumeRAY->ReleaseGraphicsResources(renderer->GetVtkRenderer()->GetRenderWindow()); ls->m_VolumeRAY = NULL; ls->m_rayInitialized=false; } } void mitk::GPUVolumeMapper3D::GenerateDataRAY( mitk::BaseRenderer *renderer ) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); if( IsLODEnabled(renderer) && mitk::RenderingManager::GetInstance()->GetNextLOD( renderer ) == 0 ) ls->m_MapperRAY->SetImageSampleDistance(4.0); else ls->m_MapperRAY->SetImageSampleDistance(1.0); // Check raycasting mode if(IsMIPEnabled(renderer)) ls->m_MapperRAY->SetBlendModeToMaximumIntensity(); else ls->m_MapperRAY->SetBlendModeToComposite(); // Updating shadings { float value=0; if(GetDataNode()->GetFloatProperty("volumerendering.ray.ambient",value,renderer)) ls->m_VolumePropertyRAY->SetAmbient(value); if(GetDataNode()->GetFloatProperty("volumerendering.ray.diffuse",value,renderer)) ls->m_VolumePropertyRAY->SetDiffuse(value); if(GetDataNode()->GetFloatProperty("volumerendering.ray.specular",value,renderer)) ls->m_VolumePropertyRAY->SetSpecular(value); if(GetDataNode()->GetFloatProperty("volumerendering.ray.specular.power",value,renderer)) ls->m_VolumePropertyRAY->SetSpecularPower(value); } } bool mitk::GPUVolumeMapper3D::IsRAYEnabled( mitk::BaseRenderer * renderer ) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); bool value = false; return ls->m_raySupported && GetDataNode()->GetBoolProperty("volumerendering.useray",value,renderer) && value; } #endif diff --git a/Modules/MitkExt/Rendering/mitkGPUVolumeMapper3D.h b/Modules/MitkExt/Rendering/mitkGPUVolumeMapper3D.h index b73efb3493..aa84a23e39 100644 --- a/Modules/MitkExt/Rendering/mitkGPUVolumeMapper3D.h +++ b/Modules/MitkExt/Rendering/mitkGPUVolumeMapper3D.h @@ -1,194 +1,195 @@ /*=================================================================== 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 MITKGPUVOLUMEMAPPER3D_H_HEADER_INCLUDED #define MITKGPUVOLUMEMAPPER3D_H_HEADER_INCLUDED //MITK #include "mitkCommon.h" #include "MitkExtExports.h" #include "mitkBaseRenderer.h" #include "mitkImage.h" #include "mitkVtkMapper.h" #include "vtkMitkVolumeTextureMapper3D.h" //VTK #include #include #include #include #include +#include // Only with VTK 5.6 or above #if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION==5) && (VTK_MINOR_VERSION>=6) )) #include "vtkMitkGPUVolumeRayCastMapper.h" #endif namespace mitk { /************************************************************************/ /* Properties that influence the mapper are: * * - \b "level window": for the level window of the volume data * - \b "LookupTable" : for the lookup table of the volume data * - \b "TransferFunction" (mitk::TransferFunctionProperty): for the used transfer function of the volume data ************************************************************************/ //##Documentation //## @brief Vtk-based mapper for VolumeData //## //## @ingroup Mapper class MitkExt_EXPORT GPUVolumeMapper3D : public VtkMapper { public: mitkClassMacro(GPUVolumeMapper3D, VtkMapper); itkNewMacro(Self); virtual const mitk::Image* GetInput(); virtual vtkProp *GetVtkProp(mitk::BaseRenderer *renderer); virtual void ApplyProperties(vtkActor* actor, mitk::BaseRenderer* renderer); static void SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer = NULL, bool overwrite = false); /** Returns true if this Mapper currently allows for Level-of-Detail rendering. * This reflects whether this Mapper currently invokes StartEvent, EndEvent, and * ProgressEvent on BaseRenderer. */ virtual bool IsLODEnabled( BaseRenderer *renderer = NULL ) const; bool IsMIPEnabled( BaseRenderer *renderer = NULL ); bool IsGPUEnabled( BaseRenderer *renderer = NULL ); bool IsRAYEnabled( BaseRenderer *renderer = NULL ); virtual void MitkRenderVolumetricGeometry(mitk::BaseRenderer* renderer); protected: GPUVolumeMapper3D(); virtual ~GPUVolumeMapper3D(); bool IsRenderable(mitk::BaseRenderer* renderer); void InitCommon(); void DeinitCommon(); void InitCPU(mitk::BaseRenderer* renderer); void DeinitCPU(mitk::BaseRenderer* renderer); void GenerateDataCPU(mitk::BaseRenderer* renderer); bool InitGPU(mitk::BaseRenderer* renderer); void DeinitGPU(mitk::BaseRenderer* renderer); void GenerateDataGPU(mitk::BaseRenderer* renderer); // Only with VTK 5.6 or above #if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION==5) && (VTK_MINOR_VERSION>=6) )) bool InitRAY(mitk::BaseRenderer* renderer); void DeinitRAY(mitk::BaseRenderer* renderer); void GenerateDataRAY(mitk::BaseRenderer* renderer); #endif void InitVtkMapper(mitk::BaseRenderer* renderer); virtual void GenerateDataForRenderer(mitk::BaseRenderer* renderer); void CreateDefaultTransferFunctions(); void UpdateTransferFunctions( mitk::BaseRenderer *renderer ); vtkSmartPointer m_VolumeNULL; bool m_commonInitialized; vtkSmartPointer m_UnitSpacingImageFilter; vtkSmartPointer m_DefaultOpacityTransferFunction; vtkSmartPointer m_DefaultGradientTransferFunction; vtkSmartPointer m_DefaultColorTransferFunction; vtkSmartPointer m_BinaryOpacityTransferFunction; vtkSmartPointer m_BinaryGradientTransferFunction; vtkSmartPointer m_BinaryColorTransferFunction; class LocalStorage : public mitk::Mapper::BaseLocalStorage { public: // NO SMARTPOINTER HERE vtkRenderWindow * m_VtkRenderWindow; bool m_cpuInitialized; vtkSmartPointer m_VolumeCPU; vtkSmartPointer m_MapperCPU; vtkSmartPointer m_VolumePropertyCPU; bool m_gpuSupported; bool m_gpuInitialized; vtkSmartPointer m_VolumeGPU; vtkSmartPointer m_MapperGPU; vtkSmartPointer m_VolumePropertyGPU; // Only with VTK 5.6 or above #if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION==5) && (VTK_MINOR_VERSION>=6) )) bool m_raySupported; bool m_rayInitialized; vtkSmartPointer m_VolumeRAY; vtkSmartPointer m_MapperRAY; vtkSmartPointer m_VolumePropertyRAY; #endif LocalStorage() { m_VtkRenderWindow = 0; m_cpuInitialized = false; m_gpuInitialized = false; m_gpuSupported = true; // assume initially gpu slicing is supported // Only with VTK 5.6 or above #if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION==5) && (VTK_MINOR_VERSION>=6) )) m_rayInitialized = false; m_raySupported = true; // assume initially gpu raycasting is supported #endif } ~LocalStorage() { if(m_cpuInitialized && m_MapperCPU && m_VtkRenderWindow) m_MapperCPU->ReleaseGraphicsResources(m_VtkRenderWindow); if(m_gpuInitialized && m_MapperGPU && m_VtkRenderWindow) m_MapperGPU->ReleaseGraphicsResources(m_VtkRenderWindow); // Only with VTK 5.6 or above #if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION==5) && (VTK_MINOR_VERSION>=6) )) if(m_rayInitialized && m_MapperRAY && m_VtkRenderWindow) m_MapperRAY->ReleaseGraphicsResources(m_VtkRenderWindow); #endif } }; mitk::LocalStorageHandler m_LSH; }; } // namespace mitk #endif /* MITKVOLUMEDATAVTKMAPPER3D_H_HEADER_INCLUDED */ diff --git a/Modules/ToFProcessing/mitkToFSurfaceVtkMapper3D.cpp b/Modules/ToFProcessing/mitkToFSurfaceVtkMapper3D.cpp index c2aee2d34e..ee81dd5536 100644 --- a/Modules/ToFProcessing/mitkToFSurfaceVtkMapper3D.cpp +++ b/Modules/ToFProcessing/mitkToFSurfaceVtkMapper3D.cpp @@ -1,509 +1,509 @@ /*=================================================================== 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 "mitkToFSurfaceVtkMapper3D.h" #include "mitkDataNode.h" #include "mitkProperties.h" #include "mitkColorProperty.h" #include "mitkLookupTableProperty.h" #include "mitkVtkRepresentationProperty.h" #include "mitkVtkInterpolationProperty.h" #include "mitkVtkScalarModeProperty.h" #include "mitkClippingProperty.h" #include "mitkIShaderRepository.h" #include "mitkShaderProperty.h" #include "mitkCoreServices.h" #include #include #include #include #include #include #include #include #include #include #include //const mitk::ToFSurface* mitk::ToFSurfaceVtkMapper3D::GetInput() const mitk::Surface* mitk::ToFSurfaceVtkMapper3D::GetInput() { //return static_cast ( GetData() ); return static_cast ( GetDataNode()->GetData() ); } mitk::ToFSurfaceVtkMapper3D::ToFSurfaceVtkMapper3D() { // m_Prop3D = vtkActor::New(); m_GenerateNormals = false; this->m_Texture = NULL; this->m_TextureWidth = 0; this->m_TextureHeight = 0; this->m_VtkScalarsToColors = NULL; } mitk::ToFSurfaceVtkMapper3D::~ToFSurfaceVtkMapper3D() { // m_Prop3D->Delete(); } void mitk::ToFSurfaceVtkMapper3D::GenerateDataForRenderer(mitk::BaseRenderer* renderer) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); bool visible = true; GetDataNode()->GetVisibility(visible, renderer, "visible"); if ( !visible ) { ls->m_Actor->VisibilityOff(); return; } // // set the input-object at time t for the mapper // //mitk::ToFSurface::Pointer input = const_cast< mitk::ToFSurface* >( this->GetInput() ); mitk::Surface::Pointer input = const_cast< mitk::Surface* >( this->GetInput() ); vtkPolyData * polydata = input->GetVtkPolyData( this->GetTimestep() ); if(polydata == NULL) { ls->m_Actor->VisibilityOff(); return; } if ( m_GenerateNormals ) { - ls->m_VtkPolyDataNormals->SetInput( polydata ); - ls->m_VtkPolyDataMapper->SetInput( ls->m_VtkPolyDataNormals->GetOutput() ); + ls->m_VtkPolyDataNormals->SetInputData( polydata ); + ls->m_VtkPolyDataMapper->SetInputData( ls->m_VtkPolyDataNormals->GetOutput() ); } else { - ls->m_VtkPolyDataMapper->SetInput( polydata ); + ls->m_VtkPolyDataMapper->SetInputData( polydata ); } // // apply properties read from the PropertyList // ApplyProperties(ls->m_Actor, renderer); if(visible) ls->m_Actor->VisibilityOn(); // // TOF extension for visualization (color/texture mapping) // if (this->m_VtkScalarsToColors) { // set the color transfer funtion if applied ls->m_VtkPolyDataMapper->SetLookupTable(this->m_VtkScalarsToColors); } if (this->m_Texture) { ls->m_Actor->SetTexture(this->m_Texture); } else { // remove the texture ls->m_Actor->SetTexture(0); } } void mitk::ToFSurfaceVtkMapper3D::ResetMapper( BaseRenderer* renderer ) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); ls->m_Actor->VisibilityOff(); } void mitk::ToFSurfaceVtkMapper3D::ApplyMitkPropertiesToVtkProperty(mitk::DataNode *node, vtkProperty* property, mitk::BaseRenderer* renderer) { // Colors { double ambient [3] = { 0.5,0.5,0.0 }; double diffuse [3] = { 0.5,0.5,0.0 }; double specular[3] = { 1.0,1.0,1.0 }; float coeff_ambient = 0.5f; float coeff_diffuse = 0.5f; float coeff_specular= 0.5f; float power_specular=10.0f; // Color { mitk::ColorProperty::Pointer p; node->GetProperty(p, "color", renderer); if(p.IsNotNull()) { mitk::Color c = p->GetColor(); ambient[0]=c.GetRed(); ambient[1]=c.GetGreen(); ambient[2]=c.GetBlue(); diffuse[0]=c.GetRed(); diffuse[1]=c.GetGreen(); diffuse[2]=c.GetBlue(); // Setting specular color to the same, make physically no real sense, however vtk rendering slows down, if these colors are different. specular[0]=c.GetRed(); specular[1]=c.GetGreen(); specular[2]=c.GetBlue(); } } // Ambient { mitk::ColorProperty::Pointer p; node->GetProperty(p, "material.ambientColor", renderer); if(p.IsNotNull()) { mitk::Color c = p->GetColor(); ambient[0]=c.GetRed(); ambient[1]=c.GetGreen(); ambient[2]=c.GetBlue(); } } // Diffuse { mitk::ColorProperty::Pointer p; node->GetProperty(p, "material.diffuseColor", renderer); if(p.IsNotNull()) { mitk::Color c = p->GetColor(); diffuse[0]=c.GetRed(); diffuse[1]=c.GetGreen(); diffuse[2]=c.GetBlue(); } } // Specular { mitk::ColorProperty::Pointer p; node->GetProperty(p, "material.specularColor", renderer); if(p.IsNotNull()) { mitk::Color c = p->GetColor(); specular[0]=c.GetRed(); specular[1]=c.GetGreen(); specular[2]=c.GetBlue(); } } // Ambient coeff { node->GetFloatProperty("material.ambientCoefficient", coeff_ambient, renderer); } // Diffuse coeff { node->GetFloatProperty("material.diffuseCoefficient", coeff_diffuse, renderer); } // Specular coeff { node->GetFloatProperty("material.specularCoefficient", coeff_specular, renderer); } // Specular power { node->GetFloatProperty("material.specularPower", power_specular, renderer); } property->SetAmbient( coeff_ambient ); property->SetDiffuse( coeff_diffuse ); property->SetSpecular( coeff_specular ); property->SetSpecularPower( power_specular ); property->SetAmbientColor( ambient ); property->SetDiffuseColor( diffuse ); property->SetSpecularColor( specular ); } // Render mode { // Opacity { float opacity = 1.0f; if( node->GetOpacity(opacity,renderer) ) property->SetOpacity( opacity ); } // Wireframe line width { float lineWidth = 1; node->GetFloatProperty("material.wireframeLineWidth", lineWidth, renderer); property->SetLineWidth( lineWidth ); } // Representation { mitk::VtkRepresentationProperty::Pointer p; node->GetProperty(p, "material.representation", renderer); if(p.IsNotNull()) property->SetRepresentation( p->GetVtkRepresentation() ); } // Interpolation { mitk::VtkInterpolationProperty::Pointer p; node->GetProperty(p, "material.interpolation", renderer); if(p.IsNotNull()) property->SetInterpolation( p->GetVtkInterpolation() ); } } } void mitk::ToFSurfaceVtkMapper3D::ApplyProperties(vtkActor* /*actor*/, mitk::BaseRenderer* renderer) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); // Applying shading properties { ApplyColorAndOpacityProperties( renderer, ls->m_Actor ) ; // VTK Properties ApplyMitkPropertiesToVtkProperty( this->GetDataNode(), ls->m_Actor->GetProperty(), renderer ); // Shaders CoreServicePointer(mitk::CoreServices::GetShaderRepository())->ApplyProperties( this->GetDataNode(),ls->m_Actor,renderer,ls->m_ShaderTimestampUpdate); } mitk::LookupTableProperty::Pointer lookupTableProp; this->GetDataNode()->GetProperty(lookupTableProp, "LookupTable", renderer); if (lookupTableProp.IsNotNull() ) { ls->m_VtkPolyDataMapper->SetLookupTable(lookupTableProp->GetLookupTable()->GetVtkLookupTable()); } mitk::LevelWindow levelWindow; if(this->GetDataNode()->GetLevelWindow(levelWindow, renderer, "levelWindow")) { ls->m_VtkPolyDataMapper->SetScalarRange(levelWindow.GetLowerWindowBound(),levelWindow.GetUpperWindowBound()); } else if(this->GetDataNode()->GetLevelWindow(levelWindow, renderer)) { ls->m_VtkPolyDataMapper->SetScalarRange(levelWindow.GetLowerWindowBound(),levelWindow.GetUpperWindowBound()); } bool scalarVisibility = false; this->GetDataNode()->GetBoolProperty("scalar visibility", scalarVisibility); ls->m_VtkPolyDataMapper->SetScalarVisibility( (scalarVisibility ? 1 : 0) ); if(scalarVisibility) { mitk::VtkScalarModeProperty* scalarMode; if(this->GetDataNode()->GetProperty(scalarMode, "scalar mode", renderer)) { ls->m_VtkPolyDataMapper->SetScalarMode(scalarMode->GetVtkScalarMode()); } else ls->m_VtkPolyDataMapper->SetScalarModeToDefault(); bool colorMode = false; this->GetDataNode()->GetBoolProperty("color mode", colorMode); ls->m_VtkPolyDataMapper->SetColorMode( (colorMode ? 1 : 0) ); float scalarsMin = 0; if (dynamic_cast(this->GetDataNode()->GetProperty("ScalarsRangeMinimum")) != NULL) scalarsMin = dynamic_cast(this->GetDataNode()->GetProperty("ScalarsRangeMinimum"))->GetValue(); float scalarsMax = 1.0; if (dynamic_cast(this->GetDataNode()->GetProperty("ScalarsRangeMaximum")) != NULL) scalarsMax = dynamic_cast(this->GetDataNode()->GetProperty("ScalarsRangeMaximum"))->GetValue(); ls->m_VtkPolyDataMapper->SetScalarRange(scalarsMin,scalarsMax); } // deprecated settings bool deprecatedUseCellData = false; this->GetDataNode()->GetBoolProperty("deprecated useCellDataForColouring", deprecatedUseCellData); bool deprecatedUsePointData = false; this->GetDataNode()->GetBoolProperty("deprecated usePointDataForColouring", deprecatedUsePointData); if (deprecatedUseCellData) { ls->m_VtkPolyDataMapper->SetColorModeToDefault(); ls->m_VtkPolyDataMapper->SetScalarRange(0,255); ls->m_VtkPolyDataMapper->ScalarVisibilityOn(); ls->m_VtkPolyDataMapper->SetScalarModeToUseCellData(); ls->m_Actor->GetProperty()->SetSpecular (1); ls->m_Actor->GetProperty()->SetSpecularPower (50); ls->m_Actor->GetProperty()->SetInterpolationToPhong(); } else if (deprecatedUsePointData) { float scalarsMin = 0; if (dynamic_cast(this->GetDataNode()->GetProperty("ScalarsRangeMinimum")) != NULL) scalarsMin = dynamic_cast(this->GetDataNode()->GetProperty("ScalarsRangeMinimum"))->GetValue(); float scalarsMax = 0.1; if (dynamic_cast(this->GetDataNode()->GetProperty("ScalarsRangeMaximum")) != NULL) scalarsMax = dynamic_cast(this->GetDataNode()->GetProperty("ScalarsRangeMaximum"))->GetValue(); ls->m_VtkPolyDataMapper->SetScalarRange(scalarsMin,scalarsMax); ls->m_VtkPolyDataMapper->SetColorModeToMapScalars(); ls->m_VtkPolyDataMapper->ScalarVisibilityOn(); ls->m_Actor->GetProperty()->SetSpecular (1); ls->m_Actor->GetProperty()->SetSpecularPower (50); ls->m_Actor->GetProperty()->SetInterpolationToPhong(); } int deprecatedScalarMode = VTK_COLOR_MODE_DEFAULT; if(this->GetDataNode()->GetIntProperty("deprecated scalar mode", deprecatedScalarMode, renderer)) { ls->m_VtkPolyDataMapper->SetScalarMode(deprecatedScalarMode); ls->m_VtkPolyDataMapper->ScalarVisibilityOn(); ls->m_Actor->GetProperty()->SetSpecular (1); ls->m_Actor->GetProperty()->SetSpecularPower (50); //m_Actor->GetProperty()->SetInterpolationToPhong(); } // Check whether one or more ClippingProperty objects have been defined for // this node. Check both renderer specific and global property lists, since // properties in both should be considered. const PropertyList::PropertyMap *rendererProperties = this->GetDataNode()->GetPropertyList( renderer )->GetMap(); const PropertyList::PropertyMap *globalProperties = this->GetDataNode()->GetPropertyList( NULL )->GetMap(); // Add clipping planes (if any) ls->m_ClippingPlaneCollection->RemoveAllItems(); PropertyList::PropertyMap::const_iterator it; for ( it = rendererProperties->begin(); it != rendererProperties->end(); ++it ) { this->CheckForClippingProperty( renderer,(*it).second.GetPointer() ); } for ( it = globalProperties->begin(); it != globalProperties->end(); ++it ) { this->CheckForClippingProperty( renderer,(*it).second.GetPointer() ); } if ( ls->m_ClippingPlaneCollection->GetNumberOfItems() > 0 ) { ls->m_VtkPolyDataMapper->SetClippingPlanes( ls->m_ClippingPlaneCollection ); } else { ls->m_VtkPolyDataMapper->RemoveAllClippingPlanes(); } } vtkProp *mitk::ToFSurfaceVtkMapper3D::GetVtkProp(mitk::BaseRenderer *renderer) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); return ls->m_Actor; } void mitk::ToFSurfaceVtkMapper3D::CheckForClippingProperty( mitk::BaseRenderer* renderer, mitk::BaseProperty *property ) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); // m_Prop3D = ls->m_Actor; ClippingProperty *clippingProperty = dynamic_cast< ClippingProperty * >( property ); if ( (clippingProperty != NULL) && (clippingProperty->GetClippingEnabled()) ) { const Point3D &origin = clippingProperty->GetOrigin(); const Vector3D &normal = clippingProperty->GetNormal(); vtkPlane *clippingPlane = vtkPlane::New(); clippingPlane->SetOrigin( origin[0], origin[1], origin[2] ); clippingPlane->SetNormal( normal[0], normal[1], normal[2] ); ls->m_ClippingPlaneCollection->AddItem( clippingPlane ); clippingPlane->UnRegister( NULL ); } } void mitk::ToFSurfaceVtkMapper3D::SetDefaultPropertiesForVtkProperty(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite) { // Shading { node->AddProperty( "material.wireframeLineWidth", mitk::FloatProperty::New(1.0f) , renderer, overwrite ); node->AddProperty( "material.ambientCoefficient" , mitk::FloatProperty::New(0.05f) , renderer, overwrite ); node->AddProperty( "material.diffuseCoefficient" , mitk::FloatProperty::New(0.9f) , renderer, overwrite ); node->AddProperty( "material.specularCoefficient", mitk::FloatProperty::New(1.0f) , renderer, overwrite ); node->AddProperty( "material.specularPower" , mitk::FloatProperty::New(16.0f) , renderer, overwrite ); //node->AddProperty( "material.ambientColor" , mitk::ColorProperty::New(1.0f,1.0f,1.0f), renderer, overwrite ); //node->AddProperty( "material.diffuseColor" , mitk::ColorProperty::New(1.0f,1.0f,1.0f), renderer, overwrite ); //node->AddProperty( "material.specularColor" , mitk::ColorProperty::New(1.0f,1.0f,1.0f), renderer, overwrite ); node->AddProperty( "material.representation" , mitk::VtkRepresentationProperty::New() , renderer, overwrite ); node->AddProperty( "material.interpolation" , mitk::VtkInterpolationProperty::New() , renderer, overwrite ); } // Shaders { CoreServicePointer(mitk::CoreServices::GetShaderRepository())->AddDefaultProperties(node,renderer,overwrite); } } void mitk::ToFSurfaceVtkMapper3D::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite) { node->AddProperty( "color", mitk::ColorProperty::New(1.0f,1.0f,1.0f), renderer, overwrite ); node->AddProperty( "opacity", mitk::FloatProperty::New(1.0), renderer, overwrite ); mitk::ToFSurfaceVtkMapper3D::SetDefaultPropertiesForVtkProperty(node,renderer,overwrite); // Shading node->AddProperty( "scalar visibility", mitk::BoolProperty::New(false), renderer, overwrite ); node->AddProperty( "color mode", mitk::BoolProperty::New(false), renderer, overwrite ); node->AddProperty( "scalar mode", mitk::VtkScalarModeProperty::New(), renderer, overwrite ); mitk::Surface::Pointer surface = dynamic_cast(node->GetData()); if(surface.IsNotNull()) { if((surface->GetVtkPolyData() != 0) && (surface->GetVtkPolyData()->GetPointData() != NULL) && (surface->GetVtkPolyData()->GetPointData()->GetScalars() != 0)) { node->AddProperty( "scalar visibility", mitk::BoolProperty::New(true), renderer, overwrite ); node->AddProperty( "color mode", mitk::BoolProperty::New(true), renderer, overwrite ); } } Superclass::SetDefaultProperties(node, renderer, overwrite); } void mitk::ToFSurfaceVtkMapper3D::SetImmediateModeRenderingOn(int /*on*/) { /* if (m_VtkPolyDataMapper != NULL) m_VtkPolyDataMapper->SetImmediateModeRendering(on); */ } void mitk::ToFSurfaceVtkMapper3D::SetTexture(vtkImageData *img) { this->m_Texture = vtkSmartPointer::New(); - this->m_Texture->SetInput(img); + this->m_Texture->SetInputData(img); // MITK_INFO << "Neuer Code"; } vtkSmartPointer mitk::ToFSurfaceVtkMapper3D::GetTexture() { return this->m_Texture; } void mitk::ToFSurfaceVtkMapper3D::SetVtkScalarsToColors(vtkScalarsToColors* vtkScalarsToColors) { this->m_VtkScalarsToColors = vtkScalarsToColors; } vtkScalarsToColors* mitk::ToFSurfaceVtkMapper3D::GetVtkScalarsToColors() { return this->m_VtkScalarsToColors; }