How to create better IFC files with Revit

Dion Moult


IFC is the ISO standard of how BIM data should be stored. Revit is one of the two BIM programs used by almost all players in the AEC industry. Autodesk is also one of the corporate bodies behind the creation of the IFC ISO standard. It should therefore stand to reason that creating and exporting high quality IFC files out of Revit should be easy. Unfortunately, this isn't the case, and poor IFC support is one of Revit's biggest problems.

In this article, I will walk through some of the fundamental concepts in IFC, and explain how to capture that data with Revit, so that the quality of your BIM data improves, and the longevity of the BIM digital twin can be increased. In contrast, if you simply supply a .rvt file to your clients, you are merely providing a BIM model with a shelf-life of 3 years (the lifespan of Autodesk support), and with no guarantee of interoperability or quality of the BIM data structure.

To start with, I will be blunt and advise that the out-of-the-box Revit provides extremely poor IFC export and import support. For this reason, there is an open-source IFC import and export plugin for Revit. Without installing this, there is little you can do with Revit. If you know how to compile it yourself, please compile the "Dev" branch, as that will give you the latest features, as it is a moving target as with most open-source things. You will need to install this to follow the rest of this article.

The export dialog of the Revit open source IFC exporter

Finally, Autodesk as produced the Autodesk Revit IFC Manual 2018 which helps describe the various options of this open source IFC exporter. Give it a read, as it will explain all the options in the exporter. It's a little vague on a few points, but hopefully this article will help clear things up.

Revit and IFC version support

One of the first questions people ask is what's the difference between the IFC versions that you can choose to export to.

Most of the industry (at least from my experience in Australia) is still producing IFC2x3. However, IFC2X3 lacks many features of IFC4, so in an ideal world we should aim to produce IFC4 IFCs as much as possible. However, although Autodesk's marketing department might tell you otherwise, IFC4 support in Revit is currently quite hit and miss, although from watching the commits, it is slowly improving. I would recommend trying to export your project in both IFC2X3 and IFC4. If all the geometry is able to be exported in IFC4, then I would use IFC4, because there are ways to set the attributes and data. If the geometry itself cannot be exported, but it works in IFC2X3, then you have little choice but to stick with IFC2X3, as geometry representation is not one of those things you can easily control in Revit.

Fundamental IFC concepts

IFC is a bold attempt to improve the transparency and interoperability of BIM data in the industry. It does this by creating a technical specification that BIM vendors (Autodesk, Graphisoft, FreeCAD), and BIM authors (yourself) attempt to follow.

This IFC specification defines different types of elements, procedures, people, and concepts found in the building industry. These concepts have different data associated with them, which should be organised in a certain way to be easily analysed and discovered. Not all concepts are physical! They can refer to people and timelines. If an element is a physical object, like walls and floors, it can have a geometric representation association with them. This allows us to see our buildings digitally in 2D or 3D. Other data, such as for quantity take-off, doesn't need to have any geometry associated with it, so a QS can work purely with raw data.

It is important to have a grasp of these fundamental concepts, which can be found in Chapter 4, IFC fundamental concepts and assumptions in the latest IFC4 specification. If you think that IFC is merely about calling some shapes walls, and other shapes floors, and hopefully opening it in one program and another, you will be surprised to find that IFC offers much more insight than that, if people used it properly, that is.

IFC project declaration in Revit

The most funamental concept is the ability to declare your project. The "project" is not a visible element in Revit, but it does have attributes associated with it. Below is a list of these attributes.

Most of the values for these attributes are derived from your "Project Information" settings. When you export an IFC, Revit will automatically create one IfcProject. Let's see what the attributes are, and where to go to set them correctly:

If you're curious where these attributes are specified, you can read the IfcProject specification page.

The coordinate system of the IfcGeometricRepresentationContext is used to define the offset of the project coordinates from the global point of origin. This seems to always be set to (0, 0, 0), and I don't think there is a way to change that through the UI. By default, true north is Y, east is X, and up / elevation is Z. Please note that the IfcProject does not define the site location.

It is not currently possible to have another IfcGeometricRepresentationContext to represent plan views out of IFC. Yes, IFC can support native plan views, not just derived plan views from IFC 3D representations, but Autodesk doesn't allow you to unfortunately.

Project library

IFC files don't necessarily only contain a BIM project. Just as you have Revit families, and can somewhat propagate shared parameters, IFC allows you to create project libraries that define either types of objects or groups of properties (known as property sets in IFC lingo). Technically, you could create your families in IFC format, and it can have parametric data stored within it, and other programs like FreeCAD or GeometryGym use this functionality.

This is not possible within Revit.

IFC object definitions and object type definitions in Revit

There are many objects that are defined in IFC. In Revit, you are used to categories such as walls, floors, ceilings, and columns. Similarly, in IFC, there is IfcWall, IfcSlab, IfcCovering, and IfcColumn. IFC has more object "classes" than what is defined in Revit, and goes into more detail and across more disciplines. Therefore, when you export to an IFC, you will have to "map" your Revit categories to IFC object "classes".

All object occurrences are defined by a mapping table supplied by Autodesk that maps Revit family categories to IFC objects. You can see this by going to File -> Export -> Options -> IFC Options. IFC objects are defined as subclasses of IfcObject, whereby you will most commonly be dealing with subclasses of IfcProduct, such as walls, beams, etc.

Autodesk Revit IFC object mapping configuration dialog

You will notice that the mapping table has two columns: one for IFC Class Name and one for IFC Type. This is, however, extremely misleading because the IFC Type field does not refer to the IFC object type. For example, an IfcBeam has an associated IfcBeamType, which serves a purpose similar to a parent class to which attributes / property sets / geometric representations can be inherited from (and overriden in the child).

Instead, the IFC Type field actually refers to PredefinedType attribute that exists for both IFC objects and IFC object types. These are basically more detailed subcategories of the semantic IFC class name. For example, an IfcBeam has a PredefinedType attribute which may contain an enum of IfcBeamTypeEnum, where you can specify your beam to be a BEAM, JOIST, HOLLOWCORE, LINTEL, and so on. So the IFC Type field is actually referring to the enum value, which must be defined in all uppercase. In the screenshot above, CONDUITSEGMENT is an enum value of IfcCableCarrierSegmentTypeEnum.

There is a fundamental problem in Revit whereby the semantic object you are modeling determines what modeling capabilities you have. If you want to model a roof, you don't necessarily get the same tools as modeling a floor, even though geometrically they can be very similar. This leads to people misusing objects for inappropriate IFC types. Thankfully, there is some way to mitigate this by ensuring that it is exported correctly into IFC, regardless of the Revit category being used.

If you add a project parameter called IfcExportAs (type or instance, both works) as a text parameter and place it in the IFC Parameters group, then you can override the IFC class and predefined type on an instance-by-instance or type-by-type basis. For instance, if you create a new generic in-place model, and type in IfcCovering, and export it into an IFC, it will turn into an IfcCovering object. If you alternatively type in IfcCovering.SKIRTINGBOARD, you will export it as an IfcCovering object, and its PredefinedType attribute will be set to SKIRTINGBOARD. This pattern of IfcClass.ENUMVALUEINUPPERCASE generally works for all classes and types. This is a great way of adding semantics to generic models.

If you are only interested in setting the PredefinedType but keeping the IFC Class, you can add a project parameter called IfcExportType, and fill it simply with SKIRTINGBOARD. Yes, this is a double up in functionality with the IfcExportAs parameter, but I'm mentioning it for completeness.

However, keep in mind that this trick only works with user-created families and in-place models. It does not work on system families. If somebody decides to model a fence using the railing tool or an office partition with a curtain wall, you can't fix it.

IFC object attributes in Revit

Each IFC object subclass has a series of attributes that are composed of the attributes of that particular class, as well as the attributes inherited by any parent classes. In the latest IFC4Add2 specification, it is now very easy to see this as each IFC object page has a section called "Attribute Inheritance", which lists it all out for you.

For instance, an IfcWall inherits GlobalId, OwnerHistory, Name, and Description from its parent IfcRoot. You will notice that this is the same as IfcProject above. This is because both IfcWall and IfcProject inherit from IfcRoot. Just like IfcProject, the GlobalId and OwnerHistory attributes are special and behave as described above. However, just like in IfcProject the Name field is special, the Name field of an IfcWall is also special (this applies to most IfcObject children). By default, it will be named after the family name, followed by the family type name, followed by the family type "tag", which is an autogenerated numerical ID. These 3 values are concatenated together with the ":" symbol as a separator. If it is an in-place family, it will use the in-place model name twice as the first two fields.

If you want a much more sensible name, you can set its Name value manually. Just create a parameter called IfcName and add to to the IFC Parameters group. This is the same technique used to set the Description attribute.

This pattern of adding a parameter named after the attribute and prefixed with Ifc is common to all attributes. For instance, an IfcWall also has an attribute called Tag (which is ambiguous, but we'll complain about that later). You can set the value of Tag by creating a parameter called IfcTag.

IFC object types in Revit

As opposed to PredefinedType, there is the true concept of object types in IFC. Any IfcObject can have a type definition relationship (IfcRelDefinesByType, or inverse IsTypedBy) to an IfcTypeObject. This corresponds roughly (but not exactly) to the selected type of the Revit family of that object.

For instance, if you create a new wall in Revit of a wall family "Basic Wall", and choose the type "Wall 1", then your IfcWall will by isTypedBy an IfcWallType with the name Wall 1. In IFC nomenclature, this is the proper place you should store the human referrable name. For instance, walls are often given human codes that correspond to a construction type, such as BLK01, or CON03, or PTN05. In Revit, although your company might have a standard, it is ambiguous whether it is stored as a type name, type mark, mark, keynote, or something else entirely. In IFC, the proper place to store it is in the IfcTypeObject's Name attribute. Given the default mapping, this must mean that you need to name your Revit family type name's after your construction type if you want proper IFC exports.

However, it is also possible to override the Name attribute using the trick of creating an IfcName parameter in the IFC Parameters group, but this time setting it as a type based parameter instead of an instance based parameter. Now you can set it to whatever you want.

This creates a little catch: Revit doesn't usually allow two parameters with the same name, one as a type-based, and one as an instance-based parameter. This limits you to either name your types properly, or name your elements properly, but not both. One workaround, which may be considered bad Revit practice, is to have one as a project parameter (say, your instance-based one for convention) and one as a shared parameter (say, your type-based one). This allows Revit to have two parameters that are named the same. As long as you don't have any scripts which use the name as the identifier, you'll be OK with this approach, but it can be confusing.

This issue also occurs with the Description attribute. It also occurs with any attribute that shares a name between objects and object types. This includes property sets - you can set property set parameters to be type based to assign that property set attribute to the object type - but you will run into this limitation where you have to choose either instance or type.

You will probably notice at this stage that IFC type objects created by Revit have their tag filled out automatically with a generated numerical ID. It's probably some internal ID which you can query with the API, though I haven't tested this. You can override it just like any other attribute, with no known ill effect.

Setting IFC object property sets in Revit

Property sets are basically groups of parameters which can be further set on object and object types. In IFC, each object or type has a list of related property sets which apply to it. Some of these are specific to that class of IFC object, and some apply to many objects.

You can export IFC property set data by checking these two boxes in the IFC setup settings.

Revit IFC property set export settings

It is not compulsory to fill this property set data in. In contrast, Revit has properties which always show even if you have no intention of filling them in, and the absence of information may sometimes be misinterpreted as intentional data (such as the default value of a boolean checkbox). This is known as the NULL vs empty problem in Revit, and can mislead BIM users. In IFC, you do not need to include a property unless you want to fill it with information.

For instance, an IfcWall can have the Pset_WallCommon property set applied to it. This property set has attributes such as AcousticRating, FireRating, ThermalTransmittance, LoadBearing and so on. Although there is room for improvement, there is generally a sensible set of attributes defined in IFC.

In addition, if your IfcWall is concrete, you can use the Pset_ConcreteElementGeneral and describe attributes such as ConstructionMethod (In-Situ / Precast), StrengthClass, and ReinforcementVolumeRatio, among others. If your wall isn't concrete, you simply exclude this property set.

If you have additional details specific to your project, then you can always create your own property sets and create your own attributes. We'll see how to do this soon. Ideally, you should create an IfcProjectLibrary so that people know what to expect in your project, but as mentioned above, it is not possible to create project libraries in Revit.

Let's say we wanted to set the FireRating value of our IfcWall in the Pset_WallCommon property set. You can do this by creating a new project parameter (probably type based, this time) called FireRating and placing it in the IFC Parameters parameter group and filling it out with whatever you want. In Australia, a value might be something like 120/120/120 for a 2-hour fire rated wall.

I chose the FireRating attribute because Revit actually already has a Fire Rating attribute (notice the space) in its Identity Data parameter group out of the box. Because this exists, Autodesk has hard-coded this value to set the IFC FireRating attribute by default. However, if both the Fire Rating parameter and the IFC FireRating parameter exists in your file, the latter will take priority, including empty values (see the NULL vs empty problem described above).

For properties such as AcousticRating where there is no OOTB Revit equivalent, you will always need to add your own project parameter.

Notice that these project parameters are not suffixed with Ifc and do not mention which property set it is part of. That is because by default Revit only deals with "common" property sets, like Pset_WallCommon. However, it is not clear what is "common" and what isn't. For instance, you will find that if you tried to define StrengthClass from Pset_ConcreteElementGeneral it works, however if you tried to define EutrophicationPerUnit from Pset_EnvironmentalImpactIndicators, it won't work. You will need to trial your required data on a case by case basis.

What if you wanted to set your own property set, or wanted to overcome an issue where Revit doesn't support the property like the EutrophicationPerUnit example above? This can be done by setting values in the DefaultUserDefinedParameterSets.txt file that the exporter comes with. Here is an example of setting a custom FooBar property in My_Own_Property_Set for IfcWall instances, as well as the ClimateChangePerUnit for Pset_EnvironmentalImpactValues.

# User Defined PropertySet Definition File
# Format:
#    PropertySet:   <Pset Name> I[nstance]/T[ype]   <element list separated by ','>
#   <Property Name 1>   <Data type> <[opt] Revit parameter name, if different from IFC>
#   <Property Name 2>   <Data type> <[opt] Revit parameter name, if different from IFC>
#   ...
# Data types supported: Area, Boolean, ClassificationReference, ColorTemperature, Count, Currency, 
#   ElectricalCurrent, ElectricalEfficacy, ElectricalVoltage, Force, Frequency, Identifier, 
#   Illuminance, Integer, Label, Length, Logical, LuminousFlux, LuminousIntensity, 
#   NormalisedRatio, PlaneAngle, PositiveLength, PositivePlaneAngle, PositiveRatio, Power, 
#   Pressure, Ratio, Real, Text, ThermalTransmittance, ThermodynamicTemperature, Volume, 
#   VolumetricFlowRate
PropertySet:    My_Own_Property_Set I   IfcWall
    FooBar  Text

PropertySet:    Pset_EnvironmentalImpactValues  I   IfcWall
    ClimateChangePerUnit    Real

Once this file has been updated, the exporter will recognise your properties and place them in property sets.

There are a few caveats. For instance, if you wanted to record the TotalPrimaryEnergyConsumptionPerUnit, you will notice that its value is an IfcEnergyMeasure. This is not one of the supported data types in the mapping file. If you check the data type definition, you will see that it is fundamentally a REAL value. Therefore, although it isn't ideal, you can record it as a Real type in the mapping text file.

You might also notice that if you try to record the WaterConsumptionPerUnit, it will successfully record it as an IfcVolumeMeasure with no mapping required. But, what unit is it in? The IFC spec states that it is usually measured in m3, but what about our unit definitions at the beginning of the export? Revit completely ignores your unit settings and will think your value is in cubic metres. But, Revit also records a conversion factor in the IFC file to convert between cubic metres and cubic feet. So depending on your viewer, it might apply the conversion factor to show it to you in cubic feet if you then open your file elsewhere. Sound confusing? That's because it is.

IFC type property sets in Revit

Property sets for types are very similar to property sets for objects, except that is applies to types, not instances, and also is defined differently in the STEP syntax (an attribute as opposed to a relationship). Go fish.

Just change your parameters to be type based instead of instance based and it will create a property set for the object type rather than the object. However, you will run into the unique parameter name issue I describe above.

IFC performance property sets

IFC has a great concept where you can document the actual performance of a built object over time - e.g. machine-measured data from building automation systems and human specified data such as task and resource usage. This can be predicted, such as from a simulation, or it can be actual recordings, to verify the performance of a building. This can be specified at different life-cycle phases of the building.

This can't be done in Revit to my knowledge.


Quantity surveying and quantity take-off in Revit

IFC has the concept of a special set of properties which can be set for each object to define quantities. This can be quantities such as counts, lengths, areas, and volumes, and are designed to be useful for quantity surveyors to easily quantify different elements from the BIM model. They are similar to property sets, but are treated a little specially under-the-hood.

The geometric representation therefore does not need to necessarily be 100% accurate, or even exist at all, as long as these values are filled in correctly. You may have noticed that Revit does actually understand quantities, so let's see how they translate into IFC.

Pop quiz time: if you draw a wall length of 18ft, joined to another wall at one end, with a void in it (either via profile, void cut, or hosted door / window / element), what length should be recorded for quantity take-off purposes in IFC, and what length value will you see when you export it out of Revit?

An example scenario of a wall

The answer is that your IFC file will contain absolutely nothing at all. By default, Revit will not export any quantity values into IFC. This means your model is useless if a QS wants to use the IFC file to do quantity take-off (odds are, they aren't doing it this way anyway, but ... we're talking about an ideal future here).

Let's play fair this time. Let's say you click the checkbox in the export properties that isn't on by default that says "export base quantities". Now, what value will you expect? 18ft? Less? Will it take into account that the wall profile starts and stops?

The answer is 18.33333ft. Or something else, depending on how the wall decided to join to the other wall. No, it won't consider the gaping hole. Does this have any correlation with the greyed out "Dimensions" parameter group in your Revit properties? Nope.

What about areas and volumes? Well, Revit will record a value called NetSideArea and NetSideVolume which is meant to be the full volume minus any penetrations or holes. Does it actually consider the penetrations when recording these values? Nope. In fact, it is misnamed. It should instead be recorded as GrossSideArea and GrossVolume.

It's also worth mentioning that NetSideVolume is not actually a valid IFC quantity name. The real name is NetVolume, not NetSideVolume. Revit seems to have gotten the quantity names all mixed up.

What happens if you export both Revit properties and quantity base properties? You'll get multiple quantity readouts depending on where they look, and both will give different values, maybe in the right place, maybe not, and maybe with the right name, maybe not.

Can you override any of these things to fix it manually? No.

The moral of the story is that quantities are currently hopelessly broken in Revit and if your QS trusts it, get a new QS. In contrast, the open-source BIM tool FreeCAD has an IFC quantities auditor - Revit should learn a thing or two from FreeCAD.

Next steps to creating better IFC files

This post covers the basics of IFC, and doesn't cover many other concepts such as relationships, associations, classifications, parametric data, and composition ... and not to mention we haven't even talked about geometry! However, I believe it should give a relatively good introduction to the current capabilities of Revit an OpenBIM, which is to say, not much, but at least it's something. At the very least, you'll be able to neaten up some of your parameter storage and improve some data export.

In the future, should time permit, I will cover more IFC concepts in another article.


If you have any comments, please send them to