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
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.