# Display text on 3D stereoscopic views

**URL:** <https://discourse.slicer.org/t/display-text-on-3d-stereoscopic-views/37807>\
**Category:** Development\
**Tags:** rendering\
**Created:** [August 9, 2024, 9:27pm UTC](https://discourse.slicer.org/t/display-text-on-3d-stereoscopic-views/37807 "2024-08-09T21:27:19Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Laura\_A](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/laura_a/32/77560_2.png) [@Laura\_A](https://discourse.slicer.org/u/Laura_A)\
**Post date:** [August 9, 2024, 9:27pm UTC](https://discourse.slicer.org/t/display-text-on-3d-stereoscopic-views/37807/1 "2024-08-09T21:27:19Z")

</div>

How can I display text in pop-up 3D views?

Steps I follow:

1. I create and show a right and left view with the following code:

```auto
layoutName = "LeftEyeView"
layoutLabel = "Left Eye"
layoutColor = [1.0, 1.0, 0.0]

viewOwnerNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLScriptedModuleNode")
                    
# Create MRML node
viewLogic = slicer.vtkMRMLViewLogic()
viewLogic.SetMRMLScene(slicer.mrmlScene)
            
# Left node
viewNodeLeft = viewLogic.AddViewNode(layoutName)
viewNodeLeft.SetLayoutLabel(layoutLabel)
viewNodeLeft.SetLayoutColor(layoutColor)
viewNodeLeft.SetAndObserveParentLayoutNodeID(viewOwnerNode.GetID())
viewNodeLeft.SetStereoType(3)# Quadbuffer Stereo layout 1 is left eye (dont know why)

# Create widget
self.viewWidgetLeft = slicer.qMRMLThreeDWidget()
self.viewWidgetLeft.setMRMLScene(slicer.mrmlScene)
self.viewWidgetLeft.setMRMLViewNode(viewNodeLeft)      
print("Left widget created")
self.viewWidgetLeft.show()       

```

1. I display some text on the 3D view from the Slicer UI

```auto
# Get the 3D view renderer
self.layoutManager = slicer.app.layoutManager()
self.threeDView = self.layoutManager.threeDWidget(0).threeDView()
self.renderer = self.threeDView.renderWindow().GetRenderers().GetFirstRenderer()

# Create a text actor to display the text
self.textActor = vtk.vtkTextActor()
# Position the text actor in the corner
self.textActor.GetPositionCoordinate().SetCoordinateSystemToNormalizedViewport()
self.textActor.SetPosition(0.8, 0.9) 

# Add the text actor to the renderer
self.renderer.AddActor2D(self.textActor )

```

1. In order to add the text in the created left and right views, I need to access those views. Using “layoutManager.threeDWidget( **–viewNumber–** ).threeDView()” does not let me display any text in those views.

The view nodes I actually have are:  
View1 (from the UI): vtkMRMLViewNode1  
View (left eye): vtkMRMLViewNodeLeftEyeView  
View\_1 (right eye): vtkMRMLViewNodeRightEyeView

How can I access the render windows of those views in order to be able to display text in those?

---

<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 10, 2024, 1:18pm UTC](https://discourse.slicer.org/t/display-text-on-3d-stereoscopic-views/37807/2 "2024-08-10T13:18:39Z")

</div>

The layout manager only manages the views in the layout. Since _you_ create the other views and widgets you can directly use thise objects.

Note that you cannot use 2D actor to display anything in a stereo display, because inconsistent stereo parallax and occlusion (this most often causes double vision for the user). You can use 3D text actors instead.

---

<div class="post-metadata">

**Author:** ![Laura\_A](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/laura_a/32/77560_2.png) [@Laura\_A](https://discourse.slicer.org/u/Laura_A)\
**Post date:** [August 12, 2024, 2:22pm UTC](https://discourse.slicer.org/t/display-text-on-3d-stereoscopic-views/37807/3 "2024-08-12T14:22:16Z")

</div>

Thanks a lot for the quick answer and explanation!

I created a 3D actor to display the text, but it doesn’t display it in the other views:

 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/5/e/5e1f1ddcd457bce22ee6a6aa5fa366c64b21c51f.png)

the code I used:  
renderer = slicer.app.layoutManager().threeDWidget( **0** ).threeDView().renderWindow().GetRenderers().GetFirstRenderer()  
text\_actor = vtk.vtkTextActor3D()  
renderer.AddActor(text\_actor)

Also, when using threeDWidget(1) or (2), there was nothing displayed in the right and left views.

Therefore, as you suggested, I tried to use the views I create directly instead of retrieving them from the layout manager. However, I can only get the camera and the views, and there is no method for adding (3D) actors that way. Neither with the “viewOwnerNode” that I create.

Is there any other way to access the render windows of the nodes I create?

---

<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 12, 2024, 11:04pm UTC](https://discourse.slicer.org/t/display-text-on-3d-stereoscopic-views/37807/4 "2024-08-12T23:04:06Z")

</div>

> [@Laura\_A](#):
>
> I created a 3D actor to display the text, but it doesn’t display it in the other views:

You directly access the renderer by using low-level calls. If you add an actor in a view, it will be only added in that view. If you want to add an object that is displayed in all views automatically then you can create a polydata from text using [vtkTextSource](https://vtk.org/doc/nightly/html/classvtkTextSource.html) and display it using a model node.

> [@Laura\_A](#):
>
> when using threeDWidget(1) or (2), there was nothing displayed in the right and left views.

The layout manager only manages the views in the layout. The views that are outside the view layout are inaccessible for the layout manager, but it is not a problem at all, because [_you_ create all these other views and widgets](https://slicer.readthedocs.io/en/latest/developer_guide/script_repository.html#show-a-3d-view-outside-the-view-layout) and so you can directly use these objects. For example, you can get the renderer from the view widget you created:

```python
renderer = viewWidget.threeDView().renderWindow().GetRenderers().GetFirstRenderer()

```
