diff --git a/Modules/QtWidgetsExt/src/QmitkSliderNavigatorWidget.cpp b/Modules/QtWidgetsExt/src/QmitkSliderNavigatorWidget.cpp
index 9c77986ca1..03709e0ffe 100644
--- a/Modules/QtWidgetsExt/src/QmitkSliderNavigatorWidget.cpp
+++ b/Modules/QtWidgetsExt/src/QmitkSliderNavigatorWidget.cpp
@@ -1,259 +1,263 @@
/*===================================================================
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 "QmitkSliderNavigatorWidget.h"
QmitkSliderNavigatorWidget::QmitkSliderNavigatorWidget(QWidget *parent, Qt::WindowFlags f) : QWidget(parent, f)
{
this->setupUi(this);
// this avoids trying to use m_Stepper until it is set to something != NULL
// (additionally to the avoiding recursions during refetching)
m_InRefetch = true;
// Hide slider labeling -- until it is explicitly activated
this->ShowLabels(false);
// Set label values as invalid (N/A)
this->SetLabelValuesValid(false, false);
m_HasLabels = false;
m_HasLabelUnit = true;
m_InverseDirection = false;
}
void QmitkSliderNavigatorWidget::Refetch()
{
if (!m_InRefetch)
{
m_InRefetch = true;
m_Slider->setMinimum(0);
m_Slider->setMaximum(m_Stepper->GetSteps() - 1);
if (m_InverseDirection)
{
m_Slider->setValue(m_Stepper->GetSteps() - 1 - m_Stepper->GetPos());
}
else
{
m_Slider->setValue(m_Stepper->GetPos());
}
m_SpinBox->setMinimum(0);
m_SpinBox->setMaximum(m_Stepper->GetSteps() - 1);
if (m_InverseDirection)
{
m_SpinBox->setValue(m_Stepper->GetSteps() - 1 - m_Stepper->GetPos());
}
else
{
m_SpinBox->setValue(m_Stepper->GetPos());
}
if (m_Stepper->HasRange() && m_HasLabels)
{
// Show slider with labels according to below settings
m_SliderLabelLeft->setHidden(false);
m_SliderLabelRight->setHidden(false);
if (m_Stepper->HasValidRange())
{
this->SetLabelValuesValid(true, true);
this->SetLabelValues(m_Stepper->GetRangeMin(), m_Stepper->GetRangeMax());
}
else
{
this->SetLabelValuesValid(false, false);
}
if (m_Stepper->HasUnitName())
{
this->SetLabelUnit(m_Stepper->GetUnitName());
}
}
else
{
// Show slider without any labels
m_SliderLabelLeft->setHidden(true);
m_SliderLabelRight->setHidden(true);
}
// Update GUI according to above settings
this->SetLabels();
m_InRefetch = false;
}
}
void QmitkSliderNavigatorWidget::SetStepper(mitk::Stepper *stepper)
{
m_Stepper = stepper;
// this avoids trying to use m_Stepper until it is set to something != NULL
// (additionally to the avoiding recursions during refetching)
m_InRefetch = (stepper == nullptr);
}
void QmitkSliderNavigatorWidget::slider_valueChanged(int)
{
if (!m_InRefetch)
{
if (m_InverseDirection)
{
m_Stepper->SetPos(m_Stepper->GetSteps() - 1 - m_Slider->value());
}
else
{
m_Stepper->SetPos(m_Slider->value());
}
this->Refetch();
}
}
void QmitkSliderNavigatorWidget::ShowLabels(bool show)
{
m_HasLabels = show;
}
void QmitkSliderNavigatorWidget::ShowLabelUnit(bool show)
{
m_HasLabelUnit = show;
}
void QmitkSliderNavigatorWidget::SetLabelValues(float min, float max)
{
m_MinValue = min;
m_MaxValue = max;
}
void QmitkSliderNavigatorWidget::SetLabelValuesValid(bool minValid, bool maxValid)
{
m_MinValueValid = minValid;
m_MaxValueValid = maxValid;
}
void QmitkSliderNavigatorWidget::SetLabelUnit(const char *unit)
{
m_LabelUnit = unit;
}
QString QmitkSliderNavigatorWidget::GetLabelUnit()
{
return m_LabelUnit;
}
QString QmitkSliderNavigatorWidget::ClippedValueToString(float value)
{
if (value < -10000000.0)
{
return "-INF";
}
else if (value > 10000000.0)
{
return "+INF";
}
else
{
return QString::number(value, 'f', 2);
}
}
QString QmitkSliderNavigatorWidget::GetMinValueLabel()
{
if (m_MinValueValid)
{
return this->ClippedValueToString(m_MinValue);
}
else
{
return "N/A";
}
}
QString QmitkSliderNavigatorWidget::GetMaxValueLabel()
{
if (m_MaxValueValid)
{
return this->ClippedValueToString(m_MaxValue);
}
else
{
return "N/A";
}
}
void QmitkSliderNavigatorWidget::SetLabels()
{
QString minText = "
" + this->GetMinValueLabel();
QString maxText = "" + this->GetMaxValueLabel();
if (m_HasLabelUnit)
{
minText += " " + this->GetLabelUnit();
maxText += " " + this->GetLabelUnit();
}
if (m_MinValueValid)
{
minText += "
(pos 0)";
}
if (m_MaxValueValid)
{
maxText += "
(pos " + QString::number(m_Stepper->GetSteps() - 1) + ")";
}
minText += "
";
maxText += "
";
m_SliderLabelLeft->setText(minText);
m_SliderLabelRight->setText(maxText);
}
void QmitkSliderNavigatorWidget::spinBox_valueChanged(int)
{
if (!m_InRefetch)
{
if (m_InverseDirection)
{
m_Stepper->SetPos(m_Stepper->GetSteps() - 1 - m_SpinBox->value());
}
else
{
m_Stepper->SetPos(m_SpinBox->value());
}
this->Refetch();
}
}
int QmitkSliderNavigatorWidget::GetPos()
{
return m_Stepper->GetPos();
}
void QmitkSliderNavigatorWidget::SetPos(int val)
{
if (!m_InRefetch)
{
m_Stepper->SetPos(val);
}
}
void QmitkSliderNavigatorWidget::SetInverseDirection(bool inverseDirection)
{
- m_InverseDirection = inverseDirection;
+ if (inverseDirection != m_InverseDirection)
+ {
+ m_InverseDirection = inverseDirection;
+ this->Refetch();
+ }
}
diff --git a/Plugins/org.mitk.gui.qt.imagenavigator/src/internal/QmitkImageNavigatorView.cpp b/Plugins/org.mitk.gui.qt.imagenavigator/src/internal/QmitkImageNavigatorView.cpp
index 0cfef766f7..960b3bd981 100644
--- a/Plugins/org.mitk.gui.qt.imagenavigator/src/internal/QmitkImageNavigatorView.cpp
+++ b/Plugins/org.mitk.gui.qt.imagenavigator/src/internal/QmitkImageNavigatorView.cpp
@@ -1,537 +1,605 @@
/*===================================================================
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 "QmitkImageNavigatorView.h"
+#include
+
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
const std::string QmitkImageNavigatorView::VIEW_ID = "org.mitk.views.imagenavigator";
static mitk::DataNode::Pointer GetTopLayerNode(const mitk::DataStorage::SetOfObjects::ConstPointer nodes, const mitk::Point3D &position, mitk::BaseRenderer* renderer)
{
mitk::DataNode::Pointer node;
int maxlayer = -32768;
if(nodes.IsNotNull())
{
// find node with largest layer, that is the node shown on top in the render window
for (unsigned int x = 0; x < nodes->size(); x++)
{
if ( (nodes->at(x)->GetData()->GetGeometry() != NULL) &&
nodes->at(x)->GetData()->GetGeometry()->IsInside(position) )
{
int layer = 0;
if(!(nodes->at(x)->GetIntProperty("layer", layer))) continue;
if(layer > maxlayer)
{
if( static_cast(nodes->at(x))->IsVisible(renderer) )
{
node = nodes->at(x);
maxlayer = layer;
}
}
}
}
}
return node;
}
QmitkImageNavigatorView::QmitkImageNavigatorView()
: m_AxialStepper(0)
, m_SagittalStepper(0)
, m_FrontalStepper(0)
, m_TimeStepper(0)
, m_Parent(0)
, m_IRenderWindowPart(0)
{
}
QmitkImageNavigatorView::~QmitkImageNavigatorView()
{
}
void QmitkImageNavigatorView::CreateQtPartControl(QWidget *parent)
{
// create GUI widgets
m_Parent = parent;
m_Controls.setupUi(parent);
- m_Controls.m_SliceNavigatorAxial->SetInverseDirection(true);
connect(m_Controls.m_XWorldCoordinateSpinBox, SIGNAL(valueChanged(double)), this, SLOT(OnMillimetreCoordinateValueChanged()));
connect(m_Controls.m_YWorldCoordinateSpinBox, SIGNAL(valueChanged(double)), this, SLOT(OnMillimetreCoordinateValueChanged()));
connect(m_Controls.m_ZWorldCoordinateSpinBox, SIGNAL(valueChanged(double)), this, SLOT(OnMillimetreCoordinateValueChanged()));
m_Parent->setEnabled(false);
mitk::IRenderWindowPart* renderPart = this->GetRenderWindowPart();
this->RenderWindowPartActivated(renderPart);
}
void QmitkImageNavigatorView::SetFocus ()
{
m_Controls.m_XWorldCoordinateSpinBox->setFocus();
}
void QmitkImageNavigatorView::RenderWindowPartActivated(mitk::IRenderWindowPart* renderWindowPart)
{
if (this->m_IRenderWindowPart != renderWindowPart)
{
this->m_IRenderWindowPart = renderWindowPart;
this->m_Parent->setEnabled(true);
QmitkRenderWindow* renderWindow = renderWindowPart->GetQmitkRenderWindow("axial");
if (renderWindow)
{
if (m_AxialStepper) m_AxialStepper->deleteLater();
m_AxialStepper = new QmitkStepperAdapter(m_Controls.m_SliceNavigatorAxial,
renderWindow->GetSliceNavigationController()->GetSlice(),
"sliceNavigatorAxialFromSimpleExample");
m_Controls.m_SliceNavigatorAxial->setEnabled(true);
m_Controls.m_AxialLabel->setEnabled(true);
m_Controls.m_ZWorldCoordinateSpinBox->setEnabled(true);
connect(m_AxialStepper, SIGNAL(Refetch()), this, SLOT(OnRefetch()));
connect(m_AxialStepper, SIGNAL(Refetch()), this, SLOT(UpdateStatusBar()));
}
else
{
m_Controls.m_SliceNavigatorAxial->setEnabled(false);
m_Controls.m_AxialLabel->setEnabled(false);
m_Controls.m_ZWorldCoordinateSpinBox->setEnabled(false);
}
renderWindow = renderWindowPart->GetQmitkRenderWindow("sagittal");
if (renderWindow)
{
if (m_SagittalStepper) m_SagittalStepper->deleteLater();
m_SagittalStepper = new QmitkStepperAdapter(m_Controls.m_SliceNavigatorSagittal,
renderWindow->GetSliceNavigationController()->GetSlice(),
"sliceNavigatorSagittalFromSimpleExample");
m_Controls.m_SliceNavigatorSagittal->setEnabled(true);
m_Controls.m_SagittalLabel->setEnabled(true);
m_Controls.m_YWorldCoordinateSpinBox->setEnabled(true);
connect(m_SagittalStepper, SIGNAL(Refetch()), this, SLOT(OnRefetch()));
connect(m_SagittalStepper, SIGNAL(Refetch()), this, SLOT(UpdateStatusBar()));
}
else
{
m_Controls.m_SliceNavigatorSagittal->setEnabled(false);
m_Controls.m_SagittalLabel->setEnabled(false);
m_Controls.m_YWorldCoordinateSpinBox->setEnabled(false);
}
renderWindow = renderWindowPart->GetQmitkRenderWindow("coronal");
if (renderWindow)
{
if (m_FrontalStepper) m_FrontalStepper->deleteLater();
m_FrontalStepper = new QmitkStepperAdapter(m_Controls.m_SliceNavigatorFrontal,
renderWindow->GetSliceNavigationController()->GetSlice(),
"sliceNavigatorFrontalFromSimpleExample");
m_Controls.m_SliceNavigatorFrontal->setEnabled(true);
m_Controls.m_CoronalLabel->setEnabled(true);
m_Controls.m_XWorldCoordinateSpinBox->setEnabled(true);
connect(m_FrontalStepper, SIGNAL(Refetch()), this, SLOT(OnRefetch()));
connect(m_FrontalStepper, SIGNAL(Refetch()), this, SLOT(UpdateStatusBar()));
}
else
{
m_Controls.m_SliceNavigatorFrontal->setEnabled(false);
m_Controls.m_CoronalLabel->setEnabled(false);
m_Controls.m_XWorldCoordinateSpinBox->setEnabled(false);
}
mitk::SliceNavigationController* timeController = renderWindowPart->GetTimeNavigationController();
if (timeController)
{
if (m_TimeStepper) m_TimeStepper->deleteLater();
m_TimeStepper = new QmitkStepperAdapter(m_Controls.m_SliceNavigatorTime,
timeController->GetTime(),
"sliceNavigatorTimeFromSimpleExample");
m_Controls.m_SliceNavigatorTime->setEnabled(true);
m_Controls.m_TimeLabel->setEnabled(true);
connect(m_TimeStepper, SIGNAL(Refetch()), this, SLOT(UpdateStatusBar()));
}
else
{
m_Controls.m_SliceNavigatorTime->setEnabled(false);
m_Controls.m_TimeLabel->setEnabled(false);
}
+
+ this->OnRefetch();
+ this->UpdateStatusBar();
}
}
void QmitkImageNavigatorView::UpdateStatusBar()
{
if (m_IRenderWindowPart != nullptr)
{
mitk::Point3D position = m_IRenderWindowPart->GetSelectedPosition();
mitk::BaseRenderer::Pointer renderer = mitk::BaseRenderer::GetInstance(m_IRenderWindowPart->GetActiveQmitkRenderWindow()->GetVtkRenderWindow());
mitk::TNodePredicateDataType::Pointer isImageData = mitk::TNodePredicateDataType::New();
mitk::DataStorage::SetOfObjects::ConstPointer nodes = this->GetDataStorage()->GetSubset(isImageData).GetPointer();
if (nodes.IsNotNull())
{
mitk::Image::Pointer image3D;
mitk::DataNode::Pointer node;
mitk::DataNode::Pointer topSourceNode;
int component = 0;
node = GetTopLayerNode(nodes, position, renderer);
if (node.IsNotNull())
{
bool isBinary(false);
node->GetBoolProperty("binary", isBinary);
if (isBinary)
{
mitk::DataStorage::SetOfObjects::ConstPointer sourcenodes = this->GetDataStorage()->GetSources(node, NULL, true);
if (!sourcenodes->empty())
{
topSourceNode = GetTopLayerNode(sourcenodes, position, renderer);
}
if (topSourceNode.IsNotNull())
{
image3D = dynamic_cast(topSourceNode->GetData());
topSourceNode->GetIntProperty("Image.Displayed Component", component);
}
else
{
image3D = dynamic_cast(node->GetData());
node->GetIntProperty("Image.Displayed Component", component);
}
}
else
{
image3D = dynamic_cast(node->GetData());
node->GetIntProperty("Image.Displayed Component", component);
}
}
// get the position and gray value from the image and build up status bar text
if (image3D.IsNotNull())
{
itk::Index<3> p;
image3D->GetGeometry()->WorldToIndex(position, p);
mitk::ScalarType pixelValue;
mitkPixelTypeMultiplex5(
mitk::FastSinglePixelAccess,
image3D->GetChannelDescriptor().GetPixelType(),
image3D,
image3D->GetVolumeData(renderer->GetTimeStep()),
p,
pixelValue,
component);
mitk::StatusBar::GetInstance()->DisplayImageInfo(position, p, renderer->GetTime(), pixelValue);
}
else
{
mitk::StatusBar::GetInstance()->DisplayImageInfoInvalid();
}
}
}
}
void QmitkImageNavigatorView::RenderWindowPartDeactivated(mitk::IRenderWindowPart* /*renderWindowPart*/)
{
m_IRenderWindowPart = 0;
m_Parent->setEnabled(false);
}
int QmitkImageNavigatorView::GetSizeFlags(bool width)
{
if(!width)
{
return berry::Constants::MIN | berry::Constants::MAX | berry::Constants::FILL;
}
else
{
return 0;
}
}
int QmitkImageNavigatorView::ComputePreferredSize(bool width, int /*availableParallel*/, int /*availablePerpendicular*/, int preferredResult)
{
if(width==false)
{
return 200;
}
else
{
return preferredResult;
}
}
int QmitkImageNavigatorView::GetClosestAxisIndex(mitk::Vector3D normal)
{
// cos(theta) = normal . axis
// cos(theta) = (a, b, c) . (d, e, f)
// cos(theta) = (a, b, c) . (1, 0, 0) = a
// cos(theta) = (a, b, c) . (0, 1, 0) = b
// cos(theta) = (a, b, c) . (0, 0, 1) = c
double absCosThetaWithAxis[3];
for (int i = 0; i < 3; i++)
{
absCosThetaWithAxis[i] = fabs(normal[i]);
}
int largestIndex = 0;
double largestValue = absCosThetaWithAxis[0];
for (int i = 1; i < 3; i++)
{
if (absCosThetaWithAxis[i] > largestValue)
{
largestValue = absCosThetaWithAxis[i];
largestIndex = i;
}
}
return largestIndex;
}
void QmitkImageNavigatorView::SetBorderColors()
{
if (m_IRenderWindowPart)
{
QString decoColor;
QmitkRenderWindow* renderWindow = m_IRenderWindowPart->GetQmitkRenderWindow("axial");
if (renderWindow)
{
decoColor = GetDecorationColorOfGeometry(renderWindow);
mitk::PlaneGeometry::ConstPointer geometry = renderWindow->GetSliceNavigationController()->GetCurrentPlaneGeometry();
if (geometry.IsNotNull())
{
mitk::Vector3D normal = geometry->GetNormal();
int axis = this->GetClosestAxisIndex(normal);
this->SetBorderColor(axis, decoColor);
}
}
renderWindow = m_IRenderWindowPart->GetQmitkRenderWindow("sagittal");
if (renderWindow)
{
decoColor = GetDecorationColorOfGeometry(renderWindow);
mitk::PlaneGeometry::ConstPointer geometry = renderWindow->GetSliceNavigationController()->GetCurrentPlaneGeometry();
if (geometry.IsNotNull())
{
mitk::Vector3D normal = geometry->GetNormal();
int axis = this->GetClosestAxisIndex(normal);
this->SetBorderColor(axis, decoColor);
}
}
renderWindow = m_IRenderWindowPart->GetQmitkRenderWindow("coronal");
if (renderWindow)
{
decoColor = GetDecorationColorOfGeometry(renderWindow);
mitk::PlaneGeometry::ConstPointer geometry = renderWindow->GetSliceNavigationController()->GetCurrentPlaneGeometry();
if (geometry.IsNotNull())
{
mitk::Vector3D normal = geometry->GetNormal();
int axis = this->GetClosestAxisIndex(normal);
this->SetBorderColor(axis, decoColor);
}
}
}
}
QString QmitkImageNavigatorView::GetDecorationColorOfGeometry(QmitkRenderWindow* renderWindow)
{
QColor color;
float rgb[3] = {1.0f, 1.0f, 1.0f};
float rgbMax = 255.0f;
mitk::BaseRenderer::GetInstance(renderWindow->GetVtkRenderWindow())->GetCurrentWorldPlaneGeometryNode()->GetColor(rgb);
color.setRed(static_cast(rgb[0]*rgbMax + 0.5));
color.setGreen(static_cast(rgb[1]*rgbMax + 0.5));
color.setBlue(static_cast(rgb[2]*rgbMax + 0.5));
QString colorAsString = QString(color.name());
return colorAsString;
}
void QmitkImageNavigatorView::SetBorderColor(int axis, QString colorAsStyleSheetString)
{
if (axis == 0)
{
this->SetBorderColor(m_Controls.m_XWorldCoordinateSpinBox, colorAsStyleSheetString);
}
else if (axis == 1)
{
this->SetBorderColor(m_Controls.m_YWorldCoordinateSpinBox, colorAsStyleSheetString);
}
else if (axis == 2)
{
this->SetBorderColor(m_Controls.m_ZWorldCoordinateSpinBox, colorAsStyleSheetString);
}
}
void QmitkImageNavigatorView::SetBorderColor(QDoubleSpinBox *spinBox, QString colorAsStyleSheetString)
{
assert(spinBox);
spinBox->setStyleSheet(QString("border: 2px solid ") + colorAsStyleSheetString + ";");
}
void QmitkImageNavigatorView::SetStepSizes()
{
this->SetStepSize(0);
this->SetStepSize(1);
this->SetStepSize(2);
}
void QmitkImageNavigatorView::SetStepSize(int axis)
{
if (m_IRenderWindowPart)
{
mitk::BaseGeometry::ConstPointer geometry = m_IRenderWindowPart->GetActiveQmitkRenderWindow()->GetSliceNavigationController()->GetInputWorldGeometry3D();
if (geometry.IsNotNull())
{
mitk::Point3D crossPositionInIndexCoordinates;
mitk::Point3D crossPositionInIndexCoordinatesPlus1;
mitk::Point3D crossPositionInMillimetresPlus1;
mitk::Vector3D transformedAxisDirection;
mitk::Point3D crossPositionInMillimetres = m_IRenderWindowPart->GetSelectedPosition();
geometry->WorldToIndex(crossPositionInMillimetres, crossPositionInIndexCoordinates);
crossPositionInIndexCoordinatesPlus1 = crossPositionInIndexCoordinates;
crossPositionInIndexCoordinatesPlus1[axis] += 1;
geometry->IndexToWorld(crossPositionInIndexCoordinatesPlus1, crossPositionInMillimetresPlus1);
transformedAxisDirection = crossPositionInMillimetresPlus1 - crossPositionInMillimetres;
int closestAxisInMillimetreSpace = this->GetClosestAxisIndex(transformedAxisDirection);
double stepSize = transformedAxisDirection.GetNorm();
this->SetStepSize(closestAxisInMillimetreSpace, stepSize);
}
}
}
void QmitkImageNavigatorView::SetStepSize(int axis, double stepSize)
{
if (axis == 0)
{
m_Controls.m_XWorldCoordinateSpinBox->setSingleStep(stepSize);
}
else if (axis == 1)
{
m_Controls.m_YWorldCoordinateSpinBox->setSingleStep(stepSize);
}
else if (axis == 2)
{
m_Controls.m_ZWorldCoordinateSpinBox->setSingleStep(stepSize);
}
}
void QmitkImageNavigatorView::OnMillimetreCoordinateValueChanged()
{
if (m_IRenderWindowPart)
{
mitk::TimeGeometry::ConstPointer geometry = m_IRenderWindowPart->GetActiveQmitkRenderWindow()->GetSliceNavigationController()->GetInputWorldTimeGeometry();
if (geometry.IsNotNull())
{
mitk::Point3D positionInWorldCoordinates;
positionInWorldCoordinates[0] = m_Controls.m_XWorldCoordinateSpinBox->value();
positionInWorldCoordinates[1] = m_Controls.m_YWorldCoordinateSpinBox->value();
positionInWorldCoordinates[2] = m_Controls.m_ZWorldCoordinateSpinBox->value();
m_IRenderWindowPart->SetSelectedPosition(positionInWorldCoordinates);
}
}
}
void QmitkImageNavigatorView::OnRefetch()
{
if (m_IRenderWindowPart)
{
mitk::BaseGeometry::ConstPointer geometry = m_IRenderWindowPart->GetActiveQmitkRenderWindow()->GetSliceNavigationController()->GetInputWorldGeometry3D();
mitk::TimeGeometry::ConstPointer timeGeometry = m_IRenderWindowPart->GetActiveQmitkRenderWindow()->GetSliceNavigationController()->GetInputWorldTimeGeometry();
if (geometry.IsNull() && timeGeometry.IsNotNull())
{
mitk::TimeStepType timeStep = m_IRenderWindowPart->GetActiveQmitkRenderWindow()->GetSliceNavigationController()->GetTime()->GetPos();
geometry = timeGeometry->GetGeometryForTimeStep(timeStep);
}
if (geometry.IsNotNull())
{
mitk::BoundingBox::BoundsArrayType bounds = geometry->GetBounds();
mitk::Point3D cornerPoint1InIndexCoordinates;
cornerPoint1InIndexCoordinates[0] = bounds[0];
cornerPoint1InIndexCoordinates[1] = bounds[2];
cornerPoint1InIndexCoordinates[2] = bounds[4];
mitk::Point3D cornerPoint2InIndexCoordinates;
cornerPoint2InIndexCoordinates[0] = bounds[1];
cornerPoint2InIndexCoordinates[1] = bounds[3];
cornerPoint2InIndexCoordinates[2] = bounds[5];
if (!geometry->GetImageGeometry())
{
cornerPoint1InIndexCoordinates[0] += 0.5;
cornerPoint1InIndexCoordinates[1] += 0.5;
cornerPoint1InIndexCoordinates[2] += 0.5;
cornerPoint2InIndexCoordinates[0] -= 0.5;
cornerPoint2InIndexCoordinates[1] -= 0.5;
cornerPoint2InIndexCoordinates[2] -= 0.5;
}
mitk::Point3D crossPositionInWorldCoordinates = m_IRenderWindowPart->GetSelectedPosition();
mitk::Point3D cornerPoint1InWorldCoordinates;
mitk::Point3D cornerPoint2InWorldCoordinates;
geometry->IndexToWorld(cornerPoint1InIndexCoordinates, cornerPoint1InWorldCoordinates);
geometry->IndexToWorld(cornerPoint2InIndexCoordinates, cornerPoint2InWorldCoordinates);
m_Controls.m_XWorldCoordinateSpinBox->blockSignals(true);
m_Controls.m_YWorldCoordinateSpinBox->blockSignals(true);
m_Controls.m_ZWorldCoordinateSpinBox->blockSignals(true);
m_Controls.m_XWorldCoordinateSpinBox->setMinimum(std::min(cornerPoint1InWorldCoordinates[0], cornerPoint2InWorldCoordinates[0]));
m_Controls.m_YWorldCoordinateSpinBox->setMinimum(std::min(cornerPoint1InWorldCoordinates[1], cornerPoint2InWorldCoordinates[1]));
m_Controls.m_ZWorldCoordinateSpinBox->setMinimum(std::min(cornerPoint1InWorldCoordinates[2], cornerPoint2InWorldCoordinates[2]));
m_Controls.m_XWorldCoordinateSpinBox->setMaximum(std::max(cornerPoint1InWorldCoordinates[0], cornerPoint2InWorldCoordinates[0]));
m_Controls.m_YWorldCoordinateSpinBox->setMaximum(std::max(cornerPoint1InWorldCoordinates[1], cornerPoint2InWorldCoordinates[1]));
m_Controls.m_ZWorldCoordinateSpinBox->setMaximum(std::max(cornerPoint1InWorldCoordinates[2], cornerPoint2InWorldCoordinates[2]));
m_Controls.m_XWorldCoordinateSpinBox->setValue(crossPositionInWorldCoordinates[0]);
m_Controls.m_YWorldCoordinateSpinBox->setValue(crossPositionInWorldCoordinates[1]);
m_Controls.m_ZWorldCoordinateSpinBox->setValue(crossPositionInWorldCoordinates[2]);
m_Controls.m_XWorldCoordinateSpinBox->blockSignals(false);
m_Controls.m_YWorldCoordinateSpinBox->blockSignals(false);
m_Controls.m_ZWorldCoordinateSpinBox->blockSignals(false);
+
+ /// Calculating 'inverse direction' property.
+
+ mitk::AffineTransform3D::MatrixType matrix = geometry->GetIndexToWorldTransform()->GetMatrix();
+ matrix.GetVnlMatrix().normalize_columns();
+ mitk::AffineTransform3D::MatrixType::InternalMatrixType inverseMatrix = matrix.GetInverse();
+
+ for (int worldAxis = 0; worldAxis < 3; ++worldAxis)
+ {
+ QmitkRenderWindow* renderWindow =
+ worldAxis == 0 ? m_IRenderWindowPart->GetQmitkRenderWindow("sagittal") :
+ worldAxis == 1 ? m_IRenderWindowPart->GetQmitkRenderWindow("coronal") :
+ m_IRenderWindowPart->GetQmitkRenderWindow("axial");
+
+ if (renderWindow)
+ {
+ const mitk::BaseGeometry* rendererGeometry = renderWindow->GetRenderer()->GetCurrentWorldGeometry();
+
+ /// Because of some problems with the current way of event signalling,
+ /// 'Modified' events are sent out from the stepper while the renderer
+ /// does not have a geometry yet. Therefore, we do a nullptr check here.
+ /// See bug T22122. This check can be resolved after T22122 got fixed.
+ if (rendererGeometry)
+ {
+ int dominantAxis = itk::Function::Max3(
+ inverseMatrix[0][worldAxis],
+ inverseMatrix[1][worldAxis],
+ inverseMatrix[2][worldAxis]);
+
+ bool referenceGeometryAxisInverted = inverseMatrix[dominantAxis][worldAxis] < 0;
+ bool rendererZAxisInverted = rendererGeometry->GetAxisVector(2)[worldAxis] < 0;
+
+ /// `referenceGeometryAxisInverted` tells if the direction of the corresponding axis
+ /// of the reference geometry is flipped compared to the 'world direction' or not.
+ ///
+ /// `rendererZAxisInverted` tells if direction of the renderer geometry z axis is
+ /// flipped compared to the 'world direction' or not. This is the same as the indexing
+ /// direction in the slice navigation controller and matches the 'top' property when
+ /// initialising the renderer planes. (If 'top' was true then the direction is
+ /// inverted.)
+ ///
+ /// The world direction can be +1 ('up') that means right, anterior or superior, or
+ /// it can be -1 ('down') that means left, posterior or inferior, respectively.
+ ///
+ /// If these two do not match, we have to invert the index between the slice navigation
+ /// controller and the slider navigator widget, so that the user can see and control
+ /// the index according to the reference geometry, rather than the slice navigation
+ /// controller. The index in the slice navigation controller depends on in which way
+ /// the reference geometry has been resliced for the renderer, and it does not necessarily
+ /// match neither the world direction, nor the direction of the corresponding axis of
+ /// the reference geometry. Hence, it is a merely internal information that should not
+ /// be exposed to the GUI.
+
+ bool inverseDirection = referenceGeometryAxisInverted != rendererZAxisInverted;
+
+ QmitkSliderNavigatorWidget* navigatorWidget =
+ worldAxis == 0 ? m_Controls.m_SliceNavigatorSagittal :
+ worldAxis == 1 ? m_Controls.m_SliceNavigatorFrontal :
+ m_Controls.m_SliceNavigatorAxial;
+
+ navigatorWidget->SetInverseDirection(inverseDirection);
+ }
+ }
+ }
}
this->SetBorderColors();
}
}