UsTK : Ultrasound ToolKit  version 2.0.1 under development (2023-12-07)
us3DSceneSlicing.cpp
1 /****************************************************************************
2  *
3  * This file is part of the ustk software.
4  * Copyright (C) 2016 - 2017 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * ("GPL") version 2 as published by the Free Software Foundation.
9  * See the file LICENSE.txt at the root directory of this source
10  * distribution for additional information about the GNU GPL.
11  *
12  * For using ustk with software that can not be combined with the GNU
13  * GPL, please contact Inria about acquiring a ViSP Professional
14  * Edition License.
15  *
16  * This software was developed at:
17  * Inria Rennes - Bretagne Atlantique
18  * Campus Universitaire de Beaulieu
19  * 35042 Rennes Cedex
20  * France
21  *
22  * If you have questions regarding the use of this file, please contact
23  * Inria at ustk@inria.fr
24  *
25  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
26  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27  *
28  * Authors:
29  * Marc Pouliquen
30  *
31  *****************************************************************************/
32 
38 #include <visp3/ustk_core/usImagePostScan3D.h>
39 #include <visp3/ustk_gui/us3DSceneSlicing.h>
40 #include <visp3/ustk_gui/usVTKConverter.h>
41 
42 #ifdef USTK_HAVE_VTK_QT
43 
44 #include <vtkAbstractTransform.h>
45 #include <vtkActor.h>
46 #include <vtkActor2D.h>
47 #include <vtkBoundedPlanePointPlacer.h>
48 #include <vtkCamera.h>
49 #include <vtkCellPicker.h>
50 #include <vtkCommand.h>
51 #include <vtkDistanceRepresentation.h>
52 #include <vtkDistanceRepresentation2D.h>
53 #include <vtkDistanceWidget.h>
54 #include <vtkHandleRepresentation.h>
55 #include <vtkImageActor.h>
56 #include <vtkImageData.h>
57 #include <vtkImageMapToWindowLevelColors.h>
58 #include <vtkImageSlabReslice.h>
59 #include <vtkInteractorStyleImage.h>
60 #include <vtkLookupTable.h>
61 #include <vtkMapper.h>
62 #include <vtkMatrix4x4.h>
63 #include <vtkMetaImageReader.h>
64 #include <vtkPlane.h>
65 #include <vtkPlaneSource.h>
66 #include <vtkPointHandleRepresentation2D.h>
67 #include <vtkPointHandleRepresentation3D.h>
68 #include <vtkProperty.h>
69 #include <vtkRenderWindow.h>
70 #include <vtkRenderer.h>
71 #include <vtkRendererCollection.h>
72 #include <vtkResliceCursor.h>
73 #include <vtkResliceCursorActor.h>
74 #include <vtkResliceCursorLineRepresentation.h>
75 #include <vtkResliceCursorPolyDataAlgorithm.h>
76 #include <vtkResliceCursorThickLineRepresentation.h>
77 #include <vtkResliceCursorWidget.h>
78 #include <vtkResliceImageViewer.h>
79 #include <vtkResliceImageViewerMeasurements.h>
80 
81 #include <vtkHomogeneousTransform.h>
82 
83 #include <QDesktopWidget>
84 #include <QResizeEvent>
85 
90 us3DSceneSlicing::us3DSceneSlicing(std::string imageFileName)
91 {
92  this->setupUi();
93  usImageIo::read(postScanImage, imageFileName);
94  usVTKConverter::convert(postScanImage, vtkImage);
95 
96  int imageDims[3];
97  double spacing[3];
98  vtkImage->GetDimensions(imageDims);
99  vtkImage->GetSpacing(spacing);
100 
101  plane1 = vtkPlane::New();
102  plane1->SetOrigin(imageDims[0] * spacing[0] / 2, 0, 0);
103  plane1->SetNormal(1, 0, 0);
104 
105  plane2 = vtkPlane::New();
106  plane2->SetNormal(0, 1, 0);
107  plane2->SetOrigin(0, imageDims[1] * spacing[1] / 2, 0);
108 
109  plane3 = vtkPlane::New();
110  plane3->SetNormal(0, 0, 1);
111  plane3->SetOrigin(0, 0, imageDims[2] * spacing[2] / 2);
112 
113  this->view->setImageData(vtkImage);
114  this->view->setPlanes(plane1, plane2, plane3);
115  this->view->init();
116 
117  sliderXplane1->setMaximum(imageDims[0] * spacing[0] * 1000);
118  sliderXplane1->setSliderPosition(imageDims[0] * spacing[0] * 1000 / 2);
119  sliderYplane1->setMaximum(imageDims[1] * spacing[1] * 1000);
120  sliderYplane1->setSliderPosition(imageDims[1] * spacing[1] * 1000 / 2);
121  sliderZplane1->setMaximum(imageDims[2] * spacing[2] * 1000);
122  sliderZplane1->setSliderPosition(imageDims[2] * spacing[2] * 1000 / 2);
123 
124  // Set up action signals and slots
125  connect(this->sliderXplane1, SIGNAL(valueChanged(int)), this, SLOT(updateX(int)));
126  connect(this->sliderYplane1, SIGNAL(valueChanged(int)), this, SLOT(updateY(int)));
127  connect(this->sliderZplane1, SIGNAL(valueChanged(int)), this, SLOT(updateZ(int)));
128 
129  connect(this->rotXplane1, SIGNAL(valueChanged(int)), this, SLOT(updateRotX(int)));
130  connect(this->rotYplane1, SIGNAL(valueChanged(int)), this, SLOT(updateRotY(int)));
131  connect(this->rotZplane1, SIGNAL(valueChanged(int)), this, SLOT(updateRotZ(int)));
132 
133  ResetViews();
134 }
135 
139 void us3DSceneSlicing::slotExit() { qApp->exit(); }
140 
145 
150 {
151 #if USTK_HAVE_VTK_VERSION < 0x090000
152  this->view->GetRenderWindow()->Render();
153 #else
154  this->view->renderWindow()->Render();
155 #endif
156 
157  this->view->update();
158 }
159 
163 void us3DSceneSlicing::setupUi()
164 {
165  this->setMinimumSize(640, 480);
166  QRect screenRect = QApplication::desktop()->screenGeometry();
167  this->resize(screenRect.size());
168 
169  gridLayoutWidget = new QWidget(this);
170  gridLayoutWidget->setObjectName(QString::fromUtf8("gridLayoutWidget"));
171  gridLayoutWidget->setGeometry(QRect(10, 10, screenRect.width() - 200, screenRect.height() - 40));
172  gridLayout_2 = new QGridLayout(gridLayoutWidget);
173  gridLayout_2->setObjectName(QString::fromUtf8("gridLayout_2"));
174  gridLayout_2->setContentsMargins(0, 0, 0, 0);
175  view = new us3DSceneWidget(gridLayoutWidget);
176  view->setObjectName(QString::fromUtf8("view"));
177 
178  gridLayout_2->addWidget(view, 0, 0, 1, 1);
179 
180  sliderXplane1 = new QSlider(this);
181  sliderXplane1->setObjectName(QString::fromUtf8("sliderX"));
182  sliderXplane1->setMinimum(0);
183  sliderXplane1->setMaximum(100);
184  sliderXplane1->setGeometry(QRect(screenRect.width() - 180, 30, 20, 200));
185 
186  sliderYplane1 = new QSlider(this);
187  sliderYplane1->setObjectName(QString::fromUtf8("sliderY"));
188  sliderYplane1->setMinimum(0);
189  sliderYplane1->setMaximum(100);
190  sliderYplane1->setGeometry(QRect(screenRect.width() - 140, 30, 20, 200));
191 
192  sliderZplane1 = new QSlider(this);
193  sliderZplane1->setObjectName(QString::fromUtf8("sliderZ"));
194  sliderZplane1->setMinimum(0);
195  sliderZplane1->setMaximum(100);
196  sliderZplane1->setGeometry(QRect(screenRect.width() - 100, 30, 20, 200));
197 
198  rotXplane1 = new QSlider(this);
199  rotXplane1->setObjectName(QString::fromUtf8("rotX"));
200  rotXplane1->setMinimum(0);
201  rotXplane1->setMaximum(100);
202  rotXplane1->setGeometry(QRect(screenRect.width() - 180, 250, 20, 200));
203 
204  rotYplane1 = new QSlider(this);
205  rotYplane1->setObjectName(QString::fromUtf8("rotY"));
206  rotYplane1->setMinimum(0);
207  rotYplane1->setMaximum(100);
208  rotYplane1->setGeometry(QRect(screenRect.width() - 140, 250, 20, 200));
209 
210  rotZplane1 = new QSlider(this);
211  rotZplane1->setObjectName(QString::fromUtf8("rotZ"));
212  rotZplane1->setMinimum(0);
213  rotZplane1->setMaximum(100);
214  rotZplane1->setGeometry(QRect(screenRect.width() - 100, 250, 20, 200));
215 }
216 
220 void us3DSceneSlicing::resizeEvent(QResizeEvent *event)
221 {
222  // Min size : 640*480
223  if (event->size().width() >= 640 && event->size().height() >= 480) {
224  QMainWindow::resizeEvent(event);
225  gridLayoutWidget->setGeometry(QRect(10, 10, event->size().width() - 220, event->size().height() - 20));
226  sliderXplane1->setGeometry(QRect(event->size().width() - 180, 30, 20, 200));
227  sliderYplane1->setGeometry(QRect(event->size().width() - 140, 30, 20, 200));
228  sliderZplane1->setGeometry(QRect(event->size().width() - 100, 30, 20, 200));
229  rotXplane1->setGeometry(QRect(event->size().width() - 180, 250, 20, 200));
230  rotYplane1->setGeometry(QRect(event->size().width() - 140, 250, 20, 200));
231  rotZplane1->setGeometry(QRect(event->size().width() - 100, 250, 20, 200));
232  }
233 }
234 
239 {
240  double origin[3];
241  plane1->GetOrigin(origin);
242  origin[0] = x / 1000.0;
243  plane1->SetOrigin(origin);
244  view->update();
245 }
246 
251 {
252  double origin[3];
253  plane1->GetOrigin(origin);
254  origin[1] = y / 1000.0;
255  plane1->SetOrigin(origin);
256  view->update();
257 }
258 
263 {
264  double origin[3];
265  plane1->GetOrigin(origin);
266  origin[2] = z / 1000.0;
267  plane1->SetOrigin(origin);
268  view->update();
269 }
270 
275 {
276  double normal[3];
277  plane1->GetNormal(normal);
278  normal[0] = x / 100.0 - 0.5;
279  plane1->SetNormal(normal);
280  view->update();
281 }
282 
287 {
288  double normal[3];
289  plane1->GetNormal(normal);
290  normal[1] = y / 100.0 - 0.50;
291  plane1->SetNormal(normal);
292  view->update();
293 }
294 
299 {
300  double normal[3];
301  plane1->GetNormal(normal);
302  normal[2] = z / 100.0 - 0.50;
303  plane1->SetNormal(normal);
304  double origin[3];
305  plane1->GetOrigin(origin);
306  view->update();
307 }
308 
309 #endif
virtual void Render()
void updateRotX(int rx)
void resizeEvent(QResizeEvent *event)
void updateRotZ(int rz)
us3DSceneSlicing(std::string imageFileName)
virtual void slotExit()
void updateRotY(int ry)
virtual void ResetViews()
Class used to render a 3D vtk scene containing a vtkImageData in a QWidget (based on QVTKWidget).
void setPlanes(vtkPlane *plane1, vtkPlane *plane2, vtkPlane *plane3)
void setImageData(vtkImageData *imageData)
static void read(usImageRF2D< short int > &imageRf2D, const std::string &headerFileName)
Definition: usImageIo.cpp:153
static void convert(const usImagePostScan3D< unsigned char > &postScanImage, vtkSmartPointer< vtkImageData > &vtkPostScanImage, vtkSmartPointer< vtkImageImport > importer=NULL)