Mayavi 2 脚本:过滤器

日期2007-08-12(最后修改),2007-08-10(创建)

简介

好吧,到目前为止,上面的例子都很简单:标量或向量数据在“真空”中呈现,也就是说,没有物体、材料或任何其他东西。

换句话说,如何显示某个物体,例如一个金属平行六面体,在标量或向量场中?

您将在这里介绍的第一个过滤器解决了这个问题。

ExtractUnstructuredGrid 过滤器

对于此示例,我们假设几个假设

* 体积数据的网格由 76x60x72 个立方体单元组成(8 个顶点);因此,用于“真空”的 VTK 对象单元称为 VTK_HEXAHEDRON(#12)。单元 ID 从 0 开始,到 #342880 结束。

* 一个金属平行六面体浸没在 EM 场中,该场遍布整个体积数据;该物体由面单元组成(4 个顶点),在 VTK 中称为 VTK_QUAD(#9)单元。这些面单元在这里使用是因为平行六面体内的 EM 场为零。单元 ID 从 #342881 开始,到 #345966 结束。

* 由于存在不同类型的单元格,因此必须使用 !UnstructuredGrid 数据集(请参阅http://www.vtk.org/pdf/file-formats.pdf以了解如何编写 !UnstructuredGrid 文件,VTK 单元格语法等)。

为了将金属平行六面体作为与真空分离的物体显示,您必须提取对应于该物体的单元格。 这样,您就可以使用例如 Surface 模块来显示此物体。

首先,像往常一样导入 !ExtractUnstructuredGrid 过滤器和 Surface 模块

在 [ ]
from enthought.mayavi.modules.surface import Surface

from enthought.mayavi.filters.extract_unstructured_grid import ExtractUnstructuredGrid

然后

在 [ ]
### for the metallic parallellepiped
script.engine.current_object = src  # current object must be set to the source
eug1 = ExtractUnstructuredGrid()
script.add_filter(eug1)
eug1.filter.cell_clipping = True
eug1.filter.cell_minimum = 342881
eug1.filter.cell_maximum = 345966
s = Surface()                       # the metallic is displayed using Surface module
eug1.add_module(s)                  # the module must be added to the current filter
s.actor.mapper.scalar_visibility = False
s.actor.property.color = (0.509804, 0.5098040, 0.5490196) # grey color for the metallic parallellepiped

### we need also extract the required cells for and only for the vaccum
script.engine.current_object = src  # current object must be set to the source
eug2 = ExtractUnstructuredGrid()
script.add_filter(eug2)
eug2.filter.cell_clipping = True
eug2.filter.cell_minimum = 0
eug2.filter.cell_maximum = 342880

### here, we can display the EM field using ScalarCutPlane/VectorCutPlane,
### Surface, Vectors modules as usual
.../...

这应该看起来像这样

![](files/../_static/items/attachments/MayaVi_ScriptingMayavi2_Filters/filter_eug1.png

对于第一个示例,只有一个物体,并且它是多面的。

现在,假设我们有一个第二个物体,不是金属而是电介质(因此其中的电磁场不应为零)。 因此,我们必须使用一些 3D 单元格,例如 VTK_HEXAHEDRON 单元格(单元格 ID 从 #345967 到 #349094)。 我们还希望在金属物体电介质物体的表面上显示场。

在 [ ]
### for the metallic parallellepiped
script.engine.current_object = src
eug1 = ExtractUnstructuredGrid()
script.add_filter(eug1)
eug1.filter.cell_clipping = True
eug1.filter.cell_minimum = 342881
eug1.filter.cell_maximum = 345966
s = Surface()
eug1.add_module(s)
s.actor.mapper.scalar_visibility = True # scalar field on the surface

### for the dielectric parallellepiped
script.engine.current_object = src
eug2 = ExtractUnstructuredGrid()
script.add_filter(eug2)
eug2.filter.cell_clipping = True
eug2.filter.cell_minimum = 345967
eug2.filter.cell_maximum = 349094
s = Surface()
eug2.add_module(s)
s.actor.mapper.scalar_visibility = True # scalar field set to on
s.enable_contours = True                # in the volume

### we need also extract the required cells for and only for the vaccum
script.engine.current_object = src  # current object must be set to the source
eug3 = ExtractUnstructuredGrid()
script.add_filter(eug3)
eug3.filter.cell_clipping = True
eug3.filter.cell_minimum = 0
eug3.filter.cell_maximum = 342880

.../...

这应该呈现如下

![](files/../_static/items/attachments/MayaVi_ScriptingMayavi2_Filters/filter_eug2.png

ExtractGrid 过滤器

使用 !ExtractGrid 过滤器更简单,因为它仅适用于结构化网格:您只需要为 x、y、z 坐标设置最小值/最大值。 因此,您可以切割数据的子体积。 您也可以对每个坐标应用比率,以减少单元格数量。

像往常一样,导入所需的模块和/或过滤器

在 [ ]
from enthought.mayavi.modules.surface import Surface

from enthought.mayavi.filters.extract_grid import ExtractGrid

然后您可以将过滤器的限制设置为

在 [ ]
eg = ExtractGrid()
script.add_filter(eg)
eg.x_min, eg.x_max = 10, 40
eg.y_min, eg.y_max = 10, 40
eg.z_min, eg.z_max = 10, 40

# eg.x_ratio = 2
# eg.y_ratio = 2
# eg.z_ratio = 2

# same example using Surface module
s = Surface()
s.enable_contours = True
s.contour.auto_contours = True
s.contour.number_of_contours = 10
s.actor.property.opacity = 0.2
script.add_module(s)
s.contour.minimum_contour = 0
s.contour.maximum_contour = 1
s.module_manager.scalar_lut_manager.data_range = [0, 1]

![](files/../_static/items/attachments/MayaVi_ScriptingMayavi2_Filters/filter_eg.png

阈值过滤器

使用此过滤器,您可以考虑包含在特定范围内的标量值。

假设您的标量数据从 0 到 1 分布,但您只对 [0.4, 0.6] 范围内的值感兴趣,并且您想在此范围内围绕 0.5 使用 !IsoSurface 模块的滑块。 默认情况下,滑块的最小值和最大值将设置为 0 和 1,因为这是您的数据范围

![](files/../_static/items/attachments/MayaVi_ScriptingMayavi2_Filters/filter_thrld1.png

为了更准确地使用 !IsoSurface 模块的滑块,您必须将最小值和最大值设置为所需的值,即 0.4 和 0.6。 因此,如果您想查看围绕 0.5 的标量数据,与滑块从 0 到 1 的情况相比,您可以更容易地将滑块从 0.4 设置到 0.6。

阈值过滤器可以帮助您做到这一点。

首先开始导入模块和过滤器

在 [ ]
from enthought.mayavi.modules.iso_surface import IsoSurface

from enthought.mayavi.filters.threshold import Threshold

然后,设置阈值

在 [ ]
thh = Threshold()
script.add_filter(thh)
thh.lower_threshold = 0.4
thh.upper_threshold = 0.6
isosurf = IsoSurface()
thh.add_module(isosurf)
isosurf.contour.contours = [0.5]
isosurf.compute_normals = True
isosurf.actor.property.opacity = 0.2
isosurf.module_manager.scalar_lut_manager.data_range = [0, 1]

您就完成了!

这应该看起来像这样

![](files/../_static/items/attachments/MayaVi_ScriptingMayavi2_Filters/filter_thrld2.png)

从前两张图中可以看出,阈值模块将边界近似到最接近的值(并不严格等于 0.4 和 0.6)。

点到单元数据过滤器

通常,数据在每个点之间进行插值。因此,它们看起来更漂亮。

但也许在某些情况下,您不希望它们被插值,而是看到“原样”的数据:它们不是显示为点,而是显示为单元格。在这种情况下,您可以使用 !PointToCellData 过滤器。

让我们再次看看使用 !ScalarCutPlane 模块的示例,并导入 !PointToCellData 过滤器

在 [ ]
from enthought.mayavi.modules.scalar_cut_plane import ScalarCutPlane

from enthought.mayavi.filters.point_to_cell_data import PointToCellData

然后像往常一样将 !ScalarCutPlane 模块添加到 !PointToCellData 过滤器的“上方”

在 [ ]
ptocd = PointToCellData()
script.add_filter(ptocd)
scp = ScalarCutPlane()
ptocd.add_module(scp)
scp.implicit_plane.normal = (1, 0, 0)
scp.implicit_plane.origin = (10, 25, 25)
scp.implicit_plane.widget.enabled = False
scp.actor.property.diffuse = 0.0
scp.actor.property.ambient = 1.0
scp.actor.property.opacity = 1.0
scp.module_manager.scalar_lut_manager.data_range = [0, 1]

因此,您可以看到每个单元格上的数据,而不是点(与显示 !ScalarCutPlane 模块使用的第一张图进行比较)

扭曲标量过滤器

您可以使用 !WarpScalar 过滤器来扭曲 2D 表面,例如。参见 [:Cookbook/MayaVi/Examples: 使用 mlab 的示例 (surf_regular_mlab.py)]。

变换数据过滤器

章节作者:FredericPetit

附件