Medical Imaging Interaction Toolkit  2018.4.99-389bf124
Medical Imaging Interaction Toolkit
mitkRenderWindowLayerController.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 // render window manager module
15 
17  : m_DataStorage(nullptr)
18 {
19  // nothing here
20 }
21 
23 {
24  if (m_DataStorage != dataStorage)
25  {
26  // set the new data storage
27  m_DataStorage = dataStorage;
28  }
29 }
30 
32 {
33  if (m_ControlledRenderer != controlledRenderer)
34  {
35  // set the new set of controlled renderer
36  m_ControlledRenderer = controlledRenderer;
37  }
38 }
39 
40 void mitk::RenderWindowLayerController::SetBaseDataNode(DataNode* dataNode, const BaseRenderer* renderer /*= nullptr*/)
41 {
42  if (nullptr == dataNode)
43  {
44  return;
45  }
46 
47  if (nullptr == renderer)
48  {
49  // set the data node as base data node in all controlled renderer
50  for (const auto& renderer : m_ControlledRenderer)
51  {
52  if (nullptr != renderer)
53  {
54  SetBaseDataNode(dataNode, renderer);
55  }
56  }
57  }
58  else
59  {
60  // get the layer stack with the base data node of the current renderer
61  RenderWindowLayerUtilities::LayerStack stackedLayers = RenderWindowLayerUtilities::GetLayerStack(m_DataStorage, renderer, true);
62  if (!stackedLayers.empty())
63  {
64  // see if base layer exists
65  RenderWindowLayerUtilities::LayerStack::iterator layerStackIterator = stackedLayers.find(RenderWindowLayerUtilities::BASE_LAYER_INDEX);
66  if (layerStackIterator != stackedLayers.end())
67  {
68  // remove the current base data node from the current renderer
69  layerStackIterator->second->GetPropertyList(renderer)->DeleteProperty("layer");
70  layerStackIterator->second->SetBoolProperty("fixedLayer", false, renderer);
71  layerStackIterator->second->SetVisibility(false, renderer);
72  }
73  }
74 
75  // "RenderWindowLayerUtilities::BASE_LAYER_INDEX" indicates the base data node --> set as new background
77  dataNode->SetBoolProperty("fixedLayer", true, renderer);
78  dataNode->SetVisibility(true, renderer);
79  dataNode->Modified();
81  }
82 }
83 
84 void mitk::RenderWindowLayerController::InsertLayerNode(DataNode* dataNode, int layer /*= RenderWindowLayerUtilities::TOP_LAYER_INDEX*/, const BaseRenderer* renderer /*= nullptr*/)
85 {
86  if (nullptr == dataNode)
87  {
88  return;
89  }
90 
91  if (nullptr == renderer)
92  {
93  // insert data node in all controlled renderer
94  for (const auto& renderer : m_ControlledRenderer)
95  {
96  if (nullptr != renderer)
97  {
98  InsertLayerNode(dataNode, layer, renderer);
99  }
100  }
101  }
102  else
103  {
105  {
106  // "RenderWindowLayerUtilities::BASE_LAYER_INDEX" indicates the base data node --> set as new background (overwrite current base node if needed)
107  SetBaseDataNode(dataNode, renderer);
108  }
109  else
110  {
111  InsertLayerNodeInternal(dataNode, layer, renderer);
112  }
113  }
114 }
115 
116 void mitk::RenderWindowLayerController::InsertLayerNodeInternal(DataNode* dataNode, int newLayer, const BaseRenderer* renderer /*= nullptr*/)
117 {
119 
120  // get the layer stack without the base node of the current renderer
121  RenderWindowLayerUtilities::LayerStack stackedLayers = RenderWindowLayerUtilities::GetLayerStack(m_DataStorage, renderer, false);
122  if (stackedLayers.empty())
123  {
124  // no layer stack for the current renderer
126  {
127  // set given layer as first layer above base layer (= 1)
128  newLayer = 1;
129  // alternatively: no layer stack for the current renderer -> insert as background node
130  //SetBaseDataNode(dataNode, renderer);
131  }
132  }
133  else
134  {
136  {
137  // get the first value (highest int-key -> topmost layer)
138  // + 1 indicates inserting the node above the topmost layer
139  newLayer = stackedLayers.begin()->first + 1;
140  }
141  else
142  {
143  MoveNodeToPosition(dataNode, newLayer, renderer);
144  return;
145  }
146  }
147  // update data storage (the "data node model")
148  dataNode->SetIntProperty("layer", newLayer, renderer);
149  dataNode->Modified();
151 }
152 
153 void mitk::RenderWindowLayerController::RemoveLayerNode(DataNode* dataNode, const BaseRenderer* renderer /*= nullptr*/)
154 {
155  if (nullptr == dataNode)
156  {
157  return;
158  }
159 
160  if (nullptr == renderer)
161  {
162  // remove data node from all controlled renderer
163  for (const auto& renderer : m_ControlledRenderer)
164  {
165  if (nullptr != renderer)
166  {
167  RemoveLayerNode(dataNode, renderer);
168  }
169  }
170  }
171  else
172  {
173  // "remove" node from the renderer list
174  dataNode->GetPropertyList(renderer)->DeleteProperty("layer");
175  dataNode->SetBoolProperty("fixedLayer", false, renderer);
176  dataNode->SetVisibility(false, renderer);
177  dataNode->Modified();
179  }
180 }
181 
182 bool mitk::RenderWindowLayerController::MoveNodeToPosition(DataNode* dataNode, int newLayer, const BaseRenderer* renderer /*= nullptr*/)
183 {
184  if (nullptr == dataNode)
185  {
186  return false;
187  }
188 
189  if (nullptr == renderer)
190  {
191  // move data node to position in all controlled renderer
192  for (const auto& renderer : m_ControlledRenderer)
193  {
194  if (nullptr != renderer)
195  {
196  MoveNodeToPosition(dataNode, newLayer, renderer);
197  // we don't store/need the returned boolean value
198  return false;
199  }
200  }
201  }
202  else
203  {
204  // get the layer stack without the base node of the current renderer
205  RenderWindowLayerUtilities::LayerStack stackedLayers = RenderWindowLayerUtilities::GetLayerStack(m_DataStorage, renderer, false);
206  if (!stackedLayers.empty())
207  {
208  // get the current layer value of the given data node
209  int currentLayer;
210  bool wasFound = dataNode->GetIntProperty("layer", currentLayer, renderer);
211  if (wasFound && currentLayer != newLayer)
212  {
213  // move the given data node to the specified layer
214  dataNode->SetIntProperty("layer", newLayer, renderer);
215 
216  int upperBound;
217  int lowerBound;
218  int step;
219  if (currentLayer < newLayer)
220  {
221  // move node up
222  upperBound = newLayer + 1;
223  lowerBound = currentLayer + 1;
224  step = -1; // move all other nodes one step down
225  }
226  else
227  {
228  upperBound = currentLayer;
229  lowerBound = newLayer;
230  step = 1; // move all other nodes one step up
231  }
232 
233  // move all other data nodes between the upper and the lower bound
234  for (auto& layer : stackedLayers)
235  {
236  if (layer.second != dataNode && layer.first < upperBound && layer.first >= lowerBound)
237  {
238  layer.second->SetIntProperty("layer", layer.first + step, renderer);
239  }
240  // else: current data node is the selected data node or
241  // was previously already above the selected data node or
242  // was previously already below the new layer position
243  }
244  dataNode->Modified();
246  return true;
247  }
248  // else: data node has no layer information or is already at the specified position
249  }
250  // else: do not work with empty layer stack
251  }
252  return false;
253 }
254 
255 bool mitk::RenderWindowLayerController::MoveNodeToFront(DataNode* dataNode, const BaseRenderer* renderer /*= nullptr*/)
256 {
257  if (nullptr == dataNode)
258  {
259  return false;
260  }
261 
262  if (nullptr == renderer)
263  {
264  // move data node to front in all controlled renderer
265  for (const auto& renderer : m_ControlledRenderer)
266  {
267  if (nullptr != renderer)
268  {
269  MoveNodeToFront(dataNode, renderer);
270  // we don't store/need the returned boolean value
271  return false;
272  }
273  }
274  }
275  else
276  {
277  // get the layer stack without the base node of the current renderer
278  RenderWindowLayerUtilities::LayerStack stackedLayers = RenderWindowLayerUtilities::GetLayerStack(m_DataStorage, renderer, false);
279  if (!stackedLayers.empty())
280  {
281  // get the first value (highest int-key -> topmost layer)
282  int topmostLayer = stackedLayers.begin()->first;
283  // get the current layer value of the given data node
284  int currentLayer;
285  bool wasFound = dataNode->GetIntProperty("layer", currentLayer, renderer);
286  if (wasFound && currentLayer < topmostLayer)
287  {
288  // move the current data node above the current topmost layer
289  dataNode->SetIntProperty("layer", topmostLayer+1, renderer);
290  dataNode->Modified();
292  return true;
293  }
294  // else: data node has no layer information or is already the topmost layer node
295  }
296  // else: do not work with empty layer stack
297  }
298  return false;
299 }
300 
301 bool mitk::RenderWindowLayerController::MoveNodeToBack(DataNode* dataNode, const BaseRenderer* renderer /*= nullptr*/)
302 {
303  if (nullptr == dataNode)
304  {
305  return false;
306  }
307 
308  if (nullptr == renderer)
309  {
310  // move data node to back in all controlled renderer
311  for (const auto& renderer : m_ControlledRenderer)
312  {
313  if (nullptr != renderer)
314  {
315  MoveNodeToBack(dataNode, renderer);
316  // we don't store/need the returned boolean value
317  return false;
318  }
319  }
320  }
321  else
322  {
323  // get the layer stack without the base node of the current renderer
324  RenderWindowLayerUtilities::LayerStack stackedLayers = RenderWindowLayerUtilities::GetLayerStack(m_DataStorage, renderer, false);
325  if (!stackedLayers.empty())
326  {
327  // get the last value (lowest int-key)
328  // cannot be the base layer as the base node was excluded by the 'GetLayerStack'-function
329  int lowermostLayer = stackedLayers.rbegin()->first;
330  // get the current layer value of the given data node
331  int currentLayer;
332  bool wasFound = dataNode->GetIntProperty("layer", currentLayer, renderer);
333  if (wasFound && currentLayer > lowermostLayer)
334  {
335  // move the current data node to the current lowermost layer
336  dataNode->SetIntProperty("layer", lowermostLayer, renderer);
337  // move all other data nodes one layer up
338  for (auto& layer : stackedLayers)
339  {
340  if (layer.second != dataNode && layer.first < currentLayer)
341  {
342  layer.second->SetIntProperty("layer", layer.first + 1, renderer);
343  }
344  // else: current data node is the selected data node or
345  // was previously already above the selected data node
346  }
347  dataNode->Modified();
349  return true;
350  }
351  // else: data node has no layer information or is already the lowermost layer node
352  }
353  // else: do not work with empty layer stack
354  }
355  return false;
356 }
357 
358 bool mitk::RenderWindowLayerController::MoveNodeUp(DataNode* dataNode, const BaseRenderer* renderer /*= nullptr*/)
359 {
360  if (nullptr == dataNode)
361  {
362  return false;
363  }
364 
365  if (nullptr == renderer)
366  {
367  // move data node down in all controlled renderer
368  for (const auto& renderer : m_ControlledRenderer)
369  {
370  if (nullptr != renderer)
371  {
372  MoveNodeUp(dataNode, renderer);
373  // we don't store/need the returned boolean value
374  return false;
375  }
376  }
377  }
378  else
379  {
380  // get the layer stack without the base node of the current renderer
381  RenderWindowLayerUtilities::LayerStack stackedLayers = RenderWindowLayerUtilities::GetLayerStack(m_DataStorage, renderer, false);
382  if (!stackedLayers.empty())
383  {
384  // get the current layer value of the given data node
385  int currentLayer;
386  bool wasFound = dataNode->GetIntProperty("layer", currentLayer, renderer);
387  if (wasFound)
388  {
389  // get the current layer in the map of stacked layers
390  RenderWindowLayerUtilities::LayerStack::const_iterator layerStackIterator = stackedLayers.find(currentLayer);
391  if (layerStackIterator != stackedLayers.end() && layerStackIterator != stackedLayers.begin())
392  {
393  // found the element in the map, at different position than 'begin' ->
394  // current node is not on the topmost layer and therefore can be moved one layer up
395  // swap the layers of the dataNode and the dataNode on the next higher layer (previous map element)
396  RenderWindowLayerUtilities::LayerStack::const_iterator prevLayerStackIterator = std::prev(layerStackIterator);
397  dataNode->SetIntProperty("layer", prevLayerStackIterator->first, renderer);
398  prevLayerStackIterator->second->SetIntProperty("layer", currentLayer, renderer);
399  dataNode->Modified();
401  return true;
402  }
403  // else: layer stack does not contain a layer with the 'currentLayer'data node or
404  // layer is already the topmost layer node
405  }
406  // else: data node has no layer information
407  }
408  // else: do not work with empty layer stack
409  }
410  return false;
411 }
412 
413 bool mitk::RenderWindowLayerController::MoveNodeDown(DataNode* dataNode, const BaseRenderer* renderer /*= nullptr*/)
414 {
415  if (nullptr == dataNode)
416  {
417  return false;
418  }
419 
420  if (nullptr == renderer)
421  {
422  // move data node up in all controlled renderer
423  for (const auto& renderer : m_ControlledRenderer)
424  {
425  if (nullptr != renderer)
426  {
427  MoveNodeDown(dataNode, renderer);
428  // we don't store/need the returned boolean value
429  return false;
430  }
431  }
432  }
433  else
434  {
435  // get the layer stack without the base node of the current renderer
436  RenderWindowLayerUtilities::LayerStack stackedLayers = RenderWindowLayerUtilities::GetLayerStack(m_DataStorage, renderer, false);
437  if (!stackedLayers.empty())
438  {
439  // get the current layer value of the given data node
440  int currentLayer;
441  bool wasFound = dataNode->GetIntProperty("layer", currentLayer, renderer);
442  if (wasFound)
443  {
444  // get the current layer in the map of stacked layers
445  RenderWindowLayerUtilities::LayerStack::const_iterator layerStackIterator = stackedLayers.find(currentLayer);
446  if (layerStackIterator != stackedLayers.end())
447  {
448  // found the element in the map ...
449  RenderWindowLayerUtilities::LayerStack::const_iterator nextLayerStackIterator = std::next(layerStackIterator);
450  if (nextLayerStackIterator != stackedLayers.end())
451  {
452  // ... and found a successor ->
453  // current node is not on the lowermost layer and therefore can be moved one layer down
454  // swap the layers of the dataNode and the dataNode on the next lower layer (next map element)
455  dataNode->SetIntProperty("layer", nextLayerStackIterator->first, renderer);
456  nextLayerStackIterator->second->SetIntProperty("layer", currentLayer, renderer);
457  dataNode->Modified();
459  return true;
460  }
461  // else: data node is already the lowermost layer node
462  }
463  // else: layer stack does not contain a layer with the 'currentLayer'
464  }
465  // else: data node has no layer information
466  }
467  // else: do not work with empty layer stack
468  }
469  return false;
470 }
471 
472 void mitk::RenderWindowLayerController::SetVisibilityOfDataNode(bool visibility, DataNode* dataNode, const BaseRenderer* renderer /*=nullptr*/)
473 {
474  if (nullptr == dataNode)
475  {
476  return;
477  }
478 
479  if (nullptr == renderer)
480  {
481  // set visibility of data node in all controlled renderer
482  for (const auto& renderer : m_ControlledRenderer)
483  {
484  if (nullptr != renderer)
485  {
486  SetVisibilityOfDataNode(visibility, dataNode, renderer);
487  }
488  }
489  }
490  else
491  {
492  dataNode->SetVisibility(visibility, renderer);
493  dataNode->Modified();
495  }
496 }
497 
499 {
500  if (nullptr == dataNode)
501  {
502  return;
503  }
504 
505  for (const auto& renderer : m_ControlledRenderer)
506  {
507  if (nullptr != renderer)
508  {
509  dataNode->GetPropertyList(renderer)->SetBoolProperty("visible", false);
510  }
511  }
512 
514 }
515 
516 void mitk::RenderWindowLayerController::ResetRenderer(bool onlyVisibility /*= true*/, const BaseRenderer* renderer /*= nullptr*/)
517 {
518  if (nullptr == renderer)
519  {
520  // reset all controlled renderer
521  for (const auto& renderer : m_ControlledRenderer)
522  {
523  if (nullptr != renderer)
524  {
525  ResetRenderer(onlyVisibility, renderer);
526  }
527  }
528  }
529  else
530  {
531  // get the layer stack with the base node of the current renderer
532  RenderWindowLayerUtilities::LayerStack stackedLayers = RenderWindowLayerUtilities::GetLayerStack(m_DataStorage, renderer, true);
533  if (!stackedLayers.empty())
534  {
535  for (const auto& layer : stackedLayers)
536  {
537  int layerLevel;
538  layer.second->GetIntProperty("layer", layerLevel, renderer);
540  {
541  // set base data node visibility to true
542  layer.second->SetVisibility(true, renderer);
543  }
544  else
545  {
546  // set visibility of all other data nodes to false
547  layer.second->SetVisibility(false, renderer);
548 
549  // modify layer node
550  if (!onlyVisibility)
551  {
552  // clear mode: additionally remove layer node from current renderer
553  layer.second->GetPropertyList(renderer)->DeleteProperty("layer");
554  layer.second->SetBoolProperty("fixedLayer", false, renderer);
555  }
556  }
557  layer.second->Modified();
558  }
559 
561  }
562  }
563 }
void SetIntProperty(const char *propertyKey, int intValue, const mitk::BaseRenderer *renderer=nullptr)
Convenience method for setting int properties (instances of IntProperty)
void SetBoolProperty(const char *propertyKey, bool boolValue)
Convenience method to set the value of a BoolProperty.
void SetVisibilityOfDataNode(bool visiblity, DataNode *dataNode, const BaseRenderer *renderer=nullptr)
Set the visibility of the given data node for the given renderer.
MITKRENDERWINDOWMANAGER_EXPORT void SetRenderWindowProperties(mitk::DataNode *dataNode, const BaseRenderer *renderer)
Set renderer-specific properties to mark a data node as &#39;managed by the specific renderer&#39;. In order for a renderer to manage a data node, the &#39;fixedLayer&#39; property has to be set for the given renderer. Additionally, the &#39;visible&#39; and the &#39;layer&#39; property are set and allow to individually render a set of nodes with a specific renderer. The last two mentioned properties are set so that they initially have the same value as the corresponding global property.
void SetVisibility(bool visible, const mitk::BaseRenderer *renderer=nullptr, const char *propertyKey="visible")
Convenience method for setting visibility properties (instances of BoolProperty)
void InsertLayerNode(DataNode *dataNode, int layer=RenderWindowLayerUtilities::TOP_LAYER_INDEX, const BaseRenderer *renderer=nullptr)
Insert the given data node at the specified layer for the given renderer.
Organizes the rendering process.
void ResetRenderer(bool onlyVisibility=true, const BaseRenderer *renderer=nullptr)
Reset the given render window: If "onlyVisibility = true": set all data nodes for the given render wi...
bool GetIntProperty(const char *propertyKey, int &intValue, const mitk::BaseRenderer *renderer=nullptr) const
Convenience access method for int properties (instances of IntProperty)
bool DeleteProperty(const std::string &propertyKey)
Remove a property from the list/map.
void SetBaseDataNode(DataNode *dataNode, const BaseRenderer *renderer=nullptr)
Set the given node as the base node of the given renderer.
std::vector< BaseRenderer * > RendererVector
bool MoveNodeToBack(DataNode *dataNode, const BaseRenderer *renderer=nullptr)
Set the node in the given renderer as the lowermost layer. This will change only the "layer" property...
mitk::DataStorage::Pointer m_DataStorage
static RenderingManager * GetInstance()
MITKRENDERWINDOWMANAGER_EXPORT LayerStack GetLayerStack(const DataStorage *dataStorage, const BaseRenderer *renderer, bool withBaseNode)
Return the stack of layers of the given renderer as std::map<int, DataNode::Pointer>, which guarantees ordering of the layers. Stacked layers are only included if they have their "fixedLayer" property set to true and their "layer" property set.
void RemoveLayerNode(DataNode *dataNode, const BaseRenderer *renderer=nullptr)
Remove the given data node for the given renderer.
bool MoveNodeToPosition(DataNode *dataNode, int newLayer, const BaseRenderer *renderer=nullptr)
Move the data node to the given layer. This will change only the "layer" property.
void SetBoolProperty(const char *propertyKey, bool boolValue, const mitk::BaseRenderer *renderer=nullptr)
Convenience method for setting boolean properties (instances of BoolProperty)
void SetControlledRenderer(RenderWindowLayerUtilities::RendererVector controlledRenderer)
Set the controlled base renderer.
void RequestUpdate(vtkRenderWindow *renderWindow)
mitk::PropertyList * GetPropertyList(const mitk::BaseRenderer *renderer=nullptr) const
Get the PropertyList of the renderer. If renderer is nullptr, the BaseRenderer-independent PropertyLi...
vtkRenderWindow * GetRenderWindow() const
Access the RenderWindow into which this renderer renders.
void HideDataNodeInAllRenderer(const DataNode *dataNode)
Hide the given data node by setting the "visible" property of the data node for all controlled render...
bool MoveNodeToFront(DataNode *dataNode, const BaseRenderer *renderer=nullptr)
Set the node in the given renderer as the topmost layer. This will change only the "layer" property...
std::map< int, DataNode::Pointer, std::greater< int > > LayerStack
bool MoveNodeDown(DataNode *dataNode, const BaseRenderer *renderer=nullptr)
Move the node in the given renderer one layer up. This will change only the "layer" property...
void SetDataStorage(DataStorage::Pointer dataStorage)
Set the data storage on which to work.
bool MoveNodeUp(DataNode *dataNode, const BaseRenderer *renderer=nullptr)
Move the node in the given renderer one layer down. This will change only the "layer" property...
void RequestUpdateAll(RequestType type=REQUEST_UPDATE_ALL)
Class for nodes of the DataTree.
Definition: mitkDataNode.h:57