朱歡麗 姚浩 陳哲
1. 中國(guó)電建集團(tuán)華東勘測(cè)設(shè)計(jì)研究院有限公司 浙江 杭州 311122;2. 浙江華東工程數(shù)字技術(shù)有限公司 浙江 杭州 311122
數(shù)字孿生是一種近年來快速發(fā)展的技術(shù),它可以將實(shí)體物體的真實(shí)數(shù)據(jù)轉(zhuǎn)化為數(shù)字化的虛擬模型,從而實(shí)現(xiàn)對(duì)其進(jìn)行仿真和分析。數(shù)字孿生圖形引擎作為數(shù)字孿生技術(shù)的重要應(yīng)用之一,可以提供精確、高效的圖形模擬和可視化效果,是數(shù)字孿生技術(shù)不可或缺的關(guān)鍵技術(shù)。
然而,面對(duì)數(shù)字孿生技術(shù)的快速增長(zhǎng)和市場(chǎng)需求的變化,數(shù)字孿生圖形引擎的應(yīng)用程序越來越多,這些應(yīng)用程序和平臺(tái)之間存在互相獨(dú)立的特點(diǎn),導(dǎo)致它們難以互相交互和兼容,這顯然會(huì)影響數(shù)字孿生技術(shù)的應(yīng)用效果和發(fā)展。因此,實(shí)現(xiàn)數(shù)字孿生多維融合圖形引擎中的標(biāo)準(zhǔn)化接口的設(shè)計(jì)成為當(dāng)前的一個(gè)實(shí)用的研究方向。
數(shù)字孿生圖形引擎是一種復(fù)雜的維數(shù)據(jù)的可視化引擎系統(tǒng),它通常需要包含復(fù)雜的數(shù)據(jù)結(jié)構(gòu)、算法和大量的可視化技術(shù)。針對(duì)這種復(fù)雜性,相應(yīng)的應(yīng)用程序可能會(huì)使用不同的技術(shù)和算法,導(dǎo)致它們無法互相交互和兼容[1]。這使得數(shù)字孿生多維圖形引擎中的應(yīng)用程序很難被其他應(yīng)用程序所重復(fù)利用和擴(kuò)展。通過整合引擎接口的統(tǒng)一,可以在應(yīng)用層面解決以上問題。
實(shí)現(xiàn)多個(gè)圖形引擎之間統(tǒng)一,一般有如下5個(gè)步驟[2]:①定義接口標(biāo)準(zhǔn):首先需要明確各個(gè)圖形引擎之間需要融合的共同點(diǎn),包括數(shù)據(jù)格式、功能、參數(shù)等,根據(jù)這些共同點(diǎn)定義接口標(biāo)準(zhǔn)。②實(shí)現(xiàn)適配器:針對(duì)不同的圖形引擎實(shí)現(xiàn)不同的適配器,將各個(gè)圖形引擎的接口轉(zhuǎn)化為通用的接口,以便實(shí)現(xiàn)融合。③實(shí)現(xiàn)橋接器:將適配器組合起來,形成一個(gè)橋接器,通過橋接器將多個(gè)圖形引擎適配器連接起來。④實(shí)現(xiàn)融合邏輯:根據(jù)實(shí)際需求,設(shè)計(jì)具體的融合邏輯,利用橋接器將多個(gè)圖形引擎的功能組合起來,實(shí)現(xiàn)多個(gè)圖形引擎的融合。⑤測(cè)試和優(yōu)化:進(jìn)行全面測(cè)試和優(yōu)化,確保融合接口的穩(wěn)定性、可靠性和性能。
總的來說,多個(gè)圖形引擎之間的融合需要進(jìn)行詳細(xì)的接口設(shè)計(jì)和實(shí)現(xiàn),需要充分考慮各種因素,包括數(shù)據(jù)格式、功能、參數(shù)等。同時(shí),需要進(jìn)行大量的測(cè)試和優(yōu)化工作,確保融合結(jié)果穩(wěn)定、可靠。
一般情況下,如果要在不同的場(chǎng)景下執(zhí)行相同的代碼以獲取相同的功能輸出,可以使用條件判斷語句(如if-else或switchcase)在函數(shù)內(nèi)部根據(jù)場(chǎng)景執(zhí)行相應(yīng)的代碼。但隨著場(chǎng)景和功能模塊的增多,這種方式會(huì)導(dǎo)致代碼變得冗長(zhǎng)且難以維護(hù)。
可以采用分模塊模式和適配器模式解決以上問題。按照引擎劃分模塊,每個(gè)模塊負(fù)責(zé)實(shí)現(xiàn)一個(gè)引擎的功能,模塊之間相互獨(dú)立,但是又遵循相同的規(guī)范(函數(shù)名、傳參、返回值)來實(shí)現(xiàn)對(duì)應(yīng)的功能[3]。這樣,每個(gè)模塊就可以獨(dú)立開發(fā)和維護(hù)。最后,通過一個(gè)控制類來進(jìn)行模塊控制和操作流程的控制。
具體實(shí)現(xiàn)中還會(huì)用到策略模式,即每個(gè)子模塊都有一個(gè)用來管理子模塊的策略類,每個(gè)策略類都實(shí)現(xiàn)了相同的接口。同時(shí),還建議使用標(biāo)準(zhǔn)化的數(shù)據(jù)格式,如JSON。通過使用JSON作為場(chǎng)景加載數(shù)據(jù)的標(biāo)準(zhǔn)格式,可以簡(jiǎn)化數(shù)據(jù)的解析和處理。這樣,在不同的場(chǎng)景下,我們只需要使用不同的JSON數(shù)據(jù)來加載對(duì)應(yīng)的模塊即可。
在實(shí)際編程中,我們應(yīng)該注重代碼的可讀性、可維護(hù)性、可擴(kuò)展性和可復(fù)用性。控制類SampleApp實(shí)現(xiàn)示例如下:

在控制類中,SampleApp.open()函數(shù)采用了策略模式,通過傳入標(biāo)準(zhǔn)化的場(chǎng)景加載參數(shù),調(diào)用SampleApp.getScene(),獲取對(duì)應(yīng)的場(chǎng)景策略類,獲取該模塊的控制入口。然后將該控制入口交給SampleApp.Scene代理,最終通過代理執(zhí)行子模塊open()方法加載對(duì)應(yīng)場(chǎng)景。SampleApp.Scene作為子模塊的代理,使用了代理模式,在后續(xù)操作中可以很方便地操作子模塊,同時(shí)還增強(qiáng)了系統(tǒng)的可擴(kuò)展性和靈活性。
引擎中的組成部分可以劃分為兩個(gè)部分:工具和API。API提供了執(zhí)行操作或返回所需內(nèi)容的接口,而工具則是通過鼠標(biāo)等輸入設(shè)備與場(chǎng)景進(jìn)行交互,以實(shí)現(xiàn)操作和輸出的交互方式。工具是API的一種應(yīng)用場(chǎng)景,例如測(cè)量、剖切等,使得與場(chǎng)景進(jìn)行交互更為便捷。
工具是指用于與場(chǎng)景進(jìn)行交互的功能模塊,如測(cè)量和剖切。這些工具可以啟動(dòng)和銷毀,因此在工具的父類Tool中,我們可以定義抽象函數(shù)start和cancel,并由子類進(jìn)行繼承和重寫以實(shí)現(xiàn)工具的啟動(dòng)和結(jié)束。為了在工具啟動(dòng)前和結(jié)束后能夠執(zhí)行一些操作,我們?cè)黾恿藃un和end函數(shù),在這兩個(gè)函數(shù)中去執(zhí)行相關(guān)操作。這樣的設(shè)計(jì)可以采用模板方法模式,將具體實(shí)現(xiàn)交給子類,同時(shí)保證父類中的算法結(jié)構(gòu)不變。同時(shí),將工具類抽象出來,利用工廠方法模式創(chuàng)建具體的工具實(shí)例,以實(shí)現(xiàn)靈活的工具管理和使用。示例代碼如下:

在實(shí)現(xiàn)具體工具時(shí),除了繼承實(shí)現(xiàn)父類中定義的抽象函數(shù):?jiǎn)?dòng)和結(jié)束,還需要為該類添加一個(gè)靜態(tài)屬性toolId,用于標(biāo)識(shí)工具的唯一ID。這個(gè)ID將作為工具注冊(cè)和獲取的關(guān)鍵信息,可以通過工具注冊(cè)類實(shí)現(xiàn)注冊(cè)和獲取功能。工具代碼示例如下:


我們可以通過工具注冊(cè)類來管理工具。在這個(gè)類中,我們將所有的工具維護(hù)在一個(gè)映射集合中,使用工具的唯一標(biāo)識(shí)toolId作為映射的鍵值,將工具實(shí)現(xiàn)類作為映射的值記錄進(jìn)map集合中。當(dāng)我們需要運(yùn)行某個(gè)工具時(shí),可以通過SampleApp.tools.run(toolId)方法獲取對(duì)應(yīng)的工具實(shí)例,然后執(zhí)行工具內(nèi)部的run方法,該方法默認(rèn)繼承自工具父類。使用工具注冊(cè)類的優(yōu)點(diǎn)在于可以動(dòng)態(tài)添加和刪除工具,從而更好地管理和維護(hù)工具集合。另外,工具的具體實(shí)現(xiàn)和管理被分離,增強(qiáng)了系統(tǒng)的可擴(kuò)展性和可維護(hù)性。工具注冊(cè)類實(shí)現(xiàn)示例如下:

在設(shè)計(jì)類似功能的API時(shí),不同的引擎有不同的設(shè)計(jì)方式,例如參數(shù)和返回值,這將導(dǎo)致很大的差異。因此,實(shí)現(xiàn)標(biāo)準(zhǔn)化API對(duì)提高Web端多維圖形引擎的效率和質(zhì)量至關(guān)重要。
在具體實(shí)施中,為了實(shí)現(xiàn)標(biāo)準(zhǔn)化接口,按照相同的函數(shù)名、參數(shù)形式和返回值來設(shè)計(jì)不同子模塊中的API。以三維引擎中常用的相機(jī)為例,即使每個(gè)引擎采用的坐標(biāo)系相同,但對(duì)API的開放程度和實(shí)現(xiàn)上也有很大差別。為了解決這一問題,在每個(gè)子模塊的Camera類中,需要統(tǒng)一實(shí)現(xiàn)獲取相機(jī)參數(shù)的方法getCameraParams。該方法不需要入?yún)ⅲ祷亟Y(jié)果需要統(tǒng)一,使用通用的經(jīng)緯度作為坐標(biāo)的格式,并將弧度制作為角度的單位格式,以保證返回值數(shù)據(jù)格式的統(tǒng)一。對(duì)應(yīng)的設(shè)置相機(jī)參數(shù)方法稱為flyTo,它只接收getCameraParams返回的數(shù)據(jù)格式,在函數(shù)將其轉(zhuǎn)換為當(dāng)前引擎所需的數(shù)據(jù)類型。至此,在后續(xù)使用中,可以執(zhí)行同一行代碼來獲取或設(shè)置相機(jī)參數(shù),不必考慮打開的是哪個(gè)引擎的場(chǎng)景。下面是相機(jī)類的實(shí)現(xiàn)示例:

在Web端對(duì)多種圖形引擎進(jìn)行標(biāo)準(zhǔn)化接口設(shè)計(jì)對(duì)數(shù)字化項(xiàng)目的研發(fā)和實(shí)施有很多實(shí)際意義。通過標(biāo)準(zhǔn)化接口,降低二次開發(fā)人員的引擎接口的學(xué)習(xí)成本,提高引擎接口的兼容性,提升開發(fā)效率和質(zhì)量。同時(shí)一致的接口,一致的前端組件,還可以統(tǒng)一系統(tǒng)的UI和交互,提高用戶體驗(yàn)。