UsTK : Ultrasound ToolKit  version 2.0.1 under development (2024-05-17)
usVirtualNeedle.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 "usVirtualNeedle.h"
39 
40 #ifdef USTK_HAVE_VTK_QT
41 
45 usVirtualNeedle::usVirtualNeedle(QWidget *parent, Qt::WindowFlags f) : usViewerWidget(parent, f)
46 {
47  // POLYDATA
48  m_meshPolyData = vtkPolyData::New();
49  // Create a cylinder for the needle
50  vtkSmartPointer<vtkCylinderSource> cylinderSource = vtkSmartPointer<vtkCylinderSource>::New();
51  cylinderSource->SetCenter(0, 0, 0);
52  cylinderSource->SetRadius(0.0001);
53  cylinderSource->SetHeight(0.01);
54  cylinderSource->SetResolution(100);
55  cylinderSource->Update();
56  m_meshNeedle = cylinderSource->GetOutput();
57 
58  // MAPPERS - ACTORS
59  vtkSmartPointer<vtkPolyDataMapper> cylinderMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
60  cylinderMapper->SetInputConnection(cylinderSource->GetOutputPort());
61  m_needleActor = vtkSmartPointer<vtkActor>::New();
62  m_needleActor->GetProperty()->SetColor(1.0, 0, 0); // red
63  m_needleActor->GetProperty()->SetOpacity(1.0);
64  m_needleActor->SetMapper(cylinderMapper);
65 
66  // Axes
67  m_axesActor = vtkSmartPointer<vtkAxesActor>::New();
68 
69  // arrows of 1cm
70  m_axesActor->SetXAxisLabelText("X");
71  m_axesActor->SetYAxisLabelText("Y");
72  m_axesActor->SetZAxisLabelText("Z");
73  m_axesActor->SetTotalLength(0.01, 0.01, 0.01); // 10cm each
74 
75  // Setup renderer
76  renderer = vtkRenderer::New();
77  renderer->AddActor(m_axesActor);
78  renderer->AddActor(m_needleActor);
79  renderer->SetBackground(0.5, 0.5, 0.5);
80  renderer->ResetCamera();
81 
82  // Setup render window
83 #if USTK_HAVE_VTK_VERSION < 0x090000
84  vtkRenderWindow *renderWindow = this->GetRenderWindow();
85 #else
86  vtkRenderWindow *renderWindow = this->renderWindow();
87 #endif
88  renderWindow->AddRenderer(renderer);
89 }
90 /*
91 usVirtualNeedle::~usVirtualNeedle()
92 {
93 
94 }*/
95 
100 void usVirtualNeedle::paintEvent(QPaintEvent *event) { usViewerWidget::paintEvent(event); }
101 
106 void usVirtualNeedle::keyPressEvent(QKeyEvent *event)
107 {
108  if (event->key() == Qt::Key_Left) {
109  vpHomogeneousMatrix transform;
110  transform.eye();
111  transform[0][3] = 0.001; // add 1mm on X axis
112  updateNeedlePosition(transform);
113  } else if (event->key() == Qt::Key_Right) {
114  vpHomogeneousMatrix transform;
115  transform.eye();
116  transform[0][3] = -0.001; // minus 1mm on X axis
117  updateNeedlePosition(transform);
118  } else if (event->key() == Qt::Key_Up) {
119  vpHomogeneousMatrix transform;
120  transform.eye();
121  transform[1][3] = 0.001; // add 1mm on Y axis
122  updateNeedlePosition(transform);
123  } else if (event->key() == Qt::Key_Down) {
124  vpHomogeneousMatrix transform;
125  transform.eye();
126  transform[1][3] = -0.001; // remove 1mm on Y axis
127  updateNeedlePosition(transform);
128  } else if (event->key() == Qt::Key_PageUp) {
129  vpHomogeneousMatrix transform;
130  transform.eye();
131  transform[2][3] = 0.001; // remove 1mm on Z axis
132  updateNeedlePosition(transform);
133  } else if (event->key() == Qt::Key_PageDown) {
134  vpHomogeneousMatrix transform;
135  transform.eye();
136  transform[2][3] = -0.001; // remove 1mm on Z axis
137  updateNeedlePosition(transform);
138  } else if (event->key() == Qt::Key_Space) { // move first point of the mesh of 1mm along Z
139  double *point1 = m_meshPolyData->GetPoints()->GetPoint(0);
140  point1[2] += 0.001;
141  m_meshPolyData->GetPoints()->SetPoint(0, point1);
142  m_meshPolyData->GetPoints()->Modified();
143 #if USTK_HAVE_VTK_VERSION < 0x090000
144  this->GetRenderWindow()->Render();
145 #else
146  this->renderWindow()->Render();
147 #endif
148  } else if (event->key() == Qt::Key_0) { // move first point of the mesh of - 1mm along Z
149  double *point1 = m_meshPolyData->GetPoints()->GetPoint(0);
150  point1[2] -= 0.001;
151  m_meshPolyData->GetPoints()->SetPoint(0, point1);
152  m_meshPolyData->GetPoints()->Modified();
153 #if USTK_HAVE_VTK_VERSION < 0x090000
154  this->GetRenderWindow()->Render();
155 #else
156  this->renderWindow()->Render();
157 #endif
158  } else {
159  usViewerWidget::keyPressEvent(event);
160  }
161 }
162 
167 void usVirtualNeedle::setMeshInScene(vtkPolyData *mesh)
168 {
169  m_meshPolyData = mesh;
170 
171  vtkSmartPointer<vtkPolyDataMapper> meshMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
172  meshMapper->SetInputData(mesh);
173  m_meshActor = vtkSmartPointer<vtkActor>::New();
174  m_meshActor->GetProperty()->SetColor(0, 0, 1.0); // blue
175  m_meshActor->SetMapper(meshMapper);
176 
177  renderer->AddActor(m_meshActor);
178 }
179 
185 void usVirtualNeedle::updateNeedlePosition(vpHomogeneousMatrix transform)
186 {
187 
188  if (m_needleActor->GetUserMatrix() == NULL) { // init case
189  vtkSmartPointer<vtkMatrix4x4> vtkMatrix = vtkSmartPointer<vtkMatrix4x4>::New();
190  usVTKConverter::convert(transform, vtkMatrix);
191  m_needleActor->SetUserMatrix(vtkMatrix);
192  } else {
193  // get current matrix
194  vpHomogeneousMatrix currentTransform;
195  currentTransform.eye();
196  usVTKConverter::convert(m_needleActor->GetUserMatrix(), currentTransform);
197 
198  // Conversion, taking in account current transform of the needle
199  vpHomogeneousMatrix newTransform = currentTransform * transform;
200 
201  // set new position
202  vtkMatrix4x4 *vtkNewtransform = vtkMatrix4x4::New();
203  usVTKConverter::convert(newTransform, vtkNewtransform);
204 
205  m_needleActor->SetUserMatrix(vtkNewtransform);
206 #if USTK_HAVE_VTK_VERSION < 0x090000
207  this->GetRenderWindow()->Render();
208 #else
209  this->renderWindow()->Render();
210 #endif
211  }
212 }
213 
219 vtkPoints *usVirtualNeedle::getMeshPoints() { return m_meshPolyData->GetPoints(); }
220 
225 {
226 #if USTK_HAVE_VTK_VERSION < 0x090000
227  this->GetRenderWindow()->Render();
228 #else
229  this->renderWindow()->Render();
230 #endif
231 }
232 
233 #endif
static void convert(const usImagePostScan3D< unsigned char > &postScanImage, vtkSmartPointer< vtkImageData > &vtkPostScanImage, vtkSmartPointer< vtkImageImport > importer=NULL)
View used to render a vtk scene in a QWidget (based on QVTKWidget for Qt4, QVTKOpenGLWidget for Qt5)
void paintEvent(QPaintEvent *event)
usVirtualNeedle(QWidget *parent=NULL, Qt::WindowFlags f=Qt::WindowFlags())
vtkPoints * getMeshPoints()
void setMeshInScene(vtkPolyData *mesh)
void paintEvent(QPaintEvent *event)
void keyPressEvent(QKeyEvent *event)
void updateNeedlePosition(vpHomogeneousMatrix transform)