python - 如何在 Mayavi2 中加入/连接/分组多个对象

标签 python vtk enthought mayavi

我想将多个 Mayavi 对象组合成一个“分组”对象,这样我就可以一起控制它们的所有属性。例如,我通过组合 3 个内置曲面(两个球体和一个圆柱体)创建了以下双凸透镜形状。现在我想一次(不是单独)为所有组成表面分配统一的属性(镜面反射、环境颜色等)。另外,我想将镜头作为一个整体进行平移/旋转。我不确定如何完成此操作。

这是在 Mayavi 中创建的双凸透镜(代码如下):

enter image description here

如下图所示,上面的镜头由三个面组成:

enter image description here


这是构建双凸透镜的代码:


import numpy as np
from mayavi import mlab
from mayavi.sources.builtin_surface import BuiltinSurface
from mayavi.modules.surface import Surface
from mayavi.filters.transform_data import TransformData


def lensUsingMayaviBuiltinSphere(radius=0.5, semiDiam=0.25, thickness=0.9):
    """
    Render a bi-convex lens
    """
    engine = mlab.get_engine()
    sag = radius - np.sqrt(radius**2 - semiDiam**2)
    cyl_height = thickness - 2.0*sag   # thickness of the cylinder in between
    # Create Mayavi data sources -- sphere_h1_src, sphere_h2_src, cylinder_src    
    # half 1: source = sphere_h1_src
    sphere_h1_src = BuiltinSurface()
    engine.add_source(sphere_h1_src)
    sphere_h1_src.source = 'sphere'
    sphere_h1_src.data_source.radius = radius
    sphere_h1_src.data_source.center = np.array([ 0.,  0.,  -np.sqrt(radius**2 - semiDiam**2) + cyl_height/2.0])
    sphere_h1_src.data_source.end_phi = np.rad2deg(np.arcsin(semiDiam/radius)) #60.0
    sphere_h1_src.data_source.end_theta = 360.0
    sphere_h1_src.data_source.phi_resolution = 300
    sphere_h1_src.data_source.theta_resolution = 300
    # half 2: source = sphere_h2_src
    sphere_h2_src = BuiltinSurface()
    engine.add_source(sphere_h2_src)
    sphere_h2_src.source = 'sphere'
    sphere_h2_src.data_source.radius = radius
    sphere_h2_src.data_source.center = np.array([ 0.,  0.,  np.sqrt(radius**2 - semiDiam**2) - cyl_height/2.0])
    sphere_h2_src.data_source.start_phi = 180.0 - np.rad2deg(np.arcsin(semiDiam/radius))
    sphere_h2_src.data_source.end_phi = 180.0
    sphere_h2_src.data_source.end_theta = 360.0
    sphere_h2_src.data_source.phi_resolution = 300
    sphere_h2_src.data_source.theta_resolution = 300
    # cylinder source data in between 
    cylinder_src = BuiltinSurface()
    engine.add_source(cylinder_src)
    cylinder_src.source = 'cylinder'
    cylinder_src.data_source.center = np.array([ 0.,  0.,  0.])
    if cyl_height > 0:
        cylinder_src.data_source.height = cyl_height
    else:
        cylinder_src.data_source.height = 0.0
    cylinder_src.data_source.radius = semiDiam
    cylinder_src.data_source.capping = False
    cylinder_src.data_source.resolution = 50

    # Add transformation filter to align cylinder length along z-axis
    transform_data_filter = TransformData()
    engine.add_filter(transform_data_filter, cylinder_src)
    Rt_c = [ 1.0000,  0.0000,  0.0000,  0.00,
             0.0000,  0.0000, -1.0000,  0.00,
             0.0000,  1.0000,  0.0000,  0.00, 
             0.0000,  0.0000,  0.0000,  1.00]
    transform_data_filter.transform.matrix.__setstate__({'elements': Rt_c})
    transform_data_filter.widget.set_transform(transform_data_filter.transform)
    transform_data_filter.filter.update()
    transform_data_filter.widget.enabled = False   # disable the rotation control further.

    # Add surface modules to each source
    right_surface = Surface()
    engine.add_filter(right_surface, sphere_h1_src)
    left_surface = Surface()
    engine.add_filter(left_surface, sphere_h2_src)
    cyl_surface = Surface()
    engine.add_filter(cyl_surface, transform_data_filter)


fig = mlab.figure()
# Add lens
lensUsingMayaviBuiltinSphere(radius=2, semiDiam=1.2)
mlab.show()

最佳答案

我不知道有什么方法可以按照您正在寻找的方式组合资源。我认为事实上这可能是不可能的,因为在引擎盖下 BuiltinSurface 对象具有特定的 vtk 源,这不是您想要的。但是,应该可以简单地使用提供您想要的内容的不同来源。在这种情况下,您可以使用 mlab.mesh 生成双凸透镜:

a,c,h=3,1,.2

phi,theta = np.mgrid[0:2*np.pi:np.pi/250, 0:2*np.pi:np.pi/250]
x=a*np.cos(theta)*np.sin(phi)
y=a*np.sin(theta)*np.sin(phi)
z=c*np.cos(phi)+(h*(-1)**(np.cos(phi)<0))

mlab.mesh(x,y,z,color=(1,1,1)
mlab.show()

enter image description here

一个细微的差别是这个表面是光滑的。这是对单个表面进行采样的本质——即,此结果是您的问题要求执行的操作的直接结果。如果这是您的图形的一个重要特征,我会建议一种完全不同的方法:将 3 个源包装在一个类中,并让事件处理程序更新所有三个的相关属性。

关于python - 如何在 Mayavi2 中加入/连接/分组多个对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22241499/

相关文章:

python - 文件 "<string>"第 1 行,在 <module> 中 NameError : name ' ' is not defined in ATOM

Python导入CSV排序代码( Pandas ?)在条目中用 ';'和 ','分隔

python - 关闭 VTK 窗口(Python)

python - OpenCV 2.4.9 VideoCapture() 在 Enthought Python 2.7 环境中无法读取视频文件

python - Django 安装在 dist-packages 中

python - Itertools 与嵌套循环性能对比

3d - VTK:setExtent、setOrigin、setSpacing 在 3D 图像中是什么意思?

c++ - 如何在最大化窗口中启动 VTK 程序?

python - 立即显示 matplotlib 中图形的内容

python - 尝试在 Mac OS X 上设置 Enthought enpkg 时出现钥匙串(keychain)问题