• 沒有找到結果。

發展以利IFC應用開發的SDK框架

N/A
N/A
Protected

Academic year: 2022

Share "發展以利IFC應用開發的SDK框架"

Copied!
49
0
0

加載中.... (立即查看全文)

全文

(1)

國立台灣大學工學院土木工程學系 碩士論文

Department of Civil Engineering College of Engineering

National Taiwan University Master Thesis

發展以利 IFC 應用開發的 SDK 框架

An SDK framework to facilitate development of IFC applications

張澤中

Ze-Zhong Zhang

指導教授:謝尚賢 博士

Advisor: Shang-Hsien Hsieh, Ph.D.

中華民國 106 年 6 月

June 2017

(2)

I

國立臺灣大學碩士學位論文

口試委員會審定書

發展以利 IFC 開發的 SDK 框架

An SDK framework to facilitate IFC development

本論文係張澤中君( R04521612)在國立臺灣大學土木工 程學系、所完成之碩士學位論文,於民國 106 年 5 月 15 日承 下列考試委員審查通過及口試及格,特此證明

口試委員:

謝 尚 賢

(指導教授)

陳 鴻 銘

吳 翌 禎

系主任 謝 尚 賢

(3)

II

誌謝

IFC 一開始并不是我研究的課題。最初我想構建一套基於脚本的模型查驗系統

(Model Checker),但實際上僅以查驗功能而言類似的系統有很多,做的也更好,

專門再搞一門脚本語言完全就是過度設計,所以研究不可避免地進入了死角。在 我尋找新研究題目的那段時間,銘祥有一天下午閑聊時對我説“你爲何不去研究 IFC,結構蠻複雜的,這方面的論文又很少”,讓我走上了現在這條路。

初看 IFC 的結構確實很複雜,IFC Schema 是用 EXPRESS 寫的,而 EXPRESS 語法又是一個要花錢才能看到的 ISO 標準,導致新手的 IFC 應用之路異常坎坷。

感謝 ifcjavatoolbox 和 IfcOpenShell 這些開源工程,給了初學者一絲學習 IFC 的希 望(雖然它們本身也很難)。

隨著研究的深入,且和業界人士交流多了以後,我發現 IFC 的應用前景并不 如之前想象的那麽美好:相關研究匱乏,官方文檔不完善(幾乎等於沒有),業 界大廠比如 Autodesk 對其的支持力度也沒有以前那麽高。感謝謝老師的鼓勵給了 我繼續進行下去的動力和方向。

最後感謝所有在 IFC 領域内奮鬥的人們。現在我們能夠享受各種支持 IFC 檔 案的軟體帶來的工作便利,正是源于他們背後對 IFC 格式的研究與支持。這不是 一個輕鬆的工作,我對堅持于這個領域的開發工程師們表示尊敬。

張澤中 于 水源

(4)

III

摘要

工業基礎分類(IFC)是建築資訊塑模(BIM)領域中非常重要的一種模型交 換格式,因其被設計爲可以同時儲存建築的幾何和非幾何資訊,相較于其它 3D 模 型格式具有明顯的優勢而被廣汎應用。但一直以來 IFC 的應用完全依靠于各個建 築、工程、施工(AEC)廠商的軟體支持,其複雜的結構和相對缺乏的文檔阻礙 了一般用戶對它進行第三方開發,市面上僅有的一些 IFC 庫也衹是負責解析 IFC 格式而已,繁重的後續任務任需由使用者承擔。這樣的現狀明顯不利于 IFC 生態 環境的發展。

本文在深入研究了 IFC 格式的基礎上,對 IFC 的對象層級和使用邏輯進行了 大量的簡化,構築了一個使用者友好的軟體開發套件(SDK)框架。相較與普通 的 IFC 庫,本 SDK 不僅在解析速度上更快,在藉助 IDE 的情況下,用戶在進行開 發時效率也更高。这其中:1)優化了 IFC 的層級,降低了使用者的學習成本;2)

引入了 Planning 模式,簡化了元件的查找過程;3)在優化后的層級上,又針對非 幾何資料的 API 做了優化。

本文希望通過提出這個 SDK 框架,緩解 IFC 在整個 BIM 環境中應用廣汎但 二次開發動力不足的情況。

關鍵字:工業基礎分類,建築資訊塑模,軟體開發套件,應用程式介面

(5)

IV

Abstract

Industry Foundation Class (IFC) models serve as a key feature in Building Information Modeling (BIM), whose schema can store both geometric and non-geometric data and all the relationships between them, a non-negligible advantage compared with other 3D formats.

But from the first day IFC was drafted, it seemed to be only adapted among professional Architecture Engineering Construction (AEC) programs and few users were interested in third-party developments due to the complexity of IFC schema and the lack of detailed documentations. Even with the help from some IFC libraries, users still have to do their own intermediate works messing about the structure of IFC. All these lead to the awkward situation of IFC.

This research comes up with an user-friendly IFC Software Development Kit (SDK) framework specifically designed for average end users, which: 1) simplifies the hierarchy of IFC so it is easier to learn; 2) introduces “Planning” so it is easier to query instances and 3) implements map interface for non-geometric data so it is easier to manipulate. Also with any modern Java IDE, it is easier to program.

I hope this SDK can lower the barrier of developing and extending IFC functions for inexperienced developers, therefore the awkward situation of IFC could be likely eased.

Keywords: IFC,BIM,SDK,API

(6)

V

目錄

口試委員會審定書...I 誌謝...II 中文摘要... III 英文摘要...IV 圖目錄...VII 表目錄... VIII

第一章 前言... 1

1.1 研究背景... 3

1.2 研究目的... 4

1.3 基本術語... 5

1.4 程式碼授權... 6

1.5 使用手冊... 6

第二章 IFC 格式基礎...7

第三章 IFC 解析器的實現...10

3.1 雜凑... 10

3.2 可擴展數組... 13

3.3 快速實例化... 16

3.4 簡易錯誤檢查... 18

3.5 性能... 18

第四章 IFC 層級簡化...20

4.1 舊有層級的局限... 21

(7)

VI

4.2 新層級... 22

第五章 IFC 實例查找...24

5.1 模型查詢語言研究回顧... 24

5.2 查詢模式 Planning...25

第六章 IFC 實例編輯...30

6.1 幾何參數編輯... 30

6.2 非幾何參數編輯... 32

第七章 實際應用... 34

第八章 結論... 38

参考文献... 39

(8)

VII

圖目錄

圖 1 IFC 作爲交換模型的連接作用...2

圖 2 獲取 IFC 實例幾何外觀的程式碼(Brep 情況下)... 4

圖 3 模型内部斷行... 9

圖 4 解析器工作流程... 10

圖 5 模型空值率... 15

圖 6 等待佇列工作原理... 17

圖 7 兩種 IFC 層級概念...20

圖 8 本文使用圖例... 20

圖 9 從 IFC 牆中獲取屬性資料...22

圖 10 新 IFC 層級...22

圖 11 IDE 關鍵字自動補全和聯想功能...25

圖 12 OpenSCAD...31

圖 13 Dynamo... 31

(9)

VIII

表目錄

表 1 中英文歧義術語對照表... 5 表 2 省略的 COBie 欄目... 37

(10)

1

第一章 前言

工業基礎分類,即 Industry Foundation Class(簡稱 IFC)標準形成於 1994 年,

是由 BuildingSMART(前身 International Alliance for Interoperability)主導並維護 的用於描述工業模型及其附加數據資料的開放格式。其主要目標是通過統一的模 型 交 換 檔 格 式 標 準 提 升 建 築 、 工 程 和 施 工 ( Architecture, Engineering and Construction,簡稱 AEC)人員的協同工作能力,現在已經發展成最為主流的,應 用於建築資訊塑模(Building Information Modeling,簡稱 BIM)領域內的通用格式

(Laakso et al., 2012)。

根據 BuildingSMART 官方公佈的資訊, CAD 業界的大部分廠商 ——如 Autodesk 、 Bentley 、 Graphisoft—— 旗 下 軟 體 均 已 通 過 IFC 標 準 的 認 證

(BuildingSMART,2017)。而在英國正在推進的 BIM Level2 階段裏也規定了最 終模型交付時,推薦附有 IFC 模型和原始工程模型(Project Information Model)如 rvt 檔(British Standards Institution, 2013),美國總務署在其 BIM 手冊中亦規定了 必須附有 IFC 模型的類似要求(U.S. General Services Administration, 2011)。

IFC 模型的廣泛應用主要歸功於其開放性。在傳統的二維平面設計時代,所有 的 CAD 圖可以列印成冊儲存保管,所以大部分機構并不會多考慮電腦上的 CAD 檔案幾十年后的儲存問題。但在 BIM 時代,列印 3D 模型到圖紙上並沒有太大意 義,如何電子化儲存模型逐漸變得重要起來。IFC 作為開放格式不依賴於任何人或 組織,也不受限於特定軟體,且從設計之初就是為了儲存建築物的 3D 幾何資訊和 非幾何資訊,沒有上述的問題,受到廣泛應用。

而另一方面,建築設計流程裏涉及到的軟體眾多,各軟體之間需要交換模型 的情況不在少數。假設 5 家公司旗下的軟體之間需要兩兩交換模型,那麼他們就

(11)

2

需要開發 20 套插件來實現這個功能,這是不可想像的工作量,且出於商業目的考 慮,他們也不一定願意這麼做。而作為中間格式的 IFC 標準的出現,讓各家公司 可以先專注於自己的軟體與 IFC 格式的交互功能的開發,當他們通過了 IFC 的認 證的時候,則相當於其軟體具備了與其他所有 IFC 認證軟體的模型交換功能,這 樣大大減輕了他們在交互性方面的工作量。

圖 1 IFC 作爲交換模型的連接作用

IFC 現在已發展至 IFC4 Add2 版本,按照時間順序排列即 IFC 第 7 版。但現在 支持最為廣泛,資料最多的版本是 IFC2x3 TC1,本文的研究亦基於其之上。IFC 的架構經過常年發展已經沉澱,所以兩個版本之間的更新内容僅限于類別的增減 和一些 bug 的修復1,對研究的影響甚小。下文開始所有涉及 IFC 的字樣均指代 IFC2x3 版,不再贅述。

1 http://www.buildingsmart-tech.org/implementation/ifc4-implementation/ifc4-vs.-ifc2x3-1

(12)

3

1.1 研究背景

本文將 IFC 的“應用”分爲兩類:一是模型交付後的設施維護(Facility Management,簡稱 FM)領域和設計階段的模型交換領域内的應用,如在 Tekla 内 設計鋼結構細節并匯出爲 IFC,再將其匯入 Revit 進行進一步操作。這一類情景里 IFC 衹是充當了信息交換的角色。

另一類則是本研究重點討論的“IFC 應用開發”:即用戶不局限于已有軟體,

而是按照自己的需求開發相關的基於 IFC 模型的擴展功能。例如將 IFC 模型轉換 爲某 3D 模型格式但市面上尚沒有相關的轉換工具的情況,又或者用戶需要一個小 型 IFC 管理軟體但外包給專業開發公司過於小題大做的情況,等等。一般來說這 些情況需要用戶具有一定的編寫程式的能力,而 BuildingSMART 和其他第三方廠 商也確實發佈了一些 IFC 庫(IFC Library)如 ifcjavatoolbox2和 IfcOpenShell3幫助 用戶解析編輯 IFC 模型,用戶藉助這些 IFC 庫完全可以完成上述(但不限于)提 到的“IFC 應用開發”。

但這些 IFC 庫無一例外都是非常底層的,它們僅僅是將純文字編碼的模型解 析成記憶體内結構化的資料,用戶拿到結構體(如 struct 或 class)后還需要大量的 IFC 相關知識才能使用。可是 IFC 發展至今(2017 年)其最新版本裏官方定義的 類別和類型就已經有 800 餘種,類別之間的繼承關係、選擇類別裏的枚舉、關係 鏈接(Relationship)等約束條件更是異常繁雜,要求一個普通用戶去學習這些知 識是不現實的,但這些細節確確實實地貫穿于 IFC 的整個開發流程,讓用戶不得 不去瞭解它們。而且即便在瞭解的前提下,用程式碼實現 IFC 的邏輯也是非常臃 腫的(如圖 2)。

2 http://www.ifctoolsproject.com/

3 http://ifcopenshell.org/

(13)

4

圖 2 獲取 IFC 實例幾何外觀的程式碼(Brep 情況下)

而另一方面,絕大部分關於 IFC 應用開發的論文都更注重于最終應用“結果”

的研究,而很少談及實現結果的“過程”——因爲它們有些使用了世面上已有的 IFC 庫或解析器,有些則是自己從零實現程式碼解析 IFC,但無論是前者或後者,

“過程”都不是研究的重點而是手段。這也是爲什麽截至本文成稿,尚沒有論文 對 IFC SDK 進行過研究。

(注:一些商業軟體會抽象 IFC 的結構以契合其内部的物件結構和使用邏輯,

從另一個角度來講,這樣的抽象化等效于 IFC SDK,但考慮到閉源的前提,這些 軟體不在本研究範圍内。同理如 EDMmodelServer4或 IFC Engine DLL5之類的 IFC 庫雖然亦有自己的 IFC API 簡化操作,但其原始碼無法從公開渠道獲得,且 IFC Engine 的 API 爲指令式,與本研究内容差別較大,故不予考慮。)

1.2 研究目的

本文認為 Revit 的成功不僅是依靠於 Autodesk 強大的市場號召力,也是因為 他們設計了一套門檻較低的 Revit API,讓廣大入門級的工程師也可以對 Revit 的

4 http://www.jotneit.no/edmmodelserver-ifc

5 http://www.ifcbrowser.org/

(14)

5

功能進行擴展,而這正是 IFC 目前所欠缺的。基於“授人以魚不如授人以漁”的 思想,本研究的目的是希望通過實現一個用戶友好的軟體開發套件(Software Development Kit,簡稱 SDK)來簡化 IFC 模型的相關操作,降低初學者的入門門 檻,減輕使用者的重複勞動,以利 IFC 應用開發。本文認爲涉及 IFC 的操作衹有 兩種:一是從模型中提取用戶想要信息的唯讀操作,一是修改模型内部資料的寫 操作。故本 SDK 最終將實現以下 4 點,其中 1、2 點爲 3、4 點的前提條件:

1) IFC 模型的解析 2) IFC 層級的優化

3) IFC 模型內部實例查找 4) IFC 模型內部實例編輯

并最終通過一個從 IFC 中提取 COBie 相關資料的實例演示 SDK 的基本功能。

1.3 基本術語

本文里反復使用的中文術語與其英文的對照如表 1,其中會有多個英文單詞對 應同一個中文單詞的情況,其具體含義依上下文而不同,本文亦會在有歧義的地 方特別注明。

表 1 中英文歧義術語對照表

英文 中文 英文 中文

Entity IFC 類別、類 Attribute 屬性、參數 Class Java 類別、類別類 Realization 實現

Argument 參數(具有值) Utility 應用、實現

Parameter 參數、參數名

(15)

6

本文中涉及到英文字元時,使用了兩種字體:

1)Times New Roman,表示一般英文的字體 2)Consolas,特別用於表達程式碼的字體

1.4 程式碼授權

本研究的 SDK 原始碼托管于 https://github.com/coyove/IfcLibrary,其使用了 ifcjavatoolbox 的 Java 類別庫。ifcjavatoolbox 使用了 CC BY-NC-SA 3.06協議,本 SDK 使用了 GPLv27協議。

對本文的引用遵循一般標準;對本 SDK 及 ifcjavatoolbox 的商業使用需要獲得 ifctoolsproject 的許可。

1.5 使用手冊

本 SDK 的用戶使用手冊需用戶自行使用 javadoc 生成:

javadoc -cp ./src -d ./javadoc org.ifc.toolkit

6 http://creativecommons.org/licenses/by-nc-sa/3.0/de/deed.en/

7 https://www.gnu.org/licenses/gpl-3.0.odt

(16)

7

第二章 IFC 格式基礎

一個 IFC 模型本質是一個 STEP(Standard for the Exchange of Product Data)檔,

而 STEP 的具體標準在 ISO-10303 中定義。該標準並不免費公開,但本文基于公开 的文檔(Loffredo, 1999),以 BNF(Backus Naur Form8)形式對 STEP 的語法進 行了總結:

<step-file>______::= 'ISO-10303-21;\n' _____________________<header-section>

_____________________<data-section>

<header-section>_::= 'HEADER;'

_____________________('\n' <header>){3}

_____________________'\nENDSEC;'

<header>_________::= ('FILE_DESCRIPTION' ____________________|_'FILE_NAME'

____________________|_'FILE_SCHEMA') <parameter-list> ';'

<data-section>___::= 'DATA;'

_____________________('\n' <instance> ('\n' <instance>)*)?

_____________________'\nENDSEC;'

<instance>_______::= <instance-ref> '=' <ifc-entity> <list> ';'

<instance-ref>___::= '#' <instance-number>

<instance-number>::= <naturals>

<list>___________::= '(' <argument> (',' <argument>)* ')'

<argument>_______::= <ifc-entity>? <list>

___________________|_<instance-ref>

___________________|_<null>

___________________|_<string>

___________________|_<integer>

8 https://en.wikipedia.org/wiki/Backus%E2%80%93Naur_form

(17)

8

___________________|_<double>

___________________|_<enum>

<ifc-entity>_____::= <identifier>

<null>___________::= '$' | '*'

<string>_________::= '\'' ([\x00-\x26\x28-\x7F] | '\'\'')* '\''

<integer>________::= ('-'? <naturals>) | 0

<naturals>_______::= [1-9] [0-9]*

<double>_________::= '-'? ([0-9]? '.' [0-9]+ | [0-9]+ '.') __________________________([eE] '-'? [0-9]+)?

<enum>___________::= '.' <identifier> '.'

<identifier>_____::= [A-Z] [A-Z0-9]*

BNF 是一種用於表示上下文無關的形式語言,專門用於描述程式語言語法,

例如以下產生式:

<instance-number> ::= <naturals>

<naturals>_______ ::= [1-9] [0-9]*

<integer>________ ::= ('-'? <naturals>) | 0

代表實例名稱(<instance-number>)由自然數(<naturals>)組成,而自然數 的定義爲 0~9 數字的排列組合,且第一位不能爲 0;整數(<integer>)的定義爲 自然數、負號+自然數、零。“+0”和“-0”的形式是非法的。

需要注意的是上述 BNF 省略了空格(space),這是因為大部分軟體匯出的 IFC 模型裏只有等於號(“=”)後面和字串內部會有空格。但實際上在 STEP 檔中,

有些地方的空格可以忽略或隨意增加,有些則不可以。各個廠商的實現方法不同,

(18)

9

所以本文沒有在 BNF 裏做限制,但本 IFC 解析器實現會考慮到任意地方出現空格 的可能性。

另外各個 IFC 解析器對於換行符(“\n”)的處理也不盡相同。如 ArchiCAD 匯出的 IFC 模型會控制每行的字元數,如果一個實例的參數表長度大於 70~80 個 字元的話會被自動換行,這樣一來就會出現一個實例佔據了多行的情況(圖 3)。

此時<list>的正確定義應為:

圖 3 模型内部斷行

<list> ::= '(' <argument> (',' '\n'? <argument>)* ')'

本文為了敘述簡便,只討論一個實例占一行的情況,但本研究最終實現的解 析器依舊考慮了上述特殊形式。

最後如果用較為簡單的話概括 IFC 格式就是:一個 STEP 檔由元數據段

<header-section>和數據段<data-section>組成,元數據段定義了 IFC 模型的 三種元數據:檔案名、模型描述和使用的 IFC Schema 版本;數據段按行分割,每 一行代表一個實例。如果把官方發佈的 IFC Schema 比作 C++裏的頭檔(Header File),那麼 IFC 模型則是原始檔案(Source File),每一行定義的實例可以看作 是變數,每個實例擁有一個模型內唯一的編號<instance-number>作為名字,該 標號為正整數。

(19)

10

第三章 IFC 解析器的實現

本 SDK 使用的 IFC 解析器來自于本文作者之前的研究(Zhang et al.,2017),

該解析器使用了 ifcjavatoolbox 里的 IFC Schema 類別庫,并實現了一個高效的解析 前端,本章將在接下來幾節對該解析器的優化細節進行更爲深入的討論。IFC 模型 的解析可以以圖 4 概括。

圖 4 解析器工作流程

在讀入 IFC 檔後,首先程式通過詞法器(Lexer)將其分割成多個 Token,其 中實例編號(Instance Number)、實例引用(Instance Reference)和 IFC 類別名(Entity Name)最為重要:類別名告訴了程式該調用什麼 Java 類別進行構建,而實例的編 號則是唯一的,實例引用正是通過這個編號才能引用到其他實例。當然上圖是高 度簡化過後的示意,本章將在接下來的幾節中詳細討論其中的一些問題。

3.1 雜凑

在詞法階段,我們獲得了 Token,其由兩部分組成:Token 類型和 Token 值,

比如一個 IFC 類別名的 Token,其類型是 EntityName,(就上例而言)其值是

(20)

11

IFCPERSON,但很明顯,這個值是一個字元型(String),所以我們並不能直接使 用 new 操作符構建類,所以通常的一個簡單做法是:

// Initialize factory

Map<String, Class> factory = new HashMap<>();

factory.put("IFCPERSON", IfcPerson.class);

// During parsing

IfcPerson person = factory.get("IFCPERSON").newInstance(…);

這是軟體設計模式中常見的工廠模式(Factory Pattern),我們使用一個 Key-Value 容器作為工廠,當我們獲得一個類型為 EntityName 的 Token 後,我們 用它的值在工廠裏尋找對應的類型類(Class),類型類是 Java 反射(Reflection)

裏的基礎,其擁有一個特別的方法 newInstance 來構造對應的類別。這樣我們就通 過一個字串構建出了對應的類別。

考慮本文在第三章所著的 BNF,其中的<ifc-entity>即代表著類型為 EntityName 的 Token,其定義為:

<ifc-entity> ::= [A-Z] [A-Z0-9]*

這裏我們假設了 IFC 的類別名是由大寫字母和數字組成的,所以對於工廠容 器我們使用了 String 作為它的 Key。但實際上 IFC 的類別名是有限的,所以

<ifc-entity>其實也可以寫成如下形式:

<ifc-entity> ::= 'IFCPERSON' | 'IFCDIRECTION' | …

(21)

12

有限的組合意味著我們並不一定需要依賴於 HashMap 這類容器。如果可以把 IFC 裏 849 個類別名映射成正整數的話,我們就可以將其儲存於數組之中。數組的 訪問可以認為是恒定 O(1)的,這樣解析器的性能相較於 HashMap 的版本會有非常 大的提升。而為了將 String 映射為 Integer,我們需要找到一個合適的雜凑函數,

且符合以下兩個條件:

1)產生的雜凑沒有碰撞

2)最小雜凑值和最大雜凑值的差值應儘量小,848 是最優解 例如 Java 中 String 的雜凑函數偽代碼如下:

set hash = 0

for each character in string

____hash = hash * 31 + ascii(character) end for

在回圈內部,每一輪雜凑值都會乘上一個質數 31,所以最終的雜凑值也會隨 著字串的長度成幾何級數增加(並溢出)。這樣保證了當我們雜凑字串時,針對 兩個只有微小差別的字串(長度差 1 或者只有一個字母不同等情況),最後得到 的雜凑值差別會非常大,這確保了雜凑的離散性。ascii 函數是獲得字元

(character)ASCII 數值的函數。

但是本研究設計的雜凑需要盡可能地減少離散性,使最終的雜凑分佈在一個 很小的範圍內,以下是實現代碼:

set hash = 0

(22)

13

for each character in string

____hash = hash + VALUE(character) * 13 ____hash = hash xor 0x16ADA

end for

hash = hash / 2

其中係數降為了 13,且移到了與字元值相乘的地方,這樣雜凑的增長速度就 會降低,但碰撞的幾率也大幅增加,於是在每次計算後,雜凑值會再跟 0x16ADA

(10110101011011010)進行一次異或(xor)計算,這次操作相當於打亂雜凑值的 各個比特位。

上述演算法中“2”,“13”和“0x16ADA”三個值由窮舉而來。

最終用該雜凑函數雜凑 849 個類別名,得到的 849 個雜凑值的範圍在 0~65000 之間。我們構建一個長度為 65000 的數組,將各個類型類按照其對應的雜凑值放 入該數組,則大約還剩 64200 個空值,它們浪費了 500KiB 左右的記憶體,但我們 認為此種浪費的程度在現代電腦上完全可以接受。

3.2 可擴展數組

如同一般的程式語言一樣,IFC 模型的每個實例都要有自己的名字,也就是我 們所說的實例編號。考察以下片段:

#4692875= IFCPROPERTYSET('1w46N3aqXDgflkE91KriAK',#41,…);

#4692877= IFCRELDEFINESBYPROPERTIES('1Hwq42Jnf1e8MaXnNoMs0a',…);

#4692881= IFCAXIS2PLACEMENT3D(#6,$,$);

#4794946= IFCRELAGGREGATES('3o9c2jHPz0UgvyZpd1xn_J',#41,…);

#4692883= IFCCARTESIANPOINT((-5991.,-3463.,0.));

(23)

14

#4692885= IFCAXIS2PLACEMENT3D(#4693703,$,$);

#4692886= IFCLOCALPLACEMENT(#2100123,#4692885);

這是一段來自於某 IFC 模型內部的代碼(已做簡化),實例起始編號 4692875,

結束編號 4692886。但是從中我們可以看出:

1)一個 IFC 模型內部的實例編號呈遞增態勢,但數字不一定連續

2)在極少數情況下,編號甚至是亂序的,如上文中:…#4692881#4794946

#4692883 #4692885…

當我們已經構建好相應的實例後,我們需要將它與實例編號聯繫在一起並儲 存。如果實例編號是連續的,那我們大可以使用 List 儲存它們,但考慮到不連續 性,ifcjavatoolbox 採用了 TreeMap,其理由非常簡單:不同於 HashMap,TreeMap 的鍵值(Key)是有序的,所以當 ifcjavatoolbox 完全解析完 IFC 模型,將它們添 加進 TreeMap 後進行遍曆(Iteration),鍵值已經按照從 1 開始到最大編號的順序 排好,且因為 TreeMap 的性質,在插入新數據時並不需要關心順序,這一點非常 符合解析 IFC 模型的需求。

但本研究認為 List 或數組依舊可以應用在這種不連續或亂序的情況下。在設 計解析器時,我們專門引入了一個新容器 ArrayEx 來儲存實例,ArrayEx 是一個非 常簡單的線性儲存容器(類似於 ArrayList),其底層也是一個數組。但是當我們 向其添加元素時,可以使用任意正整數當作索引,也不需要考慮先後順序,底層 的數組會自動擴容至目標長度:

// Java native implementation List a = new ArrayList();

a.add(new IfcEntity1());

(24)

15

a.add(new IfcEntity2());

a.set(3, new IfcEntity3()); // wrong, IndexOutOfRangeException

// Our parser

ArrayEx a = new ArrayEx();

a.add(0, new IfcEntity1());

a.add(3, new IfcEntity2()); // ok a.add(1, new IfcEntity3()); // ok

使用數組的優勢前文已經說明,但是需要注意的是,因為實例編號的不連續 性,使用 TreeMap 的樹結構不會浪費空間,而 ArrayEx 裏則會存在大量的 null 值。

為此本研究對 95 個 IFC 模型進行了簡單統計,如圖 5。

圖 5 模型空值率

該圖的縱軸代表每個模型的空值率(Inflation Ratio),這個值等於每個模型解 析後最大的實例編號除以全部實例個數的值。可以發現該值不過 1.8,我們以近似 2.0 算,也就是說對於任意具有 N 個實例的模型,使用 ArrayEx 作為底層容器儲存,

其長度不超過 2N,其中不到 N 個 null 值,相當於在 64bit 的電腦上浪費了 8×N 位元組的空間。但考慮到使用 TreeMap 容器時必須用 Integer 類型作為 Key,而 N 個 Integer 耗費的記憶體遠多於 8×N 位元組,所以 ArrayEx 依舊有很大的優勢。

(25)

16

3.3 快速實例化

如果我們再次回顧圖 4,可以發現在解析階段構建實際類別時,如果實例引用 了其他實例,我們就需要使用:

model.getInstance(number)

來獲得那個類別,然後才能將其作為參數構建實例,最後通過:

model.addInstance(number, instance)

將新實例添加進模型。但是解析器是按照從左至右,從上而下的順序讀取實例的,

所以請考慮如下情況:

// Case 1

#1= IFCENTITY1(#2);

#2= IFCENTITY2(…);

// Case 2

#2= IFCENTITY2(#1);

#1= IFCENTITY1(…);

以上兩者均存在向後引用(Backward Reference)的情況,即當解析第一行時,

model.getInstance 無法獲得對應實例,因為那個實例必須在稍後解析到第二行

時才能被添加進 model。

為了解決這個問題,ifcjavatoolbox 的方法是對模型先做第一遍解析,把實例 初始化到一個中間狀態並添加進 model,此時每個實例雖然已經被實例化,但它

(26)

17

們都還沒有參數,所以稱之為中間狀態;然後 ifcjavatoolbox 遍曆 model 實例集合,

將每個實例需要的參數填入到其參數表中,這裏會用到 model.getInstance,但 因爲此時所有實例都已經存在於記憶體中,對它們的引用也是有效的,故不存在 向後引用的問題。但很明顯的是這個方法需要一次解析一次遍曆,第二次遍曆還 是以遞歸形式進行的,所以耗時頗多。

本解析器則是在第一遍解析的時候就完全實例化所有沒有向後引用的實例。

對於存在向後引用的實例,則將它們初始化至等待狀態,然後插入到等待佇列

(Waiting Queue)中。這樣第二遍解析時,解析器只需要遍曆等待佇列即可。而

“等待狀態”是指構建類別時,對於參數中存在的向後引用,用其對應的空類別 代替。第二次遍歷時,這些空類別會被替換為實際類別。這個過程可用圖 6 表示。

圖 6 等待佇列工作原理

一般的 IFC 模型中向後引用的情況是少數,所以相較於 ifcjavatoolbox 遍曆兩 邊的做法,本解析器使用等待佇列可以在絕大部分的情況下獲得更加優秀的性能 表現。

(27)

18

3.4 簡易錯誤檢查

本研究的 IFC 解析器放棄了詳細錯誤檢查,用戶可以選擇忽略錯誤強行解析。

這不同於一般程式語言的編譯器,它們在發現錯誤時會給出詳細的錯誤檢查資訊:

如錯誤代碼,錯誤位置,錯誤原因,甚至是改正建議9等,而本 IFC 解析器並不具 備這些功能——在發現錯誤後其至多只能給出錯誤位置的資訊。

本文認為在解析 IFC 模型時處理錯誤并產生詳細信息給用戶是毫無意義的,

還會拖慢速度。從另一個角度來說,對於 IFC 模型的除錯(Debug)本身也不現實。

因為一般的 IFC 模型動輒就有數萬實例,這意味著其 STEP 檔的內容至少也有 相應的數萬行,這遠遠超出了人類可讀範圍內的程式碼檔所應該包含的行數。所 以即便在解析時其中某一個實例發生錯誤而解析器給出了錯誤原因,用戶也沒有 可能手動進行 Debug,在這種情況下,用戶只能選擇修改源模型再重新匯出或忽略 錯誤繼續解析。

另一方面,大部分支持匯出 IFC 模型的軟體都是經過 BuildingSMART 認證的,

其產生的模型除非遭到破壞性修改(如在網路中傳輸到一半被迫中止導致檔案只 有一半內容),理論上不應該產生任何語法錯誤。

基於這樣的前提,本解析器放棄了詳細錯誤檢查以提高解析速度。

3.5 性能

優化后的本 IFC 解析器性能達到了 ifcjavatoolbox 的 10 倍以上(Zhang et al.,

2017),處於業界領先位置,對於 IFC4 的支持也在論證和研究當中。高效的解析 器是 SDK 的基礎,且用戶在使用 SDK 編寫程式、debug 的過程中,反復讀取 IFC

9 如 https://hackage.haskell.org/package/hlint

(28)

19

模型是不可避免的動作,過慢的 IFC 解析速度會讓用戶耗費大量時間在無意義的 等待上面,所以任何一點在解析速度上的提升都可以大幅提高用戶體驗。

(29)

20

第四章 IFC 層級簡化

本研究中提到的 IFC 層級分為兩種:一是各個類別之間因繼承派生關係而產 生的層級,如:IfcWall → IfcBuildingElement → IfcElement,二是每個類別都有自己 的一組參數,其中每個參數相對於該類別也產生了層級(從屬)關係,如每個 IfcProduct 都具有參數 GlobalId,我們可以用 UML10(圖 7)來表示這樣的關係。

圖 7 兩種 IFC 層級概念

但從下文開始爲了排版簡潔將不繼續使用 UML 圖而改用如圖 8 的圖例:

圖 8 本文使用圖例

10 統一塑模語言(Unified Modeling Language)

(30)

21

4.1 舊有層級的局限

IFC 裏的層級是一個複雜的概念,但究其原因並不是它們“層級太深”而複雜

(事實上 IFC 物件層級最深衹有 7 層,大部分爲一兩層,相較于 Apache Batik11等 SDK 是完全可以接受),而是因為 STEP 檔裏每一行是一個實例,他們之間並沒 有嵌套而是自上而下線性平鋪的關係,所以複雜——以圖 9 爲例,IFC 裏的非幾何 資料並不會嵌套在元件裏(即出現在參數表裏),而是一個單獨的類別 IfcProperty,

兩者是同級的,為了表明它們之間的從屬關係,IFC 只好引入了關係鏈接的概念:

通過第三個類別 IfcRelDefines 將參數連接到元件身上。

如果我們使用XML或 json之類天生可以表達嵌套關係的語言來描述上述例子 的話會非常簡單,但在 IFC 裏需要三個類別才能正確表示這樣的關係,其他的例 子更是不勝枚舉,由此稱其為“複雜”。

(注:STEP 語法允許直接嵌套,比如:

// Case 1

#1= IFCTEXT('Hello World');

#2= IFCENTITY(#1);

// Case 2

#1= IFCENTITY(IFCTEXT('Hello World'));

以上兩者是理論等價的(但不一定每個 IFC 解析器都支持),但考慮到相容性、

一些實例會被大量複用的情況(比如 IfcPlacement)和基本的設計模式,第一種方 法是主流。)

11 https://xmlgraphics.apache.org/batik/javadoc/overview-tree.html

(31)

22

圖 9 從 IFC 牆中獲取屬性資料

4.2 新層級

從易用性的角度來說,IFC 的層級必須優化甚至重新設計,但從實際應用環境 和向前相容性的角度來說,這是不可能的。本研究的 SDK 在不改動原有 IFC Schema 的前提下,重新實現了一套新的層級,對 IFC 的內部類別進行了包裹(Wrap),

例如 Wall 對應 IFC 裏的 IfcWall 和 IfcWallStandardCase(在 IFC4 中已廢除),Column 對應 IfcColumn。但是它們的層級關係更加簡單,如圖 10。

圖 10 新 IFC 層級

(32)

23

在重新設計的層級中,所有的類別均由 Element 派生而來,這點與 Revit API 類似,比如 Project 類代表 IFC 模型,類似於 Revit API 中的 Document,Property 類別代表一組屬性,其可以包含單個或多個非幾何資訊,GeoElement 代表具有幾 何 形 狀 的 元 件 , 如 門 、 窗 , 它 們 具 有 兩 個 基 本 方 法 : getLocalGeometry 和 getGeometry,前者是獲得元件在本地坐標系下的 3D 網格面片,後者是獲得元件 在世界坐標系下的面片;SpatialElement 代表可以承載或包含其他幾何元件的空間 幾何體,如房間、樓層。

理論上牆體亦可以劃進空間幾何體(因為可以包含窗)的範疇,如在 Revit API 中 Wall 派生於 HostObjects(可包含其他對象),但在 IFC 中 IfcWall 並不派生於 IfcSpatialStructureElement,在這一點上本文認為遵循 IFC 的設計邏輯並無不妥。

(33)

24

第五章 IFC 實例查找

用戶在沒有可視化介面(GUI)幫助的前提下,通過自行編寫程式從模型中選 擇需要的元件是非常困難的,這種困難體現在兩個方面:一是因為沒有交互介面,

用戶沒有有效的手段直接找到自己想要的元件,只能通過 GUID、實例 ID、實例 名和類別名等間接過濾手段;一是即便用戶知道自己該如何找到所需的元件,通 過程式實現也要相當多的邏輯。

解決這類問題的方法,一般是針對物件模型的架構設計專門的模型查詢語言

(Model Query Language)來簡化其中的過程。

5.1 模型查詢語言研究回顧

目前已有一些論文討論過基於 IFC 模型的查詢語言(Query Language)的設計,

如 Graph Query(Tauscher et al., 2016),BIMQL(Mazairac et al., 2013),QL4BIM

(Daum et al., 2015),但是本文認為引入一門新的語言或概念會增加 SDK 不必要 的複雜性,是一件需要慎重考慮的事。

當我們將一門程式語言應用到實際工作時,最關心的應該是該語言的生態環 境,比如第三方庫的支持、有無整合開發環境(Integrated Development Environment,

簡稱 IDE)和完善的文檔。Revit API 選用.NET 作為主要的開發語言,正是綜合考 慮了上面幾點才做出的決定。而現在大部分提出的 IFC 模型和通用模型查詢語言,

無一不是語法怪異,缺少文檔,晦澀難學,且缺乏 IDE 的支持,對於用戶來說非 常不友好。

在這之中我們尤其認為 IDE 佔據了主要的地位。如前文所述 IFC 的層級非常 複雜,在缺乏 IDE 有效的關鍵字自動補全(Intellisense)的情況下(圖 11),使

(34)

25

用者必須完全依靠經驗來操作 IFC 元件和其屬性,這無形中又大大提高了 IFC 編 程的成本。

圖 11 IDE 關鍵字自動補全和聯想功能

5.2 查詢模式 Planning

本研究參考了 LINQ 和 Java Stream 的設計模式,引入了一種邏輯上相對簡單 的查詢模式,稱之為 Planning,其既可以實現按 ID 查找,按類別過濾等基本功能,

也可以實現按樓層劃分,按屬性劃分等較爲複雜功能。Planning 基於 Java 實現,

所以市面上任何 Java IDE 都可以對其提供優秀的支持。如:

for (Element elm : Planning ___________________.from(model)

___________________.select(Wall.class)

___________________.withProperty("ExtendToStructure")) { ____// do something with elm

}

表示選中模型中所有帶有 ExtendToStructure 屬性的牆,而:

(35)

26

for (Element elm : Planning ___________________.from(model)

___________________.select(Wall.class, Slab.class) ___________________.onStorey("b1")) {

____// do something with elm }

表示選中所有在“b1”樓的牆和樓板。兩個 Planning 亦可以鏈接起來,如:

Planning p1 = Planning.from(model).select(Wall.class);

Planning p2 = Planning.from(model).select(Slab.class);

Planning p3 = p1.or(p2);

表示在執行 p3 時,過濾條件是選擇牆或(or)板。

Planning 裏涉及到名稱查找時均使用了基於 Levenshtein Distance 的字串模糊 匹配的方式進行搜索,即 Planning 首先以全文匹配的方式查找元件,失敗後使用 模糊匹配的方式重新查找,這樣用戶不必嚴格輸入文本也可以獲得大概結果,如

“b1”、“b-1”、“B1”等輸入都可以指代名字為“b1”的地下一樓樓層。

Planning 本身是一個疊代器,其默認疊代模型里的所有實例,而用戶可以向其 中串聯過濾條件來縮小疊代範圍(交集),多個 Planning 可以并聯爲一個 Planning

(聯集),亦可以對單個 Planning 取反(差集)。Planning 的設計理念是鼓勵使用 者構建一個完整的 Planning(選擇邏輯),執行并得到自己想要的物件,然後對這 些物件操作。這樣用於獲得物件的程式碼和用於編輯物件的程式碼不會混在一起,

從視覺觀感和可維護性的角度來説更好。

(36)

27

所以說 Planning 的設計就是其内部提供的過濾條件的設計,簡單的條件比如 按 ID 過濾,按名稱過濾等不必贅述,對於非常複雜的過濾條件該如何設計是本研 究的討論重點:根據“複雜”的程度不同,有些過濾條件并不適合 Planning。比如:

// In one query expression but it is complex for (Element elm : Planning

___________________.from(model)

___________________.select(Wall.class)

___________________.withMinimumWindows(1)) { ____// do something with elm

}

// We think this is more expressive for (Element elm : Planning

___________________.from(model)

___________________.select(Wall.class)) { ____Wall wall = (Wall) elm;

____if (wall.getWindows().length > 0) { ________// this wall has windows inside ____}

}

上述兩者是針對“牆體內部是否開窗”來過濾的高級判別式的不同設計,本研究 傾向于後者的設計思路,因爲前者中的 withMinimumWindows 存在過度設計

(Overengineering)的問題,具體原因有兩點:

1)該函數存在兩個條件:最小值(Minimum)和窗體(Window),這樣勢 必意味著 Planning 需要設計 withMaximumWindows,考慮到墻體内還會存在門,

(37)

28

洞,管綫等構件,所以還必須設計 withMaximumDoors,withMaximumHoles……這 樣 Planning 的功能過於臃腫。

2)不僅是墻内可以存在窗體,板也可以(天窗),房間也可以(房間包含墻),

而事實上 IFC 并沒有規定窗必須存在于特定元件中。但沒有相關知識的一般使用 者會自然地認爲 withMinimumWindows 衹適用于墻,所以以下程式碼:

Planning.from(model).onStorey("b1").withMinimumWindows(1) // may returns Wall, Space, Door …

對他們來説會產生未預料結果(Unexpected Results),因為 Planning 可能返回了 牆以外的物件,而使用者並沒有實現對它們進行處理的程式碼。

綜上所述,本研究選擇了后一種設計方法,其它的過濾條件也都考慮了類似 的前提。截至成稿,Planning 中設計完成的過濾條件如下:

1)select:選擇單個或多個類別;

2)from:從模型中選擇;

3)withId:選擇具有特定 ID 的實例;

4)withGuid:選擇具有特定 GUID 的實例;

5)withGeometry:選擇具有幾何外觀的實例;

6)onStorey:選擇某樓層上的實例;

7)onStoreyRange:選擇從某層到某層上的全部實例;

8)inSpace:選擇某空間内的實例;

9)inBuilding:選擇某建築物内的實例;

10)withProperty:選擇具有特定屬性的實例;

(38)

29

11)connectedTo:選擇與特定實例有連接的實例(如墻對墻,墻對門,墻對 空間等);

12)or:并聯其它 Planning 過濾條件。如果兩個 Planning 均 from 同一個 IFC 模型,第二個可以省略 from:

Planning p1 = Planning.from(model).select(…);

Planning p2 = Planning.onStorey(…); // also from model Planning p3 = p1.or(p2);

若兩個 Planning 各自 from 不同的模型,則 or 會執行兩個 Planning 的疊代器得到兩 個結果,并合并成一個列表:

Planning p1 = Planning.from(model_1).select(…);

Planning p2 = Planning.from(model_2).select(…);

Planning p3 = p1.or(p2);

// equivalent to:

List<Element> p3 = p1.toList().addAll(p2.toList());

此時 p3 已經失去疊代器的意義,退化成一個列表。

(39)

30

第六章 IFC 實例編輯

一直以來對於 IFC 模型的編輯問題,業界內的討論較少。這主要是因為 IFC 作為交換模型本身需要修改的情境不多,即便需要修改,也是在上游軟體內先完 成,再重新匯出為 IFC。雖然 STEP 的最初設計是考慮到人類可讀可改的,但是隨 著 IFC 標準發展到現在,其複雜的結構早已使編輯變得非常棘手。

但即便是少數情況,具備 IFC 模型修改的能力也是非常必須的,例如設施運 營維護時,針對某個特定元件新增的資料屬性參數,該值並不一定需要回到源模 型中,但如果沒有相應的 IFC 編輯能力,維護人員只能:

1)修改源模型添加該值再匯出為新的 IFC 模型;

2)將該值存儲於其他容器如資料庫或 Excel。

這兩種方法,一個是變動了源模型,且重新匯出費時費力;另一個需要依靠外部 容器,增加了運營成本。

6.1 幾何參數編輯

對於幾何模型的編輯,本文認為難度較大,但這並不是從 SDK 設計角度而言 的難度,而是與前一章開頭提到的 GUI 有關——即在沒有圖形介面的情況下,用 戶通過程式創建、修改 3D 網格面片模型是極其複雜的,這種複雜性包含兩點:

1)用戶需要具備基本的圖形學的知識。雖然用戶並不需要親自實現各種相關 函數,但至少它們需要懂得每個函數是幹什麼的才能調用;

2)就算最終生成模型,也還是要依靠 GUI 介面才能展現。特地只使用程式碼 修改 3D 模型的行為本身並沒有太大意義。

(40)

31

目前市面上確實存在一些“程式化模型編輯軟體”,比如 Dynamo12(圖 12)

和 OpenSCAD13(圖 13)。但需要注意的是它們並不是嚴格意義上的“SDK”而 是一套“工具”。從設計理念上來說,SDK 並不等價於工具——工具應該是基於 SDK 的更高級的應用。

圖 12 OpenSCAD 圖 13 Dynamo

本研究的 SDK 只提供了四個基本的 API 進行操作:

1)replaceGeometry:用某個已經存在的模型的多邊形網格替換另一個元件的 網格。如用戶新建一面牆,則做法是構建一面空牆,再將一面已有的牆的幾何外 觀複製到該空牆上,或從 obj、ifc 等外部模型導入網格作為其外觀。

2)descendToBoundingBox:降低模型面數。即使用一個立方體替換原有元件 的 3D 網格,該立方體三維尺寸等同於原元件的邊界範圍(Bounding Box)。

3)descendToMesh:對於 IFC 内定義的參數幾何外觀(擠出 Extrude、掃掠 Sweep 等),將其轉變爲純粹的多邊形網格。

4)transform:改變模型在坐標系中的位置,位置(Location)資訊包含:位 移(Translation)、旋轉(Rotation)和縮放(Scale)。

12 http://dynamobim.org/

13 http://www.openscad.org/

(41)

32

對於一些特殊情況,比如任何具有 IfcExtrudedAreaSoild 外觀的幾何體,用戶 可以修改擠出(Extrude)高度;對於 IfcProfileDef 裏的常規曲線比如矩形,圓,

用戶也可以編輯其中的一些參數。

本 SDK 提供了 Mesh、Face、Vector、Matrix 等涉及圖形學的基礎類別,但不 會承擔上述 API 以外的更為複雜的模型編輯功能。

6.2 非幾何參數編輯

對於非幾何資料的編輯主要基於 IFC 的 IfcProperty 類別,但如前文所述,IFC 裏屬性參數是不附加在元件身上的而是通過關係鏈接,所以 SDK 裏專門提供了 Property 類別抽象化 IfcProperty 以及關係鏈接 IfcRelDefines。

Property 本身是一個 Key-Value 容器,代理儲存了原來在 IfcSimpleProperty 裏 的參數資訊。使用了 Property 以後,對於參數的獲取、增添和刪除就變成了 Java 內 置 的 Map 容 器 的 get 、 add 和 remove , 其 中 key 是 String 類 型 , value 是 Property.Value 類型。這簡化了程式邏輯,也極大地減輕了用戶的負擔,如以下示 例程式碼演示了獲取墻的 Phase 參數,并修改爲 2。

Wall w = Planning.from(model).select(Wall.class).toList().get(0);

Property.Value phase = w.getProperty().get("Phase");

phase.setValue(2);

w.getProperty().put("Phase", phase);

但這其中存在不少特殊情況需要處理,比如房間(Space)的面積(Area)等 相關參數,它們由 IfcElementQuantity 記錄,該類別是 IfcProperty 的子類別,但是

(42)

33

在 SDK 中這些參數的操作并不會由 Property 類別處理,而是交由 Space 類別内部 的專門獲取函數(Getter)如 getArea。這樣的設計考慮了兩點:

1)Property.Value 是可修改的(Mutable),但不改變幾何外觀而直接修改面 積、體積等幾何參數并沒有太大意義。所以 SDK 不用 Property 類別封裝這些參數,

同時也衹提供 Getter 函數而不提供 Setter。

2)在某些情況下,從軟體匯出的 IFC 里的 IfcSpace 實例并沒有對應的 IfcElementQuantity 參數,但空間的面積體積等幾何參數是確實存在的,所以 getArea 仍會基於其幾何形狀計算一個近似值。

最後,SDK 裏的非抽象類別(即不是 Element、GeoElement、SpatialElement 的類別)都可以實例化,這一點設計不同於 Revit API。在 Revit 的 API 中,我們 所看到的 Element 及其派生類別並不真實存在——它們的底層是 ElementProxy。因 为 Revit 主程式裏的元件基於 C++,API 必须通過 ElementProxy(C++/CLI)將它 們與 C#裏的元件關聯起來,所以在 Revit API 中并不能實例化一面墻(new Wall),

而是必須由 Revit 主程式建立一面墻,然後用 API“獲得”它。但从物件导向的理 念来说,这样的设计不符合用户直觉。本研究并不需要考慮兩種語言之間物件傳 遞的問題,SDK 的設計也盡量貼合了語義表達:

Wall w = new Wall("new wall");

w.replaceGeometry(anotherWall.getGeometry()).transform(…);

model.addElement(w);

上述程式碼構建了一面新牆,名稱為“new wall”,其幾何外觀從另一面牆複製,

最後該牆被添加進模型中。

(43)

34

第七章 實際應用

施 工 運 營 建 築 信 息 交 換 ( Construction Operations Building Information Exchange,簡稱 COBie)是由美國陸軍工兵單位于 2007 年提出的一種用於營建工 程專案資料交換的格式(East et al., 2007),目前已經被很多 BIM 標準接受,是與 IFC 同等重要的用於運營維護階段的標準。

嚴格來説 COBie 是 IFC 的子集,其存在的目的是爲了簡化 IFC 并提取出其中 用於設施管理的非幾何資料,如設備(System),樓層(Floor),區域(Zone)

等。COBie 資料存儲與 Excel 内部,COBie Worksheet 對應 Excel 裏的表單(Sheet)。

每一張表單即爲 COBie 的一個品類,裏面包含了通用的欄目,如名稱(Name)等,

和每個品類的特殊欄目,如對於 Floor 品類,其擁有層高(Height)等參數。對於 每一個參數,COBie 使用固定的顔色定義其重要程度,如黃色爲必填參數,橙色 爲引用其他表單的參數,綠色爲用戶定義的必須參數。

COBie 的分類與 IFC 内的類別存在對應的關係,如 System 對應 IfcSystem,Floor 對應 IfcBuildingStorey,Zone 是特例,其可能對應單個或多個 IfcSpace。這些對應 關係即 Model View Definition14(簡稱 MVD),我們基於官方給出的 MVD15和本 研究的 SDK,即可以自行編寫程式將 IFC 匯出爲 COBie。流程如下,首先我們讀 入 IFC 模型:

IfcModel model = new IfcModel();

model.readStepFile(new FileInputStream("file path …"));

解析完成后,我們需要獲得模型中的實例,以樓層爲例:

14 http://www.buildingsmart-tech.org/specifications/ifc-view-definition

15 http://docs.buildingsmartalliance.org/MVD_COBIE/

(44)

35

List<Element> floors = Planning.from(model)

_______________________________.select(Storey.class) _______________________________.toList();

需要注意的是 IFC 里的樓層并沒有層高的信息,所以這裏我們需要手動計算。首 先對所有樓層按離地海拔(Elevation)進行從小到大的排序:

TreeMap<Double, Storey> sorting = new TreeMap<>();

for (Element floor : floors)

____sorting.put(((Storey) floor).getElevation(), (Storey) floor);

然後遍歷 sorting,每一層的層高即爲上一層的海拔減去本層的海拔:

Map<Storey, Double> heights = new HashMap<>();

Iterator iter = sorting.entrySet().iterator();

Map.Entry<Double, Storey> floor = iter.next();

while (iter.hasNext()) {

____Map.Entry<Double, Storey> f = iter.next();

____heights.put(floor.getValue(), f.getKey() - floor.getKey());

____floor = f;

}

heights.put(floor.getValue(), 0.0);

然後我們可以正式開始向 Excel 寫入資料,以下程式碼忽略了 Excel 排版的部分:

(45)

36

for (Element elm : floors) { ____Storey s = (Storey) elm;

____String name = s.getName();

____String createdBy = "";

____String createdOn = currentDate();

____String category = "Floor";

____String extSystem = "Autodesk";

____String extObject = "樓層";

____String extIdentifier = "";

____String description = s.getDescription();

____double elevation = s.getElevation();

____double height = heights.get(s);

____// write to excel sheet … }

其它類別的操作與上述過程類似,但因爲 IFC 模型内缺少相應資料,我們省略了 一些表單内的欄目内容(用空值代替),如表 2。

(46)

37

表 2 省略的 COBie 欄目

CreatedBy CreatedOn SerialNumber InstallationDate WarrantyStartDate TagNumber BarCode AssetIdentifier RoomTag

Category Company Phone

Department OrganizationCode GivenName

FamilyName Street PostalBox

Town StateRegion PostalCode

Country Ext 開頭的欄目 External 開頭的欄目

(47)

38

第八章 結論

同一份程式碼內不做兩件複雜工作是模組化的基本原則,而 SDK 正是為此而 存在的。在本研究之前,市面上存在的 IFC 庫并不會對 IFC 對象進行封裝,它們 直接曝露底層的做法讓用戶必須同時處理 IFC 的複雜層級和他們自己的程式邏輯 兩件事,這樣不僅程式的可讀性會降低,潛在的性能陷阱出現的風險也大大提高

(如反復遍歷一個大模型)。

本研究提出了一個操作 IFC 的基本 SDK 框架,將大量的邏輯細節隱藏進了可 復用的程式碼中,而向用戶呈現了一組相對簡單明瞭的 API;Planning 的出現,亦 是從另一個方面優化了 IFC 模型内實例的查找過程,幫助使用者規避了一些性能 陷阱。由於 IFC 架構本身設計的限制,其中還有一些細節需要完善,但它在速度,

易用性等方面已經展現出了非常大的潛力。

雖然隱藏過多的細節可能不利于用戶瞭解 IFC 背後的詳細機制,但本文認爲 現實的狀況是 IFC 背後過於複雜的機制已經成爲阻擋絕大多數用戶將 IFC 應用到 實際環境中的重要原因,在無法修改 IFC Schema 的情況下,使用 SDK 將其完全 抽象化是十分必要的。

在 SDK 的幫助下,使用者可以專注于自己的業務邏輯——比如本文第七章中 的 COBie 示例,其絕大部分的程式碼都在處理 Excel 的排版,而涉及到 IFC 的地 方均是非常簡單的語句——這樣操作 IFC 的成本大大降低,從另一個角度來説,

也就是門檻降低。讓更多用戶可以進行 IFC 的相關開發,才有可能緩解 IFC 尷尬 的現狀,這也就是本研究的追求。

(48)

39

参考文献

Abbott, E. L. S., Yeoh, K. and Chua, D. K. H., 2015, “Formalizing a Language for Specifying Building Components from IFC”, proceedings of the 6th International Conference on Engineering, Project, and Production Management at Queensland, Australia on September 2-4, 2015.

BuildingSMART, 2017, “List of certified and participating software products”, from http://www.buildingsmart-tech.org/certification, accessed on June 1, 2017.

British Standards Institution, 2013, “PAS 1192-2:2013 Specification for information management for the capital/delivery phase of construction projects using building information modelling”.

Daum, S., Borrmann, A. and Kolbe, T. H., 2015, “A Spatio-semantic Query Language for the Integrated Analysis of City Models and Building Information Models”, Advances in 3D Geoinformation, Springer Publishing, pp. 79-93.

East, E. W., 2007, “Construction Operations Building Information Exchange (COBIE), Requirements Definition and Pilot Implementation Standard”, U.S. Army Engineer Research and Development Center.

Laakso, M. and Kiviniemi, A., 2012, “The IFC standard: A review of History, development, and standardization”, journal of ITcon, vol. 17, pp. 134-161.

Loffredo, D., 1999, “Fundamentals of STEP Implementation”, STEP Tools, Inc.

Mazairac, W. and Beetz, J., 2013, “BIMQL - An open query language for building information models”, journal of Advanced Engineering Informatics, vol. 27, pp.

444-456.

(49)

40

Marguerie, F., Eichert, S. and Wooley, J., 2008, LINQ in Action, Manning Press.

Tauscher, E., Bargstädt, H. J. and Smarsly, K., 2016, “Generic BIM queries based on the IFC object model using graph theory”, proceedings of the 16th International Conference on Computing in Civil and Building Engineering at Osaka, Japan on July 6-8, 2016.

U.S. General Services Administration, 2011, “BIM Guide For Facility Management”, pp. 8.

Zhang, Z. Z. and Hsieh, S. H., 2017, “A domain-specific approach to speeding up IFC parsing”, proceedings of the 3rd International Conference on Civil and Building Engineering Informatics at Taipei, Taiwan on April 19-21, 2017.

數據

表 1 中英文歧義術語對照表.......................................................................................
圖 4 解析器工作流程
圖 7 兩種 IFC 層級概念
圖 10 新 IFC 層級
+3

參考文獻

相關文件

This study will use BIM, Web-base, RFID, Wireless Network, ER Model, Database and Information Technology environment to develop “Electronic Building Construction

Li, “Concurrent engineering: a strategy for procuring construction projects,” International Journal of Project Management, Vol. Towill and D.R., “Time compression and supply chain

(1999), “Relationship Marketing and Data Quality Management," SAM Advanced Management Journal, Vol. (2004), “The Role of Multichannel Integration in Customer

development of AutoLISP programming language for building and into Knowledge Engineering (Knowledge Based Engineering, KBE) technology, the ball screw and linear guideway the use

Y., (1997), “Resource recovery of sludge as building and construction materials — a future trend in sludge management,” Journal of Water Science and Technology, Vol. J.,

Sheu, 2006, “Integrating Multivariate Engineering Process Control and Multivariate Statistical Control,” International Journal of Advanced Manufacturing Technology 29, 129-136.

Business Information Technology Unit Development &amp; Construction Division Housing Department, “Building Information Modelling (BIM) User Guide for Development and

Y., (1999), “Examining the technology acceptance model using physician acceptance of telemedicine technology,” Journal of Management Information Systems, Vol. and Baroudi,