#!/usr/bin/env python """ This script demonstrates how one can do a computation in another thread and update the mayavi pipeline. It also shows how to create a numpy array data and visualize it as image data using a few modules. """ # Author: Prabhu Ramachandran <prabhu_r@users.sf.net> # Copyright (c) 2007-2008, Enthought, Inc. # License: BSD Style. # Standard library imports import numpy from threading import Thread from time import sleep # Enthought library imports from enthought.mayavi.scripts import mayavi2 from enthought.traits.api import HasTraits, Button, Instance from enthought.traits.ui.api import View, Item from enthought.mayavi.sources.array_source import ArraySource from enthought.mayavi.modules.outline import Outline from enthought.mayavi.modules.image_plane_widget import ImagePlaneWidget from enthought.pyface.api import GUI def make_data(dims=(128, 128, 128)): """Creates some simple array data of the given dimensions to test with.""" np = dims[0]*dims[1]*dims[2] # Create some scalars to render. x, y, z = numpy.ogrid[-5:5:dims[0]*1j,-5:5:dims[1]*1j,-5:5:dims[2]*1j] x = x.astype('f') y = y.astype('f') z = z.astype('f') scalars = (numpy.sin(x*y*z)/(x*y*z)) # The copy makes the data contiguous and the transpose makes it # suitable for display via tvtk. Please note that we assume here # that the ArraySource is configured to not transpose the data. s = numpy.transpose(scalars).copy() # Reshaping the array is needed since the transpose messes up the # dimensions of the data. The scalars themselves are ravel'd and # used internally by VTK so the dimension does not matter for the # scalars. s.shape = s.shape[::-1] return s class ThreadedAction(Thread): def __init__(self, data, **kwargs): Thread.__init__(self, **kwargs) self.data = data def run(self): print "Performing expensive calculation in %s..."%self.getName(), sleep(3) sd = self.data.scalar_data sd += numpy.sin(numpy.random.rand(*sd.shape)*2.0*numpy.pi) GUI.invoke_later(self.data.update) print 'done.' class Controller(HasTraits): run_calculation = Button('Run calculation') data = Instance(ArraySource) view = View(Item(name='run_calculation')) def _run_calculation_changed(self, value): action = ThreadedAction(self.data) action.start() @mayavi2.standalone def view_numpy(): """Example showing how to view a 3D numpy array in mayavi2. """ # 'mayavi' is always defined on the interpreter. mayavi.new_scene() # Make the data and add it to the pipeline. data = make_data() src = ArraySource(transpose_input_array=False) src.scalar_data = data mayavi.add_source(src) # Visualize the data. o = Outline() mayavi.add_module(o) ipw = ImagePlaneWidget() mayavi.add_module(ipw) ipw.module_manager.scalar_lut_manager.show_scalar_bar = True ipw_y = ImagePlaneWidget() mayavi.add_module(ipw_y) ipw_y.ipw.plane_orientation = 'y_axes' computation = Controller(data=src) computation.edit_traits() if __name__ == '__main__': view_numpy()