许可优化
许可优化
产品
产品
解决方案
解决方案
服务支持
服务支持
关于
关于
软件库
当前位置:服务支持 >  软件文章 >  ANSYS任意平面节点自动抓取代码+封装一步到位,学员刚需解法

ANSYS任意平面节点自动抓取代码+封装一步到位,学员刚需解法

阅读数 1
点赞 0
article_banner


导读: 大家好,我是小郭老师,硕士毕业于中科院,专注于运用 Python 深度集成 ANSYS 进行工程数值计算与仿真自动化开发,精通基于 Python实现ANSYS Workbench众多模块的全流程脚本驱动(建模、求解、后处理),并具备将复杂仿真流程封装为高效、可复用软件工具的专业能力,今天给大家分享一些ANSYS二次开发方面的干货。

在ANSYS仿真后处理中,提取任意自定义平面的物理量(如应力、位移、应变)是高频需求——小到零部件的截面分析,大到复杂结构的多平面验证,都离不开“筛选目标平面节点”这一步。但传统手动框选的方式,不仅容易漏选、错选,精度全靠肉眼判断,遇到复杂网格或多批次分析时,重复操作更是耗时费力。

前阵子有学员专门找我反馈:“能不能做一个工具,我选3个节点定好平面,软件自动把平面内所有节点都抓出来?”。今天就基于这个真实工程需求,带大家用ANSYS二次开发实现“3点定平面+节点自动抓取+一键封装”,全程干货,代码可直接复制使用!

一、核心思路:从“3个点”到“整个平面”的逻辑拆解

其实这个需求的核心逻辑很简单——用数学方法精准定位平面,再用代码批量筛选节点,具体可以拆成4个关键步骤,小白也能看懂:

  1. 获取基准点:用户在ANSYS界面手动选中3个节点,作为定义目标平面的“基准三点”;
  2. 计算平面方程:通过向量叉积求出这3个点所在平面的方程(ax+by+cz+d=0),这是判断节点是否在平面上的数学基础;
  3. 批量筛选节点:遍历整个模型的所有网格节点,计算每个节点到目标平面的距离,在设定容差范围内的节点,判定为“平面内节点”;
  4. 创建命名选择:自动将筛选出的节点打包成“命名选择”,后续直接调用这个命名选择就能提取物理量,无需重复筛选。

整个过程用代码替代了手动框选的“模糊操作”,既保证了精度,又省去了重复劳动,这正是ANSYS二次开发的实用价值所在。

二、实战代码解析:逐模块看懂实现逻辑

下面我们结合完整代码,逐模块拆解核心功能——代码基于ANSYS Mechanical的Python API开发,兼容大部分版本,关键部分都加了详细注释,大家可以边看边理解。

1. 基础依赖:3个核心函数,搞定平面计算与节点筛选

这部分是整个工具的“数学核心”,负责平面方程计算和节点有效性判断,完全独立于ANSYS界面,逻辑通用:

(1)平面方程计算函数(calculate_plane_equation)

代码块

Python


     自动换行
   


     复制代码
   

123456789101112131415161718192021222324


def calculate_plane_equation(p1, p2, p3):
    """
    通过三个点计算平面方程系数
    
    参数:
        p1, p2, p3: 三个点的坐标,每个点是一个包含(x, y, z)的元组/列表
    
    返回:
        a, b, c, d: 平面方程ax + by + cz + d = 0的系数
    """
    # 计算从p1出发的两个向量
    AB = (p2[0] - p1[0], p2[1] - p1[1], p2[2] - p1[2])  # 向量AB
    AC = (p3[0] - p1[0], p3[1] - p1[1], p3[2] - p1[2])  # 向量AC
    
    # 通过叉积计算法向量
    normal = (AB[1]*AC[2] - AB[2]*AC[1],  # 法向量的x分量
              AB[2]*AC[0] - AB[0]*AC[2],  # 法向量的y分量
              AB[0]*AC[1] - AB[1]*AC[0])  # 法向量的z分量
    
    # 提取法向量分量作为平面方程系数a, b, c
    a, b, c = normal
    d = -(a * p1[0] + b * p1[1] + c * p1[2])  # 计算常数项d
    
    return a, b, c, d
    
      复制成功
     
     
     
     

通过3个基准点的坐标,用向量叉积求出平面的法向量,进而推导平面方程ax+by+cz+d=0的4个系数(a、b、c、d)。 核心逻辑:先计算从第一个点出发的两个向量,再通过叉积得到垂直于这两个向量的法向量(法向量方向就是平面的垂直方向),最后代入点坐标求出常数项d。

(2)节点平面判断函数(is_point_on_plane)

代码块

Python


     自动换行
   


     复制代码
   

123456789101112131415161718192021222324


def is_point_on_plane(point, plane_coeffs, tolerance=1e-2):
    """
    判断点是否在平面上
    
    参数:
        point: 点的坐标(x, y, z)
        plane_coeffs: 平面方程系数(a, b, c, d)
        tolerance: 距离容差,默认为1e-3
    
    返回:
        True/False: 点是否在平面上
    """
    a, b, c, d = plane_coeffs  # 解包平面方程系数
    
    # 计算点到平面的距离
    numerator = abs(a*point[0] + b*point[1] + c*point[2] + d)  # 绝对距离
    denominator = math.sqrt(a*a + b*b + c*c)  # 法向量模长
    
    if denominator == 0:  # 避免除零错误
        return False
    
    normalized_distance = numerator / denominator  # 计算归一化距离
    
    return normalized_distance < tolerance  # 判断是否在容差范围内
    
      复制成功
     
     
     
     

判断单个节点是否在目标平面上,核心是“距离容差法”: 计算节点到平面的垂直距离,若距离小于设定的容差(默认1e-2,可根据网格精度调整),则认为节点在平面上。 这里加了“除零防护”——如果法向量模长为0(说明3个基准点共线,无法构成平面),直接返回False,避免程序报错。

(3)平面节点提取函数(get_nodes_on_plane)

代码块

Python


     自动换行
   


     复制代码
   

123456789101112131415161718192021222324


def get_nodes_on_plane(mesh_data, plane_p1, plane_p2, plane_p3, tolerance=1e-2):
    """
    获取网格中位于指定平面上的所有节点
    
    参数:
        mesh_data: 网格数据对象
        plane_p1, plane_p2, plane_p3: 定义平面的三个点
        tolerance: 距离容差,默认为1e-3
    
    返回:
        on_plane_nodes: 位于平面上的节点ID列表
    """
    # 计算平面方程
    plane_coeffs = calculate_plane_equation(plane_p1, plane_p2, plane_p3)
    
    on_plane_nodes = []  # 存储平面上节点ID的列表
    
    # 遍历网格中的所有节点
    for node in mesh_data.Nodes:
        node_coords = (node.X, node.Y, node.Z)  # 获取节点坐标
        if is_point_on_plane(node_coords, plane_coeffs, tolerance):  # 判断是否在平面上
            on_plane_nodes.append(node.Id)  # 存储节点ID
    
    return on_plane_nodes
    
      复制成功
     
     
     
     

批量遍历模型所有节点,调用上面的“节点平面判断函数”,把符合条件的节点ID收集起来,最终返回一个“平面内节点ID列表”,为后续创建命名选择做准备。

2. 主程序逻辑:对接ANSYS界面,实现“选择-计算-筛选-输出”闭环

这部分是代码与ANSYS Mechanical交互的关键,负责获取用户操作、校验输入合法性、执行筛选并生成命名选择:

(1)网格数据获取

通过获取模型的全局网格数据,这是读取所有节点坐标的基础; 通过获取用户当前选中的节点,提取节点ID和坐标。

(2)输入合法性校验

强制要求用户必须选中3个节点——如果选中节点数不是3,会弹出错误提示(“错误!手动选择必须选择3个节点”),并终止程序,避免因输入错误导致计算失败。

代码块

Python


     自动换行
   


     复制代码
   

12345


# 确定平面的三个点
if len(node_ids) != 3:  # 必须选择3个节点
    msg = Ansys.Mechanical.Application.Message("错误!手动选择必须选择3个节点", MessageSeverityType.Error)
    ExtAPI.Application.Messages.Add(msg)
    raise ValueError("错误!手动选择必须选择3个节点")
    
      复制成功
     
     
     
     

(3)平面节点抓取与命名选择创建

调用前面定义的函数,获取目标平面上的所有节点ID; 通过创建新的命名选择,将筛选出的节点ID赋值给命名选择,最后执行生成,全程自动完成,无需手动干预。

3. 完整可复制代码

代码块

Python


     自动换行
   


     复制代码
   

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112


# 导入数学库,用于向量和距离计算
import math


################################################################################
# 函数定义
################################################################################

def calculate_plane_equation(p1, p2, p3):
    """
    通过三个点计算平面方程系数
    
    参数:
        p1, p2, p3: 三个点的坐标,每个点是一个包含(x, y, z)的元组/列表
    
    返回:
        a, b, c, d: 平面方程ax + by + cz + d = 0的系数
    """
    # 计算从p1出发的两个向量
    AB = (p2[0] - p1[0], p2[1] - p1[1], p2[2] - p1[2])  # 向量AB
    AC = (p3[0] - p1[0], p3[1] - p1[1], p3[2] - p1[2])  # 向量AC
    
    # 通过叉积计算法向量
    normal = (AB[1]*AC[2] - AB[2]*AC[1],  # 法向量的x分量
              AB[2]*AC[0] - AB[0]*AC[2],  # 法向量的y分量
              AB[0]*AC[1] - AB[1]*AC[0])  # 法向量的z分量
    
    # 提取法向量分量作为平面方程系数a, b, c
    a, b, c = normal
    d = -(a * p1[0] + b * p1[1] + c * p1[2])  # 计算常数项d
    
    return a, b, c, d


def is_point_on_plane(point, plane_coeffs, tolerance=1e-2):
    """
    判断点是否在平面上
    
    参数:
        point: 点的坐标(x, y, z)
        plane_coeffs: 平面方程系数(a, b, c, d)
        tolerance: 距离容差,默认为1e-3
    
    返回:
        True/False: 点是否在平面上
    """
    a, b, c, d = plane_coeffs  # 解包平面方程系数
    
    # 计算点到平面的距离
    numerator = abs(a*point[0] + b*point[1] + c*point[2] + d)  # 绝对距离
    denominator = math.sqrt(a*a + b*b + c*c)  # 法向量模长
    
    if denominator == 0:  # 避免除零错误
        return False
    
    normalized_distance = numerator / denominator  # 计算归一化距离
    
    return normalized_distance < tolerance  # 判断是否在容差范围内


def get_nodes_on_plane(mesh_data, plane_p1, plane_p2, plane_p3, tolerance=1e-2):
    """
    获取网格中位于指定平面上的所有节点
    
    参数:
        mesh_data: 网格数据对象
        plane_p1, plane_p2, plane_p3: 定义平面的三个点
        tolerance: 距离容差,默认为1e-3
    
    返回:
        on_plane_nodes: 位于平面上的节点ID列表
    """
    # 计算平面方程
    plane_coeffs = calculate_plane_equation(plane_p1, plane_p2, plane_p3)
    
    on_plane_nodes = []  # 存储平面上节点ID的列表
    
    # 遍历网格中的所有节点
    for node in mesh_data.Nodes:
        node_coords = (node.X, node.Y, node.Z)  # 获取节点坐标
        if is_point_on_plane(node_coords, plane_coeffs, tolerance):  # 判断是否在平面上
            on_plane_nodes.append(node.Id)  # 存储节点ID
    
    return on_plane_nodes


################################################################################
# 主程序逻辑:根据指定模式确定平面,然后获取平面上所有节点并创建命名选择
################################################################################
# 获取网格数据
meshData = DataModel.MeshDataByName("Global")  # 从DataModel获取网格数据
selection = ExtAPI.SelectionManager.CurrentSelection  # 获取当前选择
node_ids = selection.Ids  # 获取选择的节点ID
# 确定平面的三个点
if len(node_ids) != 3:  # 必须选择3个节点
    msg = Ansys.Mechanical.Application.Message("错误!手动选择必须选择3个节点", MessageSeverityType.Error)
    ExtAPI.Application.Messages.Add(msg)
#    raise ValueError("错误!手动选择必须选择3个节点")
else:
    plane_points = []  # 存储平面点坐标
    for node_id in selection.Ids:  # 遍历选择的节点
        node = meshData.NodeById(node_id)  # 通过ID获取节点
        plane_points.append([node.X, node.Y, node.Z])  # 存储坐标
    # 获取平面上所有节点的ID
    nodeIds_on_plane = get_nodes_on_plane(meshData, plane_points[0], plane_points[1], plane_points[2])
    
    # 创建命名选择
    selection = ExtAPI.SelectionManager.CreateSelectionInfo(SelectionTypeEnum.MeshNodes)  # 创建网格节点选择对象
    selection.Ids = nodeIds_on_plane  # 设置选择的节点ID
    ns = Model.AddNamedSelection()  # 添加命名选择
    ns.Location = selection  # 设置选择位置
    ns.Generate()  # 生成命名选择
    
      复制成功
     
     
     
     

4. 关键细节说明(避坑重点)

  • 容差设置:代码中默认容差是1e-2(即0.01),如果网格较密(节点间距小于0.01),可调整为1e-3,避免漏选;如果网格较粗,可放大到5e-2,提高筛选效率;
  • 除零防护:在计算点到平面距离时,增加了denominator == 0的判断,防止3个基准点共线导致的程序崩溃;
  • 错误提示:用户选中节点数不是3时,会弹出ANSYS系统错误提示,同时终止程序,方便快速定位问题。

三、快速落地:1分钟封装成自定义按钮,一键调用

代码写好后,不用每次都复制粘贴到Scripting窗口——利用ANSYS Mechanical的「User Buttons」功能,可直接封装成自定义按钮,下次用的时候点击一下就行,步骤超简单:

1. 封装工具介绍

「User Buttons」是ANSYS Mechanical Automation选项卡下的原生功能,专门用于存放用户自定义的二次开发工具,支持Python代码直接封装,无需复杂配置。


2. 封装步骤(以ANSYS 2023R2为例)

  1. 打开ANSYS Mechanical,切换到「Automation」选项卡,找到「User Buttons」组,点击「Manage」;
  2. 在弹出的“Button Editor”窗口中,输入按钮名称(比如“GetPlane”),选择图标(可选,方便识别)
  3. 在「Script」文本框中,删除默认内容,粘贴上面的完整代码;
  4. 点击左上角保存图标进行保存

3. 调用流程演示

1. 在ANSYS Mechanical中,打开已划分网格的模型;

2. 选中网格节点功能,选择至少三个的网格节点:


3. 点击「Automation -> User Buttons -> GetPlaneNodes (自己给定的按钮名称)」,程序会自动计算平面、筛选节点,并创建命名选择;

4. 后续提取物理量时,直接选择这个命名选择,即可快速获取目标平面的所有物理量数据。


四、总结:二次开发的“实用性”,藏在解决工程痛点里

这个工具虽然简单,但精准解决了“自定义平面节点筛选”的高频痛点,核心优势很明确:

• 适配任意平面:不管是倾斜平面、复杂截面,只要选3个基准点,就能自动抓取所有平面内节点;

• 操作极简:封装后一键调用,无需专业编程知识,普通工程师也能快速上手;

• 延伸性强:生成的命名选择可直接用于物理量提取、云图显示、数据导出,甚至批量优化分析。

其实ANSYS二次开发不用追求“高大上”,从实际工程需求出发,用几行代码解决一个具体痛点,就是最实用的开发。比如这个工具,看似简单,却能让工程师从重复的手动操作中解放出来,把时间花在更核心的仿真分析上——这正是二次开发的核心意义。

如果大家还有其他ANSYS使用中的痛点(比如批量设置载荷、自动生成报告、多工况对比等),欢迎在评论区留言,后续会持续分享针对性的二次开发实战案例!

点击链接《https://www.fangzhenxiu.com/course/13411984/》,立即学习《ANSYS Workbench & Mechanical企业级二次开发程序与Python应用入门进阶》,掌握ANSYS Workbench & Mechanical的脚本自动化开发能力。

本课程从基础脚本开发到多工况批量计算的自动化实现,手把手教你用 Python 打通 “仿真流程自动化 - 多工况批量计算” 全链路,让 “重复仿真工作自动化、复杂工况高效计算” 从想法变成日常。

我还为付费用户提供VIP群进行交流、答疑服务持续加餐内容、提供定制化培训和咨询服务仿真人才库高薪内推就业、仿真秀还提供奖学金、学完此课程,推荐学习者报名参加工程仿真技术(CAE分析职业能力等级评价证书)。

以下是课程大纲及主要内容




免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删

相关文章
技术文档
QR Code
微信扫一扫,欢迎咨询~
customer

online

联系我们
武汉格发信息技术有限公司
湖北省武汉市经开区科技园西路6号103孵化器
电话:155-2731-8020 座机:027-59821821
邮件:tanzw@gofarlic.com
Copyright © 2023 Gofarsoft Co.,Ltd. 保留所有权利
遇到许可问题?该如何解决!?
评估许可证实际采购量? 
不清楚软件许可证使用数据? 
收到软件厂商律师函!?  
想要少购买点许可证,节省费用? 
收到软件厂商侵权通告!?  
有正版license,但许可证不够用,需要新购? 
联系方式 board-phone 155-2731-8020
close1
预留信息,一起解决您的问题
* 姓名:
* 手机:

* 公司名称:

姓名不为空

姓名不为空

姓名不为空
手机不正确

手机不正确

手机不正确
公司不为空

公司不为空

公司不为空