首先,抱歉,很久没有更新文章了,也来不及解释了,我们直接进入正题吧。这篇还是接上之前挖坑的IFC系列,前面的几篇文章我们聊了IFC的一些概念、数据结构和可视化工具等等,有了这些铺垫之后,我们基本就可以说一些实战性的内容了,比如如何利用开源工具包读写IFC数据,这其中就包括模型结构树数据、几何数据和属性数据。
所以这篇文章的主题就是提取IFC模型结构树的信息,且基于 IFC 4 版本,但对 IFC 2x3 大部分都是通用的。首先结合下方的图片对IFC模型结构树做一个说明:在拆解IFC结构树过程中会涉及两种关联实体,IfcRelAggregates 和 IfcRelContainedInSpatialStructure,其中前者表达空间分解,例如一个建筑可以分为多个楼层,又如桥墩可以分为盖梁、立柱、承台和桩基础;后者则表达空间内的元素,例如一层有结构墙、柱、门、窗等。换而言之,我们可以把元素非为空间元素和非空间元素,如果要获取空间元素中的非空间元素用IfcRelContainedInSpatialStructure,其余都用 IfcRelAggregates 。
这里我们用到的开源工具包是xBIM,它是面向.NET平台的 IFC tookit,主要的开发语言为C#,当然几何库部分还是以C++为主。如果有读者习惯用Python,也推荐大家使用 IfcOpenShell 这个库,基本逻辑都是差不多的。
IfcRelContainedInSpatialStructure
要获取空间元素中的非空间元素,首先我们需要判断当前元素是否为空间元素 IfcSpatialStructureElement,然后用该类对应的属性ContainsElements来获取其中的元素集。
var spaceEle = elem as IIfcSpatialStructureElement; if (spaceEle != null) { //using IfcRelContainedInSpatialElement to get contained elements var containedElements = spaceEle.ContainsElements.SelectMany(rel => rel.RelatedElements).ToList(); for (int i = 0; i < containedElements.Count(); i++) { // do what you want // 使用递归完成对结构树的遍历 } }
IfcRelAggregates
空间分解的子集元素可以通过反向属性 IsDecomposedBy 获取。
foreach ( var item in elem.IsDecomposedBy.SelectMany ( r => r.RelatedObjects ) ) { // do what you want // 使用递归完成对结构树的遍历 }
空间元素分解
IFC拥有一个语义化的空间结构树,单个文件中会定义一个“项目IfcProject”,项目中包含一至多个“场地 IfcSite”,场地中又包含一至多个“建筑 IfcBuilding”,再从建筑到楼层,从楼层再到墙、板、柱。当然这只是一个简单的例子,随着IFC标准的逐渐完善和丰富,分级方式也是越来越多样,例如场地中可以有路线 IfcAlignment,有桥梁IfcBridge等等。
非空间元素的分解
复合元素 IfcElementAssembly也是一种结构层次的表达手段,它可以被进一步分解,例如我们把桥梁主梁的一个标准节段作为一个复合对象,而它可以被分解为顶板、底板、腹板、加劲肋等构件。
小结
在实际的代码编制过程中,我们需要结合上述两种结构划分方式,并利用递归逻辑实现完整结构树的遍历。Ok,就聊到这里,下期预告:《工业基础类—利用xBIM提取IFC几何和属性数据》。以下是我的创建的IFC交流群,有兴趣的可以扫码加入!