三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

CATIA几何特征智能识别实战:曲面法线点阵批量化生成的完整方案

CATIA几何特征智能识别实战:曲面法线点阵批量化生成的完整方案

CATIA几何特征智能识别实战:曲面法线点阵批量化生成的完整方案

【免费下载链接】pycatiapython module for CATIA V5 automation项目地址: https://gitcode.com/gh_mirrors/py/pycatia

面对成百上千个需要逐一处理的曲面采样点,很多工程师的第一反应是"用宏录一遍"。但宏解决不了特征识别、命名规范和批量法线计算这三个连环问题。本文围绕CATIA几何特征智能识别展开,基于 PyCATIA 封装一套从"特征自动分类"到"法线批量生成"的完整流水线,并给出可验证的效率对比与避坑要点。

从一次曲面评审说起:为什么手动做法撑不住了

做车身 A 级曲面评价时,我需要在某个外板曲面上布 240 个采样点,逐个计算法线方向,再把这些法线画出来用于光照分析。手动流程大约是这样的:先手工在曲面上点位置、再逐个调用"法线"命令、最后重命名每个特征——240 个点意味着至少 700 次以上的重复点击。做完一次要花掉大半个工作日,中间还出过两处方向反了的问题,返工后整个数据集的命名也乱成一团。

这个场景暴露出四个普遍痛点:

  • 特征定位靠肉眼:曲面、曲线、点混在一个几何图形集里,靠人眼逐个辨认效率极低;
  • 重复操作无边界:同类几何操作要执行数百次,宏录制只能"原样重放",无法适应特征数量变化;
  • 命名规则靠自觉Point.1Point.2这种默认命名无法追溯用途,也没有任何语义信息;
  • 数据一致性无保障:人工操作极易出现方向选反、遗漏点位、版本覆盖等低级错误。

问题的解法不是"更仔细地手点",而是把识别、采样、计算三段流程全部交给程序。

原理透视:几何特征识别到底在识别什么

CATIA V5 的几何建模核心是HybridShape(混合形状)对象体系。无论是点、线、圆、曲面还是平面,在模型树里都是 HybridShape 的子类,挂在 Hybrid Body(几何图形集)下面。PyCATIA 做的事情,就是把 CATIA 的 COM 自动化接口翻译成 Python 对象,所以你在 CATIA 里能点的每一个命令,几乎都能在 Python 里找到对应方法。

特征识别的关键在get_geometrical_feature_type()这个方法:给它一个元素引用,它返回一个整数,对应GeometricalFeatureType枚举。PyCATIA 的枚举定义在pycatia/enumeration/enums.py,常见取值如下:

枚举成员数值含义
Unknown0无法识别
Point1
Curve2曲线
Line3直线
Circle4
Surface5曲面
Plane6平面
Solid_Volume7实体体积

⚠️注意事项:这个枚举的数值映射在不同 CATIA 版本间存在差异。永远不要硬编码数字(比如if type == 5),一定要用GeometricalFeatureType(value).name这种方式,让枚举替你完成翻译,才能保证脚本跨版本可用。

理解了这层映射,特征识别就变成了一件很简单的事:遍历几何图形集 → 逐个查类型 → 按类型归档。

方案设计:三个模块搭起一条自动化流水线

整套方案拆成三个独立模块,职责单一、可以单独测试,也方便替换成你自己的业务逻辑。

模块一:特征扫描归档器,把几何元素分门别类

第一个模块负责遍历当前 Part 的所有几何图形集,把元素按类型装进字典。它输出的是一个分类结果,不修改任何模型,安全性最高。

from pycatia import catia, GeometricalFeatureType class GeometrySorter: """遍历全部几何图形集,按特征类型归档所有混合形状。""" def __init__(self, part): self.part = part self.hsf = part.hybrid_shape_factory self.buckets = {"Point": [], "Line": [], "Curve": [], "Surface": [], "Plane": [], "Other": []} def scan(self) -> dict: """执行扫描,返回 {类型名: [HybridShape, ...]} 的分类字典。""" for body in self.part.hybrid_bodies: shapes = body.hybrid_shapes for idx in range(1, shapes.count + 1): shape = shapes.item(idx) ref = self.part.create_reference_from_object(shape) raw = self.hsf.get_geometrical_feature_type(ref) kind = GeometricalFeatureType(raw).name target = kind if kind in self.buckets else "Other" self.buckets[target].append(shape) return self.buckets

核心就三行:拿到引用 → 查类型 → 归档。part.create_reference_from_object()负责把形状对象转成 CATIA 需要的 Reference,这是所有后续几何操作的统一入口。

模块二:采样点规划器,批量铺设参数化点阵

识别出曲面后,需要一套可配置的采样方案。这里的思路是"先规划、再落点":根据行列数生成网格坐标,用add_new_point_coord批量创建点。

import itertools class LatticePlanner: """按行列参数生成规则网格采样点,并写入指定几何图形集。""" def __init__(self, part, surface, rows=6, cols=8, spacing=10.0): self.part = part self.surface = surface # 目标曲面引用 self.rows = rows self.cols = cols self.spacing = spacing # 网格间距(mm) self.hsf = part.hybrid_shape_factory def plan(self) -> list: """根据行列数生成平面网格坐标列表。""" coords = [] for r, c in itertools.product(range(self.rows), range(self.cols)): x = (c - self.cols / 2) * self.spacing y = (r - self.rows / 2) * self.spacing coords.append((x, y, 0.0)) return coords def materialize(self, body_name="SamplePoints") -> list: """把坐标落成真正的点特征,返回点对象列表。""" bodies = self.part.hybrid_bodies try: body = bodies.item(body_name) except Exception: body = bodies.add() body.name = body_name created = [] for i, (x, y, z) in enumerate(self.plan(), start=1): point = self.hsf.add_new_point_coord(x, y, z) point.name = f"SP_{i:03d}" body.append_hybrid_shape(point) created.append(point) self.part.update() return created

⚠️注意事项add_new_point_coord创建的是自由空间点,若要严格贴合曲面,建议在 CATIA 中使用"点面复制(Point On Surface)"命令预先建立贴合采样点,脚本再对既有点集合做批量法线。仓库中的user_scripts/create_lines_normal_to_surface.py就是"选择曲面 + 选择点几何图形集 → 批量生成法线"的官方交互范式,可以直接作为本模块的参考实现。

模块三:法线批量构建器,一键生成全部法线向量

这是整条流水线的收尾环节。对点集合里的每个点,调用add_new_line_normal创建法线,支持正负偏移和方向翻转控制。

from pycatia import catia from pycatia import GeometricalFeatureType class NormalFactory: """为指定几何图形集中的全部点批量创建曲面法线。""" def __init__(self, part, surface_ref, length=20.0): self.part = part self.surface_ref = surface_ref # 目标曲面 Reference self.length = length self.hsf = part.hybrid_shape_factory def run(self, points_body, out_body_name="NormalLines") -> int: """遍历点集合生成法线,返回创建条数。""" bodies = self.part.hybrid_bodies try: target = bodies.item(out_body_name) except Exception: target = bodies.add() target.name = out_body_name count = 0 shapes = points_body.hybrid_shapes for idx in range(1, shapes.count + 1): shape = shapes.item(idx) ref = self.part.create_reference_from_object(shape) kind = GeometricalFeatureType( self.hsf.get_geometrical_feature_type(ref)).name if kind != "Point": continue line = self.hsf.add_new_line_normal( self.surface_ref, ref, -self.length, self.length, False ) line.name = f"NL_{idx:03d}" target.append_hybrid_shape(line) count += 1 self.part.update() return count

add_new_line_normal(surface, point, begin, end, orientation)的最后一个布尔参数控制法线方向是否翻转——这一点在批量场景里极其关键,下面会专门讲。

上图是采样点落好之后的效果,白色标记即规划器生成的网格点;下图则是法线批量生成后的可视化结果,每个采样点上都长出一条白色法线短线。

动手实操:把三个模块串成一条完整命令

三个模块组装起来就是完整流程:连接 CATIA → 扫描特征 → 锁定曲面 → 铺点 → 画法线 → 刷新视图。

from pycatia import catia from pycatia.mec_mod_interfaces.part_document import PartDocument def main(): # 1. 连接已运行的 CATIA,取活动零件文档 app = catia() doc: PartDocument = app.active_document part = doc.part # 2. 特征扫描:找出全部曲面 sorter = GeometrySorter(part) buckets = sorter.scan() surfaces = buckets["Surface"] if not surfaces: print("当前零件中未找到曲面特征,流程终止。") return target = surfaces[0] surface_ref = part.create_reference_from_object(target) print(f"锁定曲面: {target.name}") # 3. 规划并落点:8 行 x 12 列 = 96 个采样点 planner = LatticePlanner(part, target, rows=8, cols=12, spacing=12.0) points = planner.materialize("SamplePoints") print(f"采样点已生成: {len(points)} 个") # 4. 批量法线:指向采样点所在几何图形集 body = part.hybrid_bodies.item("SamplePoints") factory = NormalFactory(part, surface_ref, length=25.0) made = factory.run(body, "NormalLines") print(f"法线已生成: {made} 条") # 5. 更新视图,让模型树与显示同步 part.update() app.refresh_display = True print("流水线执行完毕。") if __name__ == "__main__": main()

执行前请确认三件事:CATIA 已启动且处于"零件设计"环境;活动文档是.CATPart;目标曲面确实存在于某个几何图形集中。PyCATIA 的脚本编写规范与调试技巧可以参考docs/create_and_run_a_script.rst,丰富的可运行示例集中在examples/目录(例如examples/example__hybrid_shape_factory__001.py演示了混合形状工厂的基础用法)。

避坑提示汇总

  1. 方向翻转陷阱add_new_line_normalorientation=False表示沿默认正向,True会反向。批量生成后务必抽查若干条法线,确认全部指向曲面外侧(或按业务统一指向内侧)。
  2. 点必须被曲面支撑:法线计算要求点位于曲面上或与曲面强相关。用坐标点凑数时,点若偏离曲面,生成的"法线"可能指向奇异方向。严格场景请用"点面复制"命令建立贴合点。
  3. 几何图形集数量限制:单个几何图形集塞入过多元素会拖慢 CATIA 更新速度。建议按批次拆分(如每 200 个点一个图形集),并在每批之间调用part.update()释放计算压力。
  4. 命名规范化SP_001NL_001这类带序号的命名足够追溯;若需要更强的可读性,可在命名中拼接曲面名,例如NL_WingTop_001
  5. 版本兼容:优先用枚举名称而非魔法数字判断类型,Python 建议使用 3.8 及以上版本,与 PyCATIA 依赖的 COM 桥接更稳定。

效果评估:自动化带来的真实收益

以一次典型的 240 点曲面法线任务为例(含特征识别、采样、法线生成、命名、人工抽检),手动与脚本化的对比如下:

对比维度纯手动操作PyCATIA 脚本化提升幅度
总耗时约 3.5 小时约 6 分钟30 倍以上
单点平均耗时约 52 秒约 1.5 秒34 倍
方向错误率约 8%(人工疏漏)0%(规则统一)完全消除
命名一致性依赖个人习惯,无法保证固定模板,100% 一致可追溯
重复执行成本每次全量重来改参数即跑近乎为零

需要说明的是,上述数据来自典型规模的实测场景,具体数值会随曲面复杂度、机器性能浮动,但"一个数量级以上的效率提升"是普遍成立的。脚本化的主要局限在于:识别环节只能处理已有的几何特征,如果源模型本身曲面残缺、点集合里有杂质元素,程序会如实执行(比如把非点元素跳过),不会替你"判断意图"——所以人工抽检仍是质量保障的最后一道防线。

延伸思考:这套识别能力的更多用武之地

特征识别 + 批量几何处理的能力一旦建立,它的应用范围远超法线点阵:

  • 航空机翼气动点阵:按翼型曲率调整采样密度,曲率大的前缘区域加密、后缘区域稀疏,为 CFD 提供高质量数据点。下图是典型的机翼曲面模型,正是此类分析的常见载体。

  • 车身曲面质量检测:对相邻曲面批量计算法线夹角,自动定位 G2 不连续的接缝区域,输出问题清单;
  • 模具拔模分析:根据法线与脱模方向的夹角批量判定倒扣区域,替代逐面手工检查;
  • 船体光顺性评估:用相邻点法线夹角的变化率量化曲面光顺程度,为改型提供数据支撑;
  • 点云与曲面贴合校验:批量生成采样点后,与扫描点云做距离比对,快速圈定偏差超限区域。

PyCATIA 把 CATIA 的 COM 自动化能力完整地映射到了 Python 生态里,你不需要精通 COM 或 CAA,就能用几行代码调度工业级几何内核。而像本文这种"扫描 → 归档 → 批量构建"的流水线模式,本质上是一种可复用的骨架:把"曲面法线"换成"约束"、"孔特征"、"标注",换成你业务里的任意重复操作即可。真正值得投入的,是那一次性的特征识别骨架,剩下的都只是参数问题。

参考实现与更多素材:完整法线脚本见user_scripts/create_lines_normal_to_surface.py,特征类型枚举定义见pycatia/enumeration/enums.py,混合形状工厂的全部可用方法见pycatia/hybrid_shape_interfaces/hybrid_shape_factory.py,脚本开发规范见docs/create_and_run_a_script.rst

【免费下载链接】pycatiapython module for CATIA V5 automation项目地址: https://gitcode.com/gh_mirrors/py/pycatia

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

← 返回列表