Extract data from .ifc files

So here a brief tutorial using Python and Pandas to get metrics and dimensions from an .ifc file. Special thanks to Dion Moult for his IfcOpenShell tutorial.

I don't pretend this is the best way to do it, but since IFC is OpenBIM, why not use open source applications and librairies?

First, you will need an 2x3 .ifc with quantities options checked. I took a basic Revit project to export the sample. You can download the file here.

This is the final code you will do, but we need to check basics functions before.

#get walls by function based on dict
import pandas as pd
import ifcopenshell
file = ifcopenshell.open('Technical_school.ifc')

def getQty(ifcClass):
    L =[]
    for i in ifcClass:
        data ={}
        for j in i.IsDefinedBy:
            try:
                if 'BaseQuantities' == j.RelatingPropertyDefinition.Name:
                    data["Name"]=i.ObjectType
                    for k in j.RelatingPropertyDefinition.Quantities:
                        data[k.Name] =k[3]                       
            except:
                pass 
        L.append(data)
    return L

quant = getQty(file.by_type('IfcWall'))

df = pd.DataFrame(quant).dropna().set_index('Name')
df.drop(columns = ['Width','NetVolume','NetSideArea','GrossFootprintArea','NetVolume'],inplace=True)

df['Area sq.m'] = df['Height']*df['Length']/1000**2
df.groupby('Name').sum().round()

I use Jupyter NoteBook as my main Python IDE. Pandas is pre-install with it, but you must install IfcOpenShell manually.

Ready? Now lets check the library basics.

Check with dir() function what you can do with the ifc. At the bottom you can see some interesting function such as by_guid(), by_id() and by_type().

Let's try by_guid()

The guid is the GlobaId of the element as shown in the xBIm explorer

The result will be the same if you using by_id() with the Ifc Label (165210).

Now let's look at a single wall properties.

i use xBIM explorer (free and easy to use)

So many attributes, but easy to get with a dot notation.

The attribute for quantities is inside the propertie IsDefinedBy.

Instead of the Id, another option is to select the first element on IfcWall by_type()

Each IfcRelDefinesByProperties has also attributes. The one we are looking for is the RelatingPropertyDefinition. But since IfcRelDefinesByType does not have it you can use a try/except in the for loop to skip.

Or better, you can filter the result if the ifcRelDefinesByProperties Name is equal to BaseQuantities! Note that will works for many IfcClasses, but not all.

Let's check a single quantity attributes.

And here's the name of each quantities

And the values at index 3 of each

Create function to simplify and reuse the coding

Next step is to create a function to get data of every instances of a specified class (i.e. : wall), but we also want to format the data in a list of dictionaries.

def getQty(ifcClass):
    L =[]
    for i in ifcClass:
        data ={}
        for j in i.IsDefinedBy:
            try:
                if 'BaseQuantities' == j.RelatingPropertyDefinition.Name:
                    data["Name"]=i.ObjectType #name of the class instance
                    for k in j.RelatingPropertyDefinition.Quantities:
                        data[k.Name] =k[3] #create a pair of key:value (aka dict)                     
            except:
                pass 
        L.append(data)
    return L

Using DataFrame in Pandas

Then we will use Pandas to create a DataFrame (think of Excel). We will drop empty values and set the Name as indexes.

Now we can also drop columns that we don't need.

What if you want to add a new column base on formula? Easy with Pandas.

Last step is to group instance by indexes names. We also want to sum values and round it.

Others IfcClasses

Bonus : export to Excel

I use xlswriter for Python.

The Excel file will be in your folder, check the result here.

Conclusion

So what the point of coding all this? Well technically, now you can get quantities from any ifc files and reuse the code for other classes. And think about it a second : get data and format it, isn't in the core of BIM?

Last updated