Commit 94ad509e authored by Emmanuel Promayon's avatar Emmanuel Promayon

FIXED bug resulting from merge conflicts + code simplification

parent aa092313
......@@ -36,6 +36,7 @@
#include <vtkQuad.h>
#include <vtkDataSetMapper.h>
#include <vtkImageMapToColors.h>
#include <vtkImageChangeInformation.h>
using namespace std;
......@@ -61,7 +62,7 @@ Slice::~Slice() {
void Slice::init() {
currentSliceIndex = 0;
for (int i=0; i<3; i++) {
for (int i = 0; i < 3; i++) {
originalSpacing[i] = 1.0;
}
......@@ -72,13 +73,8 @@ void Slice::init() {
pickPlaneActorPointSet = nullptr;
pixelActor = nullptr;
pixelActorPointSet = nullptr;
image2DChangeInfo = vtkSmartPointer<vtkImageChangeInformation>::New();
image2DReslicer = vtkSmartPointer<vtkImageReslice>::New();
transformReslicer = vtkSmartPointer<vtkTransform>::New();
resliceTransform = vtkSmartPointer<vtkTransform>::New();
transformReslicer->Identity();
resliceTransform->Identity();
image2DReslicer = nullptr;
resliceTransform = nullptr;
}
// -------------------- getImageData --------------------
......@@ -98,7 +94,7 @@ void Slice::setOriginalVolume(vtkSmartPointer<vtkImageData> volume) {
originalVolume->GetDimensions(originalDimensions);
originalVolume->GetSpacing(originalSpacing);
for (int i=0; i<3; i++) {
for (int i = 0; i < 3; i++) {
// compute original size (nb of slice * spacing)
originalSize[i] = originalDimensions[i] * originalSpacing[i];
......@@ -268,40 +264,6 @@ void Slice::setReslicerTransform(vtkSmartPointer<vtkTransform> t) {
resliceTransform = t;
}
// -------------------- updateReslice --------------------
void Slice::updateReslice() {
if (sliceOrientation == ARBITRARY) {
double wxyz[4];
transformReslicer->Identity();
transformReslicer->Translate(originalDimensions[0] / 2, originalDimensions[1] / 2, originalDimensions[2] / 2);
resliceTransform->GetOrientationWXYZ(wxyz);
transformReslicer->RotateWXYZ(wxyz[0], wxyz[1], wxyz[2], wxyz[3]);
transformReslicer->Translate(-originalDimensions[0] / 2, -originalDimensions[1] / 2, -originalDimensions[2] / 2);
transformReslicer->Translate(0.0, 0.0, currentSliceIndex);
image2DReslicer->SetResliceAxes(transformReslicer->GetMatrix());
image2DReslicer->Update();
image3DActor->SetUserMatrix(resliceTransform->GetMatrix());
image3DActor->SetInputData(image2DReslicer->GetOutput());
image3DActor->Update();
}
updateLocalTransformation();
updatePickPlane();
}
// -------------------- updateLocalTransformation --------------------
void Slice::updateLocalTransformation() {
image2DReslicer->SetOutputDimensionality(3);
image2DReslicer->UpdateInformation();
image2DReslicer->SetOutputDimensionality(2);
image2DReslicer->UpdateInformation();
}
// -------------------- get2DImageActor --------------------
vtkSmartPointer<vtkImageActor> Slice::get2DImageActor() const {
return image2DActor;
......@@ -331,8 +293,23 @@ void Slice::initActors() {
// set the lookupTable
imgToMapFilter->SetLookupTable(lut);
// the 2D and 3D image actors are directly plugged to the output of imgToMapFilter
image3DActor = vtkSmartPointer<vtkImageActor>::New();
image3DActor->GetMapper()->SetInputConnection(imgToMapFilter->GetOutputPort());
image3DActor->InterpolateOn();
image2DActor = vtkSmartPointer<vtkImageActor>::New();
image2DActor->GetMapper()->SetInputConnection(imgToMapFilter->GetOutputPort());
image2DActor->InterpolateOn();
// 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();
......@@ -340,20 +317,15 @@ void Slice::initActors() {
image2DReslicer->SetOutputExtentToDefault();
image2DReslicer->SetOutputSpacingToDefault();
// the 2D and 3D image actors are directly plugged to the output of imgToMapFilter
image3DActor = vtkSmartPointer<vtkImageActor>::New();
image3DActor->GetMapper()->SetInputConnection(imgToMapFilter->GetOutputPort());
image3DActor->InterpolateOn();
image2DActor = vtkSmartPointer<vtkImageActor>::New();
image2DActor->GetMapper()->SetInputConnection(imgToMapFilter->GetOutputPort());
image2DActor->InterpolateOn();
// use identity by default for the arbitrary slice
resliceTransform = vtkSmartPointer<vtkTransform>::New();
resliceTransform->Identity();
// Pick plane
// Picked plane
initPickPlaneActor();
updatePickPlane();
// pixel
// Picked pixel
initPixelActor();
updatePixelActor();
}
......@@ -527,8 +499,8 @@ void Slice::updatePickPlane() {
switch (sliceOrientation) {
case AXIAL_NEURO:
case AXIAL:
sliceBackPlane = currentSliceIndex*originalSpacing[2] - originalSpacing[2] / 2.0;
sliceFrontPlane = currentSliceIndex*originalSpacing[2] + originalSpacing[2] / 2.0;
sliceBackPlane = currentSliceIndex * originalSpacing[2] - originalSpacing[2] / 2.0;
sliceFrontPlane = currentSliceIndex * originalSpacing[2] + originalSpacing[2] / 2.0;
pickPlaneActorPointSet->GetPoints()->SetPoint(0, 0.0, 0.0, sliceBackPlane);
pickPlaneActorPointSet->GetPoints()->SetPoint(1, 0.0, 0.0, sliceFrontPlane);
pickPlaneActorPointSet->GetPoints()->SetPoint(2, 0.0, originalSize[1], sliceFrontPlane);
......@@ -540,8 +512,8 @@ void Slice::updatePickPlane() {
break;
case CORONAL:
sliceBackPlane = currentSliceIndex*originalSpacing[1] - originalSpacing[1] / 2.0;
sliceFrontPlane = currentSliceIndex*originalSpacing[1] + originalSpacing[1] / 2.0;
sliceBackPlane = currentSliceIndex * originalSpacing[1] - originalSpacing[1] / 2.0;
sliceFrontPlane = currentSliceIndex * originalSpacing[1] + originalSpacing[1] / 2.0;
pickPlaneActorPointSet->GetPoints()->SetPoint(0, 0.0, sliceBackPlane, 0.0);
pickPlaneActorPointSet->GetPoints()->SetPoint(1, 0.0, sliceFrontPlane, 0.0);
pickPlaneActorPointSet->GetPoints()->SetPoint(2, 0.0, sliceFrontPlane, originalSize[2]);
......@@ -553,8 +525,8 @@ void Slice::updatePickPlane() {
break;
case SAGITTAL:
sliceBackPlane = currentSliceIndex*originalSpacing[0] - originalSpacing[0] / 2.0;
sliceFrontPlane = currentSliceIndex*originalSpacing[0] + originalSpacing[0] / 2.0;
sliceBackPlane = currentSliceIndex * originalSpacing[0] - originalSpacing[0] / 2.0;
sliceFrontPlane = currentSliceIndex * originalSpacing[0] + originalSpacing[0] / 2.0;
pickPlaneActorPointSet->GetPoints()->SetPoint(0, sliceBackPlane, 0.0, 0.0);
pickPlaneActorPointSet->GetPoints()->SetPoint(1, sliceFrontPlane, 0.0, 0.0);
pickPlaneActorPointSet->GetPoints()->SetPoint(2, sliceFrontPlane, 0.0, originalSize[2]);
......@@ -636,6 +608,52 @@ void Slice::updatePixelActor(double x, double y, double z) {
pixelActorPointSet->Modified();
}
// -------------------- updateReslice --------------------
void Slice::updateReslice() {
if (sliceOrientation == ARBITRARY) {
double wxyz[4];
// 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
transformationInsideVolume->Translate(originalDimensions[0] / 2, originalDimensions[1] / 2, originalDimensions[2] / 2);
// apply the current rotation from the frame
resliceTransform->GetOrientationWXYZ(wxyz);
transformationInsideVolume->RotateWXYZ(wxyz[0], wxyz[1], wxyz[2], wxyz[3]);
// go back to the image origin
transformationInsideVolume->Translate(-originalDimensions[0] / 2, -originalDimensions[1] / 2, -originalDimensions[2] / 2);
// translate to the current slice
transformationInsideVolume->Translate(0.0, 0.0, currentSliceIndex);
image2DReslicer->SetResliceAxes(transformationInsideVolume->GetMatrix());
image2DReslicer->Update();
image3DActor->SetUserMatrix(resliceTransform->GetMatrix());
image3DActor->SetInputData(image2DReslicer->GetOutput());
image3DActor->Update();
}
updateLocalTransformation();
updatePickPlane();
}
// -------------------- updateLocalTransformation --------------------
void Slice::updateLocalTransformation() {
image2DReslicer->SetOutputDimensionality(3);
image2DReslicer->UpdateInformation();
image2DReslicer->SetOutputDimensionality(2);
image2DReslicer->UpdateInformation();
}
......
......@@ -37,6 +37,7 @@
#include <vtkActor.h>
#include <vtkImageActor.h>
#include <vtkUnstructuredGrid.h>
#include <vtkImageReslice.h>
namespace camitk {
/**
......@@ -47,6 +48,8 @@ namespace camitk {
*
* This class manages the visual representation of one slice of a volume image.
* The slice depends on the orientation and the currently selected slice index.
* A special case is the arbitrary orientation, where the orientation is not perpendicular to one
* of the axes, but can have any free orientation and translation.
*
* A slice is represented in 2D and 3D thanks to:
* - image2DActor that provides a 2D representation (the slice in the world reference frame)
......@@ -303,25 +306,17 @@ protected:
/// @name Management of the arbitrary slice
/// @{
/// Transformations required to compute the arbitrary slice inside the volume
/// this can be any transform, unlike the image orientation
vtkSmartPointer<vtkTransform> transformReslicer;
/// Transformation relative to the 3D image actor (it is not parallel to one
/// of the main axe, but has a specific rotation)
/// of the main axe, but has a specific rotation). This should be initialized
/// using the single image component transformation to the world or parent.
vtkSmartPointer<vtkTransform> resliceTransform;
/// update the 2D reslicer
void updateLocalTransformation();
/// This is required for the arbitrary slice.
/// It builds a simple image from the original image
/// that has default origin, extent and spacing
vtkSmartPointer<vtkImageChangeInformation> image2DChangeInfo;
/// The image reslicer computes the arbitrary slice pixels
vtkSmartPointer<vtkImageReslice> image2DReslicer;
/// update the 2D reslicer
void updateLocalTransformation();
/// @}
/// @name Used to visualize the current picking
......@@ -376,3 +371,4 @@ protected:
}
#endif // CANONICAL_SLICE_H
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