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 开发者博客、相关社区问答等。