![Siemens NX二次开发](https://wfqqreader-1252317822.image.myqcloud.com/cover/979/41202979/b_41202979.jpg)
5.5 NXOpen C
NXOpen C开放了超过5000个API,面对如此多的API,如何快速找到自己期望的API?这需要开发者掌握两方面的知识,一是了解关于NXOpen C API名称的一些命名约定,二是掌握API帮助文档的搜索功能。
5.5.1 NXOpen C命名约定
NXOpen C API有两种命名约定,即标准命名约定与遗留命名约定。
(1)标准命名约定(Standard Naming Convention):根据API所在的模块与实现的功能赋予有意义的名称。这一类API格式是UF_<area>_<name>,UF是User Function的简写。<area>通常是对应用模块或功能领域的说明,例如:UF_MODL_create_sphere中的MODL就表示Modeling模块。<name>通常是对实现的具体功能的描述,一般由动词或名词组成,常见的词语有ask(查询)、get(获取)、create(创建)、new(新建)、edit(编辑)、delete(删除)、set(设置)、init(初始化)、remove(移除)等。
(2)遗留命名约定(Legacy Naming Convention):这一类API的名称格式是uc<××××>或者uf<××××>,<××××>通常是4位数字或者3位数字加一字母(NX早期采用FORTRAN语言开发,FORTRAN77中变量名长度限制为6)。这一类型的API大部分已经被其他标准命名约定的API替代,但还有一部分被开发者青睐,如uc1601、uf5947,它们的名字没有规律可循,需要开发者积累经验。
相关知识的介绍,开发者也可以参考官方帮助文档Open C Programmer's Guide中与“Command Line Arguments”相关的描述。
当开发者了解NXOpen C命名约定后,就可以从API帮助文档中去寻找期望的API。例如:期望利用NXOpen C中的API创建一个Sketch(草图),根据模块分类这个API应该是以UF_SKET开头的,很容易找到它“UF_SKET_create_sketch”。
也可以在API帮助文档中搜索关键词,如图5-6所示。如果您不太确定关键词是什么,可以考虑将NX切换为英文版,在其中找到相应功能所对应的英文单词,再利用这些单词在API帮助文档中搜索。
![](https://epubservercos.yuewen.com/A6F99C/21440188008281206/epubprivate/OEBPS/Images/32757_57_1.jpg?sign=1738870212-6LghneJhdeucf2MO30fAjc5RilepMYdo-0-3556b8629bfc8f327e701da68052edc8)
图5-6 NXOpen C API帮助文档界面
5.5.2 NXOpen C API分类
开发者在使用NXOpen C API时,应该添加对应的头文件,头文件与API分类一一对应。例如:新建一个部件使用的API是UF_PART_new,那就应该添加“uf_part.h”这个头文件,NXOpen C API分类如表5-4所示。
表5-4 NXOpen C API分类
![](https://epubservercos.yuewen.com/A6F99C/21440188008281206/epubprivate/OEBPS/Images/32757_57_2.jpg?sign=1738870212-sI1GvoNQ4aQYeVpYVH6jFm5mzVJKujXB-0-48035adf928a2612e7b07c153ade1265)
续表
![](https://epubservercos.yuewen.com/A6F99C/21440188008281206/epubprivate/OEBPS/Images/32757_58_1.jpg?sign=1738870212-B1Vb92bYwuwglnvjDRdAkqLv7y8qB1KF-0-8d22c7bdaa6b93f4f8807fc57c163290)
续表
![](https://epubservercos.yuewen.com/A6F99C/21440188008281206/epubprivate/OEBPS/Images/32757_59_1.jpg?sign=1738870212-Qcw7ZTbAVymcghCn4IXVWoMCe6x51tqH-0-b14b00548d439b87c633918b01afdbb4)
续表
![](https://epubservercos.yuewen.com/A6F99C/21440188008281206/epubprivate/OEBPS/Images/32757_60_1.jpg?sign=1738870212-X5CkeCTIg8u30QHI2xNn26lBplAitbTt-0-ed742b48ff7c686493cc3997faf0d37e)
5.5.3 NXOpen C对象
NX中包含了很多对象,例如:Feature(特征)、Point(点)、Body(体)、Face(面)、Edge(边)等。到目前为止,常见的对象被定义在“%UGII_BASE_DIR%\UGOPEN\uf_object_types.h”文件中。
对象拥有Type(类型)与Subtype(子类型)两部分定义,Subtype可更详细地描述对象(可以利用UF_OBJ_ask_type_and_subtype来获取对象的Type与Subtype)。对于NX中已经存在的对象,如果期望找到它们,一般使用以下这些API:
![](https://epubservercos.yuewen.com/A6F99C/21440188008281206/epubprivate/OEBPS/Images/32757_60_2.jpg?sign=1738870212-mjRBZ2PhXX7ZoPkkRNsiKL0U05s5sCSY-0-17fb39f69bd4ee4336f66faa32c218ad)
如开发者期望遍历得到当前工作部件中所有的Body,可以参考以下代码格式:
![](https://epubservercos.yuewen.com/A6F99C/21440188008281206/epubprivate/OEBPS/Images/32757_60_3.jpg?sign=1738870212-CEnHA0SOF9HmdwqMv7mzVsBUm7UcPkv8-0-77306c7fd04622da597ec184372270a2)
NX对象存在四种状态,可以利用UF_OBJ_ask_status获取对象的状态。这四种状态分别是:
● UF_OBJ_ALIVE:表明该对象是活动的。
● UF_OBJ_DELETED:表明对象已删除。
● UF_OBJ_TEMPORARY:表明对象是临时的,不保存在部件中。例如:利用UF_CSYS_create_temp_csys创建的CSYS。
● UF_OBJ_CONDEMNED:这种状态的对象通常在NX中不显示,例如:矩阵对象、智能对象。
在开发应用程序时,为了保证代码更加健壮,一般情况下会先获取对象的状态,如果对象的状态为是“UF_OBJ_ALIVE”再执行相关操作。
5.5.4 NXOpen C数据类型
除C/C++标准的数据类型外,NXOpen C还大量使用结构体、联合结构体、枚举、指针等数据类型,常见的数据类型约定如表5-5所示。
表5-5 NXOpen C数据类型约定
![](https://epubservercos.yuewen.com/A6F99C/21440188008281206/epubprivate/OEBPS/Images/32757_61_1.jpg?sign=1738870212-Vj7695OgPdYiE0SWJ7HurzV6kdZRdqyr-0-ce2887f4d2ef1c6eb2e2f05f8d8d91ef)
除了后缀满足上表约定,数据类型的命名约定还与API命名约定一致,下面的结构体展示了这一点,它来自与建模相关的头文件(uf_modl_types.h)。
![](https://epubservercos.yuewen.com/A6F99C/21440188008281206/epubprivate/OEBPS/Images/32757_61_2.jpg?sign=1738870212-LL4CkFfFvvSbO6zDCsMkBDcbTQxjRcst-0-ecc918e7e81a1362c02120e7ecd97e60)
在NXOpen C中,使用最多的数据类型是tag_t,在文件“%UGII_BASE_DIR%\UGOPEN\uf_defs.h”中的定义如下:
![](https://epubservercos.yuewen.com/A6F99C/21440188008281206/epubprivate/OEBPS/Images/32757_61_3.jpg?sign=1738870212-fXvHayJ0tHfqC5xkmq6k2CaMCZE9D0Ts-0-524b64049da9b05715039f3abb6a4b1f)
这种数据类型,早期被称为“Eid”(实体标识符,Entity Identifier),如今统一称为“对象标识符”(Object Identifier)。
在NX系统中,每一个对象,都有唯一的标识符。可以理解为每一个对象都是由大于0的不重复整数来标识它,对象标识符是由NX系统根据一定的算法规则临时生成的,它不会随着部件的保存而保存。例如:开发者期望当前工作部件中指定的Face(面),在下次打开部件时,自动高亮显示它。而一般情况下,同一部件在不同的计算机上打开,或者被再次打开后,对象标识符的值是不相同的。此时,开发者可以考虑利用“handle”(句柄)来解决这个问题。Handle会随着部件的保存而保存,相关API如下:
![](https://epubservercos.yuewen.com/A6F99C/21440188008281206/epubprivate/OEBPS/Images/32757_62_1.jpg?sign=1738870212-6L3Tit8KNLGvxU4bVXtQjDD0aKzkuROW-0-36894ca3bed068b4980c7206acc5549b)
5.5.5 NXOpen C API声明
NXOpen C提供的API符合ANSI/ISO C标准,在相应的头文件中定义的原型格式为:
![](https://epubservercos.yuewen.com/A6F99C/21440188008281206/epubprivate/OEBPS/Images/32757_62_2.jpg?sign=1738870212-kwnm1yn3OC3g0X8U9hYqdx7WXzIcM321-0-4a3167f23c1fa88e4c6e29ad4e7596db)
● <return data type>:大部分的NXOpen C API返回都是一个整数(int),为0时,表明该API执行正常;非0时,表明API执行有异常。如果开发者期望获取非0整数所代表的意义,需要使用UF_get_fail_message这个API。需要注意的是,有部分API返回非0整数时,不表示执行有异常,例如:UF_PART_ask_num_parts这个API返回的是当前NX会话中加载部件的数量。
● <function name>:遵循前述的“NXOpen C命名约定”。
● (argument list):参考API帮助文档或者相应头文件说明。
在利用NXOpen C开发应用程序时,开发者需要仔细阅读理解API帮助文档。在API帮助文档中,API的描述一般由以下部分组成:
● Defined in:描述API被定义在哪个头文件中。
● Overview:描述API实现的功能等。
● Environment:描述API允许的运行模式。如果描述中不包含关键词“External”,说明这个API不允许以批处理模式(Batch,又称外部模式External)运行。例如:uc1601这个API不允许以批处理模式运行。
● See Also:描述与该API相关联或者类似的API。若描述中含有“Refer to example”关键字段,表明这个API有样例,点击它即可查看。
● History:描述API发布的NX版本。
● Required License(s):使用该API需要的License。
● API详细声明:一般格式如表5-6所示(以UF_MODL_create_plane为例)。
表5-6 API详细声明
![](https://epubservercos.yuewen.com/A6F99C/21440188008281206/epubprivate/OEBPS/Images/32757_62_3.jpg?sign=1738870212-ca0tvrf8vqxMsyEmM4qR1grxIDOXPAys-0-e670181956f8ba07fe4769c895dc120f)
在理解这些声明时,开发者可以根据NX工具本身的输入参数进行判断,如上表中关于创建Plane的声明。创建Plane需要一个点和一个法向量,所以在输入参数中,会要求指定Plane的原点及法向量,如果成功创建就输出创建Plane的标识符。
5.5.6 UF_CALL函数
在官方样例中(如“%UGII_BASE_DIR%\UGOPEN\ufd_curve_create_arc.c”),经常会看到在NXOpen C API的前面加上“UF_CALL”函数,如下所示,为什么要这样做呢?
![](https://epubservercos.yuewen.com/A6F99C/21440188008281206/epubprivate/OEBPS/Images/32757_63_1.jpg?sign=1738870212-TxfrEc6HUTvrXkE4L816JABgmrEuu5Pu-0-c7d4833e612caa162e04486401413697)
在研究此问题之前,先设想一种场景,当应用程序代码上万行时,出现了BUG,如何快速找到问题?如前所述,大部分的NXOpen C API返回一个整数,如果非0表示有异常。有没有一种手段能在应用程序遇到异常时,自动告诉我们是哪行代码因为何种原因引起的呢?
官方样例中的UF_CALL为解决这一问题提供了可行性。UF_CALL是一个自定义的宏,开发者可以参考官方思路进行修改,以下通过实例进行说明。
(1)启动Visual Studio,利用NXOpen C++Wizard创建一个名为ch5_3的项目(本例代码保存在“D:\nxopen_demo\code\ch5_3”),删除原有内容再添加下列代码:
![](https://epubservercos.yuewen.com/A6F99C/21440188008281206/epubprivate/OEBPS/Images/32757_63_2.jpg?sign=1738870212-uToLneKqBy1eVFyd0t6z5Xyoflmj1Glu-0-9ff939c105d1b6ee7fbf99dc0f64fd01)
![](https://epubservercos.yuewen.com/A6F99C/21440188008281206/epubprivate/OEBPS/Images/32757_64_1.jpg?sign=1738870212-l6tfro4uk6TNE7scrYqSygROgmRstntz-0-178df7b0e9605b0ed8f6b12a06560552)
(2)编译链接生成*.dll文件。
(3)在NX中打开或新建一部件文件,单击“File”→“Execute”→“NX Open”按钮,在弹出的对话框中选择动态链接库“ch5_3.dll”,运行结果如图5-7所示。
![](https://epubservercos.yuewen.com/A6F99C/21440188008281206/epubprivate/OEBPS/Images/32757_64_2.jpg?sign=1738870212-eNNILGOHACkgQeP5NLn2xmOs7JSziQTu-0-7f27bdcedc782cd2033c5d2e4d11fc64)
图5-7 使用UF_CALL显示异常结果
从图中可以看出,当使用NXOpen C API时,添加UF_CALL遇到异常后会以Information窗口形式显示详细信息。
通过这种方式,可以快速定位异常代码,提高开发效率。这个样例仅展示了UF_CALL的一种用法,开发者可以根据实际需求进行调整,例如:将异常信息打印在日志文件中代替打印在Information窗口。
5.5.7 动态内存
使用动态内存是开发应用程序时常见的做法。动态分配内存与释放内存的API如下:
![](https://epubservercos.yuewen.com/A6F99C/21440188008281206/epubprivate/OEBPS/Images/32757_65_1.jpg?sign=1738870212-lJG4NtXvqzEs7abUI0rtrVmhX12Mg16C-0-53304f8a081156ad3b626b55c6521662)
除以上这几个常用API外,还有一部分特定释放内存的API,如UF_CURVE_free_trim,开发者需要仔细查阅API帮助文档。
常见分配内存的代码格式如下:
![](https://epubservercos.yuewen.com/A6F99C/21440188008281206/epubprivate/OEBPS/Images/32757_65_2.jpg?sign=1738870212-5ex8Z6Nnmgdd7iPyVSjpwZC1zEUrQxee-0-48727fbad863481643b1f52fe94d3105)
5.5.8 NXOpen C对象转换
开发者在操作NX中的对象时,必须理解对象之间的区别与联系。例如:利用NXOpen C中的UF_MODL_create_block创建了一个Block,输出的是Block Feature的标识符,此时如果要对所有的Edge(边)进行Edge Blend操作,那传入的对象是每一条Edge的标识符,而不是Feature的标识符。这就涉及对象之间的相互转换,常见的对象转换API如下:
![](https://epubservercos.yuewen.com/A6F99C/21440188008281206/epubprivate/OEBPS/Images/32757_66_1.jpg?sign=1738870212-9L4ng13pVToimwSzYdN1cIUsR4prXZcX-0-6d2e6f1d264d3c3e79ebbfdfbe21824d)
以下通过一个实例来说明对象转换的必要性,假定需求是:创建一个圆台,原点坐标为(15,20,30),旋转中心轴方向平行于绝对坐标系的Z方向;底面直径为50,顶面直径为25,高度为40,此时这个圆台拥有两个平面、一个锥面和两条边,需要找出直径最大的一边条再创建边倒圆特征,倒角半径值为5,如图5-8所示。
![](https://epubservercos.yuewen.com/A6F99C/21440188008281206/epubprivate/OEBPS/Images/32757_66_2.jpg?sign=1738870212-gtlmsNLSCuz9waQlwdpVylovZSi0HLm8-0-c085d58304ed2bb9dd571f1f86b00944)
图5-8 创建结果
这个实例将展示:NXOpen C对象之间的转换;NXOpen C中链表的使用方法;如何通过一定的算法,找出期望的对象;如何合理地释放内存。
以下为实现本功能的核心代码(本例完整代码保存在“D:\nxopen_demo\code\ch5_4”)。
![](https://epubservercos.yuewen.com/A6F99C/21440188008281206/epubprivate/OEBPS/Images/32757_66_3.jpg?sign=1738870212-6pKmPTfGijyopxgo83SQHOR4cKK8t2V4-0-9b9bb7d9847f73e0e63499a547fc8968)
![](https://epubservercos.yuewen.com/A6F99C/21440188008281206/epubprivate/OEBPS/Images/32757_67_1.jpg?sign=1738870212-UOXWj5lBV5idtslf5Z5rmaNmrxOQeRuk-0-e66634f1bd784fae7fabadcc0e8acf2d)
![](https://epubservercos.yuewen.com/A6F99C/21440188008281206/epubprivate/OEBPS/Images/32757_68_1.jpg?sign=1738870212-UxFoTwh9ZCpwFz56jfIT6kVMssDhp68Q-0-829ec99619e0ef775a4b61993f731037)