Example #1
0
def load_vtk(temp_vtk_path_file,
             engine,
             datatitle,
             visible=True,
             useCBar=True):
    # Clear current scene of possible vtk and potential electrode
    engine.scenes[0].children[0:2] = []
    # Add file data to engine
    #print('\nOpening: '+temp_vtk_path_file)
    src = engine.open(temp_vtk_path_file)

    if visible:
        # Add surface module to make data visible
        engine.add_filter(Surface(), src)

    # Populate list of indices of the scalars, within the vtk, that have datatitle as part of its name
    datalist = []
    for dataID, dataname in enumerate(src._cell_scalars_list):
        if datatitle in dataname:
            datalist.append(dataID)

    if useCBar:
        # Make colorbar visible, oriented, scaled, and positioned
        module_manager = src.children[0]
        module_manager.scalar_lut_manager.show_scalar_bar = True
        module_manager.scalar_lut_manager.scalar_bar_representation.orientation = 0
        #module_manager.scalar_lut_manager.scalar_bar.orientation = 'horizontal'
        module_manager.scalar_lut_manager.scalar_bar_representation.position2 = np.array(
            [0.8, 0.1])  #size
        module_manager.scalar_lut_manager.scalar_bar_representation.position = np.array(
            [0.1, 0.87])  #position of bottom-left-most point
        module_manager.scalar_lut_manager.scalar_bar.maximum_number_of_colors = 21  #limits color range for consistent gif colors
        #[0.1, 0.01] for bottom alignment

    return src, datalist
Example #2
0
    def setUp(self):
        """Initial setting up of test fixture, automatically called by
        TestCase before any other test method is invoked"""

        e = NullEngine()
        # Uncomment to see visualization for debugging etc.
        #e = Engine()
        e.start()
        s = e.new_scene()

        poly_data = BuiltinSurface()
        e.add_source(poly_data)

        outline = Outline()
        e.add_module(outline)

        surface = Surface()
        e.add_module(surface)

        poly_data.data_source.shaft_radius = 0.05
        poly_data.data_source.shaft_resolution = 7
        poly_data.data_source.tip_radius = 0.1

        self.e = e
        self.scene = e.current_scene

        return
Example #3
0
def get_mayavi_cubic_arena_source(engine, info=None):

    v = info['verts4x4']  # arranged in 2 rectangles of 4 verts

    points = v
    lines = [[0, 1], [1, 2], [2, 3], [3, 0], [4, 5], [5, 6], [6, 7], [7, 4],
             [0, 4], [1, 5], [2, 6], [3, 7]]

    if 0:
        import enthought.mayavi.tools.mlab as mlab
        for lineseg in lines:
            p0 = points[lineseg[0]]
            p1 = points[lineseg[1]]
            x = np.array([p0[0], p1[0]])
            y = np.array([p0[1], p1[1]])
            z = np.array([p0[2], p1[2]])
            mlab.plot3d(x, y, z)

    #polys = numpy.arange(0, len(points), 1, 'l')
    #polys = numpy.reshape(polys, (len(points), 1))
    pd = tvtk.PolyData(
        points=points,  #polys=polys,
        lines=lines)

    e = engine
    e.add_source(VTKDataSource(data=pd, name='cubic arena'))

    s = Surface()
    e.add_module(s)
Example #4
0
    def test_3d_data(self):
        "Test for 3D data arrays."
        # Add a 3D data source
        d = self.data
        sc, vec = self.make_3d_data()
        d.scalar_data = sc
        d.vector_data = vec
        d.start()  # Start the object so it flushes the pipeline etc.

        # Create an outline for the data.
        o = Outline()
        d.add_child(o)
        o.start()
        self.assertEqual(tuple(o.actor.actor.bounds), (0, 1., 0., 1., 0., 1.))
        # Create a surface module.
        surf = Surface()
        d.add_child(surf)
        self.assertEqual(surf.running, True)

        tps = numpy.transpose
        expect = [tps(sc), tps(vec, (2, 1, 0, 3))]
        sc2 = surf.actor.mapper.input.point_data.scalars.to_array()
        self.assertEqual(numpy.allclose(sc2.flatten(), expect[0].flatten()),
                         True)
        vec2 = surf.actor.mapper.input.point_data.vectors.to_array()
        self.assertEqual(numpy.allclose(vec2.flatten(), expect[1].flatten()),
                         True)
Example #5
0
    def test_2d_data(self):
        """Generic tests for 2D data arrays."""
        d = self.data
        sc, vec = self.make_2d_data()
        d.origin = (-1, -1, 0)
        d.scalar_data = sc
        d.vector_data = vec
        d.start()  # Start the object so it flushes the pipeline etc.

        # Create an outline for the data.
        o = Outline()
        d.add_child(o)
        o.start()
        self.assertEqual(tuple(o.actor.actor.bounds),
                         (-1., 0., -1., 0., 0., 0.))
        # Create a surface module.
        surf = Surface()
        d.add_child(surf)
        self.assertEqual(surf.running, True)

        tps = numpy.transpose
        expect = [tps(sc), tps(vec, (1, 0, 2))]
        sc1 = surf.actor.mapper.input.point_data.scalars.to_array()
        self.assertEqual(numpy.allclose(sc1.flatten(), expect[0].flatten()),
                         True)
        vec1 = surf.actor.mapper.input.point_data.vectors.to_array()
        self.assertEqual(numpy.allclose(vec1.flatten(), expect[1].flatten()),
                         True)
Example #6
0
    def setUp(self):

        e = NullEngine()
        # Uncomment to see visualization for debugging etc.
        # e = Engine()
        e.start()
        s = e.new_scene()

        image_data = BuiltinImage()
        e.add_source(image_data)

        outline = Outline()
        e.add_module(outline)

        surface = Surface()
        e.add_module(surface)

        image_data.data_source.radius = array([80., 80., 80.])
        image_data.data_source.center = array([150., 150., 0.])
        image_data.data_source.whole_extent = array([10, 245, 10, 245, 0, 0])
        if is_old_pipeline():
            image_data.data_source.update_whole_extent()
        elif vtk_major_version < 8:
            image_data.data_source.set_update_extent_to_whole_extent()

        self.e = e
        self.scene = e.current_scene

        return
def view():
    from mayavi.modules.surface import Surface
    from simphony_mayavi.sources.api import CUDSSource

    mayavi.new_scene()  # noqa
    src = CUDSSource(cuds=mesh_inside_wrapper)
    mayavi.add_source(src)  # noqa
    s = Surface()
    mayavi.add_module(s)  # noqa
def view(dataset):
    from mayavi.modules.surface import Surface
    from simphony_mayavi.sources.api import CUDSSource

    mayavi.new_scene()  # noqa
    src = CUDSSource(cuds=dataset)
    mayavi.add_source(src)  # noqa
    s = Surface()
    mayavi.add_module(s)  # noqa
Example #9
0
def view():
    from mayavi.sources.vtk_data_source import VTKDataSource
    from mayavi.modules.surface import Surface

    mayavi.new_scene()
    src = VTKDataSource(data=mesh)
    mayavi.add_source(src)
    s = Surface()
    mayavi.add_module(s)
Example #10
0
def surf_regular():
    """Now visualize the data as done in mlab.
    """
    w = WarpScalar()
    mayavi.add_filter(w)
    o = Outline()
    s = Surface()
    mayavi.add_module(o)
    mayavi.add_module(s)
Example #11
0
def bathymetry(engine):
    cell_to_point_data = CellToPointData()
    engine.add_filter(cell_to_point_data)
    surface = Surface()
    engine.add_module(surface)
    module_manager = cell_to_point_data.children[0]
    module_manager.scalar_lut_manager.lut_mode = 'gist_earth'
    surface.actor.actor.scale = np.array([1., 1., 100.])
    surface.actor.actor.position = np.array([0., 0., 1000.])
Example #12
0
def cylinder(engine, radius, height, resolution):
    test = BuiltinSurface()
    test.source = 'cylinder'
    test.data_source.center = np.array([0., 0., 0.])
    test.data_source.radius = radius
    test.data_source.height = height
    test.data_source.capping = False
    test.data_source.resolution = resolution
    test_surface = Surface()
    engine.add_source(test)
    engine.add_filter(test_surface)
Example #13
0
def view():
    from mayavi.sources.vtk_data_source import VTKDataSource
    from mayavi.modules.outline import Outline
    from mayavi.modules.surface import Surface
    from mayavi.modules.vectors import Vectors

    mayavi.new_scene()
    # The single type one
    src = VTKDataSource(data = ug1)
    mayavi.add_source(src)
    mayavi.add_module(Outline())
    mayavi.add_module(Surface())
    mayavi.add_module(Vectors())

    # Mixed types.
    src = VTKDataSource(data = ug2)
    mayavi.add_source(src)
    mayavi.add_module(Outline())
    mayavi.add_module(Surface())
    mayavi.add_module(Vectors())
def view():
    from mayavi.sources.vtk_data_source import VTKDataSource
    from mayavi.modules.outline import Outline
    from mayavi.modules.surface import Surface
    from mayavi.modules.vectors import Vectors
    from mayavi.filters.api import WarpVector, ExtractTensorComponents

    mayavi.new_scene()
    # The single type one
    src = VTKDataSource(data=ug)
    mayavi.add_source(src)
    warp_vector = WarpVector()
    mayavi.add_filter(warp_vector, src)
    surface = Surface()
    mayavi.add_filter(surface, warp_vector)

    etc = ExtractTensorComponents()
    mayavi.add_filter(etc, warp_vector)
    surface2 = Surface()
    mayavi.add_filter(surface2, etc)
    etc.filter.scalar_mode = 'component'
Example #15
0
def view():
    from mayavi.sources.vtk_data_source import VTKDataSource
    from mayavi.filters.warp_scalar import WarpScalar
    from mayavi.filters.poly_data_normals import PolyDataNormals
    from mayavi.modules.surface import Surface

    mayavi.new_scene()
    src = VTKDataSource(data = spoints)
    mayavi.add_source(src)
    mayavi.add_filter(WarpScalar())
    mayavi.add_filter(PolyDataNormals())
    s = Surface()
    mayavi.add_module(s)
    def test_that_custom_views_are_loaded(self):
        # Given/When
        s = Surface()

        # Then
        self.assertTrue(os.path.exists(s._view_filename))
        self.assertTrue(s._module_view is not None)
        self.assertTrue(isinstance(s._module_view, View))

        # When there is no view, it should work safely.
        # Given/When
        o = Outline()

        # Then
        self.assertFalse(os.path.exists(o._view_filename))
        self.assertEqual(o._module_view, None)
Example #17
0
    def test_pickle(self):
        "Test if pickling works."

        # Test if saving a visualization and restoring it works.
        d = self.data
        sc, vec = self.make_3d_data()
        d.scalar_data = sc
        d.vector_data = vec
        d.spacing = [1, 2, 3]
        d.origin = [4, 5, 6]
        d.start()  # Start the object so it flushes the pipeline etc.

        # Create an outline for the data.
        o = Outline()
        d.add_child(o)
        o.start()
        # Create a surface module.
        surf = Surface()
        d.add_child(surf)

        data = pickle.dumps(d)
        del d, surf, o
        d = pickle.loads(data)
        # We must explicitly start the object.
        d.start()
        mm = d.children[0]
        o, surf = mm.children

        # Test the unpciked state.
        self.assertEqual(tuple(o.actor.actor.bounds), (4., 5., 5., 7., 6., 9.))
        self.assertEqual(surf.running, True)
        self.assertEqual(o.running, True)
        self.assertEqual(d.running, True)
        self.assertEqual(numpy.allclose(d.spacing, [1, 2, 3]), True)
        self.assertEqual(numpy.allclose(d.origin, [4, 5, 6]), True)

        tps = numpy.transpose
        expect = [tps(sc), tps(vec, (2, 1, 0, 3))]
        sc2 = surf.actor.mapper.input.point_data.scalars.to_array()
        self.assertEqual(numpy.allclose(sc2.flatten(), expect[0].flatten()),
                         True)
        vec2 = surf.actor.mapper.input.point_data.vectors.to_array()
        self.assertEqual(numpy.allclose(vec2.flatten(), expect[1].flatten()),
                         True)
Example #18
0
def waterlevel(engine):
    cell_to_point_data = CellToPointData()
    engine.add_filter(cell_to_point_data)
    warp_scalar = WarpScalar()
    # use data as z
    # scale z
    warp_scalar.filter.normal = np.array([0., 0., 1.])
    # scale it up a bit
    warp_scalar.filter.scale_factor = 100.0
    engine.add_filter(warp_scalar)
    surface = Surface()
    engine.add_module(surface)
    # raise it a bit
    surface.actor.actor.position = np.array([0., 0., 1000.])
    surface.actor.property.opacity = 0.7

    # color normal scale
    module_manager = warp_scalar.children[0]
    module_manager.scalar_lut_manager.lut_mode = 'YlGnBu'
    module_manager.scalar_lut_manager.data_range = np.array([-1.5, 1.5])
def main():
    # Create some random points to view.
    pd = tvtk.PolyData()
    pd.points = np.random.random((1000, 3))
    verts = np.arange(0, 1000, 1)
    verts.shape = (1000, 1)
    pd.verts = verts
    pd.point_data.scalars = np.random.random(1000)
    pd.point_data.scalars.name = 'scalars'

    # Now visualize it using mayavi2.
    from mayavi.sources.vtk_data_source import VTKDataSource
    from mayavi.modules.outline import Outline
    from mayavi.modules.surface import Surface

    mayavi.new_scene()
    d = VTKDataSource()
    d.data = pd
    mayavi.add_source(d)
    mayavi.add_module(Outline())
    s = Surface()
    mayavi.add_module(s)
    s.actor.property.trait_set(representation='p', point_size=2)
Example #20
0
    def do(self):
        ############################################################
        # Imports.
        script = self.script
        from mayavi.sources.array_source import ArraySource
        from mayavi.modules.outline import Outline
        from mayavi.modules.surface import Surface
        from mayavi.modules.vectors import Vectors

        ############################################################
        # Create a new scene and set up the visualization.
        s = self.new_scene()

        d = ArraySource()
        self.check_input_validation(d)
        sc, vec = self.make_2d_data()
        d.origin = (-1, -1, 0)
        d.scalar_data = sc
        d.vector_data = vec

        script.add_source(d)

        # Create an outline for the data.
        o = Outline()
        script.add_module(o)
        # View the data.
        s = Surface()
        script.add_module(s)
        v = Vectors()
        script.add_module(v)

        # Add a 3D data source
        d = ArraySource()
        sc, vec = self.make_3d_data()
        d.scalar_data = sc
        d.vector_data = vec
        script.add_source(d)
        # Create an outline for the data.
        o = Outline()
        script.add_module(o)
        # View a slice.
        s = Surface()
        script.add_module(s)
        v = Vectors()
        script.add_module(v)

        # Set the scene to a suitable view.
        s.scene.z_plus_view()
        c = s.scene.camera
        c.azimuth(-30)
        c.elevation(30)

        self.check()

        ############################################################
        # Test if saving a visualization and restoring it works.

        bg = s.scene.background
        # Save visualization.
        f = StringIO()
        f.name = abspath('test.mv2')  # We simulate a file.
        script.save_visualization(f)
        f.seek(0)  # So we can read this saved data.

        # Remove existing scene.
        engine = script.engine
        engine.close_scene(s)

        # Load visualization
        script.load_visualization(f)
        s = engine.current_scene

        # Set the scene to a suitable view.
        s.scene.z_plus_view()
        c = s.scene.camera
        c.azimuth(-30)
        c.elevation(30)
        s.scene.background = bg

        self.check()

        ############################################################
        # Test if the MayaVi2 visualization can be deepcopied.

        # Pop the source object.
        sources = s.children
        s.children = []
        # Add it back to see if that works without error.
        s.children.extend(sources)

        s.scene.reset_zoom()

        self.check()

        # Now deepcopy the source and replace the existing one with
        # the copy.  This basically simulates cutting/copying the
        # object from the UI via the right-click menu on the tree
        # view, and pasting the copy back.
        sources1 = copy.deepcopy(sources)
        s.children[:] = sources
        s.scene.reset_zoom()
        self.check()
Example #21
0
# Recorded script from Mayavi2
from numpy import array
from mayavi import mlab
try:
    engine = mayavi.engine
except NameError:
    from mayavi.api import Engine
    engine = Engine()
    engine.start()
if len(engine.scenes) == 0:
    engine.new_scene()
# ------------------------------------------- 
vtk_file_reader = engine.open('/home/dori/develop/pySAM/vtk/_55_1.11595_1.70081e-05.vtk')
from mayavi.modules.surface import Surface
surface = Surface()
engine.add_filter(surface, vtk_file_reader)
mlab.savefig('scene.png')
def draw(vtk_files,
         coords_file,
         conn_list=None,
         brain_rgba=(0.5, 0.5, 0.5, 0.2),
         node_rgba=(0.30, 0.69, 1.0, 1.0),
         node_rad=2.5,
         conn_thr=[0.75, 1.0],
         conn_cmap='YlOrRd'):

    ### Setup the engine and scene
    my_engine = Engine()
    my_engine.start()

    # Create a new scene
    my_scene = my_engine.new_scene()

    # Set background
    my_scene.scene.background = (1.0, 1.0, 1.0)

    # Initialize the rendering
    my_scene.scene.disable_render = True

    # Import VTK file to pipeline
    for vtk_file in vtk_files:
        vtk_source = my_engine.open(vtk_file)

        # Render surface
        vtk_surface = Surface()
        my_engine.add_module(vtk_surface, obj=vtk_source)
        vtk_surface.actor.property.specular_color = brain_rgba[:3]
        vtk_surface.actor.property.diffuse_color = brain_rgba[:3]
        vtk_surface.actor.property.ambient_color = brain_rgba[:3]
        vtk_surface.actor.property.color = brain_rgba[:3]
        vtk_surface.actor.property.opacity = brain_rgba[3]

    # Reset camera
    my_scene.scene.disable_render = False
    my_scene.scene.reset_zoom()

    ### Sensor-Locations
    # Load Coordinates in MRI-space
    node_coords = np.loadtxt(coords_file, delimiter=',')
    n_node = node_coords.shape[0]
    n_conn = np.int(n_node * (n_node - 1) * 0.5)

    # Import coordinates into pipeline
    crd_source = mlab.pipeline.scalar_scatter(node_coords[:, 0],
                                              node_coords[:, 1],
                                              node_coords[:, 2])
    # Render Glyphs for node points
    crd_surface = mlab.pipeline.glyph(crd_source,
                                      scale_mode='none',
                                      scale_factor=node_rad,
                                      mode='sphere',
                                      colormap='cool',
                                      color=node_rgba[:3],
                                      opacity=node_rgba[3])

    ### Connection-Locations
    if conn_list is None:
        return
    assert len(conn_list) == n_conn

    # Generate all vectors
    e_start = np.zeros((n_conn, 3))
    e_vec = np.zeros((n_conn, 3))

    triu_ix, triu_iy = np.triu_indices(n_node, k=1)

    for ii, (ix, iy) in enumerate(zip(triu_ix, triu_iy)):
        e_start[ii, :] = node_coords[ix, :]
        e_vec[ii, :] = 1e-3 * (node_coords[iy, :] - node_coords[ix, :])

    # Import vectors (connections) into pipeline
    edg_source = mlab.pipeline.vector_scatter(e_start[:, 0], e_start[:, 1],
                                              e_start[:, 2], e_vec[:, 0],
                                              e_vec[:, 1], e_vec[:, 2])
    edg_source.mlab_source.dataset.point_data.scalars = conn_list

    edg_thresh = mlab.pipeline.threshold(
        edg_source,
        low=np.percentile(conn_list, 100 * conn_thr[0]),
        up=np.percentile(conn_list, 100 * conn_thr[1]))
    edg_thresh.auto_reset_lower = False
    edg_thresh.auto_reset_upper = False

    edg_surface = mlab.pipeline.vectors(edg_thresh,
                                        colormap=conn_cmap,
                                        line_width=3.0,
                                        scale_factor=1000,
                                        scale_mode='vector')

    edg_surface.glyph.glyph.clamping = False
    edg_surface.actor.property.opacity = 0.75
    edg_surface.module_manager.vector_lut_manager.reverse_lut = True

    edg_surface.glyph.glyph_source.glyph_source = (
        edg_surface.glyph.glyph_source.glyph_dict['glyph_source2d'])
    edg_surface.glyph.glyph_source.glyph_source.glyph_type = 'dash'
Example #23
0
    def view(prefix, name):
        """
        construct a generic visualization of base mesh, refined mesh,
        and potential/field/pseudopotential data in mayavi2
        requires running within mayavi2 or ipython with threads or
        something like::

            from pyface.api import GUI
            GUI().start_event_loop()

        in your script to interact with it.

        this is from a simplified macro recorded in mayavi2
        """
        try:
            engine = mayavi.engine
        except NameError:
            from mayavi.api import Engine
            engine = Engine()
            engine.start()

        if len(engine.scenes) == 0:
            engine.new_scene()

        scene = engine.scenes[0]

        base_mesh_name = "%s_mesh.vtk" % prefix
        if os.access(base_mesh_name, os.R_OK):
            base_mesh = engine.open(base_mesh_name)
            surface = Surface()
            engine.add_filter(surface, base_mesh)
            surface.actor.property.representation = 'wireframe'
            surface.actor.property.line_width = 1

        mesh_name = "%s_%s_mesh.vtk" % (prefix, name)
        if os.access(mesh_name, os.R_OK):
            mesh = engine.open(mesh_name)
            mesh.cell_scalars_name = 'charge'
            surface = Surface()
            engine.add_filter(surface, mesh)
            module_manager = mesh.children[0]
            module_manager.scalar_lut_manager.lut_mode = 'RdBu'
            module_manager.scalar_lut_manager.use_default_range = False
            r = np.fabs(module_manager.scalar_lut_manager.data_range).max()
            module_manager.scalar_lut_manager.data_range = [-r, r]
            surface.actor.property.backface_culling = True

        data_name = "%s_%s.vtk" % (prefix, name)
        if os.access(data_name, os.R_OK):
            data = engine.open(data_name)
            if "pseudo_potential" in data._point_scalars_list:
                data.point_scalars_name = "pseudo_potential"
            else:
                data.point_scalars_name = "potential"
            iso_surface = IsoSurface()
            engine.add_filter(iso_surface, data)
            module_manager = data.children[0]
            module_manager.scalar_lut_manager.lut_mode = 'Greys'
            iso_surface.contour.auto_contours = True
            iso_surface.contour.number_of_contours = 5
            try:
                iso_surface.contour.maximum_contour = 1e-2
            except:
                pass

        scene.scene.isometric_view()
        scene.scene.render()
Example #24
0
from numpy import array
from mayavi.modules.axes import Axes
from mayavi.api import Engine
from mayavi.modules.surface import Surface
from mayavi.tools.show import show

try:
    engine = mayavi.engine
except NameError:
    engine = Engine()
    engine.start()
if len(engine.scenes) == 0:
    engine.new_scene()

scene = engine.scenes[0]
vtk_file_reader = engine.open(sys.argv[1], scene)
axes = Axes()
axes.property.color = (0.0, 0.0, 0.0)
engine.add_filter(axes, vtk_file_reader)
surface = Surface()
engine.add_filter(surface, vtk_file_reader)
scene.scene.background = (1.0, 1.0, 1.0)
scene.scene.foreground = (0.0, 0.0, 0.0)
surface.contour.contours = [1.5]
surface.actor.mapper.progress = 1.0
surface.actor.mapper.scalar_range = array([ 0.,  3.])
surface.enable_contours = True

show()
Example #25
0
    def view(prefix, name):
        """
        construct a generic visualization of base mesh, refined mesh,
        and potential/field/pseudopotential data in mayavi2
        requires running within mayavi2 or ipython with threads or
        something like::

            from pyface.api import GUI
            GUI().start_event_loop()

        in your script to interact with it.

        this is from a simplified macro recorded in mayavi2
        """
        """
        wwc 11/23/2018
        In both python 2.7 and 3.5, this 3D visualization with mayavi 
        works in Linux, but it's not compatible with X11 remote forwarding. 
        Install mayavi through conda channel "menpo" in python 3.5 or just 
        see environment setup of "ele35" in README. However, I haven't 
        found a mayavi version for python 3.6.
        """

        import mayavi
        try:
            from mayavi.api import Engine
            engine = Engine()
            engine.start()
        except AttributeError: # NameError:
            engine = mayavi.engine

        if len(engine.scenes) == 0:
            engine.new_scene()

        scene = engine.scenes[0]

        base_mesh_name = "%s_mesh.vtk" % prefix
        if os.access(base_mesh_name, os.R_OK):
            base_mesh = engine.open(base_mesh_name)
            surface = Surface()
            engine.add_filter(surface, base_mesh)
            surface.actor.property.representation = 'wireframe'
            surface.actor.property.line_width = 1

        mesh_name = "%s_%s_mesh.vtk" % (prefix, name)
        if os.access(mesh_name, os.R_OK):
            mesh = engine.open(mesh_name)
            mesh.cell_scalars_name = 'charge'
            surface = Surface()
            engine.add_filter(surface, mesh)
            module_manager = mesh.children[0]
            module_manager.scalar_lut_manager.lut_mode = 'RdBu'
            module_manager.scalar_lut_manager.use_default_range = False
            r = np.fabs(module_manager.scalar_lut_manager.data_range).max()
            module_manager.scalar_lut_manager.data_range = [-r, r]
            surface.actor.property.backface_culling = True

        data_name = "%s_%s.vtk" % (prefix, name)
        if os.access(data_name, os.R_OK):
            data = engine.open(data_name)
            if "pseudo_potential" in data._point_scalars_list:
                data.point_scalars_name = "pseudo_potential"
            else:
                data.point_scalars_name = "potential"
            iso_surface = IsoSurface()
            engine.add_filter(iso_surface, data)
            module_manager = data.children[0]
            module_manager.scalar_lut_manager.lut_mode = 'Greys'
            iso_surface.contour.auto_contours = True
            iso_surface.contour.number_of_contours = 5
            try:
                iso_surface.contour.maximum_contour = 1e-2
            except:
                pass

        scene.scene.isometric_view()
        scene.scene.render()
Example #26
0
    def test_script_recording(self):
        "Does script recording work correctly."
        # Create a mayavi pipeline and record it.
        tape = self.tape
        e = NullEngine()
        e.start()
        # Start recording.
        tape.recording = True
        tape.register(e, known=True, script_id='engine')
        e.new_scene()
        #print tape.script
        self.assertEqual(tape.lines[-1],
                         "dummy_viewer = engine.new_scene()")

        src = ParametricSurface()
        e.add_source(src)
        expect = 'from mayavi.sources.parametric_surface '\
                 'import ParametricSurface'
        self.assertEqual(tape.lines[-3], expect)
        self.assertEqual(tape.lines[-2],
                         "parametric_surface = ParametricSurface()")
        self.assertEqual(tape.lines[-1],
                         "engine.add_source(parametric_surface)")

        src.function = 'dini'
        self.assertEqual(tape.lines[-1],
                         "parametric_surface.function = 'dini'")

        o = Outline()
        e.add_module(o)
        expect = 'from mayavi.modules.outline import Outline'
        self.assertEqual(tape.lines[-3], expect)
        self.assertEqual(tape.lines[-2], "outline = Outline()")
        self.assertEqual(tape.lines[-1],
                         "engine.add_module(outline)")

        o.actor.property.color = (1,0,0)
        self.assertEqual(tape.lines[-1],
                         "outline.actor.property.color = (1.0, 0.0, 0.0)")

        s = Surface()
        e.add_module(s)
        expect = 'from mayavi.modules.surface import Surface'
        self.assertEqual(tape.lines[-3], expect)
        self.assertEqual(tape.lines[-2], "surface = Surface()")
        self.assertEqual(tape.lines[-1],
                         "engine.add_module(surface)")

        s.actor.property.representation = 'wireframe'
        self.assertEqual(tape.lines[-1],
                         "surface.actor.property.representation = 'wireframe'")

        o.actor.property.representation = 'wireframe'
        self.assertEqual(tape.lines[-1],
                         "outline.actor.property.representation = 'wireframe'")

        s.actor.property.opacity = 0.5
        self.assertEqual(tape.lines[-1],
                         "surface.actor.property.opacity = 0.5")

        s.actor.mapper.scalar_visibility = False
        self.assertEqual(tape.lines[-1],
                         "surface.actor.mapper.scalar_visibility = False")

        #print tape.script

        # Stop recording and test.
        tape.unregister(e)
        tape.record('#end') # Placeholder
        o.actor.property.opacity = 0.5
        self.assertEqual(tape.lines[-1], '#end')
        s.actor.property.color = (1,0,0)
        self.assertEqual(tape.lines[-1], '#end')
        s.enable_contours = True
        self.assertEqual(tape.lines[-1], '#end')
        src.function = 'klein'
        self.assertEqual(tape.lines[-1], '#end')
Example #27
0
    def depth_slice(self,
                    depth_km="surface",
                    save=None,
                    show=True,
                    startup=True,
                    anno_text=None):
        """
        Plot a topdown view of the model, either with a surface projection
        (map view) or at some depth slice determined by `depth_km`

        :type depth_km: float or None
        :param depth_km: depth to show the model at in units of km, by default
            plots a map view of the 'surface'
        :type save: str
        :param save: save the figure with a unique generic identifier
        :type show: bool
        :param show: show the figure after making it
        :type startup: bool
        :param startup: run the _startup() function which closes all instances
            of mlab and creates a new mlab figure and engine. Normally the
            necessary thing to do so defaults to True
        :type anno_text: str
        :param anno_text: text to annotate into the corner of the figure, 
            defaults to annotating the depth value
        """
        src_color = self.kwargs.get("src_color", "g")
        src_marker = self.kwargs.get("src_marker", "2dcircle")
        rcv_color = self.kwargs.get("rcv_color", "w")
        rcv_marker = self.kwargs.get("rcv_marker", "2ddiamond")

        if startup:
            self._startup()

        logger.info(f"Depth Slice (Z) of '{self.fid}' at {depth_km} [km]")
        coastline_z = self.ranges[-1]

        if depth_km != "surface":
            depth_m = -1 * abs(depth_km) * 1E3
            coastline_z = depth_m

        # Put the coastline at some height above the topography, or at depth
        if self.coast is not None:
            coastline(self.coast, coastline_z)

        # Plot the stations and receivers
        if self.rcvs is not None:
            srcrcv(self.rcvs,
                   color=rcv_color,
                   z_value=coastline_z,
                   marker=rcv_marker)
        if self.srcs is not None:
            srcrcv(self.srcs,
                   color=src_color,
                   z_value=coastline_z,
                   marker=src_marker)

        # Plot the model at the given height
        # Axes behave weirdly when cutting planes so turn off Y-axis, not sure
        # why this works... sorry
        if depth_km == "surface":
            # Show a surface projection
            self.engine.add_filter(Surface(), self.vtkfr)
            tag = depth_km
            set_axes(xyz=[True, True, False],
                     ranges=self.axes_ranges,
                     **self.kwargs)
        else:
            # Show a slice (plane) at a given depth
            self._cut_plane(axis="Z", slice_at=depth_m)
            tag = f"depth_{int(abs(depth_km))}km"
            set_axes(xyz=[True, False, True],
                     ranges=self.axes_ranges,
                     **self.kwargs)

        # Set the camera with top down view
        scene = self.engine.scenes[0]
        scene.scene.z_plus_view()

        # Plot extras
        colorscale(orientation="vertical", **self.kwargs)
        if anno_text is None:
            anno_text = tag.replace("_", " ")
        annotate(s=anno_text, c="k", width=0.175)  # was 0.2

        # Finalize
        save_tag = None
        if save:
            mlab.savefig(save.format(tag=tag))
            save_tag = save.format(tag=tag)
        if show:
            mlab.show()
        else:
            mlab.close(self.fig)

        return save_tag
Example #28
0
    def plot(self):
        '''
        Plot a 3D visualisation of the Voronoi grid using mayavi.

        This method requires mayavi to be installed and also needs the vertices
        information to be available (see the class constructor).

        Note that in order for this method to work in an interactive IPython session,
        a series of environment variables and proper switches need to be used
        depending on your system configuration. For instance, on a Linux machine
        with PyQt4 and a recent IPython version, the following bash startup
        command for IPython can be used:
        ``ETS_TOOLKIT=qt4 QT_API=pyqt ipython --gui=qt4``
        This sets both the mayavi and the IPython GUI toolkit to qt4, and the ``QT_API``
        variable is used to specify that we want the ``pyqt`` API (as opposed to the
        ``pyside`` alternative API - PySide is an alternative implementation of PyQt).

        It should be possible to get this method working on different configurations,
        but the details will be highly system-dependent.
        '''

        if not self._with_vertices:
            raise ValueError(
                'the class must be constructed with \'with_vertices=True\' in order to support plotting'
            )

        import numpy as np
        try:
            from tvtk.api import tvtk
            from mayavi.api import Engine
            from mayavi import mlab
            from mayavi.sources.vtk_data_source import VTKDataSource
            from mayavi.modules.surface import Surface
            from mayavi.modules.scalar_cut_plane import ScalarCutPlane
        except ImportError:
            raise ImportError(
                'the plot method requires Mayavi, please make sure it is correctly installed'
            )

        # Shortcut.
        vertices = self._neighbours_table['vertices']

        # This is a list of all the vertices composing all voronoi cells.
        # points = [[x1,y1,z1],[x2,y2,z2],...]
        points = []
        # Array to describe each voronoi cell in terms of the points list above. E.g.,
        # cells = [4,0,1,2,3,5,4,5,6,7,8]
        # This describes two cells, the first with 4 vertices whose indices in the points array
        # are 0,1,2,3, the second with 5 vertices whose indices are 4,5,6,7,8.
        cells = []
        cur_cell_idx = 0
        # Indices in the cells array where each new cell starts. In the example above,
        # offset = [0,5]
        offset = []
        cur_offset = 0
        # Array of cell types. Cells will all be of the same type.
        cell_types = []

        # Build the above quantities.
        for v in vertices:
            # Drop the empty vertices coordinates, signalled by NaN.
            arr = v[~np.isnan(v)]
            assert (len(arr) % 3 == 0)
            tmp = np.split(arr, len(arr) / 3)
            # Append the vertices.
            points = points + tmp
            # Append the cell description.
            cells = cells + \
                [len(tmp)] + range(cur_cell_idx, cur_cell_idx + len(tmp))
            cur_cell_idx += len(tmp)
            # Append the offset info.
            offset.append(cur_offset)
            cur_offset += len(tmp) + 1
            # Append the cell type.
            cell_types.append(tvtk.ConvexPointSet().cell_type)

        # Cache the sites' positions.
        sites_arr = self._neighbours_table['coordinates']

        # Setup the Mayavi engine and figure.
        e = Engine()
        e.start()
        fig = mlab.figure(engine=e)

        # Plot the sites.
        mlab.points3d(sites_arr[:, 0],
                      sites_arr[:, 1],
                      sites_arr[:, 2],
                      figure=fig)

        # Plot the cells with coloured surfaces.
        # This is just an array of scalars to assign a "temperature" to each cell vertex, which will be
        # used for coloring purposes.
        temperature = np.arange(0, len(points) * 10, 10, 'd')
        # Initialise the array of cells.
        cell_array = tvtk.CellArray()
        cell_array.set_cells(len(vertices), np.array(cells))
        # Initialise the unstructured grid object.
        ug = tvtk.UnstructuredGrid(points=np.array(points))
        ug.set_cells(np.array(cell_types), np.array(offset), cell_array)
        ug.point_data.scalars = temperature
        ug.point_data.scalars.name = 'temperature'
        # Create a data source from the unstructured grid object.
        src = VTKDataSource(data=ug)
        # Add the source to the engine.
        e.add_source(src)
        # Create a surface object with opacity 0.5
        surf = Surface()
        surf.actor.property.opacity = 0.5
        # Add the surface object to the engine.
        e.add_module(surf)
        # Add a cut plane as well.
        e.add_module(ScalarCutPlane())

        # Create another representation of the grid, this time using only white wireframe
        # to highlight to shape of the cells.
        # Rebuild the ug.
        ug = tvtk.UnstructuredGrid(points=np.array(points))
        ug.set_cells(np.array(cell_types), np.array(offset), cell_array)
        src = VTKDataSource(data=ug)
        e.add_source(src)
        surf = Surface()
        surf.actor.property.representation = 'wireframe'
        e.add_module(surf)
        cp = ScalarCutPlane()
        e.add_module(cp)
Example #29
0
    def test_script_recording(self):
        "Does script recording work correctly."
        # Create a mayavi pipeline and record it.
        tape = self.tape
        e = NullEngine()
        e.start()
        # Start recording.
        tape.recording = True
        tape.register(e, known=True, script_id='engine')
        e.new_scene()
        self.assertEqual(tape.lines[-1], "dummy_viewer = engine.new_scene()")

        src = ParametricSurface()
        e.add_source(src)
        expect = 'from mayavi.sources.parametric_surface '\
                 'import ParametricSurface'
        self.assertEqual(tape.lines[-3], expect)
        self.assertEqual(tape.lines[-2],
                         "parametric_surface = ParametricSurface()")
        self.assertEqual(tape.lines[-1],
                         "engine.add_source(parametric_surface)")

        src.function = 'dini'
        self.assertEqual(tape.lines[-1],
                         "parametric_surface.function = 'dini'")

        o = Outline()
        e.add_module(o)
        expect = 'from mayavi.modules.outline import Outline'
        self.assertEqual(tape.lines[-3], expect)
        self.assertEqual(tape.lines[-2], "outline = Outline()")
        self.assertEqual(tape.lines[-1], "engine.add_module(outline)")

        o.actor.property.color = (1, 0, 0)
        self.assertEqual(tape.lines[-1],
                         "outline.actor.property.color = (1.0, 0.0, 0.0)")

        s = Surface()
        e.add_module(s)
        expect = 'from mayavi.modules.surface import Surface'
        self.assertEqual(tape.lines[-3], expect)
        self.assertEqual(tape.lines[-2], "surface = Surface()")
        self.assertEqual(tape.lines[-1], "engine.add_module(surface)")

        s.actor.property.representation = 'wireframe'
        self.assertEqual(
            tape.lines[-1],
            "surface.actor.property.representation = 'wireframe'")

        o.actor.property.representation = 'wireframe'
        self.assertEqual(
            tape.lines[-1],
            "outline.actor.property.representation = 'wireframe'")

        s.actor.property.opacity = 0.5
        self.assertEqual(tape.lines[-1],
                         "surface.actor.property.opacity = 0.5")

        s.actor.mapper.scalar_visibility = False
        self.assertEqual(tape.lines[-1],
                         "surface.actor.mapper.scalar_visibility = False")

        # Stop recording and test.
        tape.unregister(e)
        tape.record('#end')  # Placeholder
        o.actor.property.opacity = 0.5
        self.assertEqual(tape.lines[-1], '#end')
        s.actor.property.color = (1, 0, 0)
        self.assertEqual(tape.lines[-1], '#end')
        s.enable_contours = True
        self.assertEqual(tape.lines[-1], '#end')
        src.function = 'klein'
        self.assertEqual(tape.lines[-1], '#end')
Example #30
0
    def __init__(self,
                 meshes,
                 center=True,
                 vmin=None,
                 vmax=None,
                 offset_axis=0,
                 offset_spacing=0.2,
                 contours=None,
                 colormap='RdBu',
                 show_labels=False,
                 actor_options=dict(),
                 offset_axis2=1,
                 offset_spacing2=0.5,
                 label_offset_axis=None,
                 label_offset=1.1,
                 num_columns=None,
                 **kwargs):
        HasTraits.__init__(self)

        if type(meshes) is dict:
            names, verts, tris, weights = list(
                zip(*[(n, v, t, w) for n, (v, t, w) in meshes.items()]))
        elif type(meshes) in [list, tuple]:
            names, verts, tris, weights = [], [], [], []
            for i, mesh in enumerate(meshes):
                # (verts, tris, weights, name)
                verts.append(mesh[0])
                tris.append(mesh[1])
                weights.append(mesh[2])
                if len(mesh) < 4:
                    names.append(str(i))
                else:
                    names.append(mesh[3])
        else:
            raise ValueError('illegal value for parameter "meshes"')

        ## single arrays given?
        #share_verts, share_tris = False, False
        #if type(weights) is np.ndarray and weights.ndim == 2:
        #    weights = [weights]
        #if type(verts) is np.ndarray and verts.ndim == 2:
        #    verts = cycle([verts])
        #    share_verts = True
        #if type(tris) is np.ndarray and tris.ndim == 2:
        #    tris = cycle([tris])
        #    share_tris = True
        #else:
        #    if not share_tris and len(tris) != len(weights):
        #        raise ValueError, "need the same number of weight and triangle arrays"
        #    if not share_verts and len(verts) != len(weights):
        #        raise ValueError, "need the same number of weight and vertex arrays"
        #    if names is not None and len(names) != len(weights):
        #        raise ValueError, "need the same number of weight arrays and names"

        if names is not None:
            assert len(set(names)) == len(names)

        self._weights = list(map(_centered, weights)) if center else weights
        self._verts = verts
        self._tris = tris
        valid_weights = [
            w.shape[-1] - 1 for w in self._weights if w is not None
        ]
        self._max_weight = max(valid_weights) if len(valid_weights) > 0 else 0
        self._names = names
        #self._names = map(str, range(len(self._weights))) if names is None else names
        #if len(weights) == 2:
        #    self.display_all = True

        # visualize each mesh
        self._trimeshes = []
        self._texts = []
        self._offsets = []
        offset = np.zeros(3)
        for i, (verts_i, tris_i, weights_i,
                name_i) in enumerate(zip(verts, tris, weights, names)):
            if i > 0:
                offset[offset_axis] += verts_i[:, offset_axis].ptp() * (
                    1 + offset_spacing)
            if num_columns is not None and i % num_columns == 0:
                offset[offset_axis2] += verts_i[:, offset_axis2].ptp() * (
                    1 + offset_spacing2)
                offset[offset_axis] = 0
            if center:
                vmin, vmax = 0, 1
            else:
                vmin, vmax = vmin, vmax
            # draw mesh
            tm = mlab.triangular_mesh(
                verts_i[:, 0],
                verts_i[:, 1],
                verts_i[:, 2],
                tris_i,
                scalars=weights_i[..., 0] if weights_i is not None
                and not weights_i.dtype == np.uint8 else None,
                colormap=colormap,
                vmin=vmin,
                vmax=vmax,
                figure=self.scene.mayavi_scene)
            if weights_i is None:
                tm.actor.mapper.scalar_visibility = False
            # disable normal splitting
            tm.parent.parent.filter.splitting = False

            if contours is not None and weights_i is not None:
                from mayavi.modules.surface import Surface
                engine = tm.scene.engine
                tm_contour = Surface()
                engine.add_filter(tm_contour, tm.module_manager)
                tm_contour.enable_contours = True
                tm_contour.contour.number_of_contours = contours
                tm_contour.actor.mapper.scalar_visibility = False
                tm_contour.actor.property.set(color=(0.0, 0.0, 0.0),
                                              line_width=4)

                self._trimeshes.append([tm, tm_contour])
            else:
                self._trimeshes.append([tm])

            if show_labels:
                txt = mlab.text(0,
                                0,
                                str(name_i),
                                z=0,
                                color=(0, 0, 0),
                                width=0.12)
                txt.actor.text_scale_mode = 'none'
                txt.property.set(font_size=11, justification='centered')
                self._texts.append(txt)

            #tm.actor.actor.property.edit_traits()
            # for the next mesh, add the extent of the current mesh (plus spacing) to the offset
            self._offsets.append(offset.copy())
            tm.actor.property.set(**actor_options)
            #if handle_points is not None:
            #    h = verts2.ptp()
            #    mlab.points3d(handle_points[:,0], handle_points[:,1], handle_points[:,2], scale_factor=h / 20)

        #actor_prop.edit_traits()
        self.selected_mesh = self._names[0]
        self._label_offset_axis = label_offset_axis
        self._label_offset = label_offset
        if self._label_offset_axis is None:
            self._label_offset_axis = (np.abs(self._offsets[-1]).argmax() +
                                       1) % 3
        self._update_view()
        self._reposition_meshes()
Example #31
0
import os
from mayavi.core.api import Engine
from mayavi.sources.vtk_file_reader import VTKFileReader
from mayavi.modules.surface import Surface

vtkFile_l = '/Users/richad/bin/lh.vtk'
vtkFile_r = '/Users/richad/bin/rh.vtk'

# Create the MayaVi engine and start it.
engine = Engine()
engine.start()
#scene = engine.new_scene()

# Read in VTK file and add as source
surface1 = Surface()
reader1 = VTKFileReader()
reader1.initialize(vtkFile_l)
engine.add_source(reader1)
engine.add_filter(surface1, reader1)

surface2 = Surface()
reader2 = VTKFileReader()
reader2.initialize(vtkFile_r)
engine.add_source(reader2)
engine.add_filter(surface2, reader2)
#import networkx as nx
import numpy as np
#import pickle as pk
#import matplotlib.pyplot as plt
#import bct
Example #32
0
    def do(self):
        ############################################################
        # Imports.
        script = self.script
        from mayavi.sources.array_source import ArraySource
        from mayavi.modules.outline import Outline
        from mayavi.modules.surface import Surface
        from mayavi.modules.vectors import Vectors

        ############################################################
        # Create a new scene and set up the visualization.
        s = self.new_scene()

        d = ArraySource()
        self.check_input_validation(d)
        sc, vec = self.make_2d_data()
        d.origin = (-1, -1, 0)
        d.scalar_data = sc
        d.vector_data = vec

        script.add_source(d)

        # Create an outline for the data.
        o = Outline()
        script.add_module(o)
        # View the data.
        s = Surface()
        script.add_module(s)
        v = Vectors()
        script.add_module(v)

        # Add a 3D data source
        d = ArraySource()
        sc, vec = self.make_3d_data()
        d.scalar_data = sc
        d.vector_data = vec
        script.add_source(d)
        # Create an outline for the data.
        o = Outline()
        script.add_module(o)
        # View a slice.
        s = Surface()
        script.add_module(s)
        v = Vectors()
        script.add_module(v)

        # Set the scene to a suitable view.
        s.scene.z_plus_view()
        c = s.scene.camera
        c.azimuth(-30)
        c.elevation(30)

        self.check()

        ############################################################
        # Test if saving a visualization and restoring it works.

        bg = s.scene.background
        # Save visualization.
        f = StringIO()
        f.name = abspath('test.mv2') # We simulate a file.
        script.save_visualization(f)
        f.seek(0) # So we can read this saved data.

        # Remove existing scene.
        engine = script.engine
        engine.close_scene(s)

        # Load visualization
        script.load_visualization(f)
        s = engine.current_scene

        # Set the scene to a suitable view.
        s.scene.z_plus_view()
        c = s.scene.camera
        c.azimuth(-30)
        c.elevation(30)
        s.scene.background = bg

        self.check()

        ############################################################
        # Test if the MayaVi2 visualization can be deepcopied.

        # Pop the source object.
        sources = s.children
        s.children = []
        # Add it back to see if that works without error.
        s.children.extend(sources)

        s.scene.reset_zoom()

        self.check()

        # Now deepcopy the source and replace the existing one with
        # the copy.  This basically simulates cutting/copying the
        # object from the UI via the right-click menu on the tree
        # view, and pasting the copy back.
        sources1 = copy.deepcopy(sources)
        s.children[:] = sources
        s.scene.reset_zoom()
        self.check()
Example #33
0
    def __init__(self, meshes, center=True, vmin=None, vmax=None, offset_axis=0, offset_spacing=0.2, contours=None, colormap='RdBu', show_labels=False, actor_options=dict(), offset_axis2=1, offset_spacing2=0.5, label_offset_axis=None, label_offset=1.1, num_columns=None, **kwargs):
        HasTraits.__init__(self)

        if type(meshes) is dict:
            names, verts, tris, weights = zip(*[(n, v, t, w) for n, (v, t, w) in meshes.iteritems()])
        elif type(meshes) in [list, tuple]:
            names, verts, tris, weights = [], [], [], []
            for i, mesh in enumerate(meshes):
                # (verts, tris, weights, name)
                verts.append(mesh[0])
                tris.append(mesh[1])
                weights.append(mesh[2])
                if len(mesh) < 4:
                    names.append(str(i))
                else:
                    names.append(mesh[3])
        else:
            raise ValueError, 'illegal value for parameter "meshes"'

        ## single arrays given?
        #share_verts, share_tris = False, False
        #if type(weights) is np.ndarray and weights.ndim == 2:
        #    weights = [weights]
        #if type(verts) is np.ndarray and verts.ndim == 2:
        #    verts = cycle([verts])
        #    share_verts = True
        #if type(tris) is np.ndarray and tris.ndim == 2:
        #    tris = cycle([tris])
        #    share_tris = True
        #else:
        #    if not share_tris and len(tris) != len(weights):
        #        raise ValueError, "need the same number of weight and triangle arrays"
        #    if not share_verts and len(verts) != len(weights):
        #        raise ValueError, "need the same number of weight and vertex arrays"
        #    if names is not None and len(names) != len(weights):
        #        raise ValueError, "need the same number of weight arrays and names"

        if names is not None:
            assert len(set(names)) == len(names)

        self._weights = map(_centered, weights) if center else weights
        self._verts = verts
        self._tris = tris
        valid_weights = [w.shape[-1] - 1 for w in self._weights if w is not None]
        self._max_weight = max(valid_weights) if len(valid_weights) > 0 else 0
        self._names = names
        #self._names = map(str, range(len(self._weights))) if names is None else names
        #if len(weights) == 2:
        #    self.display_all = True

        # visualize each mesh
        self._trimeshes = []
        self._texts = []
        self._offsets = []
        offset = np.zeros(3)
        for i, (verts_i, tris_i, weights_i, name_i) in enumerate(zip(verts, tris, weights, names)):
            if i > 0:
                offset[offset_axis] += verts_i[:,offset_axis].ptp() * (1 + offset_spacing)
            if num_columns is not None and i % num_columns == 0:
                offset[offset_axis2] += verts_i[:, offset_axis2].ptp() * (1 + offset_spacing2)
                offset[offset_axis] = 0
            if center:
                vmin, vmax = 0, 1
            else:
                vmin, vmax = vmin, vmax
            # draw mesh
            tm = mlab.triangular_mesh(
                verts_i[:,0], verts_i[:,1], verts_i[:,2], tris_i, 
                scalars=weights_i[...,0] if weights_i is not None and not weights_i.dtype == np.uint8 else None, 
                colormap=colormap,
                vmin=vmin, vmax=vmax,
                figure=self.scene.mayavi_scene)
            if weights_i is None:
                tm.actor.mapper.scalar_visibility = False
            # disable normal splitting
            tm.parent.parent.filter.splitting = False

            if contours is not None and weights_i is not None:
                from mayavi.modules.surface import Surface
                engine = tm.scene.engine
                tm_contour = Surface()
                engine.add_filter(tm_contour, tm.module_manager)
                tm_contour.enable_contours = True
                tm_contour.contour.number_of_contours = contours
                tm_contour.actor.mapper.scalar_visibility = False
                tm_contour.actor.property.set(color = (0.0, 0.0, 0.0), line_width=4)

                self._trimeshes.append([tm, tm_contour])
            else:
                self._trimeshes.append([tm])

            if show_labels:
                txt = mlab.text(0, 0, str(name_i), z=0, color=(0, 0, 0), width=0.12)
                txt.actor.text_scale_mode = 'none'
                txt.property.set(font_size=11, justification='centered')
                self._texts.append(txt)


            #tm.actor.actor.property.edit_traits()
            # for the next mesh, add the extent of the current mesh (plus spacing) to the offset
            self._offsets.append(offset.copy())
            tm.actor.property.set(**actor_options)
            #if handle_points is not None:
            #    h = verts2.ptp()
            #    mlab.points3d(handle_points[:,0], handle_points[:,1], handle_points[:,2], scale_factor=h / 20)

        #actor_prop.edit_traits()
        self.selected_mesh = self._names[0]
        self._label_offset_axis = label_offset_axis
        self._label_offset = label_offset
        if self._label_offset_axis is None:
            self._label_offset_axis = (np.abs(self._offsets[-1]).argmax() + 1) % 3
        self._update_view()
        self._reposition_meshes()