diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/manifest_headers.cmake b/Plugins/org.mitk.gui.qt.diffusionimaging/manifest_headers.cmake index 587c6184fd..f9deaced2c 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/manifest_headers.cmake +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/manifest_headers.cmake @@ -1,5 +1,5 @@ set(Plugin-Name "MITK Diffusion Imaging") set(Plugin-Version "0.1") set(Plugin-Vendor "DKFZ, Medical and Biological Informatics") set(Plugin-ContactAddress "http://www.mitk.org") -set(Require-Plugin org.mitk.gui.qt.common.legacy org.mitk.diffusionimaging) +set(Require-Plugin org.mitk.gui.qt.common.legacy org.mitk.gui.qt.common org.mitk.diffusionimaging) diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkODFDetailsView.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkODFDetailsView.cpp index 375f471e46..73547468e5 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkODFDetailsView.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkODFDetailsView.cpp @@ -1,366 +1,375 @@ /*=================================================================== 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. ===================================================================*/ // Blueberry #include #include // Qmitk #include "QmitkODFDetailsView.h" -#include #include #include #include #include #include #include #include #include #include #include #include const std::string QmitkODFDetailsView::VIEW_ID = "org.mitk.views.odfdetails"; QmitkODFDetailsView::QmitkODFDetailsView() - : QmitkFunctionality() + : QmitkAbstractView() , m_Controls( 0 ) - , m_MultiWidget( NULL ) , m_OdfNormalization(0) , m_ImageNode(NULL) { m_VtkActor = vtkActor::New(); m_VtkMapper = vtkPolyDataMapper::New(); m_Renderer = vtkRenderer::New(); m_VtkRenderWindow = vtkRenderWindow::New(); m_RenderWindowInteractor = vtkRenderWindowInteractor::New(); m_Camera = vtkCamera::New(); m_VtkRenderWindow->SetSize(300,300); + } QmitkODFDetailsView::~QmitkODFDetailsView() { - + if (m_ImageNode.IsNotNull()) + m_ImageNode->RemoveObserver( m_PropertyObserverTag ); } -void QmitkODFDetailsView::CreateQtPartControl( QWidget *parent ) +void QmitkODFDetailsView::Visible() { - // build up qt view, unless already done - if ( !m_Controls ) + mitk::IRenderWindowPart* renderWindow = this->GetRenderWindowPart(); + + if (renderWindow) { - // create GUI widgets from the Qt Designer's .ui file - m_Controls = new Ui::QmitkODFDetailsViewControls; - m_Controls->setupUi( parent ); - m_Controls->m_OdfBox->setVisible(false); - m_Controls->m_ODFRenderWidget->setVisible(false); - } -} + { + mitk::SliceNavigationController* slicer = renderWindow->GetQmitkRenderWindow(QString("axial"))->GetSliceNavigationController(); + itk::ReceptorMemberCommand::Pointer command = itk::ReceptorMemberCommand::New(); + command->SetCallbackFunction( this, &QmitkODFDetailsView::OnSliceChanged ); + m_SliceObserverTag1 = slicer->AddObserver( mitk::SliceNavigationController::GeometrySliceEvent(NULL, 0), command ); + } -void QmitkODFDetailsView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget) -{ - m_MultiWidget = &stdMultiWidget; + { + mitk::SliceNavigationController* slicer = renderWindow->GetQmitkRenderWindow(QString("sagittal"))->GetSliceNavigationController(); + itk::ReceptorMemberCommand::Pointer command = itk::ReceptorMemberCommand::New(); + command->SetCallbackFunction( this, &QmitkODFDetailsView::OnSliceChanged ); + m_SliceObserverTag2 = slicer->AddObserver( mitk::SliceNavigationController::GeometrySliceEvent(NULL, 0), command ); + } - { - mitk::SliceNavigationController* slicer = m_MultiWidget->mitkWidget1->GetSliceNavigationController(); - itk::ReceptorMemberCommand::Pointer command = itk::ReceptorMemberCommand::New(); - command->SetCallbackFunction( this, &QmitkODFDetailsView::OnSliceChanged ); - m_SliceObserverTag1 = slicer->AddObserver( mitk::SliceNavigationController::GeometrySliceEvent(NULL, 0), command ); + { + mitk::SliceNavigationController* slicer = renderWindow->GetQmitkRenderWindow(QString("coronal"))->GetSliceNavigationController(); + itk::ReceptorMemberCommand::Pointer command = itk::ReceptorMemberCommand::New(); + command->SetCallbackFunction( this, &QmitkODFDetailsView::OnSliceChanged ); + m_SliceObserverTag3 = slicer->AddObserver( mitk::SliceNavigationController::GeometrySliceEvent(NULL, 0), command ); + } } +} - { - mitk::SliceNavigationController* slicer = m_MultiWidget->mitkWidget2->GetSliceNavigationController(); - itk::ReceptorMemberCommand::Pointer command = itk::ReceptorMemberCommand::New(); - command->SetCallbackFunction( this, &QmitkODFDetailsView::OnSliceChanged ); - m_SliceObserverTag2 = slicer->AddObserver( mitk::SliceNavigationController::GeometrySliceEvent(NULL, 0), command ); - } +void QmitkODFDetailsView::Hidden() +{ + mitk::IRenderWindowPart* renderWindow = this->GetRenderWindowPart(); + if (renderWindow) { - mitk::SliceNavigationController* slicer = m_MultiWidget->mitkWidget3->GetSliceNavigationController(); - itk::ReceptorMemberCommand::Pointer command = itk::ReceptorMemberCommand::New(); - command->SetCallbackFunction( this, &QmitkODFDetailsView::OnSliceChanged ); - m_SliceObserverTag3 = slicer->AddObserver( mitk::SliceNavigationController::GeometrySliceEvent(NULL, 0), command ); + mitk::SliceNavigationController* slicer = renderWindow->GetQmitkRenderWindow(QString("axial"))->GetSliceNavigationController(); + slicer->RemoveObserver(m_SliceObserverTag1); + slicer = renderWindow->GetQmitkRenderWindow(QString("sagittal"))->GetSliceNavigationController(); + slicer->RemoveObserver(m_SliceObserverTag2); + slicer = renderWindow->GetQmitkRenderWindow(QString("coronal"))->GetSliceNavigationController(); + slicer->RemoveObserver(m_SliceObserverTag3); } } -void QmitkODFDetailsView::StdMultiWidgetNotAvailable() +void QmitkODFDetailsView::Activated() { +} - { - mitk::SliceNavigationController* slicer = m_MultiWidget->mitkWidget1->GetSliceNavigationController(); - slicer->RemoveObserver( m_SliceObserverTag1 ); - } +void QmitkODFDetailsView::Deactivated() +{ +} - { - mitk::SliceNavigationController* slicer = m_MultiWidget->mitkWidget2->GetSliceNavigationController(); - slicer->RemoveObserver( m_SliceObserverTag2 ); - } +void QmitkODFDetailsView::SetFocus() +{ + this->m_Controls->m_ODFRenderWidget->setFocus(); +} +void QmitkODFDetailsView::CreateQtPartControl( QWidget *parent ) +{ + // build up qt view, unless already done + if ( !m_Controls ) { - mitk::SliceNavigationController* slicer = m_MultiWidget->mitkWidget3->GetSliceNavigationController(); - slicer->RemoveObserver( m_SliceObserverTag3 ); + // create GUI widgets from the Qt Designer's .ui file + m_Controls = new Ui::QmitkODFDetailsViewControls; + m_Controls->setupUi( parent ); + m_Controls->m_OdfBox->setVisible(false); + m_Controls->m_ODFRenderWidget->setVisible(false); } - - m_MultiWidget = NULL; } -void QmitkODFDetailsView::OnSelectionChanged( std::vector nodes ) +void QmitkODFDetailsView::OnSelectionChanged( berry::IWorkbenchPart::Pointer source, + const QList& nodes ) { if (m_ImageNode.IsNotNull()) m_ImageNode->RemoveObserver( m_PropertyObserverTag ); m_Controls->m_InputData->setTitle("Please Select Input Data"); m_Controls->m_InputImageLabel->setText("mandatory"); m_ImageNode = NULL; // iterate selection - for( std::vector::iterator it = nodes.begin(); it != nodes.end(); ++it ) + foreach( mitk::DataNode::Pointer node, nodes ) { - mitk::DataNode::Pointer node = *it; if( node.IsNotNull() && (dynamic_cast(node->GetData()) || dynamic_cast(node->GetData())) ) { m_Controls->m_InputImageLabel->setText(node->GetName().c_str()); m_ImageNode = node; } } UpdateOdf(); if (m_ImageNode.IsNotNull()) { itk::ReceptorMemberCommand::Pointer command = itk::ReceptorMemberCommand::New(); command->SetCallbackFunction( this, &QmitkODFDetailsView::OnSliceChanged ); m_PropertyObserverTag = m_ImageNode->AddObserver( itk::ModifiedEvent(), command ); m_Controls->m_InputData->setTitle("Input Data"); } } void QmitkODFDetailsView::UpdateOdf() { - try { m_Controls->m_OverviewBox->setVisible(true); - if (m_ImageNode.IsNull() || !m_MultiWidget) + if (m_ImageNode.IsNull() || !this->GetRenderWindowPart()) { m_Controls->m_ODFRenderWidget->setVisible(false); m_Controls->m_OdfBox->setVisible(false); m_Controls->m_OverviewBox->setVisible(false); return; } // restore the input image label ( needed in case the last run resulted into an exception ) m_Controls->m_InputImageLabel->setText(m_ImageNode->GetName().c_str()); // ODF Normalization Property mitk::OdfNormalizationMethodProperty* nmp = dynamic_cast(m_ImageNode->GetProperty( "Normalization" )); if(nmp) m_OdfNormalization = nmp->GetNormalization(); m_TemplateOdf = itk::OrientationDistributionFunction::GetBaseMesh(); m_OdfTransform = vtkSmartPointer::New(); m_OdfTransform->Identity(); m_OdfVals = vtkSmartPointer::New(); m_OdfSource = vtkSmartPointer::New(); itk::OrientationDistributionFunction odf; - mitk::Point3D world = m_MultiWidget->GetCrossPosition(); + mitk::Point3D world = this->GetRenderWindowPart()->GetSelectedPosition(); mitk::Point3D index; mitk::Image::Pointer img = dynamic_cast(m_ImageNode->GetData()); unsigned int *img_dimension = img->GetDimensions(); img->GetGeometry()->WorldToIndex(world, index); float sum = 0; float max = itk::NumericTraits::NonpositiveMin(); float min = itk::NumericTraits::max(); QString values; QString overviewText; // check if dynamic_cast successfull and if the crosshair position is inside of the geometry of the ODF data // otherwise possible crash for a scenario with multiple nodes if (dynamic_cast(m_ImageNode->GetData()) && ( m_ImageNode->GetData()->GetGeometry()->IsInside(world) ) ) { m_Controls->m_ODFRenderWidget->setVisible(true); m_Controls->m_OdfBox->setVisible(true); try { const mitk::QBallImage* qball_image = dynamic_cast< mitk::QBallImage* >( m_ImageNode->GetData() ); // get access to the qball image data with explicitely allowing exceptions if memory locked mitk::ImageReadAccessor readAccess( qball_image, qball_image->GetVolumeData(0), mitk::ImageAccessorBase::ExceptionIfLocked ); const float* qball_cPtr = static_cast< const float*>(readAccess.GetData()); OdfVectorImgType::IndexType ind; ind[0] = (int)(index[0]+0.5); ind[1] = (int)(index[1]+0.5); ind[2] = (int)(index[2]+0.5); // pixel size = QBALL_ODFSIZE // position offset = standard offset unsigned int offset_to_data = QBALL_ODFSIZE * (ind[2] * img_dimension[1] * img_dimension[0] + ind[1] * img_dimension[0] + ind[0]); const float *pixel_data = qball_cPtr + offset_to_data; for (int i=0; imax) max = val; if (val pd = odf.GetDirection(odf.GetPrincipleDiffusionDirection()); overviewText += "Main Diffusion:\n "+QString::number(pd[0])+"\n "+QString::number(pd[1])+"\n "+QString::number(pd[2])+"\n"; m_Controls->m_OdfValuesTextEdit->setText(values); m_Controls->m_OverviewTextEdit->setVisible(true); } catch( mitk::Exception &e ) { MITK_WARN << "LOCKED : " << e.what(); m_Controls->m_ODFRenderWidget->setVisible(false); m_Controls->m_OdfBox->setVisible(false); m_Controls->m_OverviewTextEdit->setVisible(false); // reset the selection m_Controls->m_InputImageLabel->setText("Click image to restore rendering!"); } } else if (dynamic_cast(m_ImageNode->GetData())) { m_Controls->m_ODFRenderWidget->setVisible(true); m_Controls->m_OdfBox->setVisible(false); const mitk::TensorImage* qball_image = dynamic_cast< mitk::TensorImage*>(m_ImageNode->GetData()); // pixel access block try { // get access to the qball image data with explicitely allowing exceptions if memory locked mitk::ImageReadAccessor readAccess( qball_image, qball_image->GetVolumeData(0), mitk::ImageAccessorBase::ExceptionIfLocked ); const float* qball_cPtr = static_cast< const float*>(readAccess.GetData()); TensorImageType::IndexType ind; ind[0] = (int)(index[0]+0.5); ind[1] = (int)(index[1]+0.5); ind[2] = (int)(index[2]+0.5); // 6 - tensorsize // remaining computation - standard offset unsigned int offset_to_data = 6 * (ind[2] * img_dimension[1] * img_dimension[0] + ind[1] * img_dimension[0] + ind[0]); const float *pixel_data = qball_cPtr + offset_to_data; float tensorelems[6] = { *(pixel_data ), *(pixel_data + 1), *(pixel_data + 2), *(pixel_data + 3), *(pixel_data + 4), *(pixel_data + 5), }; itk::DiffusionTensor3D tensor(tensorelems); odf.InitFromTensor(tensor); /** Array of eigen-values. */ typedef itk::FixedArray EigenValuesArrayType; /** Matrix of eigen-vectors. */ typedef itk::Matrix MatrixType; typedef itk::Matrix EigenVectorsMatrixType; EigenValuesArrayType eigenValues; EigenVectorsMatrixType eigenvectors; QString pos = QString::number(ind[0])+", "+QString::number(ind[1])+", "+QString::number(ind[2]); overviewText += "Coordinates: "+pos+"\n"; overviewText += "FA: "+QString::number(tensor.GetFractionalAnisotropy())+"\n"; overviewText += "RA: "+QString::number(tensor.GetRelativeAnisotropy())+"\n"; overviewText += "Trace: "+QString::number(tensor.GetTrace())+"\n"; tensor.ComputeEigenAnalysis(eigenValues,eigenvectors); overviewText += "Eigenvalues:\n "+QString::number(eigenValues[2])+"\n "+QString::number(eigenValues[1])+"\n "+QString::number(eigenValues[0])+"\n"; overviewText += "Main Diffusion:\n "+QString::number(eigenvectors(2, 0))+"\n "+QString::number(eigenvectors(2, 1))+"\n "+QString::number(eigenvectors(2, 2))+"\n"; overviewText += "Values:\n "+QString::number(tensorelems[0])+"\n "+QString::number(tensorelems[1])+"\n "+QString::number(tensorelems[2])+"\n "+QString::number(tensorelems[3])+"\n "+QString::number(tensorelems[4])+"\n "+QString::number(tensorelems[5])+"\n "+"\n"; m_Controls->m_OverviewTextEdit->setVisible(true); } // end pixel access block catch(mitk::Exception &e ) { MITK_WARN << "LOCKED : " << e.what(); m_Controls->m_ODFRenderWidget->setVisible(false); m_Controls->m_OdfBox->setVisible(false); m_Controls->m_OverviewTextEdit->setVisible(false); // reset the selection m_Controls->m_InputImageLabel->setText("Click image to restore rendering!"); } } else { m_Controls->m_ODFRenderWidget->setVisible(false); m_Controls->m_OdfBox->setVisible(false); overviewText += "Please reinit image geometry.\n"; } // proceed only if the render widget is visible which indicates that the // predecessing computations were successfull if( m_Controls->m_ODFRenderWidget->isVisible() ) { m_Controls->m_ODFDetailsWidget->SetParameters(odf); switch(m_OdfNormalization) { case 0: odf = odf.MinMaxNormalize(); break; case 1: odf = odf.MaxNormalize(); break; case 2: odf = odf.MaxNormalize(); break; default: odf = odf.MinMaxNormalize(); } m_Controls->m_ODFRenderWidget->GenerateODF(odf); m_Controls->m_OverviewTextEdit->setText(overviewText.toStdString().c_str()); } } catch(...) { QMessageBox::critical(0, "Error", "Data could not be analyzed. The image might be corrupted."); } } void QmitkODFDetailsView::OnSliceChanged(const itk::EventObject& /*e*/) { UpdateOdf(); } diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkODFDetailsView.h b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkODFDetailsView.h index 02f17d5060..b4386d9a92 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkODFDetailsView.h +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkODFDetailsView.h @@ -1,115 +1,119 @@ /*=================================================================== 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 _QMITKQmitkODFDetailsView_H_INCLUDED #define _QMITKQmitkODFDetailsView_H_INCLUDED #include -#include +#include +#include "mitkILifecycleAwarePart.h" #include "ui_QmitkODFDetailsViewControls.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include /*! \brief View displaying details of the orientation distribution function in the voxel at the current crosshair position. \sa QmitkFunctionality \ingroup Functionalities */ -class QmitkODFDetailsView : public QmitkFunctionality +class QmitkODFDetailsView : public QmitkAbstractView, public mitk::ILifecycleAwarePart { // this is needed for all Qt objects that should have a Qt meta-object // (everything that derives from QObject and wants to have signal/slots) Q_OBJECT public: static const std::string VIEW_ID; QmitkODFDetailsView(); virtual ~QmitkODFDetailsView(); typedef float TOdfPixelType; typedef itk::Vector OdfVectorType; typedef itk::Image OdfVectorImgType; typedef itk::DiffusionTensor3D< TOdfPixelType > TensorPixelType; typedef itk::Image< TensorPixelType, 3 > TensorImageType; virtual void CreateQtPartControl(QWidget *parent); - virtual void StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget); - virtual void StdMultiWidgetNotAvailable(); - void OnSliceChanged(const itk::EventObject& e); protected slots: protected: /// \brief called by QmitkFunctionality when DataManager's selection has changed - virtual void OnSelectionChanged( std::vector nodes ); + virtual void OnSelectionChanged( berry::IWorkbenchPart::Pointer source, + const QList& nodes ); + + virtual void SetFocus(); + void Visible(); + void Hidden(); + void Activated(); + void Deactivated(); void UpdateOdf(); ///< called if slice position or datamanager selection has changed Ui::QmitkODFDetailsViewControls* m_Controls; - QmitkStdMultiWidget* m_MultiWidget; /** observer flags */ int m_SliceObserverTag1; int m_SliceObserverTag2; int m_SliceObserverTag3; int m_PropertyObserverTag; /** ODF related variables like mesh structure, values etc. */ vtkPolyData* m_TemplateOdf; ///< spherical base mesh vtkSmartPointer m_OdfTransform; vtkSmartPointer m_OdfVals; vtkSmartPointer m_OdfSource; int m_OdfNormalization; ///< normalization method defined in the visualization view /** rendering of the ODF */ vtkActor* m_VtkActor; vtkPolyDataMapper* m_VtkMapper; vtkRenderer* m_Renderer; vtkRenderWindow* m_VtkRenderWindow; vtkRenderWindowInteractor* m_RenderWindowInteractor; vtkCamera* m_Camera; mitk::DataNode::Pointer m_ImageNode; }; #endif // _QmitkODFDetailsView_H_INCLUDED