If you’re reading this, we assume you already know IFC and just want to quickly get started with IfcOpenShell.
This crash course guides you through basic code snippets that give you a general idea of the low-level functionality that IfcOpenShell-python provides. You’ll need to have IfcOpenShell installed and a sample IFC model. To get the most out of it, try out the code yourself and see what results you get!
If you don’t have an IFC model available, here’s a small one for your convenience provided by the Institute for Automation and Applied Informatics (IAI) / Karlsruhe Institute of Technology. It’s in German, so you may need to use some creativity when reading the data :)
Let’s start with loading the model. Import the IfcOpenShell module, then use the
open function to load the model into a variable called model.
import ifcopenshell model = ifcopenshell.open('/path/to/your/model.ifc')
Let’s see what IFC schema we are using:
print(model.schema) # May return IFC2X3, IFC4, or IFC4X3.
Let’s get the first piece of data in our IFC file:
But getting data from beginning to end isn’t too meaningful to humans. What if we knew a GlobalId value instead?
print(model.by_guid('0EI0MSHbX9gg8Fxwar7lL8'))
If we’re not looking specifically for a single element, perhaps let’s see how many walls are in our file, and count them:
walls = model.by_type('IfcWall') print(len(walls))
Once we have an element, we can see what IFC class it is:
wall = model.by_type('IfcWall')[0] print(wall.is_a()) # Returns 'IfcWall'
You can also test if it is a certain class, as well as check for parent classes too:
print(wall.is_a('IfcWall')) # Returns True print(wall.is_a('IfcElement')) # Returns True print(wall.is_a('IfcWindow')) # Returns False
Let’s quickly check the STEP ID of our element:
Let’s get some attributes of an element. IFC attributes have a particular order. We can access it just like a list, so let’s get the first and third attribute:
print(wall[0]) # The first attribute is the GlobalId print(wall[2]) # The third attribute is the Name
Knowing the order of attributes is boring and technical. We can access them by name too:
print(wall.GlobalId) print(wall.Name)
Getting attributes one by one is tedious. Let’s grab them all:
# Gives us a dictionary of attributes, such as: # {'id': 8, 'type': 'IfcWall', 'GlobalId': '2_qMTAIHrEYu0vYcqK8cBX', ... } print(wall.get_info())
Let’s see all the properties and quantities associated with this wall:
import ifcopenshell.util import ifcopenshell.util.element print(ifcopenshell.util.element.get_psets(wall))
Some attributes are special, called “inverse attributes”. They happen when another element is referencing our element. They can reference it for many reasons, like to define a relationship, such as if they create a void in our wall, join our wall, or define a quantity take-off value for our wall, among others. Just treat them like regular attributes:
Perhaps we want to see all elements which are referencing our wall?
print(model.get_inverse(wall))
Let’s do the opposite, let’s see all the elements which our wall references instead:
print(model.traverse(wall)) # Or, let's just go down one level deep print(model.traverse(wall, max_levels=1))
If you want to modify data, just assign it to the relevant attribute:
wall.Name = 'My new wall name'
You can also generate a new GlobalId:
wall.GlobalId = ifcopenshell.guid.new()
After modifying some IFC data, you can save it to a new IFC-SPF file:
model.write('/path/to/a/new.ifc')
You can generate a new IFC from scratch too, instead of reading an existing one:
ifc = ifcopenshell.file() # Or if you want a particular schema: ifc = ifcopenshell.file(schema='IFC4')
You can create new IFC elements, and add it either to an existing or newly created IFC file object:
# Will return #1=IfcWall($,$,$,$,$,$,$,$,$) - notice all of the attributes are blank! new_wall = model.createIfcWall() # Will return a list with our wall in it: [#1=IfcWall($,$,$,$,$,$,$,$,$)] print(model.by_type('IfcWall'))
Alternatively, you can also use this way to create new elements:
model.create_entity('IfcWall')
Specifying more arguments lets you fill in attributes while creating the element instead of assigning them separately. You specify them in the order of the attributes.
# Gives us #1=IfcWall('0EI0MSHbX9gg8Fxwar7lL8',$,$,$,$,$,$,$,$) model.create_entity('IfcWall', ifcopenshell.guid.new())
Again, knowing the order of attributes is difficult, so you can use keyword arguments instead:
# Gives us #1=IfcWall('0EI0MSHbX9gg8Fxwar7lL8',$,'Wall Name',$,$,$,$,$,$) model.create_entity('IfcWall', GlobalId=ifcopenshell.guid.new(), Name='Wall Name')
Sometimes, it’s easier to expand a dictionary:
data = { 'GlobalId': ifcopenshell.guid.new(), 'Name': 'Wall Name' } model.create_entity('IfcWall', **data)
Some attributes of an element aren’t just text, they may be a reference to another element. Easy:
wall = model.createIfcWall() wall.OwnerHistory = model.createIfcOwnerHistory()
What if we already have an element from one IFC file and want to add it to another?
wall = model.by_type('IfcWall')[0] new_model = ifcopenshell.file() new_model.add(wall)
Fed up with an object? Let’s delete it:
This is only a small sample of the basic building blocks of manipulating IFC data. IFC comes with a huge utility library and API for performing common tasks. See Code examples for more.