Difference between revisions of "IfcOpenShell code examples"
Line 1: | Line 1: | ||
− | To load a file, you'll need to import IfcOpenShell and store the IFC file in a variable. We'll use the variable <code>ifc</code>. | + | To load a file, you'll need to import IfcOpenShell and store the IFC file in a variable. We'll use the variable <code>ifc</code>. The <code>ifc</code> will be then used throughout. |
− | <syntaxhighlight lang="python" | + | <syntaxhighlight lang="python"> |
import ifcopenshell | import ifcopenshell | ||
ifc = ifcopenshell.open('/path/to/your/file.ifc') | ifc = ifcopenshell.open('/path/to/your/file.ifc') | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Let's see what IFC schema we are using: | ||
+ | |||
+ | <syntaxhighlight lang="python"> | ||
+ | print(ifc.schema) # May return IFC2X3 or IFC4 | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Let's get the first piece of data in our IFC file: | ||
+ | |||
+ | <syntaxhighlight lang="python"> | ||
+ | print(ifc.by_id(1)) | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | But getting data from beginning to end isn't too meaningful to humans. What if we knew a <code>GlobalId</code> value instead? | ||
+ | |||
+ | <syntaxhighlight lang="python"> | ||
+ | print(ifc.by_guid('0EI0MSHbX9gg8Fxwar7lL8')) | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | If we're not looking specifically for a single element, perhaps let's see how many walls are in our file, and count them: | ||
+ | |||
+ | <syntaxhighlight lang="python"> | ||
+ | walls = ifc.by_type('IfcWall') | ||
+ | print(len(walls)) | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Once we have an element, we can see what IFC class it is: | ||
+ | |||
+ | <syntaxhighlight lang="python"> | ||
+ | wall = ifc.by_type('IfcWall')[0] | ||
+ | print(wall.is_a()) # Returns 'IfcWall' | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | You can also test if it is a certain class, as well as check for parent classes too: | ||
+ | |||
+ | <syntaxhighlight lang="python"> | ||
+ | print(wall.is_a('IfcWall')) # Returns True | ||
+ | print(wall.is_a('IfcElement')) # Returns True | ||
+ | print(wall.is_a('IfcWindow')) # Returns False | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Let's quickly check the STEP ID of our element: | ||
+ | |||
+ | <syntaxhighlight lang="python"> | ||
+ | print(wall.id()) | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | 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: | ||
+ | |||
+ | <syntaxhighlight lang="python"> | ||
+ | print(wall[0]) # The first attribute is the GlobalId | ||
+ | print(wall[2]) # The third attribute is the Name | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Knowing the order of attributes is boring and technical. We can access them by name too: | ||
+ | |||
+ | <syntaxhighlight lang="python"> | ||
+ | print(wall.GlobalId) | ||
+ | print(wall.Name) | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Getting attributes one by one is tedious. Let's grab them all: | ||
+ | |||
+ | <syntaxhighlight lang="python"> | ||
+ | print(wall.get_info()) # Gives us a dictionary of attributes, such as {'id': 8, 'type': 'IfcWall', 'GlobalId': '2_qMTAIHrEYu0vYcqK8cBX', ... } | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Let's see all the properties and quantities associated with this wall: | ||
+ | |||
+ | <syntaxhighlight lang="python"> | ||
+ | print(ifcopenshell.util.get_psets(wall)) | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | 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: | ||
+ | |||
+ | <syntaxhighlight lang="python"> | ||
+ | print(wall.IsDefinedBy) | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Perhaps we want to see all elements which are referencing our wall? | ||
+ | |||
+ | <syntaxhighlight lang="python"> | ||
+ | print(ifc.get_inverse(wall)) | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Let's do the opposite, let's see all the elements which our wall references instead: | ||
+ | |||
+ | <syntaxhighlight lang="python"> | ||
+ | print(ifc.traverse(wall)) | ||
+ | print(ifc.traverse(wall, max_levels=1)) # Or, let's just go down one level deep | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | If you want to modify data, just assign it to the relevant attribute: | ||
+ | |||
+ | <syntaxhighlight lang="python"> | ||
+ | wall.Name = 'My new wall name' | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | You can also generate new <code>GlobalId</code>s: | ||
+ | |||
+ | <syntaxhighlight lang="python"> | ||
+ | wall.GlobalId = ifcopenshell.guid.new() | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | After modifying some IFC data, you can save it to a new IFC-SPF file: | ||
+ | |||
+ | <syntaxhighlight lang="python"> | ||
+ | ifc.write('/path/to/a/new.ifc') | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | You can generate a new IFC from scratch too, instead of reading an existing one: | ||
+ | |||
+ | <syntaxhighlight lang="python"> | ||
+ | ifc = ifcopenshell.file() | ||
+ | # Or if you want a particular schema: | ||
+ | ifc = ifcopenshell.file(schema='IFC4') | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | You can create new IFC elements, and add it either to an existing or newly created IFC file object: | ||
+ | |||
+ | <syntaxhighlight lang="python"> | ||
+ | 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($,$,$,$,$,$,$,$,$)] | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Alternatively, you can also use this way to create new elements: | ||
+ | |||
+ | <syntaxhighlight lang="python"> | ||
+ | ifc.create_entity('IfcWall') | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | 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. | ||
+ | |||
+ | <syntaxhighlight lang="python"> | ||
+ | ifc.create_entity('IfcWall', ifcopenshell.guid.new()) # Gives us #1=IfcWall('0EI0MSHbX9gg8Fxwar7lL8',$,$,$,$,$,$,$,$) | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Again, knowing the order of attributes is difficult, so you can use keyword arguments instead: | ||
+ | |||
+ | <syntaxhighlight lang="python"> | ||
+ | ifc.create_entity('IfcWall', GlobalId=ifcopenshell.guid.new(), Name='Wall Name') # Gives us #1=IfcWall('0EI0MSHbX9gg8Fxwar7lL8',$,'Wall Name',$,$,$,$,$,$) | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Sometimes, it's easier to expand a dictionary: | ||
+ | |||
+ | <syntaxhighlight lang="python"> | ||
+ | data = { | ||
+ | 'GlobalId': ifcopenshell.guid.new(), | ||
+ | 'Name': 'Wall Name' | ||
+ | } | ||
+ | ifc.create_entity('IfcWall', **data) | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Some attributes of an element aren't just text, they may be a reference to another element. Easy: | ||
+ | |||
+ | <syntaxhighlight lang="python"> | ||
+ | wall = ifc.createIfcWall() | ||
+ | wall.OwnerHistory = ifc.createIfcOwnerHistory() | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | What if we already have an element from one IFC file and want to add it to another? | ||
+ | |||
+ | <syntaxhighlight lang="python"> | ||
+ | wall = ifc.by_type('IfcWall')[0] | ||
+ | new_ifc = ifcopenshell.file() | ||
+ | new_ifc.add(wall) | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Fed up with an object? Let's delete it: | ||
+ | |||
+ | <syntaxhighlight lang="python"> | ||
+ | ifc.remove(wall) | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Revision as of 07:06, 19 June 2020
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++ |