Medical Imaging Interaction Toolkit  2018.4.99-1640525a
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 (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 
13 #include "QmitkVideoBackground.h"
14 
15 // MITK includes
16 #include "mitkRenderingManager.h"
17 #include "mitkVtkLayerController.h"
18 
19 // QT includes
20 #include <QTimer>
21 
22 // itk includes
23 #include <itkCommand.h>
24 
25 // VTK includes
26 #include <vtkCallbackCommand.h>
27 #include <vtkCamera.h>
28 #include <vtkCommand.h>
29 #include <vtkCommand.h>
30 #include <vtkImageActor.h>
31 #include <vtkImageImport.h>
32 #include <vtkMapper.h>
33 #include <vtkObjectFactory.h>
34 #include <vtkRenderWindow.h>
35 #include <vtkRenderer.h>
36 #include <vtkSmartPointer.h>
37 #include <vtkSystemIncludes.h>
38 
40  : QObject(parent), m_QTimer(new QTimer(this)), m_VideoSource(nullptr), m_VideoSourceObserverTag(0)
41 {
42  this->ResetVideoBackground();
43 }
44 
46  : QObject(nullptr), m_QTimer(new QTimer(this)), m_VideoSource(nullptr), m_VideoSourceObserverTag(0)
47 {
48  this->SetVideoSource(v);
49  this->ResetVideoBackground();
50 }
51 
53 {
54  m_QTimer->setInterval(25);
55  connect(m_QTimer, SIGNAL(timeout()), SLOT(UpdateVideo()));
57 }
58 
60 {
61  this->Disable();
62 }
63 
64 void QmitkVideoBackground::AddRenderWindow(vtkRenderWindow *renderWindow)
65 {
66  if (!renderWindow || !m_VideoSource)
67  {
68  MITK_WARN << "No Renderwindow or VideoSource set!";
69  return;
70  }
71 
72  this->RemoveRenderWindow(renderWindow);
73 
74  vtkRenderer *videoRenderer = vtkRenderer::New();
75  vtkImageActor *videoActor = vtkImageActor::New();
76  vtkImageImport *videoImport = vtkImageImport::New();
77 
78  videoImport->SetDataScalarTypeToUnsignedChar();
79  videoImport->SetNumberOfScalarComponents(3);
80 
81  if (m_VideoSource->GetImageWidth() == 0)
83 
84  videoImport->SetWholeExtent(0, m_VideoSource->GetImageWidth() - 1, 0, m_VideoSource->GetImageHeight() - 1, 0, 1 - 1);
85  videoImport->SetDataExtentToWholeExtent();
86 
88  v.renWin = renderWindow;
89  v.videoRenderer = videoRenderer;
90  v.videoActor = videoActor;
91  v.videoImport = videoImport;
92 
93  // callback for the deletion of the renderwindow
94  vtkSmartPointer<vtkCallbackCommand> deleteCallback = vtkSmartPointer<vtkCallbackCommand>::New();
95  deleteCallback->SetCallback(QmitkVideoBackground::OnRenderWindowDelete);
96  deleteCallback->SetClientData(this);
97 
98  v.renderWindowObserverTag = renderWindow->AddObserver(vtkCommand::DeleteEvent, deleteCallback);
99 
100  m_renderWindowVectorInfo.push_back(v);
101 
102  // completes the initialization
103  this->Modified();
104 }
105 
106 void QmitkVideoBackground::RemoveRenderWindow(vtkRenderWindow *renderWindow)
107 {
108  this->RemoveRenderWindow(renderWindow, true);
109 }
110 
111 void QmitkVideoBackground::RemoveRenderWindow(vtkRenderWindow *renderWindow, bool removeObserver)
112 {
113  // search for renderwindow and remove it
114  for (auto it = m_renderWindowVectorInfo.begin(); it != m_renderWindowVectorInfo.end(); it++)
115  {
116  if ((*it).renWin == renderWindow)
117  {
118  mitk::VtkLayerController *layerController = mitk::VtkLayerController::GetInstance((*it).renWin);
119  // unregister video backround renderer from renderwindow
120  if (layerController)
121  layerController->RemoveRenderer((*it).videoRenderer);
122 
123  (*it).videoRenderer->Delete();
124  (*it).videoActor->Delete();
125  (*it).videoImport->Delete();
126  // remove listener
127  if (removeObserver)
128  renderWindow->RemoveObserver((*it).renderWindowObserverTag);
129  m_renderWindowVectorInfo.erase(it);
130  break;
131  }
132  }
133 }
134 
135 bool QmitkVideoBackground::IsRenderWindowIncluded(vtkRenderWindow *renderWindow)
136 {
137  for (auto it = m_renderWindowVectorInfo.begin(); it != m_renderWindowVectorInfo.end(); it++)
138  {
139  if ((*it).renWin == renderWindow)
140  return true;
141  }
142  return false;
143 }
144 
146 {
147  m_QTimer->stop();
148 }
149 
151 {
152  m_QTimer->start();
153 }
154 
160 {
161  UpdateVideo();
162  Modified();
163 
164  m_QTimer->start();
165 }
166 
172 {
173  if (this->IsEnabled())
174  {
175  mitk::VtkLayerController *layerController = nullptr;
176  for (auto it = m_renderWindowVectorInfo.begin(); it != m_renderWindowVectorInfo.end(); it++)
177  {
178  layerController = mitk::VtkLayerController::GetInstance((*it).renWin);
179  if (layerController)
180  layerController->RemoveRenderer((*it).videoRenderer);
181  }
182  m_QTimer->stop();
183  }
184 }
185 
187 {
188  return m_QTimer->isActive();
189 }
190 
192 {
193  if (m_renderWindowVectorInfo.size() > 0)
194  {
195  unsigned char *src = nullptr;
196 
197  try
198  {
200  }
201  catch (const std::logic_error &error)
202  {
203  MITK_DEBUG << error.what();
205  return;
206  }
207 
208  if (src)
209  {
210  for (auto it = m_renderWindowVectorInfo.begin(); it != m_renderWindowVectorInfo.end(); it++)
211  {
212  (*it).videoImport->SetImportVoidPointer(src);
213  (*it).videoImport->Modified();
214  (*it).videoImport->Update();
216  }
218  }
219  else
220  MITK_WARN << "No video texture available";
221  }
222 }
223 
225 {
226  // ensures registration of video backrounds in each renderwindow
227  for (auto it = m_renderWindowVectorInfo.begin(); it != m_renderWindowVectorInfo.end(); it++)
228  {
229  (*it).videoImport->Update();
230  (*it).videoActor->SetInputData((*it).videoImport->GetOutput());
231  (*it).videoRenderer->AddActor2D((*it).videoActor);
232  (*it).videoRenderer->ResetCamera();
233  (*it).videoRenderer->InteractiveOff();
234  (*it).videoRenderer->GetActiveCamera()->ParallelProjectionOn();
235  (*it).videoRenderer->GetActiveCamera()->SetParallelScale(m_VideoSource->GetImageHeight() / 2);
236 
237  mitk::VtkLayerController *layerController = mitk::VtkLayerController::GetInstance((*it).renWin);
238 
239  if (layerController && !layerController->IsRendererInserted((*it).videoRenderer))
240  layerController->InsertBackgroundRenderer((*it).videoRenderer, true);
241  }
242 }
243 
245 {
246  if (m_VideoSource == videoSource)
247  return;
248 
249  if (m_VideoSource)
250  m_VideoSource->RemoveObserver(m_VideoSourceObserverTag);
251 
252  m_VideoSource = videoSource;
253 
254  if (m_VideoSource)
255  {
256  itk::MemberCommand<QmitkVideoBackground>::Pointer _ModifiedCommand =
257  itk::MemberCommand<QmitkVideoBackground>::New();
258  _ModifiedCommand->SetCallbackFunction(this, &QmitkVideoBackground::OnVideoSourceDelete);
259  m_VideoSourceObserverTag = m_VideoSource->AddObserver(itk::DeleteEvent(), _ModifiedCommand);
260  }
261 }
262 
264 {
265  m_QTimer->setInterval(ms);
266 }
267 
269 {
270  return m_VideoSource;
271 }
272 
274 {
275  return m_QTimer->interval();
276 }
277 
278 void QmitkVideoBackground::OnVideoSourceDelete(const itk::Object *, const itk::EventObject &)
279 {
280  this->Disable(); // will only disable if enabled
281  m_VideoSource = nullptr;
282 }
283 
284 void QmitkVideoBackground::OnRenderWindowDelete(vtkObject *object, unsigned long, void *clientdata, void *)
285 {
286  QmitkVideoBackground *instance = static_cast<QmitkVideoBackground *>(clientdata);
287  instance->RemoveRenderWindow(static_cast<vtkRenderWindow *>(object), false);
288 }
unsigned long m_VideoSourceObserverTag
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:22
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:19
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