Assimp IFC 解析流程剖析
1. 引言
Assimp是一个将各种 3D 文件格式加载到共享的内存中格式的库。它支持 59 多种文件格式的导入和的十多种导出文件格式。 这是支持导入导出的所有格式:
https://github.com/assimp/assimp/blob/master/doc/Fileformats.md
2. IFC Schema 速览
IFC 架构使用 ISO 10303-11 定义的 EXPRESS 语言来描述建筑元素。下面以 IfcWall 和 IfcWindow 为例,展示部分 EXPRESS 代码并解释其继承关系和属性:

上例定义了 IfcWall 实体,它继承于 IfcBuildingElement ,并且存在两个子类型( IfcWallElementedCase 、 IfcWallStandardCase )。 PredefinedType 是一个可选属性,其类型为枚举 IfcWallTypeEnum *。程序读取 IFC 数据时,会根据 EXPRESS 中的继承结构,生成对应的 C++ 类层次(如 IfcWall 继承自 IfcBuildingElement )。
另一个示例, IfcWindow 的 EXPRESS 定义片段如下:

以上片段说明 IfcWindow 继承于 IfcBuildingElement *,并含有高度、宽度这两个可选属性。这表明同一个实体可以有多种属性。在 Assimp 中,阅读 IFC 架构文件后,会用脚本自动生成相应的 C++ 类(如以下节所述),并在解析 IFC 文件时填充这些类实例的属性。
3. Assimp 解析总流程

Assimp 的 IFC 导入器主要遵循以下步骤: 读取文件→词法分析→语法解析→实体映射→场景构建 。首先, IFCImporter::InternReadFile 打开 IFC STEP 文件( .ifc ),并调用 STEP 解析器( STEPFileReader )对文件进行词法和语法分析,将文本内容转换为内部的对象数据库。然后,逐个 映射(IFC实体→C++对象) :解析器根据 IFC 文件里的每个记录(例如 #123=IFCWALL(...) )创建对应的 C++ 类实例,并填充其属性。最后,根据 IFC 的 关系表征 (aggregation、containment、material assignment 等)构建 aiScene ,将各个几何表示(如墙面、门窗)转换为 aiMesh 并组织为节点树。最终输出一个包含所有网格(Mesh)、材质和层次结构的 aiScene 对象,供上层渲染或分析使用。
4. 脚本生成 C++ 类
Assimp 为了自动适配 IFC 模式,提供了位于 scripts/StepImporter/ 下的解析脚本( CppGenerator.py )。该脚本会读取 IFC2X3的 EXPRESS 架构定义,自动生成对应的 C++ 头文件(在 code/AssetLib/IFC/ 目录)。 使用方式 :我执行后未能生成对应的c++类,不过Assimp提供了对应的IFC2X3 C++文件,从头文件以及代码风格来看应该脚本生成的:

看下生成的IfcWindow结构体:

在这个示例中,类名对应 IFC 实体名,父类 IfcBuildingElement 对应其在 EXPRESS 中的超类型。成员变量(例如 OverallHeight )使用 Maybe<>::Out 封装可选属性类型。脚本生成后的头文件会被进一步手工或自动整合到编译系统中,用于 IFC 文件的实际解析。
5. IFCImporter 核心类与调用链
Assimp 中的 IFC 导入主要集中在 IFCImporter 类(位于 AssetLib/IFC/IFCLoader.cpp )中。核心函数 IFCImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem* pIOHandler) 是入口点, 从代码来看支持IFCZip格式 ,但我没试过,不过支持IFCZip也不是啥难事,毕竟只是压缩了下。

IFCImporter 完成以下操作:
- STEP 解析
- 调用 STEP::ReadFile(...) (在内部使用 STEPFileReader )将 IFC 文件读入一个中间数据库对象,同时根据文件头检查 FILE_SCHEMA 。Assimp 目前只支持 IFC2x3 格式,因此 FILE_SCHEMA 中必须包含 'IFC2X3' ;否则会报错提示“Unrecognized file schema”。
- 单位转换
- IFC 文件中可能使用了不同长度单位(如毫米、米),Assimp 会在根节点上应用全局缩放,把模型统一转换到米制单位。这意味着导入后几何尺寸可能会变化,开发者可以根据需要调整 aiScene 根节点的缩放。
- 实体映射
- 解析器遍历所有解析出的 IFC 实体(如 IfcWall、IfcWindow),为每种类型调用相应的 C++ 类构造器,填充属性。期间会建立实体间的指针或索引关系,如 IfcOpeningElement 与 IfcRelVoidsElement 的关联可以用来在几何上开洞。
- 场景构造
- 根据 IFC 中的聚合( aggregation )和包含( containment )关系,生成 aiNode 树;对于包含几何形状的实体(例如 IfcFacetedBRep、IfcExtrudedAreaSolid 等),生成对应的 aiMesh 并附加到节点上。Assimp 只处理常见的关系类型(如聚合、材料分配),并将它们映射到最终的场景图。其他复杂的关系会被忽略。最终得到的 aiScene 包含所有网格、材质和节点层次,用于渲染或进一步处理。
6. 总结与参考
Assimp 对 IFC 的支持使得 BIM 数据能够被集成到游戏、可视化、仿真等管线中,其优点在于 统一了多种格式 的加载流程,并能自动处理复杂的 IFC 继承结构和几何转换。不过当前支持还 存在局限 :Assimp主要针对 IFC2x3 标准进行开发( 其实即便是IFC2X3支持得也不是很完美,比如材质不对,某些数据几何也不太对,建模问题 ),IFC4 的一些新特性和实体尚未全面覆盖,甚至无法正确解析IFC4;导入过程也不会执行布尔运算来自动开洞(需要在输入几何中定义开口)。综合而言,Assimp 提供了一个 可用但不完备 的 IFC 导入解决方案,适合快速入门和轻量级使用。更多细节可参考 Assimp 官方文档和社区讨论,包括用户指南、源代码注释、以及各类实现文档。
一句话总结:
Assimp是一个“大而全”的开源库并非一个“大而美”的开源库。本文只是探讨Assimp IFC解析流程,并不会将Assimp IFC用于实际生成中。
参考资料: Assimp 官方文档(IFC 导入说明)、buildingSMART IFC 规范、Assimp 开发者博客、相关社区问答等。