我正在尝试使用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
我研究了definitions
无论我试图为 test = geometry.X()
放置哪种类型的函数,我都会收到错误:
文件“C:\ Python27 \ lib \ site-packages \ ifcopenshell \ entity_instance.py”,第48行,在__getattr__中
“类型'%s'的实体实例没有属性'%s'”%(self.wrapped_data.is_a(),name))
AttributeError:'IfcSlab'类型的实体实例没有属性'IfcPhysicalQuantity'
不知道如何解决这个问题,并希望得到帮助 .
EDIT:
获得平板和进一步参考的进一步工作:
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的兼容性,我将尝试使用this forum post.的指令重新编译
EDIT 2:
现在使用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
无论我在 step1 = line.
之后放置什么都有错误,以下都不会给出结果:
line.IfcPropertySet
line.IfcElementQuantity
line.RelatingPropertyDefiniton
但是,此代码的输出仍然是:
IfcPropertySet
IfcPropertySet
IfcPropertySet
IfcPropertySet
IfcPropertySet
IfcPropertySet
IfcPropertySet
IfcPropertySet
IfcPropertySet
IfcPropertySet
IfcElementQuantity
IfcElementQuantity
这意味着我可以访问 IfcElementQuantity
,但没有任何属性可以工作 . 我看了schema reference但找不到正确的 .
1 回答
实现这一点时,您应该注意导入库使用的IFC版本 - 由IfcOpenShell-Website分发的版本与IFC2X3一起使用 . 对于IFC4,您可能需要自己编译版本 . (你可以用
ifcopenshell.schema_identifier
检查你的IFC版本)即使我在谈论IFC2X3,我也 Build 了关于buildingSMART IFC 4定义的链接 . 在buildingSMART网页上,IFC2X3的差异以红色标记 . 并且IFC4定义更易于阅读(IMO) .
数量不像属性那样直接附加 . 它们被写为属性集,然后与元素或元素类型相关 . 首先,您应该确保您的IFC文件包含数量 - 否则您将找不到任何数量 . 通常,您从特定产品开始 -
ifc_file.by_type('IfcSlab')
. 您可以通过反向属性访问属性集 - 这些属性通常由IFC库设置,它们不直接作为文件中的属性出现 .我把你的示例文件缩短到大约三分之一(所以它仍然是一个有效的IFC2X3文件):
这是一块附有面积测量的平板 . 它应该具有反向属性
IsDefinedBy
. 在IFC2X3中,这指向实体IfcRelDefinesByProperties和IfcRelDefinesByType的列表 . 使用IFC4,IfcRelDefinesByType将被放入inverse属性IsTypedBy
.每个IfcRelDefinesByProperties指向其属性
RelatingPropertyDefinition
中设置的属性 . 有各种属性集类型,您希望在搜索物理量时它是IfcElementQuantity类型 . 在迭代属性关系列表时,您必须在运行时检查当前持有的类型 .数量集在
Quantities
属性中附加了IfcPhysicalQuantities列表 . 这些可以是简单数量或复数量,由多个简单数量组成 . 对于简单数量,区域,计数或重量有特定的子类型 . 同样,您必须在运行时检查具体类型 .区域数量本身有一个名称和描述,以提供更多的背景(不是我们的,但可能在现实世界中) . value属性以数量类型命名,因此IfcQuantityArea具有属性
AreaValue
. 同样感兴趣的是属性Unit
,它是对值单位的引用 . 如果未设置(如我们的示例中所示),则需要在IfcProject实体中查找已分配的单元 .不幸的是,这可能不是全部 . 如果对象(这里是我们的IfcSlab)具有指定的对象类型,那么该类型也可以附加属性集(我将示例文件修改为这种情况) . 你的类型实体没有逆属性,而是直接属性
HasProperties
. 如果已设置,您可以通过它发现附加属性 .总而言之,您可能需要多个循环:
对于每个对象,获取属性集
对于每个属性集,测试它是否为数量集
对于每个数量集,请查看数量
如果对象具有用户定义的类型,则可能会重复此搜索 .
下面的代码应该这样做(用我的机器上写的python 3.5.4和ifcopenshell与IFC2X3架构)):
从文件中获取所有平板(只有一个)
遍历inverse属性
IsDefinedBy
中的所有实体 - 这些可以是IfcRelDefinesByProperties
或IFcRelDefinesByType
.从实体获取属性集
检查给定的属性集是否为
IfcElementQuantity
,如果是,则继续打印quantitites .对于该示例,这导致: