Commit 5484398d authored by Emmanuel Promayon's avatar Emmanuel Promayon

NEW ArbitrarySlice is back

For now only rotation works properly. ArbitrarySingleImageComponent,
a new SingleImageComponent derived class now manages the arbitrary
orientation directly.
parent d21e4444
......@@ -34,6 +34,7 @@
// VTK includes
#include <vtkStringArray.h>
#include <vtkPointData.h>
#include <vtkImageChangeInformation.h>
// GDCM includes
#include <vtkGDCMImageReader.h>
......
......@@ -38,8 +38,7 @@ AnglesSetterWidget::AnglesSetterWidget(SetAnglesAction* a, QWidget* parent): QWi
ui.setupUi(this);
// Ui slice number change slot connection
connect(ui.sliceSpinBox, SIGNAL(valueChanged(int)), this, SLOT(updateSlider(int)));
connect(ui.sliceSlider, SIGNAL(valueChanged(int)), this, SLOT(updateSlider(int))) ;
connect(ui.translationSpinBox, SIGNAL(valueChanged(double)), this, SLOT(translationSpinBoxChanged(double)));
// Ui angles slot connection
connect(ui.xAngleDial, SIGNAL(valueChanged(int)), this, SLOT(xAngleDialValueChanged(int)));
......@@ -47,6 +46,7 @@ AnglesSetterWidget::AnglesSetterWidget(SetAnglesAction* a, QWidget* parent): QWi
connect(ui.zAngleDial, SIGNAL(valueChanged(int)), this, SLOT(zAngleDialValueChanged(int)));
connect(ui.showArbitraryViewer, SIGNAL(clicked(bool)), this, SLOT(showArbitraryViewer(bool)));
connect(ui.resetButton, SIGNAL(clicked()), this, SLOT(resetTransform()));
}
// -------------------- destructor --------------------
......@@ -55,22 +55,14 @@ AnglesSetterWidget::~AnglesSetterWidget() {
// -------------------- updateGUI --------------------
void AnglesSetterWidget::updateGUI() {
// get values
Property * sliceIndexProperty = myAction->getProperty("Slice Index");
int max = sliceIndexProperty->getAttribute("maximum").toInt();
int currentValue = myAction->property("Slice Index").toInt();
// set ui
ui.sliceSlider->blockSignals(true);
ui.sliceSlider->setMaximum(max);
ui.sliceSlider->setValue(currentValue);
ui.sliceSlider->blockSignals(false);
ui.sliceSpinBox->blockSignals(true);
ui.sliceSpinBox->setMaximum(max);
ui.sliceSpinBox->setValue(currentValue);
ui.sliceSpinBox->blockSignals(false);
ui.translationSpinBox->blockSignals(true);
ui.upButton->blockSignals(true);
ui.downButton->blockSignals(true);
ui.translationSpinBox->setValue(myAction->property("Translation").toDouble());
ui.translationSpinBox->blockSignals(false);
ui.upButton->blockSignals(false);
ui.downButton->blockSignals(false);
ui.xAngleDial->blockSignals(true);
ui.xAngleDial->setValue(myAction->property("X Angle").toInt());
ui.xAngleDial->blockSignals(false);
......@@ -92,10 +84,14 @@ void AnglesSetterWidget::showArbitraryViewer(bool buttonState) {
myAction->showArbitraryViewer(buttonState);
}
// -------------------- updateSlice --------------------
void AnglesSetterWidget::updateSlider(int sliceNumber) {
// Ui slider and spin box are mapped and thus automatically updated when a change occurs.
myAction->setProperty("Slice Index",sliceNumber);
// -------------------- updateAngleSliderLabel --------------------
void AnglesSetterWidget::resetTransform() {
myAction->resetTransform();
}
// -------------------- translationSpinBoxChanged --------------------
void AnglesSetterWidget::translationSpinBoxChanged(double value) {
myAction->setProperty("Translation", value);
}
// -------------------- xAngleDialValueChanged --------------------
......@@ -120,6 +116,7 @@ void AnglesSetterWidget::zAngleDialValueChanged(int value) {
void AnglesSetterWidget::updateAngleSliderLabel(QDial* dial) {
QString angleLetter;
QLabel *label;
if (dial == ui.xAngleDial) {
angleLetter = "X";
label = ui.xAngleValue;
......@@ -137,4 +134,3 @@ void AnglesSetterWidget::updateAngleSliderLabel(QDial* dial) {
label->setText(angleLetter + QString(" Angle: <tt>%1</tt>").arg(dial->value(), 3) + QChar(0x00B0));
label->update();
}
......@@ -58,8 +58,8 @@ public:
private slots:
/// Update slice number to be displayed
void updateSlider(int);
/// Update the translation value
void translationSpinBoxChanged(double);
/// Method that update the angle dialog slider (text + value)
void xAngleDialValueChanged(int);
......@@ -69,10 +69,12 @@ private slots:
/// change the visibility of the axial viewer
void showArbitraryViewer(bool);
void resetTransform();
private:
/// update the angle dialog slider label using the current dial value
void updateAngleSliderLabel(QDial*);
// the GUI class itself
Ui::AnglesSetterWidget ui;
......
......@@ -51,18 +51,15 @@ SetAnglesAction::SetAnglesAction(ActionExtension* extension) : Action(extension)
setEmbedded(true);
currentImageComp = nullptr;
blockEvent = true;
// the AnglesSetterWidget is going to modify these parameters using the GUI
// but defining them as the action parameters also allows to set them programmatically
// (for instance using another GUI or in a pipeline)
// Setting parameters default values by using properties
Property* actionProperty = new Property(tr("Slice Index"), 1, tr("Current selected slice index"), "");
actionProperty->setAttribute("minimum", 0);
actionProperty->setAttribute("maximum", 99);
actionProperty->setAttribute("singleStep", 1);
addParameter(actionProperty);
addParameter(new Property(tr("Translation"), 0.0, tr("Current translation inside the image"), ""));
actionProperty = new Property(tr("X Angle"), 0, tr("X Angle"), "degree");
Property* actionProperty = actionProperty = new Property(tr("X Angle"), 0, tr("X Angle"), "degree");
actionProperty->setAttribute("minimum", 0);
actionProperty->setAttribute("maximum", 360);
addParameter(actionProperty);
......@@ -89,60 +86,68 @@ SetAnglesAction::~SetAnglesAction() {
// --------------- getWidget -------------------
QWidget* SetAnglesAction::getWidget() {
if (!actionWidget) {
// TODO integrates https://github.com/aaronsnoswell/QMLVirtualJoystick
actionWidget = new AnglesSetterWidget(this);
// first call : force visibility of the arbitrary viewer
MedicalImageViewer::getInstance()->setVisibleViewer(MedicalImageViewer::VIEWER_ARBITRARY);
// connect the arbitrary viewer so that a change to its slider can update the "Slice Index" attribute
connect(InteractiveViewer::getArbitraryViewer(), SIGNAL(selectionChanged()), this, SLOT(viewerSliderChanged()));
showArbitraryViewer(true);
}
// reset current pointer so that nothing will happen in the event(..) method
currentImageComp = nullptr;
SingleImageComponent* newCurrentImageComp = dynamic_cast<ImageComponent*>(getTargets().last())->getArbitrarySlices();
// update the pointer
currentImageComp = dynamic_cast<ImageComponent*>(getTargets().last())->getArbitrarySlices();
// update current action properties safely (i.e. without event(..) to be doing anything on the component
Property* sliceIndexProperty = getProperty("Slice Index");
sliceIndexProperty->setAttribute("maximum", newCurrentImageComp->getNumberOfSlices() - 1);
setProperty("Slice Index", newCurrentImageComp->getSlice());
// update the properties
updateParameters();
double rotation[3];
newCurrentImageComp->getTransform()->GetOrientation(rotation);
setProperty("X Angle", rotation[0]);
setProperty("Y Angle", rotation[1]);
setProperty("Z Angle", rotation[2]);
CAMITK_INFO(QString("Z changed to [%1]").arg(rotation[2]))
return actionWidget;
}
// now set currentImageComp to the proper value to keep it up-to-date when the GUI will change
currentImageComp = newCurrentImageComp;
// ---------------------- updateParameters ----------------------------
void SetAnglesAction::updateParameters() {
// update current action properties safely (i.e. without event(..) to be doing anything on the component)
blockEvent = true;
// current translation along the z axis of the arbitrary slice
setProperty("Translation", currentImageComp->getTranslationInVolume()*100.0);
// update widget
dynamic_cast<AnglesSetterWidget*>(actionWidget)->updateGUI();
return actionWidget;
// keep property up-to-date when the GUI will change
blockEvent = false;
}
// ---------------------- showArbitraryViewer ----------------------------
void SetAnglesAction::showArbitraryViewer(bool visible) {
if (visible) {
// keep the current value
visibleViewer = MedicalImageViewer::getInstance()->getVisibleViewer();
// force visibility of the arbitrary viewer
MedicalImageViewer::getInstance()->setVisibleViewer(MedicalImageViewer::VIEWER_ARBITRARY);
}
else {
// hide the arbitrary viewer
MedicalImageViewer::getInstance()->setVisibleViewer(MedicalImageViewer::VIEWER_ALL);
MedicalImageViewer::getInstance()->setVisibleViewer(visibleViewer);
}
}
// ---------------------- viewerSliderChanged ----------------------------
void SetAnglesAction::viewerSliderChanged() {
setProperty("Slice Index", currentImageComp->getSlice());
// update widget
dynamic_cast<AnglesSetterWidget*>(actionWidget)->updateGUI();
// ---------------------- resetTransform ----------------------------
void SetAnglesAction::resetTransform() {
currentImageComp->resetTransform();
// Reset the angle to zero
blockEvent = true;
setProperty("X Angle", 0);
setProperty("Y Angle", 0);
setProperty("Z Angle", 0);
blockEvent = false;
updateParameters();
currentImageComp->refresh();
}
// ---------------------- event ----------------------------
bool SetAnglesAction::event(QEvent* e) {
if (currentImageComp == nullptr)
if (currentImageComp == nullptr || blockEvent)
return QObject::event(e);
if (e->type() == QEvent::DynamicPropertyChange) {
......@@ -153,13 +158,16 @@ bool SetAnglesAction::event(QEvent* e) {
return false;
// do something depending of the property that has changed
if (changeEvent->propertyName() == "Slice Index") {
currentImageComp->setSlice(property(changeEvent->propertyName()).toInt());
if (changeEvent->propertyName() == "Translation") {
currentImageComp->setTransformTranslation(0.0, 0.0, property(changeEvent->propertyName()).toDouble());
}
else {
currentImageComp->setTransformRotation(property("X Angle").toInt(), property("Y Angle").toInt(), property("Z Angle").toInt());
}
// needed as rotation might change the translation value or translation might have been rejected
updateParameters();
currentImageComp->refresh();
return true;
......
......@@ -28,7 +28,8 @@
// CamiTK stuff
#include <QObject>
#include <Action.h>
#include <SingleImageComponent.h>
#include <ArbitrarySingleImageComponent.h>
#include <MedicalImageViewer.h>
#include "ArbitrarySliceAPI.h"
......@@ -58,6 +59,9 @@ public:
/// show or hide the arbitrary viewer
void showArbitraryViewer(bool);
// reset transform to identity
void resetTransform();
public slots:
/** This method returns always SUCCESS as the action aims at displaying its widget to be used in order to control the
......@@ -66,15 +70,19 @@ public slots:
virtual ApplyStatus apply() {
return SUCCESS;
}
protected slots:
/// called when the arbitrary viewer slicer has changed directly
virtual void viewerSliderChanged();
protected:
// block event during initialization
camitk::SingleImageComponent* currentImageComp;
private:
/// update action's parameter using the current image state + update widget GUI
void updateParameters();
/// currently controled image
camitk::ArbitrarySingleImageComponent* currentImageComp;
/// block property changed event (temporarily)
bool blockEvent;
/// current visibility state of the medical image viewer
camitk::MedicalImageViewer::LayoutVisibility visibleViewer;
};
#endif // SETANGLESACTION_H
......
......@@ -31,6 +31,7 @@
// Includes CamiTK
#include <Application.h>
#include <SingleImageComponent.h>
#include <Log.h>
using namespace camitk;
......
......@@ -25,7 +25,7 @@
#include "ShowArbitrarySliceIn3D.h"
#include <ImageComponent.h>
#include <SingleImageComponent.h>
#include <ArbitrarySingleImageComponent.h>
#include <InteractiveViewer.h>
using namespace camitk;
......
......@@ -26,6 +26,8 @@
#include "Frame.h"
#include "Viewer.h"
#include "Log.h"
// Includes from Vtk
#include <vtkTransform.h>
#include <vtkTransformPolyDataFilter.h>
......@@ -247,6 +249,7 @@ void Frame::resetTransform() {
void Frame::translate(double x, double y, double z) {
transformParentToMe->Translate(x, y, z);
transformParentToMe->Update();
transformWorldToMe->Update();
representationTransformFilter->Update();
}
......@@ -257,15 +260,16 @@ void Frame::rotate(double aroundX, double aroundY, double aroundZ) {
double* initialPos = transformParentToMe->GetPosition();
transformParentToMe->Translate(-initialPos[0], -initialPos[1], -initialPos[2]);
transformParentToMe->Update();
transformParentToMe->RotateX(aroundX);
transformParentToMe->RotateY(aroundY);
transformParentToMe->RotateZ(aroundZ);
transformParentToMe->Update();
transformParentToMe->Translate(initialPos[0], initialPos[1], initialPos[2]);
transformParentToMe->Update();
transformWorldToMe->Update();
representationTransformFilter->Update();
}
......@@ -275,33 +279,77 @@ void Frame::rotateVTK(double aroundX, double aroundY, double aroundZ) {
double* initialPos = transformParentToMe->GetPosition();
transformParentToMe->Translate(-initialPos[0], -initialPos[1], -initialPos[2]);
transformParentToMe->Update();
transformParentToMe->RotateZ(aroundZ);
transformParentToMe->RotateX(aroundX);
transformParentToMe->RotateY(aroundY);
transformParentToMe->Update();
transformParentToMe->Translate(initialPos[0], initialPos[1], initialPos[2]);
transformParentToMe->Update();
transformWorldToMe->Update();
representationTransformFilter->Update();
}
// ------------------- setTransformTranslation --------------------------
void Frame::setTransformTranslation(double x, double y, double z) {
// CAMITK_INFO_ALT(QString("before n=%1").arg(getTransform()->GetNumberOfConcatenatedTransforms()))
// CAMITK_INFO_ALT(QString("m=[%1,%2,%3,%4] [%5,%6,%7,%8] [%9,%10,%11,%12] [%13,%14,%15,%16]")
// .arg(getTransform()->GetMatrix()->GetElement(0,0))
// .arg(getTransform()->GetMatrix()->GetElement(0,1))
// .arg(getTransform()->GetMatrix()->GetElement(0,2))
// .arg(getTransform()->GetMatrix()->GetElement(0,3))
// .arg(getTransform()->GetMatrix()->GetElement(1,0))
// .arg(getTransform()->GetMatrix()->GetElement(1,1))
// .arg(getTransform()->GetMatrix()->GetElement(1,2))
// .arg(getTransform()->GetMatrix()->GetElement(1,3))
// .arg(getTransform()->GetMatrix()->GetElement(2,0))
// .arg(getTransform()->GetMatrix()->GetElement(2,1))
// .arg(getTransform()->GetMatrix()->GetElement(2,2))
// .arg(getTransform()->GetMatrix()->GetElement(2,3))
// .arg(getTransform()->GetMatrix()->GetElement(3,0))
// .arg(getTransform()->GetMatrix()->GetElement(3,1))
// .arg(getTransform()->GetMatrix()->GetElement(3,2))
// .arg(getTransform()->GetMatrix()->GetElement(3,3))
// )
double* initialRotation = transformParentToMe->GetOrientation();
transformParentToMe->Identity();
transformParentToMe->RotateX(initialRotation[0]);
transformParentToMe->RotateY(initialRotation[1]);
transformParentToMe->RotateZ(initialRotation[2]);
transformParentToMe->Update();
transformParentToMe->Translate(x, y, z);
transformParentToMe->Update();
transformWorldToMe->Update();
representationTransformFilter->Update();
// CAMITK_INFO_ALT(QString("after n=%1").arg(getTransform()->GetNumberOfConcatenatedTransforms()))
// CAMITK_INFO_ALT(QString("m=[%1,%2,%3,%4] [%5,%6,%7,%8] [%9,%10,%11,%12] [%13,%14,%15,%16]")
// .arg(getTransform()->GetMatrix()->GetElement(0,0))
// .arg(getTransform()->GetMatrix()->GetElement(0,1))
// .arg(getTransform()->GetMatrix()->GetElement(0,2))
// .arg(getTransform()->GetMatrix()->GetElement(0,3))
// .arg(getTransform()->GetMatrix()->GetElement(1,0))
// .arg(getTransform()->GetMatrix()->GetElement(1,1))
// .arg(getTransform()->GetMatrix()->GetElement(1,2))
// .arg(getTransform()->GetMatrix()->GetElement(1,3))
// .arg(getTransform()->GetMatrix()->GetElement(2,0))
// .arg(getTransform()->GetMatrix()->GetElement(2,1))
// .arg(getTransform()->GetMatrix()->GetElement(2,2))
// .arg(getTransform()->GetMatrix()->GetElement(2,3))
// .arg(getTransform()->GetMatrix()->GetElement(3,0))
// .arg(getTransform()->GetMatrix()->GetElement(3,1))
// .arg(getTransform()->GetMatrix()->GetElement(3,2))
// .arg(getTransform()->GetMatrix()->GetElement(3,3))
// )
}
// ------------------- setTransformTranslationVTK --------------------------
......@@ -309,13 +357,16 @@ void Frame::setTransformTranslationVTK(double x, double y, double z) {
double* initialRotation = transformParentToMe->GetOrientation();
transformParentToMe->Identity();
// VTK rotation order is Z, X, Y
transformParentToMe->RotateZ(initialRotation[2]);
transformParentToMe->RotateX(initialRotation[0]);
transformParentToMe->RotateY(initialRotation[1]);
transformParentToMe->Update();
transformParentToMe->Translate(x, y, z);
transformParentToMe->Update();
transformWorldToMe->Update();
representationTransformFilter->Update();
}
......@@ -325,13 +376,15 @@ void Frame::setTransformRotation(double aroundX, double aroundY, double aroundZ)
double* initialTranslation = transformParentToMe->GetPosition();
transformParentToMe->Identity();
transformParentToMe->RotateX(aroundX);
transformParentToMe->RotateY(aroundY);
transformParentToMe->RotateZ(aroundZ);
transformParentToMe->Update();
transformParentToMe->Translate(initialTranslation[0], initialTranslation[1], initialTranslation[2]);
transformParentToMe->Update();
transformWorldToMe->Update();
representationTransformFilter->Update();
}
......@@ -341,13 +394,16 @@ void Frame::setTransformRotationVTK(double aroundX, double aroundY, double aroun
double* initialTranslation = transformParentToMe->GetPosition();
transformParentToMe->Identity();
// VTK rotation order is Z, X, Y
transformParentToMe->RotateZ(aroundZ);
transformParentToMe->RotateX(aroundX);
transformParentToMe->RotateY(aroundY);
transformParentToMe->Update();
transformParentToMe->Translate(initialTranslation[0], initialTranslation[1], initialTranslation[2]);
transformParentToMe->Update();
transformWorldToMe->Update();
representationTransformFilter->Update();
}
......
......@@ -77,6 +77,11 @@ namespace camitk {
* \note (easter egg) hit "t" on any slice viewer and move the camera around to see the quad geometries and
* how these extra actors are build.
*
* \note <b>Warning</b> Be careful, the <b>center</b> of the first voxel, of image coordinates (0,0,0),
* is displayed at coordinates (0.0, 0.0, 0.0) → There is a small shift of half a pixel.
* The same occurs to the last pixel.
* Therefore, pixels of a 2D slice that are located on an image border are represented only by their half,
* or quarter depending on their coordinates.
*
* \verbatim
* 3D Volume 2D Slice
......
......@@ -27,6 +27,7 @@
#include "ImageComponent.h"
#include "ImageComponentExtension.h"
#include "SingleImageComponent.h"
#include "ArbitrarySingleImageComponent.h"
#include "ImageOrientationHelper.h"
// -- Core stuff
......@@ -454,12 +455,12 @@ SingleImageComponent* ImageComponent::getSagittalSlices() {
}
// -------------------- getArbitrarySlices --------------------
SingleImageComponent* ImageComponent::getArbitrarySlices() {
ArbitrarySingleImageComponent* ImageComponent::getArbitrarySlices() {
return arbitrarySlices;
}
// -------------------- setSingleImageComponents --------------------
void ImageComponent::setSingleImageComponents(SingleImageComponent* axialSlices, SingleImageComponent* sagittalSlices, SingleImageComponent* coronalSlices, SingleImageComponent* arbitrarySlices) {
void ImageComponent::setSingleImageComponents(SingleImageComponent* axialSlices, SingleImageComponent* sagittalSlices, SingleImageComponent* coronalSlices, ArbitrarySingleImageComponent* arbitrarySlices) {
if (this->axialSlices != nullptr && axialSlices != this->axialSlices) {
removeChild(this->axialSlices);
delete this->axialSlices;
......@@ -544,7 +545,7 @@ void ImageComponent::buildImageComponents() {
}
if (arbitrarySlices == nullptr) {
arbitrarySlices = new SingleImageComponent(this, Slice::ARBITRARY, "Arbitrary view", lut);
arbitrarySlices = new ArbitrarySingleImageComponent(this, "Arbitrary view", lut);
}
if (volumeRenderingChild != nullptr) {
......
......@@ -27,8 +27,8 @@
#define IMAGE_COMPONENT_H
// -- Core image component stuff
#include "SingleImageComponent.h"
#include "CamiTKAPI.h"
#include "Component.h"
#include "ImageOrientationHelper.h"
// -- vtk stuff
......@@ -48,9 +48,13 @@ class QVariant;
class QTableView;
class QStandardItemModel;
namespace camitk {
class MeshComponent;
class SingleImageComponent;
class ArbitrarySingleImageComponent;
/**
* @ingroup group_sdk_libraries_core_component_image
......@@ -179,7 +183,7 @@ public:
/** Returns the sagittal slice */
SingleImageComponent* getSagittalSlices();
/** Returns the arbitrary slice */
SingleImageComponent* getArbitrarySlices();
ArbitrarySingleImageComponent* getArbitrarySlices();
/** Returns the MeshComponent which will contain the volume rendering actor */
MeshComponent* getVolumeRenderingChild();
......@@ -233,7 +237,7 @@ protected:
* @param coronalSlices the coronal slices representation (use getCoronalSlices() if you don't need to modify this particular orientation)
* @param arbitrarySlices the arbirtrary slices representation (use getArbitrarySlices() if you don't need to modify this particular orientation)
*/
virtual void setSingleImageComponents(SingleImageComponent* axialSlices, SingleImageComponent* sagittalSlices, SingleImageComponent* coronalSlices, SingleImageComponent* arbitrarySlices);
virtual void setSingleImageComponents(SingleImageComponent* axialSlices, SingleImageComponent* sagittalSlices, SingleImageComponent* coronalSlices, ArbitrarySingleImageComponent* arbitrarySlices);
private:
/** Update the Properties displayed in the PropertyExplorer
......@@ -284,7 +288,7 @@ private:
SingleImageComponent* coronalSlices;
/// the arbitrary slices representation (all intelligence is delegated to a Slice class instance)
SingleImageComponent* arbitrarySlices;
ArbitrarySingleImageComponent* arbitrarySlices;
/// When an action computes volume rendering for an image,
/// it stores the corresponding actor as a prop of this Component.
......
......@@ -38,6 +38,7 @@
#include <vtkImageClip.h>
#include <vtkImageChangeInformation.h>
#include <vtkProperty.h>
#include <vtkMatrix4x4.h>
#include <cmath>
......@@ -86,7 +87,7 @@ void SingleImageComponent::setViewSliceIn3D(bool toggle) {
void SingleImageComponent::initRepresentation() {
// initialize Slice
mySlice = new Slice(dynamic_cast<ImageComponent*>(getParentComponent())->getImageData(), sliceOrientation, lut);
// initialize 3D image actor to the proper position/orientation in the world reference frame
mySlice->setImageWorldTransform(getTransformFromWorld());
......@@ -101,12 +102,8 @@ void SingleImageComponent::initRepresentation() {
case Slice::SAGITTAL:
setVisibility(InteractiveViewer::getSagittalViewer(), true);
break;
case Slice::ARBITRARY:
case Slice::ARBITRARY:
setVisibility(InteractiveViewer::getArbitraryViewer(), true);
// initial arbitrary slice is centered in the volume along the original z axis
myFrame->translate(0.0, 0.0, dynamic_cast<ImageComponent*>(getParentComponent())->getImageData()->GetDimensions()[2]/2.0*dynamic_cast<ImageComponent*>(getParentComponent())->getImageData()->GetSpacing()[2]);
// initialize the arbitrary transform using the transform to parent vtkTransform
mySlice->setArbitraryTransform(getTransform());
break;
}
}
......@@ -122,147 +119,47 @@ void SingleImageComponent::pixelPicked(double i, double j, double k) {
// -------------------- setTransform --------------------
void SingleImageComponent::setTransform(vtkSmartPointer<vtkTransform> transform) {
// Do nothing, my parent (the ImageComponent) should do that globally
// unless this is a arbitrary slice
if (sliceOrientation == Slice::ARBITRARY) {
myFrame->setTransform(transform);
}
}
// -------------------- resetTransform --------------------
void SingleImageComponent::resetTransform() {
// Do nothing, my parent (the ImageComponent) should do that globally
// unless this is a arbitrary slice
if (sliceOrientation == Slice::ARBITRARY) {
myFrame->resetTransform();
}
}
// -------------------- rotate --------------------
void SingleImageComponent::rotate(double aroundX, double aroundY, double aroundZ) {
// Do nothing, my parent (the ImageComponent) should do that globally
// unless this is a arbitrary slice
if (sliceOrientation == Slice::ARBITRARY) {