Рисование отключенных линий в Mayavi, вызывающих mlab.plot3d один раз - PullRequest
0 голосов
/ 11 января 2019

Я начал использовать Mayavi и пытаюсь построить воксельную сетку. Для этого я использую mlab.plot3d для построения каждой линии сетки, что делает программу очень медленной, так как рендеринг должен вызываться для каждой строки. Есть ли способ построить все линии, вызвав mlab.plot3d только один раз? Основная проблема заключается в том, что линии, которые я строю, отсоединяются, если я помещаю одну линию за другой в один и тот же массив, то рендер будет отображать соединения, которые мне не нужны. Я попытался соединить две несвязанные линии, поставив None между обеими линиями:

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

Но это не работает.

Моя функция для построения сетки линия за линией представлена ​​ниже:

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)

Ответы [ 2 ]

0 голосов
/ 14 января 2019

Спасибо @Jannick за ответ.

Вот новая функция, если кто-то заинтересован:

def draw_voxel_grid_cells(voxel_grid):

# Array for the points with the shape of the total number of points needed to define for drawing all the lines of the grid
points = np.zeros((((voxel_grid.nbr_cells_z+1)*(voxel_grid.nbr_cells_y+1) + (voxel_grid.nbr_cells_z+1)*(voxel_grid.nbr_cells_x+1) + (voxel_grid.nbr_cells_y+1)*(voxel_grid.nbr_cells_x+1))*2, 3))
i = 0
# Drawing lines parallel to x axis
for z_step in range(voxel_grid.nbr_cells_z+1):
    for y_step in range(voxel_grid.nbr_cells_y+1):
        points[i,:]    = [voxel_grid.min_grid_x, voxel_grid.min_grid_y+(voxel_grid.resolution*y_step), voxel_grid.min_grid_z+(voxel_grid.resolution*z_step)]
        points[i+1, :] = [voxel_grid.max_grid_x, voxel_grid.min_grid_y+(voxel_grid.resolution*y_step), voxel_grid.min_grid_z+(voxel_grid.resolution*z_step)]
        i += 2
# Drawing lines parallel to y axis
for z_step in range(voxel_grid.nbr_cells_z+1):
    for x_step in range(voxel_grid.nbr_cells_x+1):
        points[i,:]    = [voxel_grid.min_grid_x+(voxel_grid.resolution*x_step), voxel_grid.min_grid_y, voxel_grid.min_grid_z+(voxel_grid.resolution*z_step)]
        points[i+1, :] = [voxel_grid.min_grid_x+(voxel_grid.resolution*x_step), voxel_grid.max_grid_y, voxel_grid.min_grid_z+(voxel_grid.resolution*z_step)]
        i += 2
# Drawing lines parallel to z axis
for y_step in range(voxel_grid.nbr_cells_y+1):
    for x_step in range(voxel_grid.nbr_cells_x+1):
        points[i,:] =    [voxel_grid.min_grid_x+(voxel_grid.resolution*x_step), voxel_grid.min_grid_y+(voxel_grid.resolution*y_step), voxel_grid.min_grid_z]
        points[i+1, :] = [voxel_grid.min_grid_x+(voxel_grid.resolution*x_step), voxel_grid.min_grid_y+(voxel_grid.resolution*y_step), voxel_grid.max_grid_z]
        i += 2
connections = np.arange(0, ((voxel_grid.nbr_cells_z+1)*(voxel_grid.nbr_cells_y+1) + (voxel_grid.nbr_cells_z+1)*(voxel_grid.nbr_cells_x+1) + (voxel_grid.nbr_cells_y+1)*(voxel_grid.nbr_cells_x+1))*2)
connections = tuple(connections.reshape(-1,2))

# Plotting -------------------------------------------------
mlab.figure()
pts = mlab.points3d(points[:, 0], points[:, 1], points[:, 2], scale_factor=0.0001, color=(1, 0, 0))
pts.mlab_source.dataset.lines = np.array(connections)
tube = mlab.pipeline.tube(pts, tube_radius=0.001)
tube.filter.radius_factor = 1.
mlab.pipeline.surface(tube, color=(1, 0, 0))
mlab.show()
# ----------------------------------------------------------

return
0 голосов
/ 13 января 2019

Соединение произвольных линий между точками одним вызовом points3d возможно и чрезвычайно быстро. Используйте следующий код из примера белка

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()
...