李文靜 干為民 徐 波
1(江蘇省特種加工重點實驗室(常州工學院) 江蘇 常州 213032) 2(常州大學機械工程學院 江蘇 常州 213164)
常用的CAD/CAM軟件功能多樣且強大,但不能滿足特定用途的設計要求。若能基于此類軟件進行針對產品的二次開發,將能顯著提升現有的生產效率。 “二次開發”就是基于類似UG、Pro/E的軟件系統,開發出有針對性的,將軟件本地化的程序的過程。目前,國內外有許多專家學者都對Pro/E的二次開發進行了研究。張峰[1]以弧面狀的凸輪機械手產品為研究對象,利用Pro/Program模塊對Pro/E進行二次開發,實現了產品模型的結構參數化設計,提高了設計效率和設計質量。王冰冰等[2]研究了Pro/E軟件二次開發的包裝機械的參數化設計和實施方法,通過在系統中輸入參數,可以自動生成三維實體模型和二維工程圖,從而提高設計效率。劉穎等[3]研究了Pro/E二次開發在圓柱齒輪減速器建模中的應用,并闡述了Pro/Toolkit二次開發的基本步驟,詳細介紹了源文件編譯,可執行文件的生成、注冊和運行等關鍵技術。Hsu等[4]以Pro/E軟件為平臺,通過編程C語言開發了一套裝配設計分析和產品概念設計系統,系統通過五個模塊實現了自動化產品。Haapala等[5]利用Pro/E建立了頭骨的三維模型,并賦予其質量屬性,如密度、表面積和慣性矩,然后編制了相應的Pro/Toolkit應用程序以標記兩個肌肉集合的位置,最后創建了一個3D同胚掃視眼和頭部運動系統。
電解加工具有工具無損耗和加工過程無切削應力的特性,故經常采用該方式加工復雜的葉輪類零件[6]。整體葉輪粗加工后,其葉片呈不規則曲面,與預期達到的圖紙上的尺寸還有一定的差距。本文二次開發的模塊程序就是為了簡化測量加工后零件余量大小,從而生成誤差報告,為后續的加工提供了很大的便捷。二次開發的程序不僅可以縮短測量的周期,而且大大提高測量的精度,更是后續加工過程的一個重要的環節。
Pro/E軟件是PTC在美國開發的3D設計軟件,不僅具有參數化、相關化的特點,而且具有更加細致而強大的設計、分析和制造功能,應用比較廣泛[7]。其二次開發主要有基于Pro/Toolkit、 Automation GATEWAY、J-Link、Pro/Web Link、VB API的五種二次開發方法。本文選擇基于 Pro/Toolkit的二次開發方法,該方法不僅可以自動建模,還可以集成需要訪問Pro/E數據或操作的外部應用程序,而且可以擴展軟件用戶界面,讓定制的流程無縫嵌入到用戶界面中[8]。
Pro/Toolkit有異步和同步兩種工作模式。異步模式的優點是Pro/Toolkit應用程序可以在Pro/E系統關閉時單獨運行,但缺點是其程序代碼復雜且運行速度較慢,因此通常不使用異步模式。在同步模式下,Pro/Toolkit應用程序與Pro/E系統必須同步運行,并且在Pro/E系統關閉時無法運行。同步模式分為DLL和多進程模式,Pro/Toolkit和Pro/E集成時采用的標準方法就是DLL模式[9]。由于Pro/Toolkit應用程序在Pro/E系統上運行,所以一般采用同步模式。
圖1為Pro/E二次開發的余量求解的設計流程圖。首先,在安裝好的Pro/Toolkit中對DLL文件進行創建和設置,其中包含關鍵的“庫文件”設置,若設置不對或缺少會導致后期出錯。在二次開發的整個流程中,最為關鍵的就是程序編譯,程序編寫主要分為三大模塊:導入模型、導入數據、誤差分析計算。其中誤差分析是本程序二次開發的核心,其目的是對導入點進行信息收集(主要是坐標屬性信息),對葉片曲面進行分解(可以看成無數的點組成),比對點到葉片距離最近的點,并拾取出來,轉換成點到點的距離計算,并得出測量結果。最后只要導入原設計模型和三坐標測得的云點數據,就可以直接計算出加工后零件尺寸與圖紙設計尺寸的誤差,同時生成誤差數據表。

圖1 總體設計流程圖
在二次開發工具包Pro/Toolkit安裝成功的基礎上,需創建和配置DLL文件。創建DLL文件需先創建一個項目MFC DLL文件,新建一個名稱AnalyticalTools的解決方案后完成MFC DLL文件的創建。然后,設置包含文件和庫文件,在“配置屬性”中“VC++目錄”中添加“包含目錄”,如圖2所示。將庫文件添加到“顯示以下內容的目錄”中,如圖3所示,編輯“預處理器定義”,添加 PRO_USE_VAR_ARGS。最后,編輯“附加依賴庫”,完成二次開發的準備工作。

圖2 添加包含目錄

圖3 添加庫文件
1) 程序頭文件。在主文件中需添加Pro/Toolkit頭文件,常用的頭文件亦可添加,這樣無須在添加新的CPP文件時設置一次頭文件。如果使用了Pro/Toolkit對象函數,則應用程序必須包含ProToolkit.h頭文件。
2) 菜單按鈕的創建。余量求解的程序中有三個按鈕,分別是“加載葉輪模型”、“添加云點數據”和“點面測量分析”。菜單按鈕的創建也分為三個部分:(1) 添加菜單按鈕;(2) 讀取信息文本文件;(3) 添加父菜單。最后編寫信息文本文件,即按鈕的名稱。創建完成后如圖4所示。
int AnalyticalToolsmenu::menuAddexcute()
{return menuAdding();
}
//添加菜單按鈕
int AnalyticalToolsmenu::menuAdding()
{
OTK::pfcUICommand uicmd;
uicmd.SetMsgFile(_T(″AnalyticalTools_msg.txt″));
//讀取信息文本文件
uicmd.parent_designate(″AnalyticalToolsMenubar″,″AnalyticalTools_Menubar″,″Utilities″);
//添加父菜單
//信息文本文件:
AnalyticalTools_Menubar
Creo2 Wizard
#
AnalyticalToolschildmenu0
AnalyticalToolschildmenu0
加載葉輪模型
#
?

圖4 菜單按鈕的創建
“加載葉輪模型”按鈕的開發其實質是對原有功能“打開文件”的調用,先添加菜單按鈕,再去調用已有函數按鈕ProCmdModelOpen,可以實現打開選擇模型的模塊。
uicmd.Designate(″AnalyticalTools_child_action0″,″AnalyticalToolschildmenu0″,″AnalyticalToolschildmenu0-help″,″button.gif″,AnalyticalToolschildmenu0action);
//添加菜單按鈕0
void Designate(IN CharPtr action_name,IN CharPtr Label,IN CharPtr pHelp,IN CharPtr icon,IN MyFunction func,IN MyuiCmdAccessFn acc=uiAccess )
//對Designate的定義
//菜單按鈕0的主函數:
extern ProError AnalyticalToolsmenu::AnalyticalToolschildmenu0action()
{
return ProMacroLoad(L″~Command ′ProCmdModelOpen′;″);
//調用函數按鈕ProCmdModelOpen使用“摘要”樣式
}
導入點云文件模塊其實質和打開模型模塊的實質相似,是對按鈕“導入”的調用,故與打開模型模塊程序編寫類似,只是改變要調用的函數按鈕。
exter ProError AnalyticalToolsmenu::AnalyticalToolschildmenu1action()
{return ProMacroLoad(L″~Command ′ProCmdModelImpAppendNew′;″);}
//調用已有函數按鈕
ProCmdModelImpAppendNew
余量求解模塊是本次二次開發程序的核心,依舊是先創建菜單按鈕,這與先前模塊一致,再對菜單按鈕的主要函數進行編寫這是關鍵一步。主要分為以下幾個部分:
(1) 對輸入的pts云點數據文件進行添加:
ProError getfeats(ProFeature p_feat,ProError status,ProAppData app_data)
{ProArrayObjectAdd((ProArray*)app_data, PRO_VALUE_UNUSED, 1, &p_feat);
//將指定位置的對象添加到數組中,或者將一個對象追加
//到數組的末尾
return (status);}
(2) 對輸入點進行特征收集:
ProError getfeats(ProFeature p_feat,ProError status,ProAppData app_data) {ProArrayObjectAdd((ProArray*)app_data, PRO_VALUE_UNUSED, 1, &p_feat);return (status);} extern ProError ProArrayObjectAdd (ProArray* p_array,int index,int n_objects,void* p_object); For example, if you want to insert one integer in an integer array, call the function as follows: ProArrayObjectAdd (&int_array, 0, 1, (void *)&int_val);
(3) 收集模型上云點投影的基準點:
ProError getGeoms(ProGeomitem*geom,ProError err,ProAppData data)
{err=ProArrayObjectAdd((ProArray*)data, PRO_VALUE_UNUSED, 1, (void*)geom);
return err;
}
ProError featGeomsCollect (ProFeature*feat, vector
{ProError status;
ProFeature *p_data;
Int nsize=0;
status=ProArrayAlloc(0,sizeof(ProGeomitem),1,(ProArray*)&p_data);
status=ProFeatureGeomitemVisit(feat, PRO_POINT, (ProGeomitemAction)getGeoms, NULL, (ProAppData)&p_data);
//對項目進行編譯
ProArraySizeGet((ProArray)p_data, &nsize);
for(int i=0; i < nsize; i++)
{p_POINT_data.push_back(p_data[i]);}
return ProArrayFree((ProArray*)&p_data);
}
(4) 對話框顯示數據:
class SolidOutlineUI
public: static void UI_Create()
{char *dialog_name=″SolidOutline″;
int ActiveDialog_status;
ProError err;
err=ProUIDialogCreate(dialog_name,dialog_name );
(5) 對固定面ID的拾取:
ProError status;
ProSelection surface_sel, cansel;
ProModelitem surface_item;
//信息過濾函數
surface_item.id=11626;
//面ID
surface_item.type=PRO_SURFACE;
//模型曲面
surface_item.owner=Curmdl;
(6) 如果不成功手動選取面:
status=ProSelectionAlloc(NULL, &surface_item, &surface_sel); if (status !=PRO_TK_NO_ERROR) {ProError err;ProSelection *p_Selection;int n_sels; err=ProSelect(″surface″,1, NULL, NULL, NULL, NULL,&p_Selection,&n_sels); if (err !=PRO_TK_NO_ERROR||n_sels==0)
{return;} ProSelectionCopy (p_Selection[0], &surface_sel); } vector Pro2dPnt uv1, uv2; Pro3dPnt xyz1, xyz2; (7) 對應面的最短距離坐標顯示: CString strHead[]={L“面坐標”,L“點坐標”,“測量值”}; int Widths[]={ 11, 11, 7 }; TableHeadSet(dialog, ″Table1″,p_POINT_data.size(), 3, strHead, Widths ); for(int i=0; i < p_POINT_data.size();i++) {status=ProSelectionAlloc(NULL, &p_POINT_data[i], &cansel);if (status==PRO_TK_NO_ERROR) {status=ProSelectionDistanceEval(surface_sel, cansel, uv1, uv2, xyz1, xyz2, &distance); //計算兩個點之間的距離 (8) 對話框輸出表格建立: private:static ProError TableItemTextSet(IN char* dialog_name, IN char* TitleName, IN int row, IN int column, IN CString ItemText) { ProCharLine strtmp, strtmp1; sprintf_s(strtmp,″col%d″,column); sprintf_s(strtmp1,″row%d″,row); return ProUITableCellLabelSet(dialog_name, TitleName, strtmp1, strtmp, (wchar_t*)(LPCTSTR)ItemText);} //設置表單元格中包含的文本 (9) 對話框表格的劃分: for(int i=0; i < column; i++) {names[i]=(char *)calloc(PRO_NAME_SIZE, sizeof(char)); labels[i]=(wchar_t *)calloc(PRO_PATH_SIZE, sizeof(wchar_t)); sprintf_s(strtmp,″col%d″,i+1);strcpy(names[i],strtmp); wcscpy(labels[i],(wchar_t*)(LPCTSTR)pHead[i]); } status=ProUITableColumnnamesSet(dialog_name, TitleName,column, names); //表格分列 status=ProUITableColumnlabelsSet(dialog_name, TitleName,column, labels); //設置表格中每列標簽的名稱 ProUITableColumnwidthsSet(dialog_name, TitleName, column, pHeadWidths); //設置表格中每列的寬度 ? ProUITableShowgridSet(dialog_name, TitleName, pGrid); return status;}} //表格顯示 最后,還需編寫一些輔助程序如注冊文件程序和菜單圖標程序。菜單圖標如圖5所示。 NAME AnalyticalTools startup dll EXEC_FILE AnalyticalTools_dirPRO_MACHINE_TYPEAnalyticalTools.dll TEXT_DIR AnalyticalTools_dir ext allow_stop true DELAY_START false revision Wildfire END //注冊文件 Button.gif //菜單圖標文件 圖5 菜單圖標 在以上設置完成基礎上,再在“資源管理器”項目中生成程序,生成程序如圖6所示,然后對程序進行調試,調試結果如圖7所示。 圖6 生成程序 圖7 程序調試成功 調試成功后需進行創建快捷啟動方式,創建程序如下: @echo off set AnalyticalTools_dir=.. set lang=chs start″″″E:Program FilesPTCCreo 2.0Parametricinparametric.exe″ Exit //創建快捷方式 運用三坐標測量機進行數據采集, 得到點云數據, 對粗加工后葉輪葉片用三坐標機進行劃線測量取點,如圖8所示,得到點云坐標。由于人為或隨機因素在測量過程中的影響,測量中存在不穩定噪聲點,文件需要點轉換,并且去除不滿足的點。對云點坐標進行處理并轉換成可以導入Pro/E點文件.pts格式文件,轉換后的.pts格式點文件如圖9所示。 圖8 劃線測量 圖9 處理后點云數據 針對電解加工后的整體葉輪葉片進行余量求解,打開“工具”菜單欄,子菜單為二次開發程序菜單,包含“加載葉輪模型”“加載點云數據”“點面測量分析”三個按鈕。第一步,點擊按鈕“加載葉輪模型”,加載完成后如圖10所示。第二步,點擊“加載點云數據”即導入之前的.pts格式的點云文件,加載完成后如圖11所示。第三步,點擊“點面測量分析”,由于一個葉片是由至少兩個曲面組成,所以葉輪葉片存在正面與反面的誤差求解。選擇需要測量的曲面,葉片正反面余量求解的結果如圖12所示。 圖10 加載葉輪模型 圖11 加載點云數據 圖12 整體葉輪葉片余量求解結果 一般誤差分析方法,針對簡單的有規則形狀零件可以直接用現有的測量工具測量,但數據不精確,而復雜的零件如整體葉輪葉片之類曲面結構較多的零件會利用算法來進行測量,工作量較大且易出錯。相比之下,二次開發余量求解程序響應快,只需很短的時間就可以得到結果并且不易出錯。 本文以Pro/E2.0為平臺,基于開發語言VC++6.0,以Pro/Toolkit為二次開發工具,使用編譯平臺VS2010,開發出一套能在Pro/E中實現粗加工模型到設計模型的余量計算的應用程序,并成功地應用在電解加工整體葉輪中,代替傳統的誤差分析方法,大大縮短測量周期,提高加工效率,降低生產成本,成為后續加工設計的重要組成部分。2.7 其他輔助程序模塊

3 程序的配置與運行


4 電解加工整體葉輪葉片余量求解實例
4.1 三坐標機采集點云坐標


4.2 余量求解實際應用




4.3 余量求解結果分析
5 結 語