--- /dev/null
+
+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 )
+
+
+
--- /dev/null
+
+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 )
+
+
+
--- /dev/null
+/**
+* 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];
+
+}
--- /dev/null
+/**
+* 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
+
--- /dev/null
+<?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&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>
--- /dev/null
+/**
+* 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();
+
+}
+
--- /dev/null
+/********************************************************************************
+** 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
--- /dev/null
+/**
+* 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;
+}
+
+
--- /dev/null
+/**
+* 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
--- /dev/null
+/**
+* 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;
+}
+
--- /dev/null
+/**
+* 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
--- /dev/null
+/**
+* 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;
+}
+
--- /dev/null
+/**
+* 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
--- /dev/null
+/**
+* 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;
+}
--- /dev/null
+/**
+* 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
--- /dev/null
+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
+
--- /dev/null
+
+INCLUDE_DIRECTORIES(
+ ${VTK_INCLUDE_DIR}
+)
+
+# --------------------------------------------------------------------------
+# Library compilation
+ADD_LIBRARY(common
+ vtkOptimizedImageData.cxx
+)
+
--- /dev/null
+
+INCLUDE_DIRECTORIES(
+ ${VTK_INCLUDE_DIR}
+)
+
+# --------------------------------------------------------------------------
+# Library compilation
+ADD_LIBRARY(common
+ vtkOptimizedImageData.cxx
+ vtkMyInteractorStyleTrackballCameraOpenHeart.cxx
+)
+
--- /dev/null
+/**
+* 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;
+}
+
--- /dev/null
+/**
+* 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
--- /dev/null
+/home/bernard/dataUS/3D_simulations/IschemicCase/images/frame
+/home/bernard/dataUS/3D_simulations/IschemicCase/meshes/mesh_
+1
--- /dev/null
+/home/bernard/Dropbox/MICCAI_Challenge/data/Training/Training_images/Patient1/Patient1_frame
+20
--- /dev/null
+/home/bernard/Dropbox/MICCAI_Challenge/data/Training/Training_images/Patient9/Patient9_frame
+18
--- /dev/null
+/home/bernard/dataUS/3D_sequences/27671405_4D.mhd
+24
+16
+200
+1
+8
--- /dev/null
+/home/bernard/dataUS/3D_sequences/49483879_4D.mhd
+24
+16
+200
+1
+8
--- /dev/null
+/home/bernard/Dropbox/MICCAI_Challenge/data/Training/Training_images/Patient1/Patient1_frame
+33
--- /dev/null
+/home/bernard/Dropbox/dataThrombus/Patient1/Images/Patient1_ROI.mhd
+24
+16
+200
+1
+8