Commit 8a0cc144 authored by Emmanuel Promayon's avatar Emmanuel Promayon

FIXED arbitrary slice is functional

parent b2b31ad5
......@@ -195,16 +195,16 @@ void Slice::setSlice(int s) {
break;
case AXIAL:
case AXIAL_NEURO:
image3DActor->SetDisplayExtent(extent[0], extent[1], extent[2], extent[3], s, s);
image2DActor->SetDisplayExtent(extent[0], extent[1], extent[2], extent[3], s, s);
image3DActor->SetDisplayExtent(extent[0], extent[1], extent[2], extent[3], currentSliceIndex, currentSliceIndex);
image2DActor->SetDisplayExtent(extent[0], extent[1], extent[2], extent[3], currentSliceIndex, currentSliceIndex);
break;
case CORONAL:
image3DActor->SetDisplayExtent(extent[0], extent[1], s, s, extent[4], extent[5]);
image2DActor->SetDisplayExtent(extent[0], extent[1], s, s, extent[4], extent[5]);
image3DActor->SetDisplayExtent(extent[0], extent[1], currentSliceIndex, currentSliceIndex, extent[4], extent[5]);
image2DActor->SetDisplayExtent(extent[0], extent[1], currentSliceIndex, currentSliceIndex, extent[4], extent[5]);
break;
case SAGITTAL:
image3DActor->SetDisplayExtent(s, s, extent[2], extent[3], extent[4], extent[5]);
image2DActor->SetDisplayExtent(s, s, extent[2], extent[3], extent[4], extent[5]);
image3DActor->SetDisplayExtent(currentSliceIndex, currentSliceIndex, extent[2], extent[3], extent[4], extent[5]);
image2DActor->SetDisplayExtent(currentSliceIndex, currentSliceIndex, extent[2], extent[3], extent[4], extent[5]);
break;
default:
break;
......@@ -264,6 +264,7 @@ void Slice::setReslicerTransform(vtkSmartPointer<vtkTransform> transform) {
// (when the transformation is changed, you need to call updateReslice() in order
// to take the new transformation into account and update the arbitrary slice image
resliceTransform = transform;
updateReslice();
}
// -------------------- get2DImageActor --------------------
......@@ -296,40 +297,31 @@ void Slice::initActors() {
imgToMapFilter->SetLookupTable(lut);
// reslicer for the arbitrary slice
// image2DChangeInfo builds a simple image from the original image
// that has default origin, extent and spacing
vtkSmartPointer<vtkImageChangeInformation> image2DChangeInfo = vtkSmartPointer<vtkImageChangeInformation>::New();
image2DChangeInfo->SetInputData(imgToMapFilter->GetOutput());
image2DChangeInfo->SetOutputOrigin(0.0, 0.0, 0.0);
image2DReslicer = vtkSmartPointer<vtkImageReslice>::New();
image2DReslicer->SetInputConnection(image2DChangeInfo->GetOutputPort());
image2DReslicer->SetInformationInput(imgToMapFilter->GetOutput());
image2DReslicer->AutoCropOutputOn();
image2DReslicer->SetOutputOriginToDefault();
image2DReslicer->SetOutputExtentToDefault();
image2DReslicer->SetOutputSpacingToDefault();
image2DReslicer = vtkSmartPointer<vtkImageReslice>::New();
image2DReslicer->SetOutputDimensionality(2);
image2DReslicer->SetInputConnection(imgToMapFilter->GetOutputPort());
// for the 2D and 3D image actors it is either directly plugged to the output of imgToMapFilter
// (if this is a perpendicular orientation) or to the reslicer (if this is an arbitrary orientation)
image3DActor = vtkSmartPointer<vtkImageActor>::New();
image3DActor->InterpolateOn();
image3DActor->GetMapper()->SetInputConnection(imgToMapFilter->GetOutputPort());
image2DActor = vtkSmartPointer<vtkImageActor>::New();
image2DActor->InterpolateOn();
if (sliceOrientation == ARBITRARY) {
image3DActor->GetMapper()->SetInputConnection(image2DReslicer->GetOutputPort());
image2DActor->GetMapper()->SetInputConnection(image2DReslicer->GetOutputPort());
}
else {
image3DActor->GetMapper()->SetInputConnection(imgToMapFilter->GetOutputPort());
image2DActor->GetMapper()->SetInputConnection(imgToMapFilter->GetOutputPort());
}
// use identity by default for the arbitrary slice
resliceTransform = vtkSmartPointer<vtkTransform>::New();
resliceTransform->Identity();
// Picked plane
initPickPlaneActor();
updatePickPlane();
......@@ -620,18 +612,19 @@ void Slice::updatePixelActor(double x, double y, double z) {
// -------------------- updateReslice --------------------
void Slice::updateReslice() {
if (sliceOrientation == ARBITRARY) {
/*
// Original volume dimensions in number of voxels (x, y and z)
int originalDimensions[3];
originalVolume->GetDimensions(originalDimensions);
// Transformations required to compute the arbitrary slice inside the volume
vtkSmartPointer<vtkTransform> transformationInsideVolume = vtkTransform::New();
transformationInsideVolume->Identity();
// go to the image center
double imageCenter[3];
for (int i=0;i<3;i++) {
imageCenter[i] = /*originalSpacing[i]**/originalDimensions[i] / 2.0;
for (int i = 0; i < 3; i++) {
imageCenter[i] = / * originalSpacing[i]* * /originalDimensions[i] / 2.0;
}
transformationInsideVolume->Translate(imageCenter[0], imageCenter[1], imageCenter[2]);
// apply the current rotation from the frame
......@@ -643,16 +636,9 @@ void Slice::updateReslice() {
// translate to the current slice
transformationInsideVolume->Translate(0.0, 0.0, currentSliceIndex);
resliceTransform->DeepCopy(transformationInsideVolume);
*/
image2DReslicer->SetResliceAxes(resliceTransform->GetMatrix());
image2DReslicer->UpdateInformation();
image2DReslicer->Update();
// image3DActor->SetUserMatrix(resliceTransform->GetMatrix());
// image3DActor->SetInputData(image2DReslicer->GetOutput());
// image3DActor->GetMapper()->SetInputConnection(image2DReslicer->GetOutputPort());
// image2DActor->Update();
// image3DActor->Update();
}
updatePickPlane();
......
......@@ -29,10 +29,10 @@
// -- Core stuff
#include "InteractiveViewer.h"
#include "Log.h"
#include "Application.h"
#include "Frame.h"
#include "Log.h"
// -- VTK stuff
#include <vtkUnstructuredGrid.h>
#include <vtkImageClip.h>
......@@ -99,9 +99,11 @@ void SingleImageComponent::initRepresentation() {
case Slice::SAGITTAL:
setVisibility(InteractiveViewer::getSagittalViewer(), true);
break;
case Slice::ARBITRARY:
case Slice::ARBITRARY:
setVisibility(InteractiveViewer::getArbitraryViewer(), true);
mySlice->setReslicerTransform(getTransform());
// initial frame is center
setSlice(getNumberOfSlices()/2);
break;
}
}
......@@ -159,7 +161,34 @@ void SingleImageComponent::setTransformRotation(double aroundX, double aroundY,
// Do nothing, my parent (the ImageComponent) should do that globally
// unless this is a arbitrary slice
if (sliceOrientation == Slice::ARBITRARY) {
myFrame->setTransformRotation(aroundX, aroundY, aroundZ);
// Rotation should be done from the center of the current slice
// compute current slice center
int dimensions[3];
double spacing[3];
dynamic_cast<ImageComponent*>(getParentComponent())->getImageData()->GetDimensions(dimensions);
dynamic_cast<ImageComponent*>(getParentComponent())->getImageData()->GetSpacing(spacing);
double initialSliceCenter[4]; // homogeneous coordinates
for (int i = 0; i < 2; i++) {
initialSliceCenter[i] = dimensions[i] * spacing[i] / 2.0;
}
initialSliceCenter[2] = 0.0;
initialSliceCenter[3] = 1.0;
double currentSliceCenter[4];
vtkSmartPointer<vtkTransform> centerTransformation = getTransform();
centerTransformation->MultiplyPoint(initialSliceCenter, currentSliceCenter);
// CAMITK_INFO_ALT(QString("initial center=(%1,%2,%3)").arg(initialSliceCenter[0]).arg(initialSliceCenter[1]).arg(initialSliceCenter[2]))
// CAMITK_INFO_ALT(QString("current center=(%1,%2,%3)").arg(currentSliceCenter[0]).arg(currentSliceCenter[1]).arg(currentSliceCenter[2]))
centerTransformation->Identity();
centerTransformation->Translate(currentSliceCenter[0], currentSliceCenter[1], currentSliceCenter[2]);
centerTransformation->RotateX(aroundX);
centerTransformation->RotateY(aroundY);
centerTransformation->RotateZ(aroundZ);
centerTransformation->Translate(-initialSliceCenter[0], -initialSliceCenter[1], 0.0);
centerTransformation->Update();
mySlice->updateReslice();
}
}
......@@ -204,4 +233,19 @@ void SingleImageComponent::translate(double x, double y, double z) {
}
}
// -------------------- setSlice --------------------
void SingleImageComponent::setSlice(int s) {
if (sliceOrientation == Slice::ARBITRARY) {
myFrame->setTransformTranslation(0, 0, s*dynamic_cast<ImageComponent*>(getParentComponent())->getImageData()->GetSpacing()[2]);
mySlice->setSlice(s);
}
else {
Component::setSlice(s);
}
}
void SingleImageComponent::setSlice(double x, double y, double z) {
Component::setSlice(x,y,z);
}
}
......@@ -96,6 +96,12 @@ public:
void setTransformRotation(double, double, double) override;
void setTransformRotationVTK(double, double, double) override;
/// @}
/// rewritten so that the arbitrary slice is directly updating its frame
// (nothing special to do when this is not an arbitrary slice
virtual void setSlice(int) override;
/// rewritten because the setSlice(int) method is overriden (compiler needs this)
virtual void setSlice(double, double, double) override;
protected:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment