class Visualisator(HasTraits): scene = Instance(MlabSceneModel, ()) #tree = View(Item('scene', editor=SceneEditor(scene_class=MayaviScene), tree = View(Item('scene', editor=SceneEditor(scene_class=Scene), height=250, width=300, show_label=False), resizable=True) grid = None def push(self, grid): self.grid = grid self.scene.mlab.clf() self.updatePlot() @on_trait_change('scene.activated') def updatePlot(self): if self.grid: surf = self.scene.mlab.pipeline.surface(self.grid, opacity=1) surf.actor.property.interpolation = 'flat' else: self.scene.mlab.test_points3d() self.scene.mlab.orientation_axes() self.scene.background = (0, 0, 0) self.scene.mlab.colorbar(orientation='vertical')
class MyApp(HasTraits): # The first engine. As default arguments (an empty tuple) are given, # traits initializes it. engine1 = Instance(Engine, args=()) scene1 = Instance(MlabSceneModel) def _scene1_default(self): " The default initializer for 'scene1' " self.engine1.start() scene1 = MlabSceneModel(engine=self.engine1) return scene1 engine2 = Instance(Engine, ()) scene2 = Instance(MlabSceneModel) def _scene2_default(self): " The default initializer for 'scene2' " self.engine2.start() scene2 = MlabSceneModel(engine=self.engine2) return scene2 # We populate the scenes only when it is activated, to avoid problems # with VTK objects that expect an active scene @on_trait_change('scene1.activated') def populate_scene1(self): self.scene1.mlab.test_surf() @on_trait_change('scene2.activated') def populate_scene2(self): self.scene2.mlab.test_mesh() # The layout of the view view = View(Group( Item('scene1', editor=SceneEditor(scene_class=MayaviScene), width=480, height=480)), Group( Item('scene2', editor=SceneEditor(scene_class=MayaviScene), width=480, height=480)), resizable=True)
class MyModel(HasTraits): n_meridional = Range( 0, 30, 6, ) #mode='spinner') n_longitudinal = Range( 0, 30, 11, ) #mode='spinner') scene = Instance(MlabSceneModel, ()) plot = Instance(PipelineBase) # When the scene is activated, or when the parameters are changed, we # update the plot. @on_trait_change('n_meridional,n_longitudinal,scene.activated') def update_plot(self): x, y, z, t = curve(self.n_meridional, self.n_longitudinal) if self.plot is None: self.plot = self.scene.mlab.plot3d(x, y, z, t, tube_radius=0.025, colormap='Spectral') else: self.plot.mlab_source.set(x=x, y=y, z=z, scalars=t) # The layout of the dialog created view = View( Item('scene', editor=SceneEditor(scene_class=MayaviScene), height=250, width=300, show_label=False), Group( '_', 'n_meridional', 'n_longitudinal', ), resizable=True, )
class MayaviView(HasTraits): scene = Instance(MlabSceneModel, ()) # The layout of the panel created by traits. view = View(Item('scene', editor=SceneEditor(), resizable=True, show_label=False), resizable=True) def __init__(self): HasTraits.__init__(self) x, y, z = ogrid[-10:10:100j, -10:10:100j, -10:10:100j] scalars = sin(x * y * z) / (x * y * z) src = ArraySource(scalar_data=scalars) self.scene.mayavi_scene.add_child(src) src.add_module(IsoSurface())
class MayaviView(HasTraits): scene = Instance(MlabSceneModel, ()) # The layout of the panel created by Traits view = View(Item('scene', editor=SceneEditor(), resizable=True, show_label=False), resizable=True) def __init__(self): HasTraits.__init__(self) # Create some data, and plot it using the embedded scene's engine x, y, z = ogrid[-10:10:100j, -10:10:100j, -10:10:100j] scalars = sin(x * y * z) / (x * y * z) src = ArraySource(scalar_data=scalars) self.scene.engine.add_source(src) src.add_module(IsoSurface())
class Visualization(HasTraits): scene = Instance(MlabSceneModel, ()) @on_trait_change('scene.activated') def update_plot(self): # This function is called when the view is opened. We don't # populate the scene when the view is not yet open, as some # VTK features require a GLContext. # We can do normal mlab calls on the embedded scene. self.scene.mlab.test_points3d() # the layout of the dialog screated view = View( Item('scene', editor=SceneEditor(scene_class=MayaviScene), height=250, width=300, show_label=False), resizable=True # We need this to resize with the parent widget )
class VolumeSlicer(HasTraits): # The data to plot data = Array() # The 4 views displayed scene3d = Instance(MlabSceneModel, ()) scene_x = Instance(MlabSceneModel, ()) scene_y = Instance(MlabSceneModel, ()) scene_z = Instance(MlabSceneModel, ()) # The data source data_src3d = Instance(Source) # The image plane widgets of the 3D scene ipw_3d_x = Instance(PipelineBase) ipw_3d_y = Instance(PipelineBase) ipw_3d_z = Instance(PipelineBase) _axis_names = dict(x=0, y=1, z=2) #--------------------------------------------------------------------------- def __init__(self, **traits): super(VolumeSlicer, self).__init__(**traits) # Force the creation of the image_plane_widgets: self.ipw_3d_x self.ipw_3d_y self.ipw_3d_z #--------------------------------------------------------------------------- # Default values #--------------------------------------------------------------------------- def _data_src3d_default(self): return mlab.pipeline.scalar_field(self.data, figure=self.scene3d.mayavi_scene) def make_ipw_3d(self, axis_name): ipw = mlab.pipeline.image_plane_widget( self.data_src3d, figure=self.scene3d.mayavi_scene, plane_orientation='%s_axes' % axis_name) return ipw def _ipw_3d_x_default(self): return self.make_ipw_3d('x') def _ipw_3d_y_default(self): return self.make_ipw_3d('y') def _ipw_3d_z_default(self): return self.make_ipw_3d('z') #--------------------------------------------------------------------------- # Scene activation callbaks #--------------------------------------------------------------------------- @on_trait_change('scene3d.activated') def display_scene3d(self): outline = mlab.pipeline.outline( self.data_src3d, figure=self.scene3d.mayavi_scene, ) self.scene3d.mlab.view(40, 50) # Interaction properties can only be changed after the scene # has been created, and thus the interactor exists for ipw in (self.ipw_3d_x, self.ipw_3d_y, self.ipw_3d_z): # Turn the interaction off ipw.ipw.interaction = 0 self.scene3d.scene.background = (0, 0, 0) # Keep the view always pointing up self.scene3d.scene.interactor.interactor_style = \ tvtk.InteractorStyleTerrain() def make_side_view(self, axis_name): scene = getattr(self, 'scene_%s' % axis_name) # To avoid copying the data, we take a reference to the # raw VTK dataset, and pass it on to mlab. Mlab will create # a Mayavi source from the VTK without copying it. # We have to specify the figure so that the data gets # added on the figure we are interested in. outline = mlab.pipeline.outline( self.data_src3d.mlab_source.dataset, figure=scene.mayavi_scene, ) ipw = mlab.pipeline.image_plane_widget(outline, plane_orientation='%s_axes' % axis_name) setattr(self, 'ipw_%s' % axis_name, ipw) # Synchronize positions between the corresponding image plane # widgets on different views. ipw.ipw.sync_trait('slice_position', getattr(self, 'ipw_3d_%s' % axis_name).ipw) # Make left-clicking create a crosshair ipw.ipw.left_button_action = 0 # Add a callback on the image plane widget interaction to # move the others def move_view(obj, evt): position = obj.GetCurrentCursorPosition() for other_axis, axis_number in self._axis_names.iteritems(): if other_axis == axis_name: continue ipw3d = getattr(self, 'ipw_3d_%s' % other_axis) ipw3d.ipw.slice_position = position[axis_number] ipw.ipw.add_observer('InteractionEvent', move_view) ipw.ipw.add_observer('StartInteractionEvent', move_view) # Center the image plane widget ipw.ipw.slice_position = 0.5 * self.data.shape[ self._axis_names[axis_name]] # Position the view for the scene views = dict( x=(0, 90), y=(90, 90), z=(0, 0), ) scene.mlab.view(*views[axis_name]) # 2D interaction: only pan and zoom scene.scene.interactor.interactor_style = \ tvtk.InteractorStyleImage() scene.scene.background = (0, 0, 0) @on_trait_change('scene_x.activated') def display_scene_x(self): return self.make_side_view('x') @on_trait_change('scene_y.activated') def display_scene_y(self): return self.make_side_view('y') @on_trait_change('scene_z.activated') def display_scene_z(self): return self.make_side_view('z') #--------------------------------------------------------------------------- # The layout of the dialog created #--------------------------------------------------------------------------- view = View( HGroup( Group( Item('scene_y', editor=SceneEditor(scene_class=Scene), height=250, width=300), Item('scene_z', editor=SceneEditor(scene_class=Scene), height=250, width=300), show_labels=False, ), Group( Item('scene_x', editor=SceneEditor(scene_class=Scene), height=250, width=300), Item('scene3d', editor=SceneEditor(scene_class=MayaviScene), height=250, width=300), show_labels=False, ), ), resizable=True, title='Volume Slicer', )
class MayaviViewer(HasTraits): """ This class represents a Mayavi based viewer for the particles. They are queried from a running solver. """ particle_arrays = List(Instance(ParticleArrayHelper), []) pa_names = List(Str, []) client = Instance(MultiprocessingClient) host = Str('localhost', desc='machine to connect to') port = Int(8800, desc='port to use to connect to solver') authkey = Password('pysph', desc='authorization key') host_changed = Bool(True) scene = Instance(MlabSceneModel, ()) controller = Property() ######################################## # Timer traits. timer = Instance(Timer) interval = Range(2, 20.0, 5.0, desc='frequency in seconds with which plot is updated') ######################################## # Solver info/control. current_time = Float(0.0, desc='the current time in the simulation') iteration = Int(0, desc='the current iteration number') pause_solver = Bool(False, desc='if the solver should be paused') ######################################## # The layout of the dialog created view = View(HSplit( Group( Group( Item(name='host'), Item(name='port'), Item(name='authkey'), label='Connection', ), Group( Item(name='current_time'), Item(name='iteration'), Item(name='pause_solver'), Item(name='interval'), label='Solver', ), Group( Item(name='particle_arrays', style='custom', show_label=False, editor=ListEditor(use_notebook=True, deletable=False, page_name='.name'))), ), Item('scene', editor=SceneEditor(scene_class=MayaviScene), height=480, width=500, show_label=False), ), resizable=True, title='Mayavi Particle Viewer') ###################################################################### # `MayaviViewer` interface. ###################################################################### @on_trait_change('scene.activated') def start_timer(self): # Just accessing the timer will start it. t = self.timer if not t.IsRunning(): t.Start(int(self.interval * 1000)) @on_trait_change('scene.activated') def update_plot(self): # do not update if solver is paused if self.pause_solver: return controller = self.controller if controller is None: return self.current_time = controller.get_t() for idx, name in enumerate(self.pa_names): pa = controller.get_named_particle_array(name) self.particle_arrays[idx].particle_array = pa ###################################################################### # Private interface. ###################################################################### @on_trait_change('host,port,authkey') def _mark_reconnect(self): self.host_changed = True def _get_controller(self): ''' get the controller, also sets the iteration count ''' reconnect = self.host_changed if not reconnect: try: c = self.client.controller self.iteration = c.get_count() except Exception as e: logger.info( 'Error: no connection or connection closed: reconnecting') reconnect = True self.client = None if reconnect: self.host_changed = False try: if MultiprocessingClient.is_available((self.host, self.port)): self.client = MultiprocessingClient(address=(self.host, self.port), authkey=self.authkey) else: return None except Exception as e: logger.info('Could not connect: check if solver is running') return None c = self.client.controller self.iteration = c.get_count() return self.client.controller def _client_changed(self, old, new): if self.client is None: return else: self.pa_names = self.client.controller.get_particle_array_names() self.scene.mayavi_scene.children[:] = [] self.particle_arrays = [ ParticleArrayHelper(scene=self.scene, name=x) for x in self.pa_names ] # Turn on the legend for the first particle array. if len(self.particle_arrays) > 0: self.particle_arrays[0].show_legend = True def _timer_event(self): # catch all Exceptions else timer will stop try: self.update_plot() except Exception as e: logger.info('Exception: %s caught in timer_event' % e) def _interval_changed(self, value): t = self.timer if t is None: return if t.IsRunning(): t.Stop() t.Start(int(value * 1000)) def _timer_default(self): return Timer(int(self.interval * 1000), self._timer_event) def _pause_solver_changed(self, value): c = self.client.controller if value: c.pause_on_next() else: c.cont()
class MyModel(HasTraits): select = Range(0, len(data) - 1, 0) last_select = deepcopy(select) iso_value = Range(iso_min, iso_max, iso_val, mode='logslider') opacity = Range(0, 1.0, 1.0) show_atoms = Bool(True) label = Str() available = List(Str) available = datalabels prev_button = Button('Previous') next_button = Button('Next') scene = Instance(MlabSceneModel, ()) plot_atoms = Instance(PipelineBase) plot0 = Instance(PipelineBase) # When the scene is activated, or when the parameters are changed, we # update the plot. @on_trait_change( 'select,iso_value,show_atoms,opacity,label,scene.activated') def update_plot(self): if self.plot0 is None: if not is_vectorfield: src = mlab.pipeline.scalar_field(X, Y, Z, data[self.select]) self.plot0 = self.scene.mlab.pipeline.iso_surface( src, contours=[-self.iso_value, self.iso_value], opacity=self.opacity, colormap='blue-red', vmin=-1e-8, vmax=1e-8) else: self.plot0 = self.scene.mlab.quiver3d( X, Y, Z, *data[self.select]) #flow self.plot0.scene.background = (1, 1, 1) elif self.select != self.last_select: if not is_vectorfield: self.plot0.mlab_source.set(scalars=data[self.select]) else: self.plot0.mlab_source.set( vectors=data[self.select].reshape((3, -1)).T) if not is_vectorfield: self.plot0.contour.contours = [-self.iso_value, self.iso_value] self.plot0.actor.property.opacity = self.opacity self.last_select = deepcopy(self.select) if datalabels is not None: self.label = datalabels[self.select] if geo_spec is not None: if self.plot_atoms is None: self.plot_atoms = self.scene.mlab.points3d( geo_spec[:, 0], geo_spec[:, 1], geo_spec[:, 2], scale_factor=0.75, resolution=20) self.plot_atoms.visible = self.show_atoms def _prev_button_fired(self): if self.select > 0: self.select -= 1 def _next_button_fired(self): if self.select < len(data) - 1: self.select += 1 # The layout of the dialog created items = (Item('scene', editor=SceneEditor(scene_class=MayaviScene), height=400, width=600, show_label=False), ) items0 = () if len(data) > 1: items0 += (Group( 'select', HSplit(Item('prev_button', show_label=False), Item('next_button', show_label=False))), ) items0 += (Group('iso_value', 'opacity', 'show_atoms'), ) if datalabels is not None: if len(datalabels) > 1: items1 = (Item('available', editor=ListStrEditor(title='Available Data', editable=False), show_label=False, style='readonly', width=300), ) items0 = HSplit(items0, items1) items += ( Group( Item('label', label='Selected Data', style='readonly', show_label=True), '_'), items0, ) else: items += items0 view = View(VSplit(items[0], items[1:]), resizable=True)
class VolumeSlicer(HasTraits): # The data to plot data = Array # The position of the view position = Array(shape=(3,)) # The 4 views displayed scene3d = Instance(MlabSceneModel, ()) scene_x = Instance(MlabSceneModel, ()) scene_y = Instance(MlabSceneModel, ()) scene_z = Instance(MlabSceneModel, ()) # The data source data_src = Instance(Source) # The image plane widgets of the 3D scene ipw_3d_x = Instance(PipelineBase) ipw_3d_y = Instance(PipelineBase) ipw_3d_z = Instance(PipelineBase) # The cursors on each view: cursors = Dict() disable_render = Bool _axis_names = dict(x=0, y=1, z=2) #--------------------------------------------------------------------------- # Object interface #--------------------------------------------------------------------------- def __init__(self, **traits): super(VolumeSlicer, self).__init__(**traits) # Force the creation of the image_plane_widgets: self.ipw_3d_x self.ipw_3d_y self.ipw_3d_z #--------------------------------------------------------------------------- # Default values #--------------------------------------------------------------------------- def _position_default(self): return 0.5*np.array(self.data.shape) def _data_src_default(self): return mlab.pipeline.scalar_field(self.data, figure=self.scene3d.mayavi_scene, name='Data',) def make_ipw_3d(self, axis_name): ipw = mlab.pipeline.image_plane_widget(self.data_src, figure=self.scene3d.mayavi_scene, plane_orientation='%s_axes' % axis_name, name='Cut %s' % axis_name) return ipw def _ipw_3d_x_default(self): return self.make_ipw_3d('x') def _ipw_3d_y_default(self): return self.make_ipw_3d('y') def _ipw_3d_z_default(self): return self.make_ipw_3d('z') #--------------------------------------------------------------------------- # Scene activation callbacks #--------------------------------------------------------------------------- @on_trait_change('scene3d.activated') def display_scene3d(self): outline = mlab.pipeline.outline(self.data_src, figure=self.scene3d.mayavi_scene, ) self.scene3d.mlab.view(40, 50) # Interaction properties can only be changed after the scene # has been created, and thus the interactor exists for ipw in (self.ipw_3d_x, self.ipw_3d_y, self.ipw_3d_z): ipw.ipw.interaction = 0 self.scene3d.scene.background = (0, 0, 0) # Keep the view always pointing up self.scene3d.scene.interactor.interactor_style = \ tvtk.InteractorStyleTerrain() self.update_position() def make_side_view(self, axis_name): scene = getattr(self, 'scene_%s' % axis_name) scene.scene.parallel_projection = True ipw_3d = getattr(self, 'ipw_3d_%s' % axis_name) # We create the image_plane_widgets in the side view using a # VTK dataset pointing to the data on the corresponding # image_plane_widget in the 3D view (it is returned by # ipw_3d._get_reslice_output()) ipw = mlab.pipeline.image_plane_widget( ipw_3d.ipw._get_reslice_output(), plane_orientation='z_axes', vmin=self.data.min(), vmax=self.data.max(), figure=scene.mayavi_scene, name='Cut view %s' % axis_name, ) setattr(self, 'ipw_%s' % axis_name, ipw) # Make left-clicking create a crosshair ipw.ipw.left_button_action = 0 x, y, z = self.position cursor = mlab.points3d(x, y, z, mode='axes', color=(0, 0, 0), scale_factor=2*max(self.data.shape), figure=scene.mayavi_scene, name='Cursor view %s' % axis_name, ) self.cursors[axis_name] = cursor # Add a callback on the image plane widget interaction to # move the others this_axis_number = self._axis_names[axis_name] def move_view(obj, evt): # Disable rendering on all scene position = list(obj.GetCurrentCursorPosition())[:2] position.insert(this_axis_number, self.position[this_axis_number]) # We need to special case y, as the view has been rotated. if axis_name is 'y': position = position[::-1] self.position = position ipw.ipw.add_observer('InteractionEvent', move_view) ipw.ipw.add_observer('StartInteractionEvent', move_view) # Center the image plane widget ipw.ipw.slice_position = 0.5*self.data.shape[ self._axis_names[axis_name]] # 2D interaction: only pan and zoom scene.scene.interactor.interactor_style = \ tvtk.InteractorStyleImage() scene.scene.background = (0, 0, 0) # Some text: mlab.text(0.01, 0.8, axis_name, width=0.08) # Choose a view that makes sens views = dict(x=(0, 0), y=(90, 180), z=(0, 0)) #mlab.view(*views[axis_name],figure=scene.mayavi_scene) #focalpoint=0.5*np.array(self.data.shape), scene.scene.camera.parallel_scale = 0.52*np.mean(self.data.shape) @on_trait_change('scene_x.activated') def display_scene_x(self): return self.make_side_view('x') @on_trait_change('scene_y.activated') def display_scene_y(self): return self.make_side_view('y') @on_trait_change('scene_z.activated') def display_scene_z(self): return self.make_side_view('z') #--------------------------------------------------------------------------- # Traits callback #--------------------------------------------------------------------------- @on_trait_change('position') def update_position(self): """ Update the position of the cursors on each side view, as well as the image_plane_widgets in the 3D view. """ # First disable rendering in all scenes to avoid unecessary # renderings self.disable_render = True # For each axis, move image_plane_widget and the cursor in the # side view for axis_name, axis_number in self._axis_names.iteritems(): ipw3d = getattr(self, 'ipw_3d_%s' % axis_name) ipw3d.ipw.slice_position = self.position[axis_number] # Go from the 3D position, to the 2D coordinates in the # side view position2d = list(self.position) position2d.pop(axis_number) if axis_name is 'y': position2d = position2d[::-1] # Move the cursor self.cursors[axis_name].mlab_source.set( x=[position2d[0]], y=[position2d[1]], z=[0]) # Finally re-enable rendering self.disable_render = False @on_trait_change('disable_render') def _render_enable(self): for scene in (self.scene3d, self.scene_x, self.scene_y, self.scene_z): scene.scene.disable_render = self.disable_render #--------------------------------------------------------------------------- # The layout of the dialog created #--------------------------------------------------------------------------- view = View(HGroup( Group( Item('scene_y', editor=SceneEditor(scene_class=Scene), height=250, width=300), Item('scene_z', editor=SceneEditor(scene_class=Scene), height=250, width=300), show_labels=False, ), Group( Item('scene_x', editor=SceneEditor(scene_class=Scene), height=250, width=300), Item('scene3d', editor=SceneEditor(scene_class=Scene), height=250, width=300), show_labels=False, ), ), resizable=True, title='Volume Slicer', )
class Lorenz(HasTraits): # The parameters for the Lorenz system, defaults to the standard ones. s = Range(0.0, 20.0, 10.0, desc='the parameter s', enter_set=True, auto_set=False) r = Range(0.0, 50.0, 28.0, desc='the parameter r', enter_set=True, auto_set=False) b = Range(0.0, 10.0, 8./3., desc='the parameter b', enter_set=True, auto_set=False) # These expressions are evaluated to compute the right hand sides of # the ODE. Defaults to the Lorenz system. u = Str('s*(y-x)', desc='the x component of the velocity', auto_set=False, enter_set=True) v = Str('r*x - y - x*z', desc='the y component of the velocity', auto_set=False, enter_set=True) w = Str('x*y - b*z', desc='the z component of the velocity', auto_set=False, enter_set=True) # Tuple of x, y, z arrays where the field is sampled. points = Tuple(Array, Array, Array) # The mayavi(mlab) scene. scene = Instance(MlabSceneModel, args=()) # The "flow" which is a Mayavi streamline module. flow = Instance(HasTraits) ######################################## # The UI view to show the user. view = View(HSplit( Group( Item('scene', editor=SceneEditor(scene_class=MayaviScene), height=500, width=500, show_label=False)), Group( Item('s'), Item('r'), Item('b'), Item('u'), Item('v'), Item('w')), ), resizable=True ) ###################################################################### # Trait handlers. ###################################################################### # Note that in the `on_trait_change` call below we listen for the # `scene.activated` trait. This conveniently ensures that the flow # is generated as soon as the mlab `scene` is activated (which # happens when the configure/edit_traits method is called). This # eliminates the need to manually call the `update_flow` method etc. @on_trait_change('s, r, b, scene.activated') def update_flow(self): x, y, z = self.points u, v, w = self.get_uvw() self.flow.mlab_source.set(u=u, v=v, w=w) @on_trait_change('u') def update_u(self): self.flow.mlab_source.set(u=self.get_vel('u')) @on_trait_change('v') def update_v(self): self.flow.mlab_source.set(v=self.get_vel('v')) @on_trait_change('w') def update_w(self): self.flow.mlab_source.set(w=self.get_vel('w')) def get_uvw(self): return self.get_vel('u'), self.get_vel('v'), self.get_vel('w') def get_vel(self, comp): """This function basically evaluates the user specified system of equations using scipy. """ func_str = getattr(self, comp) try: g = scipy.__dict__ x, y, z = self.points s, r, b = self.s, self.r, self.b val = eval(func_str, g, {'x': x, 'y': y, 'z': z, 's':s, 'r':r, 'b': b}) except: # Mistake, so return the original value. val = getattr(self.flow.mlab_source, comp) return val ###################################################################### # Private interface. ###################################################################### def _points_default(self): x, y, z = np.mgrid[-50:50:100j,-50:50:100j,-10:60:70j] return x, y, z def _flow_default(self): x, y, z = self.points u, v, w = self.get_uvw() f = self.scene.mlab.flow(x, y, z, u, v, w) f.stream_tracer.integration_direction = 'both' f.stream_tracer.maximum_propagation = 200 src = f.mlab_source.m_data o = mlab.outline() mlab.view(120, 60, 150) return f
class Application(HasTraits): scene = Instance(MlabSceneModel, (), editor=SceneEditor()) # The mayavi engine view. engine_view = Instance(EngineView) coils = List(Instance(Loop, (), allow_none=False), editor=ListEditor(style='custom'), value=[ Loop(position=(0, 0, -0.05), ), Loop(position=(0, 0, 0.05), ), ]) Bx = Array(value=np.zeros_like(X)) By = Array(value=np.zeros_like(X)) Bz = Array(value=np.zeros_like(X)) Bnorm = Array(value=np.zeros_like(X)) vector_field = None def __init__(self, **traits): HasTraits.__init__(self, **traits) self.engine_view = EngineView(engine=self.scene.engine) @on_trait_change('scene.activated,coils') def init_view(self): if self.scene._renderer is not None: self.scene.scene_editor.background = (0, 0, 0) for coil in self.coils: coil.app = self coil.display() self.visualize_field() def visualize_field(self): self.Bx = np.zeros_like(X) self.By = np.zeros_like(X) self.Bz = np.zeros_like(X) self.Bnorm = np.zeros_like(X) self.scene.scene.disable_render = True for coil in self.coils: self.Bx += coil.Bx self.By += coil.By self.Bz += coil.Bz self.Bnorm = np.sqrt(self.Bx**2 + self.By**2 + self.Bz**2) if self.vector_field is None: self.vector_field = self.scene.mlab.pipeline.vector_field( X, Y, Z, self.Bx, self.By, self.Bz, scalars=self.Bnorm, name='B field') vectors = self.scene.mlab.pipeline.vectors( self.vector_field, mode='arrow', resolution=10, mask_points=6, colormap='YlOrRd', scale_factor=2 * np.abs(X[0, 0, 0] - X[1, 1, 1])) vectors.module_manager.vector_lut_manager.reverse_lut = True vectors.glyph.mask_points.random_mode = False self.scene.mlab.axes() self.scp = self.scene.mlab.pipeline.scalar_cut_plane( self.vector_field, colormap='hot') else: # Modify in place the data source. The visualization will # update automaticaly self.vector_field.mlab_source.set(u=self.Bx, v=self.By, w=self.Bz, scalars=self.Bnorm) self.scene.scene.disable_render = False view = View( HSplit(VSplit(Item(name='engine_view', style='custom', resizable=True), Item('coils', springy=True), show_labels=False), 'scene', show_labels=False), resizable=True, title='Coils...', height=0.8, width=0.8, )
class SurfaceViewer(HasTraits): n_times = Range( 0, 100, 0, ) scene = Instance(MlabSceneModel, ()) surf = Instance(PipelineBase) text = Instance(PipelineBase) def __init__(self, src, data, times, n_smooth=20, cmap='jet'): super(SurfaceViewer, self).__init__() self.src = src self.data = data self.times = times self.n_smooth = n_smooth self.cmap = cmap lh_points = src[0]['rr'] rh_points = src[1]['rr'] # lh_faces = src[0]['tris'] # rh_faces = src[1]['tris'] lh_faces = src[0]['use_tris'] rh_faces = src[1]['use_tris'] points = np.r_[lh_points, rh_points] points *= 200 faces = np.r_[lh_faces, lh_points.shape[0] + rh_faces] lh_idx = np.where(src[0]['inuse'])[0] rh_idx = np.where(src[1]['inuse'])[0] use_idx = np.r_[lh_idx, lh_points.shape[0] + rh_idx] self.points = points[use_idx] self.faces = np.searchsorted(use_idx, faces) # When the scene is activated, or when the parameters are changed, we # update the plot. @on_trait_change('n_times,scene.activated') def update_plot(self): idx = int(self.n_times * len(self.times) / 100) t = self.times[idx] d = self.data[:, idx].astype(np.float) # 8bits for mayavi points = self.points faces = self.faces info_time = "%d ms" % (1e3 * t) if self.surf is None: surface_mesh = self.scene.mlab.pipeline.triangular_mesh_source( points[:, 0], points[:, 1], points[:, 2], faces, scalars=d) smooth_ = tvtk.SmoothPolyDataFilter( number_of_iterations=self.n_smooth, relaxation_factor=0.18, feature_angle=70, feature_edge_smoothing=False, boundary_smoothing=False, convergence=0.) surface_mesh_smooth = self.scene.mlab.pipeline.user_defined( surface_mesh, filter=smooth_) self.surf = self.scene.mlab.pipeline.surface( surface_mesh_smooth, colormap=self.cmap) self.scene.mlab.colorbar() self.text = self.scene.mlab.text(0.7, 0.9, info_time, width=0.2) self.scene.background = (.05, 0, .1) else: self.surf.mlab_source.set(scalars=d) self.text.set(text=info_time) # The layout of the dialog created view = View( Item('scene', editor=SceneEditor(scene_class=MayaviScene), height=800, width=800, show_label=False), Group( '_', 'n_times', ), resizable=True, )
class Maya3DScene(HasTraits): scene = Instance(MlabSceneModel, ()) plot = Instance(PipelineBase) def __init__(self, volumeEditor, overlayItemReference, raw): HasTraits.__init__(self) self.volumeEditor = volumeEditor self.overlayItemReference = overlayItemReference self.raw = raw #print self.item.shape, self.item.dtype # When the scene is activated, or when the parameters are changed, we # update the plot. @on_trait_change('scene.activated') def update_plot(self): if self.plot is None: stuff = self.overlayItemReference._data[ 0, :, :, :, self.overlayItemReference.channel] print stuff.__class__ print stuff.shape, stuff.dtype self.dataField = self.scene.mlab.pipeline.scalar_field(stuff) self.rawField = self.scene.mlab.pipeline.scalar_field(self.raw) # self.xp = self.scene.mlab.pipeline.image_plane_widget(self.rawField, # plane_orientation='x_axes', # slice_index=10 # ) # def move_slicex(obj, evt): # #print obj # print obj.GetCurrentCursorPosition() # print self.xp.ipw.slice_position # # self.xp.ipw.add_observer('EndInteractionEvent', move_slicex) # # self.yp = self.scene.mlab.pipeline.image_plane_widget(self.rawField, # plane_orientation='y_axes', # slice_index=10 # ) # def move_slicey(obj, evt): # #print obj # print obj.GetCurrentCursorPosition() # print self.yp.ipw.slice_position # # self.yp.ipw.add_observer('EndInteractionEvent', move_slicey) # # self.zp = self.scene.mlab.pipeline.image_plane_widget(self.rawField, # plane_orientation='z_axes', # slice_index=10 # ) # def move_slicez(obj, evt): # #print obj # print obj.GetCurrentCursorPosition() # print self.zp.ipw.slice_position # # self.zp.ipw.add_observer('EndInteractionEvent', move_slicez) self.plot = self.scene.mlab.pipeline.iso_surface( self.dataField, contours=[1, 2]) #opacity=0.4 # cm = numpy.zeros((256,4),'uint8')#self.plot.module_manager.scalar_lut_manager.lut.table.to_array() # # cm[:,3] = 255 # # for index in range(0,255): # c = self.overlayItemReference.colorTable[index] # c = QtGui.QColor.fromRgba(c) # print index, " ", c.red(), " ", c.green() # cm[index,0] = c.red() # cm[index,1] = c.green() # cm[index,2] = c.blue() # # mlab.colorbar(title="LUT", orientation="vertical") # # self.plot.module_manager.scalar_lut_manager.lut.number_of_colors = 256 # self.plot.module_manager.scalar_lut_manager.lut.table_range = (0,255) # self.plot.module_manager.scalar_lut_manager.lut.range = (0,255) # self.plot.module_manager.scalar_lut_manager.lut.value_range = (0,255) # self.plot.module_manager.scalar_lut_manager.lut.vector_mode = 'magnitude' # self.plot.module_manager.scalar_lut_manager.lut.table = cm # # # print self.plot # # print self.plot.module_manager.scalar_lut_manager.lut #self.scene.mlab.pipeline.volume(self.scene.mlab.pipeline.scalar_field(self.item._data[0,:,:,:,0]), vmin=0.5, vmax=1.5) #self.scene.mlab.outline() else: self.plot.mlab_source.set(self.item._data[0, :, :, :, 0]) az, elev, dist, focal = self.scene.mlab.view() self.scene.mlab.view(-90, 175, dist, focal) # <- top view self.scene.picker.pointpicker.add_observer('EndPickEvent', self.picker_callback) self.mvt_picker = MvtPicker(self.scene.picker.pointpicker, self.scene) self.scene.interactor.add_observer('LeftButtonPressEvent', self.mvt_picker.on_button_press) self.scene.interactor.add_observer('MouseMoveEvent', self.mvt_picker.on_mouse_move) self.scene.interactor.add_observer('LeftButtonReleaseEvent', self.mvt_picker.on_button_release) def picker_callback(self, picker_obj, evt): print self.scene.mlab.view() picker_obj = tvtk.to_tvtk(picker_obj) position = picker_obj.pick_position self.volumeEditor.changeSlice(int(position[0] - 1), 0) self.volumeEditor.changeSlice(int(position[1] - 1), 1) self.volumeEditor.changeSlice(int(position[2] - 1), 2) # The layout of the dialog created view = View(Item('scene', editor=SceneEditor(scene_class=MayaviScene), height=480, width=640, show_label=False), resizable=True)