Eu uso o vtk com o driver MesaOS porque quero executar a renderização como parte de um notebook jupyter no modo headless, mais alguns detalhes da configuração do pacote podem ser encontrados aqui:
https://github.com/conda-forge/vtk-feedstock/issues/20
Quando eu uso o exemplo VTK fora da tela, ele está funcionando bem:
#! ./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()
Mas quando eu testo o exemplo fora da tela do mayavi, ele não está funcionando:
# 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()
A mensagem de erro que recebo é:
ERROR: In ../Rendering/OpenGL2/vtkXOpenGLRenderWindow.cxx, line 301
vtkXOpenGLRenderWindow (0x30ced20): bad X server connection. DISPLAY=Aborted
Então, para mim, parece que a inicialização fora da tela não é encaminhada corretamente para o VTK. Infelizmente, não fui capaz de localizar a inicialização do VTK dentro de mayavi. Para mim, parece estar acontecendo em tvtk_access.py
, mas ainda não vejo uma opção para forçar a renderização fora da tela diretamente.
Descobri que, ao definir ETS_TOOLKIT='null'
, poderia reproduzir este erro usando:
>>> 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)
Se ETS_TOOLKIT='null'
não estiver definido, nem mesmo a importação funciona. Então, por enquanto, o script acima falha quando tento criar uma cena new_scene()
@ jan-janssen - Você pode testar com o master mais recente, ele deve estar consertado agora. Você ainda precisará de export ETS_TOOLKIT=null
mas o resto deve funcionar agora.
Eu testei isso usando os pacotes vtk osmesa conda-forge e não consigo fazer funcionar sem um servidor X. Acho que tenho o env configurado corretamente.
O que eu fiz foi:
$ 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, na verdade, o exemplo puro de VTK dado no OP também não funciona, então presumo que haja algo errado com meu env. Eu obtenho a mesma coisa com um pip install git+https://github.com/enthought/mayavi
direto, então estou assumindo que estou perdendo alguma coisa no vtk em algum lugar.
Obrigado pelo teste, você pode verificar se o VTK instalado tem vtkOSOpenGLRenderWindow
, ou seja,
import vtk; print(hasattr(vtk, 'vtkOSOpenGLRenderWindow'))
. Do contrário, provavelmente o VTK não foi desenvolvido com suporte a osmesa. Se isso acontecer, terei de investigar cuidadosamente.
Não tem isso. Suponho que você não saiba o que controla se existe ou não ?!
Quando o VTK é construído, você precisa definir VTK_OPENGL_HAS_OSMESA
como ON.
hmmm, pelo que posso dizer, o pacote conda-forge osmesa deve fazer isso. Vou abrir um problema lá.
Acho que as versões mais recentes do mesa não permitem tanto o mesa quanto osmesa, portanto, os lançamentos VTK mais recentes podem desligar automaticamente o osmesa quando vtk_use_x é ativado. Mas não estou totalmente certo sobre isso, pois muitas coisas poderiam ter mudado ...
Se possível, você poderia tentar com uma versão mais antiga como VTK-7.x ou sempre que funcionasse?
Estou recebendo a mesma mensagem de erro no Ubuntu 18, vtk 8.1.2, mayavi 4.6.2
Também estou tendo esse problema com mayavi. Alguém encontrou alguma solução? Estou tendo esse problema ao usar mayavi em um servidor, embora tenha o monitor sendo encaminhado para o meu computador local.
Tive um problema semelhante ao usar Mayavi em um Jupyter-Notebook fornecido por um servidor Jupyter-Hub remoto. O problema é que não há nenhum servidor X em execução.
Eu resolvi isso instalando o xvfbwrapper e o back-end do Xvfb. Antes de fazer qualquer coisa com mayavi, inicie um Display.
Exemplo
#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
Se não houver uma forma mais elegante, acho que seria bom mencionar isso no manual.
@ max9111 você se lembra de fazer mais alguma coisa? Tentei seu código depois de instalar xvfbwrapper
. Mas depois de enviar ssh para meu servidor usando a sinalização -X, ainda recebo o erro:
ERRO: Em ../Rendering/OpenGL2/vtkXOpenGLRenderWindow.cxx, linha 606
vtkXOpenGLRenderWindow (0x55b43e61d590): Não é possível criar o contexto GLX. Abortando.
@tjiagoM Talvez você tenha esquecido de instalar o xfb (sudo apt-get install xvfb)?
@ max9111 oh, não, inicialmente cometi esse erro, mas eles gerariam um erro dizendo que nenhum xvfb foi encontrado / ativo (ou algo semelhante)
@ max9111 Estou lutando com a mesma configuração, mayavi em um jupyterhub remoto. Você tem uma imagem docker de amostra usada pelo hub? Tentei usar xvfbwrapper
como você sugeriu, mas não funcionou para mim. Desde já, obrigado!
@mirestrepo
Infelizmente, não temos uma imagem docker.
Minha configuração é:
Uma máquina virtual rodando em Kubuntu 18.04 (usando Virtual Box) em uma estação de trabalho remota que roda em CentOS7.
Instalou o Littlest JupyterHub
Disponibilize o Jupyterhub de fora (encaminhamento de porta, configuração de firewall)
Instalada XfVB na máquina virtual como o que
O ponto crucial aqui é obter um X-Server funcional (então, tutoriais gerais sobre como fazer algo relacionado à GUI em uma imagem do Docker também podem ajudar), sugiro tentar o script simples do link para verificar isso. Nesse caso, você também receberá uma mensagem de erro significativa.
Se isso funcionar, é importante que você inicie o X-Server antes de fazer qualquer coisa relacionada ao mayavi, como mostrado no exemplo acima. Se você importar mayavi from mayavi import mlab
antes de inicializar o X-Server mayavi irá travar.
@ max9111 Consegui pular o wrapper xvfb lançando xvfb
no ponto de entrada do meu docker ENTRYPOINT ["tini", "-g", "--", "xvfb-run"]
mas só consigo mlab
para trabalhar com png
backend ... Eu não tentei construir vtk
com OSMesa
embora ...
O xvfb-run pode ajudá-lo:
xvfb-run python your-py-script.py
Observe que você precisa instalar o xvfb antes de executar o comando acima.
Comentários muito úteis
Tive um problema semelhante ao usar Mayavi em um Jupyter-Notebook fornecido por um servidor Jupyter-Hub remoto. O problema é que não há nenhum servidor X em execução.
Eu resolvi isso instalando o xvfbwrapper e o back-end do Xvfb. Antes de fazer qualquer coisa com mayavi, inicie um Display.
Exemplo
Se não houver uma forma mais elegante, acho que seria bom mencionar isso no manual.