Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
QmitkSurfaceBasedInterpolatorWidget.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 
18 
19 #include "mitkColorProperty.h"
20 #include "mitkInteractionConst.h"
21 #include "mitkOperationEvent.h"
22 #include "mitkProgressBar.h"
23 #include "mitkProperties.h"
24 #include "mitkRenderingManager.h"
25 #include "mitkSegTool2D.h"
28 #include "mitkUndoController.h"
31 
32 #include "QmitkStdMultiWidget.h"
33 
34 #include <itkCommand.h>
35 #include <vtkProperty.h>
36 
37 #include <QMessageBox>
38 
40  : QWidget(parent),
41  m_SurfaceBasedInterpolatorController(mitk::SurfaceBasedInterpolationController::GetInstance()),
42  m_ToolManager(NULL),
43  m_DataStorage(NULL),
44  m_Activated(false)
45 {
46  m_Controls.setupUi(this);
47 
49  Q_ASSERT(m_ToolManager);
50 
53 
54  connect(m_Controls.m_btStart, SIGNAL(toggled(bool)), this, SLOT(OnToggleWidgetActivation(bool)));
55  connect(m_Controls.m_btAccept, SIGNAL(clicked()), this, SLOT(OnAcceptInterpolationClicked()));
56  connect(m_Controls.m_cbShowPositionNodes, SIGNAL(toggled(bool)), this, SLOT(OnShowMarkers(bool)));
57 
61  m_SurfaceInterpolationInfoChangedObserverTag =
62  m_SurfaceBasedInterpolatorController->AddObserver(itk::ModifiedEvent(), command);
63 
64  m_InterpolatedSurfaceNode = mitk::DataNode::New();
65  m_InterpolatedSurfaceNode->SetName("Surface Interpolation feedback");
66  m_InterpolatedSurfaceNode->SetProperty("color", mitk::ColorProperty::New(255.0, 255.0, 0.0));
67  m_InterpolatedSurfaceNode->SetProperty("opacity", mitk::FloatProperty::New(0.5));
68  m_InterpolatedSurfaceNode->SetProperty("includeInBoundingBox", mitk::BoolProperty::New(false));
69  m_InterpolatedSurfaceNode->SetProperty("helper object", mitk::BoolProperty::New(true));
70  m_InterpolatedSurfaceNode->SetVisibility(false);
71 
72  m_3DContourNode = mitk::DataNode::New();
73  m_3DContourNode->SetName("Drawn Contours");
74  m_3DContourNode->SetProperty("color", mitk::ColorProperty::New(0.0, 0.0, 0.0));
75  m_3DContourNode->SetProperty("helper object", mitk::BoolProperty::New(true));
76  m_3DContourNode->SetProperty("material.representation", mitk::VtkRepresentationProperty::New(VTK_WIREFRAME));
77  m_3DContourNode->SetProperty("material.wireframeLineWidth", mitk::FloatProperty::New(2.0f));
78  m_3DContourNode->SetProperty("includeInBoundingBox", mitk::BoolProperty::New(false));
79  m_3DContourNode->SetVisibility(
81  m_3DContourNode->SetVisibility(
83  m_3DContourNode->SetVisibility(
85  m_3DContourNode->SetVisibility(
87 
88  connect(&m_Watcher, SIGNAL(started()), this, SLOT(StartUpdateInterpolationTimer()));
89  connect(&m_Watcher, SIGNAL(finished()), this, SLOT(OnSurfaceInterpolationFinished()));
90  connect(&m_Watcher, SIGNAL(finished()), this, SLOT(StopUpdateInterpolationTimer()));
91 
92  m_Timer = new QTimer(this);
93  connect(m_Timer, SIGNAL(timeout()), this, SLOT(ChangeSurfaceColor()));
94 
95  m_Controls.m_btAccept->setEnabled(false);
96  m_Controls.m_cbShowPositionNodes->setEnabled(false);
97 
98  this->setEnabled(false);
99 }
100 
102 {
103  m_DataStorage = &storage;
104 }
105 
107 {
110 
111  if (m_DataStorage->Exists(m_3DContourNode))
112  m_DataStorage->Remove(m_3DContourNode);
113 
114  if (m_DataStorage->Exists(m_InterpolatedSurfaceNode))
115  m_DataStorage->Remove(m_InterpolatedSurfaceNode);
116 
117  // remove observer
118  m_SurfaceBasedInterpolatorController->RemoveObserver(m_SurfaceInterpolationInfoChangedObserverTag);
119 
120  delete m_Timer;
121 }
122 
124 {
125  if (m_InterpolatedSurfaceNode.IsNotNull())
126  m_InterpolatedSurfaceNode->SetVisibility(status);
127 
128  if (m_3DContourNode.IsNotNull())
129  m_3DContourNode->SetVisibility(
131 
133 }
134 
136 {
137  mitk::Surface::Pointer interpolatedSurface = m_SurfaceBasedInterpolatorController->GetInterpolationResult();
138 
139  if (interpolatedSurface.IsNotNull())
140  {
141  m_InterpolatedSurfaceNode->SetData(interpolatedSurface);
142  m_3DContourNode->SetData(m_SurfaceBasedInterpolatorController->GetContoursAsSurface());
143  this->ShowInterpolationResult(true);
144  }
145  else
146  {
147  m_InterpolatedSurfaceNode->SetData(NULL);
148  m_3DContourNode->SetData(NULL);
149  this->ShowInterpolationResult(false);
150  }
151 }
152 
154 {
156  m_DataStorage->GetSubset(mitk::NodePredicateProperty::New("isContourMarker", mitk::BoolProperty::New(true)));
157 
158  for (mitk::DataStorage::SetOfObjects::ConstIterator it = allContourMarkers->Begin(); it != allContourMarkers->End();
159  ++it)
160  {
161  it->Value()->SetProperty("helper object", mitk::BoolProperty::New(!state));
162  }
163 
164  mitk::SegTool2D::Pointer manualSegmentationTool;
165 
166  unsigned int numberOfExistingTools = m_ToolManager->GetTools().size();
167 
168  for (unsigned int i = 0; i < numberOfExistingTools; i++)
169  {
170  manualSegmentationTool = dynamic_cast<mitk::SegTool2D *>(m_ToolManager->GetToolById(i));
171 
172  if (manualSegmentationTool)
173  {
174  manualSegmentationTool->SetShowMarkerNodes(state);
175  }
176  }
177 }
178 
180 {
181  m_Timer->start(500);
182 }
183 
185 {
186  m_Timer->stop();
187  m_InterpolatedSurfaceNode->SetProperty("color", mitk::ColorProperty::New(255.0, 255.0, 0.0));
189  mitk::BaseRenderer::GetInstance(mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget4"))->GetRenderWindow());
190 }
191 
193 {
194  float currentColor[3];
195  m_InterpolatedSurfaceNode->GetColor(currentColor);
196 
197  float yellow[3] = {255.0, 255.0, 0.0};
198 
199  if (currentColor[2] == yellow[2])
200  {
201  m_InterpolatedSurfaceNode->SetProperty("color", mitk::ColorProperty::New(255.0, 255.0, 255.0));
202  }
203  else
204  {
205  m_InterpolatedSurfaceNode->SetProperty("color", mitk::ColorProperty::New(yellow));
206  }
207  m_InterpolatedSurfaceNode->Update();
209  mitk::BaseRenderer::GetInstance(mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget4"))->GetRenderWindow());
210 }
211 
213 {
214  mitk::DataNode *workingNode = this->m_ToolManager->GetWorkingData(0);
215  if (!workingNode)
216  {
217  this->setEnabled(false);
218  return;
219  }
220 
221  mitk::LabelSetImage *workingImage = dynamic_cast<mitk::LabelSetImage *>(workingNode->GetData());
222  // TODO adapt tool manager so that this check is done there, e.g. convenience function
223  // Q_ASSERT(workingImage);
224  if (!workingImage)
225  {
226  this->setEnabled(false);
227  return;
228  }
229 
230  if (workingImage->GetDimension() > 4 || workingImage->GetDimension() < 3)
231  {
232  this->setEnabled(false);
233  return;
234  }
235 
236  m_WorkingImage = workingImage;
237 
238  this->setEnabled(true);
239 }
240 
242 {
243  m_SurfaceBasedInterpolatorController->Interpolate();
244 }
245 
247 {
248  Q_ASSERT(m_ToolManager);
249 
250  mitk::DataNode *workingNode = m_ToolManager->GetWorkingData(0);
251  if (!workingNode)
252  return;
253 
254  m_Controls.m_btAccept->setEnabled(enabled);
255  m_Controls.m_cbShowPositionNodes->setEnabled(enabled);
256 
257  if (enabled)
258  m_Controls.m_btStart->setText("Stop");
259  else
260  m_Controls.m_btStart->setText("Start");
261 
262  for (unsigned int i = 0; i < m_ToolManager->GetTools().size(); i++)
263  {
264  mitk::SegTool2D *tool = dynamic_cast<mitk::SegTool2D *>(m_ToolManager->GetToolById(i));
265  if (tool)
266  tool->SetEnable3DInterpolation(enabled);
267  }
268 
269  if (enabled)
270  {
271  if (!m_DataStorage->Exists(m_InterpolatedSurfaceNode))
272  {
273  m_DataStorage->Add(m_InterpolatedSurfaceNode);
274  }
275 
276  if (!m_DataStorage->Exists(m_3DContourNode))
277  {
278  m_DataStorage->Add(m_3DContourNode);
279  }
280 
281  mitk::Vector3D spacing = m_WorkingImage->GetGeometry(0)->GetSpacing();
282  double minSpacing(100);
283  double maxSpacing(0);
284  for (int i = 0; i < 3; i++)
285  {
286  if (spacing[i] < minSpacing)
287  {
288  minSpacing = spacing[i];
289  }
290  else if (spacing[i] > maxSpacing)
291  {
292  maxSpacing = spacing[i];
293  }
294  }
295 
296  m_SurfaceBasedInterpolatorController->SetWorkingImage(m_WorkingImage);
297  m_SurfaceBasedInterpolatorController->SetActiveLabel(m_WorkingImage->GetActiveLabel()->GetValue());
298  m_SurfaceBasedInterpolatorController->SetMaxSpacing(maxSpacing);
299  m_SurfaceBasedInterpolatorController->SetMinSpacing(minSpacing);
300  m_SurfaceBasedInterpolatorController->SetDistanceImageVolume(50000);
301 
302  int ret = QMessageBox::Yes;
303 
304  if (m_SurfaceBasedInterpolatorController->EstimatePortionOfNeededMemory() > 0.5)
305  {
306  QMessageBox msgBox;
307  msgBox.setText("Due to short handed system memory the 3D interpolation may be very slow!");
308  msgBox.setInformativeText("Are you sure you want to activate the 3D interpolation?");
309  msgBox.setStandardButtons(QMessageBox::No | QMessageBox::Yes);
310  ret = msgBox.exec();
311  }
312 
313  if (m_Watcher.isRunning())
314  m_Watcher.waitForFinished();
315 
316  if (ret == QMessageBox::Yes)
317  {
318  m_Future = QtConcurrent::run(this, &QmitkSurfaceBasedInterpolatorWidget::OnRunInterpolation);
319  m_Watcher.setFuture(m_Future);
320  }
321  }
322  else
323  {
324  if (m_DataStorage->Exists(m_InterpolatedSurfaceNode))
325  {
326  m_DataStorage->Remove(m_InterpolatedSurfaceNode);
327  }
328  if (m_DataStorage->Exists(m_3DContourNode))
329  {
330  m_DataStorage->Remove(m_3DContourNode);
331  }
332 
334  }
335 
336  m_Activated = enabled;
337 
339 }
340 
342 {
343  if (m_InterpolatedSurfaceNode.IsNotNull() && m_InterpolatedSurfaceNode->GetData())
344  {
345  // m_WorkingImage->SurfaceStamp(dynamic_cast<mitk::Surface*>(m_InterpolatedSurfaceNode->GetData()), false);
346  this->ShowInterpolationResult(false);
347  }
348 }
349 
351 {
352  if (m_Activated)
353  {
354  if (m_Watcher.isRunning())
355  m_Watcher.waitForFinished();
356 
357  m_Future = QtConcurrent::run(this, &QmitkSurfaceBasedInterpolatorWidget::OnRunInterpolation);
358  m_Watcher.setFuture(m_Future);
359  }
360 }
Ui::QmitkSurfaceBasedInterpolatorWidgetGUIControls m_Controls
Data management class that handles 'was created by' relations.
itk::SmartPointer< Self > Pointer
void ShowInterpolationResult(bool)
Set the visibility of the interpolation.
static BaseRenderer * GetInstance(vtkRenderWindow *renWin)
static vtkRenderWindow * GetRenderWindowByName(const std::string &name)
static Pointer New()
Tool * GetToolById(int id)
DataCollection - Class to facilitate loading/accessing structured data.
virtual mitk::ToolManager * GetToolManager()
Returns ToolManager object.
BaseData * GetData() const
Get the data object (instance of BaseData, e.g., an Image) managed by this DataNode.
Constants for most interaction classes, due to the generic StateMachines.
void OnToggleWidgetActivation(bool)
Reaction to "Start/Stop" button click.
void OnSurfaceInterpolationInfoChanged(const itk::EventObject &)
void SetEnable3DInterpolation(bool)
Enables or disables the 3D interpolation after writing back the 2D segmentation result, and defaults to true.
itk::SmartPointer< const Self > ConstPointer
static Pointer New()
mitk::DataStorage::Pointer m_DataStorage
static Pointer New()
static RenderingManager * GetInstance()
static Pointer New(const char *_arg)
static Pointer New()
void RequestUpdate(vtkRenderWindow *renderWindow)
const ToolVectorTypeConst GetTools()
Gives you a list of all tools. This is const on purpose.
Abstract base class for segmentation tools.
Definition: mitkSegTool2D.h:58
static UndoModel * GetCurrentUndoModel()
gives access to the currently used UndoModel Introduced to access special functions of more specific ...
LabelSetImage class for handling labels and layers in a segmentation session.
QmitkSurfaceBasedInterpolatorWidget(QWidget *parent=0, const char *name=0)
virtual void Clear()=0
clears undo and Redolist
unsigned int GetDimension() const
Get dimension of the image.
Definition: mitkImage.cpp:110
void RequestUpdateAll(RequestType type=REQUEST_UPDATE_ALL)
Class for nodes of the DataTree.
Definition: mitkDataNode.h:66
DataVectorType GetWorkingData()
static mitk::ToolManagerProvider * GetInstance()
Returns an instance of ToolManagerProvider service.
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.