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進行開發可以擴充和增強系統的功能,可以更好地滿足制造業信息化的要求。