Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Force Mayavi to plot when figure embedded in a TraitsUI window #59

Closed
larsoner opened this issue Mar 22, 2013 · 2 comments
Closed

Force Mayavi to plot when figure embedded in a TraitsUI window #59

larsoner opened this issue Mar 22, 2013 · 2 comments
Labels

Comments

@larsoner
Copy link
Collaborator

Hello,

I am having an issue where I cannot get Mayavi to render the window when embedded in a TraitsUI window. Specifically, if I run the following code (minimal representation of Mayavi scene in TraitsUI window), I get strange results:

# Enthought imports.
from traits.api import HasTraits, Instance
from traitsui.api import View, Item
from tvtk.pyface.scene_editor import SceneEditor
from mayavi.tools.mlab_scene_model import MlabSceneModel
from mayavi.sources.api import ParametricSurface
from mayavi import mlab
import pylab as pl
pl.ion()


class Mayavi(HasTraits):
    scene = Instance(MlabSceneModel, ())
    view = View(Item(name='scene', editor=SceneEditor(),
                     show_label=False, resizable=True, height=250,
                     width=500))

s = ParametricSurface()
m = Mayavi()
m.edit_traits()
mlab.pipeline.surface(s, figure=m.scene.mayavi_scene)

# this one comes up all black
img = mlab.screenshot(figure=m.scene.mayavi_scene)
pl.imshow(img)
# wait a second for the figure to appear, then it works correctly

The output of the first call to pl.imshow(img) is:
Screenshot from 2013-03-21 16:57:15
Once that pops up, the Mayavi screen then finally shows up on-screen, and renders correctly:
Screenshot from 2013-03-21 16:57:13
And after that has happened, re-running the two lines to get the screenshot and plot the image with pylab works:
Screenshot from 2013-03-21 16:57:22

So basically, I need a way to force Mayavi (and/or TraitsUI) to have the window 1) show up, and then 2) fully render before moving on to the screenshot() line. I've tried inserting mlab.draw() after the addition of the surface (immediately preceding mlab.screenshot() to no avail. It's possible this might be solvable by telling TraitsUI to draw the window and not return control until it has. If that's the case, it would be useful to add to the examples, since I've searched and not managed to find a workable solution to this...

Note that this is not an issue if the figure is created with mlab.figure() instead of being buried inside a TraitsUI window, but that is not a workable solution for my use case because I want to pull up several plots simultaneously (several Mayavi scenes) in the same window. This is part of a GUI that shows multiple views of the same object, and I need them to be rendered properly in order to determine certain useful properties (such as optimal camera distance) that, at the moment, is broken. I also can't for example, set the lighting properties, since after telling the windows to be created, the scenes aren't rendered immediately so the lights or light_manager property is None (whereas, again, if I wait a few seconds for the window to actually show up, those properties exist).

Running Mayavi 4.1.0 on Ubuntu Linux.

@larsoner
Copy link
Collaborator Author

Found a hackish way to do it by looking at how mlab.show() works; this allows the code to function, at least on my system. Adding this before the mlab.screenshot() call causes the correct screenshot to be taken:

from pyface.api import GUI
_gui = GUI()
orig_val = _gui.busy
_gui.set_busy(busy=True)
_gui.set_busy(busy=orig_val)
_gui.process_events()

The _gui.process_events() was not enough (although this caused the image to go from black to light gray). I needed both that and _gui.set_busy(busy=True) to get it to work. Somehow this seems sub-optimal to me. Is there a cleaner way?

@larsoner
Copy link
Collaborator Author

FWIW GUI().process_events() seems to be sufficient nowadays. I'll close as "resolved enough" :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants