Mayavi: Mayavi off screen rendering not working for VTK 7.1.0

Created on 18 Jan 2017  ·  21Comments  ·  Source: enthought/mayavi

I use vtk with the MesaOS driver as I want to run the rendering as part of a jupyter notebook in headless mode, some more details to the package configuration can be found here:
https://github.com/conda-forge/vtk-feedstock/issues/20

When I use the VTK off screen example it is working fine:

#! ./local/bin/python

from vtk import (vtkSphereSource, vtkPolyDataMapper, vtkActor, vtkRenderer,
        vtkRenderWindow, vtkWindowToImageFilter, vtkPNGWriter)

sphereSource = vtkSphereSource()
mapper = vtkPolyDataMapper()
mapper.SetInputConnection(sphereSource.GetOutputPort())

actor = vtkActor()
actor.SetMapper(mapper)

renderer = vtkRenderer()
renderWindow = vtkRenderWindow()
renderWindow.SetOffScreenRendering(1)
renderWindow.AddRenderer(renderer)

renderer.AddActor(actor)
renderer.SetBackground(1, 1, 1)

renderWindow.Render()

windowToImageFilter = vtkWindowToImageFilter()
windowToImageFilter.SetInput(renderWindow)
windowToImageFilter.Update()

writer = vtkPNGWriter()
writer.SetFileName("sphere.png")
writer.SetInputConnection(windowToImageFilter.GetOutputPort())
writer.Write()

But when I test the mayavi off screen example, it is not working:

# Author: Prabhu Ramachandran <[email protected]>
# Copyright (c) 2007, Enthought, Inc.
# License: BSD Style.

from os.path import join, abspath, dirname

# The offscreen Engine.
from mayavi.api import OffScreenEngine

# Usual MayaVi imports
from mayavi.scripts.util import get_data_dir
from mayavi.sources.api import VTKXMLFileReader
from mayavi.modules.api import Outline, ScalarCutPlane, Streamline


def main():
    # Create the MayaVi offscreen engine and start it.
    e = OffScreenEngine()
    # Starting the engine registers the engine with the registry and
    # notifies others that the engine is ready.
    e.start()

    # Create a new scene.
    win = e.new_scene()

    # Now setup a normal MayaVi pipeline.
    src = VTKXMLFileReader()
    src.initialize(join(get_data_dir(dirname(abspath(__file__))),
                        'fire_ug.vtu'))
    e.add_source(src)
    e.add_module(Outline())
    e.add_module(ScalarCutPlane())
    e.add_module(Streamline())
    win.scene.isometric_view()
    # Change the size argument to anything you want.
    win.scene.save('offscreen.png', size=(800, 800))


if __name__ == '__main__':
    main()

The error message I get is:

ERROR: In ../Rendering/OpenGL2/vtkXOpenGLRenderWindow.cxx, line 301
vtkXOpenGLRenderWindow (0x30ced20): bad X server connection. DISPLAY=Aborted

So to me it seems like the off screen initialisation is not correctly forwarded to VTK. Unfortunately I was unable to locate the initialisation of VTK inside mayavi myself. To me it seems to be happening in tvtk_access.py, still I do not see an option to force offscreen rendering directly.

Most helpful comment

I had quite a similar problem when using Mayavi in a Jupyter-Notebook provided by a remote Jupyter-Hub server. The problem was that that there is no X Server is running.

I solved it with installing xvfbwrapper and the Xvfb back-end. Before doing anything with mayavi start a Display.

Example

#The following 3 lines must be before doing anything with mayavi (even importing)
from xvfbwrapper import Xvfb
vdisplay = Xvfb(width=1920, height=1080)
vdisplay.start()

from mayavi import mlab
mlab.init_notebook()
s = mlab.test_plot3d()
s

If there is no more elegant way, I think it would be good to mention this in the manual.

All 21 comments

I found that by setting ETS_TOOLKIT='null' I could reproduce this error using:

>>> from mayavi import mlab
>>> mlab.options.offscreen = True
>>> mlab.test_plot3d()
ERROR: In ../Rendering/OpenGL2/vtkXOpenGLRenderWindow.cxx, line 301
vtkXOpenGLRenderWindow (0x2e027d0): bad X server connection. DISPLAY=Aborted (core dumped)

If ETS_TOOLKIT='null' is not set, not even the import works. So for the moment the script above fails when I try to create a scene new_scene()

@jan-janssen -- Can you please test with latest master, it should be fixed now. You will still need the export ETS_TOOLKIT=null but the rest should work now.

I have tested this using the osmesa conda-forge vtk packages and I can't make it work without an X server. I think I have the env setup properly.

What I did was:

$ export ETS_TOOLKIT='null'
$ conda create -n mayavi_osmesa -c conda-forge mesalib pyqt numpy vtk
$ pip install git+https://github.com/enthought/mayavi
$ python -c "from mayavi import mlab; mlab.options.offscreen=True; mlab.test_plot3d(); mlab.savefig('test.png')"
ERROR: In ../Rendering/OpenGL2/vtkXOpenGLRenderWindow.cxx, line 445
vtkXOpenGLRenderWindow (0x1c58c80): bad X server connection. DISPLAY=Aborted (core dumped)

ok actually the pure VTK example given in the OP dosen't work either, so I assume there is something wrong with my env. I get the same thing with a straight pip install git+https://github.com/enthought/mayavi so I am assuming I am missing something in vtk somewhere.

Thanks for testing, can you check if the installed VTK has vtkOSOpenGLRenderWindow, i.e.
import vtk; print(hasattr(vtk, 'vtkOSOpenGLRenderWindow')). If it doesn't, VTK was probably not built with osmesa support. If it does, I will need to investigate carefully.

It does not have that. I don't suppose you know what controls if that exists or not?!

When VTK is built you need to set VTK_OPENGL_HAS_OSMESA to ON.

hmmm, as far as I can tell the conda-forge osmesa package should do that. I will go open an issue there.

I think newer mesa releases do not allow both mesa and osmesa so recent VTK releases may automatically turn off osmesa when vtk_use_x is turned on. But I am not entirely sure about this as many things could have changed ...

If possible could you try with an older version like VTK-7.x or whenever this was known to work?

I'm having the same error message on Ubuntu 18, vtk 8.1.2, mayavi 4.6.2

I'm also having this issue with mayavi. Did anyone find any solution? I'm having this issue when using mayavi in a server, although I have the display being forwarded to my local computer.

I had quite a similar problem when using Mayavi in a Jupyter-Notebook provided by a remote Jupyter-Hub server. The problem was that that there is no X Server is running.

I solved it with installing xvfbwrapper and the Xvfb back-end. Before doing anything with mayavi start a Display.

Example

#The following 3 lines must be before doing anything with mayavi (even importing)
from xvfbwrapper import Xvfb
vdisplay = Xvfb(width=1920, height=1080)
vdisplay.start()

from mayavi import mlab
mlab.init_notebook()
s = mlab.test_plot3d()
s

If there is no more elegant way, I think it would be good to mention this in the manual.

@max9111 do you remember doing anything else? I tried your code after installing xvfbwrapper. But after ssh'ing to my server using the -X flag, I still get the error:

ERROR: In ../Rendering/OpenGL2/vtkXOpenGLRenderWindow.cxx, line 606
vtkXOpenGLRenderWindow (0x55b43e61d590): Cannot create GLX context. Aborting.

@tjiagoM Maybe you have forgotten to install xfb itself (sudo apt-get install xvfb)?

@max9111 oh, no, initially I made that mistake but they would throw an error saying that no xvfb was found/active (or something similar)

@max9111 I'm struggling with the same set-up, mayavi on a remote jupyterhub. Do you have a sample docker image used by the hub? I tried using xvfbwrapper as you suggested but it didn't do the trick for me. Thanks in advance!

@mirestrepo
Unfortunately don't have a docker image.

My setup is:

  • A virtual Machine running on Kubuntu 18.04 (using Virtual Box) on a remote Workstation which runs on CentOS7.

  • Installed The Littlest JupyterHub

  • Make Jupyterhub available from outside (Port-forwarding, Firewallsetup)

  • Installed XfVB in the virtual machine like that
    The crucial Point here is to get a working X-Server (so general tutorials how to do something GUI related in a Docker image might also help) I would suggest trying the simple script from the link to check this. In this case you would also get a meaningful error message.

  • If this works it is important that you start the X-Server before doing any mayavi related stuff, like shown in the example above. If you import mayavi from mayavi import mlab before initializing the X-Server mayavi will crash.

@max9111 I managed to skip the xvfb wrapper by launching xvfb at entry point for my docker ENTRYPOINT ["tini", "-g", "--", "xvfb-run"] but I can only get mlab to work with the png backend... I haven't tried building vtk with OSMesa though...

The xvfb-run may come to your assistance:

 xvfb-run python your-py-script.py

Note you need to install xvfb before running the command above.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

indranilsinharoy picture indranilsinharoy  ·  9Comments

PennyQ picture PennyQ  ·  4Comments

igamenovoer picture igamenovoer  ·  7Comments

stefanoborini picture stefanoborini  ·  11Comments

anntzer picture anntzer  ·  7Comments