You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python的IfcOpenShell提取IFC文件中构件的工程量?

如何用IfcOpenShell读取IFC对象的最深层工程量?

我的问题历程

初始尝试与错误

我尝试用Python的IfcOpenShell读取IFC文件中楼板的最深层工程量,最初写的代码是这样的:

import ifcopenshell
path = r'D:\ifcos_1\slab.ifc'
ifc_file = ifcopenshell.open(path)
geometries = ifc_file.by_type("IfcProduct")
for geometry in geometries:
    if geometry.is_a("IfcSlab"):
        print geometry
        test = geometry.IfcPhysicalQuantity()
        print test

但不管怎么调整geometry.X()里的方法,都会报这个错误:

AttributeError: entity instance of type 'IfcSlab' has no attribute 'IfcPhysicalQuantity'

我查了IFC定义文档,还是没找到正确的调用方式。

第一次编辑:获取关联信息

后来我写了能获取楼板及关联信息的代码:

for geometry in geometries:
    if geometry.is_a("IfcSlab"):
        print geometry
        definedBy = geometry.IsDefinedBy
        print definedBy[0]
        for each in definedBy:
            test = each.is_a()
            print test

这时候遇到了IFC4兼容性问题,我打算参考相关论坛说明重新编译IfcOpenShell。

第二次编辑:转向IFC2x3后的困境

我换成了IFC 2x3标准,也确认文件里确实包含工程量信息,代码更新为:

for geometry in geometries:
    if geometry.is_a("IfcSlab"):
        definedBy = geometry.IsDefinedBy
        for line in definedBy:
            test = line.is_a()
            # print test
            if line.is_a() == 'IfcRelDefinesByProperties' or line.is_a() == 'IfcRelDefinesByType':
                step1 = line.RelatingPropertyDefinition
                step2 = step1.is_a()
                print step2

输出结果里能看到IfcElementQuantity:

IfcPropertySet
IfcPropertySet
...
IfcElementQuantity
IfcElementQuantity

但不管我在step1 = line.后加什么属性(比如line.IfcPropertySet、line.IfcElementQuantity、line.RelatingPropertyDefinition)都会报错,找不到正确的属性访问方式。


解决方案

问题核心是你对IFC数据结构的访问逻辑有误:IfcPhysicalQuantity并不是IfcSlab的直接属性,它嵌套在IfcElementQuantity中,而IfcElementQuantity又通过IfcRelDefinesByProperties关联到IfcSlab。下面是正确的遍历流程:

正确代码示例(针对IFC2x3)

import ifcopenshell

path = r'D:\ifcos_1\slab.ifc'
ifc_file = ifcopenshell.open(path)
slabs = ifc_file.by_type("IfcSlab")

for slab in slabs:
    print(f"楼板ID: {slab.GlobalId}")
    # 遍历所有关联的定义关系
    for rel in slab.IsDefinedBy:
        if rel.is_a("IfcRelDefinesByProperties"):
            prop_def = rel.RelatingPropertyDefinition
            # 筛选出存储工程量的容器
            if prop_def.is_a("IfcElementQuantity"):
                print("找到工程量集合:")
                # 遍历具体的工程量条目
                for quantity in prop_def.Quantities:
                    quantity_type = quantity.is_a()
                    quantity_name = quantity.Name
                    # 根据工程量类型获取对应数值
                    if quantity_type == "IfcVolumeQuantity":
                        value = quantity.VolumeValue
                        print(f"- {quantity_name}: {value} 立方米")
                    elif quantity_type == "IfcAreaQuantity":
                        value = quantity.AreaValue
                        print(f"- {quantity_name}: {value} 平方米")
                    elif quantity_type == "IfcLengthQuantity":
                        value = quantity.LengthValue
                        print(f"- {quantity_name}: {value} 米")
                    # 其他工程量类型可以按需扩展

关键知识点

  1. 不要直接调用类名作为属性:比如geometry.IfcPhysicalQuantity()是错误的,IFC实体的属性都是成员变量(驼峰式或小写开头),不是类方法调用。
  2. 关系对象的筛选:IsDefinedBy返回的关系可能有多种类型,要先筛选IfcRelDefinesByProperties,再通过它的RelatingPropertyDefinition拿到属性集合。
  3. 区分属性集合类型:RelatingPropertyDefinition可能是IfcPropertySet(普通属性)或IfcElementQuantity(工程量),需要先判断类型再处理。
  4. 工程量的差异化获取:不同的IfcPhysicalQuantity子类有不同的数值属性,比如体积用VolumeValue、面积用AreaValue,要根据类型匹配。

内容的提问来源于stack exchange,提问作者Yafim Simanovsky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:14:39