Skip to content

02: Inspecting IFC instance objects

jakob-beetz edited this page Dec 20, 2016 · 6 revisions

Instance object attribute values

Once you have retrieved the desired object(s) from the model you can start to inspect its contents, values and relations to other objects. First, let's take a look at some simple values of our project, by accessing its attributes.

Accessing ENTITY attributes

There are a number of ways by which you can inspect and access the values of the attribute of an ENTITY instance:

Access attributes by name

Most IFC ENTITY have a number attributes. They are the same as the attributes listed on the in the specifification of the model, e.g. the documentation of the IfcProject ENTITY definition. Each attribute, including the inherited attributes and can be accesses using a . after the instance variable, e.g.

project = model.by_type("IfcProject")
print (project[0].Name)

which in our case prints out

Hello wall project

The Name actually is not an attribute specific to the IfcProject ENTITY, but since it is a superclass of IfcRoot, and thus inherits its attributes (see the schema at the end of the documentation it can be accessed just the same.

Similarly, all other attributes defined in the schema can be accessed

project = model.by_type("IfcProject")
print (project[0].Name)
print (project[0].GlobalId)
print (project[0].Description)
print (project[0].LongName)

yield the output

Hello wall project
0YvctVUKr0kugbFTf53O9L
Simple wall with door
None

Notice, that print (project[0].LongName) resulted in None. If we inspect the particular line in the SPFF file by print (project[0]) we can see that

#1=IfcProject('0YvctVUKr0kugbFTf53O9L',#2,'Hello wall project','Simple wall with door',$,$,$,(#20),#7)

The $ sign signifying an attribute that has not filled in. This is very often the case for attributes that have been made OPTIONAL in the ENTITY definition in the schema.

###Access attributes by index Sometimes, you cannot lookup all attributes of an entity instance in the schema (or are too lazy to do so). A handy way to IfcOpenShell provides a way to access the attributes by their order (in the schema, reflected in the SPFF part 21 file) If you want to list the names of all attributes that a particular object has you can e.g. use this:

project = model.by_type("IfcProject")[0]
for att_idx in range(0,len(project)):
    print(project.attribute_name(att_idx))

which will print

GlobalId
OwnerHistory
Name
Description
ObjectType
LongName
Phase
RepresentationContexts
UnitsInContext

Note that len() gives you the number of attributes of that particular entity without the inverse attributes, just like listed in the specification. It is the size of the list of all attributes defined for this particular ENTITY instance, so IfcProject in our case. Refer to the Python tutorial on lists to see how they can be handled.

This can be used to print any value of any ENTITY instance we encounter in our IFC file. Let's extend the above script by also printing the values of each attribute that we find using the index mechanism.

door = model.by_type("IfcDoor")[0]
for att_idx in range(0,len(project)-1):
    field_width = 20
    # In case we are dealing with a different IFC version
    # there might by attributes that do not exist in a 2x3 file
    # handle the attempt to print out a value where there is no
    # attribute gracefully
    try:
        att_name = door.attribute_name(att_idx)
        att_type = door.attribute_type(att_name)
        att_value = door[att_name]
        print("{}\t{}\t{}".format(att_name.ljust(field_width),door.attribute_type(att_name).ljust(field_width), door[att_name]))
    except:
        pass

Two things to notice here:

  1. IfcOpenShell is built against the IFC 4 schema. In the case of an IfcDoor for example, three new attributes have been added in IFC 4 to the ENTITY definition of IfcDoor: PredefinedType OperationType and UserDefinedOperationType. Compare the specs of IFC 4 with the IFX 2x3 version. To prevent the application from crashing, we have to catch the error (exception) that occurs when we are trying to access the value of e.g. door['PredefinedType'] by using the try ... except mechanism built into Python.
  2. In order to have a nice output, the results are printed to the console using the .format function that can be applied to any strings printed out

Traversing ENTITY instances

Up to now, we have mostly taken a look at

Link to by_type or btf

Clone this wiki locally