1

I have a Traits and Mayavi script that presents an mlab scene and several traits editors. The editors affect what data is shown in a surface, quiver3d and legend (Scalar LUT Manager) by calling my drawing method. Each change triggers a clear figure and re-draw.

Learning from the Mlab interactive dialog example the plot3d* uses mlab_source.set to change the data without clearing the figure and re-drawing. In update_plot():

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)

What my surface and quiver3d calls return are mayavi.modules.surface.Surface and mayavi.modules.vectors.Vectors objects respectively. Surface and LUTManager report no mlab_source: AttributeError: 'Surface'/'LUTManager' object has no attribute 'mlab_source'. Quiver3d reports an mayavi.tools.sources.MGlyphSource

1) How can I change the data/source in my surface and scalar LUTManager?

2) How do I correctly change the quiver’s data/source?

When I attempt to change the values of the quiver I get a TraitError: Cannot set the undefined 'u' attribute of a 'Vectors' object. This puzzles me because I used the six-value initializer.

if self.quiver is None:
    self.quiver = self.scene.mlab.quiver3d(xyz[:,0], xyz[:,1], xyz[:,2],
        velocity[:,0], velocity[:,1], velocity[:,2], 
        figure=self.scene.mayavi_scene, scale_factor = self.scale)
else:
    self.quiver.mlab_source.set(x = xyz[:,0], y = xyz[:,1], z = xyz[:,2],
            u = velocity[:,0], v = velocity[:,1], w = velocity[:,2])

In the example the plot3d returns a mayavi.modules.surface.Surface and its mlab_source object is a mayavi.tools.sources.MLineSource. Searching the docs for MLineSource is fruitless but externally yields Enthought Tool Suite 3.2 results. Are the Tool Suite docs current?

*self.plot, self.surface and self.quiver are declared as variable = Instance(PipelineBase). PipelineBase is imported from mayavi.core.api.

Community
  • 1
  • 1
fearmint
  • 5,276
  • 2
  • 33
  • 45
  • I played around with `quiver3d` on some random data and accessing/setting `mlab_source.u` is no problem. Can you provide a self-contained script that reproduces your problem (which need not have traitsui elements)? – aestrivex Jun 03 '14 at 19:12
  • Extracting everything out of Traits, I was able to 1) show a figure with the parameter `stop=True`, 2) stop it -letting my script continue-, 3) after the method call to show: change the quiver data with `mlab_source.set()` and 4) re-show the scene with the updated data. The `surface` and `LUTManager` report no attribute `mlab_source`. Am I correct to stop showing the scene and then re-show it? Is there anything else I can provide to help? Will the surface and legend only ever be updated through a clear figure? – fearmint Jun 04 '14 at 13:51
  • Whether or not you call `mlab.show()` or are using traitsui should have nothing to do with whether or not you can update the figure. How are you generating the surface? – aestrivex Jun 04 '14 at 16:12
  • It is a `tvtk.PolyData` which has an array of vertices (float, float, float) and an array of triangles (int, int, int). Its `scalars` are an array of floats. Like so: `mesh = tvtk.PolyData(points=vertices, polys=triangles) mesh.cell_data.scalars = z mesh.cell_data.update() self.surface = self.scene.mlab.pipeline.surface(mesh,transparent=True, figure=self.scene.mayavi_scene)` – fearmint Jun 04 '14 at 22:22

1 Answers1

2

Based on your comments:

The reason there is no reference to an mlab source in surface is because there is no mlab source. Your module just consists of a raw vtk source, which mayavi is perfectly happy to render unadulterated. However you retain a reference to the PolyData and so you could edit the scalars from that. (You could also use mlab.triangular_mesh which very likely does what you want while introducing an intervening TriangularMeshSource to control the vtk PolyData).

You can get to the LUT with surface.module_manager.scalar_lut_manager.

And you should also be able to get to the mlab level source for the vectors as in the comments, I don't know what is the problem with that if there still is one. The use of traitsui should not have an effect -- the problem is probably a conflict between mayavi and your object model. Try setting the trait type of your mayavi objects to be Any.

aestrivex
  • 5,170
  • 2
  • 27
  • 44
  • Thank you! Now I have it smoothly animating. The data is not entirely right, but I’ll work that part out. – fearmint Jun 06 '14 at 14:17
  • Fixed the surface data not displaying entirely right. I needed to stop using `self.mesh.points = vertices` and `self.mesh.polys = triangles` but instead use `self.mesh.set(points = vertices, polys = triangles)` in my update_plot method. – fearmint Jun 06 '14 at 14:27
  • Hmm. Now updating the quiver’s scale_factor through `mlab_source.scale_factor` and `mlab_source.set(scale_factor = ` don’t seem to be working. An odd part is that logging the scale before and after changing it shows that mlab_source receives the updates. (I may end up asking another question about animating a quiver’s scale factor). – fearmint Jun 06 '14 at 15:18
  • 1
    Do you really mean `mlab_source.scale_factor`? I just conjured a random `mlab.quiver3d` and it has no `mlab_source.scale_factor`. But if you open the `edit_traits` window provided by mayavi, it shows you that it has a `glyph.glyph.scale_factor` which is what you can adjust. – aestrivex Jun 06 '14 at 22:30
  • Hi can you please tell me how you can set the scalar in polydata object. I succeeded using a triangular mesh for a regular 3d mesh but now I have another mesh which has irregular vertices. So I have to use polydata objects. But how can I set its scalar which animating. – ssm Sep 23 '14 at 15:03