校月軍
Inventor 二次開發(fā)有 3種方式:Add-In, EXE和 VBA Macro[1]。Add-In和VBA Macro都是進程內(nèi)加載運行;EXE方式,是在進程外,通過創(chuàng)建 Inventor進程并獲取其Application訪問Inventor對象,或者通過Inventor Apprentice將Inventor的一些功能模塊加載到自己的進程中運行,但該方式下的API集要小一些[2]。他們各有自己的優(yōu)缺點,可以根據(jù)需要自己選擇。
Add-In的優(yōu)點,是直接將自己的功能完全嵌入到Inventor當中,可以完全訪問Inventor的所有API,該方式對于用戶,具有較高透明性,用戶可以控制其加載和卸載。Add-In可以獨立發(fā)布,單獨制作安裝包;其缺點是需要較多的時間來開發(fā)。同時,Add-In分為兩種:Application Add-In和Translator Add-In。Translator Add-In是專門針對其他CAD文件和Inventor文件之間格式轉(zhuǎn)換而設計的Add-In 框架。而Application Add-In 可以歸結(jié)為其他的一般的Add-In。兩者間的啟動方式和入口不大一樣,Translator Add-In一般設計為打開某個特定文件時才會加載該 Add-In模塊,而Application Add-In 一般是隨著Inventor的啟動或者打開第一個Add-In所支持的文檔時加載(2012才有的Delay loading的功能)。本文著重介紹Application Add-In。
EXE方式由于只能訪問部分Inventor API,故其主要是將Inventor的部分功能,集成到自己的應用中。例如安裝包里的TaskScheduler工具,其主要是利用Inventor對Inventor文件進行簡單的操作; Exe還可以通過 Apprentice集成Inventor的功能,Apprentice 類似于一個沒有UI的Inventor的內(nèi)核,API也相對少一些。Apprentice的優(yōu)點,是不需要啟動 Inventor進程就能對 Inventor文檔進行操作,缺點是API沒有Inventor API豐富。
VBA Macro是Inventor自帶的VBA開發(fā)環(huán)境,啟動Inventor后,就能通過直接編寫 VBA代碼來訪問所有Inventor的API,調(diào)試也相對簡單,能夠查看Inventor 對象里的各個變量值。不需要學習復雜的高級編程語言,開發(fā)簡單、快速、適用于做原型論證(Prototype);但其缺點是代碼是暴露給所有用戶,用戶需要在Inventor VBA環(huán)境中加載VBA macro的工程,運行其代碼。
Inventor作為整個二次開發(fā)的平臺,必須在機器上安裝Autodesk的Inventor產(chǎn)品,同時需要安裝類似Visual Studio之類的軟件開發(fā)工具及組件。因為 Inventor Add-In本身是COM組件,所以,該開發(fā)工具需要具備COM組件開發(fā)的功能。
本文的例子是基于Inventor 2012平臺之上,采用的開發(fā)語言是C++,開發(fā)工具是VC++ 2008。如果你的Inventor和 Visual Studio版本較低,仍然也可以按照本文的步驟操作,實現(xiàn)一個Add-In (部分2011 和2012版本上的才有的新功能除外) 。
2.2.1 創(chuàng)建與加載新的Add-In
在裝有Inventor產(chǎn)品的機器上,可以看到以下路徑中含有eveloperTools.msi 和UserTools.msi兩個安裝包:
Win7:C:UsersPublicDocumentsAutodeskInventor 2012SDK
WinXP:C:Program FilesAutodeskInventor 2010SDK
其中,DevelopTools.MSI安裝后會生成5個文件夾:Docs下放的是一些Add-In開發(fā)的指導文檔,其中包括API結(jié)構(gòu)圖;Include下是為C++開發(fā)環(huán)境準備的頭文件庫;Reference下方的是 Inventor用來讀寫注冊表的模塊;Sample下一些二次開發(fā)的實例;Tools下有一些二次開發(fā)相關(guān)的有用的工具,比如Event Watcher 就是一個查看Inventor事件的很好的工具;Wizard下的 InventorWizards.msi 是 Visual Studio環(huán)境中的一個Inventor Add-In模板安裝包,安裝完畢后,你的VS環(huán)境中就會有一個名字叫Autodesk Inventor AddIn模板(包括VB和C#[3]:
選擇該模板,創(chuàng)建一個新的項目,命名為“MyInventorAddIn”, 下一步到“Add-In Type & Settings”頁面:Project Type可選為Application Add-In in a regular dll 或者Translator Add-In in a regular dll。Details里面的name是Add-In的啟動類,description為該Add-In的描述,我把他們都設置為MyInventorAddInServer和This is my first Add-In,下一步直到結(jié)束。
配置好項目環(huán)境后編譯該工程,如果遇到 fatal error LNK1000,修改工程屬性 Build Event>Post Build Event>command line, 指定正確的目的文件夾,本例的正確路徑為"C:ProgramDataAutodeskInventor 2012Addins”),成功后,啟動Inventor.exe,點擊按鈕Tools>Add-Ins,啟動Add-In Manager窗口,可以看到的Add-In已經(jīng)在Add-Ins列表中。
2.3.1 Solution文件結(jié)構(gòu)說明與講解:
該目錄結(jié)構(gòu)由模板自動生成,主要具有以下文件,如圖1所示:
圖1 Solution文件組成
MyInventorAddInServer.cpp:定義了該 Add-In的入口(即加載點);
MyInventorAddIn.idl:定義了該COM對象相關(guān)的信息,定義在coclass前的classID(即uuid)一般作為Add-In的唯一標識,Inventor根據(jù)這個ID來創(chuàng)建Add-In的COM對象,從而根據(jù)預定義的接口來加載Add-In模塊;
MyInventorAddIn.X.manifest:(開始于2011版本)定義了該COM對象的manifest文件,用于支持side-by-side的功能,其文件結(jié)構(gòu)(.addin)為:
Inventor 2011引入了一種新的Add-In注冊方式:.addin方式。在之前的版本,Inventor Add-In的信息是通過AddInServer的DllRegisterServer(…)函數(shù)將Add-In信息以COM注冊的方式寫在注冊表當中的,Inventor會去遍歷出這些信息,創(chuàng)建Add-In對象并且加載。2011開始,Inventor也會遍歷預定義的Add-In文件夾,遍歷所有的.addin文件,從而獲取 Add-In的必要信息??赡苄枰f明的是
三個重要函數(shù):
該函數(shù)是Add-In的入口函數(shù),該Add-In的COM對象一旦被創(chuàng)建出來,Inventor就會Query該方法,參數(shù)FirstTime值由Inventor給出,表明該Add-In是否為第一次初始化,一般是指Inventor安裝后的第一次加載該Add-In模塊。 類CMyInventorAddInServer繼承于模板類 CApplication AddInServerImpl,該基類持有指向InventorApplication的指針m_pApplication,通過該指針你可以訪問Inventor的API庫,從而操作Inventor對象。
OnDeactivate()方法會在該Add-In模塊被unload的情況下被調(diào)用。最后才會被清理的對象或指針一般放在這里釋放。
Inventor 不僅可以暴露自己的API,同樣也支持用戶設計的Add-In API,用戶可以通過該函數(shù)將Add-In Server的對象暴露出去,用戶可用通過Inventor API取到Add-In的handle,從而操作其暴露的函數(shù)。
此時的Add-In雖然已經(jīng)可以被Inventor識別和加載,但沒有實現(xiàn)任何功能,如何添加功能,將在下面介紹。
2.3.2 Add-In的Framework
Add-In的功能,除了自己的邏輯之外,很大的一部分模塊是用來和Inventor 交互的,由于Inventor的API對于所有的Add-In來講都是一樣的,所以就有可能存在統(tǒng)一或者類似的 Add-In framework,不管你使用的是哪種,都會有下面幾個重要的元素:Interface,command和request。本文結(jié)合例子SamplesVC++AddInsCustomCommand來研究Add-In的模型以及其是如何工作的。
Interface是指Inventor UI上的Add-In的command命令,在該實例中,由基類CCommand提供的CreateButton (…) 方法生成新的 ButtonDefinition,在 ButtonDefinition的OnActivate方法中可以創(chuàng)建一個新的 command,
當按鈕被用戶點擊后,該Command即被激活,對應的ButtonDefinition就會收到Inventor的OnExecute事件,在該事件中,可以初始化Add-In的對話框,可以為模態(tài)也可以為非模態(tài),同時啟動 Interaction事件,該事件可以通過OnPreselect,OnSelect,OnUnselect等方法,幫你選擇你需要的操作對象,比如說平面或者圓弧之類,這些數(shù)據(jù)將作為該command的輸入數(shù)據(jù)。
當所有必需的輸入數(shù)據(jù)都準備好后,該command就可以調(diào)用對應的 request類執(zhí)行該 command,request主要由ChangeProcessor對象來扮演,所有的 request通過ChangeProcessor執(zhí)行后將會自動合成為一個事務操作,自動支持undo和redo。ChangeProcessor同時支持Inventor的Transcript腳本, 實現(xiàn)自動化測試:OnReadFromScript從script中恢復輸入數(shù)據(jù),包括 Inventor的對象;OnWritetoScript將所有的輸入數(shù)據(jù)寫入到script中存儲。
Inventor能夠成功加載Add-In,調(diào)試也就相當簡單。首先確定.AddIn文件中指定的AddInServer dll所指向的是編譯生成的dll,然后用Visual Studio 打開該工程文件,選擇AddInServer所在的Dll,右鍵中選擇“設置為啟動項目(Set as startup Project)”,然后再次右鍵,選擇屬性 (Property) > 調(diào)試 (Debugging) > 命令(command), 輸入Inventor.exe的全路徑,F(xiàn)5(start debugging)。設置斷點,然后Inventor運行到該斷點時,將會自動觸發(fā)。
另一種方式是采用 Visual Studio 中的 Attach Inventor.exe的方式。
Add-In的部署和一般軟件的部署一樣,只要將所需的文件安裝正確的目錄即可,如果還是通過寫注冊表的方式來注冊,Add-In,Inventor內(nèi)部的Add-In通常是采用另外編寫一個exe程序,對所有需要register的dll進行注冊和反注冊,由安裝包在安裝時執(zhí)行該exe程序,完成注冊過程,卸載是執(zhí)行反注冊過程。
CAD軟件的二次開發(fā),一直以來都是一個比較活躍的話題,各個平臺間的二次開發(fā),也有著較大的差別,本文研究和實踐了Inventor Add-In的一些基本知識和技術(shù)。同時,隨著新技術(shù)的不斷出現(xiàn),Add-In的開發(fā),也在不斷融入新的內(nèi)容,如:
(1)多核CPU要求Add-In及其平臺能夠具有多任務處理的能力。
(2)通過云計算將Add-In的功能模塊引入云端。
(3)移動平臺的迅速發(fā)展,也要求Add-In能夠具備較好的跨平臺能力。
[1]Brian Ekins, Taking the Step from VBA Macros to Autodesk Inventor Add-Ins,[M]Autodesk University 2009
[2]Brian Ekins, Upgrading your Autodesk Inventor Add-Ins to Use the New Ribbon User Interface,[M]Autodesk University 2009
[3]Rajeev Lochan C.G, Develop Autodesk Inventor Addin using C#, 2008.9