Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Constrain Mayavi mouse drag to rotating Earth around its axis

Using iPython Notebook, I have been able to bring up a globe of the Earth with code like:

from mayavi import mlab
from mayavi.sources.builtin_surface import BuiltinSurface

ocean_blue = (0.4, 0.5, 1.0)
r = 6371 # km

sphere = mlab.points3d(0, 0, 0, name='Globe',
  scale_mode='none', scale_factor=r * 2.0,
  color=ocean_blue, resolution=50)

sphere.actor.property.specular = 0.20
sphere.actor.property.specular_power = 10

continents_src = BuiltinSurface(source='earth', name='Continents')
continents_src.data_source.on_ratio = 1  # detail level
continents_src.data_source.radius = r
continents = mlab.pipeline.surface(continents_src, color=(0, 0, 0))

But when I interact with the resulting 3D window using the mouse, it is very difficult to keep it right-side-up, because the UI interprets a mouse-drag to either the left or the right as an attempt to rotate the scene (or camera?) around the current vertical axis of the window, instead of through the axis of the globe itself.

Is there any way to constrain the user interaction code so that a left or right mouse-drag spins the globe around its axis, regardless of whether the axis is pointing straight-up-and-down or not, either by setting some Mayavi parameters, or by getting some Python code registered as the UI event handler for mouse dragging?

like image 338
Brandon Rhodes Avatar asked Oct 06 '22 10:10

Brandon Rhodes


1 Answers

Nine months later, I have finally run across a clue that lead me to a solution! Another Stack Overflow question and answer, Is it possible to prohibit axes rotation with the mouse in Mayavi?, exposed me to the idea of setting up a non-default “interactor” to control what mouse clicks and drags mean.

And there is indeed an interactor that keeps the Z-axis “up” no matter what the user does:

http://www.vtk.org/doc/nightly/html/classvtkInteractorStyleTerrain.html

To activate this interactor in the Mayavi main window, simply add the following three lines to your code (for example, you can add them to my globe-building code in the question), and the globe will always remain upright!

from tvtk.api import tvtk
fig = mlab.gcf()
fig.scene.interactor.interactor_style = tvtk.InteractorStyleTerrain()
like image 152
Brandon Rhodes Avatar answered Oct 10 '22 03:10

Brandon Rhodes