GOPHERSPACE.DE - P H O X Y
gophering on thinkmoult.com
# How to create better IFC files with Revit

 - Author: Dion Moult
 - Date: 2019-03-12

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:

-   `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 history
-   `Name` - 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) called `IfcDescription`, 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) called `IfcObjectType` 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.

![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:    I[nstance]/T[ype]   
    #       <[opt] Revit parameter name, if different from IFC>
    #       <[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?

![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.

Reference: poor IFC support is one of Revit's biggest problems
Reference: open-source IFC import and export plugin for Revit
Reference: The export dialog of the Revit open source IFC exporter
Reference: Autodesk Revit IFC Manual 2018
Reference: Chapter 4, IFC fundamental concepts and assumptions
/HTML/schema/chapter-4.htm
Reference: latest IFC4 specification
Reference: specification page
Reference: Autodesk Revit IFC object mapping configuration dialog
Reference: Revit IFC property set export settings
Reference: `Pset_WallCommon`
Reference: data type definition
energymeasure.htm
Reference: usually measured in m3
fcvolumemeasure.htm
Reference: An example scenario of a wall
Reference: FreeCAD has an IFC quantities auditor

## Comments

If you have any comments, please send them to dion@thinkmoult.com.

## License

This work is licensed under a Creative Commons Attribution-ShareAlike 4.0
International License, unless explicitly mentioned in the article.