diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/QmitkODFRenderWidget.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging/src/QmitkODFRenderWidget.cpp index 1332f10645..2fff514fea 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/QmitkODFRenderWidget.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/QmitkODFRenderWidget.cpp @@ -1,123 +1,124 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "QmitkODFRenderWidget.h" #include #include #include #include #include QmitkODFRenderWidget::QmitkODFRenderWidget(QWidget* parent, Qt::WindowFlags f): QWidget(parent, f) { //create Layouts QmitkODFRenderWidgetLayout = new QHBoxLayout( this ); //Set Layout to widget this->setLayout(QmitkODFRenderWidgetLayout); //Create RenderWindow m_RenderWindow = new QmitkRenderWindow(this, "odf render widget"); m_RenderWindow->setMaximumSize(300,300); m_RenderWindow->GetRenderer()->SetMapperID( mitk::BaseRenderer::Standard3D ); //m_RenderWindow->SetLayoutIndex( 3 ); QmitkODFRenderWidgetLayout->addWidget( m_RenderWindow ); } QmitkODFRenderWidget::~QmitkODFRenderWidget() { } void QmitkODFRenderWidget::GenerateODF( itk::OrientationDistributionFunction odf ) { try { m_Surface = mitk::Surface::New(); m_ds = mitk::StandaloneDataStorage::New(); m_Node = mitk::DataNode::New(); vtkPolyData* m_TemplateOdf = itk::OrientationDistributionFunction::GetBaseMesh(); vtkPolyData *polyData = vtkPolyData::New(); vtkPoints *points = vtkPoints::New(); vtkFloatArray *scalars = vtkFloatArray::New(); for (int i=0; iGetPoints()->GetPoint(i,p); double val = odf[i]; p[0] *= val; p[1] *= val; p[2] *= val; points->InsertPoint(i,p); scalars->InsertTuple1(i, 1-val); } polyData->SetPoints(points); vtkCellArray* polys = m_TemplateOdf->GetPolys(); polyData->SetPolys(polys); polyData->GetPointData()->SetScalars(scalars); polys->Delete(); scalars->Delete(); points->Delete(); m_Surface->SetVtkPolyData(polyData); m_Node->SetData(m_Surface); mitk::LookupTable::Pointer mitkLut = mitk::LookupTable::New(); vtkLookupTable* vtkLut = mitkLut->GetVtkLookupTable(); vtkLut->SetTableRange(0, 1); vtkLut->Build(); mitk::LookupTableProperty::Pointer mitkLutProp = mitk::LookupTableProperty::New(); mitkLutProp->SetLookupTable(mitkLut); m_Node->SetProperty( "LookupTable", mitkLutProp ); m_Node->SetProperty("scalar visibility", mitk::BoolProperty::New(true)); m_Node->SetProperty("color mode", mitk::BoolProperty::New(true)); m_Node->SetProperty("material.specularCoefficient", mitk::FloatProperty::New(0.5)); m_ds->Add(m_Node); m_RenderWindow->GetRenderer()->SetDataStorage( m_ds ); // adjust camera to current plane rotation mitk::Geometry2D::ConstPointer worldGeometry = mitk::GlobalInteraction::GetInstance()->GetFocus()->GetCurrentWorldGeometry2D(); mitk::PlaneGeometry::ConstPointer worldPlaneGeometry = dynamic_cast( worldGeometry.GetPointer() ); mitk::Vector3D normal = worldPlaneGeometry->GetNormal(); mitk::Vector3D up = worldPlaneGeometry->GetAxisVector(1); normal.Normalize(); up.Normalize(); vtkSmartPointer cam = vtkSmartPointer::New(); const double camPos[3] = {normal[0],normal[1],normal[2]}; const double camUp[3] = {up[0],up[1],up[2]}; cam->SetPosition(camPos); cam->SetViewUp(camUp); cam->SetParallelProjection(1); m_RenderWindow->GetRenderer()->GetVtkRenderer()->SetActiveCamera(cam); + m_RenderWindow->update(); } catch (...) { } } 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 ec4a591294..8cda17993f 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkODFDetailsView.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkODFDetailsView.cpp @@ -1,312 +1,308 @@ /*========================================================================= Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ // Blueberry #include #include // Qmitk #include "QmitkODFDetailsView.h" #include #include #include #include #include #include #include #include #include #include #include const std::string QmitkODFDetailsView::VIEW_ID = "org.mitk.views.odfdetails"; QmitkODFDetailsView::QmitkODFDetailsView() : QmitkFunctionality() , m_Controls( 0 ) , m_MultiWidget( NULL ) , m_OdfNormalization(0) , m_SelectedNode(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() { QmitkStdMultiWidget* MultiWidget = this->GetActiveStdMultiWidget(false); if(MultiWidget) { //unregister observers when view is destroyed if( MultiWidget->mitkWidget1 != NULL && m_SliceObserverTag1 != 0) { mitk::SliceNavigationController* slicer = MultiWidget->mitkWidget1->GetSliceNavigationController(); slicer->RemoveObserver( m_SliceObserverTag1 ); } if( MultiWidget->mitkWidget2 != NULL && m_SliceObserverTag2 != 0) { mitk::SliceNavigationController* slicer = MultiWidget->mitkWidget2->GetSliceNavigationController(); slicer->RemoveObserver( m_SliceObserverTag2 ); } if( MultiWidget->mitkWidget3!= NULL && m_SliceObserverTag3 != 0) { mitk::SliceNavigationController* slicer = MultiWidget->mitkWidget3->GetSliceNavigationController(); slicer->RemoveObserver( m_SliceObserverTag3 ); } } } void QmitkODFDetailsView::CreateQtPartControl( QWidget *parent ) { // build up qt view, unless already done if ( !m_Controls ) { // 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); } } void QmitkODFDetailsView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget) { m_MultiWidget = &stdMultiWidget; { 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 = 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 ); } { 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 ); } } void QmitkODFDetailsView::StdMultiWidgetNotAvailable() { { mitk::SliceNavigationController* slicer = m_MultiWidget->mitkWidget1->GetSliceNavigationController(); slicer->RemoveObserver( m_SliceObserverTag1 ); } { mitk::SliceNavigationController* slicer = m_MultiWidget->mitkWidget2->GetSliceNavigationController(); slicer->RemoveObserver( m_SliceObserverTag2 ); } { mitk::SliceNavigationController* slicer = m_MultiWidget->mitkWidget3->GetSliceNavigationController(); slicer->RemoveObserver( m_SliceObserverTag3 ); } m_MultiWidget = NULL; } void QmitkODFDetailsView::OnSelectionChanged( std::vector nodes ) { if (m_SelectedNode.IsNotNull()) m_SelectedNode->RemoveObserver( m_PropertyObserverTag ); UpdateOdf(); if (m_SelectedNode.IsNotNull()) { itk::ReceptorMemberCommand::Pointer command = itk::ReceptorMemberCommand::New(); command->SetCallbackFunction( this, &QmitkODFDetailsView::OnSliceChanged ); m_PropertyObserverTag = m_SelectedNode->AddObserver( itk::ModifiedEvent(), command ); } } void QmitkODFDetailsView::UpdateOdf() { try { m_Values.clear(); std::vector nodes = this->GetDataManagerSelection(); if (nodes.empty()) return; if (!nodes.front()) return; m_SelectedNode = nodes.front(); mitk::Image::Pointer img = dynamic_cast(nodes.front()->GetData()); if (!img) return; if (!m_MultiWidget) return; // ODF Normalization Property mitk::OdfNormalizationMethodProperty* nmp = dynamic_cast(nodes.front()->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; - itk::OrientationDistributionFunction originalOdf; mitk::Point3D world = m_MultiWidget->GetCrossPosition(); mitk::Point3D index; img->GetTimeSlicedGeometry()->WorldToIndex(world, index); float sum = 0; float max = itk::NumericTraits::min(); 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(nodes.front()->GetData()) && ( nodes.front()->GetData()->GetGeometry()->IsInside(world) ) ) { m_Controls->m_ODFRenderWidget->setVisible(true); m_Controls->m_OdfBox->setVisible(true); OdfVectorImgType::Pointer itkQBallImage = OdfVectorImgType::New(); mitk::CastToItkImage(dynamic_cast(nodes.front()->GetData()), itkQBallImage); OdfVectorImgType::IndexType ind; ind[0] = (int)(index[0]+0.5); ind[1] = (int)(index[1]+0.5); ind[2] = (int)(index[2]+0.5); OdfVectorImgType::PixelType pixel = itkQBallImage->GetPixel(ind); 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); } else if (dynamic_cast(nodes.front()->GetData())) { m_Controls->m_ODFRenderWidget->setVisible(true); m_Controls->m_OdfBox->setVisible(false); TensorImageType::Pointer itkQBallImage = TensorImageType::New(); mitk::CastToItkImage(dynamic_cast(nodes.front()->GetData()), itkQBallImage); TensorImageType::IndexType ind; ind[0] = (int)(index[0]+0.5); ind[1] = (int)(index[1]+0.5); ind[2] = (int)(index[2]+0.5); TensorImageType::PixelType pixel = itkQBallImage->GetPixel(ind); float tensorelems[6] = { (float)pixel[0], (float)pixel[1], (float)pixel[2], (float)pixel[3], (float)pixel[4], (float)pixel[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[0][0])+"\n "+QString::number(eigenVectors[1][0])+"\n "+QString::number(eigenVectors[2][0])+"\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"; } else { m_Controls->m_ODFRenderWidget->setVisible(false); m_Controls->m_OdfBox->setVisible(false); overviewText += "Please select a Q-Ball or tensor image\n"; } - - originalOdf = odf; + 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_ODFDetailsWidget->SetParameters(originalOdf); 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(); }