原創做者:flowell,轉載請標明出處:http://www.javashuo.com/article/p-zercrwgn-r.htmlhtml
IFC是建築信息模型(BIM)數據開放的國際標準,在建築行業或設施管理行業的各個參與者使用的軟件應用程序之間做爲中間媒介交換和共享。該標準涵蓋建築物生命週期所需數據的定義和管理流程,對建築信息進行有組織的高效管理。node
對於本文而言,IFC更重要的特性之一即是IFC做爲一種平臺中立的開放文件格式規範,不受單個供應商或供應商組的控制。它是一種基於對象的文件格式,具備由特殊組織BuildingSMART(之前稱爲國際互操做性聯盟,IAI)開發的數據模型,以促進組織架構,工程和構造(AEC)行業中的互操做性,而且是建築信息中經常使用的協做格式。基於建築建模(BIM)的項目。這意味着IFC模型規範是開放的而且是可重用的。研究IFC格式對於增強不一樣行業的建模或是不一樣建模軟件之間的交流都有極爲重要的意義。設計模式
例如,因爲丹麥政府專一於軟件平臺之間的互操做性,所以丹麥政府已將IFC格式強制用於公共輔助建築項目。此外,芬蘭國有設施管理公司Senate Properties要求在全部項目中使用IFC兼容軟件和BIM。[3]挪威政府,衛生和國防客戶組織也要求在全部項目中使用IFC BIM,以及許多市政當局,私人客戶,承包商和設計師在其業務中整合了IFC BIM。IFC做爲一種通用的建模信息交流中間媒介,在建築建模和模型展現之間起到了承上啓下的重要意義。數組
IFC能夠以多種格式編碼,每種格式都具備軟件支持,可伸縮性和可讀性的益處和權衡。這些格式表示數據如何以電子形式編碼。因爲建築數據可能很是大(即千兆字節),所以格式的選擇可能具備實際考慮因素。本文參考的IFC文件是基於Revit項目導出的IFC文件,具備.ifc拓展名的後綴,是IFC在實踐中使用最普遍的格式,同時也是做爲文本讀取的格式中最緊湊的格式,而且還具備最大的兼容性和支持性。架構
IFC數據以對象實例爲結點構成層次結構,其中全部可識別對象都派生自IfcRoot類。每一個對象都有一個128位數字(GUID)形式的GlobalID,它永遠不會在整個生命週期中發生變化,一個用於人類識別的名稱(Name)或將在施工計劃中顯示的名稱,一個用於捕獲雜項信息的描述(Description),以及一個可使用的全部者歷史記錄(Tag)。指示對象的建立和最後修改的對象,時間和方式,以及指示鎖定狀態和合並狀態(建立,修改,刪除或無更改)的版本控制屬性。IFC中的實體(Entity)涵蓋了建築生命流程中所必需的絕大部分元素,包括IfcActor,表示承包商或建築物佔用者等我的或組織。IfcControl表示指令,例如工單,許可,工做計劃或投標提交。IfcGroup表示相關產品的集合,例如機械系統。IfcProduct表示在空間中構件的實例,例如物理產品或建築物中的房間。IfcProcess指示當時發生的事情,例如任務或事件。IfcResource表示使用材料,人工或設備等可用性有限的東西。IfcRelationShip表示對象是如何組織起來的,如彙集,包含,鏈接,依賴等概念上或空間上的組織關係。由於本文關注的是BIM三維模型在轉換處理過程當中的數據流向,因此本文將重點關注於IFC中的物理實體(IfcProduct)和關係實體(IfcRelationShip)。經過遍歷單個IFC文件中的關係層次樹,咱們將依次抵達一個個鏈接在一塊兒的物理實體,經過輸出物理實體的模型信息和屬性信息,同時輸出物理實體間的組織關係,咱們將能夠經過IFC重構原有的建築模型信息。工具
IFC Schema規定的700多個類裏,繼承自IfcElement的類和建築行業的具體構建對應,好比繼承自IfcSpatialElement的類和建築中的空間部件對應。在咱們要處理的IFC文件中,主要關注屬於物理實體類型的繼承自IfcElement的類和繼承自IfcSpatialElement的類,此類均屬於建築場景中的建築構件或空間構建,咱們將其稱之爲IFC物理實體。例如,IfcWall的實例就是建築空間中的一堵牆,IfcSpace實例表明一個建築空間。在提取IFC文件時,咱們重點關注IFC物理實體。特別的,繼承自IfcElement的物理實體都有對應的Type表示該實體擁有的屬性,材質信息,幾何展現等相關信息,在提取IFC文件時也要一併關注這些信息。動畫
圖1 IFC物理實體的繼承樹ui
IFC遵循面向對象的設計模式,除了IFC物理實體以外,IFC還定義了IFC關係實體來表達物理實體或其餘實體之間的關聯,依賴,聚合,組合,包含等關係。IFC關係實體一般以「IfcRel」前綴開頭,它對應的實例爲IFC關係實例。編碼
圖2 IFC關係實體的繼承樹設計
例如,IfcRelAggregates是IfcRelComposes的子類,用以表達聚合關係,一般是一對多。經過解析IfcRelAggregates實例的鏈接上級的RelatingObject和鏈接下級的RelatedObject屬性能夠獲取在聚合關係兩端的實體,空間實例一般以聚合關係鏈接起來。而IfcRelContainedInSpatialStructure這個關係實體是咱們要重點關注的,它表明了建築的包含關係,用以將一個建築元素(物理實體)分配給空間上的某個部件,以鏈接物理實體中IfcSpatialElement和IfcElement,。而且任何元素只能分配給某個級別的空間結構惟一一次,使得元素只能被包含於單個空間結構中。相似的關係實體還有表示引用關係的IfcRelReferencedInSpatialStructure,可是引用關係沒必要是一對一的,它能夠引用零個,一個或者多個。
圖3 IFC關係實體的應用
如圖3所示,圖中的場景實例包含了表明建築空間的三個IfcBuilding實例,以及兩個IfcBuildingSteroy實例和表明建築關係的兩個IfcAggregates實例,表明包含關係的兩個IfcRelContainedInSpatialStructure實例。而做爲建築元素之一的兩個IfcWall實例和IfcStair實例經過建築關係被包含於建築空間中。由此可知,IFC標準經過IFC的關係實例將模型組織成井井有理的空間層次關係,全部的建築信息和構建信息都能有被有效地組織和管理,所以IFC標準爲BIM模型的信息描述和信息交換都提供了堅實的保障。而由此也能夠提出,基於構件之間的包含和彙集關係,本文若是立足於IFC的根節點,按照關係層次一層一層地去遍歷IFC節點樹,是能夠作到將IFC的每個構件生成在同一棵節點樹內,從而實現IFC文件中全部構件按層次地導出。IFC標準中對構件之間的關係的定義,將是本文模型提取的理論前提。
GLTF(GL TransmissionFormat)即圖形語言交換格式,它是一種3D內容的格式標準,由Khronos Group管理(Khronos Group還管理着OpenGL系列、OpenCL等重要的行業標準)。GLTF用於應用之間的模型高效傳輸和加載3D場景和模型。GLTF最大限度地減小了3D模型的大小,以及解壓縮和使用模型所需的運行時處理,同時以最大的限度保障模型信息的完整度。GLTF爲三維內容工具和服務定義了一種可擴展的通用發佈格式,可簡化創做的工做流程並實現整個行業內容的可互操做使用。GLTF一直致力於成爲三維圖形界的JPEG,可見它在信息傳輸和存儲中所包含的強大特性和無窮的發展力。
GLTF格式將易於解析的JSON場景描述與一個或多個幾何的表示,與動畫和其餘豐富數據的二進制文件相結合。數據以二進制的方式存儲,即它能夠直接加載到GPU緩衝區中而無需額外的解析或其餘操做。同時結構信息又以JSON格式組織,即保證了可讀性又保證瞭解析的快速性。使用這種方法,GLTF可以在具備Node,Mesh,Camera,Material和Animation的完整分層展現場景,同時實現高效傳輸和快速加載。
圖4 GLTF實體間的組織關係
GLTF按照Scene-Node-Mesh-Accessor-BufferView-Buffer由高到低的層次關係來組織三維模型信息。
Scene:GLTF包括場景定義數據,使用一棵場景樹來組織定義場景。Scene中的節點包含Transform矩陣(也就是位置、旋轉、縮放)以及場景節點父子關係的描述,以及該場景包含的功能(mesh、camera等);一般意義上的Scene是一種經常使用的場景對象組織方式。咱們把場景中的對象,按照必定的規則(一般是空間關係)組織成一棵樹,樹上的每一個節點表明場景中的一個對象。每一個節點均可以有零到多個子節點,但只有一個父節點。 每一個節點都包含多個對「空間的定義」的屬性,如Transform屬性,經過一個 4x4 的矩陣表示,也能夠經過位置、旋轉、縮放三個份量來表示,它表明該場景相對世界座標系的轉換。如Nodes屬性,則表明該場景中的子節點,根據Node的索引指向同一個GLTF文件中的Node數組中的某個或多個Node。
Node:Node是場景中的節點,被Scene包含或指向,一般對應於模型中的一個建築構件。若是Scene表明一個建築場景,如一個房子及房子周邊的場地,那麼Node的細度就是這個房子裏的一把椅子,一張桌子,一扇門,甚至這件房子在總體上也能夠當作是一個Nod。Node能夠主要包含的屬性有Children,定義了該節點所包含的子節點。Mesh屬性則是該節點所包含的模型信息,具體地說能夠包含頂點,法向量,材質,紋理等信息。延續剛纔的例子來說,若是房子是一個Node,那麼它的Children屬性應該指向房子裏的構件好比椅子,桌子等。而這些椅子,桌子自己也是Node,它被房子的Node指向,同時也能夠指向更細層次的子節點,如椅子的椅子腿,椅子的靠背等。一般高層次的Node都不包含Mesh屬性,最深層次的Node節點,也就是葉節點,會包含Mesh屬性,它指向同一個GLTF文件中的Mesh數組中的某個Mesh,它包含了刻畫該節點的模型的信息。
Mesh:Mesh在GLTF中表明要渲染的三維空間中的物體的模型信息。具體表明三維空間中表示物體的造型。GLTF按照目前圖形學中最經常使用的方法邊界表示法,即用一組多邊形或者曲面來定義物體的邊界,並用以區分了空間中哪些部分是物體的內部和物體的外部。構造一個物體邊界的一組多邊形就被稱爲Mesh。在GLTF中,Mesh主要包含Primitives屬性和Index屬性。Primitives屬性包含物體邊界的頂點信息和法向量信息,它存儲對應Accessor索引,以找到對應的信息。Index則是關於邊界曲面的拓撲順序,具體的順序以Primitives中的Mode屬性定義,能夠定義的順序包括:POINTS,LINES,TRIANGLES,TRIANGLES_STRIP,TRIANGLES_FAN。
Accessor:Accessor是BufferView中數據的訪問器,一個BufferView能夠同時存儲多組同類數據,所以須要用不一樣的訪問器以得到不一樣的數據。經過Accessor對BufferView的數據進行劃分,以得到不一樣的訪問效果。
BufferView:BufferView能夠比做數據視圖,一個BufferView一般會對應一種數據,如浮點數,整數。這些數據從BufferView的角度來看是單純的數組。
Buffer:Buffer是存儲數據的數組,在這裏,數據以二進制形式存儲,經過Base64的編碼形式編碼。
如咱們在上一章討論的,IFC是建築行業的標準,包含了不少的非幾何信息,而咱們導出的GLTF只包含幾何信息,所以在轉換時應關注幾何信息。
IFC中全部的對象都組織在同一棵樹中,這顆樹的根是一個IfcProject對象,存儲該模型的元信息。由根出發,IFC對象尤爲是建築構件由聚合關係或者包含等關係按照空間上的關係彙集在這棵樹上,所以在裝載成GLTF時也要注意保存這種組織順序。在對象樹中的IFC建築構件,都擁有它對應的圖元信息,這些圖元信息將被咱們提取,轉換成GLTF對象,一個建築構件在IFC中是一個IfcProduct的子類(如IfcElement),而在GLTF中是一個Node結點。IfcProduct的成員中包含它的圖元信息的連接,經過連接找到它對應的圖元信息,對應的是多個IfcShape對象,而在GLTF中則是多個Mesh,一個IfcShape對應一個Mesh。所以,一個IfcProduct擁有多個IfcShape,在GLTF中則是一個Node的children屬性指向多個Mesh(實際上是指向Node,可是這些node是葉子節點,只包含一個Mesh),在現實世界中,對應的概念則如一個椅子(IfcProduct)擁有多個構件,如凳腿,靠背,座板等。
在處理的時候,以遞歸的方式訪問IFC對象樹,而後對於每個訪問的對象,建立一個Node節點,而且找到該對象對應的Shape,建立Mesh節點。下圖中以隊列的方式實現對IFC對象樹的遞歸訪問。