Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkInteractionTestHelper.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 // MITK
18 #include <mitkIOUtil.h>
23 
24 // VTK
25 #include <vtkCamera.h>
26 #include <vtkRenderWindowInteractor.h>
27 
28 // us
29 #include <usGetModuleContext.h>
30 
31 #include <tinyxml.h>
32 
33 mitk::InteractionTestHelper::InteractionTestHelper(const std::string &interactionXmlFilePath)
34  : m_InteractionFilePath(interactionXmlFilePath)
35 {
36  this->Initialize(interactionXmlFilePath);
37 }
38 
39 void mitk::InteractionTestHelper::Initialize(const std::string &interactionXmlFilePath)
40 {
41  // TiXmlDocument document(interactionXmlPath.c_str());
42  TiXmlDocument document(interactionXmlFilePath);
43  bool loadOkay = document.LoadFile();
44  if (loadOkay)
45  {
46  // get RenderingManager instance
48 
49  // create data storage
51 
52  // for each renderer found create a render window and configure
53  for (TiXmlElement *element = document.FirstChildElement(mitk::InteractionEventConst::xmlTagInteractions())
55  ->FirstChildElement(mitk::InteractionEventConst::xmlTagRenderer());
56  element != NULL;
57  element = element->NextSiblingElement(mitk::InteractionEventConst::xmlTagRenderer()))
58  {
59  // get name of renderer
60  const char *rendererName =
62 
63  // get view direction
65  if (element->Attribute(mitk::InteractionEventConst::xmlEventPropertyViewDirection()) != NULL)
66  {
67  int viewDirectionNum =
68  std::atoi(element->Attribute(mitk::InteractionEventConst::xmlEventPropertyViewDirection())->c_str());
69  viewDirection = static_cast<mitk::SliceNavigationController::ViewDirection>(viewDirectionNum);
70  }
71 
72  // get mapper slot id
74  if (element->Attribute(mitk::InteractionEventConst::xmlEventPropertyMapperID()) != NULL)
75  {
76  int mapperIDNum =
77  std::atoi(element->Attribute(mitk::InteractionEventConst::xmlEventPropertyMapperID())->c_str());
78  mapperID = static_cast<mitk::BaseRenderer::MapperSlotId>(mapperIDNum);
79  }
80 
81  // Get Size of Render Windows
82  int size[3];
83  size[0] = size[1] = size[2] = 0;
84  if (element->Attribute(mitk::InteractionEventConst::xmlRenderSizeX()) != NULL)
85  {
86  size[0] = std::atoi(element->Attribute(mitk::InteractionEventConst::xmlRenderSizeX())->c_str());
87  }
88  if (element->Attribute(mitk::InteractionEventConst::xmlRenderSizeY()) != NULL)
89  {
90  size[1] = std::atoi(element->Attribute(mitk::InteractionEventConst::xmlRenderSizeY())->c_str());
91  }
92  if (element->Attribute(mitk::InteractionEventConst::xmlRenderSizeZ()) != NULL)
93  {
94  size[2] = std::atoi(element->Attribute(mitk::InteractionEventConst::xmlRenderSizeZ())->c_str());
95  }
96 
97  // create renderWindow, renderer and dispatcher
99  mitk::RenderWindow::New(NULL, rendererName, rm); // VtkRenderWindow is created within constructor if NULL
100 
101  if (size[0] != 0 && size[1] != 0)
102  {
103  rw->SetSize(size[0], size[1]);
104  rw->GetRenderer()->Resize(size[0], size[1]);
105  }
106 
107  // set storage of renderer
108  rw->GetRenderer()->SetDataStorage(m_DataStorage);
109 
110  // set view direction to axial
111  rw->GetSliceNavigationController()->SetDefaultViewDirection(viewDirection);
112 
113  // set renderer to render 2D
114  rw->GetRenderer()->SetMapperID(mapperID);
115 
116  rw->GetRenderer()->PrepareRender();
117 
118  // Some more magic for the 3D render window case:
119  // Camera view direction, position and focal point
120 
121  if (mapperID == mitk::BaseRenderer::Standard3D)
122  {
123  if (element->Attribute(mitk::InteractionEventConst::xmlCameraFocalPointX()) != NULL)
124  {
125  double cameraFocalPoint[3];
126 
127  cameraFocalPoint[0] =
128  std::atoi(element->Attribute(mitk::InteractionEventConst::xmlCameraFocalPointX())->c_str());
129  cameraFocalPoint[1] =
130  std::atoi(element->Attribute(mitk::InteractionEventConst::xmlCameraFocalPointY())->c_str());
131  cameraFocalPoint[2] =
132  std::atoi(element->Attribute(mitk::InteractionEventConst::xmlCameraFocalPointZ())->c_str());
133  rw->GetRenderer()->GetVtkRenderer()->GetActiveCamera()->SetFocalPoint(cameraFocalPoint);
134  }
135 
136  if (element->Attribute(mitk::InteractionEventConst::xmlCameraPositionX()) != NULL)
137  {
138  double cameraPosition[3];
139 
140  cameraPosition[0] = std::atoi(element->Attribute(mitk::InteractionEventConst::xmlCameraPositionX())->c_str());
141  cameraPosition[1] = std::atoi(element->Attribute(mitk::InteractionEventConst::xmlCameraPositionY())->c_str());
142  cameraPosition[2] = std::atoi(element->Attribute(mitk::InteractionEventConst::xmlCameraPositionZ())->c_str());
143  rw->GetRenderer()->GetVtkRenderer()->GetActiveCamera()->SetPosition(cameraPosition);
144  }
145 
146  if (element->Attribute(mitk::InteractionEventConst::xmlViewUpX()) != NULL)
147  {
148  double viewUp[3];
149 
150  viewUp[0] = std::atoi(element->Attribute(mitk::InteractionEventConst::xmlViewUpX())->c_str());
151  viewUp[1] = std::atoi(element->Attribute(mitk::InteractionEventConst::xmlViewUpY())->c_str());
152  viewUp[2] = std::atoi(element->Attribute(mitk::InteractionEventConst::xmlViewUpZ())->c_str());
153  rw->GetRenderer()->GetVtkRenderer()->GetActiveCamera()->SetViewUp(viewUp);
154  }
155  }
156 
157  rw->GetVtkRenderWindow()->Render();
158  rw->GetVtkRenderWindow()->WaitForCompletion();
159 
160  // connect SliceNavigationControllers to timestep changed event of TimeNavigationController
161  rw->GetSliceNavigationController()->ConnectGeometryTimeEvent(rm->GetTimeNavigationController(), false);
162  rm->GetTimeNavigationController()->ConnectGeometryTimeEvent(rw->GetSliceNavigationController(), false);
163 
164  // add to list of kown render windows
165  m_RenderWindowList.push_back(rw);
166  }
167 
168  // TODO: check the following lines taken from QmitkStdMultiWidget and adapt them to be executed in our code here.
169  // mitkWidget1->GetSliceNavigationController()
170  // ->ConnectGeometrySendEvent(mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow()));
171 
172  //########### register display interactor to handle scroll events ##################
173  // use MouseModeSwitcher to ensure that the statemachine of DisplayInteractor is loaded correctly
174  m_MouseModeSwitcher = mitk::MouseModeSwitcher::New();
175  }
176  else
177  {
178  mitkThrow() << "Can not load interaction xml file <" << m_InteractionFilePath << ">";
179  }
180 
181  // WARNING assumes a 3D window exists !!!!
182  this->AddDisplayPlaneSubTree();
183 }
184 
186 {
188 
189  // unregister renderers
190  InteractionTestHelper::RenderWindowListType::iterator it = m_RenderWindowList.begin();
191  InteractionTestHelper::RenderWindowListType::iterator end = m_RenderWindowList.end();
192 
193  for (; it != end; ++it)
194  {
195  rm->GetTimeNavigationController()->Disconnect((*it)->GetSliceNavigationController());
196  (*it)->GetSliceNavigationController()->Disconnect(rm->GetTimeNavigationController());
197  mitk::BaseRenderer::RemoveInstance((*it)->GetVtkRenderWindow());
198  }
199  rm->RemoveAllObservers();
200 }
201 
203 {
204  return m_DataStorage;
205 }
206 
208 {
209  this->m_DataStorage->Add(node);
210 
211  this->Set3dCameraSettings();
212 }
213 
215 {
217  // load events if not loaded yet
218  if (m_Events.empty())
219  this->LoadInteraction();
220 
221  InteractionTestHelper::RenderWindowListType::iterator it = m_RenderWindowList.begin();
222  InteractionTestHelper::RenderWindowListType::iterator end = m_RenderWindowList.end();
223  for (; it != end; ++it)
224  {
225  (*it)->GetRenderer()->PrepareRender();
226 
227  (*it)->GetVtkRenderWindow()->Render();
228  (*it)->GetVtkRenderWindow()->WaitForCompletion();
229  }
231 
232  it = m_RenderWindowList.begin();
233  for (; it != end; ++it)
234  {
235  (*it)->GetVtkRenderWindow()->Render();
236  (*it)->GetVtkRenderWindow()->WaitForCompletion();
237  }
238 
239  // mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll();
240  // playback all events in queue
241  for (unsigned long i = 0; i < m_Events.size(); ++i)
242  {
243  // let dispatcher of sending renderer process the event
244  m_Events.at(i)->GetSender()->GetDispatcher()->ProcessEvent(m_Events.at(i));
245  }
246  if (false)
247  {
248  it--;
249  (*it)->GetVtkRenderWindow()->GetInteractor()->Start();
250  }
251 }
252 
254 {
255  // load interaction pattern from xml file
256  std::ifstream xmlStream(m_InteractionFilePath.c_str());
257  mitk::XML2EventParser parser(xmlStream);
258  m_Events = parser.GetInteractions();
259  xmlStream.close();
260  // Avoid VTK warning: Trying to delete object with non-zero reference count.
261  parser.SetReferenceCount(0);
262 }
263 
265 {
267 
268  bool timeStepIsvalid =
270  newTimeStep);
271 
272  if (timeStepIsvalid)
273  {
275  }
276 }
277 
279 {
280  InteractionTestHelper::RenderWindowListType::iterator it = m_RenderWindowList.begin();
281  InteractionTestHelper::RenderWindowListType::iterator end = m_RenderWindowList.end();
282 
283  for (; it != end; ++it)
284  {
285  if (name.compare((*it)->GetRenderer()->GetName()) == 0)
286  return (*it).GetPointer();
287  }
288 
289  return NULL;
290 }
291 
294 {
295  InteractionTestHelper::RenderWindowListType::iterator it = m_RenderWindowList.begin();
296  InteractionTestHelper::RenderWindowListType::iterator end = m_RenderWindowList.end();
297 
298  for (; it != end; ++it)
299  {
300  if (viewDirection == (*it)->GetSliceNavigationController()->GetDefaultViewDirection())
301  return (*it).GetPointer();
302  }
303 
304  return NULL;
305 }
306 
308 {
309  if (index < m_RenderWindowList.size())
310  {
311  return m_RenderWindowList.at(index).GetPointer();
312  }
313  else
314  {
315  return NULL;
316  }
317 }
318 
320 {
321  // add the displayed planes of the multiwidget to a node to which the subtree
322  // @a planesSubTree points ...
323 
326 
328  node->SetProperty("name", mitk::StringProperty::New("Widgets"));
329  node->SetProperty("helper object", mitk::BoolProperty::New(true));
330 
331  m_DataStorage->Add(node);
332 
333  for (auto it : m_RenderWindowList)
334  {
335  if (it->GetRenderer()->GetMapperID() == BaseRenderer::Standard3D)
336  continue;
337 
338  // ... of widget 1
339  mitk::DataNode::Pointer planeNode1 =
340  (mitk::BaseRenderer::GetInstance(it->GetVtkRenderWindow()))->GetCurrentWorldPlaneGeometryNode();
341 
342  planeNode1->SetProperty("visible", mitk::BoolProperty::New(true));
343  planeNode1->SetProperty("name", mitk::StringProperty::New("widget1Plane"));
344  planeNode1->SetProperty("includeInBoundingBox", mitk::BoolProperty::New(false));
345  planeNode1->SetProperty("helper object", mitk::BoolProperty::New(true));
346  planeNode1->SetProperty("layer", layer);
347  planeNode1->SetColor(1.0, 0.0, 0.0);
349  planeNode1->SetMapper(mitk::BaseRenderer::Standard2D, mapper);
350  m_DataStorage->Add(planeNode1, node);
351  }
352 }
353 
355 {
356  TiXmlDocument document(m_InteractionFilePath);
357  bool loadOkay = document.LoadFile();
358  if (loadOkay)
359  {
360  // for each renderer found create a render window and configure
361  for (TiXmlElement *element = document.FirstChildElement(mitk::InteractionEventConst::xmlTagInteractions())
362  ->FirstChildElement(mitk::InteractionEventConst::xmlTagConfigRoot())
363  ->FirstChildElement(mitk::InteractionEventConst::xmlTagRenderer());
364  element != NULL;
365  element = element->NextSiblingElement(mitk::InteractionEventConst::xmlTagRenderer()))
366  {
367  // get name of renderer
368  const char *rendererName =
369  element->Attribute(mitk::InteractionEventConst::xmlEventPropertyRendererName().c_str());
370 
371  // get mapper slot id
373  if (element->Attribute(mitk::InteractionEventConst::xmlEventPropertyMapperID()) != NULL)
374  {
375  int mapperIDNum =
376  std::atoi(element->Attribute(mitk::InteractionEventConst::xmlEventPropertyMapperID())->c_str());
377  mapperID = static_cast<mitk::BaseRenderer::MapperSlotId>(mapperIDNum);
378  }
379 
380  if (mapperID == mitk::BaseRenderer::Standard3D)
381  {
382  RenderWindow *namedRenderer = nullptr;
383 
384  for (auto it : m_RenderWindowList)
385  {
386  if (strcmp(it->GetRenderer()->GetName(), rendererName) == 0)
387  {
388  namedRenderer = it.GetPointer();
389  break;
390  }
391  }
392 
393  if (namedRenderer == nullptr)
394  {
395  MITK_ERROR << "No match for render window was found.";
396  return;
397  }
398  namedRenderer->GetRenderer()->PrepareRender();
399 
400  if (element->Attribute(mitk::InteractionEventConst::xmlCameraFocalPointX()) != NULL)
401  {
402  double cameraFocalPoint[3];
403 
404  cameraFocalPoint[0] =
405  std::atoi(element->Attribute(mitk::InteractionEventConst::xmlCameraFocalPointX())->c_str());
406  cameraFocalPoint[1] =
407  std::atoi(element->Attribute(mitk::InteractionEventConst::xmlCameraFocalPointY())->c_str());
408  cameraFocalPoint[2] =
409  std::atoi(element->Attribute(mitk::InteractionEventConst::xmlCameraFocalPointZ())->c_str());
410  namedRenderer->GetRenderer()->GetVtkRenderer()->GetActiveCamera()->SetFocalPoint(cameraFocalPoint);
411  }
412 
413  if (element->Attribute(mitk::InteractionEventConst::xmlCameraPositionX()) != NULL)
414  {
415  double cameraPosition[3];
416 
417  cameraPosition[0] = std::atoi(element->Attribute(mitk::InteractionEventConst::xmlCameraPositionX())->c_str());
418  cameraPosition[1] = std::atoi(element->Attribute(mitk::InteractionEventConst::xmlCameraPositionY())->c_str());
419  cameraPosition[2] = std::atoi(element->Attribute(mitk::InteractionEventConst::xmlCameraPositionZ())->c_str());
420  namedRenderer->GetRenderer()->GetVtkRenderer()->GetActiveCamera()->SetPosition(cameraPosition);
421  }
422 
423  if (element->Attribute(mitk::InteractionEventConst::xmlViewUpX()) != NULL)
424  {
425  double viewUp[3];
426 
427  viewUp[0] = std::atoi(element->Attribute(mitk::InteractionEventConst::xmlViewUpX())->c_str());
428  viewUp[1] = std::atoi(element->Attribute(mitk::InteractionEventConst::xmlViewUpY())->c_str());
429  viewUp[2] = std::atoi(element->Attribute(mitk::InteractionEventConst::xmlViewUpZ())->c_str());
430  namedRenderer->GetRenderer()->GetVtkRenderer()->GetActiveCamera()->SetViewUp(viewUp);
431  }
432 
433  namedRenderer->GetVtkRenderWindow()->Render();
434  }
435  }
436  }
437 }
static const std::string xmlCameraPositionZ()
virtual const mitk::TimeGeometry * GetCreatedWorldGeometry()
Access the created geometry.
static const std::string xmlViewUpX()
const SliceNavigationController * GetTimeNavigationController() const
virtual vtkRenderWindow * GetVtkRenderWindow() override
static const std::string xmlEventPropertyRendererName()
static BaseRenderer * GetInstance(vtkRenderWindow *renWin)
void AddDisplayPlaneSubTree()
#define MITK_ERROR
Definition: mitkLogMacros.h:24
void PlaybackInteraction()
PlaybackInteraction playback loaded interaction by passing events to the dispatcher.
static const std::string xmlTagConfigRoot()
static const std::string xmlTagInteractions()
static const std::string xmlEventPropertyMapperID()
static const std::string xmlCameraFocalPointZ()
static Pointer New()
static Pointer New()
void SetTimeStep(int newTimeStep)
SetTimeStep Sets timesteps of all SliceNavigationControllers to given timestep.
static const std::string xmlCameraFocalPointX()
static Pointer New()
static const std::string xmlCameraFocalPointY()
static const std::string xmlRenderSizeX()
void ConnectGeometryTimeEvent(T *receiver, bool connectSendEvent=true)
mitk::DataStorage::Pointer m_DataStorage
int MapperSlotId
MapperSlotId defines which kind of mapper (e.g., 2D or 3D) shoud be used.
Manager for coordinating the rendering process.
static Pointer New()
static const std::string xmlRenderSizeY()
void AddDisplayPlaneSubTree()
AddDisplayPlaneSubTree.
static RenderingManager * GetInstance()
#define mitkThrow()
virtual mitk::VtkPropRenderer * GetRenderer()
static const std::string xmlEventPropertyViewDirection()
virtual void SetPos(unsigned int pos)
Definition: mitkStepper.h:59
RenderWindow * GetRenderWindowByDefaultViewDirection(mitk::SliceNavigationController::ViewDirection viewDirection)
GetRenderWindowByDefaultViewDirection Get a renderWindow by its default viewdirection.
static const std::string xmlTagRenderer()
void Initialize(const std::string &interactionXmlFilePath)
Initialize Internal method to initialize the renderwindow and set the datastorage.
RenderWindow * GetRenderWindowByName(const std::string &name)
GetRenderWindowByName Get renderWindow by the name of its renderer.
static const std::string xmlViewUpY()
RenderWindow * GetRenderWindow(unsigned int index)
GetRenderWindow Get renderWindow at position 'index'.
virtual void PrepareRender()
This methods contains all method neceassary before a VTK Render() call.
static const std::string xmlCameraPositionX()
static Pointer New()
void LoadInteraction()
LoadInteraction loads events from xml file.
mitkRenderWindow integrates the MITK rendering mechanism into VTK and is NOT QT dependent ...
static const std::string xmlCameraPositionY()
static const std::string xmlRenderSizeZ()
mitk::Stepper * GetTime()
Get the Stepper through the time.
static void RemoveInstance(vtkRenderWindow *renWin)
vtkRenderer * GetVtkRenderer() const
virtual void InitializeViewsByBoundingObjects(const DataStorage *)
Initializes the renderwindows by the aggregated geometry of all objects that are held in the data sto...
ViewDirection
Possible view directions, Original will uses the PlaneGeometry instances in a SlicedGeometry3D provid...
static const std::string xmlViewUpZ()
static Pointer New()
void AddNodeToStorage(mitk::DataNode::Pointer node)
AddNodeToStorage Add a node to the datastorage and perform a reinit which is necessary for rendering...
virtual bool IsValidTimeStep(TimeStepType timeStep) const =0
Test for the given time step if a geometry is availible.
InteractionTestHelper(const std::string &interactionXmlFilePath)
InteractionTestHelper set up all neseccary objects by calling Initialize.
mitk::DataStorage::Pointer GetDataStorage()
Returns the datastorage, in order to modify the data inside a rendering test.