齊成龍
(中國鐵路設(shè)計(jì)集團(tuán)有限公司土建院,天津300308)
在橋墩BIM 設(shè)計(jì)中,設(shè)計(jì)單位交付的BIM 模型無法全面考慮施工過程的影響。對于高度大于某一范圍的橋墩,實(shí)際施工時(shí),無法一次澆筑,需要沿高度方向分節(jié)段澆筑或拼裝,圖1 所示為某橋墩節(jié)段拼裝工程實(shí)例,這種情況下,施工階段橋墩BIM模型必須能夠反映出這種節(jié)段的劃分。同時(shí),由于每一個(gè)橋墩在現(xiàn)場施工環(huán)境和可用設(shè)備方面存在差異性,即使是相同高度的橋墩,其豎向節(jié)段的劃分標(biāo)準(zhǔn)也不相同,而這種差異性是設(shè)計(jì)階段BIM 模型無法預(yù)估的。因此,解決這種問題的最好辦法是將橋墩分節(jié)段澆筑或拼裝導(dǎo)致的模型變化交給施工階段來完成。
圖1 橋墩分節(jié)段拼裝工程實(shí)例Fig.1 Project instance for segmental assembly of the pier
本文介紹一種橋墩BIM 模型切割工具,該工具使用達(dá)索/組件應(yīng)用架構(gòu)(CAA)二次開發(fā)語言實(shí)現(xiàn),嵌入到達(dá)索軟件裝配設(shè)計(jì)模塊內(nèi)部[1]。由用戶選擇被切割體、切割面和切割結(jié)果的裝配目標(biāo)位置,程序運(yùn)行結(jié)束后,自動(dòng)將切割結(jié)果插入到裝配目標(biāo)位置。
根據(jù)前述應(yīng)用需求,設(shè)計(jì)出如圖2 所示的用戶交互界面。該人機(jī)交互的橋墩切割工具采用達(dá)索/CAA 語言二次開發(fā),直接嵌入到達(dá)索軟件內(nèi)部[2-3]。具備以下幾個(gè)特點(diǎn):①橋墩切割工具嵌入到達(dá)索裝配設(shè)計(jì)(AssemblyDesign)模塊中;②被切割體可由多個(gè)部分構(gòu)成,各部分可分屬于不同的物理產(chǎn)品(Physical Product),對物理產(chǎn)品的層次結(jié)構(gòu)沒有限制,同一個(gè)物理產(chǎn)品下還可包含多個(gè)3DShape;③屬于同一物理產(chǎn)品的被切割體,在切割后,將被分解為多個(gè)物理產(chǎn)品,每個(gè)物理產(chǎn)品包含一個(gè)無法編輯、輕量化的Datum類型特征[4]。
以某橋墩的主墩切割過程為例,如圖2 所示,主墩模型存儲(chǔ)于“01Pier main”節(jié)點(diǎn)下,由三部分組成,由圖中結(jié)構(gòu)樹可知這三部分所在物理產(chǎn)品節(jié)點(diǎn)的層次結(jié)構(gòu)。如圖3 所示,首先點(diǎn)擊嵌入到達(dá)索裝配設(shè)計(jì)模塊下的操作按鈕,打開用戶交互窗口,在CutProduct 位置選擇被切割體所在的節(jié)點(diǎn)“01Pier main”,在CutSurfaces 位置選擇切割面所在的幾何圖形集“CutSurface”,在TargetProduct位置選擇切割結(jié)果需要裝配的目標(biāo)位置。
圖2 切割前的橋墩模型用戶交互界面Fig.2 Pier model before segmentation and user interface
圖3 嵌入到裝配設(shè)計(jì)模塊下的操作按鈕Fig.3 Operation button embedded in assembly design module
點(diǎn)擊“確定”按鈕后,程序使用用戶所選幾何圖形集內(nèi)的三個(gè)切割平面執(zhí)行切割操作。切割前,被切割拓?fù)潴w存儲(chǔ)在3 個(gè)3DShape 下,對比圖2 和圖4 可以看出,切割前后,主墩由3 個(gè)部分變成12 個(gè)部分。切割后,目標(biāo)裝配總結(jié)點(diǎn)下包含由12個(gè)物理產(chǎn)品組成的子節(jié)點(diǎn)。
圖4 切割后的橋墩模型Fig.4 Pier model after segmentation
為了實(shí)現(xiàn)上一節(jié)介紹的操作。需要使用如圖5 所示的流程進(jìn)行二次開發(fā),具體分為以下三個(gè)重要步驟:
(1)獲取切割面、被切割體、目標(biāo)位置;
(2)遍歷、存儲(chǔ)被切割體;
(3)生成切割結(jié)果并組裝至目標(biāo)位置。
圖5 程序二次開發(fā)流程Fig.5 Development process of this program
以下各節(jié)將依次通過對此三個(gè)步驟的介紹,闡述本程序的二次開發(fā)策略和思路。
切割面、被切割體、目標(biāo)位置,這三種元素作為程序執(zhí)行的先決條件,它們的獲取是屬于用戶界面交互功能的職能范疇,用戶界面交互功能分為創(chuàng)建工具按鈕和創(chuàng)建用戶交互窗口兩部分。
工具條采用Add-in 的方式添加,為了將橋墩切割功能嵌入到裝配設(shè)計(jì)(AssemblyDesign)模塊,用于添加工具條的Add-in 類必須實(shí)現(xiàn)CATIAssyWorkBenchAddin 接 口 。 再 通 過CATAfrCommandHeader:
CATCreateCommandHeader()成員函數(shù)使添加的工具條與橋墩切割命令相關(guān)聯(lián)。這樣就實(shí)現(xiàn)了在已有裝配設(shè)計(jì)模塊下添加一個(gè)按鈕,用戶點(diǎn)擊此按鈕,激活橋墩切割命令[5]。
首先創(chuàng)建用戶交互窗口Dialog 文件,該文件與切割命令所在文件相互獨(dú)立。在橋墩切割命令文件中,通過對CATMmrPanelStateCmd 類的派生,重載GiveMyPanel 方法,使包含橋墩切割命令的派生類與用戶交互對話窗口Dialog 文件關(guān)聯(lián)。Dialog 文件僅用于窗口控件屬性的獲取和賦值,而對話流程操作是通過切割命令文件對BuildGraph()方法的重載實(shí)現(xiàn)的。
BuildGraph 方法通過命令狀態(tài)(Command State)和代理(Agent)兩個(gè)關(guān)鍵元素來實(shí)現(xiàn)用戶與界面的交互響應(yīng)[6]。
本程序使用了兩種代理:CATDialogAgent 代理用于獲取界面控件響應(yīng),命令當(dāng)中定義了三個(gè)此類代理,分別表示對代表切割面、被切割體、目標(biāo)位置的三種DialogList 控件的選擇;CATPathElementAgent 繼承自 CATDialogAgent,命令當(dāng)中也定義了三個(gè)此類代理,此種代理用于獲取從根節(jié)點(diǎn)開始,到鼠標(biāo)下對象的完整路徑,這個(gè)對象可以是位于模型顯示空間的某幾何體或者是位于結(jié)構(gòu)樹的某個(gè)節(jié)點(diǎn),再通過對該代理施加對象類型和過濾條件的限制,使之分別用于獲取鼠標(biāo)下的切割面(幾何圖形集)、被切割體(物理產(chǎn)品)、目標(biāo)位置(物理產(chǎn)品)。
對于前述兩種代理,當(dāng)用戶成功選擇了相應(yīng)的 DialogList 控件時(shí),CATDialogAgent 代理就被賦值;當(dāng)用戶成功選擇了鼠標(biāo)下的某個(gè)符合要求的對象時(shí),CATPathElementAgent 代理就被賦值。每個(gè)命令狀態(tài)都存儲(chǔ)了若干個(gè)代理,在程序中,對于每個(gè)命令狀態(tài),預(yù)定義了其中的各個(gè)代理被賦值以后程序應(yīng)該執(zhí)行的具體操作,以及向其他命令狀態(tài)轉(zhuǎn)換的規(guī)則。圖6以命令狀態(tài)1為例,介紹了用戶與界面交互的原理。在程序執(zhí)行過程中,當(dāng)某命令狀態(tài)中的一個(gè)代理被成功賦值以后,CAA程序就會(huì)查閱前述轉(zhuǎn)換規(guī)則,來決定此時(shí)應(yīng)該向哪一個(gè)命令狀態(tài)進(jìn)行轉(zhuǎn)換。
圖6 通過命令狀態(tài)和代理實(shí)現(xiàn)用戶與程序交互Fig.6 Interaction between user and program through command state and agent
從二次開發(fā)層面來說,達(dá)索系統(tǒng)有四種常用的核心成員對象(PLM Core Data),分別是參考(References)、實(shí) 例(Instances)、代 理 參 考(RepresentationReferences) 和 代 理 實(shí) 例(RepresentationInstances)。結(jié)構(gòu)樹的每一個(gè)節(jié)點(diǎn)可以是實(shí)例或代理實(shí)例,而實(shí)例或代理實(shí)例分別是由參考和代理參考實(shí)例化而來。從用戶手動(dòng)操作的層面來說,達(dá)索向用戶開放的操作對象有兩種,分別是物理產(chǎn)品(Physical Product)和三維形狀(3DShape)。用戶手動(dòng)操作層面的兩種對象與二次開發(fā)層面的四種對象有如下對應(yīng)關(guān)系:物理產(chǎn)品對應(yīng)于參考和實(shí)例,三維形狀對應(yīng)于代理參考和代理實(shí)例[7]。
CAA提供了四種接口CATIPLMNavReference,CATIPLMNavInstance,CATIPLMNavRepReference,CATIPLMNavRepInstance,它們分別與二次開發(fā)層面的四種常用核心成員對象相對應(yīng),用于對樹形結(jié)構(gòu)中各成員的遍歷和檢索。
在用戶與界面的交互過程中,程序成功獲取了一個(gè)用于存儲(chǔ)被切割體的物理產(chǎn)品,由于具體建模方式和組織結(jié)構(gòu)的多樣性,從層次結(jié)構(gòu)上講,該物理產(chǎn)品可以再分解為多個(gè)子物理產(chǎn)品,每一個(gè)子物理產(chǎn)品還可以繼續(xù)分解。在這種樹型的被切割體組織結(jié)構(gòu)中,3Dshape 是具體的特征存儲(chǔ)位置,每一個(gè)3Dshape 都必須依附于某物理產(chǎn)品才能存在,而模型的幾何形狀體現(xiàn)在各種特征當(dāng)中,因此,對被切割體的遍歷和存儲(chǔ)最終都是在3Dshape 中完成的。對于”程序界面及操作流程設(shè)計(jì)“一節(jié)所介紹的示例,其樹型組織結(jié)構(gòu)如圖7所示,可以看出,它是四層樹形結(jié)構(gòu),如果要獲取承載被切割體的特征,需要在3 個(gè)3DShape 下進(jìn)行遍歷。
圖7 示例中主墩被切割體模型樹型組織結(jié)構(gòu)Fig.7 Tree structure of main pier cut model in the example
在達(dá)索系統(tǒng)當(dāng)中,特征無法直接存儲(chǔ)于3DShape 下,而是通過有兩種特征存儲(chǔ)集合(geometrical features set)實(shí)現(xiàn)存儲(chǔ)功能:幾何圖形集(Geometrical Set)和零件幾何體(Solid features set)[8],幾何圖形集無法存儲(chǔ)與三維拓?fù)鋵?yīng)的特征,而零件幾何體可用于存儲(chǔ)任何拓?fù)漕愋偷奶卣?。這兩種特征存儲(chǔ)集合還可以繼續(xù)嵌套幾何圖形集和零件幾何體,也形成一種與前述被切割體類似的樹型組織結(jié)構(gòu)。本小節(jié)介紹如何從具備這樣一種組織結(jié)構(gòu)的3DShape 下,獲取其中的拓?fù)潴w,并將其存儲(chǔ)于一個(gè)CATLISTP(CATBody)類型的集合中,該集合中的拓?fù)潴w分別與3DShape 下的所有特征一一對應(yīng)。
目前,在CAA可用的API中,CATIPartRequest接口的GetDirectBodies()方法,能夠獲取當(dāng)前3DShape 下的第一級(jí)特征存儲(chǔ)集合;CATIBodyRequest 接口的 GetDirectBodies()方法,能夠獲取當(dāng)前特征存儲(chǔ)集合的第一級(jí)子特征存儲(chǔ)集合。因此,對于這種不確定具體層數(shù)的樹型組織結(jié)構(gòu),可采用遞歸調(diào)用的方法獲取某一3DShape 下的所有特征存儲(chǔ)集合,繼而獲取其中的被切割體拓?fù)?,?dāng)通過CATIBodyRequest 接口的GetDirectBodies()方法獲取某一特征存儲(chǔ)集合下的所有子特征集合,并且集合大小為0 時(shí),說明當(dāng)前集合沒有子集合,遞歸調(diào)用滿足終止條件。具體流程如圖8所示。
圖8 獲取具備樹型組織結(jié)構(gòu)的3DShape下所有拓?fù)潴w的流程Fig.8 Topological body obtaining process of 3D Shape with a tree structure
通過CATIPartRequest 接口獲取當(dāng)前3DShape的所有特征存儲(chǔ)集合后,循環(huán)操作,依次對每一個(gè)特征存儲(chǔ)集合執(zhí)行如下遞歸調(diào)用的過程:
(1)通過CATIMmiUseBodyContent 接口獲取當(dāng)前特征存儲(chǔ)集合i 下的所有特征,對于其中的第j 個(gè)特征,通過CATIMmiUseGeometricalElement接口獲取與之對應(yīng)的拓?fù)潴w;
(2)把步驟(1)中生成的拓?fù)潴w追加到CATLISTP(CATBody)類型的集合中;
(3)在j的范圍內(nèi)循環(huán),也就是在存儲(chǔ)集合i下的所有特征范圍內(nèi)循環(huán)。循環(huán)結(jié)束時(shí),通過CATIBodyRequest 接口,查看當(dāng)前特征存儲(chǔ)集合i下是否還有其他子存儲(chǔ)集合;
(4)如果通過步驟(3)發(fā)現(xiàn),特征存儲(chǔ)集合i下還有其他子存儲(chǔ)集合,返回步驟(1),對每一個(gè)子存儲(chǔ)集合執(zhí)行遞歸調(diào)用的過程。如果通過步驟(3)發(fā)現(xiàn),特征存儲(chǔ)集合i 下不再包含其他子存儲(chǔ)集合,不再執(zhí)行遞歸操作,執(zhí)行下一個(gè)循環(huán),返回步驟(1),繼續(xù)對3DShape 下的第i+1 個(gè)特征存儲(chǔ)集合執(zhí)行獲取拓?fù)潴w的操作。
該函數(shù)以被切割體總結(jié)點(diǎn)的物理產(chǎn)品(Physical Product)作為輸入?yún)?shù),輸出一個(gè)用于存儲(chǔ)CutBodyStruct類型結(jié)構(gòu)體的集合。在作為輸出結(jié)果的集合中,每一個(gè)CutBodyStruct 類型的結(jié)構(gòu)體數(shù)據(jù)代表切割后的最小單元。
該類型結(jié)構(gòu)體的聲明如下:
從前述第4.1節(jié)可知,被切割體的拓?fù)湫螤畲鎯?chǔ)在總結(jié)點(diǎn)樹型組織結(jié)構(gòu)下各離散的3DShape中。切割之前,作為輸入?yún)?shù)的CutBodyStruct 結(jié)構(gòu)體,其BodyList 成員代表總結(jié)點(diǎn)物理產(chǎn)品下某3DShape 中存儲(chǔ)的拓?fù)潴w集合,切割之后,一個(gè)3DShape 中存儲(chǔ)的拓?fù)湫螤顣?huì)被分為若干個(gè)部分,與各部分相對應(yīng)的多個(gè)CutBodyStruct 結(jié)構(gòu)體會(huì)以集合的方式輸出,其中每個(gè)CutBodyStruct 結(jié)構(gòu)體的BodyList 成員代表切割后每個(gè)部分中存儲(chǔ)的 拓 撲 體 子 集 ,每 個(gè) 結(jié) 構(gòu) 體 的spOccOnCurrentNode 成員代表與該3DShape 直接相關(guān)的上一級(jí)物理產(chǎn)品節(jié)點(diǎn)。
切割操作的大致步驟是:對于一個(gè)指定的3DShape,首先在所有切割面的范圍內(nèi)循環(huán),依次使用每一個(gè)切割面對當(dāng)前被切割體進(jìn)行切割,當(dāng)完成一次循環(huán)也就是使用其中一個(gè)切割面完成切割后,CutBodyStruct 類型結(jié)構(gòu)體的集合就會(huì)更新。在下一次循環(huán)使用新的切割面進(jìn)行切割時(shí),切割對象就是上一次循環(huán)產(chǎn)生的新的CutBodyStruct類型結(jié)構(gòu)體集合,這樣,循環(huán)結(jié)束后的結(jié)構(gòu)體集合正是所需的輸出結(jié)果。
本小節(jié)前面部分介紹了在一個(gè)3DShape 范圍內(nèi)的切割操作流程,為了對整個(gè)被切割體樹型組織結(jié)構(gòu)中的所有3DShape 成員執(zhí)行切割操作,BrowseOccurrence()函數(shù)采用如圖9 所示的流程,通過遞歸調(diào)用的方法完成切割任務(wù),并最終返回一個(gè)存儲(chǔ)CutBodyStruct類型結(jié)構(gòu)體的集合作為切割結(jié)果。流程如下:
圖9 BrowseOccurrence()函數(shù)執(zhí)行流程Fig.9 Implementation process of Browse Occurrence()function
(1)使用CATIPLMNavOccurrence 接口,以被切割體根節(jié)點(diǎn)物理產(chǎn)品的實(shí)例(Instance)為輸入?yún)?shù),首先從該參數(shù)獲取所有子節(jié)點(diǎn)Instance,及與根節(jié)點(diǎn)直接相關(guān)的3DShape。
(2) 使 用 上 一 節(jié) 介 紹 的RecursionGetCutBodys()函數(shù),從 3DShape 中獲取待切割拓?fù)潴w的集合,放入OriCutBodyList當(dāng)中。
(3)分別在切割面數(shù)目和OriCutBodyList 集合數(shù)目范圍內(nèi)執(zhí)行循環(huán),循環(huán)體內(nèi),使用第i個(gè)切割面切割OriCutBodyList 集合中的第j個(gè)成員。切割結(jié)束后,更新OriCutBodyList 集合。在第i+1 次循環(huán)體當(dāng)中,切割對象變成第i 次循環(huán)生成的最新OriCutBodyList集合。
(4)依次以當(dāng)前根節(jié)點(diǎn)的所有子節(jié)點(diǎn)Instance 為輸入?yún)?shù),遞歸調(diào)用BrowseOccurrence()函數(shù),當(dāng)某個(gè)子節(jié)點(diǎn)instance 不再包含子節(jié)點(diǎn)時(shí),遞歸調(diào)用滿足終止條件。
對被切割體施加上一個(gè)小節(jié)介紹的BrowseOccurrence()函數(shù),可以生成一個(gè)以CutBodyStruct 類型結(jié)構(gòu)體集合代表的切割結(jié)果,但是集合中的每一個(gè)結(jié)構(gòu)體僅存儲(chǔ)了切割后的拓?fù)潴w,必須要將這些拓?fù)潴w轉(zhuǎn)換為特征并存儲(chǔ)在相應(yīng)的物理產(chǎn)品下才能作為真正的BIM交付物。
本小節(jié)介紹的CreateNewCutObjectProduct()函數(shù)以集合中的一個(gè)CutBodyStruct類型結(jié)構(gòu)體作為輸入?yún)?shù),處理方法是:
首先從輸入?yún)?shù)結(jié)構(gòu)體中抽取出spOccOnCurrentNode成員,使用CATAdpDuplicator接口的Duplicate()方法,復(fù)制出一個(gè)新的物理產(chǎn)品的參考(Reference),采用復(fù)制的方法,能夠保證物理產(chǎn)品類型和屬性的一致性。再使用CATIPLMProducts接口的AddProduct()方法,將復(fù)制結(jié)果添加到用戶選擇的目標(biāo)裝配體位置。
對于輸入?yún)?shù)結(jié)構(gòu)體中的BodyList 成員,使用 CATIMmiUseDatumFactory 接口的 Instanciate Datum()方法,將拓?fù)潴w變成輕量化、不可編輯的的Datum 類型特征,并插入到復(fù)制后生成的物理產(chǎn)品中。
在結(jié)構(gòu)體集合范圍內(nèi)循環(huán)調(diào)用這個(gè)函數(shù)后,就能夠在目標(biāo)裝配體下生成與切割結(jié)果數(shù)目相應(yīng)的若干物理產(chǎn)品,并且每個(gè)物理產(chǎn)品中都包含相應(yīng)的特征結(jié)果。
本文介紹了一種通過達(dá)索/CAA 二次開發(fā)實(shí)現(xiàn)橋墩BIM切割的工具。該切割工具的作用是將橋墩分節(jié)段澆筑導(dǎo)致BIM模型變化的主動(dòng)權(quán)交給施工單位,由施工單位根據(jù)現(xiàn)場具體情況快速、方便地修改模型。
本文繼而從“獲取切割面、被切割體、目標(biāo)位置”“遍歷、存儲(chǔ)被切割體”“生成切割結(jié)果并組裝至目標(biāo)位置”三個(gè)方面重點(diǎn)介紹了程序的開發(fā)策略和思路。
“獲取切割面、被切割體、目標(biāo)位置”,從本質(zhì)上就是用戶與程序界面的交互。在這個(gè)交互功能的實(shí)現(xiàn)中,借助Add-in 的方式添加工具條,并通過命令狀態(tài)(Command State)和代理(Agent)兩個(gè)關(guān)鍵元素來實(shí)現(xiàn)用戶與界面的交互響應(yīng)。
“遍歷、存儲(chǔ)被切割體”一節(jié)中,分析了被切割體所具有的一種復(fù)雜樹型組成結(jié)構(gòu),RecursionGetCutBodys()作為一個(gè)遞歸調(diào)用函數(shù),以一個(gè)3DShape 作為輸入?yún)?shù),獲取其中的被切割拓?fù)潴w,輸出并存儲(chǔ)于一個(gè)CATLISTP(CATBody)類型的集合中。
為了實(shí)現(xiàn)“生成切割結(jié)果并組裝至目標(biāo)位置”的目的,首先使用BrowseOccurrence()函數(shù),以被切割體根節(jié)點(diǎn)做為輸入?yún)?shù),輸出一個(gè)用于存儲(chǔ)CutBodyStruct 類型結(jié)構(gòu)體的集合。本函數(shù)也是遞歸函數(shù),當(dāng)根節(jié)點(diǎn)物理產(chǎn)品下仍然存在物理產(chǎn)品子節(jié)點(diǎn)時(shí),繼續(xù)對子節(jié)點(diǎn)施加本函數(shù)。最后,通過CreateNewCutObjectProduct () 函 數(shù) , 以CutBodyStruct 類型結(jié)構(gòu)體為輸入?yún)?shù),生成可以代表切割結(jié)果的物理產(chǎn)品并插入目標(biāo)裝配位置。