]> Creatis software - openheart.git/commitdiff
commit all the files for the first time master
authorolivier <olivier.bernard@creatis.insa-lyon.fr>
Tue, 10 Jun 2014 11:49:27 +0000 (13:49 +0200)
committerolivier <olivier.bernard@creatis.insa-lyon.fr>
Tue, 10 Jun 2014 11:49:27 +0000 (13:49 +0200)
28 files changed:
Applications/CMakeLists.txt [new file with mode: 0644]
Applications/CMakeLists.txt~ [new file with mode: 0644]
Applications/OpenHeartGui.cxx [new file with mode: 0644]
Applications/OpenHeartGui.h [new file with mode: 0644]
Applications/OpenHeartGui.ui [new file with mode: 0644]
Applications/qtOpenHeart.cxx [new file with mode: 0644]
Applications/ui_OpenHeartGui.h [new file with mode: 0644]
Applications/vtkMyInteractorStyleTrackballCameraOpenHeart.cxx [new file with mode: 0644]
Applications/vtkMyInteractorStyleTrackballCameraOpenHeart.h [new file with mode: 0644]
Applications/vtkMyInteractorStyleTrackballCameraOpenHeartXY.cxx [new file with mode: 0644]
Applications/vtkMyInteractorStyleTrackballCameraOpenHeartXY.h [new file with mode: 0644]
Applications/vtkMyInteractorStyleTrackballCameraOpenHeartXZ.cxx [new file with mode: 0644]
Applications/vtkMyInteractorStyleTrackballCameraOpenHeartXZ.h [new file with mode: 0644]
Applications/vtkMyInteractorStyleTrackballCameraOpenHeartYZ.cxx [new file with mode: 0644]
Applications/vtkMyInteractorStyleTrackballCameraOpenHeartYZ.h [new file with mode: 0644]
CMakeLists.txt [new file with mode: 0644]
Common/CMakeLists.txt [new file with mode: 0644]
Common/CMakeLists.txt~ [new file with mode: 0644]
Common/vtkOptimizedImageData.cxx [new file with mode: 0644]
Common/vtkOptimizedImageData.h [new file with mode: 0644]
Config/ConfigIschemicCase.txt~ [new file with mode: 0644]
Config/ConfigOpenHeart.txt [new file with mode: 0644]
Config/ConfigOpenHeart.txt~ [new file with mode: 0644]
Config/HeartBeatsConfig (copy).txt~ [new file with mode: 0644]
Config/HeartBeatsConfig.txt~ [new file with mode: 0644]
Config/HeartSimuConfig.txt~ [new file with mode: 0644]
Config/HeartSimuConfig_tmp.txt~ [new file with mode: 0644]
test.txt~ [new file with mode: 0644]

diff --git a/Applications/CMakeLists.txt b/Applications/CMakeLists.txt
new file mode 100644 (file)
index 0000000..0b1d91d
--- /dev/null
@@ -0,0 +1,39 @@
+
+INCLUDE_DIRECTORIES(
+    ${VTK_INCLUDE_DIR}
+    ${APPLICATIONS_INCLUDE_DIR}
+    ${OPENHEART_INCLUDE_DIR}
+)
+
+SET(OpenHeartGuiSrcs qtOpenHeart.cxx OpenHeartGui.cxx)
+SET(OpenHeartGuiUI OpenHeartGui.ui)
+SET(OpenHeartGuiHeaders OpenHeartGui.h)
+QT4_WRAP_UI(UISrcs ${OpenHeartGuiUI})
+QT4_WRAP_CPP(MOCSrcs ${OpenHeartGuiHeaders} )
+SOURCE_GROUP("Resources" FILES
+  ${OpenHeartGuiUI}
+)
+SOURCE_GROUP("Generated" FILES
+  ${UISrcs}
+  ${MOCSrcs}
+)
+
+ADD_EXECUTABLE( qtOpenHeart ${OpenHeartGuiSrcs} ${UISrcs} ${MOCSrcs})
+
+
+ADD_LIBRARY(interactors
+  vtkMyInteractorStyleTrackballCameraOpenHeart.cxx
+  vtkMyInteractorStyleTrackballCameraOpenHeartXY.cxx
+  vtkMyInteractorStyleTrackballCameraOpenHeartXZ.cxx
+  vtkMyInteractorStyleTrackballCameraOpenHeartYZ.cxx
+)
+
+
+TARGET_LINK_LIBRARIES( qtOpenHeart common interactors QVTK
+        vtkCommon vtkFiltering vtkGraphics vtkImaging vtkIO vtkRendering vtkWidgets vtkHybrid vtkCharts )
+
+
+
diff --git a/Applications/CMakeLists.txt~ b/Applications/CMakeLists.txt~
new file mode 100644 (file)
index 0000000..0b1d91d
--- /dev/null
@@ -0,0 +1,39 @@
+
+INCLUDE_DIRECTORIES(
+    ${VTK_INCLUDE_DIR}
+    ${APPLICATIONS_INCLUDE_DIR}
+    ${OPENHEART_INCLUDE_DIR}
+)
+
+SET(OpenHeartGuiSrcs qtOpenHeart.cxx OpenHeartGui.cxx)
+SET(OpenHeartGuiUI OpenHeartGui.ui)
+SET(OpenHeartGuiHeaders OpenHeartGui.h)
+QT4_WRAP_UI(UISrcs ${OpenHeartGuiUI})
+QT4_WRAP_CPP(MOCSrcs ${OpenHeartGuiHeaders} )
+SOURCE_GROUP("Resources" FILES
+  ${OpenHeartGuiUI}
+)
+SOURCE_GROUP("Generated" FILES
+  ${UISrcs}
+  ${MOCSrcs}
+)
+
+ADD_EXECUTABLE( qtOpenHeart ${OpenHeartGuiSrcs} ${UISrcs} ${MOCSrcs})
+
+
+ADD_LIBRARY(interactors
+  vtkMyInteractorStyleTrackballCameraOpenHeart.cxx
+  vtkMyInteractorStyleTrackballCameraOpenHeartXY.cxx
+  vtkMyInteractorStyleTrackballCameraOpenHeartXZ.cxx
+  vtkMyInteractorStyleTrackballCameraOpenHeartYZ.cxx
+)
+
+
+TARGET_LINK_LIBRARIES( qtOpenHeart common interactors QVTK
+        vtkCommon vtkFiltering vtkGraphics vtkImaging vtkIO vtkRendering vtkWidgets vtkHybrid vtkCharts )
+
+
+
diff --git a/Applications/OpenHeartGui.cxx b/Applications/OpenHeartGui.cxx
new file mode 100644 (file)
index 0000000..24c324b
--- /dev/null
@@ -0,0 +1,2491 @@
+/**
+* Progam made by Olivier Bernard, associate professor
+* at Institut National des Sciences Appliquees (INSA) Lyon,
+* CREATIS Laboratory,
+* 69621 Villeurbanne, France,
+* 07th of May 2014
+*/
+
+#include "OpenHeartGui.h"
+
+#include <vtkObjectFactory.h>
+#include <vtkRenderWindow.h>
+#include <vtkRenderer.h>
+#include <vtkImageData.h>
+#include <vtkTextProperty.h>
+#include <vtkProperty.h>
+#include <vtkRendererCollection.h>
+#include <vtkRenderer.h>
+#include <vtkInteractorStyleTrackballCamera.h>
+#include <vtkCamera.h>
+#include <vtkImageGaussianSmooth.h>
+#include <vtkMarchingCubes.h>
+#include <vtkDataSetMapper.h>
+#include <vtkPolyDataMapper.h>
+#include <vtkCutter.h>
+#include <vtkSphereSource.h>
+#include <vtkInteractorStyleSwitch.h>
+#include <vtkTextMapper.h>
+#include <vtkMath.h>
+#include <vtkMetaImageWriter.h>
+#include <vtkDepthSortPolyData.h>
+#include <vtkTimerLog.h>
+#include <vtkTransform.h>
+#include <vtkTransformPolyDataFilter.h>
+#include <vtkContextView.h>
+#include <vtkTable.h>
+#include <vtkFloatArray.h>
+#include <vtkChartXY.h>
+#include <vtkPlot.h>
+#include <vtkContextScene.h>
+#include <vtkAxis.h>
+#include <vtkCamera.h>
+#include <vtkAxesActor.h>
+#include <vtkOrientationMarkerWidget.h>
+#include <vtkCaptionActor2D.h>
+#include <vtkMetaImageReader.h>
+#include <vtkImageCast.h>
+#include <vtkUnstructuredGridReader.h>
+#include <vtkUnstructuredGrid.h>
+#include <vtkGenericDataObjectReader.h>
+#include <vtkCellArray.h>
+#include <vtkXMLPolyDataReader.h>
+#include <vtkPolyDataReader.h>
+#include <vtkUnstructuredGridGeometryFilter.h>
+#include <vtkDepthSortPolyData.h>
+#include <vtkLineSource.h>
+#include <vtkSmartPointer.h>
+#include <vtkIntersectionPolyDataFilter.h>
+#include <vtkTriangleFilter.h>
+#include <vtkImageData.h>
+#include <vtkImageReslice.h>
+#include <vtkImageMapper.h>
+#include <vtkSphereSource.h>
+#include <vtkLine.h>
+#include <vtkOutlineFilter.h>
+#include "vtkMyInteractorStyleTrackballCameraOpenHeart.h"
+#include "vtkMyInteractorStyleTrackballCameraOpenHeartXY.h"
+#include "vtkMyInteractorStyleTrackballCameraOpenHeartXZ.h"
+#include "vtkMyInteractorStyleTrackballCameraOpenHeartYZ.h"
+#include <QResizeEvent>
+#include <QPalette>
+
+
+#define CONFIG_FILE "../../Config/ConfigOpenHeart.txt"
+
+
+// ****************************************************************
+// ****************************************************************
+// ****************************************************************
+class vtkMyChartXY : public vtkChartXY
+{
+
+    bool MouseButtonPressEvent(const vtkContextMouseEvent &mouse) { return true; }
+    bool MouseWheelEvent(const vtkContextMouseEvent &mouse, int delta) { return true; }
+    bool MouseMoveEvent(const vtkContextMouseEvent &mouse) { return true; }
+    bool MouseButtonReleaseEvent(const vtkContextMouseEvent &mouse) { return true; }
+
+};
+
+
+// ****************************************************************
+// ****************************************************************
+// ****************************************************************
+OpenHeartGui::OpenHeartGui()
+{
+
+    /// Initialize window
+    this->setupUi(this);
+    this->InstantiateQtVtkRenderers();
+
+    /// Set colors of the interface
+    this->SetInterfaceColors();
+
+    /// Allocate attributes
+    for ( int k=0; k<3; k++ )
+        this->Dims[k] = 0;
+    this->PreviousFrame = 0;
+    this->CurrentFrame = 0;
+    this->NumberOfVolumes = 0;
+    this->ImageData = 0;
+    this->TableChart = 0;
+    this->Properties = new RendererProperties;
+    this->ViewButton = 0;
+    this->MeshRepresentation = 0;
+    this->MeshColor = 0;
+    this->ZoomLabel = 1.6;
+    this->ZoomMain = 1.5;
+    this->RotationMatrix = vtkSmartPointer<vtkMatrix4x4>::New();
+    this->RotationMatrix->Identity();
+    this->TransformViewOrientation = vtkSmartPointer<vtkTransform>::New();
+    this->RotationMatrixInv = vtkSmartPointer<vtkMatrix4x4>::New();
+    this->RotationMatrixInv->Identity();
+    this->TransformViewOrientationInv = vtkSmartPointer<vtkTransform>::New();
+    this->OrientationWidget = vtkSmartPointer<vtkOrientationMarkerWidget>::New();
+
+    /// Flag management
+    this->FlagInterpolation = 0;
+    this->FlagDisplayMesh = 0;
+    this->FlagDisplayMeshContours = 0;
+    this->FlagDisplayMeshContourX = 0;
+    this->FlagDisplayMeshContourY = 0;
+    this->FlagDisplayMeshContourZ = 0;
+    this->FlagLoopEndToBegin = 0;
+    this->FlagLoopBeginToEnd = 0;
+    this->FlagPlay = 0;
+    this->FlagDisplayText = 1;
+    this->FlagHidePlan = 0;
+    this->FlagLongAxis = 0;
+    this->FlagDisplayApexPoint = 0;
+    this->FlagDisplayBasalPoint = 0;
+    this->FlagDisplayMeshContours = 1;
+    this->FlagDisplayLongAxis = 0;
+    this->FlagReslice = 0;
+
+    /// Widget management
+    this->InitPickers();
+    this->InitProperties();
+    this->InitWidgets();
+    this->SetCustomInteractorStyle();
+
+    /// Read 3D volume and create corresponding OpenHeart
+    std::ifstream file(CONFIG_FILE, std::ifstream::in);
+    std::string inputFilename;
+    file >> inputFilename;
+    file >> this->NumberOfVolumes;
+
+    /// Load sequence of volumes
+    this->CreateFromSequenceDataPointer(inputFilename);
+
+    /// Manage main window display
+    /// Force to view XZ orientation at initialization
+    this->ForceXZView();
+
+    /// Initialize text displayed in the main window
+    this->InitTexts();
+
+    /// Initialize the orientation axes after rendering the volume
+    this->InitOrientationAxes();
+
+    /// Manage XY window display
+    this->qVTKXY->GetRenderWindow()->Render();
+
+    /// Manage XZ window display
+    this->qVTKXZ->GetRenderWindow()->Render();
+
+    /// Manage YZ window display
+    this->qVTKYZ->GetRenderWindow()->Render();
+
+    /// Manage scrollbar
+    this->scrollBar->setMaximum(this->NumberOfVolumes-1);
+    this->SliderMeshAlpha->setMaximum(100);
+    this->SliderMeshAlpha->setSingleStep(1);
+    this->SliderMeshAlpha->setValue(20);
+
+    /// Initialized the chart part of the interface
+    this->ViewChart = vtkSmartPointer<vtkContextView>::New();
+    this->ViewChart->SetInteractor(this->qVTKChart->GetInteractor());
+    this->qVTKChart->SetRenderWindow(this->ViewChart->GetRenderWindow());
+    this->qVTKChart->GetRenderWindow()->SetSize(478,478);
+    this->ViewChart->GetRenderer()->SetBackground(255./255.,255./255.,255./255.);
+    this->InitChar();
+
+    /// Instantiate timer for the player
+    Timer = new QTimer(this);
+
+    /// Instantiate Qt events
+    connect(this->scrollBar, SIGNAL(valueChanged(int)), this, SLOT(slotRefreshViewer(int)));
+    connect(this->SliderMeshAlpha, SIGNAL(valueChanged(int)), this, SLOT(slotMeshAlpha(int)));
+    connect(this->pushButtonPlay, SIGNAL(clicked()), this, SLOT(slotPlay()));
+    connect(this->pushButtonXY, SIGNAL(clicked()), this, SLOT(slotXYView()));
+    connect(this->pushButtonXZ, SIGNAL(clicked()), this, SLOT(slotXZView()));
+    connect(this->pushButtonYZ, SIGNAL(clicked()), this, SLOT(slotYZView()));
+    connect(this->pushButton3D, SIGNAL(clicked()), this, SLOT(slot3DView()));
+    connect(this->pushButtonMesh, SIGNAL(clicked()), this, SLOT(slotMeshView()));
+    connect(this->pushButtonMeshRepresentation, SIGNAL(clicked()), this, SLOT(slotMeshRepresentation()));
+    connect(this->pushButtonMeshColor, SIGNAL(clicked()), this, SLOT(slotMeshColor()));
+    connect(this->pushButtonCutter, SIGNAL(clicked()), this, SLOT(slotMeshCutter()));
+    connect(this->Timer, SIGNAL(timeout()), this, SLOT(slotTimerEvent()));
+    connect(this->tabWidgetOption, SIGNAL(currentChanged(int)), this, SLOT(slotTabChange(int)));
+    connect(this->pushButtonBasalPoint, SIGNAL(clicked()), this, SLOT(slotBasalPoint()));
+    connect(this->pushButtonApexPoint, SIGNAL(clicked()), this, SLOT(slotApexPoint()));
+    connect(this->pushButtonReslice, SIGNAL(clicked()), this, SLOT(slotReslice()));
+
+    /// Update coords as we move through the window
+    Connections = vtkEventQtSlotConnect::New();
+    Connections->Connect(this->qVTK->GetRenderWindow()->GetInteractor(),
+                        vtkCommand::MouseMoveEvent,
+                        this,
+                        SLOT(slotUpdateCoords(vtkObject*)));
+
+}
+
+
+OpenHeartGui::~OpenHeartGui()
+{
+
+  Connections->Delete();
+
+}
+
+
+void OpenHeartGui::InstantiateQtVtkRenderers()
+{
+
+    /// ****************************************************************
+    /// Create the main window
+    vtkSmartPointer<vtkRenderWindow> renwin = vtkSmartPointer<vtkRenderWindow>::New();
+    renwin->StereoCapableWindowOn();
+
+    /// Activate 3DConnexion device
+    this->qVTK->SetUseTDx(true);
+    this->qVTK->SetRenderWindow(renwin);
+
+    /// Initialize interactor
+    this->Interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
+    this->Interactor = static_cast<vtkRenderWindowInteractor *>(this->qVTK->GetInteractor()->GetRenderWindow()->GetInteractor());
+
+    /// Add a renderer
+    this->Ren = vtkSmartPointer<vtkRenderer>::New();
+    this->qVTK->GetRenderWindow()->AddRenderer(this->Ren);
+    this->Ren->SetBackground(0,0,0);
+    this->Ren->GetActiveCamera()->SetParallelProjection(1);
+
+
+    /// ****************************************************************
+    /// Create XY window
+    vtkSmartPointer<vtkRenderWindow> renwinXY = vtkSmartPointer<vtkRenderWindow>::New();
+    renwinXY->StereoCapableWindowOn();
+
+    /// Activate 3DConnexion device
+    this->qVTKXY->SetUseTDx(true);
+    this->qVTKXY->SetRenderWindow(renwinXY);
+
+    /// Initialize interactor
+    this->InteractorXY = vtkSmartPointer<vtkRenderWindowInteractor>::New();
+    this->InteractorXY = static_cast<vtkRenderWindowInteractor *>(this->qVTKXY->GetInteractor()->GetRenderWindow()->GetInteractor());
+
+    /// Add a renderer
+    this->RenXY = vtkSmartPointer<vtkRenderer>::New();
+    this->qVTKXY->GetRenderWindow()->AddRenderer(this->RenXY);
+    this->RenXY->SetBackground(0,0,0);
+    this->RenXY->GetActiveCamera()->SetParallelProjection(1);
+
+
+    /// ****************************************************************
+    /// Create XZ window
+    vtkSmartPointer<vtkRenderWindow> renwinXZ = vtkSmartPointer<vtkRenderWindow>::New();
+    renwinXZ->StereoCapableWindowOn();
+
+    /// Activate 3DConnexion device
+    this->qVTKXZ->SetUseTDx(true);
+    this->qVTKXZ->SetRenderWindow(renwinXZ);
+
+    /// Initialize interactor
+    this->InteractorXZ = vtkSmartPointer<vtkRenderWindowInteractor>::New();
+    this->InteractorXZ = static_cast<vtkRenderWindowInteractor *>(this->qVTKXZ->GetInteractor()->GetRenderWindow()->GetInteractor());
+
+    /// Add a renderer
+    this->RenXZ = vtkSmartPointer<vtkRenderer>::New();
+    this->qVTKXZ->GetRenderWindow()->AddRenderer(this->RenXZ);
+    this->RenXZ->SetBackground(0,0,0);
+    this->RenXZ->GetActiveCamera()->SetParallelProjection(1);
+
+
+    /// ****************************************************************
+    /// Create YZ window
+    vtkSmartPointer<vtkRenderWindow> renwinYZ = vtkSmartPointer<vtkRenderWindow>::New();
+    renwinYZ->StereoCapableWindowOn();
+
+    /// Activate 3DConnexion device
+    this->qVTKYZ->SetUseTDx(true);
+    this->qVTKYZ->SetRenderWindow(renwinYZ);
+
+    /// Initialize interactor
+    this->InteractorYZ = static_cast<vtkRenderWindowInteractor *>(this->qVTKYZ->GetInteractor()->GetRenderWindow()->GetInteractor());
+
+    /// Add a renderer
+    this->RenYZ = vtkSmartPointer<vtkRenderer>::New();
+    this->qVTKYZ->GetRenderWindow()->AddRenderer(this->RenYZ);
+    this->RenYZ->SetBackground(0,0,0);
+    this->RenYZ->GetActiveCamera()->SetParallelProjection(1);
+
+}
+
+
+void OpenHeartGui::slotMeshView()
+{
+    this->HidePlanModeManagement();
+}
+
+
+void OpenHeartGui::slotYZView()
+{
+
+    this->ViewButton = 1;
+    this->Properties->xIPW->SetTextureVisibility(1);
+    this->Properties->xIPW->GetPlaneProperty()->SetOpacity(1);
+    this->Properties->xIPW->GetPlaneProperty()->SetColor(0,0,0);
+    this->Properties->yIPW->SetTextureVisibility(0);
+    this->Properties->yIPW->GetPlaneProperty()->SetOpacity(0);
+    this->Properties->yIPW->GetPlaneProperty()->SetColor(0,0,0);
+    this->Properties->zIPW->SetTextureVisibility(0);
+    this->Properties->zIPW->GetPlaneProperty()->SetOpacity(0);
+    this->Properties->zIPW->GetPlaneProperty()->SetColor(0,0,0);
+
+    if ( this->FlagHidePlan == 0 )
+    {
+
+        /// Update corresponding viewer
+        int view = 2;
+        this->UpdateViewer(view,this->ZoomMain,this->Ren);
+
+        /// Also update Slice text
+        int slice = (int)( (this->Properties->position[0] - this->ImageData->GetOrigin()[0]) / this->ImageData->GetSpacing()[0] + 0.5f );
+        QString strSlice;
+        strSlice.sprintf("Slice: %d",slice);
+        this->Properties->TextMapperSlice->SetInput(strSlice.toStdString().c_str());
+
+    }
+    else {
+        this->FlagHidePlan = 0;
+    }
+
+    if ( this->FlagDisplayMeshContours == 1 )
+    {
+        this->GetMeshRenderer()->AddActor(this->Properties->xCutActor);
+        this->GetMeshRenderer()->RemoveActor(this->Properties->yCutActor);
+        this->GetMeshRenderer()->RemoveActor(this->Properties->zCutActor);
+        this->GetRenderWindow()->Render();
+    }
+
+}
+
+
+void OpenHeartGui::slotXZView()
+{
+
+    this->ViewButton = 2;
+    this->Properties->xIPW->SetTextureVisibility(0);
+    this->Properties->xIPW->GetPlaneProperty()->SetOpacity(0);
+    this->Properties->xIPW->GetPlaneProperty()->SetColor(0,0,0);
+    this->Properties->yIPW->SetTextureVisibility(1);
+    this->Properties->yIPW->GetPlaneProperty()->SetOpacity(1);
+    this->Properties->yIPW->GetPlaneProperty()->SetColor(0,0,0);
+    this->Properties->zIPW->SetTextureVisibility(0);
+    this->Properties->zIPW->GetPlaneProperty()->SetOpacity(0);
+    this->Properties->zIPW->GetPlaneProperty()->SetColor(0,0,0);
+
+    if ( this->FlagHidePlan == 0 )
+    {
+
+        /// Update corresponding viewer
+        int view = 1;
+        this->UpdateViewer(view,this->ZoomMain,this->Ren);
+
+        /// Also update Slice text
+        int slice = (int)( (this->Properties->position[1] - this->ImageData->GetOrigin()[1]) / this->ImageData->GetSpacing()[1] + 0.5f );
+        QString strSlice;
+        strSlice.sprintf("Slice: %d",slice);
+        this->Properties->TextMapperSlice->SetInput(strSlice.toStdString().c_str());
+
+    }
+    else {
+        this->FlagHidePlan = 0;
+    }
+
+    if ( this->FlagDisplayMeshContours == 1 )
+    {
+        this->GetMeshRenderer()->RemoveActor(this->Properties->xCutActor);
+        this->GetMeshRenderer()->AddActor(this->Properties->yCutActor);
+        this->GetMeshRenderer()->RemoveActor(this->Properties->zCutActor);
+        this->GetRenderWindow()->Render();
+    }
+
+}
+
+
+void OpenHeartGui::slotXYView()
+{
+
+    this->ViewButton = 3;
+    this->Properties->xIPW->SetTextureVisibility(0);
+    this->Properties->xIPW->GetPlaneProperty()->SetOpacity(0);
+    this->Properties->xIPW->GetPlaneProperty()->SetColor(0,0,0);
+    this->Properties->yIPW->SetTextureVisibility(0);
+    this->Properties->yIPW->GetPlaneProperty()->SetOpacity(0);
+    this->Properties->yIPW->GetPlaneProperty()->SetColor(0,0,0);
+    this->Properties->zIPW->SetTextureVisibility(1);
+    this->Properties->zIPW->GetPlaneProperty()->SetOpacity(1);
+    this->Properties->zIPW->GetPlaneProperty()->SetColor(0,0,0);
+
+    if ( this->FlagHidePlan == 0 )
+    {
+
+        /// Update corresponding viewer
+        int view = 0;
+        this->UpdateViewer(view,this->ZoomMain,this->Ren);
+
+        /// Also update Slice text
+        int slice = (int)( (this->Properties->position[2] - this->ImageData->GetOrigin()[2]) / this->ImageData->GetSpacing()[2] + 0.5f );
+        QString strSlice;
+        strSlice.sprintf("Slice: %d",slice);
+        this->Properties->TextMapperSlice->SetInput(strSlice.toStdString().c_str());
+
+    }
+    else {
+        this->FlagHidePlan = 0;
+    }
+
+    if ( this->FlagDisplayMeshContours == 1 )
+    {
+        this->GetMeshRenderer()->RemoveActor(this->Properties->xCutActor);
+        this->GetMeshRenderer()->RemoveActor(this->Properties->yCutActor);
+        this->GetMeshRenderer()->AddActor(this->Properties->zCutActor);
+        this->GetRenderWindow()->Render();
+    }
+
+}
+
+
+void OpenHeartGui::slot3DView()
+{
+
+    this->ViewButton = 0;
+    this->Properties->xIPW->SetTextureVisibility(1);
+    this->Properties->xIPW->GetPlaneProperty()->SetOpacity(1);
+    this->Properties->xIPW->GetPlaneProperty()->SetColor(1,0,0);
+    this->Properties->yIPW->SetTextureVisibility(1);
+    this->Properties->yIPW->GetPlaneProperty()->SetOpacity(1);
+    this->Properties->yIPW->GetPlaneProperty()->SetColor(1,1,0);
+    this->Properties->zIPW->SetTextureVisibility(1);
+    this->Properties->zIPW->GetPlaneProperty()->SetOpacity(1);
+    this->Properties->zIPW->GetTextProperty()->SetColor(1,0,0);
+    this->Properties->zIPW->GetPlaneProperty()->SetColor(0,0,1);
+
+    if ( this->FlagHidePlan == 0 )
+    {
+
+        this->Ren->ResetCamera();
+        this->Ren->GetActiveCamera()->Zoom(1.);
+
+        if ( this->Properties->MeshActor != 0 )
+        {
+            if ( this->FlagDisplayMesh == 0 ) {
+                this->FlagDisplayMesh = 1;
+                this->GetMeshRenderer()->AddActor(this->Properties->MeshActor);
+            }
+        }
+
+    }
+    else {
+        this->FlagHidePlan = 0;
+    }
+    this->GetRenderWindow()->Render();
+
+}
+
+
+void OpenHeartGui::slotMeshRepresentation()
+{
+
+    if ( this->Properties->MeshActor )
+    {
+
+        if ( this->FlagDisplayMeshContours == 1 )
+        {
+            this->GetMeshRenderer()->RemoveActor(this->Properties->xCutActor);
+            this->GetMeshRenderer()->RemoveActor(this->Properties->yCutActor);
+            this->GetMeshRenderer()->RemoveActor(this->Properties->zCutActor);
+            this->FlagDisplayMeshContours = 0;
+            this->GetMeshRenderer()->AddActor(this->Properties->MeshActor);
+            this->FlagDisplayMesh = 1;
+        }
+        switch (this->MeshRepresentation) {
+        case 0:
+            this->MeshRepresentation = 1;
+            this->pushButtonMeshRepresentation->setText("Surface");
+            this->Properties->MeshActor->GetProperty()->SetRepresentationToPoints();
+            break;
+        case 1:
+            this->MeshRepresentation = 2;
+            this->pushButtonMeshRepresentation->setText("No mesh");
+            this->Properties->MeshActor->GetProperty()->SetRepresentationToSurface();
+            break;
+        case 2:
+            this->MeshRepresentation = 3;
+            this->pushButtonMeshRepresentation->setText("Wire");
+            this->GetMeshRenderer()->RemoveActor(this->Properties->MeshActor);
+            this->FlagDisplayMesh = 0;
+            break;
+        case 3:
+            this->MeshRepresentation = 0;
+            this->pushButtonMeshRepresentation->setText("Points");
+            this->Properties->MeshActor->GetProperty()->SetRepresentationToWireframe();
+            this->GetMeshRenderer()->AddActor(this->Properties->MeshActor);
+            this->FlagDisplayMesh = 1;
+            break;
+        default:
+            break;
+        }
+        this->GetRenderWindow()->Render();
+
+    }
+
+}
+
+
+
+void OpenHeartGui::slotMeshColor()
+{
+
+    if ( this->Properties->MeshActor ) {
+        if ( this->MeshColor == 0 ) {
+            this->MeshColor = 1;
+            this->pushButtonMeshColor->setText("Color R");
+            this->Properties->MeshActor->GetProperty()->SetColor(1,1,0);
+            //this->Properties->xCutActor->GetProperty()->SetColor(1,1,0);
+            //this->Properties->yCutActor->GetProperty()->SetColor(1,1,0);
+            //this->Properties->zCutActor->GetProperty()->SetColor(1,1,0);
+        }
+        else if ( this->MeshColor == 1 ) {
+            this->MeshColor = 2;
+            this->pushButtonMeshColor->setText("Color G");
+            this->Properties->MeshActor->GetProperty()->SetColor(1,0,0);
+            //this->Properties->xCutActor->GetProperty()->SetColor(1,0,0);
+            //this->Properties->yCutActor->GetProperty()->SetColor(1,0,0);
+            //this->Properties->zCutActor->GetProperty()->SetColor(1,0,0);
+        }
+        else if ( this->MeshColor == 2 ) {
+            this->MeshColor = 3;
+            this->pushButtonMeshColor->setText("Color B");
+            this->Properties->MeshActor->GetProperty()->SetColor(0,1,0);
+            //this->Properties->xCutActor->GetProperty()->SetColor(0,1,0);
+            //this->Properties->yCutActor->GetProperty()->SetColor(0,1,0);
+            //this->Properties->zCutActor->GetProperty()->SetColor(0,1,0);
+        }
+        else if ( this->MeshColor == 3 ) {
+            this->MeshColor = 4;
+            this->pushButtonMeshColor->setText("Color W");
+            this->Properties->MeshActor->GetProperty()->SetColor(0,0,1);
+            //this->Properties->xCutActor->GetProperty()->SetColor(0,0,1);
+            //this->Properties->yCutActor->GetProperty()->SetColor(0,0,1);
+            //this->Properties->zCutActor->GetProperty()->SetColor(0,0,1);
+        }
+        else if ( this->MeshColor == 4 ) {
+            this->MeshColor = 0;
+            this->pushButtonMeshColor->setText("Color Y");
+            this->Properties->MeshActor->GetProperty()->SetColor(1,1,1);
+            //this->Properties->xCutActor->GetProperty()->SetColor(1,1,1);
+            //this->Properties->yCutActor->GetProperty()->SetColor(1,1,1);
+            //this->Properties->zCutActor->GetProperty()->SetColor(1,1,1);
+        }
+        this->GetRenderWindow()->Render();
+    }
+
+}
+
+
+void OpenHeartGui::slotMeshCutter()
+{
+
+    if ( this->Properties->MeshActor )
+    {
+        if ( this->FlagDisplayMeshContours == 1 )
+        {
+            this->FlagDisplayMeshContours = 0;
+            this->pushButtonCutter->setText("Cut on");
+            this->GetMeshRenderer()->RemoveActor(this->Properties->xCutActor);
+            this->GetMeshRenderer()->RemoveActor(this->Properties->yCutActor);
+            this->GetMeshRenderer()->RemoveActor(this->Properties->zCutActor);
+            if ( this->FlagDisplayMesh == 0 ) {
+                this->FlagDisplayMesh = 1;
+                this->GetMeshRenderer()->AddActor(this->Properties->MeshActor);
+            }
+        }
+        else
+        {
+            if ( this->FlagDisplayMesh == 1 ) {
+                this->FlagDisplayMesh = 0;
+                this->GetMeshRenderer()->RemoveActor(this->Properties->MeshActor);
+            }
+            this->FlagDisplayMeshContours = 1;
+            this->pushButtonCutter->setText("Cut off");
+            switch (this->ViewButton) {
+            case 0:
+                this->GetMeshRenderer()->AddActor(this->Properties->xCutActor);
+                this->GetMeshRenderer()->AddActor(this->Properties->yCutActor);
+                this->GetMeshRenderer()->AddActor(this->Properties->zCutActor);
+                break;
+            case 1:
+                this->GetMeshRenderer()->AddActor(this->Properties->xCutActor);
+                break;
+            case 2:
+                this->GetMeshRenderer()->AddActor(this->Properties->yCutActor);
+                break;
+            case 3:
+                this->GetMeshRenderer()->AddActor(this->Properties->zCutActor);
+                break;
+            default:
+                break;
+            }
+            /*
+            if (this->ViewButton == 0) {
+                this->GetMeshRenderer()->AddActor(this->Properties->xCutActor);
+                this->GetMeshRenderer()->AddActor(this->Properties->yCutActor);
+                this->GetMeshRenderer()->AddActor(this->Properties->zCutActor);
+            }
+            else if (this->ViewButton == 1) {
+                this->GetMeshRenderer()->AddActor(this->Properties->xCutActor);
+            }
+            else if (this->ViewButton == 2) {
+                this->GetMeshRenderer()->AddActor(this->Properties->yCutActor);
+            }
+            else if (this->ViewButton == 3) {
+                this->GetMeshRenderer()->AddActor(this->Properties->zCutActor);
+            }
+            */
+        }
+        this->GetRenderWindow()->Render();
+    }
+
+
+}
+
+
+void OpenHeartGui::ForceXZView()
+{
+
+    this->ViewButton = 2;
+    this->Properties->xIPW->SetTextureVisibility(0);
+    this->Properties->xIPW->GetPlaneProperty()->SetOpacity(0);
+    this->Properties->yIPW->SetTextureVisibility(1);
+    this->Properties->yIPW->GetPlaneProperty()->SetOpacity(1);
+    this->Properties->zIPW->SetTextureVisibility(0);
+    this->Properties->zIPW->GetPlaneProperty()->SetOpacity(0);
+
+    this->Ren->GetActiveCamera()->SetFocalPoint( this->ImageData->GetDimensions()[0]/2,
+                                                 this->ImageData->GetDimensions()[0]/2,
+                                                 this->ImageData->GetDimensions()[2]/2 );
+    this->Ren->GetActiveCamera()->SetPosition(   this->ImageData->GetDimensions()[0]/2,
+                                                 this->ImageData->GetDimensions()[1]*10,
+                                                 this->ImageData->GetDimensions()[0]/2 );
+    this->Ren->GetActiveCamera()->SetViewUp(0,0,-1);
+    this->Ren->ResetCamera();
+    this->Ren->GetActiveCamera()->Zoom(this->ZoomMain);
+    this->GetRenderWindow()->Render();
+
+}
+
+void OpenHeartGui::slotUpdateCoords(vtkObject* obj)
+{
+
+    if (this->FlagPlay == 0)
+    {
+
+        if ( (this->FlagDisplayText) && (this->Properties->TextMapperPixel) )
+        {
+
+            /// Get interactor
+            vtkRenderWindowInteractor* iren = vtkRenderWindowInteractor::SafeDownCast(obj);
+
+            // Get intensity value at the corresponding position
+            int X = iren->GetEventPosition()[0];
+            int Y = iren->GetEventPosition()[1];
+            this->Picker->Pick(X,Y,0.0,this->GetMeshRenderer());
+            double pos[3];
+            this->Picker->GetPickPosition( pos );
+            int pixel[3];
+            for ( int i=0; i<3; i++) {
+                pixel[i] = (int)( (pos[i] - this->ImageData->GetOrigin()[i]) / this->ImageData->GetSpacing()[i] + 0.5f );
+            }
+
+            if ( (pixel[0]>=0) && (pixel[0]<this->Dims[0]) &&
+                 (pixel[1]>=0) && (pixel[1]<this->Dims[1]) &&
+                 (pixel[2]>=0) && (pixel[2]<this->Dims[2]) )
+            {
+
+                /// Display Pixel coordinates
+                QString strPixel;
+                strPixel.sprintf("pixel: (%d %d %d)", pixel[0], pixel[1], pixel[2]);
+                this->Properties->TextMapperPixel->SetInput(strPixel.toStdString().c_str());
+
+                /// Display Pixel coordinates
+                QString strMM;
+                strMM.sprintf("mm:  (%.0f %.0f %.0f)", pos[0]*1000, pos[1]*1000, pos[2]*1000);
+                this->Properties->TextMapperMM->SetInput(strMM.toStdString().c_str());
+
+                QString strValue;
+                switch (this->ImageData->GetScalarType())
+                {
+                    case VTK_UNSIGNED_CHAR: {
+                        strValue.sprintf("data value: %u", static_cast<unsigned char*>(this->ImageData->GetScalarPointer(pixel))[0]);
+                        break;
+                    }
+                    case VTK_UNSIGNED_SHORT: {
+                        strValue.sprintf("data value: %u", static_cast<unsigned short*>(this->ImageData->GetScalarPointer(pixel))[0]);
+                        break;
+                    }
+                    case VTK_INT: {
+                        strValue.sprintf("data value: %d", static_cast<int*>(this->ImageData->GetScalarPointer(pixel))[0]);
+                        break;
+                    }
+                    case VTK_FLOAT: {
+                        strValue.sprintf("data value: %.1f", static_cast<float*>(this->ImageData->GetScalarPointer(pixel))[0]);
+                        break;
+                    }
+                    case VTK_DOUBLE: {
+                        strValue.sprintf("data value: %.1f", static_cast<double*>(this->ImageData->GetScalarPointer(pixel))[0]);
+                        break;
+                    }
+
+                }
+                this->Properties->TextMapperValue->SetInput(strValue.toStdString().c_str());
+
+            }
+
+            else {
+                this->Properties->TextMapperPixel->SetInput("");
+                this->Properties->TextMapperMM->SetInput("");
+                this->Properties->TextMapperValue->SetInput("");
+            }
+
+        }
+
+        else
+        {
+            if ( this->Properties->TextMapperPixel )
+            {
+                this->Properties->TextMapperPixel->SetInput("");
+                this->Properties->TextMapperMM->SetInput("");
+                this->Properties->TextMapperValue->SetInput("");
+            }
+        }
+
+        this->GetRenderWindow()->Render();
+
+    }
+
+}
+
+
+void OpenHeartGui::UpdateCoords(double *pos)
+{
+
+    if (this->FlagPlay == 0)
+    {
+
+        if ( (this->FlagDisplayText) && (this->Properties->TextMapperPixel) )
+        {
+
+            int pixel[3];
+            for ( int i=0; i<3; i++) {
+                pixel[i] = (int)( (pos[i] - this->ImageData->GetOrigin()[i]) / this->ImageData->GetSpacing()[i] + 0.5f );
+            }
+
+            if ( (pixel[0]>=0) && (pixel[0]<this->Dims[0]) &&
+                 (pixel[1]>=0) && (pixel[1]<this->Dims[1]) &&
+                 (pixel[2]>=0) && (pixel[2]<this->Dims[2]) )
+            {
+
+                /// Display Pixel coordinates
+                QString strPixel;
+                strPixel.sprintf("pixel: (%d %d %d)", pixel[0], pixel[1], pixel[2]);
+                this->Properties->TextMapperPixel->SetInput(strPixel.toStdString().c_str());
+
+                /// Display Pixel coordinates
+                QString strMM;
+                strMM.sprintf("mm:  (%.0f %.0f %.0f)", pos[0]*1000, pos[1]*1000, pos[2]*1000);
+                this->Properties->TextMapperMM->SetInput(strMM.toStdString().c_str());
+
+                QString strValue;
+                switch (this->ImageData->GetScalarType())
+                {
+                    case VTK_UNSIGNED_CHAR: {
+                        strValue.sprintf("data value: %u", static_cast<unsigned char*>(this->ImageData->GetScalarPointer(pixel))[0]);
+                        break;
+                    }
+                    case VTK_UNSIGNED_SHORT: {
+                        strValue.sprintf("data value: %u", static_cast<unsigned short*>(this->ImageData->GetScalarPointer(pixel))[0]);
+                        break;
+                    }
+                    case VTK_INT: {
+                        strValue.sprintf("data value: %d", static_cast<int*>(this->ImageData->GetScalarPointer(pixel))[0]);
+                        break;
+                    }
+                    case VTK_FLOAT: {
+                        strValue.sprintf("data value: %.1f", static_cast<float*>(this->ImageData->GetScalarPointer(pixel))[0]);
+                        break;
+                    }
+                    case VTK_DOUBLE: {
+                        strValue.sprintf("data value: %.1f", static_cast<double*>(this->ImageData->GetScalarPointer(pixel))[0]);
+                        break;
+                    }
+                }
+                this->Properties->TextMapperValue->SetInput(strValue.toStdString().c_str());
+
+            }
+
+            else {
+                this->Properties->TextMapperPixel->SetInput("");
+                this->Properties->TextMapperMM->SetInput("");
+                this->Properties->TextMapperValue->SetInput("");
+            }
+
+        }
+        else
+        {
+            if ( this->Properties->TextMapperPixel )
+            {
+                this->Properties->TextMapperPixel->SetInput("");
+                this->Properties->TextMapperMM->SetInput("");
+                this->Properties->TextMapperValue->SetInput("");
+            }
+        }
+
+        this->GetRenderWindow()->Render();
+
+    }
+
+}
+
+
+void OpenHeartGui::InitChar()
+{
+
+    this->TableChart = vtkSmartPointer<vtkTable>::New();
+    vtkSmartPointer<vtkFloatArray> arrX = vtkSmartPointer<vtkFloatArray>::New();
+    arrX->SetName("Number of frames");
+    this->TableChart->AddColumn(arrX);
+    vtkSmartPointer<vtkFloatArray> arrY = vtkSmartPointer<vtkFloatArray>::New();
+    arrY->SetName("Volume");
+    this->TableChart->AddColumn(arrY);
+
+    int numPoints = this->NumberOfVolumes;
+    this->TableChart->SetNumberOfRows(numPoints);
+    for (int i=0; i<numPoints; ++i)
+    {
+        this->TableChart->SetValue(i, 0, i);
+        this->TableChart->SetValue(i, 1, 0);
+    }
+    // Add multiple line plots, setting the colors etc
+    vtkSmartPointer<vtkChartXY> chart = vtkSmartPointer<vtkChartXY>::New();
+    ViewChart->GetScene()->AddItem(chart);
+    chart->AddPlot(vtkChart::LINE);
+    vtkPlot *line = chart->AddPlot(vtkChart::LINE);
+    line->SetInput(this->TableChart, 0, 1);
+    line->SetColor(0, 0, 255, 255);
+    line->SetWidth(3.0);
+    chart->GetAxis(vtkAxis::LEFT)->SetTitle("Volume (mL)");
+    chart->GetAxis(vtkAxis::BOTTOM)->SetTitle("Frames");
+    chart->GetAxis(vtkAxis::LEFT)->SetNotation(2);
+    chart->GetAxis(vtkAxis::LEFT)->SetPrecision(1);
+
+}
+
+
+void OpenHeartGui::InitPickers()
+{
+    this->Picker = vtkSmartPointer<vtkCellPicker>::New();
+    this->Picker->SetTolerance(0.005);
+    this->Interactor->SetPicker(this->Picker);
+    this->PickerXY = vtkSmartPointer<vtkCellPicker>::New();
+    this->PickerXY->SetTolerance(0.005);
+    this->InteractorXY->SetPicker(this->PickerXY);
+    this->PickerXZ = vtkSmartPointer<vtkCellPicker>::New();
+    this->PickerXZ->SetTolerance(0.005);
+    this->InteractorXZ->SetPicker(this->PickerXZ);
+    this->PickerYZ = vtkSmartPointer<vtkCellPicker>::New();
+    this->PickerYZ->SetTolerance(0.005);
+    this->InteractorYZ->SetPicker(this->PickerYZ);
+
+}
+
+
+
+void OpenHeartGui::InitWidgets()
+{
+    /// ImagePlane Widget
+    this->InitPlaneWidget();
+}
+
+
+void OpenHeartGui::InitOrientationAxes()
+{
+    vtkSmartPointer<vtkAxesActor> axes = vtkSmartPointer<vtkAxesActor>::New();
+    axes->GetYAxisTipProperty()->SetColor(1,1,0);
+    axes->GetYAxisShaftProperty()->SetColor(1,1,0);
+    this->OrientationWidget->SetOrientationMarker( axes );
+    this->OrientationWidget->SetInteractor( this->qVTK->GetRenderWindow()->GetInteractor() );
+    this->OrientationWidget->SetViewport( 0.8, 0.0, 1.0, 0.2 );
+    this->OrientationWidget->SetEnabled( 1 );
+    this->OrientationWidget->InteractiveOff();
+}
+
+
+void OpenHeartGui::InitProperties()
+{
+    this->Properties->lut = 0;
+    this->Properties->xIPW = 0;
+    this->Properties->yIPW = 0;
+    this->Properties->zIPW = 0;
+    this->Properties->xyIPW = 0;
+    this->Properties->xzIPW = 0;
+    this->Properties->yzIPW = 0;
+    this->Properties->TextActorPixel = 0;
+    this->Properties->TextMapperPixel = 0;
+    this->Properties->TextActorMM = 0;
+    this->Properties->TextMapperMM = 0;
+    this->Properties->TextActorValue = 0;
+    this->Properties->TextMapperValue = 0;
+    this->Properties->TextActorSlice = 0;
+    this->Properties->TextMapperSlice = 0;
+    this->Properties->TextActorNumFrame = 0;
+    this->Properties->TextMapperNumFrame = 0;
+    this->Properties->TextActorResolution = 0;
+    this->Properties->TextMapperResolution = 0;
+    this->Properties->MeshActor = 0;
+    this->Properties->xCutActor = 0;
+    this->Properties->yCutActor = 0;
+    this->Properties->zCutActor = 0;
+    this->Properties->BasalPointActor = 0;
+    this->Properties->ApexPointActor = 0;
+    this->Properties->LongAxisActor = 0;
+    this->Properties->BoundingBoxActor = 0;
+    this->Properties->position = new double[3];
+}
+
+
+void OpenHeartGui::InitPlaneWidget()
+{
+
+    /// Manage main window
+    this->Properties->xIPW = vtkSmartPointer<vtkImagePlaneWidget>::New();
+    this->Properties->yIPW = vtkSmartPointer<vtkImagePlaneWidget>::New();
+    this->Properties->zIPW = vtkSmartPointer<vtkImagePlaneWidget>::New();
+
+    this->Properties->xIPW->SetInteractor(vtkRenderWindowInteractor::New());
+    this->Properties->yIPW->SetInteractor(this->Properties->xIPW->GetInteractor());
+    this->Properties->zIPW->SetInteractor(this->Properties->xIPW->GetInteractor());
+
+    this->Properties->xIPW->DisplayTextOn();
+    this->Properties->xIPW->GetTextProperty()->SetColor(0,0,0);
+    this->Properties->xIPW->SetPicker(this->Picker);
+    this->Properties->xIPW->RestrictPlaneToVolumeOn();
+    this->Properties->xIPW->GetPlaneProperty()->SetColor(0,0,0);
+    this->Properties->xIPW->SetResliceInterpolateToNearestNeighbour();
+    this->Properties->xIPW->TextureInterpolateOff();
+
+    this->Properties->yIPW->DisplayTextOn();
+    this->Properties->yIPW->GetTextProperty()->SetColor(0,0,0);
+    this->Properties->yIPW->SetPicker(this->Picker);
+    this->Properties->yIPW->RestrictPlaneToVolumeOn();
+    this->Properties->yIPW->GetPlaneProperty()->SetColor(0,0,0);
+    this->Properties->yIPW->SetTexturePlaneProperty(this->Properties->xIPW->GetTexturePlaneProperty());
+    this->Properties->yIPW->SetResliceInterpolateToNearestNeighbour();
+    this->Properties->yIPW->TextureInterpolateOff();
+
+    this->Properties->zIPW->DisplayTextOn();
+    this->Properties->zIPW->GetTextProperty()->SetColor(0,0,0);
+    this->Properties->zIPW->SetPicker(this->Picker);
+    this->Properties->zIPW->GetPlaneProperty()->SetColor(0,0,0);
+    this->Properties->zIPW->SetTexturePlaneProperty(this->Properties->xIPW->GetTexturePlaneProperty());
+    this->Properties->zIPW->SetResliceInterpolateToNearestNeighbour();
+    this->Properties->zIPW->TextureInterpolateOff();
+
+
+    /// Manage XY window
+    this->Properties->xyIPW = vtkImagePlaneWidget::New();
+    this->Properties->xyIPW->SetInteractor(vtkRenderWindowInteractor::New());
+    this->Properties->xyIPW->DisplayTextOn();
+    this->Properties->xyIPW->GetTextProperty()->SetColor(0,0,0);
+    this->Properties->xyIPW->SetPicker(this->PickerXY);
+    this->Properties->xyIPW->RestrictPlaneToVolumeOn();
+    this->Properties->xyIPW->GetPlaneProperty()->SetColor(0,0,0);
+    this->Properties->xyIPW->SetResliceInterpolateToNearestNeighbour();
+    this->Properties->xyIPW->TextureInterpolateOff();
+
+    /// Manage XZ window
+    this->Properties->xzIPW = vtkImagePlaneWidget::New();
+    this->Properties->xzIPW->SetInteractor(vtkRenderWindowInteractor::New());
+    this->Properties->xzIPW->DisplayTextOn();
+    this->Properties->xzIPW->GetTextProperty()->SetColor(0,0,0);
+    this->Properties->xzIPW->RestrictPlaneToVolumeOn();
+    this->Properties->xzIPW->GetPlaneProperty()->SetColor(0,0,0);
+    this->Properties->xzIPW->SetResliceInterpolateToNearestNeighbour();
+    this->Properties->xzIPW->TextureInterpolateOff();
+
+    /// Manage YZ window
+    this->Properties->yzIPW = vtkImagePlaneWidget::New();
+    this->Properties->yzIPW->SetInteractor(vtkRenderWindowInteractor::New());
+    this->Properties->yzIPW->DisplayTextOn();
+    this->Properties->yzIPW->GetTextProperty()->SetColor(0,0,0);
+    this->Properties->yzIPW->RestrictPlaneToVolumeOn();
+    this->Properties->yzIPW->GetPlaneProperty()->SetColor(0,0,0);
+    this->Properties->yzIPW->SetResliceInterpolateToNearestNeighbour();
+    this->Properties->yzIPW->TextureInterpolateOff();
+
+}
+
+void OpenHeartGui::InitTexts()
+{
+
+    /// Display pixel coordinates
+    this->Properties->TextActorPixel = vtkSmartPointer<vtkActor2D>::New();
+    this->Properties->TextMapperPixel = vtkSmartPointer<vtkTextMapper>::New();
+    this->Properties->TextMapperPixel->GetTextProperty()->SetColor(0, 1, 0);
+    this->Properties->TextMapperPixel->GetTextProperty()->SetFontSize(15);
+    if ( this->FlagDisplayText ) {
+        this->Properties->TextMapperPixel->SetInput("");
+    }
+    this->Properties->TextMapperPixel->GetTextProperty()->SetJustificationToRight();
+    this->Properties->TextMapperPixel->GetTextProperty()->ShadowOff();
+    this->Properties->TextActorPixel->SetPosition(490,520);
+    this->Properties->TextActorPixel->SetMapper(this->Properties->TextMapperPixel);
+    this->GetMeshRenderer()->AddActor(this->Properties->TextActorPixel);
+
+    /// Display mm coordinates
+    this->Properties->TextActorMM = vtkSmartPointer<vtkActor2D>::New();
+    this->Properties->TextMapperMM= vtkSmartPointer<vtkTextMapper>::New();
+    this->Properties->TextMapperMM->GetTextProperty()->SetColor(0, 1, 0);
+    this->Properties->TextMapperMM->GetTextProperty()->SetFontSize(15);
+    if ( this->FlagDisplayText ) {
+        this->Properties->TextMapperMM->SetInput("");
+    }
+    this->Properties->TextMapperMM->GetTextProperty()->SetJustificationToRight();
+    this->Properties->TextMapperMM->GetTextProperty()->ShadowOff();
+    this->Properties->TextActorMM->SetPosition(490,495);
+    this->Properties->TextActorMM->SetMapper(this->Properties->TextMapperMM);
+    this->GetMeshRenderer()->AddActor(this->Properties->TextActorMM);
+
+    /// Display data value
+    this->Properties->TextActorValue = vtkSmartPointer<vtkActor2D>::New();
+    this->Properties->TextMapperValue = vtkSmartPointer<vtkTextMapper>::New();
+    this->Properties->TextMapperValue->GetTextProperty()->SetColor(0, 1, 0);
+    this->Properties->TextMapperValue->GetTextProperty()->SetFontSize(15);
+    if ( this->FlagDisplayText ) {
+        this->Properties->TextMapperValue->SetInput("");
+    }
+    this->Properties->TextMapperValue->GetTextProperty()->SetJustificationToRight();
+    this->Properties->TextMapperValue->GetTextProperty()->ShadowOff();
+    this->Properties->TextActorValue->SetPosition(490,470);
+    this->Properties->TextActorValue->SetMapper(this->Properties->TextMapperValue);
+    this->GetMeshRenderer()->AddActor(this->Properties->TextActorValue);
+
+    /// Display Slice
+    this->Properties->TextActorSlice = vtkSmartPointer<vtkActor2D>::New();
+    this->Properties->TextMapperSlice = vtkSmartPointer<vtkTextMapper>::New();
+    this->Properties->TextMapperSlice->GetTextProperty()->SetColor(0, 1, 0);
+    this->Properties->TextMapperSlice->GetTextProperty()->SetFontSize(15);
+    if ( this->FlagDisplayText ) {
+        int slice = (int)( (this->Properties->position[1] - this->ImageData->GetOrigin()[1]) / this->ImageData->GetSpacing()[1] + 0.5f );
+        //cout << this->Properties->position[1] << endl;
+        QString strSlice;
+        strSlice.sprintf("Slice: %d",slice);
+        this->Properties->TextMapperSlice->SetInput(strSlice.toStdString().c_str());
+    }
+    this->Properties->TextMapperSlice->GetTextProperty()->SetJustificationToLeft();
+    this->Properties->TextMapperSlice->GetTextProperty()->ShadowOff();
+    this->Properties->TextActorSlice->SetPosition(10,520);
+    this->Properties->TextActorSlice->SetMapper(this->Properties->TextMapperSlice);
+    this->GetMeshRenderer()->AddActor(this->Properties->TextActorSlice);
+
+    /// Display frame number
+    this->Properties->TextActorNumFrame = vtkSmartPointer<vtkActor2D>::New();
+    this->Properties->TextMapperNumFrame = vtkSmartPointer<vtkTextMapper>::New();
+    this->Properties->TextMapperNumFrame->GetTextProperty()->SetColor(0, 1, 0);
+    this->Properties->TextMapperNumFrame->GetTextProperty()->SetFontSize(15);
+    if ( this->FlagDisplayText ) {
+        QString str;
+        str.sprintf("Frame: %d",this->CurrentFrame);
+        this->Properties->TextMapperNumFrame->SetInput(str.toStdString().c_str());
+    }
+    this->Properties->TextMapperNumFrame->GetTextProperty()->SetJustificationToLeft();
+    this->Properties->TextMapperNumFrame->GetTextProperty()->ShadowOff();
+    this->Properties->TextActorNumFrame->SetPosition(10, 45);
+    this->Properties->TextActorNumFrame->SetMapper(this->Properties->TextMapperNumFrame);
+    this->GetMeshRenderer()->AddActor(this->Properties->TextActorNumFrame);
+
+    /// Display resolution value
+    this->Properties->TextActorResolution = vtkSmartPointer<vtkActor2D>::New();
+    this->Properties->TextMapperResolution = vtkSmartPointer<vtkTextMapper>::New();
+    this->Properties->TextMapperResolution->GetTextProperty()->SetColor(0, 1, 0);
+    this->Properties->TextMapperResolution->GetTextProperty()->SetFontSize(15);
+    if ( this->FlagDisplayText ) {
+        QString str;
+        str.sprintf("Resolution: %.2f x %.2f x %.2f mm",this->ImageData->GetSpacing()[0]*1000,this->ImageData->GetSpacing()[1]*1000,this->ImageData->GetSpacing()[2]*1000);
+        this->Properties->TextMapperResolution->SetInput(str.toStdString().c_str());
+    }
+    this->Properties->TextMapperResolution->GetTextProperty()->SetJustificationToLeft();
+    this->Properties->TextMapperResolution->GetTextProperty()->ShadowOff();
+    this->Properties->TextActorResolution->SetPosition(10, 20);
+    this->Properties->TextActorResolution->SetMapper(this->Properties->TextMapperResolution);
+    this->GetMeshRenderer()->AddActor(this->Properties->TextActorResolution);
+
+}
+
+
+void OpenHeartGui::SetCustomInteractorStyle()
+{
+
+    /// customize main interactor
+    vtkSmartPointer<vtkMyInteractorStyleTrackballCameraOpenHeart> CustomInteractorStyle =
+            vtkSmartPointer<vtkMyInteractorStyleTrackballCameraOpenHeart>::New();
+    CustomInteractorStyle->SetOpenHeartGui( this );
+    this->Interactor->SetInteractorStyle(CustomInteractorStyle);
+
+    /// customize XY interactor
+    vtkSmartPointer<vtkMyInteractorStyleTrackballCameraOpenHeartXY> CustomInteractorStyleXY =
+            vtkSmartPointer<vtkMyInteractorStyleTrackballCameraOpenHeartXY>::New();
+    CustomInteractorStyleXY->SetOpenHeartGui( this );
+    this->InteractorXY->SetInteractorStyle(CustomInteractorStyleXY);
+
+    /// customize XZ interactor
+    vtkSmartPointer<vtkMyInteractorStyleTrackballCameraOpenHeartXZ> CustomInteractorStyleXZ =
+            vtkSmartPointer<vtkMyInteractorStyleTrackballCameraOpenHeartXZ>::New();
+    CustomInteractorStyleXZ->SetOpenHeartGui( this );
+    this->InteractorXZ->SetInteractorStyle(CustomInteractorStyleXZ);
+
+    /// customize YZ interactor
+    vtkSmartPointer<vtkMyInteractorStyleTrackballCameraOpenHeartYZ> CustomInteractorStyleYZ =
+            vtkSmartPointer<vtkMyInteractorStyleTrackballCameraOpenHeartYZ>::New();
+    CustomInteractorStyleYZ->SetOpenHeartGui( this );
+    this->InteractorYZ->SetInteractorStyle(CustomInteractorStyleYZ);
+
+}
+
+
+void OpenHeartGui::CreateFromSequenceDataPointer(std::string inputFilename)
+{
+
+    /// Read 3D volume
+    QString str;
+    for (int i=1; i<=this->NumberOfVolumes; i++)
+    {
+        if (i<10)
+            str.sprintf("%s0%d.mhd",inputFilename.c_str(),i);
+        else
+            str.sprintf("%s%d.mhd",inputFilename.c_str(),i);
+        vtkMetaImageReader *reader = vtkMetaImageReader::New();
+        reader->SetFileName(str.toStdString().c_str());
+        reader->Update();
+        this->StackVolume.push_back(reader->GetOutput());
+    }
+
+    /// Initialize attibute related to stack of volumes
+    this->itStackVolume = this->StackVolume.begin();
+    this->CurrentFrame = 0;
+    this->ImageData = (*this->itStackVolume);
+    double center[3];
+    for ( unsigned int k=0; k<3; k++ ) {
+        this->Dims[k] = this->ImageData->GetDimensions()[k];
+        center[k] = ((this->ImageData->GetDimensions()[k])*(this->ImageData->GetSpacing()[k]))/2;
+    }
+
+    /// Allocate lookuptable
+    double range[2];
+    this->ImageData->GetScalarRange(range);
+    int NumberOfColors = vtkMath::Round(range[1]-range[0]);
+    NumberOfColors++;
+    this->Properties->lut = vtkSmartPointer<vtkLookupTable>::New();
+    this->Properties->lut->SetNumberOfColors(NumberOfColors);
+    this->Properties->lut->SetValueRange(range[0]/NumberOfColors,range[1]/NumberOfColors);
+    this->Properties->lut->SetRampToLinear();
+    this->Properties->lut->SetSaturationRange(0.,0.);
+    this->Properties->lut->SetHueRange(0.,0.);
+
+    /// Manage main window
+    this->Properties->xIPW->SetCurrentRenderer(this->GetMainRenderer());
+    this->Properties->yIPW->SetCurrentRenderer(this->GetMainRenderer());
+    this->Properties->zIPW->SetCurrentRenderer(this->GetMainRenderer());
+
+    /// The 3 image plane widgets are used.
+    this->Properties->xIPW->SetInput(this->ImageData);
+    this->Properties->yIPW->SetInput(this->ImageData);
+    this->Properties->zIPW->SetInput(this->ImageData);
+
+    this->Properties->xIPW->SetPlaneOrientationToXAxes();
+    this->Properties->yIPW->SetPlaneOrientationToYAxes();
+    this->Properties->zIPW->SetPlaneOrientationToZAxes();
+
+    this->Properties->xIPW->SetSlicePosition(center[0]);
+    this->Properties->yIPW->SetSlicePosition(center[1]);
+    this->Properties->zIPW->SetSlicePosition(center[2]);
+
+    this->Properties->xIPW->SetLookupTable(this->Properties->lut);
+    this->Properties->yIPW->SetLookupTable(this->Properties->lut);
+    this->Properties->zIPW->SetLookupTable(this->Properties->lut);
+
+    this->Properties->position[0] = center[0];
+    this->Properties->position[1] = center[1];
+    this->Properties->position[2] = center[2];
+
+    this->Properties->xIPW->On();
+    this->Properties->yIPW->On();
+    this->Properties->zIPW->On();
+
+    /// Manage XY window
+    this->Properties->xyIPW->SetCurrentRenderer(this->GetXYRenderer());
+    this->Properties->xyIPW->SetInput(this->ImageData);
+    this->Properties->xyIPW->SetPlaneOrientationToZAxes();
+    this->Properties->xyIPW->SetSlicePosition(center[2]);
+    this->Properties->xyIPW->SetLookupTable(this->Properties->lut);
+    this->Properties->xyIPW->On();
+    this->RenXY->GetActiveCamera()->SetFocalPoint( this->ImageData->GetDimensions()[0]/2,
+                                                   this->ImageData->GetDimensions()[1]/2,
+                                                   this->ImageData->GetDimensions()[2]/2 );
+    this->RenXY->GetActiveCamera()->SetPosition( this->ImageData->GetDimensions()[0]/2,
+                                                 this->ImageData->GetDimensions()[1]/2,
+                                                 this->ImageData->GetDimensions()[2]*10 );
+    this->RenXY->GetActiveCamera()->SetViewUp(0,0,-1);
+    this->RenXY->ResetCamera();
+    this->RenXY->GetActiveCamera()->Zoom(this->ZoomLabel);
+    this->GetRenderWindowXY()->Render();
+
+    /// Manage XZ window
+    this->Properties->xzIPW->SetCurrentRenderer(this->GetXZRenderer());
+    this->Properties->xzIPW->SetInput(this->ImageData);
+    this->Properties->xzIPW->SetPlaneOrientationToYAxes();
+    this->Properties->xzIPW->SetSlicePosition(center[1]);
+    this->Properties->xzIPW->SetLookupTable(this->Properties->lut);
+    this->Properties->xzIPW->On();
+    this->RenXZ->GetActiveCamera()->SetFocalPoint( this->ImageData->GetDimensions()[0]/2,
+                                                   this->ImageData->GetDimensions()[1]/2,
+                                                   this->ImageData->GetDimensions()[2]/2 );
+    this->RenXZ->GetActiveCamera()->SetPosition( this->ImageData->GetDimensions()[0]/2,
+                                                 this->ImageData->GetDimensions()[1]*10,
+                                                 this->ImageData->GetDimensions()[2]/2 );
+    this->RenXZ->GetActiveCamera()->SetViewUp(0,0,-1);
+
+    this->RenXZ->ResetCamera();
+    this->RenXZ->GetActiveCamera()->Zoom(this->ZoomLabel);
+
+
+    /// Manage YZ window
+    this->Properties->yzIPW->SetCurrentRenderer(this->GetYZRenderer());
+    this->Properties->yzIPW->SetInput(this->ImageData);
+    this->Properties->yzIPW->SetPlaneOrientationToXAxes();
+    this->Properties->yzIPW->SetSlicePosition(center[0]);
+    this->Properties->yzIPW->SetLookupTable(this->Properties->lut);
+    this->Properties->yzIPW->On();
+    this->RenYZ->GetActiveCamera()->SetFocalPoint( this->ImageData->GetDimensions()[0]/2,
+                                                   this->ImageData->GetDimensions()[1]/2,
+                                                   this->ImageData->GetDimensions()[2]/2 );
+    this->RenYZ->GetActiveCamera()->SetPosition( this->ImageData->GetDimensions()[0]*10,
+                                                 this->ImageData->GetDimensions()[1]/2,
+                                                 this->ImageData->GetDimensions()[2]/2 );
+    this->RenYZ->GetActiveCamera()->SetViewUp(0,0,-1);
+    this->RenYZ->ResetCamera();
+    this->RenYZ->GetActiveCamera()->Zoom(this->ZoomLabel);
+
+    /// Manage Bounding box around the volume for the 3D display
+    vtkSmartPointer<vtkOutlineFilter> outlineData = vtkSmartPointer<vtkOutlineFilter>::New();
+    outlineData->SetInput(this->ImageData);
+    vtkSmartPointer<vtkPolyDataMapper> mapOutline = vtkSmartPointer<vtkPolyDataMapper>::New();
+    mapOutline->SetInput(outlineData->GetOutput());
+    this->Properties->BoundingBoxActor = vtkSmartPointer<vtkActor>::New();
+    this->Properties->BoundingBoxActor->SetMapper(mapOutline);
+
+    /// Refresh YZ viewer
+    this->GetRenderWindowYZ()->Render();
+
+}
+
+
+void OpenHeartGui::InterpolationManagement()
+{
+
+    if ( this->FlagReslice == 0 )
+    {
+        if ( this->FlagInterpolation == 0 )
+        {
+            this->FlagInterpolation = 1;
+            this->Properties->xIPW->TextureInterpolateOn();
+            this->Properties->yIPW->TextureInterpolateOn();
+            this->Properties->zIPW->TextureInterpolateOn();
+        }
+        else
+        {
+            this->FlagInterpolation = 0;
+            this->Properties->xIPW->TextureInterpolateOff();
+            this->Properties->yIPW->TextureInterpolateOff();
+            this->Properties->zIPW->TextureInterpolateOff();
+        }
+
+        /// Force to display the change on the XYZ planes
+        this->Properties->xIPW->SetInput(this->ImageData);
+        this->Properties->yIPW->SetInput(this->ImageData);
+        this->Properties->zIPW->SetInput(this->ImageData);
+        this->Properties->xIPW->SetSlicePosition(this->Properties->position[0]);
+        this->Properties->yIPW->SetSlicePosition(this->Properties->position[1]);
+        this->Properties->zIPW->SetSlicePosition(this->Properties->position[2]);
+
+        this->GetRenderWindow()->Render();
+    }
+
+}
+
+
+void OpenHeartGui::UpdateForwardViewers()
+{
+
+    if ( this->ImageData )
+    {
+
+        ++(this->itStackVolume);
+        ++(this->CurrentFrame);
+        if (this->Properties->MeshActor) {
+            ++(this->itStackMesh);
+            ++(this->Properties->itStackMapperList);
+            ++(this->Properties->itStackMapXCutter);
+            ++(this->Properties->itStackMapYCutter);
+            ++(this->Properties->itStackMapZCutter);
+        }
+
+        if ( this->itStackVolume == this->StackVolume.end() ) {
+            this->itStackVolume = this->StackVolume.begin();
+            this->CurrentFrame = 0;
+            if (this->Properties->MeshActor) {
+                this->itStackMesh = this->StackMesh.begin();
+                this->Properties->itStackMapperList = this->Properties->StackMapperList.begin();
+                this->Properties->itStackMapXCutter = this->Properties->StackMapXCutter.begin();
+                this->Properties->itStackMapYCutter = this->Properties->StackMapYCutter.begin();
+                this->Properties->itStackMapZCutter = this->Properties->StackMapZCutter.begin();
+            }
+        }
+
+        /// Update image data pointer
+        this->ImageData = (*this->itStackVolume);
+
+        if ( this->FlagReslice == 0 )
+        {
+
+            /// Update the 3 planes and the corresponding 2D plane windows
+            this->Properties->xIPW->SetInput(this->ImageData);
+            this->Properties->yIPW->SetInput(this->ImageData);
+            this->Properties->zIPW->SetInput(this->ImageData);
+            this->Properties->xyIPW->SetInput(this->ImageData);
+            this->Properties->xzIPW->SetInput(this->ImageData);
+            this->Properties->yzIPW->SetInput(this->ImageData);
+            this->Properties->xIPW->SetSlicePosition(this->Properties->position[0]);
+            this->Properties->yIPW->SetSlicePosition(this->Properties->position[1]);
+            this->Properties->zIPW->SetSlicePosition(this->Properties->position[2]);
+            this->Properties->xyIPW->SetSlicePosition(this->Properties->position[2]);
+            this->Properties->xzIPW->SetSlicePosition(this->Properties->position[1]);
+            this->Properties->yzIPW->SetSlicePosition(this->Properties->position[0]);
+
+        }
+        else
+        {
+
+            /// Update X plan
+            double pto[3];
+            double pt1[3];
+            double pt2[3];
+            for (int i=0;i<3; i++) {
+                pto[i] = this->Properties->xIPW->GetOrigin()[i];
+                pt1[i] = this->Properties->xIPW->GetPoint1()[i];
+                pt2[i] = this->Properties->xIPW->GetPoint2()[i];
+            }
+            double position = this->Properties->xIPW->GetSlicePosition();
+            this->Properties->xIPW->SetInput(this->ImageData);
+            this->Properties->yzIPW->SetInput(this->ImageData);
+            this->Properties->xIPW->SetOrigin(pto);
+            this->Properties->xIPW->SetPoint1(pt1);
+            this->Properties->xIPW->SetPoint2(pt2);
+            this->Properties->xIPW->UpdatePlacement();
+            this->Properties->yzIPW->SetOrigin(pto);
+            this->Properties->yzIPW->SetPoint1(pt1);
+            this->Properties->yzIPW->SetPoint2(pt2);
+            this->Properties->yzIPW->UpdatePlacement();
+            this->Properties->xIPW->SetSlicePosition(position);
+            this->Properties->yzIPW->SetSlicePosition(position);
+
+            /// Update Y plan
+            for (int i=0;i<3; i++) {
+                pto[i] = this->Properties->yIPW->GetOrigin()[i];
+                pt1[i] = this->Properties->yIPW->GetPoint1()[i];
+                pt2[i] = this->Properties->yIPW->GetPoint2()[i];
+            }
+            position = this->Properties->yIPW->GetSlicePosition();
+            this->Properties->yIPW->SetInput(this->ImageData);
+            this->Properties->xzIPW->SetInput(this->ImageData);
+            this->Properties->yIPW->SetOrigin(pto);
+            this->Properties->yIPW->SetPoint1(pt1);
+            this->Properties->yIPW->SetPoint2(pt2);
+            this->Properties->yIPW->UpdatePlacement();
+            this->Properties->xzIPW->SetOrigin(pto);
+            this->Properties->xzIPW->SetPoint1(pt1);
+            this->Properties->xzIPW->SetPoint2(pt2);
+            this->Properties->xzIPW->UpdatePlacement();
+            this->Properties->yIPW->SetSlicePosition(position);
+            this->Properties->xzIPW->SetSlicePosition(position);
+
+            /// Update Z plan
+            for (int i=0;i<3; i++) {
+                pto[i] = this->Properties->zIPW->GetOrigin()[i];
+                pt1[i] = this->Properties->zIPW->GetPoint1()[i];
+                pt2[i] = this->Properties->zIPW->GetPoint2()[i];
+            }
+            position = this->Properties->zIPW->GetSlicePosition();
+            this->Properties->zIPW->SetInput(this->ImageData);
+            this->Properties->xyIPW->SetInput(this->ImageData);
+            this->Properties->zIPW->SetOrigin(pto);
+            this->Properties->zIPW->SetPoint1(pt1);
+            this->Properties->zIPW->SetPoint2(pt2);
+            this->Properties->zIPW->UpdatePlacement();
+            this->Properties->xyIPW->SetOrigin(pto);
+            this->Properties->xyIPW->SetPoint1(pt1);
+            this->Properties->xyIPW->SetPoint2(pt2);
+            this->Properties->xyIPW->UpdatePlacement();
+            this->Properties->zIPW->SetSlicePosition(position);
+            this->Properties->xyIPW->SetSlicePosition(position);
+
+        }
+
+        /// Update the segmented mesh if needed
+        if (this->Properties->MeshActor)
+        {
+            this->Properties->MeshActor->SetMapper(*this->Properties->itStackMapperList);
+            vtkPolyDataMapper* cutMapperX = vtkPolyDataMapper::New();
+            cutMapperX->SetInputConnection((*this->Properties->itStackMapXCutter)->GetOutputPort());
+            this->Properties->xCutActor->SetMapper(cutMapperX);
+            vtkPolyDataMapper* cutMapperY = vtkPolyDataMapper::New();
+            cutMapperY->SetInputConnection((*this->Properties->itStackMapYCutter)->GetOutputPort());
+            this->Properties->yCutActor->SetMapper(cutMapperY);
+            vtkPolyDataMapper* cutMapperZ = vtkPolyDataMapper::New();
+            cutMapperZ->SetInputConnection((*this->Properties->itStackMapZCutter)->GetOutputPort());
+            this->Properties->zCutActor->SetMapper(cutMapperZ);
+        }
+
+        /// Update viewers
+        this->GetRenderWindow()->Render();
+        this->GetXYRenderer()->ResetCameraClippingRange();
+        this->GetRenderWindowXY()->Render();
+        this->GetXZRenderer()->ResetCameraClippingRange();
+        this->GetRenderWindowXZ()->Render();
+        this->GetYZRenderer()->ResetCameraClippingRange();
+        this->GetRenderWindowYZ()->Render();
+
+    }
+
+}
+
+
+void OpenHeartGui::UpdateBackwardViewers()
+{
+
+    if ( this->ImageData )
+    {
+
+        if ( this->itStackVolume == this->StackVolume.begin() )
+        {
+            this->itStackVolume = this->StackVolume.end();
+            this->CurrentFrame = this->NumberOfVolumes;
+            if (this->Properties->MeshActor) {
+                this->itStackMesh = this->StackMesh.end();
+                this->Properties->itStackMapperList = this->Properties->StackMapperList.end();
+                this->Properties->itStackMapXCutter = this->Properties->StackMapXCutter.end();
+                this->Properties->itStackMapYCutter = this->Properties->StackMapYCutter.end();
+                this->Properties->itStackMapZCutter = this->Properties->StackMapZCutter.end();
+            }
+        }
+
+        --(this->itStackVolume);
+        --(this->CurrentFrame);
+        if (this->Properties->MeshActor) {
+            --(this->itStackMesh);
+            --(this->Properties->itStackMapperList);
+            --(this->Properties->itStackMapXCutter);
+            --(this->Properties->itStackMapYCutter);
+            --(this->Properties->itStackMapZCutter);
+        }
+
+        /// Update image data pointer
+        this->ImageData = (*this->itStackVolume);
+
+        if ( this->FlagReslice == 0 )
+        {
+
+            /// Update the 3 planes
+            this->Properties->xIPW->SetInput(this->ImageData);
+            this->Properties->yIPW->SetInput(this->ImageData);
+            this->Properties->zIPW->SetInput(this->ImageData);
+            this->Properties->xyIPW->SetInput(this->ImageData);
+            this->Properties->xzIPW->SetInput(this->ImageData);
+            this->Properties->yzIPW->SetInput(this->ImageData);
+            this->Properties->xIPW->SetSlicePosition(this->Properties->position[0]);
+            this->Properties->yIPW->SetSlicePosition(this->Properties->position[1]);
+            this->Properties->zIPW->SetSlicePosition(this->Properties->position[2]);
+            this->Properties->xyIPW->SetSlicePosition(this->Properties->position[2]);
+            this->Properties->xzIPW->SetSlicePosition(this->Properties->position[1]);
+            this->Properties->yzIPW->SetSlicePosition(this->Properties->position[0]);
+
+        }
+        else
+        {
+
+            /// Update X plan
+            double pto[3];
+            double pt1[3];
+            double pt2[3];
+            for (int i=0;i<3; i++) {
+                pto[i] = this->Properties->xIPW->GetOrigin()[i];
+                pt1[i] = this->Properties->xIPW->GetPoint1()[i];
+                pt2[i] = this->Properties->xIPW->GetPoint2()[i];
+            }
+            double position = this->Properties->xIPW->GetSlicePosition();
+            this->Properties->xIPW->SetInput(this->ImageData);
+            this->Properties->yzIPW->SetInput(this->ImageData);
+            this->Properties->xIPW->SetOrigin(pto);
+            this->Properties->xIPW->SetPoint1(pt1);
+            this->Properties->xIPW->SetPoint2(pt2);
+            this->Properties->xIPW->UpdatePlacement();
+            this->Properties->yzIPW->SetOrigin(pto);
+            this->Properties->yzIPW->SetPoint1(pt1);
+            this->Properties->yzIPW->SetPoint2(pt2);
+            this->Properties->yzIPW->UpdatePlacement();
+            this->Properties->xIPW->SetSlicePosition(position);
+            this->Properties->yzIPW->SetSlicePosition(position);
+
+            /// Update Y plan
+            for (int i=0;i<3; i++) {
+                pto[i] = this->Properties->yIPW->GetOrigin()[i];
+                pt1[i] = this->Properties->yIPW->GetPoint1()[i];
+                pt2[i] = this->Properties->yIPW->GetPoint2()[i];
+            }
+            position = this->Properties->yIPW->GetSlicePosition();
+            this->Properties->yIPW->SetInput(this->ImageData);
+            this->Properties->xzIPW->SetInput(this->ImageData);
+            this->Properties->yIPW->SetOrigin(pto);
+            this->Properties->yIPW->SetPoint1(pt1);
+            this->Properties->yIPW->SetPoint2(pt2);
+            this->Properties->yIPW->UpdatePlacement();
+            this->Properties->xzIPW->SetOrigin(pto);
+            this->Properties->xzIPW->SetPoint1(pt1);
+            this->Properties->xzIPW->SetPoint2(pt2);
+            this->Properties->xzIPW->UpdatePlacement();
+            this->Properties->yIPW->SetSlicePosition(position);
+            this->Properties->xzIPW->SetSlicePosition(position);
+
+            /// Update Z plan
+            for (int i=0;i<3; i++) {
+                pto[i] = this->Properties->zIPW->GetOrigin()[i];
+                pt1[i] = this->Properties->zIPW->GetPoint1()[i];
+                pt2[i] = this->Properties->zIPW->GetPoint2()[i];
+            }
+            position = this->Properties->zIPW->GetSlicePosition();
+            this->Properties->zIPW->SetInput(this->ImageData);
+            this->Properties->xyIPW->SetInput(this->ImageData);
+            this->Properties->zIPW->SetOrigin(pto);
+            this->Properties->zIPW->SetPoint1(pt1);
+            this->Properties->zIPW->SetPoint2(pt2);
+            this->Properties->zIPW->UpdatePlacement();
+            this->Properties->xyIPW->SetOrigin(pto);
+            this->Properties->xyIPW->SetPoint1(pt1);
+            this->Properties->xyIPW->SetPoint2(pt2);
+            this->Properties->xyIPW->UpdatePlacement();
+            this->Properties->zIPW->SetSlicePosition(position);
+            this->Properties->xyIPW->SetSlicePosition(position);
+
+        }
+
+        /// Update the segmented mesh if needed
+        if (this->Properties->MeshActor)
+        {
+            this->Properties->MeshActor->SetMapper(*this->Properties->itStackMapperList);
+            vtkPolyDataMapper* cutMapperX = vtkPolyDataMapper::New();
+            cutMapperX->SetInputConnection((*this->Properties->itStackMapXCutter)->GetOutputPort());
+            this->Properties->xCutActor->SetMapper(cutMapperX);
+            vtkPolyDataMapper* cutMapperY = vtkPolyDataMapper::New();
+            cutMapperY->SetInputConnection((*this->Properties->itStackMapYCutter)->GetOutputPort());
+            this->Properties->yCutActor->SetMapper(cutMapperY);
+            vtkPolyDataMapper* cutMapperZ = vtkPolyDataMapper::New();
+            cutMapperZ->SetInputConnection((*this->Properties->itStackMapZCutter)->GetOutputPort());
+            this->Properties->zCutActor->SetMapper(cutMapperZ);
+        }
+
+        this->GetRenderWindow()->Render();
+        this->GetRenderWindowXY()->Render();
+        this->GetRenderWindowXZ()->Render();
+        this->GetRenderWindowYZ()->Render();
+
+    }
+
+}
+
+
+void OpenHeartGui::slotMeshAlpha(int val)
+{
+
+    if ( this->Properties->MeshActor )
+    {
+        this->Properties->MeshActor->GetProperty()->SetOpacity(val/100.);
+        this->GetRenderWindow()->Render();
+    }
+
+}
+
+
+void OpenHeartGui::slotRefreshViewer(int val)
+{
+
+    /// Loop cases
+    while ( val != this->CurrentFrame )
+    {
+        if ( (this->FlagLoopEndToBegin == 0) && (this->FlagLoopBeginToEnd == 0) )
+        {
+            /// Normal transition
+            if ( ( val-this->CurrentFrame ) > 0 )
+                UpdateForwardViewers();
+            else
+                UpdateBackwardViewers();
+        }
+        else
+        {
+            /// Loop end to begin
+            if ( this->FlagLoopEndToBegin == 1 ) {
+                this->FlagLoopEndToBegin = 0;
+                UpdateForwardViewers();
+            }
+            /// Loop begin to end
+            if ( this->FlagLoopBeginToEnd == 1 ) {
+                this->FlagLoopBeginToEnd = 0;
+                UpdateBackwardViewers();
+            }
+        }
+    }
+
+    /// Update Frame text
+    if ( (this->FlagDisplayText) && (this->Properties->TextMapperNumFrame) )
+    {
+        QString str;
+        str.sprintf("Frame: %d",this->CurrentFrame);
+        this->Properties->TextMapperNumFrame->SetInput(str.toStdString().c_str());
+        this->GetRenderWindow()->Render();
+    }
+
+}
+
+
+void OpenHeartGui::slotTabChange(int val)
+{
+
+    if (val==3)
+    {
+
+        if ( this->Properties->ApexPointActor != 0 ) {
+            this->GetMainRenderer()->AddActor(this->Properties->ApexPointActor);
+            this->FlagDisplayApexPoint = 1;
+        }
+        if ( this->Properties->BasalPointActor != 0 ) {
+            this->GetMainRenderer()->AddActor(this->Properties->BasalPointActor);
+            this->FlagDisplayBasalPoint = 1;
+        }
+        if ( this->Properties->LongAxisActor != 0 ) {
+            this->GetMainRenderer()->AddActor(this->Properties->LongAxisActor);
+            this->FlagDisplayLongAxis = 1;
+        }
+
+        this->slot3DView();
+    }
+    else
+    {
+
+        if ( this->FlagDisplayApexPoint == 1 ) {
+            this->GetMainRenderer()->RemoveActor(this->Properties->ApexPointActor);
+            this->FlagDisplayApexPoint = 0;
+            this->GetRenderWindow()->Render();
+        }
+        if ( this->FlagDisplayBasalPoint == 1 ) {
+            this->GetMainRenderer()->RemoveActor(this->Properties->BasalPointActor);
+            this->FlagDisplayBasalPoint = 0;
+            this->GetRenderWindow()->Render();
+        }
+        if ( this->FlagDisplayLongAxis == 1 ) {
+            this->GetMainRenderer()->RemoveActor(this->Properties->LongAxisActor);
+            this->FlagDisplayLongAxis = 0;
+            this->GetRenderWindow()->Render();
+        }
+
+    }
+
+}
+
+
+
+void OpenHeartGui::slotPlay()
+{
+    if ( this->FlagPlay == 0 ) {
+        this->FlagPlay = 1;
+        this->pushButtonPlay->setText("Pause");
+        this->scrollBar->setEnabled(false);
+        this->Timer->start(40);
+    }
+    else {
+        this->FlagPlay = 0;
+        this->Timer->stop();
+        this->pushButtonPlay->setText("Play");
+        this->scrollBar->setEnabled(true);
+    }
+}
+
+
+void OpenHeartGui::slotTimerEvent()
+{
+
+    int val = this->CurrentFrame;
+    if ( val < (this->NumberOfVolumes-1) )
+        this->scrollBar->setSliderPosition(val+1);
+    else {
+        this->FlagLoopEndToBegin = 1;
+        this->scrollBar->setSliderPosition(0);
+    }
+
+}
+
+
+void OpenHeartGui::slotBasalPoint()
+{
+
+    if ( this->Properties->BasalPointActor == 0 ) {
+        this->Properties->BasalPointActor = vtkSmartPointer<vtkActor>::New();
+    }
+    else {
+        this->GetMainRenderer()->RemoveActor(this->Properties->BasalPointActor);
+    }
+
+    vtkSmartPointer<vtkSphereSource> sphereSource = vtkSmartPointer<vtkSphereSource>::New();
+    sphereSource->SetCenter(this->Properties->position[0],
+                            this->Properties->position[1],
+                            this->Properties->position[2]);
+    sphereSource->SetRadius(5.0*this->ImageData->GetSpacing()[0]);
+    sphereSource->Update();
+
+    for (int i=0; i<3; i++)
+        this->BasalPoint[i] = this->Properties->position[i];
+
+    vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
+    mapper->SetInput(sphereSource->GetOutput());
+
+    this->Properties->BasalPointActor->SetMapper(mapper);
+    this->Properties->BasalPointActor->GetProperty()->SetColor(0,1,0);
+
+    this->GetMainRenderer()->AddActor(this->Properties->BasalPointActor);
+    this->FlagDisplayBasalPoint = 1;
+
+    if ( this->Properties->ApexPointActor != 0 )
+    {
+        this->CreateLongAxisActor();
+        this->FlagLongAxis = 1;
+        this->GetMainRenderer()->AddActor(this->Properties->LongAxisActor);
+        this->FlagDisplayLongAxis = 1;
+        this->pushButtonReslice->setEnabled(true);
+    }
+
+    this->GetRenderWindow()->Render();
+
+}
+
+
+void OpenHeartGui::slotApexPoint()
+{
+
+    if ( this->Properties->ApexPointActor == 0 ) {
+        this->Properties->ApexPointActor = vtkSmartPointer<vtkActor>::New();
+    }
+    else {
+        this->GetMainRenderer()->RemoveActor(this->Properties->ApexPointActor);
+    }
+
+    vtkSmartPointer<vtkSphereSource> sphereSource = vtkSmartPointer<vtkSphereSource>::New();
+    sphereSource->SetCenter(this->Properties->position[0],
+                            this->Properties->position[1],
+                            this->Properties->position[2]);
+    sphereSource->SetRadius(5.0*this->ImageData->GetSpacing()[0]);
+    sphereSource->Update();
+
+    for (int i=0; i<3; i++)
+        this->ApexPoint[i] = this->Properties->position[i];
+
+    vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
+    mapper->SetInput(sphereSource->GetOutput());
+
+    this->Properties->ApexPointActor->SetMapper(mapper);
+    this->Properties->ApexPointActor->GetProperty()->SetColor(0,1,0);
+
+    this->GetMainRenderer()->AddActor(this->Properties->ApexPointActor);
+    this->FlagDisplayApexPoint = 1;
+
+    if ( this->Properties->BasalPointActor != 0 )
+    {
+        this->CreateLongAxisActor();
+        this->FlagLongAxis = 1;
+        this->GetMainRenderer()->AddActor(this->Properties->LongAxisActor);
+        this->FlagDisplayLongAxis = 1;
+        this->pushButtonReslice->setEnabled(true);
+    }
+
+    this->GetRenderWindow()->Render();
+
+}
+
+
+void OpenHeartGui::CreateLongAxisActor()
+{
+
+    if ( this->Properties->LongAxisActor == 0 ) {
+        this->Properties->LongAxisActor = vtkSmartPointer<vtkActor>::New();
+    }
+    else {
+        this->GetMainRenderer()->RemoveActor(this->Properties->LongAxisActor);
+    }
+
+    vtkSmartPointer<vtkLineSource> lineSource = vtkSmartPointer<vtkLineSource>::New();
+    lineSource->SetPoint1(this->BasalPoint);
+    lineSource->SetPoint2(this->ApexPoint);
+    lineSource->Update();
+
+    vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
+    mapper->SetInputConnection(lineSource->GetOutputPort());
+
+    this->Properties->LongAxisActor->SetMapper(mapper);
+    this->Properties->LongAxisActor->GetProperty()->SetLineWidth(2);
+    this->Properties->LongAxisActor->GetProperty()->SetColor(0,1,0);
+
+}
+
+
+void OpenHeartGui::DisplayMainAxisManagement()
+{
+
+}
+
+
+void OpenHeartGui::DisplayMeshManagement()
+{
+
+    if ( this->Properties->MeshActor != 0 )
+    {
+
+        if ( this->FlagDisplayMesh == 0 )
+        {
+            this->GetMeshRenderer()->AddActor(this->Properties->MeshActor);
+            this->FlagDisplayMesh = 1;
+        }
+        else
+        {
+            this->GetMeshRenderer()->RemoveActor(this->Properties->MeshActor);
+            this->FlagDisplayMesh = 0;
+        }
+        this->GetRenderWindow()->Render();
+
+    }
+
+}
+
+void OpenHeartGui::DisplayModeManagement()
+{
+
+    if ( this->FlagDisplayText == 0 )
+    {
+
+        this->FlagDisplayText = 1;
+        if ( this->Properties->TextMapperPixel ) {
+            this->Properties->TextMapperPixel->SetInput("Display on");
+        }
+        if ( this->Properties->TextMapperNumFrame ) {
+            QString str;
+            str.sprintf("f = %d",this->CurrentFrame);
+            this->Properties->TextMapperNumFrame->SetInput(str.toStdString().c_str());
+        }
+        if ( this->Properties->TextMapperResolution ) {
+            QString str;
+            str.sprintf("Resolution: %.2f x %.2f x %.2f mm",this->ImageData->GetSpacing()[0]*1000,this->ImageData->GetSpacing()[1]*1000,this->ImageData->GetSpacing()[2]*1000);
+            this->Properties->TextMapperResolution->SetInput(str.toStdString().c_str());
+        }
+        if ( this->Properties->TextMapperSlice ) {
+            int slice = (int)( (this->Properties->position[1] - this->ImageData->GetOrigin()[1]) / this->ImageData->GetSpacing()[1] + 0.5f );
+            QString strSlice;
+            strSlice.sprintf("Slice: %d",slice);
+            this->Properties->TextMapperSlice->SetInput(strSlice.toStdString().c_str());
+        }
+
+        this->GetRenderWindow()->Render();
+
+    }
+    else
+    {
+
+        this->FlagDisplayText = 0;
+        if ( this->Properties->TextMapperPixel ) {
+            this->Properties->TextMapperPixel->SetInput("Display off");
+        }
+        if ( this->Properties->TextMapperNumFrame ) {
+            this->Properties->TextMapperNumFrame->SetInput("");
+        }
+        if ( this->Properties->TextMapperResolution ) {
+            this->Properties->TextMapperResolution->SetInput("");
+        }
+        if ( this->Properties->TextMapperSlice ) {
+            this->Properties->TextMapperSlice->SetInput("");
+        }
+        if ( this->Properties->TextMapperMM ) {
+            this->Properties->TextMapperMM->SetInput("");
+        }
+        if ( this->Properties->TextMapperValue ) {
+            this->Properties->TextMapperValue->SetInput("");
+        }
+        this->GetRenderWindow()->Render();
+
+    }
+
+}
+
+
+vtkActor2D* OpenHeartGui::AddFixedText(const char *text, float x, float y, float R,float G, float B, int Size)
+{
+
+    vtkTextMapper *Mapper = vtkTextMapper::New();
+    vtkActor2D *Actor = vtkActor2D::New();
+    Mapper->SetInput(text);
+    Mapper->GetTextProperty()->SetColor(R, G, B);
+    Mapper->GetTextProperty()->SetFontSize(Size);
+    Mapper->GetTextProperty()->SetJustificationToLeft();
+    Mapper->GetTextProperty()->ShadowOff();
+    Actor->SetPosition(x, y);
+    Actor->SetMapper(Mapper);
+    return Actor;
+
+}
+
+
+void OpenHeartGui::resizeEvent(QResizeEvent* event)
+{
+    int sizeX = this->qVTK->GetRenderWindow()->GetSize()[0];
+    int sizeY = this->qVTK->GetRenderWindow()->GetSize()[1];
+    if ( (sizeX!=382) || (sizeY!=462) ) {
+        this->Properties->TextActorSlice->SetPosition(10,this->GetRenderWindow()->GetSize()[1]-20);
+        this->Properties->TextActorPixel->SetPosition(this->GetRenderWindow()->GetSize()[0]-10,this->GetRenderWindow()->GetSize()[1]-20);
+        this->Properties->TextActorMM->SetPosition(this->GetRenderWindow()->GetSize()[0]-10,this->GetRenderWindow()->GetSize()[1]-45);
+        this->Properties->TextActorValue->SetPosition(this->GetRenderWindow()->GetSize()[0]-10,this->GetRenderWindow()->GetSize()[1]-70);
+        this->GetRenderWindow()->Render();
+        QMainWindow::resizeEvent(event);
+    }
+}
+
+
+void OpenHeartGui::HidePlanModeManagement()
+{
+
+    if ( this->FlagHidePlan == 0 )
+    {
+        this->FlagHidePlan = 1;
+        this->Properties->xIPW->SetTextureVisibility(0);
+        this->Properties->xIPW->GetPlaneProperty()->SetOpacity(0);
+        this->Properties->yIPW->SetTextureVisibility(0);
+        this->Properties->yIPW->GetPlaneProperty()->SetOpacity(0);
+        this->Properties->zIPW->SetTextureVisibility(0);
+        this->Properties->zIPW->GetPlaneProperty()->SetOpacity(0);
+
+        if ( (this->FlagDisplayMesh==0) && (this->FlagDisplayMeshContours==0) ) {
+            this->GetMeshRenderer()->AddActor(this->Properties->MeshActor);
+            this->FlagDisplayMesh = 1;
+        }
+        /*
+        if ( this->FlagDisplayMeshContours == 1 ) {
+            this->GetMeshRenderer()->RemoveActor(this->Properties->xCutActor);
+            this->GetMeshRenderer()->RemoveActor(this->Properties->yCutActor);
+            this->GetMeshRenderer()->RemoveActor(this->Properties->zCutActor);
+            this->FlagDisplayMeshContours = 0;
+        }
+        */
+        this->GetRenderWindow()->Render();
+
+    }
+    else
+    {
+        if ( this->FlagDisplayMesh == 1 )
+            this->GetMeshRenderer()->RemoveActor(this->Properties->MeshActor);
+        if ( this->FlagDisplayMeshContours == 1 ) {
+            this->GetMeshRenderer()->RemoveActor(this->Properties->xCutActor);
+            this->GetMeshRenderer()->RemoveActor(this->Properties->yCutActor);
+            this->GetMeshRenderer()->RemoveActor(this->Properties->zCutActor);
+        }
+        this->FlagHidePlan = 0;
+
+        switch (this->ViewButton) {
+        case 0:  /// 3D view
+            this->Properties->xIPW->SetTextureVisibility(1);
+            this->Properties->xIPW->GetPlaneProperty()->SetOpacity(1);
+            this->Properties->yIPW->SetTextureVisibility(1);
+            this->Properties->yIPW->GetPlaneProperty()->SetOpacity(1);
+            this->Properties->zIPW->SetTextureVisibility(1);
+            this->Properties->zIPW->GetPlaneProperty()->SetOpacity(1);
+            if ( this->FlagDisplayMeshContours == 1 ) {
+                this->GetMeshRenderer()->AddActor(this->Properties->xCutActor);
+                this->GetMeshRenderer()->AddActor(this->Properties->yCutActor);
+                this->GetMeshRenderer()->AddActor(this->Properties->zCutActor);
+            }
+            break;
+        case 1:  /// XY view
+            this->Properties->xIPW->SetTextureVisibility(1);
+            this->Properties->xIPW->GetPlaneProperty()->SetOpacity(1);
+            if ( this->FlagDisplayMeshContours == 1 ) {
+                this->GetMeshRenderer()->AddActor(this->Properties->xCutActor);
+            }
+            break;
+        case 2:  /// XZ view
+            this->Properties->yIPW->SetTextureVisibility(1);
+            this->Properties->yIPW->GetPlaneProperty()->SetOpacity(1);
+            if ( this->FlagDisplayMeshContours == 1 ) {
+                this->GetMeshRenderer()->AddActor(this->Properties->yCutActor);
+            }
+            break;
+        case 3:  /// YZ view
+            this->Properties->zIPW->SetTextureVisibility(1);
+            this->Properties->zIPW->GetPlaneProperty()->SetOpacity(1);
+            if ( this->FlagDisplayMeshContours == 1 ) {
+                this->GetMeshRenderer()->AddActor(this->Properties->zCutActor);
+            }
+            break;
+        default:
+            break;
+        }
+
+        if ( this->FlagDisplayMesh == 1 )
+            this->GetMeshRenderer()->AddActor(this->Properties->MeshActor);
+        this->GetRenderWindow()->Render();
+    }
+
+}
+
+
+void OpenHeartGui::UpdateClinicalIndices()
+{
+
+    float EDV = 0;
+    float ESV = 1000000;
+    int NbElements = this->TableChart->GetNumberOfRows();
+    for ( int k=0; k<NbElements; k++)
+    {
+        float val = this->TableChart->GetValue(k,1).ToFloat();
+        if ( val > EDV )
+            EDV = val;
+        if ( val < ESV )
+            ESV = val;
+    }
+    /// End Diastolic and End systolic volume
+    QString strESV;
+    strESV.sprintf("%2.1f ml",ESV);
+    QString strEDV;
+    strEDV.sprintf("%2.1f ml",EDV);
+    this->labelESVValue->setText(strESV);
+    this->labelEDVValue->setText(strEDV);
+    /// Ejection fraction indice
+    float EF = 100 * (EDV-ESV) / (EDV+1e-6);
+    QString strEF;
+    strEF.sprintf("%2.1f %%",EF);
+    this->labelEFValue->setText(strEF);
+    /// Stroke volume indice
+    float SV = EDV-ESV;
+    QString strSV;
+    strSV.sprintf("%2.1f ml",SV);
+    this->labelSVValue->setText(strSV);
+
+}
+
+
+/// Custimize interface colors
+void OpenHeartGui::SetInterfaceColors()
+{
+    this->tabMesh->setStyleSheet("background-color: rgb(0,0,0);");
+    this->widgetXY->setStyleSheet("border-style: solid; border-width: 2px;  border-color: blue;");
+    this->widgetXZ->setStyleSheet("border-style: solid; border-width: 2px;  border-color: yellow;");
+    this->widgetYZ->setStyleSheet("border-style: solid; border-width: 2px;  border-color: red;");
+}
+
+
+void OpenHeartGui::slotReslice()
+{
+
+    if ( this->pushButtonReslice->isEnabled() )
+    {
+        if ( this->FlagReslice == 0 )
+        {
+            /// Reslice planes according to the main axis
+            this->SetLongAxisView();
+            /// Display off the Slice text actor
+            this->GetMainRenderer()->RemoveActor(this->Properties->TextActorSlice);
+            /// Replace Reslice text by Reset one into the push button
+            this->pushButtonReslice->setText("Reset");
+            /// Set corresponding flag to 1
+            this->FlagReslice = 1;
+        }
+        else
+        {
+            /// Reset the reslicing operation
+            this->ResetReslicing();
+            /// Display on the Slice text actor
+            this->GetMainRenderer()->AddActor(this->Properties->TextActorSlice);
+            /// Replace Reslice text by Reset one into the push button
+            this->pushButtonReslice->setText("Reslice");
+            /// Set corresponding flag to 0
+            this->FlagReslice = 0;
+        }
+
+    }
+
+}
+
+
+void OpenHeartGui::SetLongAxisView()
+{
+
+    /// Compute the rotation matrix between the Z-axis and the long axis of the heart
+    this->ComputeRotationMatrix();
+
+    /// Set the corresponding vtkTransform object
+    this->TransformViewOrientation->SetMatrix(this->RotationMatrix);
+    this->TransformViewOrientationInv->SetMatrix(this->RotationMatrixInv);
+
+    /// Set the plans at the center of the volume
+    double center[3];
+    for ( int i=0; i<3; i++ )
+        center[i] = 0.5*(this->ImageData->GetDimensions()[i])*(this->ImageData->GetSpacing()[i]);
+    this->Properties->xIPW->SetSlicePosition(center[0]);
+    this->Properties->yIPW->SetSlicePosition(center[1]);
+    this->Properties->zIPW->SetSlicePosition(center[2]);
+    this->Properties->yzIPW->SetSlicePosition(center[0]);
+    this->Properties->xzIPW->SetSlicePosition(center[1]);
+    this->Properties->xyIPW->SetSlicePosition(center[2]);
+
+    /////////////////////////////////////////////////
+    /////////////////////////////////////////////////
+    /////////////////////////////////////////////////
+    /// Process XZ-plans
+
+    /// Apply the rotation to the points defining the cartesian plan of interest
+    //double *cy = this->Properties->yIPW->GetCenter();
+    double *pt1 = this->Properties->yIPW->GetPoint1();
+    double *pt2 = this->Properties->yIPW->GetPoint2();
+    double *pto = this->Properties->yIPW->GetOrigin();
+    double newpt1[3];
+    double newpt2[3];
+    double newpto[3];
+
+    /// Do this to ensure that the center of the rotation corresponds to the center of the volume
+    for (int i=0; i<3; i++) {
+        pt1[i] -= center[i];
+        pt2[i] -= center[i];
+        pto[i] -= center[i];
+    }
+
+    /// Apply transformation
+    this->TransformViewOrientation->TransformPoint(pt1,newpt1);
+    this->TransformViewOrientation->TransformPoint(pt2,newpt2);
+    this->TransformViewOrientation->TransformPoint(pto,newpto);
+    for (int i=0; i<3; i++) {
+        newpt1[i] += center[i];
+        newpt2[i] += center[i];
+        newpto[i] += center[i];
+    }
+    ///
+    this->Properties->yIPW->SetOrigin(newpto);
+    this->Properties->yIPW->SetPoint1(newpt1);
+    this->Properties->yIPW->SetPoint2(newpt2);
+    this->Properties->yIPW->UpdatePlacement();
+    ///
+    this->Properties->xzIPW->SetOrigin(newpto);
+    this->Properties->xzIPW->SetPoint1(newpt1);
+    this->Properties->xzIPW->SetPoint2(newpt2);
+    this->Properties->xzIPW->UpdatePlacement();
+
+
+    /////////////////////////////////////////////////
+    /////////////////////////////////////////////////
+    /////////////////////////////////////////////////
+    /// Process YZ-plans
+
+    pt1 = this->Properties->xIPW->GetPoint1();
+    pt2 = this->Properties->xIPW->GetPoint2();
+    pto = this->Properties->xIPW->GetOrigin();
+
+    /// Do this to ensure that the center of the rotation corresponds to the center of the volume
+    for (int i=0; i<3; i++) {
+        pt1[i] -= center[i];
+        pt2[i] -= center[i];
+        pto[i] -= center[i];
+    }
+
+    /// Apply transformation
+    this->TransformViewOrientation->TransformPoint(pt1,newpt1);
+    this->TransformViewOrientation->TransformPoint(pt2,newpt2);
+    this->TransformViewOrientation->TransformPoint(pto,newpto);
+    for (int i=0; i<3; i++) {
+        newpt1[i] += center[i];
+        newpt2[i] += center[i];
+        newpto[i] += center[i];
+    }
+    ///
+    this->Properties->xIPW->SetOrigin(newpto);
+    this->Properties->xIPW->SetPoint1(newpt1);
+    this->Properties->xIPW->SetPoint2(newpt2);
+    this->Properties->xIPW->UpdatePlacement();
+    ///
+    this->Properties->yzIPW->SetOrigin(newpto);
+    this->Properties->yzIPW->SetPoint1(newpt1);
+    this->Properties->yzIPW->SetPoint2(newpt2);
+    this->Properties->yzIPW->UpdatePlacement();
+
+
+    /////////////////////////////////////////////////
+    /////////////////////////////////////////////////
+    /////////////////////////////////////////////////
+    /// Process XY-plans
+
+    pt1 = this->Properties->zIPW->GetPoint1();
+    pt2 = this->Properties->zIPW->GetPoint2();
+    pto = this->Properties->zIPW->GetOrigin();
+
+    /// Do this to ensure that the center of the rotation corresponds to the center of the volume
+    for (int i=0; i<3; i++) {
+        pt1[i] -= center[i];
+        pt2[i] -= center[i];
+        pto[i] -= center[i];
+    }
+
+    /// Apply transformation
+    this->TransformViewOrientation->TransformPoint(pt1,newpt1);
+    this->TransformViewOrientation->TransformPoint(pt2,newpt2);
+    this->TransformViewOrientation->TransformPoint(pto,newpto);
+    for (int i=0; i<3; i++) {
+        newpt1[i] += center[i];
+        newpt2[i] += center[i];
+        newpto[i] += center[i];
+    }
+    ///
+    this->Properties->zIPW->SetOrigin(newpto);
+    this->Properties->zIPW->SetPoint1(newpt1);
+    this->Properties->zIPW->SetPoint2(newpt2);
+    this->Properties->zIPW->UpdatePlacement();
+    ///
+    this->Properties->xyIPW->SetOrigin(newpto);
+    this->Properties->xyIPW->SetPoint1(newpt1);
+    this->Properties->xyIPW->SetPoint2(newpt2);
+    this->Properties->xyIPW->UpdatePlacement();
+
+    /////////////////////////////////////////////////
+    /////////////////////////////////////////////////
+    /////////////////////////////////////////////////
+    /// Final translation to match the Long axis
+
+    /// XZ plan translation
+    double *ncy = this->Properties->yIPW->GetCenter();
+    double t;
+    double closest[3];
+    vtkLine::DistanceToLine(ncy, this->BasalPoint, this->ApexPoint, t, closest);
+    double offset = this->Properties->yIPW->GetSlicePosition() + (closest[1] - ncy[1]);
+    this->Properties->yIPW->SetSlicePosition(offset);
+    this->Properties->xzIPW->SetSlicePosition(offset);
+
+    /// YZ plan translation
+    double *ncx = this->Properties->xIPW->GetCenter();
+    vtkLine::DistanceToLine(ncx, this->BasalPoint, this->ApexPoint, t, closest);
+    offset = this->Properties->xIPW->GetSlicePosition() + (closest[0] - ncx[0]);
+    this->Properties->xIPW->SetSlicePosition(offset);
+    this->Properties->yzIPW->SetSlicePosition(offset);
+
+    /// XY plan translation
+    double *ncz = this->Properties->zIPW->GetCenter();
+    double mid[3];
+    for (int i=0; i<3; i++)
+        mid[i] = this->BasalPoint[i] + 0.5 * (this->ApexPoint[i]-this->BasalPoint[i]);
+    offset = this->Properties->zIPW->GetSlicePosition() + (mid[2] - ncz[2]);
+    this->Properties->zIPW->SetSlicePosition(offset);
+    this->Properties->xyIPW->SetSlicePosition(offset);
+
+    /// Update Properties->position to fit to the new position
+    this->Properties->position[0] = this->Properties->xIPW->GetSlicePosition();
+    this->Properties->position[1] = this->Properties->yIPW->GetSlicePosition();
+    this->Properties->position[2] = this->Properties->zIPW->GetSlicePosition();
+
+
+    /////////////////////////////////////////////////
+    /////////////////////////////////////////////////
+    /////////////////////////////////////////////////
+    /// Update renderer
+    this->UpdateViewer(0,this->ZoomLabel,this->RenXY);
+    this->UpdateViewer(1,this->ZoomLabel,this->RenXZ);
+    this->UpdateViewer(2,this->ZoomLabel,this->RenYZ);
+    this->GetRenderWindow()->Render();
+
+}
+
+
+/// Compute the rotation matrix between the Z-axis and the long axis of the heart
+void OpenHeartGui::ComputeRotationMatrix()
+{
+
+    double ZAxis[] = {0,0,1};
+    double MainAxis[3];
+    for (int i=0; i<3; i++)
+        MainAxis[i] = this->BasalPoint[i] - this->ApexPoint[i];
+    vtkMath::Normalize(MainAxis);
+
+    /// Compute rotation matrix between two vectors: MainAxis and ZAxis
+    double normal1[3];
+    double normal2[3];
+    for (int i=0; i<3; i++) {
+        normal1[i] = ZAxis[i];
+        normal2[i] = MainAxis[i];
+    }
+
+    double vec[3];
+    vtkMath::Cross(normal1, normal2, vec);
+    double costheta = vtkMath::Dot(normal1, normal2);
+    double sintheta = vtkMath::Norm(vec);
+    double theta = atan2(sintheta, costheta);
+    if (sintheta != 0)
+    {
+        vec[0] /= sintheta;
+        vec[1] /= sintheta;
+        vec[2] /= sintheta;
+    }
+
+    /// convert to quaternion
+    costheta = cos(0.5*theta);
+    sintheta = sin(0.5*theta);
+    double quat[4];
+    quat[0] = costheta;
+    quat[1] = vec[0]*sintheta;
+    quat[2] = vec[1]*sintheta;
+    quat[3] = vec[2]*sintheta;
+
+    /// convert to matrix
+    double mat[3][3];
+    vtkMath::QuaternionToMatrix3x3(quat,mat);
+
+    /// Create corresponding 4x4 matrix
+    this->RotationMatrix->Identity();
+    this->RotationMatrixInv->Identity();
+    for (unsigned int i = 0; i < 3; i++) {
+        for (unsigned int j = 0; j < 3; j++) {
+            this->RotationMatrix->SetElement(i, j, mat[i][j]);
+            this->RotationMatrixInv->SetElement(i, j, mat[i][j]);
+        }
+    }
+    this->RotationMatrixInv->Invert();
+
+}
+
+
+/// Reset the reslicing operation
+void OpenHeartGui::ResetReslicing()
+{
+
+    /// Set the rotation matrix to identity
+    this->RotationMatrix->Identity();
+    this->RotationMatrixInv->Identity();
+
+    /// Set the corresponding vtkTransform object
+    this->TransformViewOrientation->SetMatrix(this->RotationMatrix);
+    this->TransformViewOrientationInv->SetMatrix(this->RotationMatrixInv);
+
+    /// Switch off the oblique orientation of each plan
+    this->Properties->xIPW->SetPlaneOrientationToXAxes();
+    this->Properties->yzIPW->SetPlaneOrientationToXAxes();
+    this->Properties->yIPW->SetPlaneOrientationToYAxes();
+    this->Properties->xzIPW->SetPlaneOrientationToYAxes();
+    this->Properties->zIPW->SetPlaneOrientationToZAxes();
+    this->Properties->xyIPW->SetPlaneOrientationToZAxes();
+
+    /// Set the plans at the center of the volume
+    double center[3];
+    for ( unsigned int k=0; k<3; k++ )
+        center[k] = ((this->ImageData->GetDimensions()[k])*(this->ImageData->GetSpacing()[k]))/2;
+
+    this->Properties->xIPW->SetSlicePosition(center[0]);
+    this->Properties->yzIPW->SetSlicePosition(center[0]);
+    this->Properties->yIPW->SetSlicePosition(center[1]);
+    this->Properties->xzIPW->SetSlicePosition(center[1]);
+    this->Properties->zIPW->SetSlicePosition(center[2]);
+    this->Properties->xyIPW->SetSlicePosition(center[2]);
+
+    /// Update Properties->position to fit to the new position
+    this->Properties->position[0] = center[0];
+    this->Properties->position[1] = center[1];
+    this->Properties->position[2] = center[2];
+
+    /// Update renderer
+    this->UpdateViewer(0,this->ZoomLabel,this->RenXY);
+    this->UpdateViewer(1,this->ZoomLabel,this->RenXZ);
+    this->UpdateViewer(2,this->ZoomLabel,this->RenYZ);
+    this->GetRenderWindow()->Render();
+
+}
+
+
+void OpenHeartGui::UpdateViewer(int view, double zoom, vtkRenderer *ren)
+{
+
+    /// Set Focal Point
+    double center[3];
+    for (int i=0; i<3; i++)
+        center[i] = 0.5 * this->ImageData->GetDimensions()[i] * this->ImageData->GetSpacing()[i];
+    ren->GetActiveCamera()->SetFocalPoint(center);
+
+    /// Set Position
+    double position[3];
+    double newPosition[3];
+    switch (view)
+    {
+    case 0: /// XY view
+        position[0] = 0.5 * this->ImageData->GetDimensions()[0] * this->ImageData->GetSpacing()[0];
+        position[1] = 0.5 * this->ImageData->GetDimensions()[1] * this->ImageData->GetSpacing()[1];
+        position[2] = 10  * this->ImageData->GetDimensions()[2] * this->ImageData->GetSpacing()[2];
+        break;
+    case 1: /// XZ view
+        position[0] = 0.5 * this->ImageData->GetDimensions()[0] * this->ImageData->GetSpacing()[0];
+        position[1] = 10  * this->ImageData->GetDimensions()[1] * this->ImageData->GetSpacing()[1];
+        position[2] = 0.5 * this->ImageData->GetDimensions()[2] * this->ImageData->GetSpacing()[2];
+        break;
+    case 2: /// YZ view
+        position[0] = 10  * this->ImageData->GetDimensions()[0] * this->ImageData->GetSpacing()[0];
+        position[1] = 0.5 * this->ImageData->GetDimensions()[1] * this->ImageData->GetSpacing()[1];
+        position[2] = 0.5 * this->ImageData->GetDimensions()[2] * this->ImageData->GetSpacing()[2];
+    }
+    for (int i=0; i<3; i++)
+        position[i]  = position[i] - center[i];
+    this->TransformViewOrientation->TransformPoint(position,newPosition);
+    for (int i=0; i<3; i++)
+        newPosition[i]  = newPosition[i] + center[i];
+    ren->GetActiveCamera()->SetPosition(newPosition);
+
+    /// Set ViewUp
+    double pt[] = {0,0,-1};
+    double viewup[3];
+    this->TransformViewOrientation->TransformPoint(pt,viewup);
+    ren->GetActiveCamera()->SetViewUp(viewup);
+    ren->ResetCamera();
+    ren->GetActiveCamera()->Zoom(zoom);
+    ren->GetRenderWindow()->Render();
+
+}
+
+
+void OpenHeartGui::ComputePointBeforeRotation(double *position)
+{
+
+    double center[3];
+    double newPosition[3];
+    for (int i=0; i<3; i++)
+        center[i] = 0.5 * this->ImageData->GetDimensions()[i] * this->ImageData->GetSpacing()[i];
+
+    for (int i=0; i<3; i++)
+        position[i]  = position[i] - center[i];
+    this->TransformViewOrientationInv->TransformPoint(position,newPosition);
+    for (int i=0; i<3; i++)
+        position[i]  = newPosition[i] + center[i];
+
+}
diff --git a/Applications/OpenHeartGui.h b/Applications/OpenHeartGui.h
new file mode 100644 (file)
index 0000000..c79d67e
--- /dev/null
@@ -0,0 +1,232 @@
+/**
+* Progam made by Olivier Bernard, associate professor
+* at Institut National des Sciences Appliquees (INSA) Lyon,
+* CREATIS Laboratory,
+* 69621 Villeurbanne, France,
+* 07th of May 2014
+*/
+
+#ifndef _OpenHeartGUI_h
+#define _OpenHeartGUI_h
+
+#include <vtkImageData.h>
+#include <vtkDataSet.h>
+#include <vtkLookupTable.h>
+#include <vtkPointWidget.h>
+#include <vtkImagePlaneWidget.h>
+#include <vtkPlane.h>
+#include <vtkCellPicker.h>
+#include <vtkRenderWindowInteractor.h>
+#include <vtkProperty.h>
+#include <vtkCommand.h>
+#include <vtkActor2D.h>
+#include <vtkTextProperty.h>
+#include <vtkEventQtSlotConnect.h>
+#include <vtkTextMapper.h>
+#include <vtkCutter.h>
+#include <vtkContextView.h>
+#include <vtkTable.h>
+#include <vtkOrientationMarkerWidget.h>
+#include <vtkMatrix4x4.h>
+#include <list>
+
+#include "ui_OpenHeartGui.h"
+#include <QMainWindow>
+#include <QtGui>
+#include <QTimer>
+
+
+using namespace std;
+
+class vtkRenderer;
+class vtkEventQtSlotConnect;
+class vtkObject;
+class vtkCommand;
+
+
+struct RendererProperties
+{
+    vtkSmartPointer<vtkLookupTable> lut;
+    vtkSmartPointer<vtkImagePlaneWidget> xIPW, yIPW, zIPW;
+    vtkSmartPointer<vtkImagePlaneWidget> xyIPW,xzIPW,yzIPW;
+    double *position;
+    vtkSmartPointer<vtkActor2D> TextActorPixel;
+    vtkSmartPointer<vtkTextMapper> TextMapperPixel;
+    vtkSmartPointer<vtkActor2D> TextActorMM;
+    vtkSmartPointer<vtkTextMapper> TextMapperMM;
+    vtkSmartPointer<vtkActor2D> TextActorValue;
+    vtkSmartPointer<vtkTextMapper> TextMapperValue;
+    vtkSmartPointer<vtkActor2D> TextActorSlice;
+    vtkSmartPointer<vtkTextMapper> TextMapperSlice;
+    vtkSmartPointer<vtkActor2D> TextActorNumFrame;
+    vtkSmartPointer<vtkTextMapper> TextMapperNumFrame;
+    vtkSmartPointer<vtkActor2D> TextActorResolution;
+    vtkSmartPointer<vtkTextMapper> TextMapperResolution;
+    vtkSmartPointer<vtkActor> MeshActor;
+    vtkSmartPointer<vtkActor> xCutActor, yCutActor, zCutActor;
+    vtkSmartPointer<vtkActor> BasalPointActor;
+    vtkSmartPointer<vtkActor> ApexPointActor;
+    vtkSmartPointer<vtkActor> LongAxisActor;
+    vtkSmartPointer<vtkActor> BoundingBoxActor;
+    list<vtkDataSetMapper*> StackMapperList;
+    list<vtkDataSetMapper*>::iterator itStackMapperList;
+    list<vtkCutter*> StackMapXCutter;
+    list<vtkCutter*>::iterator itStackMapXCutter;
+    list<vtkCutter*> StackMapYCutter;
+    list<vtkCutter*>::iterator itStackMapYCutter;
+    list<vtkCutter*> StackMapZCutter;
+    list<vtkCutter*>::iterator itStackMapZCutter;
+};
+
+
+class OpenHeartGui : public QMainWindow, public Ui::OpenHeartGui
+{
+    Q_OBJECT
+    public:
+
+        OpenHeartGui();
+        ~OpenHeartGui();
+
+        vtkSmartPointer<vtkCellPicker> GetPicker() { return this->Picker; }
+        vtkSmartPointer<vtkCellPicker> GetPickerXY() { return this->PickerXY; }
+        vtkSmartPointer<vtkCellPicker> GetPickerXZ() { return this->PickerXZ; }
+        vtkSmartPointer<vtkCellPicker> GetPickerYZ() { return this->PickerYZ; }
+        RendererProperties *GetRendererProperties() { return this->Properties; }
+        vtkRenderWindow *GetRenderWindow() { return this->qVTK->GetRenderWindow(); }
+        vtkRenderWindow *GetRenderWindowXY() { return this->qVTKXY->GetRenderWindow(); }
+        vtkRenderWindow *GetRenderWindowXZ() { return this->qVTKXZ->GetRenderWindow(); }
+        vtkRenderWindow *GetRenderWindowYZ() { return this->qVTKYZ->GetRenderWindow(); }
+        vtkSmartPointer<vtkRenderer> GetMeshRenderer() { return this->Ren; }
+        vtkSmartPointer<vtkRenderer> GetMainRenderer() { return this->Ren; }
+        vtkSmartPointer<vtkRenderer> GetXYRenderer() { return this->RenXY; }
+        vtkSmartPointer<vtkRenderer> GetXZRenderer() { return this->RenXZ; }
+        vtkSmartPointer<vtkRenderer> GetYZRenderer() { return this->RenYZ; }
+
+        vtkImageData *GetCurrentImageData() { return this->ImageData; }
+        int *GetDimensions() { return this->Dims; }
+        void InterpolationManagement();
+        void CreateFromSequenceDataPointer(std::string inputFilename);
+        void UpdateForwardViewers();
+        void UpdateBackwardViewers();
+        int GetCurrentFrame() { return this->CurrentFrame; }
+        int GetNumberOfFrames() { return this->NumberOfVolumes; }
+        void SetFlagLoopEndToBegin( int val ) { this->FlagLoopEndToBegin = val; }
+        void SetFlagLoopBeginToEnd( int val ) { this->FlagLoopBeginToEnd = val; }
+        void DisplayMainAxisManagement();
+        void DisplayMeshManagement();
+        void DisplayModeManagement();
+        void HidePlanModeManagement();
+        void UpdateCoords(double *pos);
+        int GetSelectedButton() { return ViewButton; }
+        int GetFlagDisplayText() { return FlagDisplayText; }
+        void ComputePointBeforeRotation(double *pt);
+
+    public slots:
+
+        void slotMeshAlpha(int);
+        void slotRefreshViewer(int);
+        void slotTabChange(int);
+        void slotPlay();
+        void slotXYView();
+        void slotXZView();
+        void slotYZView();
+        void slot3DView();
+        void slotMeshView();
+        void slotMeshRepresentation();
+        void slotMeshColor();
+        void slotMeshCutter();
+        void slotTimerEvent();
+        void slotBasalPoint();
+        void slotApexPoint();
+        void slotReslice();
+        void slotUpdateCoords(vtkObject*);
+
+    protected:
+
+        int Dims[3];
+        int PreviousFrame;
+        int CurrentFrame;
+        int NumberOfVolumes;
+        double BasalPoint[3];
+        double ApexPoint[3];
+        vtkSmartPointer<vtkRenderer> Ren;
+        vtkSmartPointer<vtkRenderer> RenXY;
+        vtkSmartPointer<vtkRenderer> RenXZ;
+        vtkSmartPointer<vtkRenderer> RenYZ;
+        vtkRenderer* RenChart;
+        QTimer *Timer;
+        vtkEventQtSlotConnect* Connections;
+
+        list<vtkImageData*> StackVolume;
+        list<vtkImageData*>::iterator itStackVolume;
+        list<vtkPolyData*> StackMesh;
+        list<vtkPolyData*>::iterator itStackMesh;
+        vtkPolyData * Mesh;
+        vtkImageData *ImageData;
+        vtkSmartPointer <vtkOrientationMarkerWidget> OrientationWidget;
+        RendererProperties *Properties;
+        vtkSmartPointer<vtkCellPicker> Picker;
+        vtkSmartPointer<vtkCellPicker> PickerXY;
+        vtkSmartPointer<vtkCellPicker> PickerXZ;
+        vtkSmartPointer<vtkCellPicker> PickerYZ;
+        vtkSmartPointer<vtkRenderWindowInteractor> Interactor;
+        vtkSmartPointer<vtkRenderWindowInteractor> InteractorXY;
+        vtkSmartPointer<vtkRenderWindowInteractor> InteractorXZ;
+        vtkSmartPointer<vtkRenderWindowInteractor> InteractorYZ;
+        vtkSmartPointer<vtkContextView> ViewChart;
+        vtkSmartPointer<vtkTable> TableChart;
+        vtkSmartPointer<vtkMatrix4x4> RotationMatrix;
+        vtkSmartPointer<vtkTransform> TransformViewOrientation;        
+        vtkSmartPointer<vtkMatrix4x4> RotationMatrixInv;
+        vtkSmartPointer<vtkTransform> TransformViewOrientationInv;
+
+        int FlagInterpolation;
+        int FlagDisplayMesh;
+        int FlagDisplayMeshContourX;
+        int FlagDisplayMeshContourY;
+        int FlagDisplayMeshContourZ;
+        int FlagLoopEndToBegin;
+        int FlagLoopBeginToEnd;
+        int FlagPlay;
+        int FlagDisplayText;
+        int FlagHidePlan;
+        int FlagDisplayMeshContours;
+        int FlagLongAxis;
+        int FlagDisplayApexPoint;
+        int FlagDisplayBasalPoint;
+        int FlagDisplayLongAxis;
+        int FlagReslice;
+
+        int ViewButton;
+        int MeshRepresentation;
+        int MeshColor;
+        double ZoomLabel;
+        double ZoomMain;
+
+        void InstantiateQtVtkRenderers();
+        void InitPickers();
+        void InitWidgets();
+        void InitProperties();
+        void InitOrientationAxes();
+        void InitPlaneWidget();
+        void InitTexts();
+        void InitChar();
+        void SetCustomInteractorStyle();
+        vtkActor2D* AddFixedText(const char *text, float x, float y, float R,float G, float B, int Size);
+        void ForceXZView();
+        void UpdateClinicalIndices();
+        void SetInterfaceColors();
+        void CreateLongAxisActor();
+        void SetLongAxisView();
+        void ResetReslicing();
+        void ComputeRotationMatrix();
+        void UpdateViewer(int view, double zoom, vtkRenderer *ren);
+
+
+        /// overloaded resize handler
+        virtual void resizeEvent(QResizeEvent* event);
+
+};
+
+#endif
+
diff --git a/Applications/OpenHeartGui.ui b/Applications/OpenHeartGui.ui
new file mode 100644 (file)
index 0000000..d6b46ec
--- /dev/null
@@ -0,0 +1,987 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>OpenHeartGui</class>
+ <widget class="QMainWindow" name="OpenHeartGui">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>773</width>
+    <height>696</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>OpenHeart GUI</string>
+  </property>
+  <widget class="QWidget" name="centralwidget">
+   <layout class="QGridLayout" name="gridLayout_10">
+    <item row="0" column="0">
+     <widget class="QTabWidget" name="tabWidget">
+      <property name="currentIndex">
+       <number>0</number>
+      </property>
+      <property name="movable">
+       <bool>false</bool>
+      </property>
+      <widget class="QWidget" name="tabMesh">
+       <attribute name="title">
+        <string>Space</string>
+       </attribute>
+       <layout class="QGridLayout" name="gridLayout_3">
+        <item row="0" column="2">
+         <layout class="QHBoxLayout" name="horizontalLayout_7">
+          <item>
+           <layout class="QVBoxLayout" name="verticalLayoutVisu2D">
+            <item>
+             <widget class="QWidget" name="widgetXY" native="true">
+              <property name="sizePolicy">
+               <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+                <horstretch>0</horstretch>
+                <verstretch>0</verstretch>
+               </sizepolicy>
+              </property>
+              <property name="minimumSize">
+               <size>
+                <width>200</width>
+                <height>155</height>
+               </size>
+              </property>
+              <layout class="QGridLayout" name="gridLayout_7">
+               <item row="0" column="0">
+                <widget class="QVTKWidget" name="qVTKXY">
+                 <property name="sizePolicy">
+                  <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+                   <horstretch>0</horstretch>
+                   <verstretch>0</verstretch>
+                  </sizepolicy>
+                 </property>
+                 <property name="minimumSize">
+                  <size>
+                   <width>196</width>
+                   <height>151</height>
+                  </size>
+                 </property>
+                </widget>
+               </item>
+              </layout>
+             </widget>
+            </item>
+            <item>
+             <spacer name="verticalSpacer_4">
+              <property name="orientation">
+               <enum>Qt::Vertical</enum>
+              </property>
+              <property name="sizeType">
+               <enum>QSizePolicy::Fixed</enum>
+              </property>
+              <property name="sizeHint" stdset="0">
+               <size>
+                <width>20</width>
+                <height>10</height>
+               </size>
+              </property>
+             </spacer>
+            </item>
+            <item>
+             <widget class="QWidget" name="widgetXZ" native="true">
+              <property name="sizePolicy">
+               <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+                <horstretch>0</horstretch>
+                <verstretch>0</verstretch>
+               </sizepolicy>
+              </property>
+              <property name="minimumSize">
+               <size>
+                <width>200</width>
+                <height>155</height>
+               </size>
+              </property>
+              <layout class="QGridLayout" name="gridLayout_8">
+               <item row="0" column="0">
+                <widget class="QVTKWidget" name="qVTKXZ">
+                 <property name="sizePolicy">
+                  <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+                   <horstretch>0</horstretch>
+                   <verstretch>0</verstretch>
+                  </sizepolicy>
+                 </property>
+                 <property name="minimumSize">
+                  <size>
+                   <width>196</width>
+                   <height>151</height>
+                  </size>
+                 </property>
+                </widget>
+               </item>
+              </layout>
+             </widget>
+            </item>
+            <item>
+             <spacer name="verticalSpacer_5">
+              <property name="orientation">
+               <enum>Qt::Vertical</enum>
+              </property>
+              <property name="sizeType">
+               <enum>QSizePolicy::Fixed</enum>
+              </property>
+              <property name="sizeHint" stdset="0">
+               <size>
+                <width>20</width>
+                <height>10</height>
+               </size>
+              </property>
+             </spacer>
+            </item>
+            <item>
+             <widget class="QWidget" name="widgetYZ" native="true">
+              <property name="sizePolicy">
+               <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+                <horstretch>0</horstretch>
+                <verstretch>0</verstretch>
+               </sizepolicy>
+              </property>
+              <property name="minimumSize">
+               <size>
+                <width>200</width>
+                <height>155</height>
+               </size>
+              </property>
+              <layout class="QGridLayout" name="gridLayout_9">
+               <item row="0" column="0">
+                <widget class="QVTKWidget" name="qVTKYZ">
+                 <property name="sizePolicy">
+                  <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+                   <horstretch>0</horstretch>
+                   <verstretch>0</verstretch>
+                  </sizepolicy>
+                 </property>
+                 <property name="minimumSize">
+                  <size>
+                   <width>196</width>
+                   <height>151</height>
+                  </size>
+                 </property>
+                </widget>
+               </item>
+              </layout>
+             </widget>
+            </item>
+           </layout>
+          </item>
+         </layout>
+        </item>
+        <item row="0" column="1">
+         <spacer name="horizontalSpacer_5">
+          <property name="orientation">
+           <enum>Qt::Horizontal</enum>
+          </property>
+          <property name="sizeType">
+           <enum>QSizePolicy::Fixed</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>20</width>
+            <height>20</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+        <item row="0" column="0">
+         <layout class="QVBoxLayout" name="verticalLayoutMesh">
+          <item>
+           <widget class="QVTKWidget" name="qVTK">
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="Expanding" vsizetype="MinimumExpanding">
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+           </widget>
+          </item>
+         </layout>
+        </item>
+       </layout>
+      </widget>
+      <widget class="QWidget" name="tabChart">
+       <attribute name="title">
+        <string>Chart</string>
+       </attribute>
+       <layout class="QGridLayout" name="gridLayout_2">
+        <item row="0" column="0">
+         <layout class="QVBoxLayout" name="verticalLayoutChart">
+          <item>
+           <spacer name="verticalSpacer_2">
+            <property name="orientation">
+             <enum>Qt::Vertical</enum>
+            </property>
+            <property name="sizeType">
+             <enum>QSizePolicy::Fixed</enum>
+            </property>
+            <property name="sizeHint" stdset="0">
+             <size>
+              <width>20</width>
+              <height>30</height>
+             </size>
+            </property>
+           </spacer>
+          </item>
+          <item>
+           <widget class="QVTKWidget" name="qVTKChart">
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <spacer name="verticalSpacer">
+            <property name="orientation">
+             <enum>Qt::Vertical</enum>
+            </property>
+            <property name="sizeType">
+             <enum>QSizePolicy::Fixed</enum>
+            </property>
+            <property name="sizeHint" stdset="0">
+             <size>
+              <width>20</width>
+              <height>20</height>
+             </size>
+            </property>
+           </spacer>
+          </item>
+          <item>
+           <layout class="QHBoxLayout" name="horizontalLayoutEF">
+            <item>
+             <widget class="QLabel" name="labelEF">
+              <property name="sizePolicy">
+               <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+                <horstretch>0</horstretch>
+                <verstretch>0</verstretch>
+               </sizepolicy>
+              </property>
+              <property name="text">
+               <string>Ejection Fraction</string>
+              </property>
+             </widget>
+            </item>
+            <item>
+             <widget class="QLabel" name="labelEFValue">
+              <property name="sizePolicy">
+               <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+                <horstretch>0</horstretch>
+                <verstretch>0</verstretch>
+               </sizepolicy>
+              </property>
+              <property name="minimumSize">
+               <size>
+                <width>40</width>
+                <height>0</height>
+               </size>
+              </property>
+              <property name="text">
+               <string/>
+              </property>
+             </widget>
+            </item>
+            <item>
+             <spacer name="horizontalSpacer">
+              <property name="orientation">
+               <enum>Qt::Horizontal</enum>
+              </property>
+              <property name="sizeType">
+               <enum>QSizePolicy::Fixed</enum>
+              </property>
+              <property name="sizeHint" stdset="0">
+               <size>
+                <width>20</width>
+                <height>20</height>
+               </size>
+              </property>
+             </spacer>
+            </item>
+            <item>
+             <spacer name="horizontalSpacer_2">
+              <property name="orientation">
+               <enum>Qt::Horizontal</enum>
+              </property>
+              <property name="sizeType">
+               <enum>QSizePolicy::Fixed</enum>
+              </property>
+              <property name="sizeHint" stdset="0">
+               <size>
+                <width>40</width>
+                <height>20</height>
+               </size>
+              </property>
+             </spacer>
+            </item>
+            <item>
+             <widget class="QLabel" name="labelEDV">
+              <property name="sizePolicy">
+               <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+                <horstretch>0</horstretch>
+                <verstretch>0</verstretch>
+               </sizepolicy>
+              </property>
+              <property name="text">
+               <string>EDV</string>
+              </property>
+             </widget>
+            </item>
+            <item>
+             <widget class="QLabel" name="labelEDVValue">
+              <property name="sizePolicy">
+               <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+                <horstretch>0</horstretch>
+                <verstretch>0</verstretch>
+               </sizepolicy>
+              </property>
+              <property name="minimumSize">
+               <size>
+                <width>40</width>
+                <height>0</height>
+               </size>
+              </property>
+              <property name="text">
+               <string/>
+              </property>
+             </widget>
+            </item>
+            <item>
+             <spacer name="horizontalSpacer_8">
+              <property name="orientation">
+               <enum>Qt::Horizontal</enum>
+              </property>
+              <property name="sizeType">
+               <enum>QSizePolicy::Fixed</enum>
+              </property>
+              <property name="sizeHint" stdset="0">
+               <size>
+                <width>20</width>
+                <height>20</height>
+               </size>
+              </property>
+             </spacer>
+            </item>
+           </layout>
+          </item>
+          <item>
+           <layout class="QHBoxLayout" name="horizontalLayoutSV">
+            <item>
+             <widget class="QLabel" name="labelSV">
+              <property name="sizePolicy">
+               <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+                <horstretch>0</horstretch>
+                <verstretch>0</verstretch>
+               </sizepolicy>
+              </property>
+              <property name="minimumSize">
+               <size>
+                <width>0</width>
+                <height>0</height>
+               </size>
+              </property>
+              <property name="text">
+               <string>Stroke volume      </string>
+              </property>
+             </widget>
+            </item>
+            <item>
+             <widget class="QLabel" name="labelSVValue">
+              <property name="sizePolicy">
+               <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+                <horstretch>0</horstretch>
+                <verstretch>0</verstretch>
+               </sizepolicy>
+              </property>
+              <property name="minimumSize">
+               <size>
+                <width>40</width>
+                <height>0</height>
+               </size>
+              </property>
+              <property name="text">
+               <string/>
+              </property>
+             </widget>
+            </item>
+            <item>
+             <spacer name="horizontalSpacer_7">
+              <property name="orientation">
+               <enum>Qt::Horizontal</enum>
+              </property>
+              <property name="sizeType">
+               <enum>QSizePolicy::Fixed</enum>
+              </property>
+              <property name="sizeHint" stdset="0">
+               <size>
+                <width>20</width>
+                <height>20</height>
+               </size>
+              </property>
+             </spacer>
+            </item>
+            <item>
+             <spacer name="horizontalSpacer_4">
+              <property name="orientation">
+               <enum>Qt::Horizontal</enum>
+              </property>
+              <property name="sizeType">
+               <enum>QSizePolicy::Fixed</enum>
+              </property>
+              <property name="sizeHint" stdset="0">
+               <size>
+                <width>40</width>
+                <height>20</height>
+               </size>
+              </property>
+             </spacer>
+            </item>
+            <item>
+             <widget class="QLabel" name="labelESV">
+              <property name="sizePolicy">
+               <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+                <horstretch>0</horstretch>
+                <verstretch>0</verstretch>
+               </sizepolicy>
+              </property>
+              <property name="text">
+               <string>ESV</string>
+              </property>
+             </widget>
+            </item>
+            <item>
+             <widget class="QLabel" name="labelESVValue">
+              <property name="sizePolicy">
+               <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+                <horstretch>0</horstretch>
+                <verstretch>0</verstretch>
+               </sizepolicy>
+              </property>
+              <property name="minimumSize">
+               <size>
+                <width>40</width>
+                <height>0</height>
+               </size>
+              </property>
+              <property name="text">
+               <string/>
+              </property>
+             </widget>
+            </item>
+            <item>
+             <spacer name="horizontalSpacer_9">
+              <property name="orientation">
+               <enum>Qt::Horizontal</enum>
+              </property>
+              <property name="sizeType">
+               <enum>QSizePolicy::Fixed</enum>
+              </property>
+              <property name="sizeHint" stdset="0">
+               <size>
+                <width>23</width>
+                <height>20</height>
+               </size>
+              </property>
+             </spacer>
+            </item>
+           </layout>
+          </item>
+          <item>
+           <spacer name="verticalSpacer_3">
+            <property name="orientation">
+             <enum>Qt::Vertical</enum>
+            </property>
+            <property name="sizeType">
+             <enum>QSizePolicy::Fixed</enum>
+            </property>
+            <property name="sizeHint" stdset="0">
+             <size>
+              <width>20</width>
+              <height>30</height>
+             </size>
+            </property>
+           </spacer>
+          </item>
+         </layout>
+        </item>
+       </layout>
+      </widget>
+     </widget>
+    </item>
+    <item row="1" column="0">
+     <widget class="QTabWidget" name="tabWidgetOption">
+      <property name="sizePolicy">
+       <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+        <horstretch>0</horstretch>
+        <verstretch>0</verstretch>
+       </sizepolicy>
+      </property>
+      <property name="palette">
+       <palette>
+        <active>
+         <colorrole role="Base">
+          <brush brushstyle="SolidPattern">
+           <color alpha="255">
+            <red>85</red>
+            <green>255</green>
+            <blue>255</blue>
+           </color>
+          </brush>
+         </colorrole>
+         <colorrole role="NoRole">
+          <brush brushstyle="SolidPattern">
+           <color alpha="255">
+            <red>170</red>
+            <green>255</green>
+            <blue>255</blue>
+           </color>
+          </brush>
+         </colorrole>
+        </active>
+        <inactive>
+         <colorrole role="Base">
+          <brush brushstyle="SolidPattern">
+           <color alpha="255">
+            <red>85</red>
+            <green>255</green>
+            <blue>255</blue>
+           </color>
+          </brush>
+         </colorrole>
+         <colorrole role="NoRole">
+          <brush brushstyle="SolidPattern">
+           <color alpha="255">
+            <red>170</red>
+            <green>255</green>
+            <blue>255</blue>
+           </color>
+          </brush>
+         </colorrole>
+        </inactive>
+        <disabled>
+         <colorrole role="Base">
+          <brush brushstyle="SolidPattern">
+           <color alpha="255">
+            <red>255</red>
+            <green>255</green>
+            <blue>255</blue>
+           </color>
+          </brush>
+         </colorrole>
+         <colorrole role="NoRole">
+          <brush brushstyle="SolidPattern">
+           <color alpha="255">
+            <red>170</red>
+            <green>255</green>
+            <blue>255</blue>
+           </color>
+          </brush>
+         </colorrole>
+        </disabled>
+       </palette>
+      </property>
+      <property name="tabPosition">
+       <enum>QTabWidget::North</enum>
+      </property>
+      <property name="tabShape">
+       <enum>QTabWidget::Rounded</enum>
+      </property>
+      <property name="currentIndex">
+       <number>0</number>
+      </property>
+      <property name="elideMode">
+       <enum>Qt::ElideNone</enum>
+      </property>
+      <property name="tabsClosable">
+       <bool>false</bool>
+      </property>
+      <widget class="QWidget" name="tab_3">
+       <attribute name="title">
+        <string>Player</string>
+       </attribute>
+       <layout class="QGridLayout" name="gridLayout_4">
+        <item row="0" column="0">
+         <layout class="QHBoxLayout" name="horizontalLayout_2">
+          <item>
+           <widget class="QPushButton" name="pushButtonPlay">
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+            <property name="minimumSize">
+             <size>
+              <width>0</width>
+              <height>0</height>
+             </size>
+            </property>
+            <property name="text">
+             <string>Play</string>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <spacer name="horizontalSpacer_6">
+            <property name="orientation">
+             <enum>Qt::Horizontal</enum>
+            </property>
+            <property name="sizeType">
+             <enum>QSizePolicy::Fixed</enum>
+            </property>
+            <property name="sizeHint" stdset="0">
+             <size>
+              <width>20</width>
+              <height>20</height>
+             </size>
+            </property>
+           </spacer>
+          </item>
+          <item>
+           <widget class="QScrollBar" name="scrollBar">
+            <property name="orientation">
+             <enum>Qt::Horizontal</enum>
+            </property>
+           </widget>
+          </item>
+         </layout>
+        </item>
+       </layout>
+      </widget>
+      <widget class="QWidget" name="tab">
+       <attribute name="title">
+        <string>Viewer</string>
+       </attribute>
+       <layout class="QGridLayout" name="gridLayout_5">
+        <item row="0" column="0">
+         <layout class="QHBoxLayout" name="horizontalLayout">
+          <item>
+           <widget class="QPushButton" name="pushButtonXY">
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+            <property name="minimumSize">
+             <size>
+              <width>20</width>
+              <height>0</height>
+             </size>
+            </property>
+            <property name="text">
+             <string>XY</string>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="QPushButton" name="pushButtonXZ">
+            <property name="text">
+             <string>XZ</string>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="QPushButton" name="pushButtonYZ">
+            <property name="text">
+             <string>YZ</string>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="QPushButton" name="pushButton3D">
+            <property name="text">
+             <string>3D</string>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="QPushButton" name="pushButtonMesh">
+            <property name="text">
+             <string>Mesh</string>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <spacer name="horizontalSpacer_3">
+            <property name="orientation">
+             <enum>Qt::Horizontal</enum>
+            </property>
+            <property name="sizeType">
+             <enum>QSizePolicy::Expanding</enum>
+            </property>
+            <property name="sizeHint" stdset="0">
+             <size>
+              <width>20</width>
+              <height>20</height>
+             </size>
+            </property>
+           </spacer>
+          </item>
+         </layout>
+        </item>
+       </layout>
+      </widget>
+      <widget class="QWidget" name="tab_2">
+       <attribute name="title">
+        <string>Mesh repr.</string>
+       </attribute>
+       <layout class="QGridLayout" name="gridLayout">
+        <item row="0" column="0">
+         <layout class="QHBoxLayout" name="horizontalLayout_4">
+          <item>
+           <widget class="QPushButton" name="pushButtonMeshRepresentation">
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+            <property name="minimumSize">
+             <size>
+              <width>86</width>
+              <height>0</height>
+             </size>
+            </property>
+            <property name="text">
+             <string>Points</string>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="QPushButton" name="pushButtonMeshColor">
+            <property name="enabled">
+             <bool>true</bool>
+            </property>
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+            <property name="minimumSize">
+             <size>
+              <width>20</width>
+              <height>0</height>
+             </size>
+            </property>
+            <property name="baseSize">
+             <size>
+              <width>20</width>
+              <height>0</height>
+             </size>
+            </property>
+            <property name="autoFillBackground">
+             <bool>false</bool>
+            </property>
+            <property name="text">
+             <string>Color Y</string>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="QPushButton" name="pushButtonCutter">
+            <property name="enabled">
+             <bool>true</bool>
+            </property>
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+            <property name="minimumSize">
+             <size>
+              <width>20</width>
+              <height>0</height>
+             </size>
+            </property>
+            <property name="text">
+             <string>Cut off</string>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="QLabel" name="labelMeshOpacity">
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+            <property name="minimumSize">
+             <size>
+              <width>85</width>
+              <height>0</height>
+             </size>
+            </property>
+            <property name="text">
+             <string>Opacity</string>
+            </property>
+            <property name="alignment">
+             <set>Qt::AlignCenter</set>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="QSlider" name="SliderMeshAlpha">
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+            <property name="orientation">
+             <enum>Qt::Horizontal</enum>
+            </property>
+           </widget>
+          </item>
+         </layout>
+        </item>
+       </layout>
+      </widget>
+      <widget class="QWidget" name="tab_4">
+       <attribute name="title">
+        <string>Main axis</string>
+       </attribute>
+       <layout class="QGridLayout" name="gridLayout_6">
+        <item row="0" column="0">
+         <layout class="QHBoxLayout" name="horizontalLayout_3">
+          <item>
+           <widget class="QPushButton" name="pushButtonBasalPoint">
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+            <property name="minimumSize">
+             <size>
+              <width>20</width>
+              <height>0</height>
+             </size>
+            </property>
+            <property name="text">
+             <string>Basal Point</string>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="QPushButton" name="pushButtonApexPoint">
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+            <property name="minimumSize">
+             <size>
+              <width>20</width>
+              <height>0</height>
+             </size>
+            </property>
+            <property name="text">
+             <string>Apex Point</string>
+            </property>
+           </widget>
+          </item>
+         </layout>
+        </item>
+        <item row="0" column="2">
+         <widget class="QPushButton" name="pushButtonReslice">
+          <property name="enabled">
+           <bool>false</bool>
+          </property>
+          <property name="sizePolicy">
+           <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+           </sizepolicy>
+          </property>
+          <property name="minimumSize">
+           <size>
+            <width>20</width>
+            <height>0</height>
+           </size>
+          </property>
+          <property name="text">
+           <string>Reslice</string>
+          </property>
+         </widget>
+        </item>
+        <item row="0" column="3">
+         <spacer name="horizontalSpacer_10">
+          <property name="orientation">
+           <enum>Qt::Horizontal</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>40</width>
+            <height>20</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+        <item row="0" column="1">
+         <spacer name="horizontalSpacer_11">
+          <property name="orientation">
+           <enum>Qt::Horizontal</enum>
+          </property>
+          <property name="sizeType">
+           <enum>QSizePolicy::Fixed</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>40</width>
+            <height>20</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+       </layout>
+      </widget>
+     </widget>
+    </item>
+   </layout>
+  </widget>
+  <action name="actionExit">
+   <property name="text">
+    <string>Exit</string>
+   </property>
+  </action>
+  <action name="actionE_xit">
+   <property name="text">
+    <string>E&amp;xit</string>
+   </property>
+  </action>
+ </widget>
+ <customwidgets>
+  <customwidget>
+   <class>QVTKWidget</class>
+   <extends>QWidget</extends>
+   <header>QVTKWidget.h</header>
+  </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>actionE_xit</sender>
+   <signal>triggered()</signal>
+   <receiver>OpenHeartGui</receiver>
+   <slot>close()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>-1</x>
+     <y>-1</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>220</x>
+     <y>180</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
diff --git a/Applications/qtOpenHeart.cxx b/Applications/qtOpenHeart.cxx
new file mode 100644 (file)
index 0000000..babf6a0
--- /dev/null
@@ -0,0 +1,23 @@
+/**
+* Progam made by Olivier Bernard, associate professor
+* at Institut National des Sciences Appliquees (INSA) Lyon,
+* CREATIS Laboratory,
+* 69621 Villeurbanne, France,
+* 07th of May 2014
+*/
+
+#include <QApplication>
+#include "OpenHeartGui.h"
+
+int main( int argc, char** argv )
+{
+
+  QApplication app(argc, argv);
+
+  OpenHeartGui myViewer;
+  myViewer.show();
+
+  return app.exec();
+
+}
+
diff --git a/Applications/ui_OpenHeartGui.h b/Applications/ui_OpenHeartGui.h
new file mode 100644 (file)
index 0000000..ea7b8b3
--- /dev/null
@@ -0,0 +1,618 @@
+/********************************************************************************
+** Form generated from reading UI file 'OpenHeartGui.ui'
+**
+** Created by: Qt User Interface Compiler version 4.8.5
+**
+** WARNING! All changes made in this file will be lost when recompiling UI file!
+********************************************************************************/
+
+#ifndef UI_OPENHEARTGUI_H
+#define UI_OPENHEARTGUI_H
+
+#include <QtCore/QVariant>
+#include <QtGui/QAction>
+#include <QtGui/QApplication>
+#include <QtGui/QButtonGroup>
+#include <QtGui/QGridLayout>
+#include <QtGui/QHBoxLayout>
+#include <QtGui/QHeaderView>
+#include <QtGui/QLabel>
+#include <QtGui/QMainWindow>
+#include <QtGui/QPushButton>
+#include <QtGui/QScrollBar>
+#include <QtGui/QSlider>
+#include <QtGui/QSpacerItem>
+#include <QtGui/QTabWidget>
+#include <QtGui/QVBoxLayout>
+#include <QtGui/QWidget>
+#include "QVTKWidget.h"
+
+QT_BEGIN_NAMESPACE
+
+class Ui_OpenHeartGui
+{
+public:
+    QAction *actionExit;
+    QAction *actionE_xit;
+    QWidget *centralwidget;
+    QGridLayout *gridLayout_10;
+    QTabWidget *tabWidget;
+    QWidget *tabMesh;
+    QGridLayout *gridLayout_3;
+    QHBoxLayout *horizontalLayout_7;
+    QVBoxLayout *verticalLayoutVisu2D;
+    QWidget *widgetXY;
+    QGridLayout *gridLayout_7;
+    QVTKWidget *qVTKXY;
+    QSpacerItem *verticalSpacer_4;
+    QWidget *widgetXZ;
+    QGridLayout *gridLayout_8;
+    QVTKWidget *qVTKXZ;
+    QSpacerItem *verticalSpacer_5;
+    QWidget *widgetYZ;
+    QGridLayout *gridLayout_9;
+    QVTKWidget *qVTKYZ;
+    QSpacerItem *horizontalSpacer_5;
+    QVBoxLayout *verticalLayoutMesh;
+    QVTKWidget *qVTK;
+    QWidget *tabChart;
+    QGridLayout *gridLayout_2;
+    QVBoxLayout *verticalLayoutChart;
+    QSpacerItem *verticalSpacer_2;
+    QVTKWidget *qVTKChart;
+    QSpacerItem *verticalSpacer;
+    QHBoxLayout *horizontalLayoutEF;
+    QLabel *labelEF;
+    QLabel *labelEFValue;
+    QSpacerItem *horizontalSpacer;
+    QSpacerItem *horizontalSpacer_2;
+    QLabel *labelEDV;
+    QLabel *labelEDVValue;
+    QSpacerItem *horizontalSpacer_8;
+    QHBoxLayout *horizontalLayoutSV;
+    QLabel *labelSV;
+    QLabel *labelSVValue;
+    QSpacerItem *horizontalSpacer_7;
+    QSpacerItem *horizontalSpacer_4;
+    QLabel *labelESV;
+    QLabel *labelESVValue;
+    QSpacerItem *horizontalSpacer_9;
+    QSpacerItem *verticalSpacer_3;
+    QTabWidget *tabWidgetOption;
+    QWidget *tab_3;
+    QGridLayout *gridLayout_4;
+    QHBoxLayout *horizontalLayout_2;
+    QPushButton *pushButtonPlay;
+    QSpacerItem *horizontalSpacer_6;
+    QScrollBar *scrollBar;
+    QWidget *tab;
+    QGridLayout *gridLayout_5;
+    QHBoxLayout *horizontalLayout;
+    QPushButton *pushButtonXY;
+    QPushButton *pushButtonXZ;
+    QPushButton *pushButtonYZ;
+    QPushButton *pushButton3D;
+    QPushButton *pushButtonMesh;
+    QSpacerItem *horizontalSpacer_3;
+    QWidget *tab_2;
+    QGridLayout *gridLayout;
+    QHBoxLayout *horizontalLayout_4;
+    QPushButton *pushButtonMeshRepresentation;
+    QPushButton *pushButtonMeshColor;
+    QPushButton *pushButtonCutter;
+    QLabel *labelMeshOpacity;
+    QSlider *SliderMeshAlpha;
+    QWidget *tab_4;
+    QGridLayout *gridLayout_6;
+    QHBoxLayout *horizontalLayout_3;
+    QPushButton *pushButtonBasalPoint;
+    QPushButton *pushButtonApexPoint;
+    QPushButton *pushButtonReslice;
+    QSpacerItem *horizontalSpacer_10;
+    QSpacerItem *horizontalSpacer_11;
+
+    void setupUi(QMainWindow *OpenHeartGui)
+    {
+        if (OpenHeartGui->objectName().isEmpty())
+            OpenHeartGui->setObjectName(QString::fromUtf8("OpenHeartGui"));
+        OpenHeartGui->resize(773, 696);
+        actionExit = new QAction(OpenHeartGui);
+        actionExit->setObjectName(QString::fromUtf8("actionExit"));
+        actionE_xit = new QAction(OpenHeartGui);
+        actionE_xit->setObjectName(QString::fromUtf8("actionE_xit"));
+        centralwidget = new QWidget(OpenHeartGui);
+        centralwidget->setObjectName(QString::fromUtf8("centralwidget"));
+        gridLayout_10 = new QGridLayout(centralwidget);
+        gridLayout_10->setObjectName(QString::fromUtf8("gridLayout_10"));
+        tabWidget = new QTabWidget(centralwidget);
+        tabWidget->setObjectName(QString::fromUtf8("tabWidget"));
+        tabWidget->setMovable(false);
+        tabMesh = new QWidget();
+        tabMesh->setObjectName(QString::fromUtf8("tabMesh"));
+        gridLayout_3 = new QGridLayout(tabMesh);
+        gridLayout_3->setObjectName(QString::fromUtf8("gridLayout_3"));
+        horizontalLayout_7 = new QHBoxLayout();
+        horizontalLayout_7->setObjectName(QString::fromUtf8("horizontalLayout_7"));
+        verticalLayoutVisu2D = new QVBoxLayout();
+        verticalLayoutVisu2D->setObjectName(QString::fromUtf8("verticalLayoutVisu2D"));
+        widgetXY = new QWidget(tabMesh);
+        widgetXY->setObjectName(QString::fromUtf8("widgetXY"));
+        QSizePolicy sizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+        sizePolicy.setHorizontalStretch(0);
+        sizePolicy.setVerticalStretch(0);
+        sizePolicy.setHeightForWidth(widgetXY->sizePolicy().hasHeightForWidth());
+        widgetXY->setSizePolicy(sizePolicy);
+        widgetXY->setMinimumSize(QSize(200, 155));
+        gridLayout_7 = new QGridLayout(widgetXY);
+        gridLayout_7->setObjectName(QString::fromUtf8("gridLayout_7"));
+        qVTKXY = new QVTKWidget(widgetXY);
+        qVTKXY->setObjectName(QString::fromUtf8("qVTKXY"));
+        QSizePolicy sizePolicy1(QSizePolicy::Expanding, QSizePolicy::Expanding);
+        sizePolicy1.setHorizontalStretch(0);
+        sizePolicy1.setVerticalStretch(0);
+        sizePolicy1.setHeightForWidth(qVTKXY->sizePolicy().hasHeightForWidth());
+        qVTKXY->setSizePolicy(sizePolicy1);
+        qVTKXY->setMinimumSize(QSize(196, 151));
+
+        gridLayout_7->addWidget(qVTKXY, 0, 0, 1, 1);
+
+
+        verticalLayoutVisu2D->addWidget(widgetXY);
+
+        verticalSpacer_4 = new QSpacerItem(20, 10, QSizePolicy::Minimum, QSizePolicy::Fixed);
+
+        verticalLayoutVisu2D->addItem(verticalSpacer_4);
+
+        widgetXZ = new QWidget(tabMesh);
+        widgetXZ->setObjectName(QString::fromUtf8("widgetXZ"));
+        sizePolicy.setHeightForWidth(widgetXZ->sizePolicy().hasHeightForWidth());
+        widgetXZ->setSizePolicy(sizePolicy);
+        widgetXZ->setMinimumSize(QSize(200, 155));
+        gridLayout_8 = new QGridLayout(widgetXZ);
+        gridLayout_8->setObjectName(QString::fromUtf8("gridLayout_8"));
+        qVTKXZ = new QVTKWidget(widgetXZ);
+        qVTKXZ->setObjectName(QString::fromUtf8("qVTKXZ"));
+        QSizePolicy sizePolicy2(QSizePolicy::Preferred, QSizePolicy::Preferred);
+        sizePolicy2.setHorizontalStretch(0);
+        sizePolicy2.setVerticalStretch(0);
+        sizePolicy2.setHeightForWidth(qVTKXZ->sizePolicy().hasHeightForWidth());
+        qVTKXZ->setSizePolicy(sizePolicy2);
+        qVTKXZ->setMinimumSize(QSize(196, 151));
+
+        gridLayout_8->addWidget(qVTKXZ, 0, 0, 1, 1);
+
+
+        verticalLayoutVisu2D->addWidget(widgetXZ);
+
+        verticalSpacer_5 = new QSpacerItem(20, 10, QSizePolicy::Minimum, QSizePolicy::Fixed);
+
+        verticalLayoutVisu2D->addItem(verticalSpacer_5);
+
+        widgetYZ = new QWidget(tabMesh);
+        widgetYZ->setObjectName(QString::fromUtf8("widgetYZ"));
+        sizePolicy.setHeightForWidth(widgetYZ->sizePolicy().hasHeightForWidth());
+        widgetYZ->setSizePolicy(sizePolicy);
+        widgetYZ->setMinimumSize(QSize(200, 155));
+        gridLayout_9 = new QGridLayout(widgetYZ);
+        gridLayout_9->setObjectName(QString::fromUtf8("gridLayout_9"));
+        qVTKYZ = new QVTKWidget(widgetYZ);
+        qVTKYZ->setObjectName(QString::fromUtf8("qVTKYZ"));
+        sizePolicy2.setHeightForWidth(qVTKYZ->sizePolicy().hasHeightForWidth());
+        qVTKYZ->setSizePolicy(sizePolicy2);
+        qVTKYZ->setMinimumSize(QSize(196, 151));
+
+        gridLayout_9->addWidget(qVTKYZ, 0, 0, 1, 1);
+
+
+        verticalLayoutVisu2D->addWidget(widgetYZ);
+
+
+        horizontalLayout_7->addLayout(verticalLayoutVisu2D);
+
+
+        gridLayout_3->addLayout(horizontalLayout_7, 0, 2, 1, 1);
+
+        horizontalSpacer_5 = new QSpacerItem(20, 20, QSizePolicy::Fixed, QSizePolicy::Minimum);
+
+        gridLayout_3->addItem(horizontalSpacer_5, 0, 1, 1, 1);
+
+        verticalLayoutMesh = new QVBoxLayout();
+        verticalLayoutMesh->setObjectName(QString::fromUtf8("verticalLayoutMesh"));
+        qVTK = new QVTKWidget(tabMesh);
+        qVTK->setObjectName(QString::fromUtf8("qVTK"));
+        QSizePolicy sizePolicy3(QSizePolicy::Expanding, QSizePolicy::MinimumExpanding);
+        sizePolicy3.setHorizontalStretch(0);
+        sizePolicy3.setVerticalStretch(0);
+        sizePolicy3.setHeightForWidth(qVTK->sizePolicy().hasHeightForWidth());
+        qVTK->setSizePolicy(sizePolicy3);
+
+        verticalLayoutMesh->addWidget(qVTK);
+
+
+        gridLayout_3->addLayout(verticalLayoutMesh, 0, 0, 1, 1);
+
+        tabWidget->addTab(tabMesh, QString());
+        tabChart = new QWidget();
+        tabChart->setObjectName(QString::fromUtf8("tabChart"));
+        gridLayout_2 = new QGridLayout(tabChart);
+        gridLayout_2->setObjectName(QString::fromUtf8("gridLayout_2"));
+        verticalLayoutChart = new QVBoxLayout();
+        verticalLayoutChart->setObjectName(QString::fromUtf8("verticalLayoutChart"));
+        verticalSpacer_2 = new QSpacerItem(20, 30, QSizePolicy::Minimum, QSizePolicy::Fixed);
+
+        verticalLayoutChart->addItem(verticalSpacer_2);
+
+        qVTKChart = new QVTKWidget(tabChart);
+        qVTKChart->setObjectName(QString::fromUtf8("qVTKChart"));
+        QSizePolicy sizePolicy4(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
+        sizePolicy4.setHorizontalStretch(0);
+        sizePolicy4.setVerticalStretch(0);
+        sizePolicy4.setHeightForWidth(qVTKChart->sizePolicy().hasHeightForWidth());
+        qVTKChart->setSizePolicy(sizePolicy4);
+
+        verticalLayoutChart->addWidget(qVTKChart);
+
+        verticalSpacer = new QSpacerItem(20, 20, QSizePolicy::Minimum, QSizePolicy::Fixed);
+
+        verticalLayoutChart->addItem(verticalSpacer);
+
+        horizontalLayoutEF = new QHBoxLayout();
+        horizontalLayoutEF->setObjectName(QString::fromUtf8("horizontalLayoutEF"));
+        labelEF = new QLabel(tabChart);
+        labelEF->setObjectName(QString::fromUtf8("labelEF"));
+        QSizePolicy sizePolicy5(QSizePolicy::Fixed, QSizePolicy::Preferred);
+        sizePolicy5.setHorizontalStretch(0);
+        sizePolicy5.setVerticalStretch(0);
+        sizePolicy5.setHeightForWidth(labelEF->sizePolicy().hasHeightForWidth());
+        labelEF->setSizePolicy(sizePolicy5);
+
+        horizontalLayoutEF->addWidget(labelEF);
+
+        labelEFValue = new QLabel(tabChart);
+        labelEFValue->setObjectName(QString::fromUtf8("labelEFValue"));
+        sizePolicy5.setHeightForWidth(labelEFValue->sizePolicy().hasHeightForWidth());
+        labelEFValue->setSizePolicy(sizePolicy5);
+        labelEFValue->setMinimumSize(QSize(40, 0));
+
+        horizontalLayoutEF->addWidget(labelEFValue);
+
+        horizontalSpacer = new QSpacerItem(20, 20, QSizePolicy::Fixed, QSizePolicy::Minimum);
+
+        horizontalLayoutEF->addItem(horizontalSpacer);
+
+        horizontalSpacer_2 = new QSpacerItem(40, 20, QSizePolicy::Fixed, QSizePolicy::Minimum);
+
+        horizontalLayoutEF->addItem(horizontalSpacer_2);
+
+        labelEDV = new QLabel(tabChart);
+        labelEDV->setObjectName(QString::fromUtf8("labelEDV"));
+        sizePolicy5.setHeightForWidth(labelEDV->sizePolicy().hasHeightForWidth());
+        labelEDV->setSizePolicy(sizePolicy5);
+
+        horizontalLayoutEF->addWidget(labelEDV);
+
+        labelEDVValue = new QLabel(tabChart);
+        labelEDVValue->setObjectName(QString::fromUtf8("labelEDVValue"));
+        sizePolicy5.setHeightForWidth(labelEDVValue->sizePolicy().hasHeightForWidth());
+        labelEDVValue->setSizePolicy(sizePolicy5);
+        labelEDVValue->setMinimumSize(QSize(40, 0));
+
+        horizontalLayoutEF->addWidget(labelEDVValue);
+
+        horizontalSpacer_8 = new QSpacerItem(20, 20, QSizePolicy::Fixed, QSizePolicy::Minimum);
+
+        horizontalLayoutEF->addItem(horizontalSpacer_8);
+
+
+        verticalLayoutChart->addLayout(horizontalLayoutEF);
+
+        horizontalLayoutSV = new QHBoxLayout();
+        horizontalLayoutSV->setObjectName(QString::fromUtf8("horizontalLayoutSV"));
+        labelSV = new QLabel(tabChart);
+        labelSV->setObjectName(QString::fromUtf8("labelSV"));
+        sizePolicy5.setHeightForWidth(labelSV->sizePolicy().hasHeightForWidth());
+        labelSV->setSizePolicy(sizePolicy5);
+        labelSV->setMinimumSize(QSize(0, 0));
+
+        horizontalLayoutSV->addWidget(labelSV);
+
+        labelSVValue = new QLabel(tabChart);
+        labelSVValue->setObjectName(QString::fromUtf8("labelSVValue"));
+        sizePolicy5.setHeightForWidth(labelSVValue->sizePolicy().hasHeightForWidth());
+        labelSVValue->setSizePolicy(sizePolicy5);
+        labelSVValue->setMinimumSize(QSize(40, 0));
+
+        horizontalLayoutSV->addWidget(labelSVValue);
+
+        horizontalSpacer_7 = new QSpacerItem(20, 20, QSizePolicy::Fixed, QSizePolicy::Minimum);
+
+        horizontalLayoutSV->addItem(horizontalSpacer_7);
+
+        horizontalSpacer_4 = new QSpacerItem(40, 20, QSizePolicy::Fixed, QSizePolicy::Minimum);
+
+        horizontalLayoutSV->addItem(horizontalSpacer_4);
+
+        labelESV = new QLabel(tabChart);
+        labelESV->setObjectName(QString::fromUtf8("labelESV"));
+        sizePolicy5.setHeightForWidth(labelESV->sizePolicy().hasHeightForWidth());
+        labelESV->setSizePolicy(sizePolicy5);
+
+        horizontalLayoutSV->addWidget(labelESV);
+
+        labelESVValue = new QLabel(tabChart);
+        labelESVValue->setObjectName(QString::fromUtf8("labelESVValue"));
+        sizePolicy5.setHeightForWidth(labelESVValue->sizePolicy().hasHeightForWidth());
+        labelESVValue->setSizePolicy(sizePolicy5);
+        labelESVValue->setMinimumSize(QSize(40, 0));
+
+        horizontalLayoutSV->addWidget(labelESVValue);
+
+        horizontalSpacer_9 = new QSpacerItem(23, 20, QSizePolicy::Fixed, QSizePolicy::Minimum);
+
+        horizontalLayoutSV->addItem(horizontalSpacer_9);
+
+
+        verticalLayoutChart->addLayout(horizontalLayoutSV);
+
+        verticalSpacer_3 = new QSpacerItem(20, 30, QSizePolicy::Minimum, QSizePolicy::Fixed);
+
+        verticalLayoutChart->addItem(verticalSpacer_3);
+
+
+        gridLayout_2->addLayout(verticalLayoutChart, 0, 0, 1, 1);
+
+        tabWidget->addTab(tabChart, QString());
+
+        gridLayout_10->addWidget(tabWidget, 0, 0, 1, 1);
+
+        tabWidgetOption = new QTabWidget(centralwidget);
+        tabWidgetOption->setObjectName(QString::fromUtf8("tabWidgetOption"));
+        QSizePolicy sizePolicy6(QSizePolicy::Expanding, QSizePolicy::Fixed);
+        sizePolicy6.setHorizontalStretch(0);
+        sizePolicy6.setVerticalStretch(0);
+        sizePolicy6.setHeightForWidth(tabWidgetOption->sizePolicy().hasHeightForWidth());
+        tabWidgetOption->setSizePolicy(sizePolicy6);
+        QPalette palette;
+        QBrush brush(QColor(85, 255, 255, 255));
+        brush.setStyle(Qt::SolidPattern);
+        palette.setBrush(QPalette::Active, QPalette::Base, brush);
+        QBrush brush1(QColor(170, 255, 255, 255));
+        brush1.setStyle(Qt::SolidPattern);
+        palette.setBrush(QPalette::Active, QPalette::NoRole, brush1);
+        palette.setBrush(QPalette::Inactive, QPalette::Base, brush);
+        palette.setBrush(QPalette::Inactive, QPalette::NoRole, brush1);
+        QBrush brush2(QColor(255, 255, 255, 255));
+        brush2.setStyle(Qt::SolidPattern);
+        palette.setBrush(QPalette::Disabled, QPalette::Base, brush2);
+        palette.setBrush(QPalette::Disabled, QPalette::NoRole, brush1);
+        tabWidgetOption->setPalette(palette);
+        tabWidgetOption->setTabPosition(QTabWidget::North);
+        tabWidgetOption->setTabShape(QTabWidget::Rounded);
+        tabWidgetOption->setElideMode(Qt::ElideNone);
+        tabWidgetOption->setTabsClosable(false);
+        tab_3 = new QWidget();
+        tab_3->setObjectName(QString::fromUtf8("tab_3"));
+        gridLayout_4 = new QGridLayout(tab_3);
+        gridLayout_4->setObjectName(QString::fromUtf8("gridLayout_4"));
+        horizontalLayout_2 = new QHBoxLayout();
+        horizontalLayout_2->setObjectName(QString::fromUtf8("horizontalLayout_2"));
+        pushButtonPlay = new QPushButton(tab_3);
+        pushButtonPlay->setObjectName(QString::fromUtf8("pushButtonPlay"));
+        sizePolicy.setHeightForWidth(pushButtonPlay->sizePolicy().hasHeightForWidth());
+        pushButtonPlay->setSizePolicy(sizePolicy);
+        pushButtonPlay->setMinimumSize(QSize(0, 0));
+
+        horizontalLayout_2->addWidget(pushButtonPlay);
+
+        horizontalSpacer_6 = new QSpacerItem(20, 20, QSizePolicy::Fixed, QSizePolicy::Minimum);
+
+        horizontalLayout_2->addItem(horizontalSpacer_6);
+
+        scrollBar = new QScrollBar(tab_3);
+        scrollBar->setObjectName(QString::fromUtf8("scrollBar"));
+        scrollBar->setOrientation(Qt::Horizontal);
+
+        horizontalLayout_2->addWidget(scrollBar);
+
+
+        gridLayout_4->addLayout(horizontalLayout_2, 0, 0, 1, 1);
+
+        tabWidgetOption->addTab(tab_3, QString());
+        tab = new QWidget();
+        tab->setObjectName(QString::fromUtf8("tab"));
+        gridLayout_5 = new QGridLayout(tab);
+        gridLayout_5->setObjectName(QString::fromUtf8("gridLayout_5"));
+        horizontalLayout = new QHBoxLayout();
+        horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout"));
+        pushButtonXY = new QPushButton(tab);
+        pushButtonXY->setObjectName(QString::fromUtf8("pushButtonXY"));
+        sizePolicy.setHeightForWidth(pushButtonXY->sizePolicy().hasHeightForWidth());
+        pushButtonXY->setSizePolicy(sizePolicy);
+        pushButtonXY->setMinimumSize(QSize(20, 0));
+
+        horizontalLayout->addWidget(pushButtonXY);
+
+        pushButtonXZ = new QPushButton(tab);
+        pushButtonXZ->setObjectName(QString::fromUtf8("pushButtonXZ"));
+
+        horizontalLayout->addWidget(pushButtonXZ);
+
+        pushButtonYZ = new QPushButton(tab);
+        pushButtonYZ->setObjectName(QString::fromUtf8("pushButtonYZ"));
+
+        horizontalLayout->addWidget(pushButtonYZ);
+
+        pushButton3D = new QPushButton(tab);
+        pushButton3D->setObjectName(QString::fromUtf8("pushButton3D"));
+
+        horizontalLayout->addWidget(pushButton3D);
+
+        pushButtonMesh = new QPushButton(tab);
+        pushButtonMesh->setObjectName(QString::fromUtf8("pushButtonMesh"));
+
+        horizontalLayout->addWidget(pushButtonMesh);
+
+        horizontalSpacer_3 = new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+
+        horizontalLayout->addItem(horizontalSpacer_3);
+
+
+        gridLayout_5->addLayout(horizontalLayout, 0, 0, 1, 1);
+
+        tabWidgetOption->addTab(tab, QString());
+        tab_2 = new QWidget();
+        tab_2->setObjectName(QString::fromUtf8("tab_2"));
+        gridLayout = new QGridLayout(tab_2);
+        gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
+        horizontalLayout_4 = new QHBoxLayout();
+        horizontalLayout_4->setObjectName(QString::fromUtf8("horizontalLayout_4"));
+        pushButtonMeshRepresentation = new QPushButton(tab_2);
+        pushButtonMeshRepresentation->setObjectName(QString::fromUtf8("pushButtonMeshRepresentation"));
+        sizePolicy.setHeightForWidth(pushButtonMeshRepresentation->sizePolicy().hasHeightForWidth());
+        pushButtonMeshRepresentation->setSizePolicy(sizePolicy);
+        pushButtonMeshRepresentation->setMinimumSize(QSize(86, 0));
+
+        horizontalLayout_4->addWidget(pushButtonMeshRepresentation);
+
+        pushButtonMeshColor = new QPushButton(tab_2);
+        pushButtonMeshColor->setObjectName(QString::fromUtf8("pushButtonMeshColor"));
+        pushButtonMeshColor->setEnabled(true);
+        sizePolicy.setHeightForWidth(pushButtonMeshColor->sizePolicy().hasHeightForWidth());
+        pushButtonMeshColor->setSizePolicy(sizePolicy);
+        pushButtonMeshColor->setMinimumSize(QSize(20, 0));
+        pushButtonMeshColor->setBaseSize(QSize(20, 0));
+        pushButtonMeshColor->setAutoFillBackground(false);
+
+        horizontalLayout_4->addWidget(pushButtonMeshColor);
+
+        pushButtonCutter = new QPushButton(tab_2);
+        pushButtonCutter->setObjectName(QString::fromUtf8("pushButtonCutter"));
+        pushButtonCutter->setEnabled(true);
+        sizePolicy.setHeightForWidth(pushButtonCutter->sizePolicy().hasHeightForWidth());
+        pushButtonCutter->setSizePolicy(sizePolicy);
+        pushButtonCutter->setMinimumSize(QSize(20, 0));
+
+        horizontalLayout_4->addWidget(pushButtonCutter);
+
+        labelMeshOpacity = new QLabel(tab_2);
+        labelMeshOpacity->setObjectName(QString::fromUtf8("labelMeshOpacity"));
+        sizePolicy.setHeightForWidth(labelMeshOpacity->sizePolicy().hasHeightForWidth());
+        labelMeshOpacity->setSizePolicy(sizePolicy);
+        labelMeshOpacity->setMinimumSize(QSize(85, 0));
+        labelMeshOpacity->setAlignment(Qt::AlignCenter);
+
+        horizontalLayout_4->addWidget(labelMeshOpacity);
+
+        SliderMeshAlpha = new QSlider(tab_2);
+        SliderMeshAlpha->setObjectName(QString::fromUtf8("SliderMeshAlpha"));
+        sizePolicy6.setHeightForWidth(SliderMeshAlpha->sizePolicy().hasHeightForWidth());
+        SliderMeshAlpha->setSizePolicy(sizePolicy6);
+        SliderMeshAlpha->setOrientation(Qt::Horizontal);
+
+        horizontalLayout_4->addWidget(SliderMeshAlpha);
+
+
+        gridLayout->addLayout(horizontalLayout_4, 0, 0, 1, 1);
+
+        tabWidgetOption->addTab(tab_2, QString());
+        tab_4 = new QWidget();
+        tab_4->setObjectName(QString::fromUtf8("tab_4"));
+        gridLayout_6 = new QGridLayout(tab_4);
+        gridLayout_6->setObjectName(QString::fromUtf8("gridLayout_6"));
+        horizontalLayout_3 = new QHBoxLayout();
+        horizontalLayout_3->setObjectName(QString::fromUtf8("horizontalLayout_3"));
+        pushButtonBasalPoint = new QPushButton(tab_4);
+        pushButtonBasalPoint->setObjectName(QString::fromUtf8("pushButtonBasalPoint"));
+        sizePolicy.setHeightForWidth(pushButtonBasalPoint->sizePolicy().hasHeightForWidth());
+        pushButtonBasalPoint->setSizePolicy(sizePolicy);
+        pushButtonBasalPoint->setMinimumSize(QSize(20, 0));
+
+        horizontalLayout_3->addWidget(pushButtonBasalPoint);
+
+        pushButtonApexPoint = new QPushButton(tab_4);
+        pushButtonApexPoint->setObjectName(QString::fromUtf8("pushButtonApexPoint"));
+        sizePolicy.setHeightForWidth(pushButtonApexPoint->sizePolicy().hasHeightForWidth());
+        pushButtonApexPoint->setSizePolicy(sizePolicy);
+        pushButtonApexPoint->setMinimumSize(QSize(20, 0));
+
+        horizontalLayout_3->addWidget(pushButtonApexPoint);
+
+
+        gridLayout_6->addLayout(horizontalLayout_3, 0, 0, 1, 1);
+
+        pushButtonReslice = new QPushButton(tab_4);
+        pushButtonReslice->setObjectName(QString::fromUtf8("pushButtonReslice"));
+        pushButtonReslice->setEnabled(false);
+        sizePolicy.setHeightForWidth(pushButtonReslice->sizePolicy().hasHeightForWidth());
+        pushButtonReslice->setSizePolicy(sizePolicy);
+        pushButtonReslice->setMinimumSize(QSize(20, 0));
+
+        gridLayout_6->addWidget(pushButtonReslice, 0, 2, 1, 1);
+
+        horizontalSpacer_10 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+
+        gridLayout_6->addItem(horizontalSpacer_10, 0, 3, 1, 1);
+
+        horizontalSpacer_11 = new QSpacerItem(40, 20, QSizePolicy::Fixed, QSizePolicy::Minimum);
+
+        gridLayout_6->addItem(horizontalSpacer_11, 0, 1, 1, 1);
+
+        tabWidgetOption->addTab(tab_4, QString());
+
+        gridLayout_10->addWidget(tabWidgetOption, 1, 0, 1, 1);
+
+        OpenHeartGui->setCentralWidget(centralwidget);
+
+        retranslateUi(OpenHeartGui);
+        QObject::connect(actionE_xit, SIGNAL(triggered()), OpenHeartGui, SLOT(close()));
+
+        tabWidget->setCurrentIndex(0);
+        tabWidgetOption->setCurrentIndex(0);
+
+
+        QMetaObject::connectSlotsByName(OpenHeartGui);
+    } // setupUi
+
+    void retranslateUi(QMainWindow *OpenHeartGui)
+    {
+        OpenHeartGui->setWindowTitle(QApplication::translate("OpenHeartGui", "OpenHeart GUI", 0, QApplication::UnicodeUTF8));
+        actionExit->setText(QApplication::translate("OpenHeartGui", "Exit", 0, QApplication::UnicodeUTF8));
+        actionE_xit->setText(QApplication::translate("OpenHeartGui", "E&xit", 0, QApplication::UnicodeUTF8));
+        tabWidget->setTabText(tabWidget->indexOf(tabMesh), QApplication::translate("OpenHeartGui", "Space", 0, QApplication::UnicodeUTF8));
+        labelEF->setText(QApplication::translate("OpenHeartGui", "Ejection Fraction", 0, QApplication::UnicodeUTF8));
+        labelEFValue->setText(QString());
+        labelEDV->setText(QApplication::translate("OpenHeartGui", "EDV", 0, QApplication::UnicodeUTF8));
+        labelEDVValue->setText(QString());
+        labelSV->setText(QApplication::translate("OpenHeartGui", "Stroke volume      ", 0, QApplication::UnicodeUTF8));
+        labelSVValue->setText(QString());
+        labelESV->setText(QApplication::translate("OpenHeartGui", "ESV", 0, QApplication::UnicodeUTF8));
+        labelESVValue->setText(QString());
+        tabWidget->setTabText(tabWidget->indexOf(tabChart), QApplication::translate("OpenHeartGui", "Chart", 0, QApplication::UnicodeUTF8));
+        pushButtonPlay->setText(QApplication::translate("OpenHeartGui", "Play", 0, QApplication::UnicodeUTF8));
+        tabWidgetOption->setTabText(tabWidgetOption->indexOf(tab_3), QApplication::translate("OpenHeartGui", "Player", 0, QApplication::UnicodeUTF8));
+        pushButtonXY->setText(QApplication::translate("OpenHeartGui", "XY", 0, QApplication::UnicodeUTF8));
+        pushButtonXZ->setText(QApplication::translate("OpenHeartGui", "XZ", 0, QApplication::UnicodeUTF8));
+        pushButtonYZ->setText(QApplication::translate("OpenHeartGui", "YZ", 0, QApplication::UnicodeUTF8));
+        pushButton3D->setText(QApplication::translate("OpenHeartGui", "3D", 0, QApplication::UnicodeUTF8));
+        pushButtonMesh->setText(QApplication::translate("OpenHeartGui", "Mesh", 0, QApplication::UnicodeUTF8));
+        tabWidgetOption->setTabText(tabWidgetOption->indexOf(tab), QApplication::translate("OpenHeartGui", "Viewer", 0, QApplication::UnicodeUTF8));
+        pushButtonMeshRepresentation->setText(QApplication::translate("OpenHeartGui", "Points", 0, QApplication::UnicodeUTF8));
+        pushButtonMeshColor->setText(QApplication::translate("OpenHeartGui", "Color Y", 0, QApplication::UnicodeUTF8));
+        pushButtonCutter->setText(QApplication::translate("OpenHeartGui", "Cut off", 0, QApplication::UnicodeUTF8));
+        labelMeshOpacity->setText(QApplication::translate("OpenHeartGui", "Opacity", 0, QApplication::UnicodeUTF8));
+        tabWidgetOption->setTabText(tabWidgetOption->indexOf(tab_2), QApplication::translate("OpenHeartGui", "Mesh repr.", 0, QApplication::UnicodeUTF8));
+        pushButtonBasalPoint->setText(QApplication::translate("OpenHeartGui", "Basal Point", 0, QApplication::UnicodeUTF8));
+        pushButtonApexPoint->setText(QApplication::translate("OpenHeartGui", "Apex Point", 0, QApplication::UnicodeUTF8));
+        pushButtonReslice->setText(QApplication::translate("OpenHeartGui", "Reslice", 0, QApplication::UnicodeUTF8));
+        tabWidgetOption->setTabText(tabWidgetOption->indexOf(tab_4), QApplication::translate("OpenHeartGui", "Main axis", 0, QApplication::UnicodeUTF8));
+    } // retranslateUi
+
+};
+
+namespace Ui {
+    class OpenHeartGui: public Ui_OpenHeartGui {};
+} // namespace Ui
+
+QT_END_NAMESPACE
+
+#endif // UI_OPENHEARTGUI_H
diff --git a/Applications/vtkMyInteractorStyleTrackballCameraOpenHeart.cxx b/Applications/vtkMyInteractorStyleTrackballCameraOpenHeart.cxx
new file mode 100644 (file)
index 0000000..d7e031b
--- /dev/null
@@ -0,0 +1,852 @@
+/**
+* Progam made by Olivier Bernard, associate professor
+* at Institut National des Sciences Appliquees (INSA) Lyon,
+* CREATIS-LRMN Laboratory,
+* 69621 Villeurbanne, France,
+* 20th of May 2014
+*/
+
+#include <vtkRenderer.h>
+#include <vtkRenderWindow.h>
+#include "vtkMyInteractorStyleTrackballCameraOpenHeart.h"
+
+
+using namespace std;
+
+
+void vtkMyInteractorStyleTrackballCameraOpenHeart::OnChar()
+{
+    vtkRenderWindowInteractor *rwi = this->Interactor;
+    switch (rwi->GetKeyCode())
+    {
+    case 'f':
+    {
+        int val = this->window->GetCurrentFrame();
+        if ( val < (this->window->GetNumberOfFrames()-1) )
+            this->window->scrollBar->setSliderPosition(val+1);
+        else {
+            this->window->SetFlagLoopEndToBegin(1);
+            this->window->scrollBar->setSliderPosition(0);
+        }
+        break;
+    }
+    case 'b':
+    {
+        int val = this->window->GetCurrentFrame();
+        if ( val > 0 )
+            this->window->scrollBar->setSliderPosition(val-1);
+        else {
+            this->window->SetFlagLoopBeginToEnd(1);
+            this->window->scrollBar->setSliderPosition(this->window->GetNumberOfFrames()-1);
+        }
+        break;
+    }
+    case 'o':
+    {
+        /// Deal with the display of a mask overlayed on the volume data
+        this->window->InterpolationManagement();
+        break;
+    }
+    case 'm':
+    {
+        /// Reset the sphere display
+        this->window->DisplayMeshManagement();
+        break;
+    }
+    case 'd':
+    {
+        /// Set the display mode
+        this->window->DisplayModeManagement();
+        break;
+    }
+    case 'h':
+    {
+        this->window->HidePlanModeManagement();
+        break;
+    }
+    case 'a':
+    {
+        this->window->DisplayMainAxisManagement();
+    }
+    default:
+        cout << "";
+    }
+
+}
+
+
+void vtkMyInteractorStyleTrackballCameraOpenHeart::OnMouseWheelForward()
+{
+
+    switch ( this->window->GetSelectedButton() ) {
+
+    case 1 :
+        this->MoveForwardYZPlan();
+        break;
+
+    case 2:
+
+        this->MoveForwardXZPlan();
+        break;
+
+    case 3:
+
+        this->MoveForwardXYPlan();
+        break;
+
+    default:
+
+        this->MoveForward();
+
+    }
+
+}
+
+
+void vtkMyInteractorStyleTrackballCameraOpenHeart::OnMouseWheelBackward()
+{
+
+    switch ( this->window->GetSelectedButton() )
+    {
+
+        case 1 :
+            this->MoveBackwardYZPlan();
+            break;
+
+        case 2:
+
+            this->MoveBackwardXZPlan();
+            break;
+
+        case 3:
+
+            this->MoveBackwardXYPlan();
+            break;
+
+        default:
+
+            this->MoveBackward();
+
+    }
+
+}
+
+
+void vtkMyInteractorStyleTrackballCameraOpenHeart::MoveForward()
+{
+
+    /// Get picker position
+    double pos[3];
+    this->GetPickerPosition(pos);
+
+    /// Go back to the initial coordinate system before reslicing
+    double posXYZ[3];
+    for (int i=0; i<3; i++)
+        posXYZ[i] = pos[i];
+    this->window->ComputePointBeforeRotation(posXYZ);
+
+    /// Compute point of interest for checking which plan is selected
+    double RefX[3];
+    for (int i=0; i<3; i++)
+        RefX[i] = this->window->GetRendererProperties()->xIPW->GetCenter()[i];
+    this->window->ComputePointBeforeRotation(RefX);
+    double RefY[3];
+    for (int i=0; i<3; i++)
+        RefY[i] = this->window->GetRendererProperties()->yIPW->GetCenter()[i];
+    this->window->ComputePointBeforeRotation(RefY);
+    double RefZ[3];
+    for (int i=0; i<3; i++)
+        RefZ[i] = this->window->GetRendererProperties()->zIPW->GetCenter()[i];
+    this->window->ComputePointBeforeRotation(RefZ);
+
+    /// Update Slice image
+    if ( this->IsInside(posXYZ) )
+    {
+
+        if ( fabs(posXYZ[0]-RefX[0]) < this->PadSliceDetection[0] )
+        {
+
+            /// Compute corresponding step
+            if ( (posXYZ[1] >= this->Limits[2] ) &&
+                 (posXYZ[1] <= this->Limits[3] ) &&
+                 (posXYZ[2] >= this->Limits[4] ) &&
+                 (posXYZ[2] <= this->Limits[5] ) )
+                this->Step = 1;
+            else
+                this->Step = 5;
+
+            /// Compute new slice position
+            double limit = this->Bounds[1];
+            posXYZ[0] += this->Step * this->SpacingImg[0];
+            if ( posXYZ[0] <= limit )
+                this->window->GetRendererProperties()->position[0] += this->Step * this->SpacingImg[0];
+
+            /// Update Slice text
+            if ( this->window->GetFlagDisplayText() )
+            {
+                int slice = (int)( (this->window->GetRendererProperties()->position[0] -
+                                    this->OriginImg[0]) /
+                                    this->SpacingImg[0] + 0.5f );
+                QString strSlice;
+                strSlice.sprintf("Slice: %d",slice);
+                this->window->GetRendererProperties()->TextMapperSlice->SetInput(strSlice.toStdString().c_str());
+            }
+
+            /// Update renderers
+            this->window->GetRendererProperties()->xIPW->SetSlicePosition(this->window->GetRendererProperties()->position[0]);
+            this->window->GetRendererProperties()->yzIPW->SetSlicePosition(this->window->GetRendererProperties()->position[0]);
+            this->window->GetRenderWindow()->Render();
+            this->window->GetYZRenderer()->ResetCameraClippingRange();
+            this->window->GetRenderWindowYZ()->Render();
+        }
+
+        if ( fabs(posXYZ[1]-RefY[1]) < this->PadSliceDetection[1] )
+        {
+
+            /// Compute corresponding step
+            if ( (posXYZ[0] >= this->Limits[0] ) &&
+                 (posXYZ[0] <= this->Limits[1] ) &&
+                 (posXYZ[2] >= this->Limits[4] ) &&
+                 (posXYZ[2] <= this->Limits[5] ) )
+                this->Step = 1;
+            else
+                this->Step = 5;
+
+            /// Compute new slice position
+            double limit = this->Bounds[3];
+            posXYZ[1] += this->Step * this->SpacingImg[1];
+            if ( posXYZ[1] <= limit )
+                this->window->GetRendererProperties()->position[1] += this->Step * this->SpacingImg[1];
+
+            /// Update Slice text
+            if ( this->window->GetFlagDisplayText() )
+            {
+                int slice = (int)( (this->window->GetRendererProperties()->position[1] -
+                                    this->OriginImg[1]) /
+                                    this->SpacingImg[1] + 0.5f );
+                QString strSlice;
+                strSlice.sprintf("Slice: %d",slice);
+                this->window->GetRendererProperties()->TextMapperSlice->SetInput(strSlice.toStdString().c_str());
+            }
+
+            /// Update renderers
+            this->window->GetRendererProperties()->yIPW->SetSlicePosition(this->window->GetRendererProperties()->position[1]);
+            this->window->GetRendererProperties()->xzIPW->SetSlicePosition(this->window->GetRendererProperties()->position[1]);
+            this->window->GetRenderWindow()->Render();
+            this->window->GetXZRenderer()->ResetCameraClippingRange();
+            this->window->GetRenderWindowXZ()->Render();
+        }
+
+        if ( fabs(posXYZ[2]-RefZ[2]) < this->PadSliceDetection[2] )
+        {
+
+            /// Compute corresponding step
+            if ( (posXYZ[0] >= this->Limits[0] ) &&
+                 (posXYZ[0] <= this->Limits[1] ) &&
+                 (posXYZ[1] >= this->Limits[2] ) &&
+                 (posXYZ[1] <= this->Limits[3] ) )
+                this->Step = 1;
+            else
+                this->Step = 5;
+
+            /// Compute new slice position
+            double limit = this->Bounds[5];
+            posXYZ[2] += this->Step * this->SpacingImg[2];
+            if ( posXYZ[2] <= limit )
+                this->window->GetRendererProperties()->position[2] += this->Step * this->SpacingImg[2];
+
+            /// Update Slice text
+            if ( this->window->GetFlagDisplayText() )
+            {
+                int slice = (int)( (this->window->GetRendererProperties()->position[2] -
+                                    this->OriginImg[2]) /
+                                    this->SpacingImg[2] + 0.5f );
+                QString strSlice;
+                strSlice.sprintf("Slice: %d",slice);
+                this->window->GetRendererProperties()->TextMapperSlice->SetInput(strSlice.toStdString().c_str());
+            }
+
+            /// Update renderers
+            this->window->GetRendererProperties()->zIPW->SetSlicePosition(this->window->GetRendererProperties()->position[2]);
+            this->window->GetRendererProperties()->xyIPW->SetSlicePosition(this->window->GetRendererProperties()->position[2]);
+            this->window->GetRenderWindow()->Render();
+            this->window->GetXYRenderer()->ResetCameraClippingRange();
+            this->window->GetRenderWindowXY()->Render();
+        }
+
+    }
+
+    /// Update text display
+    this->window->UpdateCoords(pos);
+
+}
+
+
+void vtkMyInteractorStyleTrackballCameraOpenHeart::MoveForwardXYPlan()
+{
+
+    /// Get picker position
+    double pos[3];
+    this->GetPickerPosition(pos);
+
+    /// Go back to the initial coordinate system before reslicing
+    double posXYZ[3];
+    for (int i=0; i<3; i++)
+        posXYZ[i] = pos[i];
+    this->window->ComputePointBeforeRotation(posXYZ);
+
+    /// Update Slice image
+    if ( this->IsInside(posXYZ) )
+    {
+        /// Compute corresponding step
+        if ( (posXYZ[0] >= this->Limits[0] ) &&
+             (posXYZ[0] <= this->Limits[1] ) &&
+             (posXYZ[1] >= this->Limits[2] ) &&
+             (posXYZ[1] <= this->Limits[3] ) )
+            this->Step = 1;
+        else
+            this->Step = 5;
+
+        /// Compute new slice position
+        double limit = this->Bounds[5];
+        posXYZ[2] += this->Step * this->window->GetCurrentImageData()->GetSpacing()[2];
+        if ( posXYZ[2] <= limit )
+            this->window->GetRendererProperties()->position[2] += this->Step * this->window->GetCurrentImageData()->GetSpacing()[2];
+
+        /// Update Slice text
+        if ( this->window->GetFlagDisplayText() )
+        {
+            int slice = (int)( (this->window->GetRendererProperties()->position[2] -
+                                this->window->GetCurrentImageData()->GetOrigin()[2]) /
+                                this->window->GetCurrentImageData()->GetSpacing()[2] + 0.5f );
+            QString strSlice;
+            strSlice.sprintf("Slice: %d",slice);
+            this->window->GetRendererProperties()->TextMapperSlice->SetInput(strSlice.toStdString().c_str());
+        }
+
+        /// Update renderers
+        this->window->GetRendererProperties()->zIPW->SetSlicePosition(this->window->GetRendererProperties()->position[2]);
+        this->window->GetRendererProperties()->xyIPW->SetSlicePosition(this->window->GetRendererProperties()->position[2]);
+        this->window->GetRenderWindow()->Render();
+        this->window->GetXYRenderer()->ResetCameraClippingRange();
+        this->window->GetRenderWindowXY()->Render();
+
+    }
+
+}
+
+
+void vtkMyInteractorStyleTrackballCameraOpenHeart::MoveForwardXZPlan()
+{
+
+    /// Get picker position
+    double pos[3];
+    this->GetPickerPosition(pos);
+
+    /// Go back to the initial coordinate system before reslicing
+    double posXYZ[3];
+    for (int i=0; i<3; i++)
+        posXYZ[i] = pos[i];
+    this->window->ComputePointBeforeRotation(posXYZ);
+
+    /// Update Slice image
+    if ( this->IsInside(posXYZ) )
+    {
+        /// Compute corresponding step
+        if ( (posXYZ[0] >= this->Limits[0] ) &&
+             (posXYZ[0] <= this->Limits[1] ) &&
+             (posXYZ[2] >= this->Limits[4] ) &&
+             (posXYZ[2] <= this->Limits[5] ) )
+            this->Step = 1;
+        else
+            this->Step = 5;
+
+        /// Compute new slice position
+        double limit = this->Bounds[3];
+        posXYZ[1] += this->Step * this->window->GetCurrentImageData()->GetSpacing()[1];
+        if ( posXYZ[1] <= limit )
+            this->window->GetRendererProperties()->position[1] += this->Step * this->window->GetCurrentImageData()->GetSpacing()[1];
+
+        /// Update Slice text
+        if ( this->window->GetFlagDisplayText() )
+        {
+            int slice = (int)( (this->window->GetRendererProperties()->position[1] -
+                                this->window->GetCurrentImageData()->GetOrigin()[1]) /
+                                this->window->GetCurrentImageData()->GetSpacing()[1] + 0.5f );
+            QString strSlice;
+            strSlice.sprintf("Slice: %d",slice);
+            this->window->GetRendererProperties()->TextMapperSlice->SetInput(strSlice.toStdString().c_str());
+        }
+
+        /// Update renderers
+        this->window->GetRendererProperties()->yIPW->SetSlicePosition(this->window->GetRendererProperties()->position[1]);
+        this->window->GetRendererProperties()->xzIPW->SetSlicePosition(this->window->GetRendererProperties()->position[1]);
+        this->window->GetRenderWindow()->Render();
+        this->window->GetXZRenderer()->ResetCameraClippingRange();
+        this->window->GetRenderWindowXZ()->Render();
+
+    }
+
+}
+
+
+void vtkMyInteractorStyleTrackballCameraOpenHeart::MoveForwardYZPlan()
+{
+
+    /// Get picker position
+    double pos[3];
+    this->GetPickerPosition(pos);
+
+    /// Go back to the initial coordinate system before reslicing
+    double posXYZ[3];
+    for (int i=0; i<3; i++)
+        posXYZ[i] = pos[i];
+    this->window->ComputePointBeforeRotation(posXYZ);
+
+    /// Update Slice image
+    if ( this->IsInside(posXYZ) )
+    {
+        /// Compute corresponding step
+        if ( (posXYZ[1] >= this->Limits[2] ) &&
+             (posXYZ[1] <= this->Limits[3] ) &&
+             (posXYZ[2] >= this->Limits[4] ) &&
+             (posXYZ[2] <= this->Limits[5] ) )
+            this->Step = 1;
+        else
+            this->Step = 5;
+
+        /// Compute new slice position
+        double limit = this->Bounds[1];
+        posXYZ[0] += this->Step * this->window->GetCurrentImageData()->GetSpacing()[0];
+        if ( posXYZ[0] <= limit )
+            this->window->GetRendererProperties()->position[0] += this->Step * this->window->GetCurrentImageData()->GetSpacing()[0];
+
+        /// Update Slice text
+        if ( this->window->GetFlagDisplayText() )
+        {
+            int slice = (int)( (this->window->GetRendererProperties()->position[0] -
+                                this->window->GetCurrentImageData()->GetOrigin()[0]) /
+                                this->window->GetCurrentImageData()->GetSpacing()[0] + 0.5f );
+            QString strSlice;
+            strSlice.sprintf("Slice: %d",slice);
+            this->window->GetRendererProperties()->TextMapperSlice->SetInput(strSlice.toStdString().c_str());
+        }
+
+        /// Update renderers
+        this->window->GetRendererProperties()->xIPW->SetSlicePosition(this->window->GetRendererProperties()->position[0]);
+        this->window->GetRendererProperties()->yzIPW->SetSlicePosition(this->window->GetRendererProperties()->position[0]);
+        this->window->GetRenderWindow()->Render();
+        this->window->GetYZRenderer()->ResetCameraClippingRange();
+        this->window->GetRenderWindowYZ()->Render();
+
+    }
+
+}
+
+
+void vtkMyInteractorStyleTrackballCameraOpenHeart::MoveBackwardXYPlan()
+{
+
+    /// Get picker position
+    double pos[3];
+    this->GetPickerPosition(pos);
+
+    /// Go back to the initial coordinate system before reslicing
+    double posXYZ[3];
+    for (int i=0; i<3; i++)
+        posXYZ[i] = pos[i];
+    this->window->ComputePointBeforeRotation(posXYZ);
+
+    /// Update Slice image
+    if ( this->IsInside(posXYZ) )
+    {
+        /// Compute corresponding step
+        if ( (posXYZ[0] >= this->Limits[0] ) &&
+             (posXYZ[0] <= this->Limits[1] ) &&
+             (posXYZ[1] >= this->Limits[2] ) &&
+             (posXYZ[1] <= this->Limits[3] ) )
+            this->Step = 1;
+        else
+            this->Step = 5;
+
+        /// Compute new slice position
+        posXYZ[2] -= this->Step * this->window->GetCurrentImageData()->GetSpacing()[2];
+        if ( posXYZ[2] >= 0 )
+            this->window->GetRendererProperties()->position[2] -= this->Step * this->window->GetCurrentImageData()->GetSpacing()[2];
+
+        /// Update Slice text
+        if ( this->window->GetFlagDisplayText() )
+        {
+            int slice = (int)( (this->window->GetRendererProperties()->position[2] -
+                                this->window->GetCurrentImageData()->GetOrigin()[2]) /
+                                this->window->GetCurrentImageData()->GetSpacing()[2] + 0.5f );
+            QString strSlice;
+            strSlice.sprintf("Slice: %d",slice);
+            this->window->GetRendererProperties()->TextMapperSlice->SetInput(strSlice.toStdString().c_str());
+        }
+
+        /// Update renderers
+        this->window->GetRendererProperties()->zIPW->SetSlicePosition(this->window->GetRendererProperties()->position[2]);
+        this->window->GetRendererProperties()->xyIPW->SetSlicePosition(this->window->GetRendererProperties()->position[2]);
+        this->window->GetRenderWindow()->Render();
+        this->window->GetXYRenderer()->ResetCameraClippingRange();
+        this->window->GetRenderWindowXY()->Render();
+
+    }
+
+}
+
+
+void vtkMyInteractorStyleTrackballCameraOpenHeart::MoveBackwardXZPlan()
+{
+
+    /// Get picker position
+    double pos[3];
+    this->GetPickerPosition(pos);
+
+    /// Go back to the initial coordinate system before reslicing
+    double posXYZ[3];
+    for (int i=0; i<3; i++)
+        posXYZ[i] = pos[i];
+    this->window->ComputePointBeforeRotation(posXYZ);
+
+    /// Update Slice image
+    if ( this->IsInside(posXYZ) )
+    {
+        /// Compute corresponding step
+        if ( (posXYZ[0] >= this->Limits[0] ) &&
+             (posXYZ[0] <= this->Limits[1] ) &&
+             (posXYZ[2] >= this->Limits[4] ) &&
+             (posXYZ[2] <= this->Limits[5] ) )
+            this->Step = 1;
+        else
+            this->Step = 5;
+
+        /// Compute new slice position
+        posXYZ[1] -= this->Step * this->window->GetCurrentImageData()->GetSpacing()[1];
+        if ( posXYZ[1] >= 0 )
+            this->window->GetRendererProperties()->position[1] -= this->Step * this->window->GetCurrentImageData()->GetSpacing()[1];
+
+        /// Update Slice text
+        if ( this->window->GetFlagDisplayText() )
+        {
+            int slice = (int)( (this->window->GetRendererProperties()->position[1] -
+                                this->window->GetCurrentImageData()->GetOrigin()[1]) /
+                                this->window->GetCurrentImageData()->GetSpacing()[1] + 0.5f );
+            QString strSlice;
+            strSlice.sprintf("Slice: %d",slice);
+            this->window->GetRendererProperties()->TextMapperSlice->SetInput(strSlice.toStdString().c_str());
+        }
+
+        /// Update renderers
+        this->window->GetRendererProperties()->yIPW->SetSlicePosition(this->window->GetRendererProperties()->position[1]);
+        this->window->GetRendererProperties()->xzIPW->SetSlicePosition(this->window->GetRendererProperties()->position[1]);
+        this->window->GetRenderWindow()->Render();
+        this->window->GetXZRenderer()->ResetCameraClippingRange();
+        this->window->GetRenderWindowXZ()->Render();
+
+    }
+
+}
+
+
+void vtkMyInteractorStyleTrackballCameraOpenHeart::MoveBackwardYZPlan()
+{
+
+    /// Get picker position
+    double pos[3];
+    this->GetPickerPosition(pos);
+
+    /// Go back to the initial coordinate system before reslicing
+    double posXYZ[3];
+    for (int i=0; i<3; i++)
+        posXYZ[i] = pos[i];
+    this->window->ComputePointBeforeRotation(posXYZ);
+
+    /// Update Slice image
+    if ( this->IsInside(posXYZ) )
+    {
+        /// Compute corresponding step
+        if ( (posXYZ[1] >= this->Limits[2] ) &&
+             (posXYZ[1] <= this->Limits[3] ) &&
+             (posXYZ[2] >= this->Limits[4] ) &&
+             (posXYZ[2] <= this->Limits[5] ) )
+            this->Step = 1;
+        else
+            this->Step = 5;
+
+        /// Compute new slice position
+        posXYZ[0] -= this->Step * this->window->GetCurrentImageData()->GetSpacing()[0];
+        if ( posXYZ[0] >= 0 )
+            this->window->GetRendererProperties()->position[0] -= this->Step * this->window->GetCurrentImageData()->GetSpacing()[0];
+
+        /// Update Slice text
+        if ( this->window->GetFlagDisplayText() )
+        {
+            int slice = (int)( (this->window->GetRendererProperties()->position[0] -
+                                this->window->GetCurrentImageData()->GetOrigin()[0]) /
+                                this->window->GetCurrentImageData()->GetSpacing()[0] + 0.5f );
+            QString strSlice;
+            strSlice.sprintf("Slice: %d",slice);
+            this->window->GetRendererProperties()->TextMapperSlice->SetInput(strSlice.toStdString().c_str());
+        }
+
+        /// Update renderers
+        this->window->GetRendererProperties()->xIPW->SetSlicePosition(this->window->GetRendererProperties()->position[0]);
+        this->window->GetRendererProperties()->yzIPW->SetSlicePosition(this->window->GetRendererProperties()->position[0]);
+        this->window->GetRenderWindow()->Render();
+        this->window->GetYZRenderer()->ResetCameraClippingRange();
+        this->window->GetRenderWindowYZ()->Render();
+
+    }
+
+}
+
+
+void vtkMyInteractorStyleTrackballCameraOpenHeart::MoveBackward()
+{
+
+    /// Get picker position
+    double pos[3];
+    this->GetPickerPosition(pos);
+
+    /// Go back to the initial coordinate system before reslicing
+    double posXYZ[3];
+    for (int i=0; i<3; i++)
+        posXYZ[i] = pos[i];
+    this->window->ComputePointBeforeRotation(posXYZ);
+
+    /// Compute point of interest for checking which plan is selected
+    double RefX[3];
+    for (int i=0; i<3; i++)
+        RefX[i] = this->window->GetRendererProperties()->xIPW->GetCenter()[i];
+    this->window->ComputePointBeforeRotation(RefX);
+    double RefY[3];
+    for (int i=0; i<3; i++)
+        RefY[i] = this->window->GetRendererProperties()->yIPW->GetCenter()[i];
+    this->window->ComputePointBeforeRotation(RefY);
+    double RefZ[3];
+    for (int i=0; i<3; i++)
+        RefZ[i] = this->window->GetRendererProperties()->zIPW->GetCenter()[i];
+    this->window->ComputePointBeforeRotation(RefZ);
+
+    /// Update Slice image
+    if ( this->IsInside(posXYZ) )
+    {
+
+        if ( fabs(posXYZ[0]-RefX[0]) < this->PadSliceDetection[0] )
+        {
+
+            /// Compute corresponding step
+            if ( (posXYZ[1] >= this->Limits[2] ) &&
+                 (posXYZ[1] <= this->Limits[3] ) &&
+                 (posXYZ[2] >= this->Limits[4] ) &&
+                 (posXYZ[2] <= this->Limits[5] ) )
+                this->Step = 1;
+            else
+                this->Step = 5;
+
+            /// Compute new slice position
+            posXYZ[0] -= this->Step * this->SpacingImg[0];
+            if ( posXYZ[0] >= 0 )
+                this->window->GetRendererProperties()->position[0] -= this->Step * this->SpacingImg[0];
+
+            /// Update Slice text
+            if ( this->window->GetFlagDisplayText() )
+            {
+                int slice = (int)( (this->window->GetRendererProperties()->position[0] -
+                                    this->OriginImg[0]) /
+                                    this->SpacingImg[0] + 0.5f );
+                QString strSlice;
+                strSlice.sprintf("Slice: %d",slice);
+                this->window->GetRendererProperties()->TextMapperSlice->SetInput(strSlice.toStdString().c_str());
+            }
+
+            /// Update renderers
+            this->window->GetRendererProperties()->xIPW->SetSlicePosition(this->window->GetRendererProperties()->position[0]);
+            this->window->GetRendererProperties()->yzIPW->SetSlicePosition(this->window->GetRendererProperties()->position[0]);
+            this->window->GetRenderWindow()->Render();
+            this->window->GetYZRenderer()->ResetCameraClippingRange();
+            this->window->GetRenderWindowYZ()->Render();
+        }
+
+        if ( fabs(posXYZ[1]-RefY[1]) < this->PadSliceDetection[1] )
+        {
+
+            /// Compute corresponding step
+            if ( (posXYZ[0] >= this->Limits[0] ) &&
+                 (posXYZ[0] <= this->Limits[1] ) &&
+                 (posXYZ[2] >= this->Limits[4] ) &&
+                 (posXYZ[2] <= this->Limits[5] ) )
+                this->Step = 1;
+            else
+                this->Step = 5;
+
+            /// Compute new slice position
+            posXYZ[1] -= this->Step * this->SpacingImg[1];
+            if ( posXYZ[1] >= 0 )
+                this->window->GetRendererProperties()->position[1] -= this->Step * this->SpacingImg[1];
+
+            /// Update Slice text
+            if ( this->window->GetFlagDisplayText() )
+            {
+                int slice = (int)( (this->window->GetRendererProperties()->position[1] -
+                                    this->OriginImg[1]) /
+                                    this->SpacingImg[1] + 0.5f );
+                QString strSlice;
+                strSlice.sprintf("Slice: %d",slice);
+                this->window->GetRendererProperties()->TextMapperSlice->SetInput(strSlice.toStdString().c_str());
+            }
+
+            /// Update renderers
+            this->window->GetRendererProperties()->yIPW->SetSlicePosition(this->window->GetRendererProperties()->position[1]);
+            this->window->GetRendererProperties()->xzIPW->SetSlicePosition(this->window->GetRendererProperties()->position[1]);
+            this->window->GetRenderWindow()->Render();
+            this->window->GetXZRenderer()->ResetCameraClippingRange();
+            this->window->GetRenderWindowXZ()->Render();
+        }
+
+        if ( fabs(posXYZ[2]-RefZ[2]) < this->PadSliceDetection[2] )
+        {
+
+            /// Compute corresponding step
+            if ( (posXYZ[0] >= this->Limits[0] ) &&
+                 (posXYZ[0] <= this->Limits[1] ) &&
+                 (posXYZ[1] >= this->Limits[2] ) &&
+                 (posXYZ[1] <= this->Limits[3] ) )
+                this->Step = 1;
+            else
+                this->Step = 5;
+
+            /// Compute new slice position
+            posXYZ[2] -= this->Step * this->SpacingImg[2];
+            if ( posXYZ[2] >= 0 )
+                this->window->GetRendererProperties()->position[2] -= this->Step * this->SpacingImg[2];
+
+            /// Update Slice text
+            if ( this->window->GetFlagDisplayText() )
+            {
+                int slice = (int)( (this->window->GetRendererProperties()->position[2] -
+                                    this->OriginImg[2]) /
+                                    this->SpacingImg[2] + 0.5f );
+                QString strSlice;
+                strSlice.sprintf("Slice: %d",slice);
+                this->window->GetRendererProperties()->TextMapperSlice->SetInput(strSlice.toStdString().c_str());
+            }
+
+            /// Update renderers
+            this->window->GetRendererProperties()->zIPW->SetSlicePosition(this->window->GetRendererProperties()->position[2]);
+            this->window->GetRendererProperties()->xyIPW->SetSlicePosition(this->window->GetRendererProperties()->position[2]);
+            this->window->GetRenderWindow()->Render();
+            this->window->GetXYRenderer()->ResetCameraClippingRange();
+            this->window->GetRenderWindowXY()->Render();
+        }
+
+        /// Update text display
+        this->window->UpdateCoords(this->window->GetRendererProperties()->position);
+
+    }
+
+}
+
+
+void vtkMyInteractorStyleTrackballCameraOpenHeart::OnEnter()
+{
+
+    if ( !this->FlagFirstTime )
+    {
+
+        /// Set flag to 1 to never enter again in this part of the code
+        this->FlagFirstTime = 1;
+        double extend[6];
+        this->window->GetCurrentImageData()->GetWholeBoundingBox(extend);
+
+        /// Save the boundary of the volume in world coordinates
+        this->Bounds[0] = this->window->GetCurrentImageData()->GetExtent()[0] * this->window->GetCurrentImageData()->GetSpacing()[0] +
+                this->window->GetCurrentImageData()->GetOrigin()[0];
+        this->Bounds[1] = this->window->GetCurrentImageData()->GetExtent()[1] * this->window->GetCurrentImageData()->GetSpacing()[0] +
+                this->window->GetCurrentImageData()->GetOrigin()[0];
+        this->Bounds[2] = this->window->GetCurrentImageData()->GetExtent()[2] * this->window->GetCurrentImageData()->GetSpacing()[1] +
+                this->window->GetCurrentImageData()->GetOrigin()[1];
+        this->Bounds[3] = this->window->GetCurrentImageData()->GetExtent()[3] * this->window->GetCurrentImageData()->GetSpacing()[1] +
+                this->window->GetCurrentImageData()->GetOrigin()[1];
+        this->Bounds[4] = this->window->GetCurrentImageData()->GetExtent()[4] * this->window->GetCurrentImageData()->GetSpacing()[2] +
+                this->window->GetCurrentImageData()->GetOrigin()[2];
+        this->Bounds[5] = this->window->GetCurrentImageData()->GetExtent()[5] * this->window->GetCurrentImageData()->GetSpacing()[2] +
+                this->window->GetCurrentImageData()->GetOrigin()[2];
+
+        /// Save the limit of the box to increase the scolling effect
+        this->Limits[0] = (this->Bounds[1] - this->Bounds[0]) * this->PadBound;
+        this->Limits[1] = this->Bounds[1] - (this->Bounds[1] - this->Bounds[0]) * this->PadBound;
+        this->Limits[2] = (this->Bounds[3] - this->Bounds[2]) * this->PadBound;
+        this->Limits[3] = this->Bounds[3] - (this->Bounds[3] - this->Bounds[2]) * this->PadBound;
+        this->Limits[4] = (this->Bounds[5] - this->Bounds[4]) * this->PadBound;
+        this->Limits[5] = this->Bounds[5] - (this->Bounds[5] - this->Bounds[4]) * this->PadBound;
+
+        /// Save usefull information
+        for ( int i=0; i<3; i++)
+        {
+            this->SpacingImg[i] = this->window->GetCurrentImageData()->GetSpacing()[i];
+            this->OriginImg[i] = this->window->GetCurrentImageData()->GetOrigin()[i];
+            this->LimitImg[i] = this->OriginImg[i] + (this->window->GetDimensions()[i]-1) *
+                    this->SpacingImg[i];
+            this->PadSliceDetection[i] = 0.01 * this->SpacingImg[i];
+        }
+
+    }
+
+    vtkInteractorStyleTrackballCamera::OnEnter();
+
+}
+
+
+void vtkMyInteractorStyleTrackballCameraOpenHeart::OnLeave()
+{
+    this->Step = 1;
+    vtkInteractorStyleTrackballCamera::OnLeave();
+}
+
+
+void vtkMyInteractorStyleTrackballCameraOpenHeart::OnLeftButtonDown()
+{
+    this->FlagLeftClick = true;
+    if ( this->window->GetSelectedButton() == 0 )
+    {
+        this->window->GetMainRenderer()->AddActor(this->window->GetRendererProperties()->BoundingBoxActor);
+        this->window->GetRenderWindow()->Render();
+    }
+    vtkInteractorStyleTrackballCamera::OnLeftButtonDown();
+}
+
+
+void vtkMyInteractorStyleTrackballCameraOpenHeart::OnLeftButtonUp()
+{
+    this->FlagLeftClick = false;
+    if ( this->window->GetSelectedButton() == 0 ) {
+        this->window->GetMainRenderer()->RemoveActor(this->window->GetRendererProperties()->BoundingBoxActor);
+        this->window->GetRenderWindow()->Render();
+    }
+    vtkInteractorStyleTrackballCamera::OnLeftButtonUp();
+}
+
+
+void vtkMyInteractorStyleTrackballCameraOpenHeart::GetPickerPosition(double *pos)
+{
+    int X = this->Interactor->GetEventPosition()[0];
+    int Y = this->Interactor->GetEventPosition()[1];
+    this->window->GetPicker()->Pick(X,Y,0.0,this->window->GetMainRenderer());
+    this->window->GetPicker()->GetPickPosition(pos);
+}
+
+
+bool vtkMyInteractorStyleTrackballCameraOpenHeart::IsInside(double *pos)
+{
+    if ( (pos[0]>=this->Bounds[0]) && (pos[0]<=this->Bounds[1]) &&
+         (pos[1]>=this->Bounds[2]) && (pos[1]<=this->Bounds[3]) &&
+         (pos[2]>=this->Bounds[4]) && (pos[2]<=this->Bounds[5]) )
+        return true;
+    else
+        return false;
+}
+
+
diff --git a/Applications/vtkMyInteractorStyleTrackballCameraOpenHeart.h b/Applications/vtkMyInteractorStyleTrackballCameraOpenHeart.h
new file mode 100644 (file)
index 0000000..8ef8802
--- /dev/null
@@ -0,0 +1,93 @@
+/**
+* Progam made by Olivier Bernard, associate professor
+* at Institut National des Sciences Appliquees (INSA) Lyon,
+* CREATIS-LRMN Laboratory,
+* 69621 Villeurbanne, France,
+* 20th of May 2014
+*/
+
+#ifndef __vtkMyInteractorStyleTrackballCameraOpenHeart_h__
+#define __vtkMyInteractorStyleTrackballCameraOpenHeart_h__
+
+#include <vtkObjectFactory.h>
+#include <vtkInteractorStyleTrackballCamera.h>
+#include "OpenHeartGui.h"
+
+
+class vtkMyInteractorStyleTrackballCameraOpenHeart : public vtkInteractorStyleTrackballCamera
+{
+
+    public:
+
+        void SetOpenHeartGui( OpenHeartGui *win ) { this->window = win; }
+
+        static vtkMyInteractorStyleTrackballCameraOpenHeart *New()
+        {
+            /// First try to create the object from the vtkObjectFactory
+            vtkObject *ret = vtkObjectFactory::CreateInstance ("vtkMyInteractorStyleTrackballCameraOpenHeart");
+            if (ret)
+            {
+                return (vtkMyInteractorStyleTrackballCameraOpenHeart *) ret;
+            }
+            /// If the factory was unable to create the object, then create it here.
+            return (new vtkMyInteractorStyleTrackballCameraOpenHeart);
+        }
+
+        virtual void OnChar();
+        virtual void OnMouseWheelForward();
+        virtual void OnMouseWheelBackward();
+
+        virtual void OnLeftButtonDown();
+        virtual void OnLeftButtonUp();
+        virtual void OnEnter();
+        virtual void OnLeave();
+
+
+    protected:
+
+        vtkMyInteractorStyleTrackballCameraOpenHeart() : FlagFirstTime(0), Step(1), PadBound(0.2), FlagLeftClick(false)
+        {
+            for (int i=0; i<6; i++) {
+                Bounds[i] = 0;
+                Limits[i] = 0;
+            }
+            for (int i=0; i<3; i++) {
+                PadSliceDetection[i] = 0;
+                SpacingImg[i] = 0;
+                OriginImg[i] = 0;
+                LimitImg[i] = 0;
+            }
+        }
+
+        ~vtkMyInteractorStyleTrackballCameraOpenHeart()
+        {}
+
+        OpenHeartGui *window;
+        int FlagFirstTime;
+        int Step;
+        double Bounds[6];
+        double Limits[6];
+        double PadSliceDetection[3];
+        double SpacingImg[3];
+        double OriginImg[3];
+        double LimitImg[3];
+        double PadBound;
+        bool FlagLeftClick;
+
+        void MoveForward();
+        void MoveForwardXYPlan();
+        void MoveForwardXZPlan();
+        void MoveForwardYZPlan();
+
+        void MoveBackward();
+        void MoveBackwardXYPlan();
+        void MoveBackwardXZPlan();
+        void MoveBackwardYZPlan();
+
+        void GetPickerPosition(double *pos);
+        bool IsInside(double *pos);
+
+};
+
+
+#endif
diff --git a/Applications/vtkMyInteractorStyleTrackballCameraOpenHeartXY.cxx b/Applications/vtkMyInteractorStyleTrackballCameraOpenHeartXY.cxx
new file mode 100644 (file)
index 0000000..0620507
--- /dev/null
@@ -0,0 +1,195 @@
+/**
+* Progam made by Olivier Bernard, associate professor
+* at Institut National des Sciences Appliquees (INSA) Lyon,
+* CREATIS-LRMN Laboratory,
+* 69621 Villeurbanne, France,
+* 20th of May 2014
+*/
+
+#include <vtkRenderer.h>
+#include <vtkRenderWindow.h>
+#include <vtkSmartPointer.h>
+#include <vtkPoints.h>
+#include <vtkPolyLine.h>
+#include <vtkCellArray.h>
+#include <vtkPolyData.h>
+#include <vtkPolyDataMapper.h>
+#include <vtkActor.h>
+
+#include "vtkMyInteractorStyleTrackballCameraOpenHeartXY.h"
+
+
+using namespace std;
+
+
+void vtkMyInteractorStyleTrackballCameraOpenHeartXY::OnMouseWheelForward()
+{
+
+    /// Get picker position
+    double pos[3];
+    this->GetPickerPosition(pos);
+
+    /// Go back to the initial coordinate system before reslicing
+    double posXYZ[3];
+    for (int i=0; i<3; i++)
+        posXYZ[i] = pos[i];
+    this->window->ComputePointBeforeRotation(posXYZ);
+
+    /// Update Slice image
+    if ( this->IsInside(posXYZ) )
+    {
+
+        /// Compute corresponding step
+        if ( (posXYZ[0] >= this->Limits[0] ) &&
+             (posXYZ[0] <= this->Limits[1] ) &&
+             (posXYZ[1] >= this->Limits[2] ) &&
+             (posXYZ[1] <= this->Limits[3] ) )
+            this->Step = 1;
+        else
+            this->Step = 5;
+
+        /// Compute new slice position
+        double limit = this->Bounds[5];
+        posXYZ[2] += this->Step * this->window->GetCurrentImageData()->GetSpacing()[2];
+        if ( posXYZ[2] <= limit )
+            this->window->GetRendererProperties()->position[2] += this->Step * this->window->GetCurrentImageData()->GetSpacing()[2];
+
+        /// Update Slice text
+        if ( this->window->GetFlagDisplayText() )
+        {
+            int slice = (int)( (this->window->GetRendererProperties()->position[2] -
+                                this->window->GetCurrentImageData()->GetOrigin()[2]) /
+                                this->window->GetCurrentImageData()->GetSpacing()[2] + 0.5f );
+            QString strSlice;
+            strSlice.sprintf("Slice: %d",slice);
+            this->window->GetRendererProperties()->TextMapperSlice->SetInput(strSlice.toStdString().c_str());
+        }
+
+        /// Update renderers
+        this->window->GetRendererProperties()->zIPW->SetSlicePosition(this->window->GetRendererProperties()->position[2]);
+        this->window->GetRendererProperties()->xyIPW->SetSlicePosition(this->window->GetRendererProperties()->position[2]);
+        this->window->GetRenderWindow()->Render();
+        this->window->GetXYRenderer()->ResetCameraClippingRange();
+        this->window->GetRenderWindowXY()->Render();
+    }
+
+}
+
+
+void vtkMyInteractorStyleTrackballCameraOpenHeartXY::OnMouseWheelBackward()
+{
+
+    /// Get picker position
+    double pos[3];
+    this->GetPickerPosition(pos);
+
+    /// Go back to the initial coordinate system before reslicing
+    double posXYZ[3];
+    for (int i=0; i<3; i++)
+        posXYZ[i] = pos[i];
+    this->window->ComputePointBeforeRotation(posXYZ);
+
+    /// Update Slice image
+    if ( this->IsInside(posXYZ) )
+    {
+
+        /// Compute corresponding step
+        if ( (posXYZ[0] >= this->Limits[0] ) &&
+             (posXYZ[0] <= this->Limits[1] ) &&
+             (posXYZ[1] >= this->Limits[2] ) &&
+             (posXYZ[1] <= this->Limits[3] ) )
+            this->Step = 1;
+        else
+            this->Step = 5;
+
+        /// Compute new slice position
+        posXYZ[2] -= this->Step * this->window->GetCurrentImageData()->GetSpacing()[2];
+        if ( posXYZ[2] >= 0 )
+            this->window->GetRendererProperties()->position[2] -= this->Step * this->window->GetCurrentImageData()->GetSpacing()[2];
+
+        /// Update Slice text
+        if ( this->window->GetFlagDisplayText() )
+        {
+            int slice = (int)( (this->window->GetRendererProperties()->position[2] -
+                                this->window->GetCurrentImageData()->GetOrigin()[2]) /
+                                this->window->GetCurrentImageData()->GetSpacing()[2] + 0.5f );
+            QString strSlice;
+            strSlice.sprintf("Slice: %d",slice);
+            this->window->GetRendererProperties()->TextMapperSlice->SetInput(strSlice.toStdString().c_str());
+        }
+
+        /// Update renderers
+        this->window->GetRendererProperties()->zIPW->SetSlicePosition(this->window->GetRendererProperties()->position[2]);
+        this->window->GetRendererProperties()->xyIPW->SetSlicePosition(this->window->GetRendererProperties()->position[2]);
+        this->window->GetRenderWindow()->Render();
+        this->window->GetXYRenderer()->ResetCameraClippingRange();
+        this->window->GetRenderWindowXY()->Render();
+    }
+
+}
+
+
+void vtkMyInteractorStyleTrackballCameraOpenHeartXY::OnEnter()
+{
+
+    if ( !this->FlagFirstTime )
+    {
+
+        /// Set flag to 1 to never enter again in this part of the code
+        this->FlagFirstTime = 1;
+        double extend[6];
+        this->window->GetCurrentImageData()->GetWholeBoundingBox(extend);
+
+        /// Save the boundary of the volume in world coordinates
+        this->Bounds[0] = this->window->GetCurrentImageData()->GetExtent()[0] * this->window->GetCurrentImageData()->GetSpacing()[0] +
+                this->window->GetCurrentImageData()->GetOrigin()[0];
+        this->Bounds[1] = this->window->GetCurrentImageData()->GetExtent()[1] * this->window->GetCurrentImageData()->GetSpacing()[0] +
+                this->window->GetCurrentImageData()->GetOrigin()[0];
+        this->Bounds[2] = this->window->GetCurrentImageData()->GetExtent()[2] * this->window->GetCurrentImageData()->GetSpacing()[1] +
+                this->window->GetCurrentImageData()->GetOrigin()[1];
+        this->Bounds[3] = this->window->GetCurrentImageData()->GetExtent()[3] * this->window->GetCurrentImageData()->GetSpacing()[1] +
+                this->window->GetCurrentImageData()->GetOrigin()[1];
+        this->Bounds[4] = this->window->GetCurrentImageData()->GetExtent()[4] * this->window->GetCurrentImageData()->GetSpacing()[2] +
+                this->window->GetCurrentImageData()->GetOrigin()[2];
+        this->Bounds[5] = this->window->GetCurrentImageData()->GetExtent()[5] * this->window->GetCurrentImageData()->GetSpacing()[2] +
+                this->window->GetCurrentImageData()->GetOrigin()[2];
+
+        /// Save the limit of the box to increase the scolling effect
+        this->Limits[0] = (this->Bounds[1] - this->Bounds[0]) * this->PadBound;
+        this->Limits[1] = this->Bounds[1] - (this->Bounds[1] - this->Bounds[0]) * this->PadBound;
+        this->Limits[2] = (this->Bounds[3] - this->Bounds[2]) * this->PadBound;
+        this->Limits[3] = this->Bounds[3] - (this->Bounds[3] - this->Bounds[2]) * this->PadBound;
+
+    }
+
+    vtkInteractorStyleTrackballCamera::OnEnter();
+
+}
+
+
+void vtkMyInteractorStyleTrackballCameraOpenHeartXY::OnLeave()
+{
+    this->Step = 1;
+    vtkInteractorStyleTrackballCamera::OnLeave();
+}
+
+
+void vtkMyInteractorStyleTrackballCameraOpenHeartXY::GetPickerPosition(double *pos)
+{
+    int X = this->Interactor->GetEventPosition()[0];
+    int Y = this->Interactor->GetEventPosition()[1];
+    this->window->GetPickerXY()->Pick(X,Y,0.0,this->window->GetXYRenderer());
+    this->window->GetPickerXY()->GetPickPosition(pos);
+}
+
+
+bool vtkMyInteractorStyleTrackballCameraOpenHeartXY::IsInside(double *pos)
+{
+    if ( (pos[0]>=this->Bounds[0]) && (pos[0]<=this->Bounds[1]) &&
+         (pos[1]>=this->Bounds[2]) && (pos[1]<=this->Bounds[3]) &&
+         (pos[2]>=this->Bounds[4]) && (pos[2]<=this->Bounds[5]) )
+        return true;
+    else
+        return false;
+}
+
diff --git a/Applications/vtkMyInteractorStyleTrackballCameraOpenHeartXY.h b/Applications/vtkMyInteractorStyleTrackballCameraOpenHeartXY.h
new file mode 100644 (file)
index 0000000..86e0cc8
--- /dev/null
@@ -0,0 +1,76 @@
+/**
+* Progam made by Olivier Bernard, associate professor
+* at Institut National des Sciences Appliquees (INSA) Lyon,
+* CREATIS-LRMN Laboratory,
+* 69621 Villeurbanne, France,
+* 20th of May 2014
+*/
+
+#ifndef __vtkMyInteractorStyleTrackballCameraOpenHeartXY_h__
+#define __vtkMyInteractorStyleTrackballCameraOpenHeartXY_h__
+
+#include <vtkObjectFactory.h>
+#include <vtkInteractorStyleTrackballCamera.h>
+#include "OpenHeartGui.h"
+
+
+class vtkMyInteractorStyleTrackballCameraOpenHeartXY : public vtkInteractorStyleTrackballCamera
+{
+
+    public:
+
+        void SetOpenHeartGui( OpenHeartGui *win ) { this->window = win; }
+
+        static vtkMyInteractorStyleTrackballCameraOpenHeartXY *New()
+        {
+            /// First try to create the object from the vtkObjectFactory
+            vtkObject *ret = vtkObjectFactory::CreateInstance ("vtkMyInteractorStyleTrackballCameraOpenHeartXY");
+            if (ret)
+            {
+                return (vtkMyInteractorStyleTrackballCameraOpenHeartXY *) ret;
+            }
+            /// If the factory was unable to create the object, then create it here.
+            return (new vtkMyInteractorStyleTrackballCameraOpenHeartXY);
+        }
+
+
+        virtual void OnLeftButtonDown() { }
+        virtual void OnRightButtonDown() { }
+        virtual void OnMiddleButtonDown() { }
+
+        virtual void OnMouseWheelForward();
+        virtual void OnMouseWheelBackward();
+        virtual void OnEnter();
+        virtual void OnLeave();
+
+
+    protected:
+
+        vtkMyInteractorStyleTrackballCameraOpenHeartXY() : FlagFirstTime(0), Step(1), PadBound(0.2)
+        {
+            for (int i=0; i<6; i++)
+                Bounds[i] = 0;
+            for (int i=0; i<4; i++)
+                Limits[i] = 0;
+        }
+
+        ~vtkMyInteractorStyleTrackballCameraOpenHeartXY()
+        { }
+
+        OpenHeartGui *window;
+
+        /// Attributes
+        int FlagFirstTime;
+        double Bounds[6];
+        double Limits[4];
+        int Step;
+        double PadBound;
+
+        /// Methods
+        void GetPickerPosition(double *pos);
+        bool IsInside(double *pos);
+
+};
+
+
+#endif
diff --git a/Applications/vtkMyInteractorStyleTrackballCameraOpenHeartXZ.cxx b/Applications/vtkMyInteractorStyleTrackballCameraOpenHeartXZ.cxx
new file mode 100644 (file)
index 0000000..03148ac
--- /dev/null
@@ -0,0 +1,185 @@
+/**
+* Progam made by Olivier Bernard, associate professor
+* at Institut National des Sciences Appliquees (INSA) Lyon,
+* CREATIS-LRMN Laboratory,
+* 69621 Villeurbanne, France,
+* 20th of May 2014
+*/
+
+#include <vtkRenderer.h>
+#include <vtkRenderWindow.h>
+#include "vtkMyInteractorStyleTrackballCameraOpenHeartXZ.h"
+
+
+using namespace std;
+
+
+void vtkMyInteractorStyleTrackballCameraOpenHeartXZ::OnMouseWheelForward()
+{
+
+    /// Get picker position
+    double pos[3];
+    this->GetPickerPosition(pos);
+
+    /// Go back to the initial coordinate system before reslicing
+    double posXYZ[3];
+    for (int i=0; i<3; i++)
+        posXYZ[i] = pos[i];
+    this->window->ComputePointBeforeRotation(posXYZ);
+
+    /// Update Slice image
+    if ( this->IsInside(posXYZ) )
+    {
+        /// Compute corresponding step
+        if ( (posXYZ[0] >= this->Limits[0] ) &&
+             (posXYZ[0] <= this->Limits[1] ) &&
+             (posXYZ[2] >= this->Limits[2] ) &&
+             (posXYZ[2] <= this->Limits[3] ) )
+            this->Step = 1;
+        else
+            this->Step = 5;
+
+        /// Compute new slice position
+        double limit = this->Bounds[3];
+        posXYZ[1] += this->Step * this->window->GetCurrentImageData()->GetSpacing()[1];
+        if ( posXYZ[1] <= limit )
+            this->window->GetRendererProperties()->position[1] += this->Step * this->window->GetCurrentImageData()->GetSpacing()[1];
+
+        /// Update Slice text
+        if ( this->window->GetFlagDisplayText() )
+        {
+            int slice = (int)( (this->window->GetRendererProperties()->position[1] -
+                                this->window->GetCurrentImageData()->GetOrigin()[1]) /
+                                this->window->GetCurrentImageData()->GetSpacing()[1] + 0.5f );
+            QString strSlice;
+            strSlice.sprintf("Slice: %d",slice);
+            this->window->GetRendererProperties()->TextMapperSlice->SetInput(strSlice.toStdString().c_str());
+        }
+
+        /// Update renderers
+        this->window->GetRendererProperties()->yIPW->SetSlicePosition(this->window->GetRendererProperties()->position[1]);
+        this->window->GetRendererProperties()->xzIPW->SetSlicePosition(this->window->GetRendererProperties()->position[1]);
+        this->window->GetRenderWindow()->Render();
+        this->window->GetXZRenderer()->ResetCameraClippingRange();
+        this->window->GetRenderWindowXZ()->Render();
+    }
+
+}
+
+
+void vtkMyInteractorStyleTrackballCameraOpenHeartXZ::OnMouseWheelBackward()
+{
+
+    /// Get picker position
+    double pos[3];
+    this->GetPickerPosition(pos);
+
+    /// Go back to the initial coordinate system before reslicing
+    double posXYZ[3];
+    for (int i=0; i<3; i++)
+        posXYZ[i] = pos[i];
+    this->window->ComputePointBeforeRotation(posXYZ);
+
+    /// Update Slice image
+    if ( this->IsInside(posXYZ) )
+    {
+        /// Compute corresponding step
+        if ( (posXYZ[0] >= this->Limits[0] ) &&
+             (posXYZ[0] <= this->Limits[1] ) &&
+             (posXYZ[2] >= this->Limits[2] ) &&
+             (posXYZ[2] <= this->Limits[3] ) )
+            this->Step = 1;
+        else
+            this->Step = 5;
+
+        /// Compute new slice position
+        posXYZ[1] -= this->Step * this->window->GetCurrentImageData()->GetSpacing()[1];
+        if ( posXYZ[1] >= 0 )
+            this->window->GetRendererProperties()->position[1] -= this->Step * this->window->GetCurrentImageData()->GetSpacing()[1];
+
+        /// Update Slice text
+        if ( this->window->GetFlagDisplayText() )
+        {
+            int slice = (int)( (this->window->GetRendererProperties()->position[1] -
+                                this->window->GetCurrentImageData()->GetOrigin()[1]) /
+                                this->window->GetCurrentImageData()->GetSpacing()[1] + 0.5f );
+            QString strSlice;
+            strSlice.sprintf("Slice: %d",slice);
+            this->window->GetRendererProperties()->TextMapperSlice->SetInput(strSlice.toStdString().c_str());
+        }
+
+        /// Update renderers
+        this->window->GetRendererProperties()->yIPW->SetSlicePosition(this->window->GetRendererProperties()->position[1]);
+        this->window->GetRendererProperties()->xzIPW->SetSlicePosition(this->window->GetRendererProperties()->position[1]);
+        this->window->GetRenderWindow()->Render();
+        this->window->GetXZRenderer()->ResetCameraClippingRange();
+        this->window->GetRenderWindowXZ()->Render();
+    }
+
+}
+
+
+void vtkMyInteractorStyleTrackballCameraOpenHeartXZ::OnEnter()
+{
+
+    if ( !this->FlagFirstTime )
+    {
+
+        /// Set flag to 1 to never enter again in this part of the code
+        this->FlagFirstTime = 1;
+        double extend[6];
+        this->window->GetCurrentImageData()->GetWholeBoundingBox(extend);
+
+        /// Save the boundary of the volume in world coordinates
+        this->Bounds[0] = this->window->GetCurrentImageData()->GetExtent()[0] * this->window->GetCurrentImageData()->GetSpacing()[0] +
+                this->window->GetCurrentImageData()->GetOrigin()[0];
+        this->Bounds[1] = this->window->GetCurrentImageData()->GetExtent()[1] * this->window->GetCurrentImageData()->GetSpacing()[0] +
+                this->window->GetCurrentImageData()->GetOrigin()[0];
+        this->Bounds[2] = this->window->GetCurrentImageData()->GetExtent()[2] * this->window->GetCurrentImageData()->GetSpacing()[1] +
+                this->window->GetCurrentImageData()->GetOrigin()[1];
+        this->Bounds[3] = this->window->GetCurrentImageData()->GetExtent()[3] * this->window->GetCurrentImageData()->GetSpacing()[1] +
+                this->window->GetCurrentImageData()->GetOrigin()[1];
+        this->Bounds[4] = this->window->GetCurrentImageData()->GetExtent()[4] * this->window->GetCurrentImageData()->GetSpacing()[2] +
+                this->window->GetCurrentImageData()->GetOrigin()[2];
+        this->Bounds[5] = this->window->GetCurrentImageData()->GetExtent()[5] * this->window->GetCurrentImageData()->GetSpacing()[2] +
+                this->window->GetCurrentImageData()->GetOrigin()[2];
+
+        /// Save the limit of the box to increase the scolling effect
+        this->Limits[0] = (this->Bounds[1] - this->Bounds[0]) * this->PadBound;
+        this->Limits[1] = this->Bounds[1] - (this->Bounds[1] - this->Bounds[0]) * this->PadBound;
+        this->Limits[2] = (this->Bounds[5] - this->Bounds[4]) * this->PadBound;
+        this->Limits[3] = this->Bounds[5] - (this->Bounds[5] - this->Bounds[4]) * this->PadBound;
+
+    }
+
+    vtkInteractorStyleTrackballCamera::OnEnter();
+
+}
+
+
+void vtkMyInteractorStyleTrackballCameraOpenHeartXZ::OnLeave()
+{
+    this->Step = 1;
+    vtkInteractorStyleTrackballCamera::OnLeave();
+}
+
+
+void vtkMyInteractorStyleTrackballCameraOpenHeartXZ::GetPickerPosition(double *pos)
+{
+    int X = this->Interactor->GetEventPosition()[0];
+    int Y = this->Interactor->GetEventPosition()[1];
+    this->window->GetPickerXZ()->Pick(X,Y,0.0,this->window->GetXZRenderer());
+    this->window->GetPickerXZ()->GetPickPosition(pos);
+}
+
+
+bool vtkMyInteractorStyleTrackballCameraOpenHeartXZ::IsInside(double *pos)
+{
+    if ( (pos[0]>=this->Bounds[0]) && (pos[0]<=this->Bounds[1]) &&
+         (pos[1]>=this->Bounds[2]) && (pos[1]<=this->Bounds[3]) &&
+         (pos[2]>=this->Bounds[4]) && (pos[2]<=this->Bounds[5]) )
+        return true;
+    else
+        return false;
+}
+
diff --git a/Applications/vtkMyInteractorStyleTrackballCameraOpenHeartXZ.h b/Applications/vtkMyInteractorStyleTrackballCameraOpenHeartXZ.h
new file mode 100644 (file)
index 0000000..b2e0611
--- /dev/null
@@ -0,0 +1,77 @@
+/**
+* Progam made by Olivier Bernard, associate professor
+* at Institut National des Sciences Appliquees (INSA) Lyon,
+* CREATIS-LRMN Laboratory,
+* 69621 Villeurbanne, France,
+* 20th of May 2014
+*/
+
+#ifndef __vtkMyInteractorStyleTrackballCameraOpenHeartXZ_h__
+#define __vtkMyInteractorStyleTrackballCameraOpenHeartXZ_h__
+
+#include <vtkObjectFactory.h>
+#include <vtkInteractorStyleTrackballCamera.h>
+#include "OpenHeartGui.h"
+
+
+class vtkMyInteractorStyleTrackballCameraOpenHeartXZ : public vtkInteractorStyleTrackballCamera
+{
+
+    public:
+
+        void SetOpenHeartGui( OpenHeartGui *win ) { this->window = win; }
+
+        static vtkMyInteractorStyleTrackballCameraOpenHeartXZ *New()
+        {
+            /// First try to create the object from the vtkObjectFactory
+            vtkObject *ret = vtkObjectFactory::CreateInstance ("vtkMyInteractorStyleTrackballCameraOpenHeartXZ");
+            if (ret)
+            {
+                return (vtkMyInteractorStyleTrackballCameraOpenHeartXZ *) ret;
+            }
+            /// If the factory was unable to create the object, then create it here.
+            return (new vtkMyInteractorStyleTrackballCameraOpenHeartXZ);
+        }
+
+
+        virtual void OnLeftButtonDown() { }
+        virtual void OnRightButtonDown() { }
+        virtual void OnMiddleButtonDown() { }
+
+        virtual void OnMouseWheelForward();
+        virtual void OnMouseWheelBackward();
+        virtual void OnEnter();
+        virtual void OnLeave();
+
+
+    protected:
+
+        vtkMyInteractorStyleTrackballCameraOpenHeartXZ() : FlagFirstTime(0), Step(1), PadBound(0.2)
+        {
+            for (int i=0; i<6; i++)
+                Bounds[i] = 0;
+            for (int i=0; i<4; i++)
+                Limits[i] = 0;
+        }
+
+        ~vtkMyInteractorStyleTrackballCameraOpenHeartXZ()
+        {}
+
+        OpenHeartGui *window;
+
+        /// Attributes
+        int FlagFirstTime;
+        double Bounds[6];
+        double Limits[4];
+        int Step;
+        double PadBound;
+
+        /// Methods
+        void GetPickerPosition(double *pos);
+        bool IsInside(double *pos);
+
+};
+
+
+
+#endif
diff --git a/Applications/vtkMyInteractorStyleTrackballCameraOpenHeartYZ.cxx b/Applications/vtkMyInteractorStyleTrackballCameraOpenHeartYZ.cxx
new file mode 100644 (file)
index 0000000..d2f7a62
--- /dev/null
@@ -0,0 +1,184 @@
+/**
+* Progam made by Olivier Bernard, associate professor
+* at Institut National des Sciences Appliquees (INSA) Lyon,
+* CREATIS-LRMN Laboratory,
+* 69621 Villeurbanne, France,
+* 20th of May 2014
+*/
+
+#include <vtkRenderer.h>
+#include <vtkRenderWindow.h>
+#include "vtkMyInteractorStyleTrackballCameraOpenHeartYZ.h"
+
+
+using namespace std;
+
+
+void vtkMyInteractorStyleTrackballCameraOpenHeartYZ::OnMouseWheelForward()
+{
+
+    /// Get picker position
+    double pos[3];
+    this->GetPickerPosition(pos);
+
+    /// Go back to the initial coordinate system before reslicing
+    double posXYZ[3];
+    for (int i=0; i<3; i++)
+        posXYZ[i] = pos[i];
+    this->window->ComputePointBeforeRotation(posXYZ);
+
+    /// Update Slice image
+    if ( this->IsInside(posXYZ) )
+    {
+        /// Compute corresponding step
+        if ( (posXYZ[1] >= this->Limits[0] ) &&
+             (posXYZ[1] <= this->Limits[1] ) &&
+             (posXYZ[2] >= this->Limits[2] ) &&
+             (posXYZ[2] <= this->Limits[3] ) )
+            this->Step = 1;
+        else
+            this->Step = 5;
+
+        /// Compute new slice position
+        double limit = this->Bounds[1];
+        posXYZ[0] += this->Step * this->window->GetCurrentImageData()->GetSpacing()[0];
+        if ( posXYZ[0] <= limit )
+            this->window->GetRendererProperties()->position[0] += this->Step * this->window->GetCurrentImageData()->GetSpacing()[0];
+
+        /// Update Slice text
+        if ( this->window->GetFlagDisplayText() )
+        {
+            int slice = (int)( (this->window->GetRendererProperties()->position[0] -
+                                this->window->GetCurrentImageData()->GetOrigin()[0]) /
+                                this->window->GetCurrentImageData()->GetSpacing()[0] + 0.5f );
+            QString strSlice;
+            strSlice.sprintf("Slice: %d",slice);
+            this->window->GetRendererProperties()->TextMapperSlice->SetInput(strSlice.toStdString().c_str());
+        }
+
+        /// Update renderers
+        this->window->GetRendererProperties()->xIPW->SetSlicePosition(this->window->GetRendererProperties()->position[0]);
+        this->window->GetRendererProperties()->yzIPW->SetSlicePosition(this->window->GetRendererProperties()->position[0]);
+        this->window->GetRenderWindow()->Render();
+        this->window->GetYZRenderer()->ResetCameraClippingRange();
+        this->window->GetRenderWindowYZ()->Render();
+    }
+
+}
+
+
+void vtkMyInteractorStyleTrackballCameraOpenHeartYZ::OnMouseWheelBackward()
+{
+
+    /// Get picker position
+    double pos[3];
+    this->GetPickerPosition(pos);
+
+    /// Go back to the initial coordinate system before reslicing
+    double posXYZ[3];
+    for (int i=0; i<3; i++)
+        posXYZ[i] = pos[i];
+    this->window->ComputePointBeforeRotation(posXYZ);
+
+    /// Update Slice image
+    if ( this->IsInside(posXYZ) )
+    {
+        /// Compute corresponding step
+        if ( (posXYZ[1] >= this->Limits[0] ) &&
+             (posXYZ[1] <= this->Limits[1] ) &&
+             (posXYZ[2] >= this->Limits[2] ) &&
+             (posXYZ[2] <= this->Limits[3] ) )
+            this->Step = 1;
+        else
+            this->Step = 5;
+
+        /// Compute new slice position
+        posXYZ[0] -= this->Step * this->window->GetCurrentImageData()->GetSpacing()[0];
+        if ( posXYZ[0] >= 0 )
+            this->window->GetRendererProperties()->position[0] -= this->Step * this->window->GetCurrentImageData()->GetSpacing()[0];
+
+        /// Update Slice text
+        if ( this->window->GetFlagDisplayText() )
+        {
+            int slice = (int)( (this->window->GetRendererProperties()->position[0] -
+                                this->window->GetCurrentImageData()->GetOrigin()[0]) /
+                                this->window->GetCurrentImageData()->GetSpacing()[0] + 0.5f );
+            QString strSlice;
+            strSlice.sprintf("Slice: %d",slice);
+            this->window->GetRendererProperties()->TextMapperSlice->SetInput(strSlice.toStdString().c_str());
+        }
+
+        /// Update renderers
+        this->window->GetRendererProperties()->xIPW->SetSlicePosition(this->window->GetRendererProperties()->position[0]);
+        this->window->GetRendererProperties()->yzIPW->SetSlicePosition(this->window->GetRendererProperties()->position[0]);
+        this->window->GetRenderWindow()->Render();
+        this->window->GetYZRenderer()->ResetCameraClippingRange();
+        this->window->GetRenderWindowYZ()->Render();
+    }
+
+}
+
+
+void vtkMyInteractorStyleTrackballCameraOpenHeartYZ::OnEnter()
+{
+
+    if ( !this->FlagFirstTime )
+    {
+
+        /// Set flag to 1 to never enter again in this part of the code
+        this->FlagFirstTime = 1;
+        double extend[6];
+        this->window->GetCurrentImageData()->GetWholeBoundingBox(extend);
+
+        /// Save the boundary of the volume in world coordinates
+        this->Bounds[0] = this->window->GetCurrentImageData()->GetExtent()[0] * this->window->GetCurrentImageData()->GetSpacing()[0] +
+                this->window->GetCurrentImageData()->GetOrigin()[0];
+        this->Bounds[1] = this->window->GetCurrentImageData()->GetExtent()[1] * this->window->GetCurrentImageData()->GetSpacing()[0] +
+                this->window->GetCurrentImageData()->GetOrigin()[0];
+        this->Bounds[2] = this->window->GetCurrentImageData()->GetExtent()[2] * this->window->GetCurrentImageData()->GetSpacing()[1] +
+                this->window->GetCurrentImageData()->GetOrigin()[1];
+        this->Bounds[3] = this->window->GetCurrentImageData()->GetExtent()[3] * this->window->GetCurrentImageData()->GetSpacing()[1] +
+                this->window->GetCurrentImageData()->GetOrigin()[1];
+        this->Bounds[4] = this->window->GetCurrentImageData()->GetExtent()[4] * this->window->GetCurrentImageData()->GetSpacing()[2] +
+                this->window->GetCurrentImageData()->GetOrigin()[2];
+        this->Bounds[5] = this->window->GetCurrentImageData()->GetExtent()[5] * this->window->GetCurrentImageData()->GetSpacing()[2] +
+                this->window->GetCurrentImageData()->GetOrigin()[2];
+
+        /// Save the limit of the box to increase the scolling effect
+        this->Limits[0] = (this->Bounds[3] - this->Bounds[2]) * this->PadBound;
+        this->Limits[1] = this->Bounds[3] - (this->Bounds[3] - this->Bounds[2]) * this->PadBound;
+        this->Limits[2] = (this->Bounds[5] - this->Bounds[4]) * this->PadBound;
+        this->Limits[3] = this->Bounds[5] - (this->Bounds[5] - this->Bounds[4]) * this->PadBound;
+
+    }
+
+    vtkInteractorStyleTrackballCamera::OnEnter();
+
+}
+
+
+void vtkMyInteractorStyleTrackballCameraOpenHeartYZ::OnLeave()
+{
+    this->Step = 1;
+    vtkInteractorStyleTrackballCamera::OnLeave();
+}
+
+
+void vtkMyInteractorStyleTrackballCameraOpenHeartYZ::GetPickerPosition(double *pos)
+{
+    int X = this->Interactor->GetEventPosition()[0];
+    int Y = this->Interactor->GetEventPosition()[1];
+    this->window->GetPickerYZ()->Pick(X,Y,0.0,this->window->GetYZRenderer());
+    this->window->GetPickerYZ()->GetPickPosition(pos);
+}
+
+
+bool vtkMyInteractorStyleTrackballCameraOpenHeartYZ::IsInside(double *pos)
+{
+    if ( (pos[0]>=this->Bounds[0]) && (pos[0]<=this->Bounds[1]) &&
+         (pos[1]>=this->Bounds[2]) && (pos[1]<=this->Bounds[3]) &&
+         (pos[2]>=this->Bounds[4]) && (pos[2]<=this->Bounds[5]) )
+        return true;
+    else
+        return false;
+}
diff --git a/Applications/vtkMyInteractorStyleTrackballCameraOpenHeartYZ.h b/Applications/vtkMyInteractorStyleTrackballCameraOpenHeartYZ.h
new file mode 100644 (file)
index 0000000..3ea7372
--- /dev/null
@@ -0,0 +1,76 @@
+/**
+* Progam made by Olivier Bernard, associate professor
+* at Institut National des Sciences Appliquees (INSA) Lyon,
+* CREATIS-LRMN Laboratory,
+* 69621 Villeurbanne, France,
+* 20th of May 2014
+*/
+
+#ifndef __vtkMyInteractorStyleTrackballCameraOpenHeartYZ_h__
+#define __vtkMyInteractorStyleTrackballCameraOpenHeartYZ_h__
+
+#include <vtkObjectFactory.h>
+#include <vtkInteractorStyleTrackballCamera.h>
+#include "OpenHeartGui.h"
+
+
+class vtkMyInteractorStyleTrackballCameraOpenHeartYZ : public vtkInteractorStyleTrackballCamera
+{
+
+    public:
+
+        void SetOpenHeartGui( OpenHeartGui *win ) { this->window = win; }
+
+        static vtkMyInteractorStyleTrackballCameraOpenHeartYZ *New()
+        {
+            /// First try to create the object from the vtkObjectFactory
+            vtkObject *ret = vtkObjectFactory::CreateInstance ("vtkMyInteractorStyleTrackballCameraOpenHeartYZ");
+            if (ret)
+            {
+                return (vtkMyInteractorStyleTrackballCameraOpenHeartYZ *) ret;
+            }
+            /// If the factory was unable to create the object, then create it here.
+            return (new vtkMyInteractorStyleTrackballCameraOpenHeartYZ);
+        }
+
+
+        virtual void OnLeftButtonDown() { }
+        virtual void OnRightButtonDown() { }
+        virtual void OnMiddleButtonDown() { }
+
+        virtual void OnMouseWheelForward();
+        virtual void OnMouseWheelBackward();
+        virtual void OnEnter();
+        virtual void OnLeave();
+
+
+    protected:
+
+        vtkMyInteractorStyleTrackballCameraOpenHeartYZ() : FlagFirstTime(0), Step(1), PadBound(0.2)
+        {
+            for (int i=0; i<6; i++)
+                Bounds[i] = 0;
+            for (int i=0; i<4; i++)
+                Limits[i] = 0;
+        }
+
+        ~vtkMyInteractorStyleTrackballCameraOpenHeartYZ()
+        {}
+
+        OpenHeartGui *window;
+
+        /// Attributes
+        int FlagFirstTime;
+        double Bounds[6];
+        double Limits[4];
+        int Step;
+        double PadBound;
+
+        /// Methods
+        void GetPickerPosition(double *pos);
+        bool IsInside(double *pos);
+
+};
+
+
+#endif
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644 (file)
index 0000000..1f02122
--- /dev/null
@@ -0,0 +1,58 @@
+PROJECT(OPENHEART)
+CMAKE_MINIMUM_REQUIRED(VERSION 2.4)
+#MARK_AS_ADVANCED( FORCE CMAKE_BACKWARDS_COMPATIBILITY )
+
+# for CMake 2.6 corrected behaviour (see "cmake --help-policy CMP0003")
+IF(COMMAND cmake_policy AND ${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} GREATER 4)
+  CMAKE_POLICY(SET CMP0003 NEW)
+#  CMAKE_POLICY(SET CMP0005 NEW)
+ENDIF(COMMAND cmake_policy AND ${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} GREATER 4)
+# --------------------------------------------------------------------------
+
+
+# --------------------- OPTIONS OF THE PROJECT -----------------------------
+# Build static lib by default
+
+OPTION(BUILD_SHARED_LIBS "Build OPENHEART with shared libraries." OFF)
+OPTION(BUILD_DOCUMENTATION "Build the html documentation with doxygen." OFF)
+MARK_AS_ADVANCED(BUILD_WXWIDGETS_GUI)
+
+#
+SET (EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin CACHE PATH "Single output directory for building all executables.")
+SET (LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin CACHE PATH "Single output directory for building all libraries.")
+MARK_AS_ADVANCED(LIBRARY_OUTPUT_PATH EXECUTABLE_OUTPUT_PATH)
+
+# -------------------- DEPENDENCIES TO EXTERNALS ---------------------------
+# Find and load VTK settings.
+#INCLUDE(${CMAKE_ROOT}/Modules/FindVTK.cmake)
+FIND_PACKAGE(VTK REQUIRED)
+IF(VTK_FOUND)
+    INCLUDE(${VTK_USE_FILE})
+ENDIF(VTK_FOUND)
+
+FIND_PACKAGE(Qt4 REQUIRED)
+INCLUDE(${QT_USE_FILE})
+
+# --------------------------------------------------------------------------
+# Find and load Doxygen settings (when required)
+IF(BUILD_DOCUMENTATION)
+    FIND_PACKAGE(Doxygen)
+ENDIF(BUILD_DOCUMENTATION)
+
+
+SET(OPENHEART_PROJECT_DIR ${PROJECT_SOURCE_DIR})
+SET(OPENHEART_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/Common)
+SET(APPLICATIONS_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/Applications)
+
+
+# -------------------------- DEFAULT DIR TO HANDLE -----------------------------
+ADD_SUBDIRECTORY(Common)
+ADD_SUBDIRECTORY(Applications)
+
+
+IF(BUILD_DOCUMENTATION)
+    ADD_SUBDIRECTORY(doc)
+ENDIF(BUILD_DOCUMENTATION)
+
+## eof - CMakeLists.txt
+
diff --git a/Common/CMakeLists.txt b/Common/CMakeLists.txt
new file mode 100644 (file)
index 0000000..3317804
--- /dev/null
@@ -0,0 +1,11 @@
+
+INCLUDE_DIRECTORIES(
+    ${VTK_INCLUDE_DIR}
+)
+
+# --------------------------------------------------------------------------
+# Library compilation
+ADD_LIBRARY(common
+  vtkOptimizedImageData.cxx
+)
+
diff --git a/Common/CMakeLists.txt~ b/Common/CMakeLists.txt~
new file mode 100644 (file)
index 0000000..3360b91
--- /dev/null
@@ -0,0 +1,12 @@
+
+INCLUDE_DIRECTORIES(
+    ${VTK_INCLUDE_DIR}
+)
+
+# --------------------------------------------------------------------------
+# Library compilation
+ADD_LIBRARY(common
+  vtkOptimizedImageData.cxx
+  vtkMyInteractorStyleTrackballCameraOpenHeart.cxx
+)
+
diff --git a/Common/vtkOptimizedImageData.cxx b/Common/vtkOptimizedImageData.cxx
new file mode 100644 (file)
index 0000000..d9f564b
--- /dev/null
@@ -0,0 +1,20 @@
+/**
+* Progam made by Olivier Bernard, associate professor
+* at Institut National des Sciences Appliquees (INSA) Lyon,
+* CREATIS-LRMN Laboratory,
+* 69621 Villeurbanne, France,
+* 31th of march 2011
+*/
+
+#include "vtkOptimizedImageData.h"
+
+using namespace std;
+
+
+template<class T>
+void vtkOptimizedImageData<T>::PrintInfo()
+{
+    cout << "Image pointer: " << data << endl;
+    cout << "Image dimension: [" << dimX << "," << dimY << "," << dimZ << "]" << endl;
+}
+
diff --git a/Common/vtkOptimizedImageData.h b/Common/vtkOptimizedImageData.h
new file mode 100644 (file)
index 0000000..a0fbd75
--- /dev/null
@@ -0,0 +1,181 @@
+/**
+* Progam made by Olivier Bernard, associate professor
+* at Institut National des Sciences Appliquees (INSA) Lyon,
+* CREATIS-LRMN Laboratory,
+* 69621 Villeurbanne, France,
+* 31th of march 2011
+*/
+
+#ifndef __vtkOptimizedImageData_h__
+#define __vtkOptimizedImageData_h__
+
+#include <vtkObjectFactory.h>
+#include <vtkImageData.h>
+#include <vtkPointData.h>
+
+
+using namespace std;
+
+template<class T>
+class VTK_EXPORT vtkOptimizedImageData : public vtkImageData
+{
+
+    private:
+
+        T* data;
+        int dimX;
+        int dimY;
+        int dimZ;
+
+    protected:
+
+        vtkOptimizedImageData() : data(NULL) {}
+        ~vtkOptimizedImageData() {}
+
+    public:
+
+        static vtkOptimizedImageData *New()
+        {
+            vtkObject* ret = vtkObjectFactory::CreateInstance("vtkOptimizedImageData");
+            if(ret) { return (vtkOptimizedImageData*)ret; }
+            // If the factory was unable to create the object, then create it here.
+            return (new vtkOptimizedImageData);
+        }
+
+        vtkOptimizedImageData& operator=(vtkImageData &m)
+        {
+            this->DeepCopy(&m);
+            return *this;
+        }
+
+        T& operator()(int x, int y, int z)
+        {
+            if ( !data ) {
+                data = static_cast<T*>(this->PointData->GetScalars()->GetVoidPointer(0));
+                dimX = this->GetDimensions()[0];
+                dimY = this->GetDimensions()[1];
+                dimZ = this->GetDimensions()[2];
+            }
+            return data[x+y*dimX+z*dimX*dimY];
+//            if ( (x>=0 && x<dimX) && (y>=0 && y<dimY) && (z>=0 && z<dimZ) )
+//                return data[x+y*dimX+z*dimX*dimY];
+//            else
+//            {
+//                cout << "Take care, try to access a point out of the volume" << endl;
+//                return data[0];
+//            }
+        }
+
+        double operator()(double x, double y, double z) // added by Daniel
+        {
+            if ( !data ) {
+                data = static_cast<T*>(this->PointData->GetScalars()->GetVoidPointer(0));
+                dimX = this->GetDimensions()[0];
+                dimY = this->GetDimensions()[1];
+                dimZ = this->GetDimensions()[2];
+            }
+
+            int x0,y0,z0;
+            x0=(int) x;
+            y0=(int) y;
+            z0=(int) z;
+
+//            cout << x << " " << y << " " << z << " " << endl;
+//            cout << x0 << " " << y0 << " " << z0 << " " << endl;
+
+
+            int x1,y1,z1;
+            x1=x0+1;
+            y1=y0+1;
+            z1=z0+1;
+
+//            cout << x1 << " " << y1 << " " << z1 << " " << endl;
+
+            double xd,yd,zd;
+            xd=x-x0;
+            yd=y-y0;
+            zd=z-z0;
+
+//            cout << xd << " " << yd << " " << zd << " " << endl;
+
+            double xdi=1.0-xd;
+            double ydi=1.0-yd;
+            double zdi=1.0-zd;
+
+            double c00, c10, c01, c11;
+            c00 = data[x0+y0*dimX+z0*dimX*dimY]*xdi+data[x1+y0*dimX+z0*dimX*dimY]*xd;
+            c10 = data[x0+y1*dimX+z0*dimX*dimY]*xdi+data[x1+y1*dimX+z0*dimX*dimY]*xd;
+            c01 = data[x0+y0*dimX+z1*dimX*dimY]*xdi+data[x1+y0*dimX+z1*dimX*dimY]*xd;
+            c11 = data[x0+y1*dimX+z1*dimX*dimY]*xdi+data[x1+y1*dimX+z1*dimX*dimY]*xd;
+
+            double c0,c1;
+            c0=c00*ydi+c10*yd;
+            c1=c01*ydi+c11*yd;
+
+            return c0*zdi+c1*zd;
+
+        }
+
+        T& operator()(int x, int y)
+        {
+            if ( !data ) {
+                data = static_cast<T*>(this->PointData->GetScalars()->GetVoidPointer(0));
+                dimX = this->GetDimensions()[0];
+                dimY = this->GetDimensions()[1];
+                dimZ = 1;
+            }
+            if ( (x>=0 && x<dimX) && (y>=0 && y<dimY) )
+                return data[x+y*dimX];
+            else
+            {
+                cout << "Take care, try to access a point out of the volume" << endl;
+                return data[0];
+            }
+        }
+
+        T& operator()(int k)
+        {
+            if ( !data ) {
+                data = static_cast<T*>(this->PointData->GetScalars()->GetVoidPointer(0));
+                dimX = this->GetDimensions()[0];
+                dimY = this->GetDimensions()[1];
+                dimZ = this->GetDimensions()[2];
+            }
+            if (k>=0 && k<dimX*dimY*dimZ)
+                return data[k];
+            else
+            {
+                cout << "Take care, try to access a point out of the volume" << endl;
+                return data[0];
+            }
+        }
+
+        void PrintDataPointer()
+        {
+                cout << "data = " << this->PointData->GetScalars()->GetVoidPointer(0) << endl;
+        }
+
+
+        void Update()
+        {
+               AllocateScalars();
+            this->Superclass::Update();
+        }
+
+        void PrintInfo();
+
+        /// Added by Daniel
+        void CopyImage(vtkDataObject *src)
+        {
+            this->DeepCopy(src);
+            data = static_cast<T*>(this->PointData->GetScalars()->GetVoidPointer(0));
+            dimX = this->GetDimensions()[0];
+            dimY = this->GetDimensions()[1];
+            dimZ = this->GetDimensions()[2];
+        }
+
+
+};
+
+
+#endif
diff --git a/Config/ConfigIschemicCase.txt~ b/Config/ConfigIschemicCase.txt~
new file mode 100644 (file)
index 0000000..3dc43c3
--- /dev/null
@@ -0,0 +1,3 @@
+/home/bernard/dataUS/3D_simulations/IschemicCase/images/frame
+/home/bernard/dataUS/3D_simulations/IschemicCase/meshes/mesh_
+1
diff --git a/Config/ConfigOpenHeart.txt b/Config/ConfigOpenHeart.txt
new file mode 100644 (file)
index 0000000..855c083
--- /dev/null
@@ -0,0 +1,2 @@
+/home/bernard/Dropbox/MICCAI_Challenge/data/Training/Training_images/Patient1/Patient1_frame
+20
diff --git a/Config/ConfigOpenHeart.txt~ b/Config/ConfigOpenHeart.txt~
new file mode 100644 (file)
index 0000000..60e38b9
--- /dev/null
@@ -0,0 +1,2 @@
+/home/bernard/Dropbox/MICCAI_Challenge/data/Training/Training_images/Patient9/Patient9_frame
+18
diff --git a/Config/HeartBeatsConfig (copy).txt~ b/Config/HeartBeatsConfig (copy).txt~
new file mode 100644 (file)
index 0000000..16c604b
--- /dev/null
@@ -0,0 +1,6 @@
+/home/bernard/dataUS/3D_sequences/27671405_4D.mhd
+24
+16
+200
+1
+8
diff --git a/Config/HeartBeatsConfig.txt~ b/Config/HeartBeatsConfig.txt~
new file mode 100644 (file)
index 0000000..cbfcf11
--- /dev/null
@@ -0,0 +1,6 @@
+/home/bernard/dataUS/3D_sequences/49483879_4D.mhd
+24
+16
+200
+1
+8
diff --git a/Config/HeartSimuConfig.txt~ b/Config/HeartSimuConfig.txt~
new file mode 100644 (file)
index 0000000..e0585e2
--- /dev/null
@@ -0,0 +1,2 @@
+/home/bernard/Dropbox/MICCAI_Challenge/data/Training/Training_images/Patient1/Patient1_frame
+33
diff --git a/Config/HeartSimuConfig_tmp.txt~ b/Config/HeartSimuConfig_tmp.txt~
new file mode 100644 (file)
index 0000000..26de337
--- /dev/null
@@ -0,0 +1,6 @@
+/home/bernard/Dropbox/dataThrombus/Patient1/Images/Patient1_ROI.mhd
+24
+16
+200
+1
+8
diff --git a/test.txt~ b/test.txt~
new file mode 100644 (file)
index 0000000..e69de29