2 * Progam made by Olivier Bernard, associate professor
3 * at Institut National des Sciences Appliquees (INSA) Lyon,
5 * 69621 Villeurbanne, France,
9 #include "OpenHeartGui.h"
11 #include <vtkObjectFactory.h>
12 #include <vtkRenderWindow.h>
13 #include <vtkRenderer.h>
14 #include <vtkImageData.h>
15 #include <vtkTextProperty.h>
16 #include <vtkProperty.h>
17 #include <vtkRendererCollection.h>
18 #include <vtkRenderer.h>
19 #include <vtkInteractorStyleTrackballCamera.h>
20 #include <vtkCamera.h>
21 #include <vtkImageGaussianSmooth.h>
22 #include <vtkMarchingCubes.h>
23 #include <vtkDataSetMapper.h>
24 #include <vtkPolyDataMapper.h>
25 #include <vtkCutter.h>
26 #include <vtkSphereSource.h>
27 #include <vtkInteractorStyleSwitch.h>
28 #include <vtkTextMapper.h>
30 #include <vtkMetaImageWriter.h>
31 #include <vtkDepthSortPolyData.h>
32 #include <vtkTimerLog.h>
33 #include <vtkTransform.h>
34 #include <vtkTransformPolyDataFilter.h>
35 #include <vtkContextView.h>
37 #include <vtkFloatArray.h>
38 #include <vtkChartXY.h>
40 #include <vtkContextScene.h>
42 #include <vtkCamera.h>
43 #include <vtkAxesActor.h>
44 #include <vtkOrientationMarkerWidget.h>
45 #include <vtkCaptionActor2D.h>
46 #include <vtkMetaImageReader.h>
47 #include <vtkImageCast.h>
48 #include <vtkUnstructuredGridReader.h>
49 #include <vtkUnstructuredGrid.h>
50 #include <vtkGenericDataObjectReader.h>
51 #include <vtkCellArray.h>
52 #include <vtkXMLPolyDataReader.h>
53 #include <vtkPolyDataReader.h>
54 #include <vtkUnstructuredGridGeometryFilter.h>
55 #include <vtkDepthSortPolyData.h>
56 #include <vtkLineSource.h>
57 #include <vtkSmartPointer.h>
58 #include <vtkIntersectionPolyDataFilter.h>
59 #include <vtkTriangleFilter.h>
60 #include <vtkImageData.h>
61 #include <vtkImageReslice.h>
62 #include <vtkImageMapper.h>
63 #include <vtkSphereSource.h>
65 #include <vtkOutlineFilter.h>
66 #include "vtkMyInteractorStyleTrackballCameraOpenHeart.h"
67 #include "vtkMyInteractorStyleTrackballCameraOpenHeartXY.h"
68 #include "vtkMyInteractorStyleTrackballCameraOpenHeartXZ.h"
69 #include "vtkMyInteractorStyleTrackballCameraOpenHeartYZ.h"
70 #include <QResizeEvent>
74 #define CONFIG_FILE "../../Config/ConfigOpenHeart.txt"
77 // ****************************************************************
78 // ****************************************************************
79 // ****************************************************************
80 class vtkMyChartXY : public vtkChartXY
83 bool MouseButtonPressEvent(const vtkContextMouseEvent &mouse) { return true; }
84 bool MouseWheelEvent(const vtkContextMouseEvent &mouse, int delta) { return true; }
85 bool MouseMoveEvent(const vtkContextMouseEvent &mouse) { return true; }
86 bool MouseButtonReleaseEvent(const vtkContextMouseEvent &mouse) { return true; }
91 // ****************************************************************
92 // ****************************************************************
93 // ****************************************************************
94 OpenHeartGui::OpenHeartGui()
99 this->InstantiateQtVtkRenderers();
101 /// Set colors of the interface
102 this->SetInterfaceColors();
104 /// Allocate attributes
105 for ( int k=0; k<3; k++ )
107 this->PreviousFrame = 0;
108 this->CurrentFrame = 0;
109 this->NumberOfVolumes = 0;
111 this->TableChart = 0;
112 this->Properties = new RendererProperties;
113 this->ViewButton = 0;
114 this->MeshRepresentation = 0;
116 this->ZoomLabel = 1.6;
117 this->ZoomMain = 1.5;
118 this->RotationMatrix = vtkSmartPointer<vtkMatrix4x4>::New();
119 this->RotationMatrix->Identity();
120 this->TransformViewOrientation = vtkSmartPointer<vtkTransform>::New();
121 this->RotationMatrixInv = vtkSmartPointer<vtkMatrix4x4>::New();
122 this->RotationMatrixInv->Identity();
123 this->TransformViewOrientationInv = vtkSmartPointer<vtkTransform>::New();
124 this->OrientationWidget = vtkSmartPointer<vtkOrientationMarkerWidget>::New();
127 this->FlagInterpolation = 0;
128 this->FlagDisplayMesh = 0;
129 this->FlagDisplayMeshContours = 0;
130 this->FlagDisplayMeshContourX = 0;
131 this->FlagDisplayMeshContourY = 0;
132 this->FlagDisplayMeshContourZ = 0;
133 this->FlagLoopEndToBegin = 0;
134 this->FlagLoopBeginToEnd = 0;
136 this->FlagDisplayText = 1;
137 this->FlagHidePlan = 0;
138 this->FlagLongAxis = 0;
139 this->FlagDisplayApexPoint = 0;
140 this->FlagDisplayBasalPoint = 0;
141 this->FlagDisplayMeshContours = 1;
142 this->FlagDisplayLongAxis = 0;
143 this->FlagReslice = 0;
145 /// Widget management
147 this->InitProperties();
149 this->SetCustomInteractorStyle();
151 /// Read 3D volume and create corresponding OpenHeart
152 std::ifstream file(CONFIG_FILE, std::ifstream::in);
153 std::string inputFilename;
154 file >> inputFilename;
155 file >> this->NumberOfVolumes;
157 /// Load sequence of volumes
158 this->CreateFromSequenceDataPointer(inputFilename);
160 /// Manage main window display
161 /// Force to view XZ orientation at initialization
164 /// Initialize text displayed in the main window
167 /// Initialize the orientation axes after rendering the volume
168 this->InitOrientationAxes();
170 /// Manage XY window display
171 this->qVTKXY->GetRenderWindow()->Render();
173 /// Manage XZ window display
174 this->qVTKXZ->GetRenderWindow()->Render();
176 /// Manage YZ window display
177 this->qVTKYZ->GetRenderWindow()->Render();
180 this->scrollBar->setMaximum(this->NumberOfVolumes-1);
181 this->SliderMeshAlpha->setMaximum(100);
182 this->SliderMeshAlpha->setSingleStep(1);
183 this->SliderMeshAlpha->setValue(20);
185 /// Initialized the chart part of the interface
186 this->ViewChart = vtkSmartPointer<vtkContextView>::New();
187 this->ViewChart->SetInteractor(this->qVTKChart->GetInteractor());
188 this->qVTKChart->SetRenderWindow(this->ViewChart->GetRenderWindow());
189 this->qVTKChart->GetRenderWindow()->SetSize(478,478);
190 this->ViewChart->GetRenderer()->SetBackground(255./255.,255./255.,255./255.);
193 /// Instantiate timer for the player
194 Timer = new QTimer(this);
196 /// Instantiate Qt events
197 connect(this->scrollBar, SIGNAL(valueChanged(int)), this, SLOT(slotRefreshViewer(int)));
198 connect(this->SliderMeshAlpha, SIGNAL(valueChanged(int)), this, SLOT(slotMeshAlpha(int)));
199 connect(this->pushButtonPlay, SIGNAL(clicked()), this, SLOT(slotPlay()));
200 connect(this->pushButtonXY, SIGNAL(clicked()), this, SLOT(slotXYView()));
201 connect(this->pushButtonXZ, SIGNAL(clicked()), this, SLOT(slotXZView()));
202 connect(this->pushButtonYZ, SIGNAL(clicked()), this, SLOT(slotYZView()));
203 connect(this->pushButton3D, SIGNAL(clicked()), this, SLOT(slot3DView()));
204 connect(this->pushButtonMesh, SIGNAL(clicked()), this, SLOT(slotMeshView()));
205 connect(this->pushButtonMeshRepresentation, SIGNAL(clicked()), this, SLOT(slotMeshRepresentation()));
206 connect(this->pushButtonMeshColor, SIGNAL(clicked()), this, SLOT(slotMeshColor()));
207 connect(this->pushButtonCutter, SIGNAL(clicked()), this, SLOT(slotMeshCutter()));
208 connect(this->Timer, SIGNAL(timeout()), this, SLOT(slotTimerEvent()));
209 connect(this->tabWidgetOption, SIGNAL(currentChanged(int)), this, SLOT(slotTabChange(int)));
210 connect(this->pushButtonBasalPoint, SIGNAL(clicked()), this, SLOT(slotBasalPoint()));
211 connect(this->pushButtonApexPoint, SIGNAL(clicked()), this, SLOT(slotApexPoint()));
212 connect(this->pushButtonReslice, SIGNAL(clicked()), this, SLOT(slotReslice()));
214 /// Update coords as we move through the window
215 Connections = vtkEventQtSlotConnect::New();
216 Connections->Connect(this->qVTK->GetRenderWindow()->GetInteractor(),
217 vtkCommand::MouseMoveEvent,
219 SLOT(slotUpdateCoords(vtkObject*)));
224 OpenHeartGui::~OpenHeartGui()
227 Connections->Delete();
232 void OpenHeartGui::InstantiateQtVtkRenderers()
235 /// ****************************************************************
236 /// Create the main window
237 vtkSmartPointer<vtkRenderWindow> renwin = vtkSmartPointer<vtkRenderWindow>::New();
238 renwin->StereoCapableWindowOn();
240 /// Activate 3DConnexion device
241 this->qVTK->SetUseTDx(true);
242 this->qVTK->SetRenderWindow(renwin);
244 /// Initialize interactor
245 this->Interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
246 this->Interactor = static_cast<vtkRenderWindowInteractor *>(this->qVTK->GetInteractor()->GetRenderWindow()->GetInteractor());
249 this->Ren = vtkSmartPointer<vtkRenderer>::New();
250 this->qVTK->GetRenderWindow()->AddRenderer(this->Ren);
251 this->Ren->SetBackground(0,0,0);
252 this->Ren->GetActiveCamera()->SetParallelProjection(1);
255 /// ****************************************************************
257 vtkSmartPointer<vtkRenderWindow> renwinXY = vtkSmartPointer<vtkRenderWindow>::New();
258 renwinXY->StereoCapableWindowOn();
260 /// Activate 3DConnexion device
261 this->qVTKXY->SetUseTDx(true);
262 this->qVTKXY->SetRenderWindow(renwinXY);
264 /// Initialize interactor
265 this->InteractorXY = vtkSmartPointer<vtkRenderWindowInteractor>::New();
266 this->InteractorXY = static_cast<vtkRenderWindowInteractor *>(this->qVTKXY->GetInteractor()->GetRenderWindow()->GetInteractor());
269 this->RenXY = vtkSmartPointer<vtkRenderer>::New();
270 this->qVTKXY->GetRenderWindow()->AddRenderer(this->RenXY);
271 this->RenXY->SetBackground(0,0,0);
272 this->RenXY->GetActiveCamera()->SetParallelProjection(1);
275 /// ****************************************************************
277 vtkSmartPointer<vtkRenderWindow> renwinXZ = vtkSmartPointer<vtkRenderWindow>::New();
278 renwinXZ->StereoCapableWindowOn();
280 /// Activate 3DConnexion device
281 this->qVTKXZ->SetUseTDx(true);
282 this->qVTKXZ->SetRenderWindow(renwinXZ);
284 /// Initialize interactor
285 this->InteractorXZ = vtkSmartPointer<vtkRenderWindowInteractor>::New();
286 this->InteractorXZ = static_cast<vtkRenderWindowInteractor *>(this->qVTKXZ->GetInteractor()->GetRenderWindow()->GetInteractor());
289 this->RenXZ = vtkSmartPointer<vtkRenderer>::New();
290 this->qVTKXZ->GetRenderWindow()->AddRenderer(this->RenXZ);
291 this->RenXZ->SetBackground(0,0,0);
292 this->RenXZ->GetActiveCamera()->SetParallelProjection(1);
295 /// ****************************************************************
297 vtkSmartPointer<vtkRenderWindow> renwinYZ = vtkSmartPointer<vtkRenderWindow>::New();
298 renwinYZ->StereoCapableWindowOn();
300 /// Activate 3DConnexion device
301 this->qVTKYZ->SetUseTDx(true);
302 this->qVTKYZ->SetRenderWindow(renwinYZ);
304 /// Initialize interactor
305 this->InteractorYZ = static_cast<vtkRenderWindowInteractor *>(this->qVTKYZ->GetInteractor()->GetRenderWindow()->GetInteractor());
308 this->RenYZ = vtkSmartPointer<vtkRenderer>::New();
309 this->qVTKYZ->GetRenderWindow()->AddRenderer(this->RenYZ);
310 this->RenYZ->SetBackground(0,0,0);
311 this->RenYZ->GetActiveCamera()->SetParallelProjection(1);
316 void OpenHeartGui::slotMeshView()
318 this->HidePlanModeManagement();
322 void OpenHeartGui::slotYZView()
325 this->ViewButton = 1;
326 this->Properties->xIPW->SetTextureVisibility(1);
327 this->Properties->xIPW->GetPlaneProperty()->SetOpacity(1);
328 this->Properties->xIPW->GetPlaneProperty()->SetColor(0,0,0);
329 this->Properties->yIPW->SetTextureVisibility(0);
330 this->Properties->yIPW->GetPlaneProperty()->SetOpacity(0);
331 this->Properties->yIPW->GetPlaneProperty()->SetColor(0,0,0);
332 this->Properties->zIPW->SetTextureVisibility(0);
333 this->Properties->zIPW->GetPlaneProperty()->SetOpacity(0);
334 this->Properties->zIPW->GetPlaneProperty()->SetColor(0,0,0);
336 if ( this->FlagHidePlan == 0 )
339 /// Update corresponding viewer
341 this->UpdateViewer(view,this->ZoomMain,this->Ren);
343 /// Also update Slice text
344 int slice = (int)( (this->Properties->position[0] - this->ImageData->GetOrigin()[0]) / this->ImageData->GetSpacing()[0] + 0.5f );
346 strSlice.sprintf("Slice: %d",slice);
347 this->Properties->TextMapperSlice->SetInput(strSlice.toStdString().c_str());
351 this->FlagHidePlan = 0;
354 if ( this->FlagDisplayMeshContours == 1 )
356 this->GetMeshRenderer()->AddActor(this->Properties->xCutActor);
357 this->GetMeshRenderer()->RemoveActor(this->Properties->yCutActor);
358 this->GetMeshRenderer()->RemoveActor(this->Properties->zCutActor);
359 this->GetRenderWindow()->Render();
365 void OpenHeartGui::slotXZView()
368 this->ViewButton = 2;
369 this->Properties->xIPW->SetTextureVisibility(0);
370 this->Properties->xIPW->GetPlaneProperty()->SetOpacity(0);
371 this->Properties->xIPW->GetPlaneProperty()->SetColor(0,0,0);
372 this->Properties->yIPW->SetTextureVisibility(1);
373 this->Properties->yIPW->GetPlaneProperty()->SetOpacity(1);
374 this->Properties->yIPW->GetPlaneProperty()->SetColor(0,0,0);
375 this->Properties->zIPW->SetTextureVisibility(0);
376 this->Properties->zIPW->GetPlaneProperty()->SetOpacity(0);
377 this->Properties->zIPW->GetPlaneProperty()->SetColor(0,0,0);
379 if ( this->FlagHidePlan == 0 )
382 /// Update corresponding viewer
384 this->UpdateViewer(view,this->ZoomMain,this->Ren);
386 /// Also update Slice text
387 int slice = (int)( (this->Properties->position[1] - this->ImageData->GetOrigin()[1]) / this->ImageData->GetSpacing()[1] + 0.5f );
389 strSlice.sprintf("Slice: %d",slice);
390 this->Properties->TextMapperSlice->SetInput(strSlice.toStdString().c_str());
394 this->FlagHidePlan = 0;
397 if ( this->FlagDisplayMeshContours == 1 )
399 this->GetMeshRenderer()->RemoveActor(this->Properties->xCutActor);
400 this->GetMeshRenderer()->AddActor(this->Properties->yCutActor);
401 this->GetMeshRenderer()->RemoveActor(this->Properties->zCutActor);
402 this->GetRenderWindow()->Render();
408 void OpenHeartGui::slotXYView()
411 this->ViewButton = 3;
412 this->Properties->xIPW->SetTextureVisibility(0);
413 this->Properties->xIPW->GetPlaneProperty()->SetOpacity(0);
414 this->Properties->xIPW->GetPlaneProperty()->SetColor(0,0,0);
415 this->Properties->yIPW->SetTextureVisibility(0);
416 this->Properties->yIPW->GetPlaneProperty()->SetOpacity(0);
417 this->Properties->yIPW->GetPlaneProperty()->SetColor(0,0,0);
418 this->Properties->zIPW->SetTextureVisibility(1);
419 this->Properties->zIPW->GetPlaneProperty()->SetOpacity(1);
420 this->Properties->zIPW->GetPlaneProperty()->SetColor(0,0,0);
422 if ( this->FlagHidePlan == 0 )
425 /// Update corresponding viewer
427 this->UpdateViewer(view,this->ZoomMain,this->Ren);
429 /// Also update Slice text
430 int slice = (int)( (this->Properties->position[2] - this->ImageData->GetOrigin()[2]) / this->ImageData->GetSpacing()[2] + 0.5f );
432 strSlice.sprintf("Slice: %d",slice);
433 this->Properties->TextMapperSlice->SetInput(strSlice.toStdString().c_str());
437 this->FlagHidePlan = 0;
440 if ( this->FlagDisplayMeshContours == 1 )
442 this->GetMeshRenderer()->RemoveActor(this->Properties->xCutActor);
443 this->GetMeshRenderer()->RemoveActor(this->Properties->yCutActor);
444 this->GetMeshRenderer()->AddActor(this->Properties->zCutActor);
445 this->GetRenderWindow()->Render();
451 void OpenHeartGui::slot3DView()
454 this->ViewButton = 0;
455 this->Properties->xIPW->SetTextureVisibility(1);
456 this->Properties->xIPW->GetPlaneProperty()->SetOpacity(1);
457 this->Properties->xIPW->GetPlaneProperty()->SetColor(1,0,0);
458 this->Properties->yIPW->SetTextureVisibility(1);
459 this->Properties->yIPW->GetPlaneProperty()->SetOpacity(1);
460 this->Properties->yIPW->GetPlaneProperty()->SetColor(1,1,0);
461 this->Properties->zIPW->SetTextureVisibility(1);
462 this->Properties->zIPW->GetPlaneProperty()->SetOpacity(1);
463 this->Properties->zIPW->GetTextProperty()->SetColor(1,0,0);
464 this->Properties->zIPW->GetPlaneProperty()->SetColor(0,0,1);
466 if ( this->FlagHidePlan == 0 )
469 this->Ren->ResetCamera();
470 this->Ren->GetActiveCamera()->Zoom(1.);
472 if ( this->Properties->MeshActor != 0 )
474 if ( this->FlagDisplayMesh == 0 ) {
475 this->FlagDisplayMesh = 1;
476 this->GetMeshRenderer()->AddActor(this->Properties->MeshActor);
482 this->FlagHidePlan = 0;
484 this->GetRenderWindow()->Render();
489 void OpenHeartGui::slotMeshRepresentation()
492 if ( this->Properties->MeshActor )
495 if ( this->FlagDisplayMeshContours == 1 )
497 this->GetMeshRenderer()->RemoveActor(this->Properties->xCutActor);
498 this->GetMeshRenderer()->RemoveActor(this->Properties->yCutActor);
499 this->GetMeshRenderer()->RemoveActor(this->Properties->zCutActor);
500 this->FlagDisplayMeshContours = 0;
501 this->GetMeshRenderer()->AddActor(this->Properties->MeshActor);
502 this->FlagDisplayMesh = 1;
504 switch (this->MeshRepresentation) {
506 this->MeshRepresentation = 1;
507 this->pushButtonMeshRepresentation->setText("Surface");
508 this->Properties->MeshActor->GetProperty()->SetRepresentationToPoints();
511 this->MeshRepresentation = 2;
512 this->pushButtonMeshRepresentation->setText("No mesh");
513 this->Properties->MeshActor->GetProperty()->SetRepresentationToSurface();
516 this->MeshRepresentation = 3;
517 this->pushButtonMeshRepresentation->setText("Wire");
518 this->GetMeshRenderer()->RemoveActor(this->Properties->MeshActor);
519 this->FlagDisplayMesh = 0;
522 this->MeshRepresentation = 0;
523 this->pushButtonMeshRepresentation->setText("Points");
524 this->Properties->MeshActor->GetProperty()->SetRepresentationToWireframe();
525 this->GetMeshRenderer()->AddActor(this->Properties->MeshActor);
526 this->FlagDisplayMesh = 1;
531 this->GetRenderWindow()->Render();
539 void OpenHeartGui::slotMeshColor()
542 if ( this->Properties->MeshActor ) {
543 if ( this->MeshColor == 0 ) {
545 this->pushButtonMeshColor->setText("Color R");
546 this->Properties->MeshActor->GetProperty()->SetColor(1,1,0);
547 //this->Properties->xCutActor->GetProperty()->SetColor(1,1,0);
548 //this->Properties->yCutActor->GetProperty()->SetColor(1,1,0);
549 //this->Properties->zCutActor->GetProperty()->SetColor(1,1,0);
551 else if ( this->MeshColor == 1 ) {
553 this->pushButtonMeshColor->setText("Color G");
554 this->Properties->MeshActor->GetProperty()->SetColor(1,0,0);
555 //this->Properties->xCutActor->GetProperty()->SetColor(1,0,0);
556 //this->Properties->yCutActor->GetProperty()->SetColor(1,0,0);
557 //this->Properties->zCutActor->GetProperty()->SetColor(1,0,0);
559 else if ( this->MeshColor == 2 ) {
561 this->pushButtonMeshColor->setText("Color B");
562 this->Properties->MeshActor->GetProperty()->SetColor(0,1,0);
563 //this->Properties->xCutActor->GetProperty()->SetColor(0,1,0);
564 //this->Properties->yCutActor->GetProperty()->SetColor(0,1,0);
565 //this->Properties->zCutActor->GetProperty()->SetColor(0,1,0);
567 else if ( this->MeshColor == 3 ) {
569 this->pushButtonMeshColor->setText("Color W");
570 this->Properties->MeshActor->GetProperty()->SetColor(0,0,1);
571 //this->Properties->xCutActor->GetProperty()->SetColor(0,0,1);
572 //this->Properties->yCutActor->GetProperty()->SetColor(0,0,1);
573 //this->Properties->zCutActor->GetProperty()->SetColor(0,0,1);
575 else if ( this->MeshColor == 4 ) {
577 this->pushButtonMeshColor->setText("Color Y");
578 this->Properties->MeshActor->GetProperty()->SetColor(1,1,1);
579 //this->Properties->xCutActor->GetProperty()->SetColor(1,1,1);
580 //this->Properties->yCutActor->GetProperty()->SetColor(1,1,1);
581 //this->Properties->zCutActor->GetProperty()->SetColor(1,1,1);
583 this->GetRenderWindow()->Render();
589 void OpenHeartGui::slotMeshCutter()
592 if ( this->Properties->MeshActor )
594 if ( this->FlagDisplayMeshContours == 1 )
596 this->FlagDisplayMeshContours = 0;
597 this->pushButtonCutter->setText("Cut on");
598 this->GetMeshRenderer()->RemoveActor(this->Properties->xCutActor);
599 this->GetMeshRenderer()->RemoveActor(this->Properties->yCutActor);
600 this->GetMeshRenderer()->RemoveActor(this->Properties->zCutActor);
601 if ( this->FlagDisplayMesh == 0 ) {
602 this->FlagDisplayMesh = 1;
603 this->GetMeshRenderer()->AddActor(this->Properties->MeshActor);
608 if ( this->FlagDisplayMesh == 1 ) {
609 this->FlagDisplayMesh = 0;
610 this->GetMeshRenderer()->RemoveActor(this->Properties->MeshActor);
612 this->FlagDisplayMeshContours = 1;
613 this->pushButtonCutter->setText("Cut off");
614 switch (this->ViewButton) {
616 this->GetMeshRenderer()->AddActor(this->Properties->xCutActor);
617 this->GetMeshRenderer()->AddActor(this->Properties->yCutActor);
618 this->GetMeshRenderer()->AddActor(this->Properties->zCutActor);
621 this->GetMeshRenderer()->AddActor(this->Properties->xCutActor);
624 this->GetMeshRenderer()->AddActor(this->Properties->yCutActor);
627 this->GetMeshRenderer()->AddActor(this->Properties->zCutActor);
633 if (this->ViewButton == 0) {
634 this->GetMeshRenderer()->AddActor(this->Properties->xCutActor);
635 this->GetMeshRenderer()->AddActor(this->Properties->yCutActor);
636 this->GetMeshRenderer()->AddActor(this->Properties->zCutActor);
638 else if (this->ViewButton == 1) {
639 this->GetMeshRenderer()->AddActor(this->Properties->xCutActor);
641 else if (this->ViewButton == 2) {
642 this->GetMeshRenderer()->AddActor(this->Properties->yCutActor);
644 else if (this->ViewButton == 3) {
645 this->GetMeshRenderer()->AddActor(this->Properties->zCutActor);
649 this->GetRenderWindow()->Render();
656 void OpenHeartGui::ForceXZView()
659 this->ViewButton = 2;
660 this->Properties->xIPW->SetTextureVisibility(0);
661 this->Properties->xIPW->GetPlaneProperty()->SetOpacity(0);
662 this->Properties->yIPW->SetTextureVisibility(1);
663 this->Properties->yIPW->GetPlaneProperty()->SetOpacity(1);
664 this->Properties->zIPW->SetTextureVisibility(0);
665 this->Properties->zIPW->GetPlaneProperty()->SetOpacity(0);
667 this->Ren->GetActiveCamera()->SetFocalPoint( this->ImageData->GetDimensions()[0]/2,
668 this->ImageData->GetDimensions()[0]/2,
669 this->ImageData->GetDimensions()[2]/2 );
670 this->Ren->GetActiveCamera()->SetPosition( this->ImageData->GetDimensions()[0]/2,
671 this->ImageData->GetDimensions()[1]*10,
672 this->ImageData->GetDimensions()[0]/2 );
673 this->Ren->GetActiveCamera()->SetViewUp(0,0,-1);
674 this->Ren->ResetCamera();
675 this->Ren->GetActiveCamera()->Zoom(this->ZoomMain);
676 this->GetRenderWindow()->Render();
680 void OpenHeartGui::slotUpdateCoords(vtkObject* obj)
683 if (this->FlagPlay == 0)
686 if ( (this->FlagDisplayText) && (this->Properties->TextMapperPixel) )
690 vtkRenderWindowInteractor* iren = vtkRenderWindowInteractor::SafeDownCast(obj);
692 // Get intensity value at the corresponding position
693 int X = iren->GetEventPosition()[0];
694 int Y = iren->GetEventPosition()[1];
695 this->Picker->Pick(X,Y,0.0,this->GetMeshRenderer());
697 this->Picker->GetPickPosition( pos );
699 for ( int i=0; i<3; i++) {
700 pixel[i] = (int)( (pos[i] - this->ImageData->GetOrigin()[i]) / this->ImageData->GetSpacing()[i] + 0.5f );
703 if ( (pixel[0]>=0) && (pixel[0]<this->Dims[0]) &&
704 (pixel[1]>=0) && (pixel[1]<this->Dims[1]) &&
705 (pixel[2]>=0) && (pixel[2]<this->Dims[2]) )
708 /// Display Pixel coordinates
710 strPixel.sprintf("pixel: (%d %d %d)", pixel[0], pixel[1], pixel[2]);
711 this->Properties->TextMapperPixel->SetInput(strPixel.toStdString().c_str());
713 /// Display Pixel coordinates
715 strMM.sprintf("mm: (%.0f %.0f %.0f)", pos[0]*1000, pos[1]*1000, pos[2]*1000);
716 this->Properties->TextMapperMM->SetInput(strMM.toStdString().c_str());
719 switch (this->ImageData->GetScalarType())
721 case VTK_UNSIGNED_CHAR: {
722 strValue.sprintf("data value: %u", static_cast<unsigned char*>(this->ImageData->GetScalarPointer(pixel))[0]);
725 case VTK_UNSIGNED_SHORT: {
726 strValue.sprintf("data value: %u", static_cast<unsigned short*>(this->ImageData->GetScalarPointer(pixel))[0]);
730 strValue.sprintf("data value: %d", static_cast<int*>(this->ImageData->GetScalarPointer(pixel))[0]);
734 strValue.sprintf("data value: %.1f", static_cast<float*>(this->ImageData->GetScalarPointer(pixel))[0]);
738 strValue.sprintf("data value: %.1f", static_cast<double*>(this->ImageData->GetScalarPointer(pixel))[0]);
743 this->Properties->TextMapperValue->SetInput(strValue.toStdString().c_str());
748 this->Properties->TextMapperPixel->SetInput("");
749 this->Properties->TextMapperMM->SetInput("");
750 this->Properties->TextMapperValue->SetInput("");
757 if ( this->Properties->TextMapperPixel )
759 this->Properties->TextMapperPixel->SetInput("");
760 this->Properties->TextMapperMM->SetInput("");
761 this->Properties->TextMapperValue->SetInput("");
765 this->GetRenderWindow()->Render();
772 void OpenHeartGui::UpdateCoords(double *pos)
775 if (this->FlagPlay == 0)
778 if ( (this->FlagDisplayText) && (this->Properties->TextMapperPixel) )
782 for ( int i=0; i<3; i++) {
783 pixel[i] = (int)( (pos[i] - this->ImageData->GetOrigin()[i]) / this->ImageData->GetSpacing()[i] + 0.5f );
786 if ( (pixel[0]>=0) && (pixel[0]<this->Dims[0]) &&
787 (pixel[1]>=0) && (pixel[1]<this->Dims[1]) &&
788 (pixel[2]>=0) && (pixel[2]<this->Dims[2]) )
791 /// Display Pixel coordinates
793 strPixel.sprintf("pixel: (%d %d %d)", pixel[0], pixel[1], pixel[2]);
794 this->Properties->TextMapperPixel->SetInput(strPixel.toStdString().c_str());
796 /// Display Pixel coordinates
798 strMM.sprintf("mm: (%.0f %.0f %.0f)", pos[0]*1000, pos[1]*1000, pos[2]*1000);
799 this->Properties->TextMapperMM->SetInput(strMM.toStdString().c_str());
802 switch (this->ImageData->GetScalarType())
804 case VTK_UNSIGNED_CHAR: {
805 strValue.sprintf("data value: %u", static_cast<unsigned char*>(this->ImageData->GetScalarPointer(pixel))[0]);
808 case VTK_UNSIGNED_SHORT: {
809 strValue.sprintf("data value: %u", static_cast<unsigned short*>(this->ImageData->GetScalarPointer(pixel))[0]);
813 strValue.sprintf("data value: %d", static_cast<int*>(this->ImageData->GetScalarPointer(pixel))[0]);
817 strValue.sprintf("data value: %.1f", static_cast<float*>(this->ImageData->GetScalarPointer(pixel))[0]);
821 strValue.sprintf("data value: %.1f", static_cast<double*>(this->ImageData->GetScalarPointer(pixel))[0]);
825 this->Properties->TextMapperValue->SetInput(strValue.toStdString().c_str());
830 this->Properties->TextMapperPixel->SetInput("");
831 this->Properties->TextMapperMM->SetInput("");
832 this->Properties->TextMapperValue->SetInput("");
838 if ( this->Properties->TextMapperPixel )
840 this->Properties->TextMapperPixel->SetInput("");
841 this->Properties->TextMapperMM->SetInput("");
842 this->Properties->TextMapperValue->SetInput("");
846 this->GetRenderWindow()->Render();
853 void OpenHeartGui::InitChar()
856 this->TableChart = vtkSmartPointer<vtkTable>::New();
857 vtkSmartPointer<vtkFloatArray> arrX = vtkSmartPointer<vtkFloatArray>::New();
858 arrX->SetName("Number of frames");
859 this->TableChart->AddColumn(arrX);
860 vtkSmartPointer<vtkFloatArray> arrY = vtkSmartPointer<vtkFloatArray>::New();
861 arrY->SetName("Volume");
862 this->TableChart->AddColumn(arrY);
864 int numPoints = this->NumberOfVolumes;
865 this->TableChart->SetNumberOfRows(numPoints);
866 for (int i=0; i<numPoints; ++i)
868 this->TableChart->SetValue(i, 0, i);
869 this->TableChart->SetValue(i, 1, 0);
871 // Add multiple line plots, setting the colors etc
872 vtkSmartPointer<vtkChartXY> chart = vtkSmartPointer<vtkChartXY>::New();
873 ViewChart->GetScene()->AddItem(chart);
874 chart->AddPlot(vtkChart::LINE);
875 vtkPlot *line = chart->AddPlot(vtkChart::LINE);
876 line->SetInput(this->TableChart, 0, 1);
877 line->SetColor(0, 0, 255, 255);
879 chart->GetAxis(vtkAxis::LEFT)->SetTitle("Volume (mL)");
880 chart->GetAxis(vtkAxis::BOTTOM)->SetTitle("Frames");
881 chart->GetAxis(vtkAxis::LEFT)->SetNotation(2);
882 chart->GetAxis(vtkAxis::LEFT)->SetPrecision(1);
887 void OpenHeartGui::InitPickers()
889 this->Picker = vtkSmartPointer<vtkCellPicker>::New();
890 this->Picker->SetTolerance(0.005);
891 this->Interactor->SetPicker(this->Picker);
892 this->PickerXY = vtkSmartPointer<vtkCellPicker>::New();
893 this->PickerXY->SetTolerance(0.005);
894 this->InteractorXY->SetPicker(this->PickerXY);
895 this->PickerXZ = vtkSmartPointer<vtkCellPicker>::New();
896 this->PickerXZ->SetTolerance(0.005);
897 this->InteractorXZ->SetPicker(this->PickerXZ);
898 this->PickerYZ = vtkSmartPointer<vtkCellPicker>::New();
899 this->PickerYZ->SetTolerance(0.005);
900 this->InteractorYZ->SetPicker(this->PickerYZ);
906 void OpenHeartGui::InitWidgets()
908 /// ImagePlane Widget
909 this->InitPlaneWidget();
913 void OpenHeartGui::InitOrientationAxes()
915 vtkSmartPointer<vtkAxesActor> axes = vtkSmartPointer<vtkAxesActor>::New();
916 axes->GetYAxisTipProperty()->SetColor(1,1,0);
917 axes->GetYAxisShaftProperty()->SetColor(1,1,0);
918 this->OrientationWidget->SetOrientationMarker( axes );
919 this->OrientationWidget->SetInteractor( this->qVTK->GetRenderWindow()->GetInteractor() );
920 this->OrientationWidget->SetViewport( 0.8, 0.0, 1.0, 0.2 );
921 this->OrientationWidget->SetEnabled( 1 );
922 this->OrientationWidget->InteractiveOff();
926 void OpenHeartGui::InitProperties()
928 this->Properties->lut = 0;
929 this->Properties->xIPW = 0;
930 this->Properties->yIPW = 0;
931 this->Properties->zIPW = 0;
932 this->Properties->xyIPW = 0;
933 this->Properties->xzIPW = 0;
934 this->Properties->yzIPW = 0;
935 this->Properties->TextActorPixel = 0;
936 this->Properties->TextMapperPixel = 0;
937 this->Properties->TextActorMM = 0;
938 this->Properties->TextMapperMM = 0;
939 this->Properties->TextActorValue = 0;
940 this->Properties->TextMapperValue = 0;
941 this->Properties->TextActorSlice = 0;
942 this->Properties->TextMapperSlice = 0;
943 this->Properties->TextActorNumFrame = 0;
944 this->Properties->TextMapperNumFrame = 0;
945 this->Properties->TextActorResolution = 0;
946 this->Properties->TextMapperResolution = 0;
947 this->Properties->MeshActor = 0;
948 this->Properties->xCutActor = 0;
949 this->Properties->yCutActor = 0;
950 this->Properties->zCutActor = 0;
951 this->Properties->BasalPointActor = 0;
952 this->Properties->ApexPointActor = 0;
953 this->Properties->LongAxisActor = 0;
954 this->Properties->BoundingBoxActor = 0;
955 this->Properties->position = new double[3];
959 void OpenHeartGui::InitPlaneWidget()
962 /// Manage main window
963 this->Properties->xIPW = vtkSmartPointer<vtkImagePlaneWidget>::New();
964 this->Properties->yIPW = vtkSmartPointer<vtkImagePlaneWidget>::New();
965 this->Properties->zIPW = vtkSmartPointer<vtkImagePlaneWidget>::New();
967 this->Properties->xIPW->SetInteractor(vtkRenderWindowInteractor::New());
968 this->Properties->yIPW->SetInteractor(this->Properties->xIPW->GetInteractor());
969 this->Properties->zIPW->SetInteractor(this->Properties->xIPW->GetInteractor());
971 this->Properties->xIPW->DisplayTextOn();
972 this->Properties->xIPW->GetTextProperty()->SetColor(0,0,0);
973 this->Properties->xIPW->SetPicker(this->Picker);
974 this->Properties->xIPW->RestrictPlaneToVolumeOn();
975 this->Properties->xIPW->GetPlaneProperty()->SetColor(0,0,0);
976 this->Properties->xIPW->SetResliceInterpolateToNearestNeighbour();
977 this->Properties->xIPW->TextureInterpolateOff();
979 this->Properties->yIPW->DisplayTextOn();
980 this->Properties->yIPW->GetTextProperty()->SetColor(0,0,0);
981 this->Properties->yIPW->SetPicker(this->Picker);
982 this->Properties->yIPW->RestrictPlaneToVolumeOn();
983 this->Properties->yIPW->GetPlaneProperty()->SetColor(0,0,0);
984 this->Properties->yIPW->SetTexturePlaneProperty(this->Properties->xIPW->GetTexturePlaneProperty());
985 this->Properties->yIPW->SetResliceInterpolateToNearestNeighbour();
986 this->Properties->yIPW->TextureInterpolateOff();
988 this->Properties->zIPW->DisplayTextOn();
989 this->Properties->zIPW->GetTextProperty()->SetColor(0,0,0);
990 this->Properties->zIPW->SetPicker(this->Picker);
991 this->Properties->zIPW->GetPlaneProperty()->SetColor(0,0,0);
992 this->Properties->zIPW->SetTexturePlaneProperty(this->Properties->xIPW->GetTexturePlaneProperty());
993 this->Properties->zIPW->SetResliceInterpolateToNearestNeighbour();
994 this->Properties->zIPW->TextureInterpolateOff();
998 this->Properties->xyIPW = vtkImagePlaneWidget::New();
999 this->Properties->xyIPW->SetInteractor(vtkRenderWindowInteractor::New());
1000 this->Properties->xyIPW->DisplayTextOn();
1001 this->Properties->xyIPW->GetTextProperty()->SetColor(0,0,0);
1002 this->Properties->xyIPW->SetPicker(this->PickerXY);
1003 this->Properties->xyIPW->RestrictPlaneToVolumeOn();
1004 this->Properties->xyIPW->GetPlaneProperty()->SetColor(0,0,0);
1005 this->Properties->xyIPW->SetResliceInterpolateToNearestNeighbour();
1006 this->Properties->xyIPW->TextureInterpolateOff();
1008 /// Manage XZ window
1009 this->Properties->xzIPW = vtkImagePlaneWidget::New();
1010 this->Properties->xzIPW->SetInteractor(vtkRenderWindowInteractor::New());
1011 this->Properties->xzIPW->DisplayTextOn();
1012 this->Properties->xzIPW->GetTextProperty()->SetColor(0,0,0);
1013 this->Properties->xzIPW->RestrictPlaneToVolumeOn();
1014 this->Properties->xzIPW->GetPlaneProperty()->SetColor(0,0,0);
1015 this->Properties->xzIPW->SetResliceInterpolateToNearestNeighbour();
1016 this->Properties->xzIPW->TextureInterpolateOff();
1018 /// Manage YZ window
1019 this->Properties->yzIPW = vtkImagePlaneWidget::New();
1020 this->Properties->yzIPW->SetInteractor(vtkRenderWindowInteractor::New());
1021 this->Properties->yzIPW->DisplayTextOn();
1022 this->Properties->yzIPW->GetTextProperty()->SetColor(0,0,0);
1023 this->Properties->yzIPW->RestrictPlaneToVolumeOn();
1024 this->Properties->yzIPW->GetPlaneProperty()->SetColor(0,0,0);
1025 this->Properties->yzIPW->SetResliceInterpolateToNearestNeighbour();
1026 this->Properties->yzIPW->TextureInterpolateOff();
1030 void OpenHeartGui::InitTexts()
1033 /// Display pixel coordinates
1034 this->Properties->TextActorPixel = vtkSmartPointer<vtkActor2D>::New();
1035 this->Properties->TextMapperPixel = vtkSmartPointer<vtkTextMapper>::New();
1036 this->Properties->TextMapperPixel->GetTextProperty()->SetColor(0, 1, 0);
1037 this->Properties->TextMapperPixel->GetTextProperty()->SetFontSize(15);
1038 if ( this->FlagDisplayText ) {
1039 this->Properties->TextMapperPixel->SetInput("");
1041 this->Properties->TextMapperPixel->GetTextProperty()->SetJustificationToRight();
1042 this->Properties->TextMapperPixel->GetTextProperty()->ShadowOff();
1043 this->Properties->TextActorPixel->SetPosition(490,520);
1044 this->Properties->TextActorPixel->SetMapper(this->Properties->TextMapperPixel);
1045 this->GetMeshRenderer()->AddActor(this->Properties->TextActorPixel);
1047 /// Display mm coordinates
1048 this->Properties->TextActorMM = vtkSmartPointer<vtkActor2D>::New();
1049 this->Properties->TextMapperMM= vtkSmartPointer<vtkTextMapper>::New();
1050 this->Properties->TextMapperMM->GetTextProperty()->SetColor(0, 1, 0);
1051 this->Properties->TextMapperMM->GetTextProperty()->SetFontSize(15);
1052 if ( this->FlagDisplayText ) {
1053 this->Properties->TextMapperMM->SetInput("");
1055 this->Properties->TextMapperMM->GetTextProperty()->SetJustificationToRight();
1056 this->Properties->TextMapperMM->GetTextProperty()->ShadowOff();
1057 this->Properties->TextActorMM->SetPosition(490,495);
1058 this->Properties->TextActorMM->SetMapper(this->Properties->TextMapperMM);
1059 this->GetMeshRenderer()->AddActor(this->Properties->TextActorMM);
1061 /// Display data value
1062 this->Properties->TextActorValue = vtkSmartPointer<vtkActor2D>::New();
1063 this->Properties->TextMapperValue = vtkSmartPointer<vtkTextMapper>::New();
1064 this->Properties->TextMapperValue->GetTextProperty()->SetColor(0, 1, 0);
1065 this->Properties->TextMapperValue->GetTextProperty()->SetFontSize(15);
1066 if ( this->FlagDisplayText ) {
1067 this->Properties->TextMapperValue->SetInput("");
1069 this->Properties->TextMapperValue->GetTextProperty()->SetJustificationToRight();
1070 this->Properties->TextMapperValue->GetTextProperty()->ShadowOff();
1071 this->Properties->TextActorValue->SetPosition(490,470);
1072 this->Properties->TextActorValue->SetMapper(this->Properties->TextMapperValue);
1073 this->GetMeshRenderer()->AddActor(this->Properties->TextActorValue);
1076 this->Properties->TextActorSlice = vtkSmartPointer<vtkActor2D>::New();
1077 this->Properties->TextMapperSlice = vtkSmartPointer<vtkTextMapper>::New();
1078 this->Properties->TextMapperSlice->GetTextProperty()->SetColor(0, 1, 0);
1079 this->Properties->TextMapperSlice->GetTextProperty()->SetFontSize(15);
1080 if ( this->FlagDisplayText ) {
1081 int slice = (int)( (this->Properties->position[1] - this->ImageData->GetOrigin()[1]) / this->ImageData->GetSpacing()[1] + 0.5f );
1082 //cout << this->Properties->position[1] << endl;
1084 strSlice.sprintf("Slice: %d",slice);
1085 this->Properties->TextMapperSlice->SetInput(strSlice.toStdString().c_str());
1087 this->Properties->TextMapperSlice->GetTextProperty()->SetJustificationToLeft();
1088 this->Properties->TextMapperSlice->GetTextProperty()->ShadowOff();
1089 this->Properties->TextActorSlice->SetPosition(10,520);
1090 this->Properties->TextActorSlice->SetMapper(this->Properties->TextMapperSlice);
1091 this->GetMeshRenderer()->AddActor(this->Properties->TextActorSlice);
1093 /// Display frame number
1094 this->Properties->TextActorNumFrame = vtkSmartPointer<vtkActor2D>::New();
1095 this->Properties->TextMapperNumFrame = vtkSmartPointer<vtkTextMapper>::New();
1096 this->Properties->TextMapperNumFrame->GetTextProperty()->SetColor(0, 1, 0);
1097 this->Properties->TextMapperNumFrame->GetTextProperty()->SetFontSize(15);
1098 if ( this->FlagDisplayText ) {
1100 str.sprintf("Frame: %d",this->CurrentFrame);
1101 this->Properties->TextMapperNumFrame->SetInput(str.toStdString().c_str());
1103 this->Properties->TextMapperNumFrame->GetTextProperty()->SetJustificationToLeft();
1104 this->Properties->TextMapperNumFrame->GetTextProperty()->ShadowOff();
1105 this->Properties->TextActorNumFrame->SetPosition(10, 45);
1106 this->Properties->TextActorNumFrame->SetMapper(this->Properties->TextMapperNumFrame);
1107 this->GetMeshRenderer()->AddActor(this->Properties->TextActorNumFrame);
1109 /// Display resolution value
1110 this->Properties->TextActorResolution = vtkSmartPointer<vtkActor2D>::New();
1111 this->Properties->TextMapperResolution = vtkSmartPointer<vtkTextMapper>::New();
1112 this->Properties->TextMapperResolution->GetTextProperty()->SetColor(0, 1, 0);
1113 this->Properties->TextMapperResolution->GetTextProperty()->SetFontSize(15);
1114 if ( this->FlagDisplayText ) {
1116 str.sprintf("Resolution: %.2f x %.2f x %.2f mm",this->ImageData->GetSpacing()[0]*1000,this->ImageData->GetSpacing()[1]*1000,this->ImageData->GetSpacing()[2]*1000);
1117 this->Properties->TextMapperResolution->SetInput(str.toStdString().c_str());
1119 this->Properties->TextMapperResolution->GetTextProperty()->SetJustificationToLeft();
1120 this->Properties->TextMapperResolution->GetTextProperty()->ShadowOff();
1121 this->Properties->TextActorResolution->SetPosition(10, 20);
1122 this->Properties->TextActorResolution->SetMapper(this->Properties->TextMapperResolution);
1123 this->GetMeshRenderer()->AddActor(this->Properties->TextActorResolution);
1128 void OpenHeartGui::SetCustomInteractorStyle()
1131 /// customize main interactor
1132 vtkSmartPointer<vtkMyInteractorStyleTrackballCameraOpenHeart> CustomInteractorStyle =
1133 vtkSmartPointer<vtkMyInteractorStyleTrackballCameraOpenHeart>::New();
1134 CustomInteractorStyle->SetOpenHeartGui( this );
1135 this->Interactor->SetInteractorStyle(CustomInteractorStyle);
1137 /// customize XY interactor
1138 vtkSmartPointer<vtkMyInteractorStyleTrackballCameraOpenHeartXY> CustomInteractorStyleXY =
1139 vtkSmartPointer<vtkMyInteractorStyleTrackballCameraOpenHeartXY>::New();
1140 CustomInteractorStyleXY->SetOpenHeartGui( this );
1141 this->InteractorXY->SetInteractorStyle(CustomInteractorStyleXY);
1143 /// customize XZ interactor
1144 vtkSmartPointer<vtkMyInteractorStyleTrackballCameraOpenHeartXZ> CustomInteractorStyleXZ =
1145 vtkSmartPointer<vtkMyInteractorStyleTrackballCameraOpenHeartXZ>::New();
1146 CustomInteractorStyleXZ->SetOpenHeartGui( this );
1147 this->InteractorXZ->SetInteractorStyle(CustomInteractorStyleXZ);
1149 /// customize YZ interactor
1150 vtkSmartPointer<vtkMyInteractorStyleTrackballCameraOpenHeartYZ> CustomInteractorStyleYZ =
1151 vtkSmartPointer<vtkMyInteractorStyleTrackballCameraOpenHeartYZ>::New();
1152 CustomInteractorStyleYZ->SetOpenHeartGui( this );
1153 this->InteractorYZ->SetInteractorStyle(CustomInteractorStyleYZ);
1158 void OpenHeartGui::CreateFromSequenceDataPointer(std::string inputFilename)
1163 for (int i=1; i<=this->NumberOfVolumes; i++)
1166 str.sprintf("%s0%d.mhd",inputFilename.c_str(),i);
1168 str.sprintf("%s%d.mhd",inputFilename.c_str(),i);
1169 vtkMetaImageReader *reader = vtkMetaImageReader::New();
1170 reader->SetFileName(str.toStdString().c_str());
1172 this->StackVolume.push_back(reader->GetOutput());
1175 /// Initialize attibute related to stack of volumes
1176 this->itStackVolume = this->StackVolume.begin();
1177 this->CurrentFrame = 0;
1178 this->ImageData = (*this->itStackVolume);
1180 for ( unsigned int k=0; k<3; k++ ) {
1181 this->Dims[k] = this->ImageData->GetDimensions()[k];
1182 center[k] = ((this->ImageData->GetDimensions()[k])*(this->ImageData->GetSpacing()[k]))/2;
1185 /// Allocate lookuptable
1187 this->ImageData->GetScalarRange(range);
1188 int NumberOfColors = vtkMath::Round(range[1]-range[0]);
1190 this->Properties->lut = vtkSmartPointer<vtkLookupTable>::New();
1191 this->Properties->lut->SetNumberOfColors(NumberOfColors);
1192 this->Properties->lut->SetValueRange(range[0]/NumberOfColors,range[1]/NumberOfColors);
1193 this->Properties->lut->SetRampToLinear();
1194 this->Properties->lut->SetSaturationRange(0.,0.);
1195 this->Properties->lut->SetHueRange(0.,0.);
1197 /// Manage main window
1198 this->Properties->xIPW->SetCurrentRenderer(this->GetMainRenderer());
1199 this->Properties->yIPW->SetCurrentRenderer(this->GetMainRenderer());
1200 this->Properties->zIPW->SetCurrentRenderer(this->GetMainRenderer());
1202 /// The 3 image plane widgets are used.
1203 this->Properties->xIPW->SetInput(this->ImageData);
1204 this->Properties->yIPW->SetInput(this->ImageData);
1205 this->Properties->zIPW->SetInput(this->ImageData);
1207 this->Properties->xIPW->SetPlaneOrientationToXAxes();
1208 this->Properties->yIPW->SetPlaneOrientationToYAxes();
1209 this->Properties->zIPW->SetPlaneOrientationToZAxes();
1211 this->Properties->xIPW->SetSlicePosition(center[0]);
1212 this->Properties->yIPW->SetSlicePosition(center[1]);
1213 this->Properties->zIPW->SetSlicePosition(center[2]);
1215 this->Properties->xIPW->SetLookupTable(this->Properties->lut);
1216 this->Properties->yIPW->SetLookupTable(this->Properties->lut);
1217 this->Properties->zIPW->SetLookupTable(this->Properties->lut);
1219 this->Properties->position[0] = center[0];
1220 this->Properties->position[1] = center[1];
1221 this->Properties->position[2] = center[2];
1223 this->Properties->xIPW->On();
1224 this->Properties->yIPW->On();
1225 this->Properties->zIPW->On();
1227 /// Manage XY window
1228 this->Properties->xyIPW->SetCurrentRenderer(this->GetXYRenderer());
1229 this->Properties->xyIPW->SetInput(this->ImageData);
1230 this->Properties->xyIPW->SetPlaneOrientationToZAxes();
1231 this->Properties->xyIPW->SetSlicePosition(center[2]);
1232 this->Properties->xyIPW->SetLookupTable(this->Properties->lut);
1233 this->Properties->xyIPW->On();
1234 this->RenXY->GetActiveCamera()->SetFocalPoint( this->ImageData->GetDimensions()[0]/2,
1235 this->ImageData->GetDimensions()[1]/2,
1236 this->ImageData->GetDimensions()[2]/2 );
1237 this->RenXY->GetActiveCamera()->SetPosition( this->ImageData->GetDimensions()[0]/2,
1238 this->ImageData->GetDimensions()[1]/2,
1239 this->ImageData->GetDimensions()[2]*10 );
1240 this->RenXY->GetActiveCamera()->SetViewUp(0,0,-1);
1241 this->RenXY->ResetCamera();
1242 this->RenXY->GetActiveCamera()->Zoom(this->ZoomLabel);
1243 this->GetRenderWindowXY()->Render();
1245 /// Manage XZ window
1246 this->Properties->xzIPW->SetCurrentRenderer(this->GetXZRenderer());
1247 this->Properties->xzIPW->SetInput(this->ImageData);
1248 this->Properties->xzIPW->SetPlaneOrientationToYAxes();
1249 this->Properties->xzIPW->SetSlicePosition(center[1]);
1250 this->Properties->xzIPW->SetLookupTable(this->Properties->lut);
1251 this->Properties->xzIPW->On();
1252 this->RenXZ->GetActiveCamera()->SetFocalPoint( this->ImageData->GetDimensions()[0]/2,
1253 this->ImageData->GetDimensions()[1]/2,
1254 this->ImageData->GetDimensions()[2]/2 );
1255 this->RenXZ->GetActiveCamera()->SetPosition( this->ImageData->GetDimensions()[0]/2,
1256 this->ImageData->GetDimensions()[1]*10,
1257 this->ImageData->GetDimensions()[2]/2 );
1258 this->RenXZ->GetActiveCamera()->SetViewUp(0,0,-1);
1260 this->RenXZ->ResetCamera();
1261 this->RenXZ->GetActiveCamera()->Zoom(this->ZoomLabel);
1264 /// Manage YZ window
1265 this->Properties->yzIPW->SetCurrentRenderer(this->GetYZRenderer());
1266 this->Properties->yzIPW->SetInput(this->ImageData);
1267 this->Properties->yzIPW->SetPlaneOrientationToXAxes();
1268 this->Properties->yzIPW->SetSlicePosition(center[0]);
1269 this->Properties->yzIPW->SetLookupTable(this->Properties->lut);
1270 this->Properties->yzIPW->On();
1271 this->RenYZ->GetActiveCamera()->SetFocalPoint( this->ImageData->GetDimensions()[0]/2,
1272 this->ImageData->GetDimensions()[1]/2,
1273 this->ImageData->GetDimensions()[2]/2 );
1274 this->RenYZ->GetActiveCamera()->SetPosition( this->ImageData->GetDimensions()[0]*10,
1275 this->ImageData->GetDimensions()[1]/2,
1276 this->ImageData->GetDimensions()[2]/2 );
1277 this->RenYZ->GetActiveCamera()->SetViewUp(0,0,-1);
1278 this->RenYZ->ResetCamera();
1279 this->RenYZ->GetActiveCamera()->Zoom(this->ZoomLabel);
1281 /// Manage Bounding box around the volume for the 3D display
1282 vtkSmartPointer<vtkOutlineFilter> outlineData = vtkSmartPointer<vtkOutlineFilter>::New();
1283 outlineData->SetInput(this->ImageData);
1284 vtkSmartPointer<vtkPolyDataMapper> mapOutline = vtkSmartPointer<vtkPolyDataMapper>::New();
1285 mapOutline->SetInput(outlineData->GetOutput());
1286 this->Properties->BoundingBoxActor = vtkSmartPointer<vtkActor>::New();
1287 this->Properties->BoundingBoxActor->SetMapper(mapOutline);
1289 /// Refresh YZ viewer
1290 this->GetRenderWindowYZ()->Render();
1295 void OpenHeartGui::InterpolationManagement()
1298 if ( this->FlagReslice == 0 )
1300 if ( this->FlagInterpolation == 0 )
1302 this->FlagInterpolation = 1;
1303 this->Properties->xIPW->TextureInterpolateOn();
1304 this->Properties->yIPW->TextureInterpolateOn();
1305 this->Properties->zIPW->TextureInterpolateOn();
1309 this->FlagInterpolation = 0;
1310 this->Properties->xIPW->TextureInterpolateOff();
1311 this->Properties->yIPW->TextureInterpolateOff();
1312 this->Properties->zIPW->TextureInterpolateOff();
1315 /// Force to display the change on the XYZ planes
1316 this->Properties->xIPW->SetInput(this->ImageData);
1317 this->Properties->yIPW->SetInput(this->ImageData);
1318 this->Properties->zIPW->SetInput(this->ImageData);
1319 this->Properties->xIPW->SetSlicePosition(this->Properties->position[0]);
1320 this->Properties->yIPW->SetSlicePosition(this->Properties->position[1]);
1321 this->Properties->zIPW->SetSlicePosition(this->Properties->position[2]);
1323 this->GetRenderWindow()->Render();
1329 void OpenHeartGui::UpdateForwardViewers()
1332 if ( this->ImageData )
1335 ++(this->itStackVolume);
1336 ++(this->CurrentFrame);
1337 if (this->Properties->MeshActor) {
1338 ++(this->itStackMesh);
1339 ++(this->Properties->itStackMapperList);
1340 ++(this->Properties->itStackMapXCutter);
1341 ++(this->Properties->itStackMapYCutter);
1342 ++(this->Properties->itStackMapZCutter);
1345 if ( this->itStackVolume == this->StackVolume.end() ) {
1346 this->itStackVolume = this->StackVolume.begin();
1347 this->CurrentFrame = 0;
1348 if (this->Properties->MeshActor) {
1349 this->itStackMesh = this->StackMesh.begin();
1350 this->Properties->itStackMapperList = this->Properties->StackMapperList.begin();
1351 this->Properties->itStackMapXCutter = this->Properties->StackMapXCutter.begin();
1352 this->Properties->itStackMapYCutter = this->Properties->StackMapYCutter.begin();
1353 this->Properties->itStackMapZCutter = this->Properties->StackMapZCutter.begin();
1357 /// Update image data pointer
1358 this->ImageData = (*this->itStackVolume);
1360 if ( this->FlagReslice == 0 )
1363 /// Update the 3 planes and the corresponding 2D plane windows
1364 this->Properties->xIPW->SetInput(this->ImageData);
1365 this->Properties->yIPW->SetInput(this->ImageData);
1366 this->Properties->zIPW->SetInput(this->ImageData);
1367 this->Properties->xyIPW->SetInput(this->ImageData);
1368 this->Properties->xzIPW->SetInput(this->ImageData);
1369 this->Properties->yzIPW->SetInput(this->ImageData);
1370 this->Properties->xIPW->SetSlicePosition(this->Properties->position[0]);
1371 this->Properties->yIPW->SetSlicePosition(this->Properties->position[1]);
1372 this->Properties->zIPW->SetSlicePosition(this->Properties->position[2]);
1373 this->Properties->xyIPW->SetSlicePosition(this->Properties->position[2]);
1374 this->Properties->xzIPW->SetSlicePosition(this->Properties->position[1]);
1375 this->Properties->yzIPW->SetSlicePosition(this->Properties->position[0]);
1385 for (int i=0;i<3; i++) {
1386 pto[i] = this->Properties->xIPW->GetOrigin()[i];
1387 pt1[i] = this->Properties->xIPW->GetPoint1()[i];
1388 pt2[i] = this->Properties->xIPW->GetPoint2()[i];
1390 double position = this->Properties->xIPW->GetSlicePosition();
1391 this->Properties->xIPW->SetInput(this->ImageData);
1392 this->Properties->yzIPW->SetInput(this->ImageData);
1393 this->Properties->xIPW->SetOrigin(pto);
1394 this->Properties->xIPW->SetPoint1(pt1);
1395 this->Properties->xIPW->SetPoint2(pt2);
1396 this->Properties->xIPW->UpdatePlacement();
1397 this->Properties->yzIPW->SetOrigin(pto);
1398 this->Properties->yzIPW->SetPoint1(pt1);
1399 this->Properties->yzIPW->SetPoint2(pt2);
1400 this->Properties->yzIPW->UpdatePlacement();
1401 this->Properties->xIPW->SetSlicePosition(position);
1402 this->Properties->yzIPW->SetSlicePosition(position);
1405 for (int i=0;i<3; i++) {
1406 pto[i] = this->Properties->yIPW->GetOrigin()[i];
1407 pt1[i] = this->Properties->yIPW->GetPoint1()[i];
1408 pt2[i] = this->Properties->yIPW->GetPoint2()[i];
1410 position = this->Properties->yIPW->GetSlicePosition();
1411 this->Properties->yIPW->SetInput(this->ImageData);
1412 this->Properties->xzIPW->SetInput(this->ImageData);
1413 this->Properties->yIPW->SetOrigin(pto);
1414 this->Properties->yIPW->SetPoint1(pt1);
1415 this->Properties->yIPW->SetPoint2(pt2);
1416 this->Properties->yIPW->UpdatePlacement();
1417 this->Properties->xzIPW->SetOrigin(pto);
1418 this->Properties->xzIPW->SetPoint1(pt1);
1419 this->Properties->xzIPW->SetPoint2(pt2);
1420 this->Properties->xzIPW->UpdatePlacement();
1421 this->Properties->yIPW->SetSlicePosition(position);
1422 this->Properties->xzIPW->SetSlicePosition(position);
1425 for (int i=0;i<3; i++) {
1426 pto[i] = this->Properties->zIPW->GetOrigin()[i];
1427 pt1[i] = this->Properties->zIPW->GetPoint1()[i];
1428 pt2[i] = this->Properties->zIPW->GetPoint2()[i];
1430 position = this->Properties->zIPW->GetSlicePosition();
1431 this->Properties->zIPW->SetInput(this->ImageData);
1432 this->Properties->xyIPW->SetInput(this->ImageData);
1433 this->Properties->zIPW->SetOrigin(pto);
1434 this->Properties->zIPW->SetPoint1(pt1);
1435 this->Properties->zIPW->SetPoint2(pt2);
1436 this->Properties->zIPW->UpdatePlacement();
1437 this->Properties->xyIPW->SetOrigin(pto);
1438 this->Properties->xyIPW->SetPoint1(pt1);
1439 this->Properties->xyIPW->SetPoint2(pt2);
1440 this->Properties->xyIPW->UpdatePlacement();
1441 this->Properties->zIPW->SetSlicePosition(position);
1442 this->Properties->xyIPW->SetSlicePosition(position);
1446 /// Update the segmented mesh if needed
1447 if (this->Properties->MeshActor)
1449 this->Properties->MeshActor->SetMapper(*this->Properties->itStackMapperList);
1450 vtkPolyDataMapper* cutMapperX = vtkPolyDataMapper::New();
1451 cutMapperX->SetInputConnection((*this->Properties->itStackMapXCutter)->GetOutputPort());
1452 this->Properties->xCutActor->SetMapper(cutMapperX);
1453 vtkPolyDataMapper* cutMapperY = vtkPolyDataMapper::New();
1454 cutMapperY->SetInputConnection((*this->Properties->itStackMapYCutter)->GetOutputPort());
1455 this->Properties->yCutActor->SetMapper(cutMapperY);
1456 vtkPolyDataMapper* cutMapperZ = vtkPolyDataMapper::New();
1457 cutMapperZ->SetInputConnection((*this->Properties->itStackMapZCutter)->GetOutputPort());
1458 this->Properties->zCutActor->SetMapper(cutMapperZ);
1462 this->GetRenderWindow()->Render();
1463 this->GetXYRenderer()->ResetCameraClippingRange();
1464 this->GetRenderWindowXY()->Render();
1465 this->GetXZRenderer()->ResetCameraClippingRange();
1466 this->GetRenderWindowXZ()->Render();
1467 this->GetYZRenderer()->ResetCameraClippingRange();
1468 this->GetRenderWindowYZ()->Render();
1475 void OpenHeartGui::UpdateBackwardViewers()
1478 if ( this->ImageData )
1481 if ( this->itStackVolume == this->StackVolume.begin() )
1483 this->itStackVolume = this->StackVolume.end();
1484 this->CurrentFrame = this->NumberOfVolumes;
1485 if (this->Properties->MeshActor) {
1486 this->itStackMesh = this->StackMesh.end();
1487 this->Properties->itStackMapperList = this->Properties->StackMapperList.end();
1488 this->Properties->itStackMapXCutter = this->Properties->StackMapXCutter.end();
1489 this->Properties->itStackMapYCutter = this->Properties->StackMapYCutter.end();
1490 this->Properties->itStackMapZCutter = this->Properties->StackMapZCutter.end();
1494 --(this->itStackVolume);
1495 --(this->CurrentFrame);
1496 if (this->Properties->MeshActor) {
1497 --(this->itStackMesh);
1498 --(this->Properties->itStackMapperList);
1499 --(this->Properties->itStackMapXCutter);
1500 --(this->Properties->itStackMapYCutter);
1501 --(this->Properties->itStackMapZCutter);
1504 /// Update image data pointer
1505 this->ImageData = (*this->itStackVolume);
1507 if ( this->FlagReslice == 0 )
1510 /// Update the 3 planes
1511 this->Properties->xIPW->SetInput(this->ImageData);
1512 this->Properties->yIPW->SetInput(this->ImageData);
1513 this->Properties->zIPW->SetInput(this->ImageData);
1514 this->Properties->xyIPW->SetInput(this->ImageData);
1515 this->Properties->xzIPW->SetInput(this->ImageData);
1516 this->Properties->yzIPW->SetInput(this->ImageData);
1517 this->Properties->xIPW->SetSlicePosition(this->Properties->position[0]);
1518 this->Properties->yIPW->SetSlicePosition(this->Properties->position[1]);
1519 this->Properties->zIPW->SetSlicePosition(this->Properties->position[2]);
1520 this->Properties->xyIPW->SetSlicePosition(this->Properties->position[2]);
1521 this->Properties->xzIPW->SetSlicePosition(this->Properties->position[1]);
1522 this->Properties->yzIPW->SetSlicePosition(this->Properties->position[0]);
1532 for (int i=0;i<3; i++) {
1533 pto[i] = this->Properties->xIPW->GetOrigin()[i];
1534 pt1[i] = this->Properties->xIPW->GetPoint1()[i];
1535 pt2[i] = this->Properties->xIPW->GetPoint2()[i];
1537 double position = this->Properties->xIPW->GetSlicePosition();
1538 this->Properties->xIPW->SetInput(this->ImageData);
1539 this->Properties->yzIPW->SetInput(this->ImageData);
1540 this->Properties->xIPW->SetOrigin(pto);
1541 this->Properties->xIPW->SetPoint1(pt1);
1542 this->Properties->xIPW->SetPoint2(pt2);
1543 this->Properties->xIPW->UpdatePlacement();
1544 this->Properties->yzIPW->SetOrigin(pto);
1545 this->Properties->yzIPW->SetPoint1(pt1);
1546 this->Properties->yzIPW->SetPoint2(pt2);
1547 this->Properties->yzIPW->UpdatePlacement();
1548 this->Properties->xIPW->SetSlicePosition(position);
1549 this->Properties->yzIPW->SetSlicePosition(position);
1552 for (int i=0;i<3; i++) {
1553 pto[i] = this->Properties->yIPW->GetOrigin()[i];
1554 pt1[i] = this->Properties->yIPW->GetPoint1()[i];
1555 pt2[i] = this->Properties->yIPW->GetPoint2()[i];
1557 position = this->Properties->yIPW->GetSlicePosition();
1558 this->Properties->yIPW->SetInput(this->ImageData);
1559 this->Properties->xzIPW->SetInput(this->ImageData);
1560 this->Properties->yIPW->SetOrigin(pto);
1561 this->Properties->yIPW->SetPoint1(pt1);
1562 this->Properties->yIPW->SetPoint2(pt2);
1563 this->Properties->yIPW->UpdatePlacement();
1564 this->Properties->xzIPW->SetOrigin(pto);
1565 this->Properties->xzIPW->SetPoint1(pt1);
1566 this->Properties->xzIPW->SetPoint2(pt2);
1567 this->Properties->xzIPW->UpdatePlacement();
1568 this->Properties->yIPW->SetSlicePosition(position);
1569 this->Properties->xzIPW->SetSlicePosition(position);
1572 for (int i=0;i<3; i++) {
1573 pto[i] = this->Properties->zIPW->GetOrigin()[i];
1574 pt1[i] = this->Properties->zIPW->GetPoint1()[i];
1575 pt2[i] = this->Properties->zIPW->GetPoint2()[i];
1577 position = this->Properties->zIPW->GetSlicePosition();
1578 this->Properties->zIPW->SetInput(this->ImageData);
1579 this->Properties->xyIPW->SetInput(this->ImageData);
1580 this->Properties->zIPW->SetOrigin(pto);
1581 this->Properties->zIPW->SetPoint1(pt1);
1582 this->Properties->zIPW->SetPoint2(pt2);
1583 this->Properties->zIPW->UpdatePlacement();
1584 this->Properties->xyIPW->SetOrigin(pto);
1585 this->Properties->xyIPW->SetPoint1(pt1);
1586 this->Properties->xyIPW->SetPoint2(pt2);
1587 this->Properties->xyIPW->UpdatePlacement();
1588 this->Properties->zIPW->SetSlicePosition(position);
1589 this->Properties->xyIPW->SetSlicePosition(position);
1593 /// Update the segmented mesh if needed
1594 if (this->Properties->MeshActor)
1596 this->Properties->MeshActor->SetMapper(*this->Properties->itStackMapperList);
1597 vtkPolyDataMapper* cutMapperX = vtkPolyDataMapper::New();
1598 cutMapperX->SetInputConnection((*this->Properties->itStackMapXCutter)->GetOutputPort());
1599 this->Properties->xCutActor->SetMapper(cutMapperX);
1600 vtkPolyDataMapper* cutMapperY = vtkPolyDataMapper::New();
1601 cutMapperY->SetInputConnection((*this->Properties->itStackMapYCutter)->GetOutputPort());
1602 this->Properties->yCutActor->SetMapper(cutMapperY);
1603 vtkPolyDataMapper* cutMapperZ = vtkPolyDataMapper::New();
1604 cutMapperZ->SetInputConnection((*this->Properties->itStackMapZCutter)->GetOutputPort());
1605 this->Properties->zCutActor->SetMapper(cutMapperZ);
1608 this->GetRenderWindow()->Render();
1609 this->GetRenderWindowXY()->Render();
1610 this->GetRenderWindowXZ()->Render();
1611 this->GetRenderWindowYZ()->Render();
1618 void OpenHeartGui::slotMeshAlpha(int val)
1621 if ( this->Properties->MeshActor )
1623 this->Properties->MeshActor->GetProperty()->SetOpacity(val/100.);
1624 this->GetRenderWindow()->Render();
1630 void OpenHeartGui::slotRefreshViewer(int val)
1634 while ( val != this->CurrentFrame )
1636 if ( (this->FlagLoopEndToBegin == 0) && (this->FlagLoopBeginToEnd == 0) )
1638 /// Normal transition
1639 if ( ( val-this->CurrentFrame ) > 0 )
1640 UpdateForwardViewers();
1642 UpdateBackwardViewers();
1646 /// Loop end to begin
1647 if ( this->FlagLoopEndToBegin == 1 ) {
1648 this->FlagLoopEndToBegin = 0;
1649 UpdateForwardViewers();
1651 /// Loop begin to end
1652 if ( this->FlagLoopBeginToEnd == 1 ) {
1653 this->FlagLoopBeginToEnd = 0;
1654 UpdateBackwardViewers();
1659 /// Update Frame text
1660 if ( (this->FlagDisplayText) && (this->Properties->TextMapperNumFrame) )
1663 str.sprintf("Frame: %d",this->CurrentFrame);
1664 this->Properties->TextMapperNumFrame->SetInput(str.toStdString().c_str());
1665 this->GetRenderWindow()->Render();
1671 void OpenHeartGui::slotTabChange(int val)
1677 if ( this->Properties->ApexPointActor != 0 ) {
1678 this->GetMainRenderer()->AddActor(this->Properties->ApexPointActor);
1679 this->FlagDisplayApexPoint = 1;
1681 if ( this->Properties->BasalPointActor != 0 ) {
1682 this->GetMainRenderer()->AddActor(this->Properties->BasalPointActor);
1683 this->FlagDisplayBasalPoint = 1;
1685 if ( this->Properties->LongAxisActor != 0 ) {
1686 this->GetMainRenderer()->AddActor(this->Properties->LongAxisActor);
1687 this->FlagDisplayLongAxis = 1;
1695 if ( this->FlagDisplayApexPoint == 1 ) {
1696 this->GetMainRenderer()->RemoveActor(this->Properties->ApexPointActor);
1697 this->FlagDisplayApexPoint = 0;
1698 this->GetRenderWindow()->Render();
1700 if ( this->FlagDisplayBasalPoint == 1 ) {
1701 this->GetMainRenderer()->RemoveActor(this->Properties->BasalPointActor);
1702 this->FlagDisplayBasalPoint = 0;
1703 this->GetRenderWindow()->Render();
1705 if ( this->FlagDisplayLongAxis == 1 ) {
1706 this->GetMainRenderer()->RemoveActor(this->Properties->LongAxisActor);
1707 this->FlagDisplayLongAxis = 0;
1708 this->GetRenderWindow()->Render();
1717 void OpenHeartGui::slotPlay()
1719 if ( this->FlagPlay == 0 ) {
1721 this->pushButtonPlay->setText("Pause");
1722 this->scrollBar->setEnabled(false);
1723 this->Timer->start(40);
1727 this->Timer->stop();
1728 this->pushButtonPlay->setText("Play");
1729 this->scrollBar->setEnabled(true);
1734 void OpenHeartGui::slotTimerEvent()
1737 int val = this->CurrentFrame;
1738 if ( val < (this->NumberOfVolumes-1) )
1739 this->scrollBar->setSliderPosition(val+1);
1741 this->FlagLoopEndToBegin = 1;
1742 this->scrollBar->setSliderPosition(0);
1748 void OpenHeartGui::slotBasalPoint()
1751 if ( this->Properties->BasalPointActor == 0 ) {
1752 this->Properties->BasalPointActor = vtkSmartPointer<vtkActor>::New();
1755 this->GetMainRenderer()->RemoveActor(this->Properties->BasalPointActor);
1758 vtkSmartPointer<vtkSphereSource> sphereSource = vtkSmartPointer<vtkSphereSource>::New();
1759 sphereSource->SetCenter(this->Properties->position[0],
1760 this->Properties->position[1],
1761 this->Properties->position[2]);
1762 sphereSource->SetRadius(5.0*this->ImageData->GetSpacing()[0]);
1763 sphereSource->Update();
1765 for (int i=0; i<3; i++)
1766 this->BasalPoint[i] = this->Properties->position[i];
1768 vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
1769 mapper->SetInput(sphereSource->GetOutput());
1771 this->Properties->BasalPointActor->SetMapper(mapper);
1772 this->Properties->BasalPointActor->GetProperty()->SetColor(0,1,0);
1774 this->GetMainRenderer()->AddActor(this->Properties->BasalPointActor);
1775 this->FlagDisplayBasalPoint = 1;
1777 if ( this->Properties->ApexPointActor != 0 )
1779 this->CreateLongAxisActor();
1780 this->FlagLongAxis = 1;
1781 this->GetMainRenderer()->AddActor(this->Properties->LongAxisActor);
1782 this->FlagDisplayLongAxis = 1;
1783 this->pushButtonReslice->setEnabled(true);
1786 this->GetRenderWindow()->Render();
1791 void OpenHeartGui::slotApexPoint()
1794 if ( this->Properties->ApexPointActor == 0 ) {
1795 this->Properties->ApexPointActor = vtkSmartPointer<vtkActor>::New();
1798 this->GetMainRenderer()->RemoveActor(this->Properties->ApexPointActor);
1801 vtkSmartPointer<vtkSphereSource> sphereSource = vtkSmartPointer<vtkSphereSource>::New();
1802 sphereSource->SetCenter(this->Properties->position[0],
1803 this->Properties->position[1],
1804 this->Properties->position[2]);
1805 sphereSource->SetRadius(5.0*this->ImageData->GetSpacing()[0]);
1806 sphereSource->Update();
1808 for (int i=0; i<3; i++)
1809 this->ApexPoint[i] = this->Properties->position[i];
1811 vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
1812 mapper->SetInput(sphereSource->GetOutput());
1814 this->Properties->ApexPointActor->SetMapper(mapper);
1815 this->Properties->ApexPointActor->GetProperty()->SetColor(0,1,0);
1817 this->GetMainRenderer()->AddActor(this->Properties->ApexPointActor);
1818 this->FlagDisplayApexPoint = 1;
1820 if ( this->Properties->BasalPointActor != 0 )
1822 this->CreateLongAxisActor();
1823 this->FlagLongAxis = 1;
1824 this->GetMainRenderer()->AddActor(this->Properties->LongAxisActor);
1825 this->FlagDisplayLongAxis = 1;
1826 this->pushButtonReslice->setEnabled(true);
1829 this->GetRenderWindow()->Render();
1834 void OpenHeartGui::CreateLongAxisActor()
1837 if ( this->Properties->LongAxisActor == 0 ) {
1838 this->Properties->LongAxisActor = vtkSmartPointer<vtkActor>::New();
1841 this->GetMainRenderer()->RemoveActor(this->Properties->LongAxisActor);
1844 vtkSmartPointer<vtkLineSource> lineSource = vtkSmartPointer<vtkLineSource>::New();
1845 lineSource->SetPoint1(this->BasalPoint);
1846 lineSource->SetPoint2(this->ApexPoint);
1847 lineSource->Update();
1849 vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
1850 mapper->SetInputConnection(lineSource->GetOutputPort());
1852 this->Properties->LongAxisActor->SetMapper(mapper);
1853 this->Properties->LongAxisActor->GetProperty()->SetLineWidth(2);
1854 this->Properties->LongAxisActor->GetProperty()->SetColor(0,1,0);
1859 void OpenHeartGui::DisplayMainAxisManagement()
1865 void OpenHeartGui::DisplayMeshManagement()
1868 if ( this->Properties->MeshActor != 0 )
1871 if ( this->FlagDisplayMesh == 0 )
1873 this->GetMeshRenderer()->AddActor(this->Properties->MeshActor);
1874 this->FlagDisplayMesh = 1;
1878 this->GetMeshRenderer()->RemoveActor(this->Properties->MeshActor);
1879 this->FlagDisplayMesh = 0;
1881 this->GetRenderWindow()->Render();
1887 void OpenHeartGui::DisplayModeManagement()
1890 if ( this->FlagDisplayText == 0 )
1893 this->FlagDisplayText = 1;
1894 if ( this->Properties->TextMapperPixel ) {
1895 this->Properties->TextMapperPixel->SetInput("Display on");
1897 if ( this->Properties->TextMapperNumFrame ) {
1899 str.sprintf("f = %d",this->CurrentFrame);
1900 this->Properties->TextMapperNumFrame->SetInput(str.toStdString().c_str());
1902 if ( this->Properties->TextMapperResolution ) {
1904 str.sprintf("Resolution: %.2f x %.2f x %.2f mm",this->ImageData->GetSpacing()[0]*1000,this->ImageData->GetSpacing()[1]*1000,this->ImageData->GetSpacing()[2]*1000);
1905 this->Properties->TextMapperResolution->SetInput(str.toStdString().c_str());
1907 if ( this->Properties->TextMapperSlice ) {
1908 int slice = (int)( (this->Properties->position[1] - this->ImageData->GetOrigin()[1]) / this->ImageData->GetSpacing()[1] + 0.5f );
1910 strSlice.sprintf("Slice: %d",slice);
1911 this->Properties->TextMapperSlice->SetInput(strSlice.toStdString().c_str());
1914 this->GetRenderWindow()->Render();
1920 this->FlagDisplayText = 0;
1921 if ( this->Properties->TextMapperPixel ) {
1922 this->Properties->TextMapperPixel->SetInput("Display off");
1924 if ( this->Properties->TextMapperNumFrame ) {
1925 this->Properties->TextMapperNumFrame->SetInput("");
1927 if ( this->Properties->TextMapperResolution ) {
1928 this->Properties->TextMapperResolution->SetInput("");
1930 if ( this->Properties->TextMapperSlice ) {
1931 this->Properties->TextMapperSlice->SetInput("");
1933 if ( this->Properties->TextMapperMM ) {
1934 this->Properties->TextMapperMM->SetInput("");
1936 if ( this->Properties->TextMapperValue ) {
1937 this->Properties->TextMapperValue->SetInput("");
1939 this->GetRenderWindow()->Render();
1946 vtkActor2D* OpenHeartGui::AddFixedText(const char *text, float x, float y, float R,float G, float B, int Size)
1949 vtkTextMapper *Mapper = vtkTextMapper::New();
1950 vtkActor2D *Actor = vtkActor2D::New();
1951 Mapper->SetInput(text);
1952 Mapper->GetTextProperty()->SetColor(R, G, B);
1953 Mapper->GetTextProperty()->SetFontSize(Size);
1954 Mapper->GetTextProperty()->SetJustificationToLeft();
1955 Mapper->GetTextProperty()->ShadowOff();
1956 Actor->SetPosition(x, y);
1957 Actor->SetMapper(Mapper);
1963 void OpenHeartGui::resizeEvent(QResizeEvent* event)
1965 int sizeX = this->qVTK->GetRenderWindow()->GetSize()[0];
1966 int sizeY = this->qVTK->GetRenderWindow()->GetSize()[1];
1967 if ( (sizeX!=382) || (sizeY!=462) ) {
1968 this->Properties->TextActorSlice->SetPosition(10,this->GetRenderWindow()->GetSize()[1]-20);
1969 this->Properties->TextActorPixel->SetPosition(this->GetRenderWindow()->GetSize()[0]-10,this->GetRenderWindow()->GetSize()[1]-20);
1970 this->Properties->TextActorMM->SetPosition(this->GetRenderWindow()->GetSize()[0]-10,this->GetRenderWindow()->GetSize()[1]-45);
1971 this->Properties->TextActorValue->SetPosition(this->GetRenderWindow()->GetSize()[0]-10,this->GetRenderWindow()->GetSize()[1]-70);
1972 this->GetRenderWindow()->Render();
1973 QMainWindow::resizeEvent(event);
1978 void OpenHeartGui::HidePlanModeManagement()
1981 if ( this->FlagHidePlan == 0 )
1983 this->FlagHidePlan = 1;
1984 this->Properties->xIPW->SetTextureVisibility(0);
1985 this->Properties->xIPW->GetPlaneProperty()->SetOpacity(0);
1986 this->Properties->yIPW->SetTextureVisibility(0);
1987 this->Properties->yIPW->GetPlaneProperty()->SetOpacity(0);
1988 this->Properties->zIPW->SetTextureVisibility(0);
1989 this->Properties->zIPW->GetPlaneProperty()->SetOpacity(0);
1991 if ( (this->FlagDisplayMesh==0) && (this->FlagDisplayMeshContours==0) ) {
1992 this->GetMeshRenderer()->AddActor(this->Properties->MeshActor);
1993 this->FlagDisplayMesh = 1;
1996 if ( this->FlagDisplayMeshContours == 1 ) {
1997 this->GetMeshRenderer()->RemoveActor(this->Properties->xCutActor);
1998 this->GetMeshRenderer()->RemoveActor(this->Properties->yCutActor);
1999 this->GetMeshRenderer()->RemoveActor(this->Properties->zCutActor);
2000 this->FlagDisplayMeshContours = 0;
2003 this->GetRenderWindow()->Render();
2008 if ( this->FlagDisplayMesh == 1 )
2009 this->GetMeshRenderer()->RemoveActor(this->Properties->MeshActor);
2010 if ( this->FlagDisplayMeshContours == 1 ) {
2011 this->GetMeshRenderer()->RemoveActor(this->Properties->xCutActor);
2012 this->GetMeshRenderer()->RemoveActor(this->Properties->yCutActor);
2013 this->GetMeshRenderer()->RemoveActor(this->Properties->zCutActor);
2015 this->FlagHidePlan = 0;
2017 switch (this->ViewButton) {
2019 this->Properties->xIPW->SetTextureVisibility(1);
2020 this->Properties->xIPW->GetPlaneProperty()->SetOpacity(1);
2021 this->Properties->yIPW->SetTextureVisibility(1);
2022 this->Properties->yIPW->GetPlaneProperty()->SetOpacity(1);
2023 this->Properties->zIPW->SetTextureVisibility(1);
2024 this->Properties->zIPW->GetPlaneProperty()->SetOpacity(1);
2025 if ( this->FlagDisplayMeshContours == 1 ) {
2026 this->GetMeshRenderer()->AddActor(this->Properties->xCutActor);
2027 this->GetMeshRenderer()->AddActor(this->Properties->yCutActor);
2028 this->GetMeshRenderer()->AddActor(this->Properties->zCutActor);
2032 this->Properties->xIPW->SetTextureVisibility(1);
2033 this->Properties->xIPW->GetPlaneProperty()->SetOpacity(1);
2034 if ( this->FlagDisplayMeshContours == 1 ) {
2035 this->GetMeshRenderer()->AddActor(this->Properties->xCutActor);
2039 this->Properties->yIPW->SetTextureVisibility(1);
2040 this->Properties->yIPW->GetPlaneProperty()->SetOpacity(1);
2041 if ( this->FlagDisplayMeshContours == 1 ) {
2042 this->GetMeshRenderer()->AddActor(this->Properties->yCutActor);
2046 this->Properties->zIPW->SetTextureVisibility(1);
2047 this->Properties->zIPW->GetPlaneProperty()->SetOpacity(1);
2048 if ( this->FlagDisplayMeshContours == 1 ) {
2049 this->GetMeshRenderer()->AddActor(this->Properties->zCutActor);
2056 if ( this->FlagDisplayMesh == 1 )
2057 this->GetMeshRenderer()->AddActor(this->Properties->MeshActor);
2058 this->GetRenderWindow()->Render();
2064 void OpenHeartGui::UpdateClinicalIndices()
2068 float ESV = 1000000;
2069 int NbElements = this->TableChart->GetNumberOfRows();
2070 for ( int k=0; k<NbElements; k++)
2072 float val = this->TableChart->GetValue(k,1).ToFloat();
2078 /// End Diastolic and End systolic volume
2080 strESV.sprintf("%2.1f ml",ESV);
2082 strEDV.sprintf("%2.1f ml",EDV);
2083 this->labelESVValue->setText(strESV);
2084 this->labelEDVValue->setText(strEDV);
2085 /// Ejection fraction indice
2086 float EF = 100 * (EDV-ESV) / (EDV+1e-6);
2088 strEF.sprintf("%2.1f %%",EF);
2089 this->labelEFValue->setText(strEF);
2090 /// Stroke volume indice
2093 strSV.sprintf("%2.1f ml",SV);
2094 this->labelSVValue->setText(strSV);
2099 /// Custimize interface colors
2100 void OpenHeartGui::SetInterfaceColors()
2102 this->tabMesh->setStyleSheet("background-color: rgb(0,0,0);");
2103 this->widgetXY->setStyleSheet("border-style: solid; border-width: 2px; border-color: blue;");
2104 this->widgetXZ->setStyleSheet("border-style: solid; border-width: 2px; border-color: yellow;");
2105 this->widgetYZ->setStyleSheet("border-style: solid; border-width: 2px; border-color: red;");
2109 void OpenHeartGui::slotReslice()
2112 if ( this->pushButtonReslice->isEnabled() )
2114 if ( this->FlagReslice == 0 )
2116 /// Reslice planes according to the main axis
2117 this->SetLongAxisView();
2118 /// Display off the Slice text actor
2119 this->GetMainRenderer()->RemoveActor(this->Properties->TextActorSlice);
2120 /// Replace Reslice text by Reset one into the push button
2121 this->pushButtonReslice->setText("Reset");
2122 /// Set corresponding flag to 1
2123 this->FlagReslice = 1;
2127 /// Reset the reslicing operation
2128 this->ResetReslicing();
2129 /// Display on the Slice text actor
2130 this->GetMainRenderer()->AddActor(this->Properties->TextActorSlice);
2131 /// Replace Reslice text by Reset one into the push button
2132 this->pushButtonReslice->setText("Reslice");
2133 /// Set corresponding flag to 0
2134 this->FlagReslice = 0;
2142 void OpenHeartGui::SetLongAxisView()
2145 /// Compute the rotation matrix between the Z-axis and the long axis of the heart
2146 this->ComputeRotationMatrix();
2148 /// Set the corresponding vtkTransform object
2149 this->TransformViewOrientation->SetMatrix(this->RotationMatrix);
2150 this->TransformViewOrientationInv->SetMatrix(this->RotationMatrixInv);
2152 /// Set the plans at the center of the volume
2154 for ( int i=0; i<3; i++ )
2155 center[i] = 0.5*(this->ImageData->GetDimensions()[i])*(this->ImageData->GetSpacing()[i]);
2156 this->Properties->xIPW->SetSlicePosition(center[0]);
2157 this->Properties->yIPW->SetSlicePosition(center[1]);
2158 this->Properties->zIPW->SetSlicePosition(center[2]);
2159 this->Properties->yzIPW->SetSlicePosition(center[0]);
2160 this->Properties->xzIPW->SetSlicePosition(center[1]);
2161 this->Properties->xyIPW->SetSlicePosition(center[2]);
2163 /////////////////////////////////////////////////
2164 /////////////////////////////////////////////////
2165 /////////////////////////////////////////////////
2166 /// Process XZ-plans
2168 /// Apply the rotation to the points defining the cartesian plan of interest
2169 //double *cy = this->Properties->yIPW->GetCenter();
2170 double *pt1 = this->Properties->yIPW->GetPoint1();
2171 double *pt2 = this->Properties->yIPW->GetPoint2();
2172 double *pto = this->Properties->yIPW->GetOrigin();
2177 /// Do this to ensure that the center of the rotation corresponds to the center of the volume
2178 for (int i=0; i<3; i++) {
2179 pt1[i] -= center[i];
2180 pt2[i] -= center[i];
2181 pto[i] -= center[i];
2184 /// Apply transformation
2185 this->TransformViewOrientation->TransformPoint(pt1,newpt1);
2186 this->TransformViewOrientation->TransformPoint(pt2,newpt2);
2187 this->TransformViewOrientation->TransformPoint(pto,newpto);
2188 for (int i=0; i<3; i++) {
2189 newpt1[i] += center[i];
2190 newpt2[i] += center[i];
2191 newpto[i] += center[i];
2194 this->Properties->yIPW->SetOrigin(newpto);
2195 this->Properties->yIPW->SetPoint1(newpt1);
2196 this->Properties->yIPW->SetPoint2(newpt2);
2197 this->Properties->yIPW->UpdatePlacement();
2199 this->Properties->xzIPW->SetOrigin(newpto);
2200 this->Properties->xzIPW->SetPoint1(newpt1);
2201 this->Properties->xzIPW->SetPoint2(newpt2);
2202 this->Properties->xzIPW->UpdatePlacement();
2205 /////////////////////////////////////////////////
2206 /////////////////////////////////////////////////
2207 /////////////////////////////////////////////////
2208 /// Process YZ-plans
2210 pt1 = this->Properties->xIPW->GetPoint1();
2211 pt2 = this->Properties->xIPW->GetPoint2();
2212 pto = this->Properties->xIPW->GetOrigin();
2214 /// Do this to ensure that the center of the rotation corresponds to the center of the volume
2215 for (int i=0; i<3; i++) {
2216 pt1[i] -= center[i];
2217 pt2[i] -= center[i];
2218 pto[i] -= center[i];
2221 /// Apply transformation
2222 this->TransformViewOrientation->TransformPoint(pt1,newpt1);
2223 this->TransformViewOrientation->TransformPoint(pt2,newpt2);
2224 this->TransformViewOrientation->TransformPoint(pto,newpto);
2225 for (int i=0; i<3; i++) {
2226 newpt1[i] += center[i];
2227 newpt2[i] += center[i];
2228 newpto[i] += center[i];
2231 this->Properties->xIPW->SetOrigin(newpto);
2232 this->Properties->xIPW->SetPoint1(newpt1);
2233 this->Properties->xIPW->SetPoint2(newpt2);
2234 this->Properties->xIPW->UpdatePlacement();
2236 this->Properties->yzIPW->SetOrigin(newpto);
2237 this->Properties->yzIPW->SetPoint1(newpt1);
2238 this->Properties->yzIPW->SetPoint2(newpt2);
2239 this->Properties->yzIPW->UpdatePlacement();
2242 /////////////////////////////////////////////////
2243 /////////////////////////////////////////////////
2244 /////////////////////////////////////////////////
2245 /// Process XY-plans
2247 pt1 = this->Properties->zIPW->GetPoint1();
2248 pt2 = this->Properties->zIPW->GetPoint2();
2249 pto = this->Properties->zIPW->GetOrigin();
2251 /// Do this to ensure that the center of the rotation corresponds to the center of the volume
2252 for (int i=0; i<3; i++) {
2253 pt1[i] -= center[i];
2254 pt2[i] -= center[i];
2255 pto[i] -= center[i];
2258 /// Apply transformation
2259 this->TransformViewOrientation->TransformPoint(pt1,newpt1);
2260 this->TransformViewOrientation->TransformPoint(pt2,newpt2);
2261 this->TransformViewOrientation->TransformPoint(pto,newpto);
2262 for (int i=0; i<3; i++) {
2263 newpt1[i] += center[i];
2264 newpt2[i] += center[i];
2265 newpto[i] += center[i];
2268 this->Properties->zIPW->SetOrigin(newpto);
2269 this->Properties->zIPW->SetPoint1(newpt1);
2270 this->Properties->zIPW->SetPoint2(newpt2);
2271 this->Properties->zIPW->UpdatePlacement();
2273 this->Properties->xyIPW->SetOrigin(newpto);
2274 this->Properties->xyIPW->SetPoint1(newpt1);
2275 this->Properties->xyIPW->SetPoint2(newpt2);
2276 this->Properties->xyIPW->UpdatePlacement();
2278 /////////////////////////////////////////////////
2279 /////////////////////////////////////////////////
2280 /////////////////////////////////////////////////
2281 /// Final translation to match the Long axis
2283 /// XZ plan translation
2284 double *ncy = this->Properties->yIPW->GetCenter();
2287 vtkLine::DistanceToLine(ncy, this->BasalPoint, this->ApexPoint, t, closest);
2288 double offset = this->Properties->yIPW->GetSlicePosition() + (closest[1] - ncy[1]);
2289 this->Properties->yIPW->SetSlicePosition(offset);
2290 this->Properties->xzIPW->SetSlicePosition(offset);
2292 /// YZ plan translation
2293 double *ncx = this->Properties->xIPW->GetCenter();
2294 vtkLine::DistanceToLine(ncx, this->BasalPoint, this->ApexPoint, t, closest);
2295 offset = this->Properties->xIPW->GetSlicePosition() + (closest[0] - ncx[0]);
2296 this->Properties->xIPW->SetSlicePosition(offset);
2297 this->Properties->yzIPW->SetSlicePosition(offset);
2299 /// XY plan translation
2300 double *ncz = this->Properties->zIPW->GetCenter();
2302 for (int i=0; i<3; i++)
2303 mid[i] = this->BasalPoint[i] + 0.5 * (this->ApexPoint[i]-this->BasalPoint[i]);
2304 offset = this->Properties->zIPW->GetSlicePosition() + (mid[2] - ncz[2]);
2305 this->Properties->zIPW->SetSlicePosition(offset);
2306 this->Properties->xyIPW->SetSlicePosition(offset);
2308 /// Update Properties->position to fit to the new position
2309 this->Properties->position[0] = this->Properties->xIPW->GetSlicePosition();
2310 this->Properties->position[1] = this->Properties->yIPW->GetSlicePosition();
2311 this->Properties->position[2] = this->Properties->zIPW->GetSlicePosition();
2314 /////////////////////////////////////////////////
2315 /////////////////////////////////////////////////
2316 /////////////////////////////////////////////////
2318 this->UpdateViewer(0,this->ZoomLabel,this->RenXY);
2319 this->UpdateViewer(1,this->ZoomLabel,this->RenXZ);
2320 this->UpdateViewer(2,this->ZoomLabel,this->RenYZ);
2321 this->GetRenderWindow()->Render();
2326 /// Compute the rotation matrix between the Z-axis and the long axis of the heart
2327 void OpenHeartGui::ComputeRotationMatrix()
2330 double ZAxis[] = {0,0,1};
2332 for (int i=0; i<3; i++)
2333 MainAxis[i] = this->BasalPoint[i] - this->ApexPoint[i];
2334 vtkMath::Normalize(MainAxis);
2336 /// Compute rotation matrix between two vectors: MainAxis and ZAxis
2339 for (int i=0; i<3; i++) {
2340 normal1[i] = ZAxis[i];
2341 normal2[i] = MainAxis[i];
2345 vtkMath::Cross(normal1, normal2, vec);
2346 double costheta = vtkMath::Dot(normal1, normal2);
2347 double sintheta = vtkMath::Norm(vec);
2348 double theta = atan2(sintheta, costheta);
2356 /// convert to quaternion
2357 costheta = cos(0.5*theta);
2358 sintheta = sin(0.5*theta);
2361 quat[1] = vec[0]*sintheta;
2362 quat[2] = vec[1]*sintheta;
2363 quat[3] = vec[2]*sintheta;
2365 /// convert to matrix
2367 vtkMath::QuaternionToMatrix3x3(quat,mat);
2369 /// Create corresponding 4x4 matrix
2370 this->RotationMatrix->Identity();
2371 this->RotationMatrixInv->Identity();
2372 for (unsigned int i = 0; i < 3; i++) {
2373 for (unsigned int j = 0; j < 3; j++) {
2374 this->RotationMatrix->SetElement(i, j, mat[i][j]);
2375 this->RotationMatrixInv->SetElement(i, j, mat[i][j]);
2378 this->RotationMatrixInv->Invert();
2383 /// Reset the reslicing operation
2384 void OpenHeartGui::ResetReslicing()
2387 /// Set the rotation matrix to identity
2388 this->RotationMatrix->Identity();
2389 this->RotationMatrixInv->Identity();
2391 /// Set the corresponding vtkTransform object
2392 this->TransformViewOrientation->SetMatrix(this->RotationMatrix);
2393 this->TransformViewOrientationInv->SetMatrix(this->RotationMatrixInv);
2395 /// Switch off the oblique orientation of each plan
2396 this->Properties->xIPW->SetPlaneOrientationToXAxes();
2397 this->Properties->yzIPW->SetPlaneOrientationToXAxes();
2398 this->Properties->yIPW->SetPlaneOrientationToYAxes();
2399 this->Properties->xzIPW->SetPlaneOrientationToYAxes();
2400 this->Properties->zIPW->SetPlaneOrientationToZAxes();
2401 this->Properties->xyIPW->SetPlaneOrientationToZAxes();
2403 /// Set the plans at the center of the volume
2405 for ( unsigned int k=0; k<3; k++ )
2406 center[k] = ((this->ImageData->GetDimensions()[k])*(this->ImageData->GetSpacing()[k]))/2;
2408 this->Properties->xIPW->SetSlicePosition(center[0]);
2409 this->Properties->yzIPW->SetSlicePosition(center[0]);
2410 this->Properties->yIPW->SetSlicePosition(center[1]);
2411 this->Properties->xzIPW->SetSlicePosition(center[1]);
2412 this->Properties->zIPW->SetSlicePosition(center[2]);
2413 this->Properties->xyIPW->SetSlicePosition(center[2]);
2415 /// Update Properties->position to fit to the new position
2416 this->Properties->position[0] = center[0];
2417 this->Properties->position[1] = center[1];
2418 this->Properties->position[2] = center[2];
2421 this->UpdateViewer(0,this->ZoomLabel,this->RenXY);
2422 this->UpdateViewer(1,this->ZoomLabel,this->RenXZ);
2423 this->UpdateViewer(2,this->ZoomLabel,this->RenYZ);
2424 this->GetRenderWindow()->Render();
2429 void OpenHeartGui::UpdateViewer(int view, double zoom, vtkRenderer *ren)
2434 for (int i=0; i<3; i++)
2435 center[i] = 0.5 * this->ImageData->GetDimensions()[i] * this->ImageData->GetSpacing()[i];
2436 ren->GetActiveCamera()->SetFocalPoint(center);
2440 double newPosition[3];
2444 position[0] = 0.5 * this->ImageData->GetDimensions()[0] * this->ImageData->GetSpacing()[0];
2445 position[1] = 0.5 * this->ImageData->GetDimensions()[1] * this->ImageData->GetSpacing()[1];
2446 position[2] = 10 * this->ImageData->GetDimensions()[2] * this->ImageData->GetSpacing()[2];
2449 position[0] = 0.5 * this->ImageData->GetDimensions()[0] * this->ImageData->GetSpacing()[0];
2450 position[1] = 10 * this->ImageData->GetDimensions()[1] * this->ImageData->GetSpacing()[1];
2451 position[2] = 0.5 * this->ImageData->GetDimensions()[2] * this->ImageData->GetSpacing()[2];
2454 position[0] = 10 * this->ImageData->GetDimensions()[0] * this->ImageData->GetSpacing()[0];
2455 position[1] = 0.5 * this->ImageData->GetDimensions()[1] * this->ImageData->GetSpacing()[1];
2456 position[2] = 0.5 * this->ImageData->GetDimensions()[2] * this->ImageData->GetSpacing()[2];
2458 for (int i=0; i<3; i++)
2459 position[i] = position[i] - center[i];
2460 this->TransformViewOrientation->TransformPoint(position,newPosition);
2461 for (int i=0; i<3; i++)
2462 newPosition[i] = newPosition[i] + center[i];
2463 ren->GetActiveCamera()->SetPosition(newPosition);
2466 double pt[] = {0,0,-1};
2468 this->TransformViewOrientation->TransformPoint(pt,viewup);
2469 ren->GetActiveCamera()->SetViewUp(viewup);
2471 ren->GetActiveCamera()->Zoom(zoom);
2472 ren->GetRenderWindow()->Render();
2477 void OpenHeartGui::ComputePointBeforeRotation(double *position)
2481 double newPosition[3];
2482 for (int i=0; i<3; i++)
2483 center[i] = 0.5 * this->ImageData->GetDimensions()[i] * this->ImageData->GetSpacing()[i];
2485 for (int i=0; i<3; i++)
2486 position[i] = position[i] - center[i];
2487 this->TransformViewOrientationInv->TransformPoint(position,newPosition);
2488 for (int i=0; i<3; i++)
2489 position[i] = newPosition[i] + center[i];