Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
QmitkToFPointSetWidget.cpp
Go to the documentation of this file.
1 /*===================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 
17 #include "QmitkToFPointSetWidget.h"
18 
19 #include <mitkVtkLayerController.h>
20 
21 #include <vtkTextProperty.h>
22 
23 
24 const std::string QmitkToFPointSetWidget::VIEW_ID = "org.mitk.views.qmitktofpointsetwidget";
25 
26 QmitkToFPointSetWidget::QmitkToFPointSetWidget(QWidget* parent, Qt::WindowFlags f): QWidget(parent, f)
27 , m_DataStorage(NULL)
28 , m_DistanceImage(NULL)
29 , m_CameraIntrinsics(NULL)
30 , m_VtkTextActor(NULL)
31 , m_ForegroundRenderer1(NULL)
32 , m_ForegroundRenderer2(NULL)
33 , m_ForegroundRenderer3(NULL)
34 , m_RenderWindow1(NULL)
35 , m_RenderWindow2(NULL)
36 , m_RenderWindow3(NULL)
37 , m_MeasurementPointSet2D(NULL)
38 , m_MeasurementPointSet3DNode(NULL)
39 , m_PointSet2D(NULL)
40 , m_PointSet3DNode(NULL)
41 , m_PointSetInteractor(NULL)
42 , m_MeasurementPointSetInteractor(NULL)
43 , m_MeasurementPointSetChangedObserverTag(0)
44 , m_PointSetChangedObserverTag(0)
45 , m_WindowHeight(0)
46 {
47  m_Controls = NULL;
48  CreateQtPartControl(this);
49 }
50 
52 {
53  this->CleanUpWidget();
54 }
55 
57 {
58  if (!m_Controls)
59  {
60  // create GUI widgets
61  m_Controls = new Ui::QmitkToFPointSetWidgetControls;
62  m_Controls->setupUi(parent);
63 
64  this->CreateConnections();
65  }
66 }
67 
69 {
70  if ( m_Controls )
71  {
72  connect( (QObject*)(m_Controls->measureButton), SIGNAL(clicked()),(QObject*) this, SLOT(OnMeasurement()) );
73  connect( (QObject*)(m_Controls->pointSetButton), SIGNAL(clicked()),(QObject*) this, SLOT(OnPointSet()) );
74  }
75 }
76 
77 void QmitkToFPointSetWidget::InitializeWidget(QHash<QString, QmitkRenderWindow*> renderWindowHashMap, mitk::DataStorage::Pointer dataStorage, mitk::CameraIntrinsics::Pointer cameraIntrinsics)
78 {
79  // initialize members
80  m_CameraIntrinsics = cameraIntrinsics;
81  m_DataStorage = dataStorage;
82  // m_RenderWindowPart = renderWindowPart;
83  m_RenderWindow1 = renderWindowHashMap.value("axial")->GetRenderWindow();
84  m_RenderWindow2 = renderWindowHashMap.value("sagittal")->GetRenderWindow();
85  m_RenderWindow3 = renderWindowHashMap.value("coronal")->GetRenderWindow();
86  m_RenderWindow4 = renderWindowHashMap.value("3d")->GetRenderWindow();
87  if ((m_RenderWindow1 != NULL) && (m_RenderWindow2 != NULL) && (m_RenderWindow3 != NULL) && (m_RenderWindow4 != NULL) && (dataStorage.IsNotNull()))
88  {
89  // enable buttons
90  m_Controls->pointSetButton->setEnabled(true);
91  m_Controls->measureButton->setEnabled(true);
92  // initialize overlays
94  this->m_VtkTextActor->SetInput("Choose measurement points with SHIFT+Click");
95  m_WindowHeight = renderWindowHashMap.value("axial")->GetRenderer()->GetSizeY();
96  this->m_VtkTextActor->SetDisplayPosition(10,m_WindowHeight-30);
97  this->m_VtkTextActor->GetTextProperty()->SetFontSize(16);
98  // this->m_VtkTextActor->GetTextProperty()->SetColor(1,0,0);
99  this->m_VtkTextActor->GetTextProperty()->BoldOn();
100  this->m_VtkTextActor->SetVisibility(0);
101  if (m_ForegroundRenderer1==NULL)
102  {
104  this->m_ForegroundRenderer1->AddActor(m_VtkTextActor);
106  }
107  if (m_ForegroundRenderer2==NULL)
108  {
110  this->m_ForegroundRenderer2->AddActor(m_VtkTextActor);
112  }
113  if (m_ForegroundRenderer3==NULL)
114  {
116  this->m_ForegroundRenderer3->AddActor(m_VtkTextActor);
118  }
119  mitk::DataNode::Pointer measurementPointSet2DNode = dataStorage->GetNamedNode("Measurement PointSet 2D") ;
120  if(dataStorage->Exists(measurementPointSet2DNode))
121  {
122  dataStorage->Remove(measurementPointSet2DNode);
123  }
124  // initialize 2D measurement point set
126  measurementPointSet2DNode = mitk::DataNode::New();
127  measurementPointSet2DNode->SetName("Measurement PointSet 2D");
128  measurementPointSet2DNode->SetBoolProperty("helper object",true);
129  measurementPointSet2DNode->SetBoolProperty("show contour",true);
130  measurementPointSet2DNode->SetVisibility(false, renderWindowHashMap.value("3d")->GetRenderer());
131  measurementPointSet2DNode->SetData(m_MeasurementPointSet2D);
132  dataStorage->Add(measurementPointSet2DNode);
134  m_MeasurementPointSetInteractor->LoadStateMachine("PointSet.xml");
135  m_MeasurementPointSetInteractor->SetEventConfig("PointSetConfig.xml");
136  m_MeasurementPointSetInteractor->SetDataNode(measurementPointSet2DNode);
137  m_MeasurementPointSetInteractor->SetMaxPoints(2);
138 
139  // create observer for m_MeasurementPointSet2D
140  itk::SimpleMemberCommand<QmitkToFPointSetWidget>::Pointer measurementPointSetChangedCommand;
141  measurementPointSetChangedCommand = itk::SimpleMemberCommand<QmitkToFPointSetWidget>::New();
142  measurementPointSetChangedCommand->SetCallbackFunction(this, &QmitkToFPointSetWidget::MeasurementPointSetChanged);
143  m_MeasurementPointSetChangedObserverTag = m_MeasurementPointSet2D->AddObserver(itk::ModifiedEvent(), measurementPointSetChangedCommand);
144  // initialize 3D measurement PointSet
145  m_MeasurementPointSet3DNode = dataStorage->GetNamedNode("Measurement PointSet 3D");
146  if(dataStorage->Exists(m_MeasurementPointSet3DNode))
147  {
148  dataStorage->Remove(m_MeasurementPointSet3DNode);
149  }
151  m_MeasurementPointSet3DNode->SetName("Measurement PointSet 3D");
152  m_MeasurementPointSet3DNode->SetBoolProperty("helper object",true);
153  m_MeasurementPointSet3DNode->SetBoolProperty("show contour",true);
154  m_MeasurementPointSet3DNode->SetFloatProperty("pointsize",5.0f);
155  mitk::PointSet::Pointer measurementPointSet3D = mitk::PointSet::New();
156  m_MeasurementPointSet3DNode->SetData(measurementPointSet3D);
157  dataStorage->Add(m_MeasurementPointSet3DNode);
158 
159  // initialize PointSets
160  mitk::DataNode::Pointer pointSet2DNode = dataStorage->GetNamedNode("ToF PointSet 2D") ;
161  if(dataStorage->Exists(pointSet2DNode))
162  {
163  dataStorage->Remove(pointSet2DNode);
164  }
166  pointSet2DNode = mitk::DataNode::New();
167  pointSet2DNode->SetName("ToF PointSet 2D");
168  pointSet2DNode->SetVisibility(false, renderWindowHashMap.value("3d")->GetRenderer());
169  pointSet2DNode->SetData(m_PointSet2D);
170  dataStorage->Add(pointSet2DNode);
172  m_PointSetInteractor->LoadStateMachine("PointSet.xml");
173  m_PointSetInteractor->SetEventConfig("PointSetConfig.xml");
174  m_PointSetInteractor->SetDataNode(pointSet2DNode);
175 
176  // create observer for m_MeasurementPointSet2D
179  pointSetChangedCommand->SetCallbackFunction(this, &QmitkToFPointSetWidget::PointSetChanged);
180  m_PointSetChangedObserverTag = m_PointSet2D->AddObserver(itk::ModifiedEvent(), pointSetChangedCommand);
181  // initialize 3D point set
182  mitk::DataNode::Pointer pointSet3DNode = dataStorage->GetNamedNode("ToF PointSet 3D");
183  if(dataStorage->Exists(pointSet3DNode))
184  {
185  dataStorage->Remove(pointSet3DNode);
186  }
188  m_PointSet3DNode->SetName("ToF PointSet 3D");
189  m_PointSet3DNode->SetFloatProperty("pointsize",5.0f);
191  m_PointSet3DNode->SetData(pointSet3D);
192  dataStorage->Add(m_PointSet3DNode);
193  }
194 }
195 
197 {
198  // toggle button state
199  if (m_Controls->measureButton->isChecked())
200  {
201  m_Controls->measureButton->setChecked(false);
202  this->OnMeasurement();
203  }
204  if (m_Controls->pointSetButton->isChecked())
205  {
206  m_Controls->pointSetButton->setChecked(false);
207  this->OnPointSet();
208  }
209  // remove observer
210  if (m_MeasurementPointSet2D.IsNotNull())
211  {
213  }
214  if (m_PointSet2D.IsNotNull())
215  {
217  }
218 // if (m_DistanceImage.IsNotNull())
219 // {
220 // m_DistanceImage->RemoveObserver(m_DistanceImageChangedObserverTag);
221 // }
222  // remove foreground renderer
224  {
226  {
228  }
229  m_ForegroundRenderer1 = NULL;
230  }
232  {
234  {
236  }
237  m_ForegroundRenderer2 = NULL;
238  }
240  {
242  {
244  }
245  m_ForegroundRenderer3 = NULL;
246  }
248  {
250  }
251 }
252 
254 {
255 // // remove existing observer
256 // if (m_DistanceImage.IsNotNull())
257 // {
258 // m_DistanceImage->RemoveObserver(m_DistanceImageChangedObserverTag);
259 // }
260  m_DistanceImage = distanceImage;
261 // // create observer for m_DistanceImage
262 // itk::SimpleMemberCommand<QmitkToFPointSetWidget>::Pointer distanceImageChangedCommand;
263 // distanceImageChangedCommand = itk::SimpleMemberCommand<QmitkToFPointSetWidget>::New();
264 // distanceImageChangedCommand->SetCallbackFunction(this, &QmitkToFPointSetWidget::MeasurementPointSetChanged);
265 // m_DistanceImageChangedObserverTag = m_DistanceImage->AddObserver(itk::ModifiedEvent(), distanceImageChangedCommand);
266 }
267 
269 {
270  m_CameraIntrinsics = cameraIntrinsics;
271 }
272 
274 {
275  // always show 2D PointSet in foreground
276  mitk::DataNode::Pointer pointSetNode = m_DataStorage->GetNamedNode("Measurement PointSet 2D");
277  if (pointSetNode.IsNotNull())
278  {
279  pointSetNode->SetIntProperty("layer",100);
280  }
281  if (m_Controls->measureButton->isChecked())
282  {
283  // disable point set interaction
284  if (m_Controls->pointSetButton->isChecked())
285  {
286  m_Controls->pointSetButton->setChecked(false);
287  // remove interactor
288  m_PointSetInteractor->EnableInteraction(false);
289  }
290  // show overlays
291  m_VtkTextActor->SetVisibility(1);
292  this->m_VtkTextActor->SetInput("Choose measurement points with SHIFT+Click");
293  // enable interactor
294  m_MeasurementPointSetInteractor->EnableInteraction(true);
295  // initial update of measurement
297  }
298  else
299  {
300  // hide overlays
301  m_VtkTextActor->SetVisibility(0);
302  // disable interactor
303  m_MeasurementPointSetInteractor->EnableInteraction(false);
304  }
305 }
306 
308 {
309  // always show 2D PointSet in foreground
310  mitk::DataNode::Pointer pointSetNode = m_DataStorage->GetNamedNode("ToF PointSet 2D");
311  if (pointSetNode.IsNotNull())
312  {
313  pointSetNode->SetIntProperty("layer",100);
314  }
315  if (m_Controls->pointSetButton->isChecked())
316  {
317  // disable measurement
318  if (m_Controls->measureButton->isChecked())
319  {
320  m_Controls->measureButton->setChecked(false);
321  // remove interactor
322  m_MeasurementPointSetInteractor->EnableInteraction(false);
323  }
324  // show overlays
325  m_VtkTextActor->SetVisibility(1);
326  this->m_VtkTextActor->SetInput("Choose points with SHIFT+Click");
327  // enable interactor
328  m_PointSetInteractor->EnableInteraction(true);
329  // initial update of PointSet
330  this->PointSetChanged();
331  }
332  else
333  {
334  // hide overlays
335  m_VtkTextActor->SetVisibility(0);
336  // disable interactor
337  m_PointSetInteractor->EnableInteraction(false);
338  }
339 }
340 
342 {
343  // replace text actor
344  this->m_VtkTextActor->SetDisplayPosition(10,m_WindowHeight-30);
345  if (m_MeasurementPointSet2D->GetSize()==2)
346  {
347  // check if points are inside the image range
348  int imageSizeX = m_DistanceImage->GetDimensions()[0];
349  int imageSizeY = m_DistanceImage->GetDimensions()[1];
350  mitk::Point3D point1 = m_MeasurementPointSet2D->GetPoint(0);
351  mitk::Point3D point2 = m_MeasurementPointSet2D->GetPoint(1);
352  if ((point1[0]>=0.0f)&&(point1[0]<imageSizeX)&&(point1[1]>=0)&&(point1[1]<imageSizeY)&&
353  (point2[0]>=0.0f)&&(point2[0]<imageSizeX)&&(point2[1]>=0)&&(point2[1]<imageSizeY))
354  {
355  // create PointSet filter
357  if (m_CameraIntrinsics.IsNotNull())
358  {
359  toFDistanceImageToPointSetFilter->SetCameraIntrinsics(m_CameraIntrinsics);
360  }
361  toFDistanceImageToPointSetFilter->SetInput(m_DistanceImage);
362  toFDistanceImageToPointSetFilter->SetSubset(m_MeasurementPointSet2D);
363  toFDistanceImageToPointSetFilter->Update();
364  mitk::PointSet::Pointer measurementPointSet3D = toFDistanceImageToPointSetFilter->GetOutput();
365  m_MeasurementPointSet3DNode->SetData(measurementPointSet3D);
366 
367  // calculate distance between points
368  if (measurementPointSet3D->GetSize()==2)
369  {
370  mitk::Point3D point1 = measurementPointSet3D->GetPoint(0);
371  mitk::Point3D point2 = measurementPointSet3D->GetPoint(1);
372  float distance = point1.EuclideanDistanceTo(point2);
373  std::stringstream stream;
374  stream<<distance<<" mm";
375  this->m_VtkTextActor->SetInput(stream.str().c_str());
376  }
377  else
378  {
379  this->m_VtkTextActor->SetInput("Choose measurement points with SHIFT+Click");
380  }
381  }
382  else
383  {
384  this->m_VtkTextActor->SetInput("Measurement outside image range.");
385  }
386  }
387  else
388  {
389  // initialize 3D pointset empty
391  m_MeasurementPointSet3DNode->SetData(pointSet3D);
392  }
393 }
394 
396 {
397  if (m_DistanceImage.IsNotNull())
398  {
399  int imageSizeX = m_DistanceImage->GetDimensions()[0];
400  int imageSizeY = m_DistanceImage->GetDimensions()[1];
401  int pointSetValid = 1;
402  for (int i=0; i<m_PointSet2D->GetSize(); i++)
403  {
404  mitk::Point3D currentPoint = m_PointSet2D->GetPoint(i);
405  if ((currentPoint[0]>=0.0f)&&(currentPoint[0]<imageSizeX)&&(currentPoint[1]>=0)&&(currentPoint[1]<imageSizeY))
406  {
407  pointSetValid*=1;
408  }
409  else
410  {
411  pointSetValid*=0;
412  }
413  }
414  if (m_PointSet2D->GetSize()>0)
415  {
416  if (pointSetValid)
417  {
418  // create PointSet filter
420  if (m_CameraIntrinsics.IsNotNull())
421  {
422  toFDistanceImageToPointSetFilter->SetCameraIntrinsics(m_CameraIntrinsics);
423  }
424  toFDistanceImageToPointSetFilter->SetInput(m_DistanceImage);
425  toFDistanceImageToPointSetFilter->SetSubset(m_PointSet2D);
426  toFDistanceImageToPointSetFilter->Update();
427  mitk::PointSet::Pointer pointSet3D = toFDistanceImageToPointSetFilter->GetOutput();
428  m_PointSet3DNode->SetData(pointSet3D);
429  this->m_VtkTextActor->SetInput("Choose points with SHIFT+Click"); }
430  else
431  {
432  this->m_VtkTextActor->SetInput("Point set outside image range.");
433  }
434  }
435  else
436  {
437  // initialize 3D pointset empty
439  m_PointSet3DNode->SetData(pointSet3D);
440  }
441  }
442 }
vtkSmartPointer< vtkRenderWindow > m_RenderWindow1
vtk render window used for showing overlay in widget 1
itk::SmartPointer< Self > Pointer
vtkSmartPointer< vtkRenderWindow > m_RenderWindow3
vtk render window used for showing overlay in widget 3
void InsertForegroundRenderer(vtkSmartPointer< vtkRenderer > renderer, bool forceAbsoluteForeground)
void PointSetChanged()
function called when the 2D PointSet has changed
vtkSmartPointer< vtkRenderWindow > m_RenderWindow2
vtk render window used for showing overlay in widget 2
static const std::string VIEW_ID
static Pointer New()
mitk::PointSetDataInteractor::Pointer m_MeasurementPointSetInteractor
PointSetInteractor used for measurement.
void SetDistanceImage(mitk::Image::Pointer distanceImage)
set the image holding the distance information used for measuring
long m_PointSetChangedObserverTag
observer tag for PointSet observer
void OnMeasurement()
Activates the interactor for the measurement point set.
vtkSmartPointer< vtkRenderer > m_ForegroundRenderer3
renderer responsible for text rendering in the foreground of widget 3
mitk::DataNode::Pointer m_PointSet3DNode
DataNode holding the 3D ToF coordinates.
vtkSmartPointer< vtkRenderer > m_ForegroundRenderer1
renderer responsible for text rendering in the foreground of widget 1
mitk::Image::Pointer m_DistanceImage
image holding the range data of the ToF camera
mitk::DataNode::Pointer m_MeasurementPointSet3DNode
DataNode holding the 3D ToF coordinates used for measuring.
void SetCameraIntrinsics(mitk::CameraIntrinsics::Pointer cameraIntrinsics)
Set intrinsic parameters of the used device.
QmitkToFPointSetWidget(QWidget *p=0, Qt::WindowFlags f1=0)
virtual void CreateQtPartControl(QWidget *parent)
long m_MeasurementPointSetChangedObserverTag
observer tag for measurement PointSet observer
mitk::PointSet::Pointer m_MeasurementPointSet2D
PointSet holding the 2D ToF image point selection used for measuring.
vtkSmartPointer< vtkTextActor > m_VtkTextActor
actor containing the text of the overlay
static VtkLayerController * GetInstance(vtkSmartPointer< vtkRenderWindow > renWin)
mitk::DataStorage::Pointer m_DataStorage
void OnPointSet()
Activates the interactor for the point set.
static Pointer New()
static RenderingManager * GetInstance()
void CleanUpWidget()
cleans up the widget when it's functionality is not used anymore. Removes observers and deletes foreg...
Ui::QmitkToFPointSetWidgetControls * m_Controls
member holding the UI elements of this widget
mitk::PointSet::Pointer m_PointSet2D
PointSet holding the 2D ToF image points.
int m_WindowHeight
Height of the renderWindow.
vtkSmartPointer< vtkRenderer > m_ForegroundRenderer2
renderer responsible for text rendering in the foreground of widget 2
void InitializeWidget(QHash< QString, QmitkRenderWindow * > renderWindowHashMap, mitk::DataStorage::Pointer dataStorage, mitk::CameraIntrinsics::Pointer cameraIntrinsics=NULL)
initializes the widget. Observers to the change events of the point sets are created, text actors are activated to be rendered into the foreground of the render window.
void RemoveRenderer(vtkSmartPointer< vtkRenderer > renderer)
void MeasurementPointSetChanged()
function called when the 2D measurement PointSet has changed
vtkSmartPointer< vtkRenderWindow > m_RenderWindow4
vtk render window used for showing overlay in widget 3
mitk::DataStorage::Pointer m_DataStorage
member holding the set DataStorage
mitk::CameraIntrinsics::Pointer m_CameraIntrinsics
intrinsic parameters of the camera
void RequestUpdateAll(RequestType type=REQUEST_UPDATE_ALL)
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.
mitk::PointSetDataInteractor::Pointer m_PointSetInteractor
PointSetInteractor used for PointSet definition.