# Add an actor (vtkCubeAxesActor) to the scene in C++

**URL:** <https://discourse.slicer.org/t/add-an-actor-vtkcubeaxesactor-to-the-scene-in-c/19294>\
**Category:** Development\
**Created:** [August 22, 2021, 12:28am UTC](https://discourse.slicer.org/t/add-an-actor-vtkcubeaxesactor-to-the-scene-in-c/19294 "2021-08-22T00:28:48Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![keri](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/keri/32/11618_2.png) [@keri](https://discourse.slicer.org/u/keri)\
**Post date:** [August 22, 2021, 12:28am UTC](https://discourse.slicer.org/t/add-an-actor-vtkcubeaxesactor-to-the-scene-in-c/19294/1 "2021-08-22T00:28:48Z")

</div>

Hi,

I have some understanding how to add `vtkObject` inherited objects as described [here](https://slicer.readthedocs.io/en/latest/developer_guide/mrml_overview.html#mrml-nodes) via MRML nodes but I can’t find a way to add [vtkCubeAxesActor](https://kitware.github.io/vtk-examples/site/Cxx/Visualization/CubeAxesActor/) (and in general `vtkActor`).

Though I have found some information on that in [script repository](https://slicer.readthedocs.io/en/latest/developer_guide/script_repository.html#access-vtk-actor-properties) but when I by analogy do:

```cpp
  vtkMRMLAbstractDisplayableManager* modelDisplayableManager =
      LayoutManager->threeDWidget(0)
          ->threeDView()
          ->displayableManagerByClassName("vtkMRMLModelDisplayableManager");

```

I cannot somehow cast `vtkMRMLAbstractDisplayableManager` to `vtkMRMLModelDisplayableManager` as there is no `vtkMRMLModelDisplayableManager.h` header (neither there is `vtkMRMLAbstractDisplayableManager.h`).

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [August 22, 2021, 4:35am UTC](https://discourse.slicer.org/t/add-an-actor-vtkcubeaxesactor-to-the-scene-in-c/19294/2 "2021-08-22T04:35:55Z")

</div>

Slicer uses `vtkMRML...DisplayableManager` classes to create actors and add them to renderers. So, if you want to add actors that none of the existing displayable managers support then you need to add your own displayable manager and you may also add MRML classew (to store data and display options in the scene).

What would you like to use a cube axis actor for? If you just want to display orientation then you can enable orientation marker display, which can use a box or arrows axis actor or an arbitrary 3D model (by default a human body). You can specify the style and size and customize the axis letters in the view node.

---

<div class="post-metadata">

**Author:** ![keri](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/keri/32/11618_2.png) [@keri](https://discourse.slicer.org/u/keri)\
**Post date:** [August 22, 2021, 11:57am UTC](https://discourse.slicer.org/t/add-an-actor-vtkcubeaxesactor-to-the-scene-in-c/19294/3 "2021-08-22T11:57:59Z")

</div>

> [@lassoan](#):
>
> What would you like to use a cube axis actor for? If you just want to display orientation then you can enable orientation marker display, which can use a box or arrows axis actor or an arbitrary 3D model (by default a human body). You can specify the style and size and customize the axis letters in the view node.

I wanted to display coordinates in 3d view. Not only the directions (wich is good by the way) but also XYZ values, like scales. I work in geographic coordinates so I would like to check correctness of my code. Usually the main object should be `vtkImageData` and display scales around it would be fine. Probably there are another options to achieve my goal?

If I create `vtkMRMLCubeAxesActorDisplayableManager` (I guess I would need to inherit from some base class) and create a button on 3d view toolbar that shows/hides `vtkCubeAxesActor` around chosen object would that be enough? Or the task is more difficult than I think?

---

<div class="post-metadata">

**Author:** ![keri](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/keri/32/11618_2.png) [@keri](https://discourse.slicer.org/u/keri)\
**Post date:** [August 22, 2021, 3:11pm UTC](https://discourse.slicer.org/t/add-an-actor-vtkcubeaxesactor-to-the-scene-in-c/19294/4 "2021-08-22T15:11:28Z")

</div>

With the [recent knowlegde about vtkCubeAxesActor transform problem](https://discourse.slicer.org/t/independent-zoom-along-different-axes/19263/14) I still want to have something like visualized coordinate system in 3D view but now I’m not much sticked to the `vtkCubeAxesActor`. Probably there are some options to achieve the goal without using `vtkCubeAxesActor`?  
Maybe I could create 8 points at `vtkImageData`'s corners and display coordinates only at these points…

Also is it ok that if I add `vtkCubeAxesActor` then the interaction perfomance noticeably decreases? Any movements becomes much slower

---

<div class="post-metadata">

**Author:** ![keri](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/keri/32/11618_2.png) [@keri](https://discourse.slicer.org/u/keri)\
**Post date:** [August 24, 2021, 1:07am UTC](https://discourse.slicer.org/t/add-an-actor-vtkcubeaxesactor-to-the-scene-in-c/19294/5 "2021-08-24T01:07:08Z")

</div>

I’m getting known with `DisplayableManager`.  
From SlicerAstro I took `vtkMRMLAstroTwoDAxesDisplayableManager` as an example and simplified it.  
According to the [documentation](https://www.slicer.org/wiki/Documentation/Nightly/Developers/DisplayableManagers) and SlicerAstro too I need to register my disp manager:

```cpp
void qSlicerStackLoadModule::setup()
{
  this->Superclass::setup();
  ...
  vtkMRMLSliceViewDisplayableManagerFactory::GetInstance()->
    RegisterDisplayableManager("vtkMRMLColadaCubeAxesDisplayableManager");
}

```

But I noticed that generated `vtkSlicerStackLoadModuleMRMLDisplayableManagerObjectFactory.cxx` does some checks and the debugging helped me to understand that `bool vtkMRMLDisplayableManagerGroup::IsADisplayableManager(const char* displayableManagerName)` returns false:

```cpp
bool vtkMRMLDisplayableManagerGroup
::IsADisplayableManager(const char* displayableManagerName)
{
  // Check if displayableManagerName is a valid displayable manager
  vtkSmartPointer<vtkObject> objectSmartPointer;
  objectSmartPointer.TakeReference(vtkObjectFactory::CreateInstance(displayableManagerName));
  if (objectSmartPointer.GetPointer() &&
      objectSmartPointer->IsA("vtkMRMLAbstractDisplayableManager"))
    {
    return true; // the execution can't reach there as `objectSmartPointer` is NULL
    }
#ifdef VTK_DEBUG_LEAKS
  vtkDebugLeaks::DestructClass(displayableManagerName);
#endif
#ifdef MRMLDisplayableManager_USE_PYTHON
  // Check if vtkClassOrScriptName is a python script
  if (std::string(displayableManagerName).find(".py") != std::string::npos)
    {
    // TODO Make sure the file exists ...
    return true;
    }
#endif
  return false;
}

```

The var `displayableManagerName` is `vtkMRMLColadaCubeAxesDisplayableManager`.  
It seems that I my disp manager doesn’t follow some conditions of a disp manager but I don’t understand what are these conditions…

It is late night and tomorrow I will try to investigate the problem more precisely. But probably you have experience and already know where to look…

Here is the header file of my disp manager:

```cpp
#ifndef __vtkMRMLColadaCubeAxesDisplayableManager_h
#define __vtkMRMLColadaCubeAxesDisplayableManager_h

// MRMLDisplayableManager includes
#include "vtkMRMLAbstractDisplayableManager.h"
#include <vtkSlicerStackLoadModuleMRMLDisplayableManagerExport.h>

// Qt declaration
class QColor;

/// \brief Displayable manager that displays 2D WCS axes in 2D view
class VTK_MRMLDISPLAYABLEMANAGER_COLADA_EXPORT vtkMRMLColadaCubeAxesDisplayableManager
  : public vtkMRMLAbstractDisplayableManager
{
  friend class vtkColadaCubeAxesRendererUpdateObserver;

public:
  static vtkMRMLColadaCubeAxesDisplayableManager* New();
  vtkTypeMacro(vtkMRMLColadaCubeAxesDisplayableManager,vtkMRMLAbstractDisplayableManager);
  void PrintSelf(ostream& os, vtkIndent indent) override;

  /// Get vtkMarkerRenderer
  vtkRenderer* vtkMarkerRenderer();

  /// Set annotation color
  void SetAnnotationsColor(double red,
                           double green,
                           double blue);

  /// Set font style
  void SetAnnotationsFontStyle(const char* font);

  /// Set font size
  void SetAnnotationsFontSize(int size);

protected:

  vtkMRMLColadaCubeAxesDisplayableManager();
  virtual ~vtkMRMLColadaCubeAxesDisplayableManager();

  /// Observe the View node and initialize the renderer accordingly.
  virtual void Create() override;

  /// Called each time the view node is modified.
  /// Internally update the renderer from the view node
  /// \sa UpdateFromMRMLViewNode()
  virtual void OnMRMLDisplayableNodeModifiedEvent(vtkObject* caller) override;

  /// Update the renderer from the view node properties.
  void UpdateFromViewNode();

  /// Update the renderer based on the master renderer (the one that the orientation marker follows)
  void UpdateFromRenderer();

private:

  vtkMRMLColadaCubeAxesDisplayableManager(const vtkMRMLColadaCubeAxesDisplayableManager&);// Not implemented
  void operator=(const vtkMRMLColadaCubeAxesDisplayableManager&); // Not Implemented

  class vtkInternal;
  vtkInternal * Internal;
};

#endif

```

---

<div class="post-metadata">

**Author:** ![keri](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/keri/32/11618_2.png) [@keri](https://discourse.slicer.org/u/keri)\
**Post date:** [August 24, 2021, 1:35pm UTC](https://discourse.slicer.org/t/add-an-actor-vtkcubeaxesactor-to-the-scene-in-c/19294/6 "2021-08-24T13:35:30Z")

</div>

I have found the problem.  
When VTK iterates over the factories (in `vtkObject* vtkObjectFactory::CreateInstance(const char* vtkclassname, bool)`), none of them is able to create instance of `vtkMRMLColadaCubeAxesDisplayableManager`.

The solution I have not found yet…

---

<div class="post-metadata">

**Author:** ![keri](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/keri/32/11618_2.png) [@keri](https://discourse.slicer.org/u/keri)\
**Post date:** [August 24, 2021, 6:25pm UTC](https://discourse.slicer.org/t/add-an-actor-vtkcubeaxesactor-to-the-scene-in-c/19294/7 "2021-08-24T18:25:38Z")

</div>

I noticed that `vtkSlicerStackLoadModuleMRMLDisplayableManagerObjectFactory` object factory is not registered even I use `SlicerConfigureDisplayableManagerObjectFactory(...)` cmake macro and there is `vtkSlicerStackLoadModuleMRMLDisplayableManagerObjectFactory.h` and `vtkSlicerStackLoadModuleMRMLDisplayableManagerObjectFactory.cxx` generated files in build dir.

---

<div class="post-metadata">

**Author:** ![keri](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/keri/32/11618_2.png) [@keri](https://discourse.slicer.org/u/keri)\
**Post date:** [August 25, 2021, 12:59pm UTC](https://discourse.slicer.org/t/add-an-actor-vtkcubeaxesactor-to-the-scene-in-c/19294/8 "2021-08-25T12:59:43Z")

</div>

Finally I have found my drawback. I should have been put these two lines of code:

```cpp
// DisplayableManager initialization
#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkSlicerStackLoadModuleMRMLDisplayableManager)

```

to the `qSlicer${MODULE_NAME}Module.cxx`.  
Now both `...DisplayableManagerObjectFactory` and `...DisplayableManager` are registered.

**As a summary to register `DisplayableManager` I needed:**

- copy `MRMLDM` folder from any built-in Slicer module (I used `Transforms` module) to my module and customize `CMakeLists.txt` (and of course customize `.cxx` and `.h` files);
- add this MRMLDM target to `MODULE_TARGET_LIBRARIES` of the main module `CMakeLists.txt`;

and in `qSlicer...Module.cxx`:

- #include “vtkMRMLSliceViewDisplayableManagerFactory.h” // for registering Disp Manager in SliceView
- #include “vtkMRMLThreeDViewDisplayableManagerFactory.h” // for registering Disp Manager in Three D view
- #include \<vtkAutoInit.h\>
- VTK\_MODULE\_INIT(…DisplayableManager) // without this the `...ObjectFactory` won’t be registered

in `setup()` method:

- bool val = vtkMRMLThreeDViewDisplayableManagerFactory::GetInstance()-\>RegisterDisplayableManager("…DisplayableManager");

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [August 25, 2021, 3:18pm UTC](https://discourse.slicer.org/t/add-an-actor-vtkcubeaxesactor-to-the-scene-in-c/19294/9 "2021-08-25T15:18:09Z")

</div>

Thank you for sharing your progress and solution. In general, it is a good idea to clone an existing working module or component and modify it.

VTK9’s build system became really complicated, so you need to do “magic” things like these VTK\_MODULE\_INIT macros (magic = more complicated than most people, including myself, would want to spend time with to understand).

---

<div class="post-metadata">

**Author:** ![keri](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/keri/32/11618_2.png) [@keri](https://discourse.slicer.org/u/keri)\
**Post date:** [August 28, 2021, 1:13am UTC](https://discourse.slicer.org/t/add-an-actor-vtkcubeaxesactor-to-the-scene-in-c/19294/10 "2021-08-28T01:13:36Z")

</div>

I need now to get current node (the last node the user interacted with and that is displayed) and create around it `vtkCubeAxesActor`. Thus I need to retrieve bounds from the node.

To achieve that I think I could do something like (in class inherited from `vtkMRMLAbstractThreeDViewDisplayableManager`):

```cpp
  vtkMRMLVolumeNode* volumeNode = vtkMRMLVolumeNode::SafeDownCast(GetSelectionNode()); // this gives me an error 
  if (!volumeNode)
    return;
  
  double bounds[6];
  volumeNode->GetBounds(bounds);

```

but I get the error when I’m trying to downcast:

`error: C2440: 'initializing': cannot convert from 'vtkObject *' to 'T *' with [T=vtkMRMLVolumeNode]`

I have looked to other modules and it seems they do almost exactly the same for example in  
`Slicer\Modules\Loadable\VolumeRendering\MRMLDM\vtkMRMLVolumeRenderingDisplayableManager.cxx`  
line 503  
`vtkMRMLVolumeNode* volumeNode = vtkMRMLVolumeNode::SafeDownCast( displayNode->GetDisplayableNode());`.

---

<div class="post-metadata">

**Author:** ![keri](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/keri/32/11618_2.png) [@keri](https://discourse.slicer.org/u/keri)\
**Post date:** [October 14, 2021, 3:23pm UTC](https://discourse.slicer.org/t/add-an-actor-vtkcubeaxesactor-to-the-scene-in-c/19294/11 "2021-10-14T15:23:49Z")

</div>

Hi,

Is there any difference of developping custom node that adds some `vtkActor` (`vtkCubeAxesActor`) to the scene and node that adds objects like volume, polydata, lines, points etc…?

As I know `vtkActor` should be added directly to renderer, would `Scene->addNode(actorNode)` work properly in this case?

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [October 17, 2021, 9:18pm UTC](https://discourse.slicer.org/t/add-an-actor-vtkcubeaxesactor-to-the-scene-in-c/19294/12 "2021-10-17T21:18:19Z")

</div>

To add an actor to the renderer, you need to create a new displayable manager class. Responsibility of this class is to observe the MRML scene and add actors to the renderer accordingly. Usually it adds one actor per display node. You register the new displayable manager class in the the displayable manager factory so that the layout manager can add it to each created view.

---

<div class="post-metadata">

**Author:** ![keri](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/keri/32/11618_2.png) [@keri](https://discourse.slicer.org/u/keri)\
**Post date:** [October 17, 2021, 9:54pm UTC](https://discourse.slicer.org/t/add-an-actor-vtkcubeaxesactor-to-the-scene-in-c/19294/13 "2021-10-17T21:54:02Z")

</div>

Thank you, this is the way how I implemented it. It works.
