ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

NX二次开发Python实战:自动提取坯料尺寸与包围盒计算

NX二次开发Python实战:自动提取坯料尺寸与包围盒计算 做NX二次开发这几年我主要是用Python写一些CAM自动化的小工具。这个领域其实挺垂直的但需求一直很实在比如“坯料尺寸”这个东西在加工编程里几乎是天天要碰的。手动测量、手动填、模型改版再测一遍这些重复劳动完全可以用脚本一次性吃掉。这篇就是这个系列的第一篇先把技术路线和核心代码骨架讲透后面再慢慢展开通孔、盲孔这些特征识别的问题。开始之前先交代一下背景NX二次开发python指的就是用NX自带的NXOpen Python API去操作模型、做自动化处理早期大家习惯叫UG二次开发现在NX版本更新到1953、2206这些大版本Python的API覆盖已经相当完整了。这篇文章适合数控工艺、CAM工程师还有想入门NX二次开发的同学思路和代码都能直接拿去跑。1. 坯料尺寸在CAM流程里的位置以及为什么值得写成脚本1.1 毛坯是CAM编程的“地基”做过CAM编程的人都知道一个完整的加工工序通常要定义三样东西加工坐标系MCS、零件几何体、毛坯几何体。毛坯blank的尺寸看起来就是个简单框但它直接影响后面几乎所有操作。举个例子型腔铣的切削层计算要基于毛坯来定刀轨的进刀、退刀安全距离要参考毛坯轮廓碰撞检查和刀轨显示仿真也要有一个真实的毛坯体才能看出来过切和撞刀甚至侧刃切削深度、拐角减速范围这些参数也会根据毛坯余量自动调整。所以说坯料尺寸不是“填个数”那么简单它本质上是一个加工策略的输入边界。1.2 手动设置毛坯的痛点做过批量编程的人都会懂我之前在一个零部件加工厂待过每天要排产十几套、几十套零件。编程员拿到模型以后第一步往往就是测量模型最大外形尺寸然后在CAM里把毛坯的X、Y、Z三个方向尺寸敲进去。这个流程单独看一次不费劲但实际生产中经常是这几个状态来回切换零件模型改版外形尺寸变了毛坯没更新刀路计算出来全是错的一批外形相似但尺寸不同的零件同样的工序要重复建立毛坯参数人工比对很容易串数据想把毛坯尺寸输出到工艺卡片或者下游系统只能靠手工抄录一个数字抄错就是一道报废工序。这些问题靠人盯着是盯不住的。用NX二次开发python写一个自动化工具把“读取零件模型最大外形尺寸、换算成坯料的长宽高、输出或写入CAM设置”这几步串成一条流水线才是效率层面的正解。1.3 这篇工具脚本到底能干什么如果只提一个最核心的目标那就是在NX里用Python自动获取当前工作部件所有实体体的包围盒尺寸并把结果按方向整理成形如“X120.0000, Y80.0000, Z45.0000”的毛坯参照尺寸输出到信息窗口同时为后续直接写回CAM的Blank几何体做准备。这个工具做好以后点一下运行毛坯尺寸就出来了不用再去测量工具里手动点。而且后续完全可以扩展成批量处理整个文件夹的prt文件导出一个工艺尺寸清单。这一篇先把最基础、最重要的数据获取环节讲明白。2. 技术选型为什么用Python以及开发环境怎么搭2.1 Python、C、C#三条路线怎么选NX二次开发历史上主要有三种语言路线C、C#或者说.NET、PythonJournal。很多老工程师习惯C因为它最底层、性能最好适合写复杂的算法和自定义UIC#在某些企业内部管理系统集成上用得也多。但我个人现在偏向Python原因很直接Python代码写起来快尤其在处理批量任务、文本输出、数据整理这些场景下开发效率高得多NX从1847系列开始Python的API覆盖程度大幅提升很多以前必须用C或者GRIP的事情现在Python都能做对于不做重型交互界面、不搞超大计算量的自动化小工具来说Python完全够用。当然Python也有它的短板比如复杂曲面算法、大装配体遍历时会比较慢但做坯料尺寸这种级别的操作根本感觉不到性能差异。2.2 NX版本和Python环境的搭配NXOpen Python的API在NX 1953系列之后变得比较稳定我建议如果条件允许至少用NX 1953以上版本做二次开发Python解释器和API文档都更齐全。老版本的NX虽然也能跑Python但一些新方法比如包围盒获取、CAM对象操作的行为会有差异后面调试起来会多花时间。环境配置上其实不需要单独安装Python解释器NX安装目录下自带了一个Python环境。比如我本机的路径大概是C:\Program Files\Siemens\NX2206\NXBIN\python你们可以根据自己的安装盘符和版本找到。如果你想用VSCode做开发只要在VSCode里配置Python解释器路径指向这个目录就能获得语法提示和代码补全能力。具体配置不展开核心就是在.vscode/settings.json里指定python.pythonPath然后装上Python插件就行。提示NX自带的Python环境是精简过的不建议在里面用pip装第三方库。如果你需要在二次开发里用numpy、openpyxl这些库要么手动把库文件放到NX搜索路径下要么在外部解释器里先用Anaconda做好测试再搬进NX环境这块单独规划更稳妥。2.3 开发调试时的起点从录制Journal开始有一个新手阶段特别推荐的做法在NX里手动操作一遍目标功能同时用“工具”菜单里的Journal录制功能把过程录成Python脚本然后再对这个脚本做二次修改。这个方法能帮你快速确认当前NX版本到底调用了哪些API比我凭文档瞎猜准确得多。比如你想知道“获取当前部件”在NXOpen Python里怎么写最稳的方法就是录一个空操作生成的开头几行就是标准模板。我的经验是每个大版本之间API有细微变化录制出来的代码永远是当前版本最有说服力的参考资料。3. 核心实现自动读取实体包围盒并计算坯料尺寸3.1 拿到当前工作部件和所有实体体NXOpen Python的命名空间里一切操作的起点是Session对象。Session是当前NX进程的总入口通过它可以拿到所有打开的Part、当前工作Part、UI对象、信息窗口等等。这部分代码几乎是所有NXOpen Python脚本的公共前缀import NXOpen def main(): the_session NXOpen.Session.GetSession() the_ui NXOpen.UI.GetUI() work_part the_session.Parts.Work if work_part is None: the_ui.NXMessageBox.Show(提示, NXOpen.NXMessageBox.DialogType.Error, 请先打开一个工作部件) return拿到work_part以后就可以遍历它下面的所有Body对象。在NXOpen对象模型里Body是几何体的容器但Body可能不是实体也可能是片体。为了识别“坯料尺寸”我们应该只统计实体体也就是IsSolidBody为True的那些。solid_bodies [body for body in work_part.Bodies if body.IsSolidBody] if not solid_bodies: the_ui.NXMessageBox.Show(提示, NXOpen.NXMessageBox.DialogType.Error, 当前部件里没有实体体) return这里用列表推导式把筛选和收集一步做完代码看起来清爽多了。3.2 用Body.GetBoundingBox获取包围盒拿到实体体以后接下来就是核心获取它的包围盒。NXOpen Python里面有两种常用的获取方式第一种是用NXOpen对象模型直接调用Body上的GetBoundingBox方法返回一个NXOpen.Box对象。这个Box对象里有X、Y、Z三个方向向量和一个Point点。X、Y、Z向量的长度可以理解为该方向上的包围盒尺寸Point是包围盒的一个角点。第二种是走UF函数比如UF_MODL_ask_bounding_box需要先从NXOpen对象拿到UF对象的tag再调用UF函数。这种方式在老的C项目里很常见Python也可以调用但需要额外处理tag转换代码会稍微啰嗦一点。我建议在新版本NX里直接用GetBoundingBox原因有两个一是代码可读性好二是它返回的就是NXOpen对象后面如果要接其他NXOpen API操作不需要再转换。import math listing_window the_session.ListingWindow listing_window.Open() for idx, body in enumerate(solid_bodies, start1): bbox body.GetBoundingBox() x_len bbox.X.Length() y_len bbox.Y.Length() z_len bbox.Z.Length() listing_window.WriteFullline(实体 %d: X%.4f, Y%.4f, Z%.4f % (idx, x_len, y_len, z_len))有一点要注意包围盒的X、Y、Z方向未必和WCS完全一致它返回的是模型空间里的绝对轴对齐包围盒。如果零件被旋转过X、Y、Z长度是零件在绝对坐标系各方向上的跨度而不是工件长宽高。实际做坯料尺寸时大家通常希望按MCS加工坐标系来取尺寸这个问题在后面的注意事项里详细讲。3.3 单位问题毫米和英寸别搞混NX模型有公制、英制之分包围盒返回的长度数值在NX内部是按当前部件的显示单位还是内部毫米单位计算不同版本有细微差别。我的经验是在信息窗口打印之前先判断一下当前部件的单位然后决定要不要换算。unit_type work_part.Preferences.Units if unit_type NXOpen.Part.Units.Inches: scale_factor 1.0 / 25.4 # 内部毫米转英寸 else: scale_factor 1.0严格来说NX内部几何数据是用毫米保存的但GetBoundingBox返回的单位可能已经按部件单位做了转换所以要结合实测判断。稳妥的做法是在开发机上用同一个测试模型分别设置公制、英制跑一遍打印出来对比一下这样你就知道自己所用NX版本的真实行为。3.4 坐标变换把绝对包围盒换算到MCS方向刚才提到直接取到的包围盒是绝对坐标系的轴对齐盒子。在CAM编程里“坯料长宽高”通常是相对于加工坐标系MCS的定义特别是四轴、五轴编程时工件装夹方向未必和绝对坐标一致。如果你只是做三轴加工零件放平了那绝对包围盒的X、Y、Z和MCS的X、Y、Z基本对得上。但严谨的做法还是把模型变换到MCS坐标下来计算。思路是获取MCS的Matrix用拍摄变换把实体体从模型空间映射到MCS坐标系下再计算变换后体的包围盒。这部分涉及矩阵运算代码会多一些。我提供一个简化方案直接用NXOpen的Matrix3x3和Point3d写一个坐标变换函数把包围盒的八个角点都换算到MCS矩阵下再重新求X、Y、Z最大值最小值。mcs None cam_setup work_part.CAMSetup if cam_setup is not None and cam_setup.MCSs.Count 0: mcs cam_setup.MCSs.Element(0)如果当前部件还没有创建任何CAM设置CAMSetup会是空引用这一步就要加判断让用户先创建一个基本的MILL_ORIENT或者直接用WCS兜底。这也是为什么我说这个工具的第一版最好保守一点优先支持三轴平放零件的场景等骨架跑通后再加MCS矩阵变换。3.5 完整代码示例把上面的内容组合起来一个可以独立运行的版本就是这样import NXOpen def main(): the_session NXOpen.Session.GetSession() the_ui NXOpen.UI.GetUI() work_part the_session.Parts.Work if work_part is None: the_ui.NXMessageBox.Show(提示, NXOpen.NXMessageBox.DialogType.Error, 请先打开一个工作部件) return listing_window the_session.ListingWindow listing_window.Open() listing_window.WriteFullline( 坯料尺寸自动提取 ) solid_bodies [body for body in work_part.Bodies if body.IsSolidBody] if not solid_bodies: the_ui.NXMessageBox.Show(提示, NXOpen.NXMessageBox.DialogType.Error, 当前部件里没有实体体) return for idx, body in enumerate(solid_bodies, start1): bbox body.GetBoundingBox() x_len bbox.X.Length() y_len bbox.Y.Length() z_len bbox.Z.Length() listing_window.WriteFullline(实体 %d: 长(X)%.4f, 宽(Y)%.4f, 高(Z)%.4f % (idx, x_len, y_len, z_len)) listing_window.WriteFullline( 完成 ) if __name__ __main__: main()在NX里用“文件-执行-NX Open Python”选择这个脚本信息窗口就会列出当前部件所有实体体的外形尺寸。这就是坯料尺寸的数据基础。3.6 为什么先输出到信息窗口而不是直接写回CAM有的同学可能会问既然标题是“坯料尺寸”为什么不一步到位把这些尺寸写入CAM的Blank设置原因是这样第一NX CAM的Blank几何体有三种来源自动块、几何体选择、小平面体。自动块模式下系统已经能自动读取部件包围盒并加上偏置我们要做的是控制偏置量和方向而不是重复制造一个包围盒写进去几何体模式下则需要用户选择毛坯体那是另一套选择逻辑。第二信息窗口输出是零风险操作不会改坏模型。对刚接触NXOpen Python的人来说先跑通数据获取再去动CAM设置可以避免一层套一层的调试地狱。第三从工程使用场景看很多人拿到坯料尺寸其实只是为了记录工艺卡片或者做离线核对并不一定都要写回NX界面。先有输出再谈写入思路更清晰。4. 从坯料尺寸往下走通孔和盲孔的拓扑识别4.1 为什么一个“读尺寸”的脚本会关联到通孔盲孔这个话题本来应该放在后面几篇但热搜词里“nx open 如何区分通孔和盲孔 拓扑”被多次提到我在实际开发中也确实会遇到这里先做一个思路预告。当你拿到毛坯尺寸和成品尺寸以后两者相减得到的“去料体积”里孔特征占了很大比例。做钻孔循环、镗孔、攻丝这些工序时CAM系统需要知道这个孔是通孔还是盲孔从而计算刀具伸出长度、安全间隙和底孔余量。这时候如果能让程序自动识别孔的类型整个自动编程流水线就更完整了。4.2 一个朴素的拓扑判定思路区分通孔和盲孔最原始也是最直观的方法是看几何拓扑一个通孔在圆柱面上有两个开放的圆边圆柱面两端都不会被一个封闭平面堵住而盲孔圆柱面一端连着底面底面和圆柱面共享一条封闭圆边。在NXOpen Python里可以遍历实体体的所有面筛出圆柱面CylindricalFace然后检查它和相邻面之间的边关系如果圆柱面的两条边都是自由边或者邻接面不是平面端盖很可能就是通孔如果圆柱面有一条边和一个平面共享并且这个平面刚好垂直于圆柱轴线那大概率是盲孔底面。这个判定方式不够严谨容易受到圆角、倒角、阶梯孔这些因素的影响但作为第一版自动识别逻辑它已经能覆盖掉大部分规则孔。更精确的做法是走到边的层面统计圆柱面边界的拓扑结构或者用像uf_modl_ask_feat_object这类函数从特征对象反查几何体拿到面集合以后再分析邻接矩阵。我在做这个功能的时候建议先不要一上来就搞高深的算法而是先用最朴素的面邻接规则做一个分类然后拿真实零件去跑一遍统计哪些孔判错了再针对错例补规则。这个“朴素规则案例迭代”的开发模式比一开始就试图构建完美算法靠谱得多。这块内容我准备在系列的第二篇专门展开到时候会把圆柱面识别、边拓扑遍历、通孔盲孔分类的完整代码都放出来这里先留个引子。5. 调试实录与常见坑位速查5.1 最容易踩的坑GetBoundingBox的坐标参考我第一次在实际零件上跑这个脚本发现输出的X、Y、Z数值和我在测量工具里看到的不一样找了大半天最后发现问题是模型是用其它三维软件转过来的导入NX以后整个体有一个旋转偏移而GetBoundingBox返回的是绝对坐标包围盒不是我视觉上看到的“工件的长宽高”。这个问题在转格式模型里特别常见。解决办法是先把体的WCS方向或者MCS矩阵拿到做一次坐标变换再求包围盒。如果你只是做快速粗估也可以先手工把WCS重新定向到工件基准边再跑脚本效果一样。5.2 多个实体体的情况有些prt文件里不仅有零件实体还有辅助体、夹具体、基准块。如果脚本不筛选就会把辅助体也算进毛坯尺寸里导致结果偏大。我的处理习惯是先按特征名称或者颜色过滤掉“非加工体”如果项目规范统一也可以约定夹具体放在单独的引用集里脚本只遍历工作引用集内的实体。没有统一规范的情况下最稳妥的方案是脚本弹出可勾选的实体列表让使用者手动确认但我个人不太喜欢这种打断流程的交互更倾向于在模型规范阶段就约定好。5.3 信息窗口中文乱码NXOpen Python的ListingWindow对中文支持在不同版本上表现不一致有时候中文标签会变成乱码。如果你遇到这种情况最简单的绕过方式是脚本里所有输出文本用英文或者拼音数值本身不受影响。如果一定要输出中文可以尝试在脚本开头设置代码文件的编码格式确保保存为UTF-8 with BOM并且在NX环境变量里把系统区域设置调整好。不过说实话对这种内部工具来说英文输出反而更省心反正关键内容是数字。5.4 一个调试技巧用录制功能生成基准脚本我在开头提到过Journal录制这里再强调一个具体用法你先手动对一个实体体执行“测量-边界盒”同时录制Journal录完以后打开生成的Python文件搜索BoundingBox相关的调用你会看到当前NX版本精确的方法名和参数签名。这是所有API困惑的最终解答方式比翻文档快得多。5.5 常见问题速查表现象最可能原因处理办法脚本报错找不到SessionNX版本太老或者代码被当成普通Python运行确认脚本是从NX的“执行NX Open Python”入口运行输出尺寸和实际测量不一致模型有旋转绝对包围盒不等于工件长宽高先定向WCS或做MCS矩阵变换后再计算没有任何实体打印部件里全是片体或小平面体检查IsSolidBody筛选条件确认实体存在中文输出乱码ListingWindow编码兼容问题改用英文输出或调整环境区域设置GetBoundingBox方法不存在NX版本较老Python API不完整升级NX或改用UF_MODL_ask_bounding_box函数6. 后续扩展方向这篇文章作为“坯料尺寸”系列的第一篇代码重点放在“读取实体体包围盒”这个核心动作上。下一步可以做的事情其实很多实现MCS矩阵变换让包围盒尺寸真正对应加工坐标方向加入偏置参数直接把“零件最大尺寸偏置量”输出为自动块的毛坯尺寸研究NX CAM Blank几何体的Python API把尺寸数据直接写回加工导航器写一个批量模式遍历文件夹下所有prt文件生成一张毛坯尺寸清单表格。我个人在实际操作中的体会是这类二次开发小工具代码本身不复杂真正花时间的永远是对NX对象模型的理解和边界情况的处理。哪怕你的第一版只做三轴、只处理单实体、只输出数字也完全够用。先把这条基础链路跑通后续再往复杂场景延伸就只是加法问题。下一篇我会重点讲通孔和盲孔的拓扑识别这中间要用到体面遍历、边分类这些更细的对象关系正好可以接着今天的包围盒基础继续往下挖。
返回列表