Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
QmitkVideoBackground.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 "QmitkVideoBackground.h"
18 
19 // MITK includes
20 #include "mitkRenderingManager.h"
21 #include "mitkVtkLayerController.h"
22 
23 // QT includes
24 #include <QTimer>
25 
26 // itk includes
27 #include <itkCommand.h>
28 
29 // VTK includes
30 #include <vtkCallbackCommand.h>
31 #include <vtkCamera.h>
32 #include <vtkCommand.h>
33 #include <vtkCommand.h>
34 #include <vtkImageActor.h>
35 #include <vtkImageImport.h>
36 #include <vtkMapper.h>
37 #include <vtkObjectFactory.h>
38 #include <vtkRenderWindow.h>
39 #include <vtkRenderer.h>
40 #include <vtkSmartPointer.h>
41 #include <vtkSystemIncludes.h>
42 
44  : QObject(parent), m_QTimer(new QTimer(this)), m_VideoSource(nullptr), m_VideoSourceObserverTag(0)
45 {
46  this->ResetVideoBackground();
47 }
48 
50  : QObject(nullptr), m_QTimer(new QTimer(this)), m_VideoSource(nullptr), m_VideoSourceObserverTag(0)
51 {
52  this->SetVideoSource(v);
53  this->ResetVideoBackground();
54 }
55 
57 {
58  m_QTimer->setInterval(25);
59  connect(m_QTimer, SIGNAL(timeout()), SLOT(UpdateVideo()));
61 }
62 
64 {
65  this->Disable();
66 }
67 
68 void QmitkVideoBackground::AddRenderWindow(vtkRenderWindow *renderWindow)
69 {
70  if (!renderWindow || !m_VideoSource)
71  {
72  MITK_WARN << "No Renderwindow or VideoSource set!";
73  return;
74  }
75 
76  this->RemoveRenderWindow(renderWindow);
77 
78  vtkRenderer *videoRenderer = vtkRenderer::New();
79  vtkImageActor *videoActor = vtkImageActor::New();
80  vtkImageImport *videoImport = vtkImageImport::New();
81 
82  videoImport->SetDataScalarTypeToUnsignedChar();
83  videoImport->SetNumberOfScalarComponents(3);
84 
85  if (m_VideoSource->GetImageWidth() == 0)
87 
88  videoImport->SetWholeExtent(0, m_VideoSource->GetImageWidth() - 1, 0, m_VideoSource->GetImageHeight() - 1, 0, 1 - 1);
89  videoImport->SetDataExtentToWholeExtent();
90 
92  v.renWin = renderWindow;
93  v.videoRenderer = videoRenderer;
94  v.videoActor = videoActor;
95  v.videoImport = videoImport;
96 
97  // callback for the deletion of the renderwindow
98  vtkSmartPointer<vtkCallbackCommand> deleteCallback = vtkSmartPointer<vtkCallbackCommand>::New();
99  deleteCallback->SetCallback(QmitkVideoBackground::OnRenderWindowDelete);
100  deleteCallback->SetClientData(this);
101 
102  v.renderWindowObserverTag = renderWindow->AddObserver(vtkCommand::DeleteEvent, deleteCallback);
103 
104  m_renderWindowVectorInfo.push_back(v);
105 
106  // completes the initialization
107  this->Modified();
108 }
109 
110 void QmitkVideoBackground::RemoveRenderWindow(vtkRenderWindow *renderWindow)
111 {
112  this->RemoveRenderWindow(renderWindow, true);
113 }
114 
115 void QmitkVideoBackground::RemoveRenderWindow(vtkRenderWindow *renderWindow, bool removeObserver)
116 {
117  // search for renderwindow and remove it
118  for (auto it = m_renderWindowVectorInfo.begin(); it != m_renderWindowVectorInfo.end(); it++)
119  {
120  if ((*it).renWin == renderWindow)
121  {
122  mitk::VtkLayerController *layerController = mitk::VtkLayerController::GetInstance((*it).renWin);
123  // unregister video backround renderer from renderwindow
124  if (layerController)
125  layerController->RemoveRenderer((*it).videoRenderer);
126 
127  (*it).videoRenderer->Delete();
128  (*it).videoActor->Delete();
129  (*it).videoImport->Delete();
130  // remove listener
131  if (removeObserver)
132  renderWindow->RemoveObserver((*it).renderWindowObserverTag);
133  m_renderWindowVectorInfo.erase(it);
134  break;
135  }
136  }
137 }
138 
139 bool QmitkVideoBackground::IsRenderWindowIncluded(vtkRenderWindow *renderWindow)
140 {
141  for (auto it = m_renderWindowVectorInfo.begin(); it != m_renderWindowVectorInfo.end(); it++)
142  {
143  if ((*it).renWin == renderWindow)
144  return true;
145  }
146  return false;
147 }
148 
150 {
151  m_QTimer->stop();
152 }
153 
155 {
156  m_QTimer->start();
157 }
158 
164 {
165  UpdateVideo();
166  Modified();
167 
168  m_QTimer->start();
169 }
170 
176 {
177  if (this->IsEnabled())
178  {
179  mitk::VtkLayerController *layerController = nullptr;
180  for (auto it = m_renderWindowVectorInfo.begin(); it != m_renderWindowVectorInfo.end(); it++)
181  {
182  layerController = mitk::VtkLayerController::GetInstance((*it).renWin);
183  if (layerController)
184  layerController->RemoveRenderer((*it).videoRenderer);
185  }
186  m_QTimer->stop();
187  }
188 }
189 
191 {
192  return m_QTimer->isActive();
193 }
194 
196 {
197  if (m_renderWindowVectorInfo.size() > 0)
198  {
199  unsigned char *src = nullptr;
200 
201  try
202  {
204  }
205  catch (const std::logic_error &error)
206  {
207  MITK_DEBUG << error.what();
209  return;
210  }
211 
212  if (src)
213  {
214  for (auto it = m_renderWindowVectorInfo.begin(); it != m_renderWindowVectorInfo.end(); it++)
215  {
216  (*it).videoImport->SetImportVoidPointer(src);
217  (*it).videoImport->Modified();
218  (*it).videoImport->Update();
220  }
222  }
223  else
224  MITK_WARN << "No video texture available";
225  }
226 }
227 
229 {
230  // ensures registration of video backrounds in each renderwindow
231  for (auto it = m_renderWindowVectorInfo.begin(); it != m_renderWindowVectorInfo.end(); it++)
232  {
233  (*it).videoImport->Update();
234  (*it).videoActor->SetInputData((*it).videoImport->GetOutput());
235  (*it).videoRenderer->AddActor2D((*it).videoActor);
236  (*it).videoRenderer->ResetCamera();
237  (*it).videoRenderer->InteractiveOff();
238  (*it).videoRenderer->GetActiveCamera()->ParallelProjectionOn();
239  (*it).videoRenderer->GetActiveCamera()->SetParallelScale(m_VideoSource->GetImageHeight() / 2);
240 
241  mitk::VtkLayerController *layerController = mitk::VtkLayerController::GetInstance((*it).renWin);
242 
243  if (layerController && !layerController->IsRendererInserted((*it).videoRenderer))
244  layerController->InsertBackgroundRenderer((*it).videoRenderer, true);
245  }
246 }
247 
249 {
250  if (m_VideoSource == videoSource)
251  return;
252 
253  if (m_VideoSource)
254  m_VideoSource->RemoveObserver(m_VideoSourceObserverTag);
255 
256  m_VideoSource = videoSource;
257 
258  if (m_VideoSource)
259  {
262  _ModifiedCommand->SetCallbackFunction(this, &QmitkVideoBackground::OnVideoSourceDelete);
263  m_VideoSourceObserverTag = m_VideoSource->AddObserver(itk::DeleteEvent(), _ModifiedCommand);
264  }
265 }
266 
268 {
269  m_QTimer->setInterval(ms);
270 }
271 
273 {
274  return m_VideoSource;
275 }
276 
278 {
279  return m_QTimer->interval();
280 }
281 
282 void QmitkVideoBackground::OnVideoSourceDelete(const itk::Object *, const itk::EventObject &)
283 {
284  this->Disable(); // will only disable if enabled
285  m_VideoSource = nullptr;
286 }
287 
288 void QmitkVideoBackground::OnRenderWindowDelete(vtkObject *object, unsigned long, void *clientdata, void *)
289 {
290  QmitkVideoBackground *instance = static_cast<QmitkVideoBackground *>(clientdata);
291  instance->RemoveRenderWindow(static_cast<vtkRenderWindow *>(object), false);
292 }
unsigned long m_VideoSourceObserverTag
itk::SmartPointer< Self > Pointer
void RemoveRenderWindow(vtkRenderWindow *renderWindow)
removes a renderwindow = disables video background there
void Disable()
disables visualization of the video.
QmitkVideoBackground(QObject *parent=nullptr)
void EndOfVideoSourceReached(mitk::VideoSource *)
#define MITK_DEBUG
Definition: mitkLogMacros.h:26
void AddRenderWindow(vtkRenderWindow *renderWindow)
add a RenderWindow in which the video is displayed. -> must be initialized before enabling the backgr...
virtual int GetImageHeight()
static void OnRenderWindowDelete(vtkObject *, unsigned long eid, void *clientdata, void *)
static VtkLayerController * GetInstance(vtkSmartPointer< vtkRenderWindow > renWin)
mitk::VideoSource * m_VideoSource
#define MITK_WARN
Definition: mitkLogMacros.h:23
static RenderingManager * GetInstance()
bool IsEnabled()
Checks, if the Video background is currently enabled (visible).
virtual int GetImageWidth()
mitk::VideoSource * GetVideoSource()
void NewFrameAvailable(mitk::VideoSource *)
void SetVideoSource(mitk::VideoSource *videoSource)
void RequestUpdate(vtkRenderWindow *renderWindow)
void RemoveRenderer(vtkSmartPointer< vtkRenderer > renderer)
bool IsRendererInserted(vtkSmartPointer< vtkRenderer > renderer)
void SetTimerDelay(int ms)
sets the update rate of the video in milli seconds, by default 25.
virtual unsigned char * GetVideoTexture()=0
void OnVideoSourceDelete(const itk::Object *caller, const itk::EventObject &event)
virtual void FetchFrame()
bool IsRenderWindowIncluded(vtkRenderWindow *renderWindow)
void InsertBackgroundRenderer(vtkSmartPointer< vtkRenderer > renderer, bool forceAbsoluteBackground)
RenderWindowVectorInfoType m_renderWindowVectorInfo
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.