add properties

Add properties to IFC using IfcOpenShell

It often happens that an IFC file, after export, contains unintended errors such as missing attributes on objects, incorrect number of properties, or missing exported values. In such cases, we typically need to open the model in the native software to make corrections.

There are also programs available that allow editing of data contained in an IFC file, but most of them are paid.

In this article, I would like to present a free method for manipulating IFC files.

This will be the first post in a series dedicated to the analysis and editing of IFC files.

What is this method?

Stay tuned to find out.

If you’re interested in the topic of IFC 4.3, be sure to check out other articles on this subject on our blog

ifcOpenShell

The hero of this article is IfcOpenShell – an open-source library created for working with IFC (Industry Foundation Classes) files, which are a standard for data exchange in the architectural and construction industries.

IfcOpenShell allows you to view, edit, and analyze the information contained in IFC files without the need for commercial software. With this library, you can manipulate the model structure, add or remove attributes, and even create new IFC files. IfcOpenShell operates in the Python programming language, so a basic understanding of Python is necessary to use the tool effectively.

You can find more information about IfcOpenShell here: LINK

However, I understand that learning Python may seem challenging, so below you’ll find a simple code snippet that you can just paste into your development environment.

I have broken it down into individual parts to explain step by step what each segment does.

Google Colab

Before we dive into the example, I’d like to introduce the tool I’ll be using – Google Colab. I chose this development environment for a simple reason: it offers easy access, is free, doesn’t require any software installation on your computer, operates in the cloud, and allows you to write and run Python code directly in your browser. It’s an ideal solution for those who do not want or cannot install Python locally.

Additionally, Google Colab facilitates collaboration – you can easily share your notebooks with others, just like with Google Docs. This enables real-time collaboration on code, making Colab a great tool for both learning and team projects.

You can find more about Google Colab here: LINK

Adding Properties to an IFC Model Using IfcOpenShell

There are often situations where an IFC file does not contain all the required properties, or we do not have access to the original files, which can create difficulties.

Manually editing an IFC file by modifying the STEP code in a text editor is time-consuming and prone to errors.

A much simpler solution is to use IfcOpenShell. In the following section of the article, I will show you how to easily add properties to a bridge model using this tool.

More about properties in IFC you can find here: LINK

Let's get started!

To get started, log in to Google Colab and create a new notebook. Then, upload the file you want to edit by clicking the icon that allows you to upload a file to the server.

Note: Files uploaded to a Colab session are deleted after the session ends. To continue working with the file in the future, you will need to upload it to the server again.

Once the file is available in the session, add a line of code in the notebook.

Copy and paste the code provided below.

Your code is now ready to use!

Note: The example is based on my specific scenario. To tailor it to your needs, carefully analyze the code and check which variables you can modify according to your project’s requirements.

Code ready to use

				
					# Installation of ifcopenshell
!pip install ifcopenshell

# Importing necessary libraries
import ifcopenshell
import ifcopenshell.util.element

# Loading the IFC file
ifc_file = ifcopenshell.open('Bridge 1.ifc')

# Searching for all IfcWall entities
walls = ifc_file.by_type('IfcWall')

# Creating a new property value MMI
property_single_value_mmi = ifc_file.create_entity(
    "IfcPropertySingleValue",
    "MMI",
    None,  # Description is optional
    ifc_file.create_entity("IfcLabel", "300"),  # Nominal value
    None  # Unit is optional
)

# Creating a new property value Status
property_single_value_status = ifc_file.create_entity(
    "IfcPropertySingleValue",
    "Status",
    None,  # Description is optional
    ifc_file.create_entity("IfcText", "InProgress"),  # Nominal value
    None  # Unit is optional
)

# Creating a new property set
property_set = ifc_file.create_entity(
    "IfcPropertySet",
    ifcopenshell.guid.new(),
    ifc_file.by_type("IfcOwnerHistory")[0],
    "BIMCorner",
    None,  # Description is optional
    [property_single_value_mmi, property_single_value_status]
)

# Iterating through walls and adding the property set
for wall in walls:
    rel_defines = ifc_file.create_entity(
        "IfcRelDefinesByProperties",
        ifcopenshell.guid.new(),
        ifc_file.by_type("IfcOwnerHistory")[0],
        None,  # Description is optional
        None,  # Description is optional
        [wall],  # Related objects
        property_set  # Related property definitions
    )

# Saving the modified IFC file
ifc_file.write('Modified_Bridge.ifc')

				
			

Code Explanation

1. Installing the IfcOpenShell library

				
					!pip install ifcopenshell
				
			
  • What you’re doing: Installing the IfcOpenShell library.
  • Why: IfcOpenShell allows for the manipulation of data in IFC files, which are the standard for data exchange in the construction industry.
  • What to keep in mind: Make sure you have the pip library installed in your environment. You can do this with pip install pip.
  • Common errors: Lack of permissions to install packages, or the pip library not being installed.

2. Importing the necessary libraries:

				
					import ifcopenshell
import ifcopenshell.util.element
				
			
  • What you’re doing: Importing the IfcOpenShell and ifcopenshell.util.element libraries.
  • Why: These libraries are essential for manipulating data in IFC files.
  • What to keep in mind: Make sure the libraries are correctly installed before importing them.
  • Common errors: Missing libraries, typos in library names.

3. Loading the IFC file:

				
					ifc_file = ifcopenshell.open('Bridge 1.ifc')
				
			
  • What you’re doing: Loading the IFC file into the variable ifc_file.
  • Why: To manipulate data in the IFC file, you must first load it.
  • What to keep in mind: The path to the file must be correct. Make sure the file exists at the specified location.
  • Common errors: Incorrect file path, file not found at the specified location.

4. Searching for target objects based on type

  • Finding IfcBridgePart entities:

				
					bridge_parts = ifc_file.by_type('IfcBridgePart')
				
			
  • What you’re doing: Searching for objects of type IfcBridgePart in the loaded IFC file.
  • Why: To add properties to specific objects, you first need to locate them.
  • What to keep in mind: Verify that objects of this type exist in the IFC file.
  • Common errors: No objects of the specified type in the file, typos in the object type name.

4.1. Searching for various target objects

  • Finding IfcWall entities:

				
					walls = ifc_file.by_type('IfcWall')
				
			
  • Finding IfcColumn entities:

				
					columns = ifc_file.by_type('IfcColumn')
				
			
  • Finding IfcBeam entities:

				
					beams = ifc_file.by_type('IfcBeam')
				
			
  • Finding IfcSlab entities:

				
					slabs = ifc_file.by_type('IfcSlab')
				
			
  • Finding IfcDoor entities:

				
					doors = ifc_file.by_type('IfcDoor')
				
			

4.2. Searching for other target objects that have the 'PredefinedType' attribute set to 'USERDEFINED'

Below, you’ll find an example of code that allows you to find an object based on a specific attribute.

				
					attribute_target_objects = []
for entity in ifc_file:
    if hasattr(entity, 'PredefinedType') and entity.PredefinedType == 'USERDEFINED':
        attribute_target_objects.append(entity)
				
			

4.3. Searching for target objects that have the 'IfcPropertySingleValue' property with 'Domain' set to 'Bridge'

Below, you’ll find an example of code that allows you to find an object based on a specific property and a defined value.
				
					property_target_objects = []
for entity in ifc_file:
    if hasattr(entity, 'IsDefinedBy'):
        for rel in entity.IsDefinedBy:
            if rel.is_a('IfcRelDefinesByProperties'):
                property_set = rel.RelatingPropertyDefinition
                if property_set.is_a('IfcPropertySet'):
                    for prop in property_set.HasProperties:
                        if prop.is_a('IfcPropertySingleValue') and prop.Name == 'Domain' and prop.NominalValue.wrappedValue == 'Bridge':
                            property_target_objects.append(entity)
                            break
				
			

***In Python code, the hasattr() function is used to check if a given object has an attribute with a specific name. This is useful when you’re not sure whether an object possesses a certain attribute and want to avoid potential errors from trying to access a non-existent attribute.

5. Creating new property values

				
					# Creating a new property value MMI
property_single_value_mmi = ifc_file.create_entity(
    "IfcPropertySingleValue",
    "MMI",
    None,  # Description is optional
    ifc_file.create_entity("IfcLabel", "300"),  # Nominal value
    None  # Unit is optional
)

# Creating a new property value Status
property_single_value_status = ifc_file.create_entity(
    "IfcPropertySingleValue",
    "Status",
    None,  # Description is optional
    ifc_file.create_entity("IfcText", "InProgress"),  # Nominal value
    None  # Unit is optional
)
				
			
  • What you’re doing: Creating a new IfcPropertySingleValue property value.
  • Why: To add specific properties to a property set.
  • What to keep in mind: Ensure that the property type and value are correct.
  • Common errors: Incorrect data types, missing required parameters.

6. Creating a new property set

				
					# Creating a new property set
property_set = ifc_file.create_entity(
    "IfcPropertySet",
    ifcopenshell.guid.new(),
    ifc_file.by_type("IfcOwnerHistory")[0],
    "BIMCorner",
    None,  # Description is optional
    [property_single_value_mmi, property_single_value_status]
)
				
			
  • What you’re doing: Creating a new IfcPropertySet.
  • Why: To group properties and assign them to objects.
  • What to keep in mind: Ensure that the property set has a unique GUID.
  • Common errors: Duplicate GUIDs, missing required parameters.

7. Iterating through objects and adding the property set:

				
					# Iterating through walls and adding the property set
for wall in walls:
    rel_defines = ifc_file.create_entity(
        "IfcRelDefinesByProperties",
        ifcopenshell.guid.new(),
        ifc_file.by_type("IfcOwnerHistory")[0],
        None,  # Description is optional
        None,  # Description is optional
        [wall],  # Related objects
        property_set  # Related property definitions
    )
				
			
  • What you’re doing: Iterating through all IfcWall entities and creating an IfcRelDefinesByProperties relationship that links these entities to the property set.
  • Why: IfcRelDefinesByProperties establishes a relationship between objects and their properties, allowing you to assign the property_set to each bridge part.
  • What to keep in mind: Ensure that each IfcWall entity has the relationship correctly assigned. You may add additional descriptions if needed to enhance readability.

7.1. Iterating through other types of objects (See section 4.1)

				
					for element in bridge_parts + walls + columns + beams + slabs + doors:
    rel_defines = ifc_file.create_entity(
        "IfcRelDefinesByProperties",
        ifcopenshell.guid.new(),
        ifc_file.by_type("IfcOwnerHistory")[0],
        None,  # Optional
        None,  # Optional
        [element],  # Related objects
        property_set  # Related property set
    )
				
			
  • What you’re doing: Iterating through all entities of different types (IfcBridgePart, IfcWall, IfcColumn, IfcBeam, IfcSlab, IfcDoor) and creating an IfcRelDefinesByProperties relationship that links these entities to the property set.
  • Why: This allows you to assign the property_set to various elements of the model.
  • What to keep in mind: Ensure that each entity of different types has the relationship correctly assigned. You can adjust the list of object types as needed for your project.
  • Common errors: Incorrectly iterating through objects, errors in creating the IfcRelDefinesByProperties relationship.

7.2. Iterating through objects with PredefinedType = USERDEFINED (See section 4.2)

				
					for attribute_target_object in attribute_target_objects:
    rel_defines = ifc_file.create_entity(
        "IfcRelDefinesByProperties",
        ifcopenshell.guid.new(),
        ifc_file.by_type("IfcOwnerHistory")[0],
        None,  # Optional
        None,  # Optional
        [attribute_target_object],  # Related objects
        property_set  # Related property sets
    )
				
			

7.3. Iterating through objects with the 'IfcPropertySingleValue' property 'Domain' set to 'Bridge' (See section 4.3)

				
					for property_target_object in property_target_objects:
    rel_defines = ifc_file.create_entity(
        "IfcRelDefinesByProperties",
        ifcopenshell.guid.new(),
        ifc_file.by_type("IfcOwnerHistory")[0],
        None,  # Optional
        None,  # Optional
        [property_target_object],  # Related objects
        property_set  # Related property sets
    )
				
			

Summary

As you may have noticed, using Python and ifcOpenShell provides us with incredible possibilities for easily and efficiently modifying IFC files. This example is just the beginning of the vast potential these tools offer. Moreover, once you master the basics of programming, you’ll unlock the door to creating your own unique applications that will streamline your work.

In the next article, I’ll guide you step by step on how to create such an application. I hope you find this topic fascinating, and that we’ll meet again to explore the world of programming in BIM together.

See you in the next installments!

Best regards,
Marcin

Did you like that post ? Share it with others !

We spend a lot of time and effort creating all of our articles and guides. It would be great if you could take a moment to share this post !

Share:

Comments:

Subscribe
Notify of
guest
0 Comments
Oldest
Newest
Inline Feedbacks
View all comments

Author:

Download BIM CASE STUDIES:

After reading this guide you will learn:

  • How BIM is used on the biggest projects in Norway
  • What were the challenges for the design team and how were they solved
  • What were the challenges on the construction site and what was our approach to them

Newest articles: