UG二次开发实战:NXOpen C++与UFUN环境配置、代码示例及部署指南
发布时间:2026/10/21 9:24:07 锦皓数字建站

简介UG二次开发系统性资料合集面向借助UG_OPEN API或GRIP脚本扩展CAD/CAM功能的机械工程师、二次开发初学者及企业定制人员。覆盖API编程基础、GRIP实用编程、环境配置、插件调试与部署等核心环节并附代码示例、头文件与动态链接库等工程文件。压缩包共620个文件约141MB以h头文件、c/cpp源码、lib库、dll动态库及obj目标为主另有prt模型、bmp位图、dlg对话框及pdf、txt文档覆盖从源码到调试打包的完整链路。已有3858人学习下载。通过此合集可系统掌握UG数据模型与对象层次结构学会运用API操作几何、装配与工程图并借助GRIP实现自动化数据处理和报告生成高级部分涉及多线程编程、动态链接库应用及界面设计等实战技巧可作日常排错与进阶参考。1. UG二次开发资料合集别再让环境变量劝退你的C插件之路如果你准备用C做UG二次开发第一周大概率不是在写业务代码而是在跟环境变量搏斗。这个合集把UG二次开发需要的资料按学习路径打包成套API手册、可编译示例工程、VS工程模板、菜单脚本、部署调试方案。它的直接价值是让你从“看一堆PDF”变成“第一天就能把HelloWorld跑起来”。我拆完这套资料最深的感受是UG二次开发的门槛不在C语法而在NXOpen和UFUN两套API体系怎么选、环境怎么配、dll怎么挂进NX。这份合集恰好把这三件事全按顺序排好了适合NX实施工程师、CAD插件开发者和准备接手老项目维护的人。2. 技术栈选型NXOpen C 与 UFUN 两条路线怎么选2.1 两条API路线的对比UG二次开发的说法很杂新手会被NXOpen、UFUN、C、C这几个词绕晕。实际就两条主线。NXOpen是面向对象的新一代API主语言是C也有C#、Java、Python绑定类层级深调用方式接近现代软件工程。UFUN是早期的纯C函数库用tag_t句柄直接操作内核对象函数名基本是UF_开头。两者都能做插件但代码风格和适用场景差很远。做选型时我的习惯是新写的工具一律走NXOpen C。理由有三个。第一NXOpen的Feature和Builder设计会正确进入部件历史记录撤销和更新行为比UFUN自然得多用户按CtrlZ能整段撤销。第二头文件和文档配套完整Visual Studio里智能提示和跳转都正常。第三后续要加Block UI对话框、生成Journal都很顺。UFUN更适合维护存量老插件或者做一些轻量对象查询——它的C函数确实简单直接。维度NXOpen CUFUN编程风格面向对象Builder模式过程式C函数核心概念Session、Part、Featuretag_t句柄、UF_initialize撤销支持原生支持部分功能需要自己处理适合场景新项目、复杂建模工具老代码维护、快速脚本在合集里的角色主线示例最多辅助保留经典用法实际项目里两条路线经常共存。我见过不少插件入口用NXOpen中间某个对象遍历却直接调UFUN两者混写反而顺手。所以合集把两套都收进来而不是只讲新不讲旧。2.2 合集里有什么整个合集按“入门教程、API手册、示例工程、工程模板、菜单与部署”五个块组织对应的是“看文档、跑示例、套模板、挂菜单”这条完整学习链。入门教程解决“第一步干吗”的问题里面不只是PDF还有环境搭建操作文档和VS工程配置说明按步骤走就能把HelloWorld跑起来。API手册这块是关键。NXOpen C官方手册非常大离线查起来恨不得砸电脑。合集里按常用模块拆了索引比如Part、Body、Features、Block UI Styler几个目录每个目录只放和二次开发强相关的类省去在线查文档的时间。示例工程是核心资产从最简单的“弹提示框”到“参数化建模”“Block UI对话框”“UFUN遍历部件”每个都是完整VS工程不是文档里截一段代码。工程模板解决重复劳动VS每次建项目要配一堆包含目录和库模板把这一步固化。菜单与部署脚本负责最后一步把编译出来的dll挂进NX界面里。2.3 环境准备版本匹配是第一优先级先说最容易翻车的点NX版本和Visual Studio版本必须匹配。NX官方Release Notes里写了某版本NX对应哪个VS版本用错版本编译出来的dll加载时各种莫名失败。我一般先看自己装的NX版本再决定VS版本老NX配新VS往往头文件语法都过不了编译。另一个坑是电脑上装过多个NX版本环境变量指到旧的那套编译链接一路报错。环境变量方面最关键的是UGII_BASE_DIR它指向NX安装根目录。NXOpen的头文件、库文件、startup目录都以它为基准。开发机上建议写入系统环境变量setx UGII_BASE_DIR D:\UG\NX setx PATH %PATH%;%UGII_BASE_DIR%\UGII命令行临时设置也可以但Visual Studio编译时会读取系统环境变量用setx持久化更省心。配置完必须重开VS不然环境变量不生效。这个“配置了但不生效”的问题每个初学者都会碰到一次算UG二次开发的第一道血泪经验。3. 目录结构拆解一份能学完UG二次开发的资料应该怎么组织3.1 顶层目录规划资料合集如果只是堆一堆文件下载下来也等于白拿。这份合集按学习路径组织目录而不是按文件格式堆PDF和源码。我拆的时候整体结构是下面这样UG二次开发资料合集/ ├── 00_入门教程/ │ ├── 环境搭建与版本匹配/ │ ├── VS工程配置指南/ │ └── 第一个插件HelloWorld/ ├── 01_API手册/ │ ├── NXOpen_C_分模块索引/ │ └── UFUN_C_函数速查/ ├── 02_示例工程/ │ ├── 001_HelloWorld/ │ ├── 002_参数化建模/ │ ├── 003_BlockUI对话框/ │ └── 004_UFUN部件遍历/ ├── 03_工程模板/ │ ├── VS工程模板/ │ └── 工程生成脚本/ └── 04_菜单与部署/ ├── MenuScript示例/ └── 部署与调试脚本/00_入门教程是给新人的第一站先在这跑通HelloWorld再往深处走。01_API手册不是塞一个超大的chm文件了事而是按模块拆成十几个索引页每个模块只留核心类和经典函数。02_示例工程每个都自包含源码、工程文件、编译说明、运行截图放同一目录打开就能编译。03_工程模板在需要频繁新建工具时价值最大04_菜单与部署解决“dll编译出来了怎么挂进NX”的最后一公里。3.2 文档和示例怎么对照看单独看示例代码容易知其然不知其所以然。比如002_参数化建模做的事是创建一个圆柱并修改参数。配套的API手册索引页里把涉及的几个类按调用顺序列了出来FeatureCollection、CylinderBuilder、Expression。我建议的顺序是先打开示例工程看main函数整体流程再翻索引页对应类名最后在关键位置打断点看对象变化。对比着看比从头啃手册快得多。示例里每个关键步骤都留下日志运行时往NX的Listing Window里打印“当前部件句柄”“圆柱直径50”这类信息方便确认代码执行到哪一步。后续二次开发时这些日志是你定位问题的重要线索。不要直接删掉日志改成多写而不是少写。3.3 工程模板解决什么自己新建一个NXOpen C项目至少要配四样东西包含目录、库目录、附加依赖项、导出入口的宏定义。手配一次十分钟起步还容易漏。工程模板把这些固化了新建项目时选模板直接生成可编译骨架。我通常还会把“编译后自动拷贝dll到startup”写进批处理脚本set UGII_USER_DIRD:\MyNXPlugins xcopy /Y release\mytool.dll %UGII_USER_DIR%\startup\UGII_USER_DIR是用户自定义目录NX启动时会额外加载这个目录下startup中的dll和菜单文件。用这种方式部署的好处是完全不碰NX安装目录系统重装、NX升级都不会把插件冲掉。这是个救命技巧早期我把dll直接拷贝到NX安装目录NX一升级全部插件失效还得一个个重新拷。4. 核心代码走读一个NXOpen C插件从入口到完成建模4.1 程序入口ufusr与SessionNXOpen C插件编译出来是一个Win32 DLLNX通过LoadLibrary加载它然后调用固定入口函数ufusr。这个入口签名不能改而且必须用extern C导出否则C的名字重整会让NX找不到函数。最简入口长这样#include NXOpen/Session.hxx #include NXOpen/Part.hxx #include NXOpen/UI.hxx #include NXOpen/NXMessageBox.hxx #define DllExport __declspec(dllexport) extern C DllExport void ufusr(char* param, int* returnCode, int rlen) { NXOpen::Session* session NXOpen::Session::GetSession(); NXOpen::Part* workPart session-Parts()-Work(); if (workPart NULL) { NXOpen::UI::GetUI()-NXMessageBox()-Show(提示, NXOpen::NXMessageBox::DialogType::Error, 当前没有打开的部件); *returnCode 1; return; } session-SetUndoMark(NXOpen::Session::MarkVisibility::Visible, MyTool); // 在这里写业务逻辑 *returnCode 0; }参数param是NX传入的命令行参数rlen是长度一般用不到。returnCode用来向NX报告执行结果非0表示失败。Session是NXOpen的总入口单例模式拿到它就能访问Parts、Features、Post等所有集合。Parts()-Work()取得当前工作部件如果NX里没打开任何模型这里返回NULL必须先判断否则下一步崩溃。SetUndoMark这行容易被忽略但很关键它给后续操作打了一个撤销标记用户按CtrlZ可以从整个插件操作回到操作前状态。不做这一步建模类插件干了坏事用户没法撤销基本会被当场打回。4.2 完成一次建模CylinderBuilder的使用NXOpen里创建一个圆柱不是new一个对象完事而是走Builder模式。Builder负责收集参数、提交给内核生成Feature整个过程会正确写入部件历史。下面是创建一个直径50、高度100的圆柱#include NXOpen/Features_CylinderBuilder.hxx #include NXOpen/Features_FeatureCollection.hxx NXOpen::Features::CylinderBuilder* builder workPart-Features()-CreateCylinderBuilder(NULL); builder-Type()-SetValue(NXOpen::Features::CylinderBuilder::Types::ArcAndHeight); builder-Diameter()-SetRightHandSide(50); builder-Height()-SetRightHandSide(100); builder-Origin()-SetValue(NXOpen::Point3d(0.0, 0.0, 0.0)); builder-Direction()-SetValue(NXOpen::Vector3d(0.0, 0.0, 1.0)); NXOpen::Features::Feature* feature builder-CommitFeature(); builder-Destroy();这里有两个容易错的地方。第一所有特征创建都从CreateCylinderBuilder(NULL)开始括号里的NULL表示“无初始特征”如果想基于已有圆柱修改这里传那个圆柱的Feature。第二Diameter和Height接受的是表达式字符串不是double。SetRightHandSide(50)和SetValue(50.0)效果类似但前者保留表达式特性以后可以用公式驱动尺寸。如果后续要通过程序改尺寸也是拿到对应Builder后调SetRightHandSide(50*2)这种方式。CommitFeature提交生成Feature之后builder必须Destroy释放否则每次运行都会泄漏一个Builder对象。我见过用这套接口的程序跑一晚上后NX内存暴涨基本全是没调Destroy。4.3 混用UFUN经典C风格的回调UFUN代码量在存量项目里依然不少。它的特点是函数式、句柄式UF_initialize初始化环境tag_t是UG内核对象的句柄所有操作围绕句柄展开。一段典型的UFUN获取当前显示部件代码#include uf.h #include uf_part.h #include uf_ui.h void ufusr(char *param, int *returnCode, int rlen) { int err UF_initialize(); if (err ! 0) { *returnCode err; return; } tag_t partTag UF_PART_ask_display_part(); if (partTag ! NULL_TAG) { char msg[256]; sprintf(msg, 当前显示部件句柄: %u, partTag); UF_UI_open_listing_window(); UF_UI_write_listing_window(msg); } UF_terminate(); }UF_initialize和UF_terminate必须成对出现前者初始化UF环境后者释放。很多代码只在开头initialize中途某个分支return跑掉漏了terminate下次调用就会出现“UF环境初始化失败”的玄学问题。所以入口里要保证单入口单出口或者用goto统一收尾。UFUN和NXOpen混用完全允许。NXOpen代码里要用UF函数先调一次UF_initialize即可。这样能享受NXOpen的撤销和自动更新在UFUN更省事的地方比如枚举对象、读取属性直接插一段C代码扬长避短。合集里004示例就是典型混用值得单独跑一遍。5. 编译运行与避坑环境配置、挂载调试、现场排查5.1 工程配置VS要设置哪些路径NXOpen C工程的核心配置就三块头文件路径、库路径、依赖的lib列表。头文件在NX安装目录的UGII\NXOpen和UGII\NXOpenCPP下库在UGII\NXOpen下经典依赖是libnxopenuicpp.lib和libugopenint.lib。前者是NXOpen C界面与核心库后者是UFUN兼容层。不想用Visual Studio图形界面时命令行编译反而最直观也能看清楚到底引了哪些东西set UGII_BASE_DIRD:\UG\NX cl /c /EHsc /std:c17 mytool.cpp ^ /I%UGII_BASE_DIR%\UGII\NXOpen ^ /I%UGII_BASE_DIR%\UGII\NXOpenCPP link /DLL mytool.obj ^ /LIBPATH:%UGII_BASE_DIR%\UGII\NXOpen ^ libnxopenuicpp.lib libugopenint.lib/EHsc是C异常开关NXOpen头文件大量依赖异常不开会在编译头文件时刷一堆警告甚至报错。/std:c17是C标准比较新的NX版本头文件要求C14以上老VS可能不支持这个参数所以VS版本选择还是要回到NX版本的Release Notes。Debug和Release建议直接用ReleaseDebug版本依赖调试运行时目标机器上没装开发环境会加载失败。5.2 把dll挂进NX部署与调试部署有两种方式。第一种是拷贝到NX安装目录的UGII\startup简单粗暴NX启动自动加载。缺点是污染安装目录NX升级时文件容易丢。第二种是设置UGII_USER_DIR指向自己的目录把dll放进该目录的startup子目录NX同样会加载。推荐第二种完整脚本大概是set UGII_USER_DIRD:\MyNXPlugins mkdir %UGII_USER_DIR%\startup %UGII_USER_DIR%\menus xcopy /Y release\mytool.dll %UGII_USER_DIR%\startup\ xcopy /Y menu\*.men %UGII_USER_DIR%\menus\菜单文件用的是MenuScript格式类似下面这样放menus目录下NX启动会按名称挂到主菜单VERSION 120 EDIT UG_GATEWAY_MAIN_MENUBAR BUTTON UG_MyTool LABEL 我的第一个工具 BITMAP mytool.bmp ACTIONS mytool.dllACTIONS后面跟的dll名要和编译输出一致。调试时用VS打开插件工程把“调试-启动”设置为“本地Windows调试器”命令指向NX可执行文件F5启动NX再手动触发插件就能在VS里断点。也可以先启动NX再在VS里“调试-附加到进程”效果一样但不用反复重启NX。注意确认编译的是x64——NX已经是64位应用任何32位配置都会在加载时报模块映像无效。5.3 常见问题排查现象、原因与解决第一条编译时就找不到NXOpen头文件。现象是#include NXOpen/Session.hxx直接报无法打开。原因基本是UGII_BASE_DIR没生效或者设置之后没重开VS。解决命令行echo %UGII_BASE_DIR%确认路径设置好之后关闭所有VS窗口再重新打开不要只关工程文件。第二条编译链接时大量LNK2019未解析外部符号。现象是链接阶段刷屏大多是libnxopenuicpp相关符号找不到。原因一般是依赖库没写全或者链接了另一套NX版本的lib。解决确认附加依赖项包含libnxopenuicpp.lib和libugopenint.lib并且LIBPATH指向当前NX版本的库目录。重点检查是不是机器上装了多个NX环境变量指到了旧的那套。第三条dll拷进startup后NX启动报错或者点菜单没反应。现象是启动时弹错误框或菜单按钮点了没动静。原因通常是入口没正确导出。解决检查ufusr签名、extern C和__declspec(dllexport)是否齐全用dumpbin /exports看dll导出表里有没有ufusr符号没有就回头看宏定义。第四条运行时一调用就崩溃断点定位在UF_initialize附近。现象是插件一触发NX直接崩溃退出。原因一般是UF环境初始化次数不配对或者在没有工作部件的状态下调用了部件相关函数。解决入口先判断workPart是否为NULL所有UF_initialize必须有对应UF_terminate建议把逻辑包进一个函数统一在函数末尾收尾不要中途到处return。6. 二次开发改造把这套资料变成自己的NX插件工具箱6.1 从示例到工具的三步法把示例工程改成自己的工具我习惯走三步先跑通原样再改业务最后包界面。跑通原样是为了确认本机环境和合集里的说明一致这一步能排除八成环境问题。改业务是把示例里创建圆柱的代码替换成自己的逻辑比如换成读取模型属性、批量导出参数。包界面则是用Block UI Styler拖一个对话框把参数暴露给用户避免每次改代码重新编译。以合集里003_BlockUI对话框做底子通常半天能出一个带界面的小工具。6.2 一个具体改造批量导出表达式假设需求是把当前部件所有表达式导出到文本。改造点很清晰删掉CylinderBuilder那部分换成遍历表达式。核心代码std::vectorNXOpen::Expression* exprs workPart-Expressions(); std::ofstream out(expressions.txt); for (NXOpen::Expression* e : exprs) { out e-Name() e-Formula() std::endl; }workPart-Expressions()返回当前部件全部表达式包括尺寸、公式、用户定义变量。Formula拿到的是右侧表达式字符串比如“50*2”。这样一个参数化模型的所有变量就能一键备份比手动记录快得多还能用来做版本对比——模型被别人改过参数导出两份文本一diff就清楚了。从那以后我每次在NX里做批量操作都强制自己先翻一遍合集里的示例看有没有现成模式可套而不是从零写。希望帮到你。本文还有配套的精品资源点击获取
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。