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