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.
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:
GlobalId
- set automatically and cannot be modified via the UI. It can, however be modified via the Revit API.OwnerHistory
- set automatically, I won't go into detail but suffice to say it is set with garbage data and cannot be relied upon for actual ownership historyName
- this is usually the "short name" or code of the project, it can be set by changing the "Project Number" attribute.Description
- this can be set by creating a new project parameter (shared or otherwise) calledIfcDescription
, and making it available to the "Project Information" category. Please ensure that you group this parameter under a group named "IFC Parameters".ObjectType
- this can be set by creating a new project parameter (shared or otherwise) calledIfcObjectType
and making it available to the "Project Information" category. Please ensure that you group this parameter under a group named "IFC Parameters".LongName
- this is the full project name, and can be set by changing the "Project Name" attribute.Phase
- the project phase is set by the "Project Status" attribute.RepresentationContexts
- Revit will automatically define only one representation context, which will be a 3-dimensional model, with a coordinate system and true north.UnitsInContext
- the units are taken from your "Project Units" settings. It is generally correct. Units can get pretty confusing in IFC with unit definitions and IFC sometimes advocating specific units in certain attributes, but this is not a Revit problem, this is an IFC problem.
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.
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.
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.
Next.
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?
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.