Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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.