UG(Unigraphics)是面向制造业的高端/CAD/CAE/CAM系统,在国内相关行业已得到了日益广泛的应用。UG 的NX系列不仅提供了强大的概念设计、工程设计、高级图形渲染、工程分析、动态仿真以及制造等强大功能,而且还提供了UG/Open GRIP、UG/Open API和UIStyler等一组开发环境和界面设计工具。利用这组工具用户可以针对具体情况开发专用的产品数字化设计、产品数据管理以及数据处理等扩展模块,使UG系统更好地为本企业服务。
UG/Open GRIP开发工具采用GRIP语言创建在UG环境下运行的应用程序,可以完成与UG的各种交互操作,一般用于规模较小的程序模块[1]。UG/Open API提供了对UG的各种数据库对象进行访问、操作和控制的用户函数(User Function),允许C或C++程序调用。UG/Open API不仅涵盖了UG/Open GRIP的全部功能,而且功能更强,比较适用于大型程序模块的开发。
1. OPEN C应用程序开发环境及一般生成方法
利用UG/Open API工具生成的C应用程序,在UG中称为OPEN C应用程序。创建OPEN C应用程序需要UG提供的API库文件和头文件,两类文件均位于系统的UGOPEN文件夹。对于Unix 系统,采用UFMENU进行编译和链接,而在Windows NT/2000/XP环境下,则可用VC++ 6.0作为编译和链接器。
文献[2]给出了在Windows NT/2000/XP环境下采用VC++生成OPEN C应用程序的基本方法和步骤,用这种方法创建的应用程序分为外部(external)和内部(internal)两种类型。前者按 “Win32 Console Application”类型创建,生成扩展名为EXE的可执行程序,可以独立运行;后者按"Win32 Dynamic-Link Library"类型创建,生成扩展名为DLL的动态链接库,作为系统的一个扩展模块在UG环境下运行。两种类型应用程序生成可以在VC的集成开发环境下完成,也可以在命令行(Command Line)方式下完成。
按照文献[2]给出的方法,无论采用何种方式均不能使用MFC(Microsoft Foundation Class)。一般情况下,利用 UG提供的UIStyler界面技术也可以不用MFC的支持完成OPEN C应用程序的开发,但是UIStyler的界面设计功能毕竟有限,无法与MFC的强大功能相比。因此,研究使用MFC的OPEN C应用程序开发技术是非常必要的。
2. 使用MFC的OPEN C应用程序设计技术
MFC是VC++程序的一个重要的软件资源,为开发Windows应用程序提供了强大的支持,使用MFC可以充分利用VC++开发环境提供的先进技术和工具,实现程序界面的可视化设计。与UIStyler界面设计技术相比,使用MFC的对话框界面在布局上更为容易,修改和调试也更为方便。文献[3]介绍了使用MFC的OPEN C应用程序开发方法和实例,但需要添加较多的程序代码,实现过程比较复杂。经过分析和研究我们确定了一种既简单又实用的设计方法,并在UG NX2.0环境运行通过。具体设计技术与步骤如下:
(1)创建OPEN C应用程序的项目文件框架
在Visual C++6.0集成开发环境下创建类型为“MFC AppWizard(dll)”的项目文件,并采用默认的“Regular DLL using shared MFC DLL”形式。VC应用程序设计向导将在项目文件中自动加入ReadMe.txt、StdAfx.cpp和以项目文件名为前缀的cpp源文件、def模块定义文件以及rc资源文件等。
(2)接口程序设计
接口程序段在与项目文件同名的cpp程序中设计。按照UG/Open API的约定,对于内部调用的应用程序其接口程序是名为ufsta的自定义函数,典型形式如下:
extern void ufsta (char *param, int *retcode, int rlen){
int error_code;
if ( (UF_initialize()) != 0) return;
UF_MB_add_actions (actions ) ;
UF_terminate();
return;
}
UG加载OPEN C应用程序时,将自动调用ufsta()函数,设置由UF_MB_add_actions()函数中的参数“actions”设定的动作。参数actions的类型为UF_MB_action_t字符串数组,其中定义了动作名和执行该动作调用的函数,其一般形式为:
static UF_MB_action_t actions[] ={{ "<动作名>", <用户函数名>, NULL },{ NULL, NULL, NULL }};
式中<用户函数名>项表示执行该动作调用的函数名称,需要在程序中定义。要求的原型为: static UF_MB_cb_status_t <函数名> (UF_MB_widget_t,UF_MB_data_t ,UF_MB_activated_button_p_t );
(3)OPEN C应用程序创建方法
在VC集成环境,按照接口程序的要求添加ufsta()函数,在参数“actions”中设置动作名和动作函数名,并定义动作函数、创建对话框等相关资源和实现程序。完成后设置API库文件和头文件的路径以及编译和链接选项,即可生成OPEN C应用程序。
对于类型为DLL的应用程序,编译选项“Code Generation”(代码生成类型)可设为“Multithreaded DLL”(多进程动态链接库),“Optimizations;”(代码优化)应设为“default”;链接所需的库文件为:libufun.lib和 libugopenint.lib。
通常情况下,OPEN C应用程序通过菜单命令调用,因此需要在菜单文件中定义相应的条目。UG用MenuScript(菜单脚本)文件的形式来定义菜单,定义执行动作条目的形式为:ACTIONS <动作名>。其〈动作名〉与UF_MB_add_actions()函数的参数“actions”中设置的动作名相同。
(4)OPEN C应用程序执行过程
OPEN C应用程序(DLL文件)和菜单文件(扩展名MEN)应保存在由系统环境变量“UGII_USER_DIR”所指定路径下的startup文件夹。启动UG时,系统将自动搜索startup文件夹中扩展名为DLL和MEM和文件,并自动加载。加载DLL时将一次性调用名为ufsta()的函数,同时注册在菜单文件中用ACTIONS项定义的动作名。当用户选择菜单命令时调用OPEN C应用程序中定义的用户函数。
3. 界面设计与相关技术
使用MFC设计在UG环境下运行的OPEN C应用程序人机交互界面主要有模式、无模式和属性页三种对话框形式。
(1)对话框创建的一般要求
创建对话框的基本要求与常规的VC++程序基本相同:第一,在应用程序向导AppWizard创建程序基本框架的基础上,添加对话框资源;第二,使用Developer Studio的对话框编辑器对界面进行布局设计,第三,使用ClassWizard(类向导)创建对话框类,自动生成CDialog派生类定义的头文件和相应的实现文件;最后在接口程序段的用户函数中创建该对话框类的一个实例,并调用其成员函数创建和显示对话框。
需要注意的是:由于OPEN C程序的对话框不是直接在Windows环境运行而是在UG环境运行,因此在使用对话框资源时,应明确指定所使用的是DLL资源。具体作法是在创建和显示对话框之前必须用AFX_MANAGE_STATE(AfxGetStaticModuleState())语句指明MFC对话框使用DLL本身的资源。AFX_MANAGE_STATE宏的作用是正确切换MFC模块的状态,在堆栈中创建一临时对象,使Windows在UG OPEN应用程序(DLL文件)中而不是在EXE中查找资源。退出对话框时,堆栈中的临时对象会自动删除。如果在不调用AFX_MANAGE_STATE宏,对话框将不会显示。
(2)模式对话框
模式对话框是Windows对话框界面的一种标准形式,在激活状态下不允许用户再选择和激活其他窗口。只有在关闭模式对话框之后,用户才能对其他窗口够进行操作。模式对话框用对话框类的DoModal()成员创建和显示。
(3)无模式对话框
无模式对话框在激活状态下可以在不关闭该对话框的条件下激活另外的窗口。此时的无模式对话框只是处于非活动状态,若用鼠标选中则可以重新激活。与模式对话框相比,无模式对话框使用更为灵活,在操作顺序上没有太多的限制。设使用类向导创建对话框类名为CUIMain,对话框资源的ID号为IDD_UIMain,则用下面的一段代码可创建和显示对话框:
AFX_MANAGE_STATE(AfxGetStaticModuleState());
CUIMain * pdlg=new CUIMain;
pdlg->Create(IDD_UIMain,NULL);
pdlg->ShowWindow(SW_SHOW);
(4)属性页对话框
属性页对话框也称选项卡对话框,一般由多属性页构成。属性对话框可按界面的信息类型分页显示,因此,在同样大小的窗口中可容纳更多的信息,使用也十分方便。属性对话框也可以分成模式和无模式两种形式,具体创建方法在文献[4]中有详细说明。
(5)界面设计的相关技术
使用MFC的对话框界面可以采用VC++6.0控件工具箱中的全部控件(图1),但目前的UG NX2.0版本还不支持ActiveX控件。尽管如此,与UG的UIStyler界面设计工具(图2)相比我们还是有了更多的控件选择余地(图2中第1行的第2~第6个图标,只是表示编辑框不同类型的数据,在VC++中可用一个编辑框控件来代替)。除了图1所示的控件之外,在对话框中还可以使用菜单和工具栏[5]。
图1 MFC支持的VC++6.0控件
图2 UG的UIStyler支持的控件
另外,界面设计中还可以使用多层对话框,也可以调用UG/Open提供的交互界面函数,如 “点构造器”对话框(函数名uc1616())。对于uc1616()类交互函数,在应用程序中必须在调用之前先执行 “UF_UI_lock_ug_access (UF_UI_FROM_CUSTOM)”语句对MFC对话框进行锁定,然后调用UG/Open的交互类函数,执行完毕后再调用“UF_UI_unlock_ug_access (UF_UI_FROM_CUSTOM)”解除锁定。
4. UG扩展模块开发实例-参数化设计工具
(1)参数化设计的实现原理
参数化设计工具主要是利用UG的表达式实现对三维模型的控制。在UG环境下,采用交互方式创建草图、标注尺寸以及生成各种特征时,系统均会以表达式的形式记录相关的设计参数。参数化设计工具通过检索三维模型的表达式以及对表达式值的修改生成新的模型。
由于UG的表达式不允许用中文命名,也没有用注释的形式对表达式的意义进行说明之功能。因此直接利用UG提供的表达式处理工具并不方便。因而用UG/OPEN开发的参数化设计工具扩充了这一功能,大大方便了用户的使用。
(2)界面设计及主要功能
参数化设计工具的界面如图3、图4所示。
图3 界面1(三维模型无提示图形)
图4 界面2(三维模型有提示图形)
(3)主要使用的UG/OPEN函数及用法
1)从当前模型中获得表达式
首先调用UF_PART_ask_display_part()函数得到当前模型的指针,然后调用UF_MODL_ask_exps_of_part()函数获得模型中全部表达式数组。再调用UF_MODL_ask_exp_tag_string()和UF_MODL_dissect_exp_string()函数得到各表达式及表达式之值。
2)设置和检索模型的属性值
调用UF_ATTR_assign()和UF_ATTR_read_value()函数可以分别设置和检索出给定模型的属性值。UF_ATTR_assign()函数需要3个输入参数,如:UF_ATTR_assign (part_tag, attr_name, attr_value)。第一个参数为三维模型的指针,第二个参数为属性名,第三个参数为属性值。属性名采用表达式左边的变量名,如对于“p2=5”则取“p2”作为属性名,其属性值为该表达式的说明字符串。这样,当从模型中检索出属性值时可以方便地确定所对应的表达式。
3)表达式的设置和模型的更新
调用UF_MODL_edit_exp()设置表达式的值;调用UF_MODL_update()函数根据新的表达式之值更新当前三维模型。
4)检索当前模型的质量属性
调用UF_WEIGHT_estab_part_props()函数可获得当前模型的质量属性。其质量属性将保存在类型为UF_WEIGHT_properties_t的函数输出参数中,UF_WEIGHT_properties_t为结构体类型的数据,成员volume为模型的体积,成员mass为模型的质量,其余成员的意义可参见文献[1]。
上述说明的参数化设计工具实际上仅仅是用MFC开发UG扩展模块的一个典型范例,由于篇幅所限没有涉及到更多功能和细节。另外,图4中的提示图形采用了文献[5]中介绍的方法来读入并显示。
5. 结论
在VC的集成开发环境中使用MFC开发UG应用程序可以实现多种类型的人机交互界面设计,较UG的UIStyler界面设计功能提供了更多选择余地和更强的功能,并可充分利用VC++资源;采用表达式控制三维模型的参数可以非常简便地实现参数化设计,并使程序具有一定的通用性,大大提高了程序代码的重用性;用设置模型属性的方法解决了三维模型表达式的意义说明问题,弥补了UG系统表达式工具的不足,方便了使用;对UG进行开发可以扩充和增强系统的功能,可以更好地满足制造业信息化的要求。