View difference between Paste ID: EcMyVBRH and fkDDf5k5
SHOW: | | - or go back to the newest paste.
1
// The original code is from VTK's Examples from here:
2
// https://github.com/Kitware/VTK/tree/master/Examples/GUI/Qt/FourPaneViewer
3
// This link also includes the necessary .ui file for Qt
4
// and the cmake file.
5
//
6
// Note: In QtVTKRenderWindows.cxx you may want to change 
7
// the path to the Dicom directory to an appropriate location.
8
9
//==========================
10
//QtVTKRenderWindows.h
11
//==========================
12
13
#ifndef QtVTKRenderWindows_H
14
#define QtVTKRenderWindows_H
15
16
#include "vtkSmartPointer.h"
17
#include "vtkResliceImageViewer.h"
18
#include "vtkImagePlaneWidget.h"
19
#include "vtkDistanceWidget.h"
20
#include "vtkResliceImageViewerMeasurements.h"
21
#include <QMainWindow>
22
23
// Forward Qt class declarations
24
class Ui_QtVTKRenderWindows;
25
26
class QtVTKRenderWindows : public QMainWindow
27
{
28
  Q_OBJECT
29
public:
30
31
  // Constructor/Destructor
32
  QtVTKRenderWindows(int argc, char *argv[]);
33
  ~QtVTKRenderWindows() {};
34
35
public slots:
36
  virtual void resliceMode(int);
37
  virtual void Render();
38
39
protected:
40
  vtkSmartPointer< vtkResliceImageViewer > riw[3];
41
  vtkSmartPointer< vtkImagePlaneWidget > planeWidget[3];
42
  vtkSmartPointer< vtkDistanceWidget > DistanceWidget[3];
43
  vtkSmartPointer< vtkResliceImageViewerMeasurements > ResliceMeasurements;
44
45
private:
46
47
  // Designer form
48
  Ui_QtVTKRenderWindows *ui;
49
};
50
51
#endif // QtVTKRenderWindows_H
52
53
//============================
54
//QtVTKRenderWindows.cxx
55
//============================
56
57
#include "ui_QtVTKRenderWindows.h"
58
#include "QtVTKRenderWindows.h"
59
60
#include <vtkRenderer.h>
61
#include <vtkRenderWindow.h>
62
#include "vtkResliceImageViewer.h"
63
#include "vtkResliceCursorLineRepresentation.h"
64
#include "vtkResliceCursorThickLineRepresentation.h"
65
#include "vtkResliceCursorWidget.h"
66
#include "vtkResliceCursorActor.h"
67
#include "vtkResliceCursorPolyDataAlgorithm.h"
68
#include "vtkResliceCursor.h"
69
#include "vtkDICOMImageReader.h"
70
#include "vtkCellPicker.h"
71
#include "vtkProperty.h"
72
#include "vtkPlane.h"
73
#include "vtkImageData.h"
74
#include "vtkCommand.h"
75
#include "vtkPlaneSource.h"
76
#include "vtkLookupTable.h"
77
#include "vtkImageMapToWindowLevelColors.h"
78
#include "vtkInteractorStyleImage.h"
79
#include "vtkImageSlabReslice.h"
80
#include "vtkBoundedPlanePointPlacer.h"
81
#include "vtkDistanceWidget.h"
82
#include "vtkDistanceRepresentation.h"
83
#include "vtkHandleRepresentation.h"
84
#include "vtkResliceImageViewerMeasurements.h"
85
#include "vtkDistanceRepresentation2D.h"
86
#include "vtkPointHandleRepresentation3D.h"
87
#include "vtkPointHandleRepresentation2D.h"
88
#include <qdebug.h>
89
90
#include <vtkPolyDataMapper.h>
91
#include <vtkObjectFactory.h>
92
#include <vtkActor.h>
93
#include <vtkSmartPointer.h>
94
#include <vtkRenderWindow.h>
95
#include <vtkRenderer.h>
96
#include <vtkRenderWindowInteractor.h>
97
#include <vtkPolyData.h>
98
#include <vtkSphereSource.h>
99
#include <vtkInteractorStyleTrackballCamera.h>
100
#include "QVTKWidget.h"
101
#include <QKeyEvent>
102
103
//----------------------------------------------------------------------------
104
// NEW: Define interactor
105
class myRenderWindowInteractor : public QVTKInteractor  //vtkRenderWindowInteractor
106
{
107
public:
108
	static myRenderWindowInteractor* New(); //return new KeyPressInteractorStyle;
109
	vtkTypeMacro(myRenderWindowInteractor, QVTKInteractor);
110
111
	virtual void OnChar(){qDebug()<<"OnChar() event stopped";};
112
	virtual void OnKeyDown(){qDebug()<<"OnKeyDown() event stopped";};
113
	virtual void OnKeyUp(){qDebug()<<"OnKeyUp() event stopped";};
114
	virtual void OnKeyPress(){qDebug()<<"OnKeyPress() event stopped";};
115
	virtual void OnKeyRelease(){qDebug()<<"OnKeyRelease() event stopped";};
116
};
117
vtkStandardNewMacro(myRenderWindowInteractor);
118
119
// Define interaction style
120
class KeyPressInteractorStyle : public vtkInteractorStyle
121
{
122
public:
123
	static KeyPressInteractorStyle* New();
124
	vtkTypeMacro(KeyPressInteractorStyle, vtkInteractorStyle);
125
126
	virtual void OnKeyPress() 
127
	{
128
		// Get the keypress
129
		vtkRenderWindowInteractor *rwi = this->Interactor;
130
		std::string key = rwi->GetKeySym();
131
132
		// Output the key that was pressed
133
		std::cout << "Pressed " << key << std::endl;
134
		qDebug()<< "Pressed " << rwi->GetKeySym();
135
136
		// Forward events
137
		vtkInteractorStyle::OnKeyPress();
138
	}
139
140
	virtual void OnChar()
141
	{
142
143
		qDebug()<<"keeeey";
144
	}
145
146
};
147
vtkStandardNewMacro(KeyPressInteractorStyle);
148
149
class MouseInteractorStyleDoubleClick : public vtkInteractorStyleTrackballCamera
150
{
151
public:
152
153
	static MouseInteractorStyleDoubleClick* New();
154
	vtkTypeMacro(MouseInteractorStyleDoubleClick, vtkInteractorStyleTrackballCamera);
155
156
	MouseInteractorStyleDoubleClick() : NumberOfClicks(0), ResetPixelDistance(5) 
157
	{ 
158
		this->PreviousPosition[0] = 0;
159
		this->PreviousPosition[1] = 0;
160
	}
161
162
	virtual void OnLeftButtonDown() 
163
	{
164
		//std::cout << "Pressed left mouse button." << std::endl;
165
		this->NumberOfClicks++;
166
		//std::cout << "NumberOfClicks = " << this->NumberOfClicks << std::endl;
167
		int pickPosition[2];
168
		this->GetInteractor()->GetEventPosition(pickPosition);
169
170
		int xdist = pickPosition[0] - this->PreviousPosition[0];
171
		int ydist = pickPosition[1] - this->PreviousPosition[1];
172
173
		this->PreviousPosition[0] = pickPosition[0];
174
		this->PreviousPosition[1] = pickPosition[1];
175
176
		int moveDistance = (int)sqrt((double)(xdist*xdist + ydist*ydist));
177
178
		// Reset numClicks - If mouse moved further than resetPixelDistance
179
		if(moveDistance > this->ResetPixelDistance)
180
		{ 
181
			this->NumberOfClicks = 1;
182
		}
183
184
185
		if(this->NumberOfClicks == 2)
186
		{
187
			std::cout << "Double clicked." << std::endl;
188
			this->NumberOfClicks = 0;
189
		}
190
		// forward events
191
		vtkInteractorStyleTrackballCamera::OnLeftButtonDown();
192
	}
193
194
private:
195
	unsigned int NumberOfClicks;
196
	int PreviousPosition[2];
197
	int ResetPixelDistance;
198
};
199
vtkStandardNewMacro(MouseInteractorStyleDoubleClick);
200
201
202
//----------------------------------------------------------------------------
203
class vtkResliceCursorCallback : public vtkCommand
204
{
205
public:
206
207
	static vtkResliceCursorCallback *New()
208
	{ 
209
		return new vtkResliceCursorCallback; }
210
211
	void Execute( vtkObject *caller, unsigned long ev,
212
		void *callData )
213
	{
214
215
		if (ev == vtkCommand::KeyPressEvent)
216
		{
217
			QKeyEvent* keyPressed = static_cast<QKeyEvent*>(callData);
218
			
219
			qDebug()<<"key pressed: "<<keyPressed->text();
220
		}
221
222
		if (ev == vtkResliceCursorWidget::WindowLevelEvent ||
223
			ev == vtkCommand::WindowLevelEvent ||
224
			ev == vtkResliceCursorWidget::ResliceThicknessChangedEvent||
225
			ev == vtkResliceCursorWidget::ResliceAxesChangedEvent||
226
			ev == vtkResliceCursorWidget::ResetCursorEvent)
227
		{
228
			//do nothing
229
		}
230
231
		vtkImagePlaneWidget* ipw =
232
			dynamic_cast< vtkImagePlaneWidget* >( caller );
233
		if (ipw)
234
		{
235
			double* wl = static_cast<double*>( callData );
236
237
			if ( ipw == this->IPW[0] )
238
			{
239
240
				this->IPW[1]->SetWindowLevel(wl[0],wl[1],1);
241
				this->IPW[2]->SetWindowLevel(wl[0],wl[1],1);
242
243
			}
244
			else if( ipw == this->IPW[1] )
245
			{
246
				this->IPW[0]->SetWindowLevel(wl[0],wl[1],1);
247
				this->IPW[2]->SetWindowLevel(wl[0],wl[1],1);
248
			}
249
			else if (ipw == this->IPW[2])
250
			{
251
				this->IPW[0]->SetWindowLevel(wl[0],wl[1],1);
252
				this->IPW[1]->SetWindowLevel(wl[0],wl[1],1);
253
			}
254
		}
255
256
		vtkResliceCursorWidget *rcw = dynamic_cast<
257
			vtkResliceCursorWidget * >(caller);
258
		if (rcw)
259
		{
260
			vtkResliceCursorLineRepresentation *rep = dynamic_cast<
261
				vtkResliceCursorLineRepresentation * >(rcw->GetRepresentation());
262
			// Although the return value is not used, we keep the get calls
263
			// in case they had side-effects
264-
	vtkSmartPointer<KeyPressInteractorStyle> style = vtkSmartPointer<KeyPressInteractorStyle>::New();
264+
265
			for (int i = 0; i < 3; i++)
266-
	this->ui->view1->GetInteractor()->SetInteractorStyle(style);
266+
267-
	//this->ui->view1->GetRenderWindow()->GetInteractor()->SetInteractorStyle(style);
267+
268-
	//this->ui->view1->GetRenderWindow()->AddRenderer(riw[0]->GetRenderer());
268+
269-
	style->SetCurrentRenderer(riw[0]->GetRenderer());
269+
270
					GetPlaneSource()->GetOrigin());
271
				ps->SetPoint1(this->RCW[i]->GetResliceCursorRepresentation()->
272-
	riw[0]->SetupInteractor(
272+
273-
		this->ui->view1->GetRenderWindow()->GetInteractor());
273+
274-
	
274+
275-
	this->ui->view2->SetRenderWindow(riw[1]->GetRenderWindow());
275+
276-
	riw[1]->SetupInteractor(
276+
277-
		this->ui->view2->GetRenderWindow()->GetInteractor());
277+
278
			}
279
		}
280-
	riw[2]->SetupInteractor(
280+
281-
		this->ui->view3->GetRenderWindow()->GetInteractor());
281+
282
		{
283
			for (int i = 0; i < 3; i++)
284
			{
285
				vtkPlaneSource *ps = static_cast< vtkPlaneSource * >(
286
					this->IPW[i]->GetPolyDataAlgorithm());
287
				ps->SetOrigin(this->RCW[i]->GetResliceCursorRepresentation()->
288
					GetPlaneSource()->GetOrigin());
289
				ps->SetPoint1(this->RCW[i]->GetResliceCursorRepresentation()->
290
					GetPlaneSource()->GetPoint1());
291
				ps->SetPoint2(this->RCW[i]->GetResliceCursorRepresentation()->
292
					GetPlaneSource()->GetPoint2());
293
294
				// If the reslice plane has modified, update it on the 3D widget
295
				this->IPW[i]->UpdatePlacement();
296
			}
297
		}
298
299
		// Render everything
300
		for (int i = 0; i < 3; i++)
301
		{
302
			this->RCW[i]->Render();
303
		}
304
		this->IPW[0]->GetInteractor()->GetRenderWindow()->Render();
305
	}
306
307
	vtkResliceCursorCallback() {}
308
	vtkImagePlaneWidget* IPW[3];
309
	vtkResliceCursorWidget *RCW[3];
310
};
311
312
313
QtVTKRenderWindows::QtVTKRenderWindows( int vtkNotUsed(argc), char *argv[])
314
{
315
	this->ui = new Ui_QtVTKRenderWindows;
316
	this->ui->setupUi(this);
317
318
	vtkSmartPointer< vtkDICOMImageReader > reader =
319
		vtkSmartPointer< vtkDICOMImageReader >::New();
320
	//reader->SetDirectoryName(argv[1]);
321
	reader->SetDirectoryName("C:/Users/Panayiotis/DentalCEsse/qt_interface/build/Release/temp_dental/2/dicom");
322
	reader->Update();
323
	int imageDims[3];
324
	reader->GetOutput()->GetDimensions(imageDims);
325
326
327
	for (int i = 0; i < 3; i++)
328
	{
329
		riw[i] = vtkSmartPointer< vtkResliceImageViewer >::New();
330
	}
331
332
	vtkSmartPointer<myRenderWindowInteractor> myInteractor1 = vtkSmartPointer<myRenderWindowInteractor>::New();
333
	vtkSmartPointer<myRenderWindowInteractor> myInteractor2 = vtkSmartPointer<myRenderWindowInteractor>::New();
334
	vtkSmartPointer<myRenderWindowInteractor> myInteractor3 = vtkSmartPointer<myRenderWindowInteractor>::New();
335
336
	this->ui->view1->SetRenderWindow(riw[0]->GetRenderWindow());
337
	this->ui->view2->SetRenderWindow(riw[1]->GetRenderWindow());	
338
	this->ui->view3->SetRenderWindow(riw[2]->GetRenderWindow());
339
340
	riw[2]->SetupInteractor(this->ui->view3->GetRenderWindow()->GetInteractor());
341
	riw[1]->SetupInteractor(this->ui->view2->GetRenderWindow()->GetInteractor());
342
	riw[0]->SetupInteractor(this->ui->view1->GetRenderWindow()->GetInteractor());
343
344
	myInteractor1->SetRenderWindow(this->ui->view1->GetRenderWindow());
345
	myInteractor2->SetRenderWindow(this->ui->view2->GetRenderWindow());
346
	myInteractor3->SetRenderWindow(this->ui->view3->GetRenderWindow());
347
348
	for (int i = 0; i < 3; i++)
349
	{
350
		// make them all share the same reslice cursor object.
351
		vtkResliceCursorLineRepresentation *rep =
352
			vtkResliceCursorLineRepresentation::SafeDownCast(
353
			riw[i]->GetResliceCursorWidget()->GetRepresentation());
354
		riw[i]->SetResliceCursor(riw[0]->GetResliceCursor());
355
356
		rep->GetResliceCursorActor()->
357
			GetCursorAlgorithm()->SetReslicePlaneNormal(i);
358
359
		riw[i]->SetInput(reader->GetOutput());
360
		riw[i]->SetSliceOrientation(i);
361
		riw[i]->SetResliceModeToAxisAligned();
362
	}
363
364
	vtkSmartPointer<vtkCellPicker> picker =
365
		vtkSmartPointer<vtkCellPicker>::New();
366
	picker->SetTolerance(0.005);
367
368
	vtkSmartPointer<vtkProperty> ipwProp =
369
		vtkSmartPointer<vtkProperty>::New();
370
371
	vtkSmartPointer< vtkRenderer > ren =
372
		vtkSmartPointer< vtkRenderer >::New();
373
374
375
376
	this->ui->view4->GetRenderWindow()->AddRenderer(ren);
377
	vtkRenderWindowInteractor *iren = this->ui->view4->GetInteractor();
378
	//commenting out the following code succesfully applies the 
379
	//'style' to view4
380
	//iren->SetInteractorStyle(style);
381
	//style->SetCurrentRenderer(ren);
382
383
384
	//vtkSmartPointer<MouseInteractorStyleDoubleClick> style2 =   vtkSmartPointer<MouseInteractorStyleDoubleClick>::New();
385
	//this->ui->view4->GetRenderWindow()->GetInteractor()->SetInteractorStyle( style2 );
386
387
	for (int i = 0; i < 3; i++)
388
	{
389
		planeWidget[i] = vtkSmartPointer<vtkImagePlaneWidget>::New();
390
		planeWidget[i]->SetInteractor( iren );
391
		planeWidget[i]->SetPicker(picker);
392
		planeWidget[i]->RestrictPlaneToVolumeOn();
393
		double color[3] = {0, 0, 0};
394
		color[i] = 1;
395
		planeWidget[i]->GetPlaneProperty()->SetColor(color);
396
397
		color[i] = 0.25;
398
		riw[i]->GetRenderer()->SetBackground( color );
399
400
		planeWidget[i]->SetTexturePlaneProperty(ipwProp);
401
		planeWidget[i]->TextureInterpolateOff();
402
		planeWidget[i]->SetResliceInterpolateToCubic();
403
		planeWidget[i]->SetInput(reader->GetOutput());
404
		planeWidget[i]->SetPlaneOrientation(i);
405
		planeWidget[i]->SetSliceIndex(imageDims[i]/2);
406
		planeWidget[i]->DisplayTextOn();
407
		planeWidget[i]->SetDefaultRenderer(ren);
408
		planeWidget[i]->On();
409
		planeWidget[i]->InteractionOn();
410
		planeWidget[i]->SetTextureVisibility(0);
411
	}
412
413
	vtkSmartPointer<vtkResliceCursorCallback> cbk =
414
		vtkSmartPointer<vtkResliceCursorCallback>::New();
415
416
	for (int i = 0; i < 3; i++)
417
	{
418
		cbk->IPW[i] = planeWidget[i];
419
		cbk->RCW[i] = riw[i]->GetResliceCursorWidget();
420
		riw[i]->GetResliceCursorWidget()->AddObserver(
421
			vtkResliceCursorWidget::ResliceAxesChangedEvent, cbk );
422
423
		riw[i]->GetResliceCursorWidget()->AddObserver(
424
			vtkResliceCursorWidget::WindowLevelEvent, cbk );
425
426
		riw[i]->GetResliceCursorWidget()->AddObserver(
427
			vtkResliceCursorWidget::ResliceThicknessChangedEvent, cbk );
428
429
		riw[i]->GetResliceCursorWidget()->AddObserver(
430
			vtkResliceCursorWidget::ResetCursorEvent, cbk );
431
432
		riw[i]->GetInteractorStyle()->AddObserver(
433
			vtkCommand::WindowLevelEvent, cbk );
434
435
		riw[i]->AddObserver(vtkResliceImageViewer::SliceChangedEvent,cbk);
436
437
		// Make them all share the same color map.
438
		riw[i]->SetLookupTable(riw[0]->GetLookupTable());
439
		planeWidget[i]->GetColorMap()->SetLookupTable(riw[0]->GetLookupTable());
440
		planeWidget[i]->SetColorMap(riw[i]->GetResliceCursorWidget()->GetResliceCursorRepresentation()->GetColorMap());
441
442
	}
443
444
	//riw[0]->GetRenderWindow()->GetInteractor()->AddObserver(vtkCommand::KeyPressEvent,cbk);
445
446
	resliceMode(1);
447
	this->ui->resliceModeCheckBox->setChecked(true);
448
449
	vtkSmartPointer<KeyPressInteractorStyle> style1 = vtkSmartPointer<KeyPressInteractorStyle>::New();
450
	vtkSmartPointer<KeyPressInteractorStyle> style2 = vtkSmartPointer<KeyPressInteractorStyle>::New();
451
	vtkSmartPointer<KeyPressInteractorStyle> style3 = vtkSmartPointer<KeyPressInteractorStyle>::New();
452
	vtkSmartPointer<KeyPressInteractorStyle> style4 = vtkSmartPointer<KeyPressInteractorStyle>::New();
453
454
	this->ui->view1->GetRenderWindow()->GetInteractor()->SetInteractorStyle(style1);
455
	this->ui->view2->GetRenderWindow()->GetInteractor()->SetInteractorStyle(style2);
456
	this->ui->view3->GetRenderWindow()->GetInteractor()->SetInteractorStyle(style3);
457
	//this->ui->view4->GetRenderWindow()->GetInteractor()->SetInteractorStyle(style4);  //don't need it on 4th view
458
459
	this->ui->view1->show();
460
	this->ui->view2->show();
461
	this->ui->view3->show();
462
463
	// Set up action signals and slots
464
	this->ui->thickModeCheckBox->setEnabled(0);
465
	this->ui->resliceModeCheckBox->setEnabled(0);
466
467
	this->ui->blendModeGroupBox->setEnabled(0);
468
	this->ui->resetButton->setEnabled(0);
469
	this->ui->AddDistance1Button->setEnabled(0);
470
};
471
472
void QtVTKRenderWindows::resliceMode(int mode)
473
{
474
	for (int i = 0; i < 3; i++)
475
	{
476
		riw[i]->SetResliceMode(mode ? 1 : 0);
477
		riw[i]->GetRenderer()->ResetCamera();
478
		riw[i]->Render();
479
	}
480
}
481
482
void QtVTKRenderWindows::Render()
483
{
484
	for (int i = 0; i < 3; i++)
485
	{
486
		riw[i]->Render();
487
	}
488
	this->ui->view3->GetRenderWindow()->Render();
489
}
490
491
//==================================
492
//QtVTKRenderWindowsApp.cxx
493
//==================================
494
495
#include <QApplication>
496
#include "QtVTKRenderWindows.h"
497
 
498
int main( int argc, char** argv )
499
{
500
  // QT Stuff
501
  QApplication app( argc, argv );
502
 
503
  QtVTKRenderWindows myQtVTKRenderWindows(argc, argv);
504
  myQtVTKRenderWindows.show();
505
 
506
  return app.exec();
507
}