python3dgridlinemayavi

Drawing disconnected lines in mayavi calling mlab.plot3d once


I've started using mayavi and I am trying to plot a voxel grid. For this I am using mlab.plot3d to plot each line of the grid, what makes the program very slow since the render has to be called for each line. Is there a way to plot all the lines by calling mlab.plot3d just once ? The main problem is that the lines I am plotting are disconnected, if I put one line after the other in the same array, the render is going to plot connections that I don't want. I've tried to connect the two non-connected lines by putting a None between both lines:

lines = [0.0, 3.0, None, 0.0, 6.0]

But this does not work.

My function to plot the grid line by line can be seen below:

def draw_voxel_grid_bbox_translated(voxel_grid, tube_radius=0.01, color=(0,0,0)):
'''
Draw a bounding box that shows the dimensions of the complete voxel grid in passed color
:param voxel_grid: The voxel grid used to draw the bounding box
:return: None
'''
# Drawing lines parallel to x axis
sense_change_z = 0
for z_step in range(2):
    sense_change_y = 0
    for y_step in range(2):
        if sense_change_y == 0:
            xs = [voxel_grid.min_grid_x - voxel_grid.min_grid_x, voxel_grid.max_grid_x - voxel_grid.min_grid_x]
            sense_change_y = 1
        else:
            xs = [voxel_grid.max_grid_x - voxel_grid.min_grid_x, voxel_grid.min_grid_x - voxel_grid.min_grid_x]
            sense_change_y = 0
        if y_step == 0:
            y_coord = voxel_grid.min_grid_y
        else:
            y_coord = voxel_grid.max_grid_y
        if z_step == 0:
            z_coord = voxel_grid.min_grid_z
        else:
            z_coord = voxel_grid.max_grid_z
        ys = [y_coord - voxel_grid.min_grid_y, y_coord - voxel_grid.min_grid_y]
        zs = [z_coord - voxel_grid.min_grid_z, z_coord - voxel_grid.min_grid_z]
        mlab.plot3d(xs, ys, zs, color=color, tube_radius=tube_radius)
# Drawing lines parallel to y axis
for x_step in range(2):
    for z_step in range(2):
        ys = [voxel_grid.min_grid_y - voxel_grid.min_grid_y, voxel_grid.max_grid_y - voxel_grid.min_grid_y]
        if x_step == 0:
            x_coord = voxel_grid.min_grid_x
        else:
            x_coord = voxel_grid.max_grid_x
        if z_step == 0:
            z_coord = voxel_grid.min_grid_z
        else:
            z_coord = voxel_grid.max_grid_z
        xs = [x_coord - voxel_grid.min_grid_x, x_coord - voxel_grid.min_grid_x]
        zs = [z_coord - voxel_grid.min_grid_z, z_coord - voxel_grid.min_grid_z]
        mlab.plot3d(xs, ys, zs, color=color, tube_radius=tube_radius)
# Drawing lines parallel to z axis
for x_step in range(2):
    for y_step in range(2):
        zs = [voxel_grid.min_grid_z - voxel_grid.min_grid_z, voxel_grid.max_grid_z - voxel_grid.min_grid_z]
        if x_step == 0:
            x_coord = voxel_grid.min_grid_x
        else:
            x_coord = voxel_grid.max_grid_x
        if y_step == 0:
            y_coord = voxel_grid.min_grid_y
        else:
            y_coord = voxel_grid.max_grid_y
        xs = [x_coord - voxel_grid.min_grid_x, x_coord - voxel_grid.min_grid_x]
        ys = [y_coord - voxel_grid.min_grid_y, y_coord - voxel_grid.min_grid_y]
        mlab.plot3d(xs, ys, zs, color=color, tube_radius=tube_radius)

Solution

  • Connecting arbitrary lines between points with one call of points3d is possible and extremely fast. Use following code from the protein example

    import mayavi.mlab as mlab
    import numpy as np
    
    connections = ((0,2),(3,5)) # point 0 and 2 and 3 and 5 are connected
    x = np.random.randn(10)
    y = np.random.randn(10)
    z = np.random.randn(10)
    pts = mlab.points3d(x, y, z)
    
    pts.mlab_source.dataset.lines = np.array(connections)
    
    tube = mlab.pipeline.tube(pts, tube_radius=0.15)
    tube.filter.radius_factor = 1.
    mlab.pipeline.surface(tube, color=(0.8, 0.8, 0))
    
    mlab.show()