【pyVista】在三维模型中的网格属性
一,什么是属性?
属性是存在于 一个网格。在 PyVista 中,我们同时使用点数据和单元数据,并且 允许轻松访问数据字典以保存属性数组 它们位于网格的所有点或所有单元上。
点数据
点数据是指值数组(标量、向量等),这些值 Live 在网格的每个点上。属性数组中的每个元素 对应于网格中的一个点。让我们创建一些点 数据。绘制时,点之间的值为 跨单元格进行插值。
import numpy as np # 导入 NumPy 库,用于处理数组和生成随机数
import pyvista as pv # 导入 PyVista 库,用于三维可视化
# 从 STL 文件读取网格数据
mesh = pv.read('hexbeam.stl')
# 设置相机位置,用于绘制时视角的选择
cpos = [(6.20, 3.00, 7.50), # 相机位置的坐标
(0.16, 0.13, 2.65), # 注意点的坐标 (即视角朝向的中心点)
(-0.28, 0.94, -0.21)] # 上向量坐标,控制相机的上方向
# 为每一个点的数据设置一个名为 'my point values' 的标量值
mesh.point_data['my point values'] = np.arange(mesh.n_points)
# 绘制网格,使用 ivalue 'my point values' 表示的标量值,并显示边缘线
mesh.plot(scalars='my point values', cpos=cpos, show_edges=True)
代码解释:
-
导入库:
numpy
用于数值运算和数组操作,这里主要用来生成值数组。pyvista
是一个用于三维可视化的库,可以方便地操作和展示三维数据。
-
读取网格文件:
- 使用
pv.read('hexbeam.stl')
从一个 STL 文件中读取三维网格数据。这种文件格式通常用于存储三维模型。
- 使用
-
设置相机位置:
cpos
是一个列表,包含三个点的三维坐标,定义了绘制图像时的相机位置、查看的目标和相机的上方向。具体包括:- 第一个点是相机的位置。
- 第二个点是相机关注的目标(视野中心点)。
- 第三个点定义了相机的“上方”方向,有助于用户更好地理解空间的方向。
-
设置点数据:
mesh.point_data['my point values']
给网格的每一个点分配一个标量数据,这里使用np.arange(mesh.n_points)
创建一个从 0 到网格点总数的数组,便于颜色映射等可视化。
-
绘制网格:
- 使用
mesh.plot()
函数进行网格的可视化,scalars='my point values'
表示使用之前设置的点数据来为每个点上色,cpos=cpos
用于设置相机视角,show_edges=True
则会在绘制时显示网格的边缘线,增强立体效果。
- 使用
这段代码的最终效果是展示一个三维网格,同时为不同的点赋予不同的颜色,使得可视化更加直观。
单元格数据
单元格数据是指值数组(标量、向量等),这些值 存在于网格的每个单元中。即整个单元 (2D face 或 3D volume)被分配该属性的值。
import numpy as np # 导入 NumPy 库,用于处理数组和生成随机数
import pyvista as pv # 导入 PyVista 库,用于三维可视化
# 从 STL 文件读取网格数据
mesh = pv.read('hexbeam.stl')
# 设置相机位置,用于绘制时视角的选择
cpos = [(6.20, 3.00, 17.50), # 相机位置的坐标
(0.16, 0.13, 2.65), # 注意点的坐标 (即视角朝向的中心点)
(-0.28, 0.94, -0.21)] # 上向量坐标,控制相机的上方向
# mesh.point_data['my point values'] = np.arange(mesh.n_points) # 注释掉的代码(不执行)
# 为每一个单元格 (cell) 的数据设置一个名为 'my cell values' 的标量值
mesh.cell_data['my cell values'] = np.arange(mesh.n_cells)
# 绘制网格,使用 'my cell values' 表示的标量值,并显示边缘线
mesh.plot(scalars='my cell values', cpos=cpos, show_edges=True)
代码解释:
-
设置单元格数据:
mesh.cell_data['my cell values'] = np.arange(mesh.n_cells)
- 这行代码为网格中的每一个单元格(cell)分配一个标量值。
mesh.n_cells
返回当前网格中单元格的总数。np.arange(mesh.n_cells)
创建一个从 0 到单元格总数的数组,赋值给my cell values
。- 此时每个单元格都有了一个唯一的标量值,这些值可以用于后续的可视化,比如色彩映射。
-
绘制网格:
mesh.plot(scalars='my cell values', cpos=cpos, show_edges=True)
- 这行代码调用
mesh.plot()
方法来可视化网格数据。 scalars='my cell values'
指定使用之前设置的单元格数据 (my cell values
) 进行色彩映射。这意味着每个单元格的颜色将根据其标量值进行变化,帮助观察者直观地理解网格的结构及分布情况。cpos=cpos
用于设置相机的视角,这样绘制时能够以特定的视点观察网格。show_edges=True
使得绘制的结果中显示网格的轮廓线,增加了立体感,便于观察网格结构的细节。
- 这行代码调用
总结
这段代码最终展示了一个带有颜色映射的三维网格,其中颜色的变化依据每个单元格的标量值。通过单元格数据的色彩映射,使得可视化效果更为丰富,有助于更好地分析和理解三维网格的特征。
以下是点数据与单元数据的比较,以及点数据如何 在映射颜色时跨单元格进行插值。这与 cell 不同 data 中具有单个值,该 data 在单元格的域中具有单个值:
import numpy as np
import pyvista as pv
# 读取 STL 文件
uni = pv.read('hexbeam.STL')
# 生成示例点数据和单元数据
# 假设您有与点数量或单元数量相同的随机值
uni.point_data['My Point Data'] = np.random.random(uni.n_points)
uni.cell_data['My Cell Data'] = np.random.random(uni.n_cells)
# 创建一个绘图对象,并设置为 1 行 2 列的子图
pl = pv.Plotter(shape=(1, 2), border=False)
# 在第一个子图中绘制点数据
pl.add_mesh(uni, scalars='My Point Data', show_edges=True)
# 切换到第二个子图
pl.subplot(0, 1)
# 在第二个子图中绘制单元数据
pl.add_mesh(uni, scalars='My Cell Data', show_edges=True)
# 显示绘图
pl.show()
代码详解
-
导入库:
import numpy as np
: 导入NumPy库,用于生成随机数及处理数组。import pyvista as pv
: 导入PyVista库,用于三维可视化。
-
读取 STL 文件:
uni = pv.read('001.STL')
: 使用PyVista读取名为001.STL
的网格文件,并将其存储在uni
变量中。uni
现在是一个包含 STL 文件几何信息的网格对象。
-
生成示例数据:
uni.point_data['My Point Data'] = np.random.random(uni.n_points)
: 为每个网格的顶点生成随机的标量值,并将其存储在point_data
中,键名为'My Point Data'
。uni.n_points
返回网格点的总数。uni.cell_data['My Cell Data'] = np.random.random(uni.n_cells)
: 为每个单元(面)生成随机的标量值,并将其存储在cell_data
中,键名为'My Cell Data'
。uni.n_cells
返回网格单元的总数。
-
创建绘图对象:
pl = pv.Plotter(shape=(1, 2), border=False)
: 创建一个绘图对象pl
,并设置为 1 行 2 列的子图布局。border=False
表示不需要显示边框。
-
绘制网格:
pl.add_mesh(uni, scalars='My Point Data', show_edges=True)
: 在第一列子图中添加网格。使用'My Point Data'
作为标量(色彩)来显示网格点的颜色,show_edges=True
表示绘制网格的边缘线,增强可视化效果。
-
切换子图:
pl.subplot(0, 1)
: 切换到第一行第二列的子图,准备在该位置绘制新的图形。
-
绘制单元数据:
pl.add_mesh(uni, scalars='My Cell Data', show_edges=True)
: 在第二列子图中添加网格,同样使用'My Cell Data'
作为标量显示单元的颜色,不同的随机值将导致不同的颜色映射。
-
显示绘图:
pl.show()
: 打开一个窗口,展示以上绘制的结果。
总结
这段代码实现了从一个 STL 文件读取 3D 网格,并为网格的点和单元生成示例随机数数据,以便进行可视化。通过将网格分为两个子图,分别显示顶点数据和单元数据,用户可以直观地看到不同标量数据的可视化效果。
应用数据
字段数据不直接与点或像元关联 但仍应附加到网格。这可能是一个字符串数组
将单元分配给网格
以下是我们如何为 (单元)cell 属性赋值并绘制它。在这里,我们 生成包含 6 面的立方体,并为每个面分配一个整数,然后绘制它。range(6)
。请注意这与将标量分配给每个点有何不同
import pyvista as pv # 导入 PyVista 库
# 创建一个立方体对象
cube = pv.Cube()
# 为立方体的单元数据 (cell data) 添加一组标量数据,范围为 0 到 5
cube.cell_data['myscalars'] = range(6)
# 复制立方体对象
other_cube = cube.copy()
# 为另一个立方体的点数据 (point data) 添加一组标量数据,范围为 0 到 7
other_cube.point_data['myscalars'] = range(8)
# 创建一个绘图器,设置为 1 行 2 列的布局,边框宽度为 1
pl = pv.Plotter(shape=(1, 2), border_width=1)
# 在第一个子图中添加第一个立方体,并使用 'coolwarm' 色图进行着色
pl.add_mesh(cube, cmap='coolwarm')
# 切换到第二个子图
pl.subplot(0, 1)
# 在第二个子图中添加第二个立方体,并同样使用 'coolwarm' 色图进行着色
pl.add_mesh(other_cube, cmap='coolwarm')
# 显示绘图
pl.show()
代码解释:
-
导入库:首先,代码导入了
pyvista
库,这是一个用于 3D 可视化的 Python 库。 -
创建立方体:使用
pv.Cube()
创建一个立方体实例,赋值给变量cube
。 -
添加单元数据:利用
cell_data
属性为立方体添加标量数据,这些数据是一个范围从 0 到 5 的整数。这些标量数据会在渲染时用于控制立方体表面的颜色。 -
复制立方体:使用
copy()
方法复制cube
以创建other_cube
。 -
添加点数据:为复制的立方体添加点数据(
point_data
),这组标量数据是范围从 0 到 7 的整数,用于控制第二个立方体颜色的显示。 -
创建绘图器:使用
pv.Plotter
创建绘图器,并设置绘图的布局为 1 行 2 列。 -
添加和渲染立方体:
- 在第一个子图内渲染第一个立方体(
cube
),使用 "coolwarm" 颜色映射。 - 切换到第二个子图,渲染第二个立方体(
other_cube
),也使用 "coolwarm" 颜色映射。
- 在第一个子图内渲染第一个立方体(
-
展示绘图:最后,通过
pl.show()
显示绘图窗口,渲染二个立方体的 3D 图像。