当前位置: 首页 > article >正文

【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)

 

代码解释:
  1. 导入库

    • numpy 用于数值运算和数组操作,这里主要用来生成值数组。
    • pyvista 是一个用于三维可视化的库,可以方便地操作和展示三维数据。
  2. 读取网格文件

    • 使用 pv.read('hexbeam.stl') 从一个 STL 文件中读取三维网格数据。这种文件格式通常用于存储三维模型。
  3. 设置相机位置

    • cpos 是一个列表,包含三个点的三维坐标,定义了绘制图像时的相机位置、查看的目标和相机的上方向。具体包括:
      • 第一个点是相机的位置。
      • 第二个点是相机关注的目标(视野中心点)。
      • 第三个点定义了相机的“上方”方向,有助于用户更好地理解空间的方向。
  4. 设置点数据

    • mesh.point_data['my point values'] 给网格的每一个点分配一个标量数据,这里使用 np.arange(mesh.n_points) 创建一个从 0 到网格点总数的数组,便于颜色映射等可视化。
  5. 绘制网格

    • 使用 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)

代码解释:
  1. 设置单元格数据

    mesh.cell_data['my cell values'] = np.arange(mesh.n_cells) 
    • 这行代码为网格中的每一个单元格(cell)分配一个标量值。
    • mesh.n_cells 返回当前网格中单元格的总数。np.arange(mesh.n_cells) 创建一个从 0 到单元格总数的数组,赋值给 my cell values
    • 此时每个单元格都有了一个唯一的标量值,这些值可以用于后续的可视化,比如色彩映射。
  2. 绘制网格

    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()
代码详解
  1. 导入库

    • import numpy as np: 导入NumPy库,用于生成随机数及处理数组。
    • import pyvista as pv: 导入PyVista库,用于三维可视化。
  2. 读取 STL 文件

    • uni = pv.read('001.STL'): 使用PyVista读取名为 001.STL 的网格文件,并将其存储在 uni 变量中。uni 现在是一个包含 STL 文件几何信息的网格对象。
  3. 生成示例数据

    • 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 返回网格单元的总数。
  4. 创建绘图对象

    • pl = pv.Plotter(shape=(1, 2), border=False): 创建一个绘图对象 pl,并设置为 1 行 2 列的子图布局。border=False 表示不需要显示边框。
  5. 绘制网格

    • pl.add_mesh(uni, scalars='My Point Data', show_edges=True): 在第一列子图中添加网格。使用 'My Point Data' 作为标量(色彩)来显示网格点的颜色,show_edges=True 表示绘制网格的边缘线,增强可视化效果。
  6. 切换子图

    • pl.subplot(0, 1): 切换到第一行第二列的子图,准备在该位置绘制新的图形。
  7. 绘制单元数据

    • pl.add_mesh(uni, scalars='My Cell Data', show_edges=True): 在第二列子图中添加网格,同样使用 'My Cell Data' 作为标量显示单元的颜色,不同的随机值将导致不同的颜色映射。
  8. 显示绘图

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

 

代码解释:

  1. 导入库:首先,代码导入了 pyvista 库,这是一个用于 3D 可视化的 Python 库。

  2. 创建立方体:使用 pv.Cube() 创建一个立方体实例,赋值给变量 cube

  3. 添加单元数据:利用 cell_data 属性为立方体添加标量数据,这些数据是一个范围从 0 到 5 的整数。这些标量数据会在渲染时用于控制立方体表面的颜色。

  4. 复制立方体:使用 copy() 方法复制 cube 以创建 other_cube

  5. 添加点数据:为复制的立方体添加点数据(point_data),这组标量数据是范围从 0 到 7 的整数,用于控制第二个立方体颜色的显示。

  6. 创建绘图器:使用 pv.Plotter 创建绘图器,并设置绘图的布局为 1 行 2 列。

  7. 添加和渲染立方体

    • 在第一个子图内渲染第一个立方体(cube),使用 "coolwarm" 颜色映射。
    • 切换到第二个子图,渲染第二个立方体(other_cube),也使用 "coolwarm" 颜色映射。
  8. 展示绘图:最后,通过 pl.show() 显示绘图窗口,渲染二个立方体的 3D 图像。

 


http://www.kler.cn/a/313918.html

相关文章:

  • 【Kafka-go】golang的kafka应用
  • Python的函数(补充浅拷贝和深拷贝)
  • 网络安全---安全见闻
  • 【Zookeeper集群搭建】安装zookeeper、zookeeper集群配置、zookeeper启动与关闭、zookeeper的shell命令操作
  • 342--358作业整理(错误 + 重点)
  • 如何在 Docker 容器中启动 X11 图形界面程序
  • JavaScript发送邮件:实现前端触发的教程?
  • 【VitualBox】VitualBox的网络模式+网络配置
  • VuePress搭建文档网站/个人博客(详细配置)主题配置
  • 自动登录 RPA 的进阶:滑块验证的巧妙实现
  • 远程连接MySQL并操作
  • PostgreSQL JAVA与SQL集成之PL/Java
  • 科研绘图系列:R语言散点图和小提琴图(scatter plot violin plot)
  • 【ORACLE】客户端或plsql无法连接Oracle问题之一
  • 基于A2C与超启发式的航天器星载自主任务规划算法-笔记
  • 大数据新视界 --大数据大厂之JavaScript在大数据前端展示中的精彩应用
  • Vue 修饰符 | 指令 区别
  • C/C++笔记
  • python基础题练习
  • leetcode 605.种花问题
  • 青岛特某电新能源有限公司-充电业务流程及数据交互规范-集控前置-精简版V1.0
  • Debian 12上安装google chrome
  • 前端vue-自己封装组件并使用三步走
  • k8s pod网络故障注入,命令行实现
  • 功能强大的任务 / 项目管理工具GoodTask for Mac
  • Redis 集群搭建教程