IfcOpenShell code examples
Before getting started, you may be interested in Using the Python console with BlenderBIM Add-on, to quickly install all the software and development environment you need to get started, without any administrator privileges required.
To load a file, you'll need to import IfcOpenShell and store the IFC file in a variable. We'll use the variable ifc
. The ifc
will be then used throughout.
import ifcopenshell
ifc = ifcopenshell.open('/path/to/your/file.ifc')
Let's see what IFC schema we are using:
print(ifc.schema) # May return IFC2X3 or IFC4
Let's get the first piece of data in our IFC file:
print(ifc.by_id(1))
But getting data from beginning to end isn't too meaningful to humans. What if we knew a GlobalId
value instead?
print(ifc.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 = ifc.by_type('IfcWall')
print(len(walls))
Once we have an element, we can see what IFC class it is:
wall = ifc.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:
print(wall.id())
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:
print(wall.get_info()) # Gives us a dictionary of attributes, such as {'id': 8, 'type': 'IfcWall', 'GlobalId': '2_qMTAIHrEYu0vYcqK8cBX', ... }
Let's see all the properties and quantities associated with this wall:
print(ifcopenshell.util.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:
print(wall.IsDefinedBy)
Perhaps we want to see all elements which are referencing our wall?
print(ifc.get_inverse(wall))
Let's do the opposite, let's see all the elements which our wall references instead:
print(ifc.traverse(wall))
print(ifc.traverse(wall, max_levels=1)) # Or, let's just go down one level deep
If you want to modify data, just assign it to the relevant attribute:
wall.Name = 'My new wall name'
You can also generate new GlobalId
s:
wall.GlobalId = ifcopenshell.guid.new()
After modifying some IFC data, you can save it to a new IFC-SPF file:
ifc.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:
new_wall = ifc.createIfcWall() # Will return #1=IfcWall($,$,$,$,$,$,$,$,$) - notice all of the attributes are blank!
print(ifc.by_type('IfcWall')) # Will return a list with our wall in it: [#1=IfcWall($,$,$,$,$,$,$,$,$)]
Alternatively, you can also use this way to create new elements:
ifc.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.
ifc.create_entity('IfcWall', ifcopenshell.guid.new()) # Gives us #1=IfcWall('0EI0MSHbX9gg8Fxwar7lL8',$,$,$,$,$,$,$,$)
Again, knowing the order of attributes is difficult, so you can use keyword arguments instead:
ifc.create_entity('IfcWall', GlobalId=ifcopenshell.guid.new(), Name='Wall Name') # Gives us #1=IfcWall('0EI0MSHbX9gg8Fxwar7lL8',$,'Wall Name',$,$,$,$,$,$)
Sometimes, it's easier to expand a dictionary:
data = {
'GlobalId': ifcopenshell.guid.new(),
'Name': 'Wall Name'
}
ifc.create_entity('IfcWall', **data)
Some attributes of an element aren't just text, they may be a reference to another element. Easy:
wall = ifc.createIfcWall()
wall.OwnerHistory = ifc.createIfcOwnerHistory()
What if we already have an element from one IFC file and want to add it to another?
wall = ifc.by_type('IfcWall')[0]
new_ifc = ifcopenshell.file()
new_ifc.add(wall)
Fed up with an object? Let's delete it:
ifc.remove(wall)
Samples from web
Subject | Language | Version | Additional infos |
---|---|---|---|
Understanding placements in IFC using IfcOpenShell and FreeCAD | python | 0.6.0a1 | FreeCAD 0.18 git |
Using IfcOpenShell to parse IFC files with Python | python | ||
Read geometry as Boundary Representation in FreeCAD | python | 0.6.0a1 | FreeCAD 0.18 git |
Read IFC geometry as triangle meshes in FreeCAD | python | 0.6.0a1 | FreeCAD 0.18 git |
Using IfcOpenShell and C++ to generate Alignments through the IFC 4×1 schema | python/C++ | ||
Creating a simple wall with property set and quantity information | python | ||
Using IfcOpenshell and pythonOCC to generate cross sections directly from an IFC file | python | <= 0.6 ? | pythonOCC 0.16.0 ? |
Using the parsing functionality of IfcOpenShell interactively | python | ||
Using IfcOpenShell and pythonOCC to construct new geometry | python | <= 0.6 | pythonOCC 0.16.0 |
Various ifc creation examples (little house, geometry etc…) | C++ |