Beta · This site is in preview and not yet officially launched.
Revit47 min read

IFC export audit checklist before issuing the file

An IFC export that opens in your viewer can still be wrong. A six-point audit catches the issues clients notice before they notice them.

BIM Mobius
with DTDucas

1. Lede: Looks Fine in the Viewer, Fails at the Consultant

You open the IFC in Solibri. Everything renders. Walls show up as walls, doors swing, the floors stack in the right order. You drag a section through the building: it looks like the model. You check the properties panel for a random wall and spot the fire-rating parameter. Satisfied, you issue the file.

Two days later, the structural consultant comes back with a screenshot. The building is sitting 47 metres north of where it should be. The floor plate is there, the geometry is correct, but it is in the wrong country, geographically speaking. The clash-detection session they ran against their Tekla model produced zero real clashes and several hundred phantom ones — because the two coordinate origins do not match.

Or: the MEP contractor runs a quantity extract. The GrossVolume on the concrete walls is reporting 1,000 times the expected value — a unit conversion artefact in the Revit IFC exporter that was present in older builds and that the receiver's QA script caught instantly. Your model did not have that bug, but it did have a different one: net and gross side areas have the same value, because the exporter wrote NetSideArea to both fields instead of distinguishing them.

Or: the client's facilities management team loads your IFC into their CAFM platform six months after practical completion. The platform uses GUIDs as the stable identifier to link assets to maintenance records. But nobody on the project locked the IFC GUID to a stored parameter. The BIM Manager exported the file four times during the project — once per RIBA stage — and every export regenerated fresh GUIDs for elements that were split, mirrored, or copied from other families. The FM links are broken. The CAFM implementation cost £40,000 to remediate.

None of these problems are visible in a viewer. A viewer tells you whether geometry has been serialised into an IFC container. It does not tell you whether the geometry is positioned correctly in a shared coordinate frame. It does not tell you whether the property sets are correctly populated or simply present. It does not tell you whether the GUIDs are stable. It does not tell you whether the classification codes that your employer's information requirements mandated are actually in the file and pointing to the correct system. And it does not tell you whether the quantities that the QS will use to check your numbers are computed from the right face of the element.

That gap — between "opens in a viewer" and "fit for handover" — is what this article is about. The six-point audit described here takes an experienced BIM coordinator between one and four hours per discipline model, depending on model size and the maturity of the project's BIM Execution Plan. It will not catch every possible IFC error. But it will catch the six categories of error that, in practice, account for the vast majority of complaints that flow back from receivers: coordinate offset, GUID drift, property set mapping misses, classification misses, quantity drift, and geometry simplification artefacts.

The audit assumes you are working with Revit as the primary authoring tool and targeting either IFC 2x3 Coordination View 2.0 or IFC 4 Reference View as the exchange format. Most of the checks are tool-agnostic and apply equally to exports from Archicad, Tekla Structures, and Civil 3D, but the configuration examples are Revit-specific.


2. What an IFC Export Actually Is

2.1 The STEP Physical File

An IFC file with a .ifc extension is a STEP Physical File, defined by ISO 10303-21 (commonly called "Part 21"). STEP stands for Standard for the Exchange of Product model data; the physical file format is the human-readable ASCII serialisation of that standard. When you open an .ifc file in a text editor, the first line you see is:

ISO-10303-21;

That line is the file magic. It tells every parser in the world that what follows is a STEP Part 21 exchange structure. The file then divides into two sections.

The HEADER section appears first. For an IFC file, it contains three mandatory entities:

HEADER;
FILE_DESCRIPTION(('ViewDefinition [CoordinationView_V2.0]'),'2;1');
FILE_NAME('MyBuilding_Architecture.ifc','2026-06-02T09:00:00',
  ('Jane Smith'),('BIM Mobius Pty Ltd'),'Autodesk Revit 2025',
  'Autodesk Revit 2025','');
FILE_SCHEMA(('IFC2X3'));
ENDSEC;

The FILE_SCHEMA entity is critical: it declares which IFC schema version the data section claims to comply with. A file stamped IFC2X3 is making a legal claim to schema conformance that validators will test. A file stamped IFC4 and IFC4X3_ADD2 has a different claim. Mismatches between what is declared here and what is actually in the data section are a common source of import failures in strict tools.

The DATA section follows immediately after ENDSEC;. Every entity in the model is assigned a sequential instance name — a positive integer prefixed with # — and serialised as a single line:

DATA;
#1 = IFCPROJECT('0YvctVUKr4n8v0FlejCEjD',$,'My Building',$,$,$,$,
  (#20),#7);
#7 = IFCUNITASSIGNMENT((#8,#9,#10,#11,#12,#13,#14,#15,#16));
#8 = IFCSIUNIT(*,.LENGTHUNIT.,.MILLI.,.METRE.);
...
#100 = IFCWALL('2O2Fr$t4X7Zf8NOew3FL9r',$,'External Wall - 200 CLK',$,
  $,#101,#105,$);
#101 = IFCLOCALPLACEMENT(#95,#102);
#102 = IFCAXIS2PLACEMENT3D(#103,#104,$);
#103 = IFCCARTESIANPOINT((0.,0.,3000.));
...
ENDSEC;
END-ISO-10303-21;

The string '0YvctVUKr4n8v0FlejCEjD' in #1 is the IfcGloballyUniqueId for the IfcProject. Every entity that inherits from IfcRoot — projects, sites, buildings, storeys, spaces, and all building elements — carries one of these 22-character strings, which are base64-encoded UUIDs. They are the stable identifiers that downstream systems use to track assets across the project lifecycle.

The DATA section is a flat, forward-referencing graph. Every #n reference is a pointer. When you load the file, the parser builds the in-memory object graph by resolving those pointers. The .ifc file contains no semantic concept of "table" or "layer" in the CAD sense; the entire structure is object-relational.

2.2 Schema Versions and What They Mean

buildingSMART International has published four major schema families that practitioners encounter today.

IFC 2x3 (ISO/PAS 16739:2005, then widely used without ISO publication) is the workhorse of the industry. The Coordination View 2.0 Model View Definition (MVD), which constrains IFC 2x3 to a specific geometry and property set profile, remains the most widely tested format for cross-tool exchange. Most clash-detection tools, FM platforms, and cost management systems have been validated against it.

IFC 4 (ISO 16739-1:2018, which covers 4.0.2.1 and its ADD2 TC1 corrigendum) introduced significant schema improvements: better geometry representations, improved property set definitions, formalised quantity sets (Qto_* replacing BaseQuantities), and the IfcMaterialProfileSet for structural section profiles. The Reference View MVD for IFC 4 is the recommended format for coordination where geometry fidelity is the priority but editability is not required.

IFC 4.1 (June 2018, no ISO publication, status: Withdrawn) was a short-lived intermediate release. You should not be targeting it. If you see a file stamped IFC4X1 in its FILE_SCHEMA, treat it with suspicion.

IFC 4.3 (ISO 16739-1:2024, formally IFC4X3_ADD2) is the current official release as of April 2024. Its primary additions are infrastructure domain support — roads, railways, bridges, ports, and earthworks — through new geometry and spatial structure extensions. For building work, IFC 4.3 adds IfcAlignment, IfcLinearPlacement, and a more rigorous coordinate reference system (CRS) framework. Revit 2024 and 2025 added IFC 4.3 Reference View export capability, but as of mid-2026, the format's support in receiving tools is still uneven: verify your receiver's IFC 4.3 certification status before issuing a 4.3 file.

2.3 The IFC Export Configuration in Revit

Revit's IFC export pipeline is controlled by a named export setup (formerly stored as a .ifcExporterUI file, now embedded in the Revit document and exportable from the UI). Understanding what the export setup does and does not do is a prerequisite for auditing its output.

The export setup persists as an XML file when you use "Save Setup" from the IFC Export dialog. Its structure exposes every option:

<?xml version="1.0" encoding="utf-8"?>
<IFCExportConfiguration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  Name="BIM Mobius Standard - IFC2x3 CV2.0"
  IFCVersion="IFC2x3CV2"
  SpaceBoundaries="0"
  ActivePhaseId="-1"
  ExportBaseQuantities="true"
  SplitWallsAndColumns="false"
  VisibleElementsOfCurrentView="false"
  Use2DRoomBoundaryForVolume="false"
  UseFamilyAndTypeNameForReference="true"
  ExportInternalRevitPropertySets="false"
  ExportIFCCommonPropertySets="true"
  Export2DElements="false"
  ExportPartsAsBuildingElements="false"
  ExportBoundingBox="false"
  ExportSolidModelRep="false"
  ExportSchedulesAsPsets="false"
  ExportUserDefinedPsets="true"
  ExportUserDefinedPsetsFileName="C:\BIM\Standards\IFC\UserDefinedPropertySets.txt"
  ExportLinkedFiles="false"
  IncludeSiteElevation="true"
  UseActiveViewGeometry="false"
  ExportSpecificSchedules="false"
  TessellationLevelOfDetail="0.5"
  StoreIFCGUID="true"
  ExportRoomsInView="false"
  UseOnlyTriangulation="false"
  KeepBrepAsSolid="false"
  ExportIFCCategoryMappingTable="true"
  CategoryMappingFileName="C:\BIM\Standards\IFC\CategoryMapping.json"
  GeoRefCRSName=""
  GeoRefCRSDesc=""
  GeoRefEPSGCode=""
  GeoRefGeodeticDatum=""
  GeoRefMapUnit=""
/>

Key parameters to understand:

ExportBaseQuantities — When true, the exporter attaches Qto_* quantity sets to elements. These are used by QS tools, energy analysis, and FM platforms. When false, no quantities are written. Many practitioners leave this false because they do not know it exists, then wonder why the cost manager says the file has no quantities.

StoreIFCGUID — When true, the exporter writes each element's generated GUID back to an IFC GUID shared parameter in the Revit model after the first export. On subsequent exports, that stored value is read and reused, making GUIDs stable across re-exports. This is the single most important flag for asset lifecycle management. It must be enabled on the first export of any file that will be used as an as-built record.

IncludeSiteElevation — When true, the Z-coordinate of the IfcSite local placement includes the survey point elevation. When false, the site is at Z=0 regardless of real-world elevation. This is the flag that most often causes multi-disciplinary models to misalign vertically.

TessellationLevelOfDetail — A float between 0.0 (coarsest) and 1.0 (finest). Controls the chord tolerance for tessellating parametric solids. At 0.0, curved surfaces are coarsely triangulated; at 1.0, they are finely faceted at the cost of dramatically larger file size. The default of 0.5 is adequate for most coordination purposes; 0.0 is appropriate for analysis models where file size matters more than visual accuracy.

GeoRefEPSGCode — The EPSG code of the coordinate reference system (e.g., 7856 for GDA2020 MGA Zone 56, 27700 for OSGB 1936). Populated in IFC 4 and 4.3 exports via IfcProjectedCRS. Blank in IFC 2x3 exports, where geographic referencing relies on the site placement entity alone.

2.4 The Category Mapping Table

Revit categories do not map one-to-one to IFC classes. A Revit "Generic Model" family could legitimately be an IfcBeam, an IfcColumn, or an IfcBuildingElementProxy, depending on its structural role. The category mapping table resolves this ambiguity by defining, for each Revit category, which IFC class and IFC predefined type the exported elements should receive.

Since Revit 2025, the mapping table is accessible directly in the export setup UI via dropdown selectors. In earlier versions, it was managed as a separate .txt file referenced by the export configuration. The table is a critical QA artefact: a wall mapped to IfcBuildingElementProxy is not a wall in IFC, and any receiver expecting IfcWall for fire-rating or acoustic queries will get empty results.

2.5 Property Set Mechanics

Property sets in IFC are instances of IfcPropertySet (for free-form properties) or IfcElementQuantity (for typed quantities) attached to elements via IfcRelDefinesByProperties. The relationship is many-to-many: one property set instance can apply to many elements via separate relationship instances, and one element can carry multiple property sets.

A minimal property assignment in STEP notation looks like this:

#200 = IFCPROPERTYSET('3UkT4G$fD8yf7nOHRlENOP',$,
  'Pset_WallCommon',$,(#201,#202,#203,#204));
#201 = IFCPROPERTYSINGLEVALUE('Reference',$,
  IFCLABEL('EXT-200-CLK'),$);
#202 = IFCPROPERTYSINGLEVALUE('IsExternal',$,
  IFCBOOLEAN(.T.),$);
#203 = IFCPROPERTYSINGLEVALUE('FireRating',$,
  IFCLABEL('FRL 120/120/120'),$);
#204 = IFCPROPERTYSINGLEVALUE('AcousticRating',$,
  IFCLABEL('Rw 45'),$);
#205 = IFCRELDEFINESBYPROPERTIES('0m8bExCdPEV8$5jrP$cVEt',$,$,$,
  (#100),(#200));

#205 is the relationship entity that binds the wall #100 to its Pset_WallCommon instance #200. The property set name Pset_WallCommon is a buildingSMART-standardised name; its properties IsExternal, FireRating, and AcousticRating are standardised property names whose definitions live in the buildingSMART Data Dictionary (bSDD).

Revit's automatic Pset mapping works by name matching: if a Revit element has a parameter named exactly IsExternal, the exporter writes it to Pset_WallCommon.IsExternal. If the parameter is named Is External (with a space), or isExternal (wrong case), the mapping silently fails and the property is either absent from the output or written to a non-standard Revit-specific property set under the name as-is. This silent failure is the most common single source of Pset errors in practice.


3. The Six Failure Modes

3.1 Coordinate Offset

What it is. The building geometry is correctly formed relative to the model's own local origin, but the origin itself is placed at the wrong location in the shared coordinate frame. The result: when two discipline models are overlaid in a coordination tool, they are offset by a fixed vector — sometimes a few millimetres (alignment rounding errors), sometimes tens of kilometres (survey point placed at GIS easting/northing without an offset compensation).

Why it happens. Revit uses four distinct reference points — the Internal Origin, the Project Base Point, the Survey Point, and the Shared Coordinates origin — and the IFC exporter must choose which of these to use as the exported IfcSite origin. The Revit IFC exporter documentation is clear that "the project base point is always mapped to the zero point of the IFC viewer, regardless of the method used for export." But the choice of whether to use Shared Coordinates (which includes the survey point offset) or Project Coordinates (which does not) is controlled by the "Coordinate base" dropdown in the export setup, and that choice is easy to get wrong.

When a project uses GIS coordinates — eastings and northings in the hundreds of thousands — and the survey point is placed at those real-world coordinates without a local origin compensation (i.e., without "clipping" the large offset by placing the project base point at a local reference), the exported IFC will place the building at coordinates that many IFC viewers and coordination tools cannot handle correctly, because they use single-precision floating point for geometry storage. The IEEE 754 float has only 7 significant decimal digits; a easting of 334,500.000 m combined with a wall-face offset of 0.003 m requires 12 significant digits to represent without rounding error. The result is geometry "jitter" — surfaces that should be planar are subtly non-planar, coincident surfaces do not coincide, and clash detection produces false positives.

Detection. Open the exported IFC in a viewer, select the IfcSite entity in the tree, and read its RefLatitude, RefLongitude, and RefElevation attributes (IFC 2x3) or examine the IfcProjectedCRS entity (IFC 4/4.3). Then check the local placement of IfcBuilding relative to IfcSite. If the IfcBuilding placement is at (0,0,0) relative to site, the whole coordinate stack is referencing from the site; if it is offset by a large vector, suspect a survey-point bleed.

3.2 GUID Drift

What it is. The IfcGloballyUniqueId values assigned to elements change between exports. An element that was wall #100 with GUID 2O2Fr$t4X7Zf8NOew3FL9r in the Stage D issue has a different GUID in the Stage F issue, even though the wall itself has not been deleted and recreated.

Why it happens. Revit derives IFC GUIDs from element UniqueIds using a deterministic algorithm — so for a stable element in a stable model, the GUID is reproducible. But the algorithm's stability breaks down in several circumstances:

  • Workset-enabled models: GUID generation for elements on different worksets can be non-deterministic across sessions if the central model has been upgraded or repaired.
  • Split and rejoined elements: Splitting a wall creates a new element with a new UniqueId; the original UniqueId is retained on one fragment. On the next export, both fragments get GUIDs derived from their respective UniqueIds, which differ from the original single-wall GUID.
  • StoreIFCGUID was not enabled on the first export: If the flag was off on the Stage D issue, no GUID was written back to the model parameter. When the flag is turned on for Stage F, the exporter generates fresh GUIDs for all elements.
  • Groups and assemblies: The GUID generation for relationship entities (IfcRelDefinesByProperties, IfcRelContainedInSpatialStructure) is not deterministic in all Revit versions; these relationship GUIDs may change even when the element GUIDs are stable.

Consequence. Any downstream system that uses GUIDs as primary keys — FM platforms, asset registers, BCF issue trackers, 4D scheduling tools — silently loses its links when GUIDs change. The model "looks right" in every viewer; the broken links are only discoverable by the systems that depend on them.

3.3 Pset Mapping Miss

What it is. A property that should be in a standardised buildingSMART property set is absent from the exported file, or present but in a non-standard location (e.g., inside a Revit Type Parameters or custom property set instead of Pset_WallCommon).

Why it happens. The name-matching mechanism described in Section 2.5 is exact and case-sensitive. FireRating works; Fire Rating, fire rating, FIRE_RATING, and Fire_Rating do not. Additionally, built-in Revit parameters do not always map to buildingSMART Pset properties — Fire Rating (Revit built-in) must be manually mapped to FireRating (Pset standard) via either a User-Defined Property Set file or a parameter renaming approach.

A subtler cause: the Revit IFC exporter writes Pset properties from instance parameters and type parameters differently. An instance parameter named IsExternal on a wall instance will export correctly. But a type parameter named IsExternal on the wall type requires the "Export type as" feature to be active, or it must be mapped via the type property set mechanism.

3.4 Classification Miss

What it is. Elements do not carry IfcClassificationReference entries, or the entries reference the wrong classification system, or they reference the correct system but with incorrect codes.

Why it happens. Unlike Psets (which are exported automatically if parameter names match), classifications require explicit configuration in Revit's export setup under the "Classification Settings" tab. By default, Revit exports OmniClass numbers from the built-in OmniClass Number and OmniClass Title parameters, but it does not export Uniclass 2015 or any other system unless the ClassificationCode parameters have been populated and the classification field name has been configured.

A further trap: the Standardised Data Tool (Autodesk's free classification add-in) writes classification data to Revit parameters in a format that does not automatically convert to IfcClassificationReference. It creates text parameters that export as IfcText properties inside a custom property set — not as proper classification references that a cost management system or FM platform can query via IfcRelAssociatesClassification.

3.5 Quantity Drift

What it is. The quantities in the IFC file do not match the quantities computed by an independent measurement tool, or do not match between the IFC and the PDF schedule issued alongside it.

Why it happens. Revit's Qto_* quantity export has several known issues across versions:

  • Gross/Net label swap: In certain Revit builds, GrossSideArea and GrossVolume are written with incorrect property names — the exporter writes NetSideArea to both the net and gross fields, so both carry the same (net) value.
  • Unit scale errors: Some Revit versions have exported GrossVolume at 1,000× the correct value due to a metre-to-millimetre unit conversion error in the quantity calculation, while the viewer shows the geometry correctly because geometry units are handled separately from quantity units.
  • Method of measurement: Revit computes GrossVolume from the full extrusion of the element without deducting openings. An independent QS tool may compute gross volume differently — for instance, deducting the structural framing zone. The MethodOfMeasurement attribute on IfcElementQuantity is supposed to document which standard was used, but Revit writes BaseQuantities for this field, which is a generic placeholder, not a specific measurement standard.
  • Phase filtering: If the export setup targets a phase other than the final phase, quantities reflect the state of the model at that phase, which may not match the current schedule.

3.6 Geometry Simplification

What it is. The exported geometry differs from the authoring model geometry in ways that matter for downstream use: faces are missing, curved surfaces are over-tessellated or under-tessellated, solids are open (non-manifold), or elements that should be separate are merged.

Why it happens. The transition from Revit's parametric representation to IFC geometry is lossy by design. Revit stores walls as WallType + constraints + joins; IFC stores them as geometric solids. The export process must resolve all joins, trim geometry at intersections, and serialise the result as either a swept solid (IfcExtrudedAreaSolid), a B-rep (IfcFacetedBrep), or triangulated mesh (IfcTriangulatedFaceSet). Complex geometries — raked ceilings, stairs with complex stringers, curtain walls with non-rectangular panels, in-place families with swept blends — sometimes fail to produce valid solids, resulting in open meshes or faces that do not close.

The TessellationLevelOfDetail parameter amplifies this: at low LOD, curved elements (pipes, circular columns, arched beams) become faceted polygons. The model looks "right" in a viewer that renders faceted meshes smoothly, but a downstream tool performing clash detection against a perfectly cylindrical pipe profile will register phantom clearance violations at the facet boundaries.


4. The Six-Point Audit

4.1 Audit Point 1: Base Point and Shared Coordinates Verification

Goal. Confirm that the exported IfcSite and IfcBuilding placements establish the correct coordinate origin, and that the origin matches the shared coordinate frame agreed in the BIM Execution Plan.

    Step 1: Document the agreed project origin before running the audit.

    The BEP should specify the project origin in terms of local shared coordinates (not GIS). Typical examples: "Project base point at ground-floor intersection of grid A and grid 1, elevation ±0.000 = 150.250 m AHD." Write this down. If the BEP does not specify it, stop: the coordinate system needs to be agreed before any IFC is issued.

    Step 2: Open the IFC in FZK Viewer or BIMvision and inspect the raw entity tree.

    Navigate to the IfcProject entity, follow the reference chain through IfcSite to IfcBuilding, and read each entity's ObjectPlacement. For IFC 2x3:

    IfcProject
      ↳ IfcSite (RefLatitude, RefLongitude, RefElevation)
          ↳ IfcBuilding (ObjectPlacement → IfcLocalPlacement → IfcAxis2Placement3D)
              ↳ IfcBuildingStorey (Elevation)

    The IfcAxis2Placement3D.Location for IfcBuilding should be the agreed origin offset from site. If it is a suspiciously large number (e.g., (334500.000, 6248000.000, 150.250)), the GIS coordinates have leaked into the local placement.

    Step 3: Check the IfcMapConversion entity (IFC 4 and 4.3 only).

    In IFC 4 exports, georeferencing is expressed via IfcMapConversion and IfcProjectedCRS. The IfcMapConversion entity carries the affine transform (Eastings, Northings, OrthogonalHeight, XAxisAbscissa, XAxisOrdinate, Scale) that maps from the IFC local coordinate system to the real-world projected CRS.

    #50 = IFCPROJECTEDCRS('EPSG:7856',$,'GDA2020 / MGA Zone 56',$,$,
      #51,.METRE.);
    #51 = IFCGEOGRAPHICELEMENT($,$,$,$,$,$,$,$);
    #52 = IFCMAPCONVERSION(#53,#50,334500.000,6248000.000,150.250,
      0.99999789,0.00205389,$);

    The Eastings/Northings in IfcMapConversion are the real-world coordinates of the IFC local origin. These should match the agreed coordination point. If IfcMapConversion is absent from an IFC 4 file, georeferencing is undefined — acceptable only if no GIS integration is planned.

    Step 4: Cross-check with another discipline model.

    Load both models in Solibri or Navisworks. Without any manual positioning, the buildings should overlap perfectly. If they do not, compute the offset vector and trace it back to which model's survey/base point configuration is wrong. Common culprits: one model exported with "Shared Coordinates" and the other with "Project Internal."

    Step 5: Validate using IfcOpenShell.

    import ifcopenshell
    import ifcopenshell.util.placement
     
    ifc = ifcopenshell.open("architecture.ifc")
     
    # Get the building's world placement
    building = ifc.by_type("IfcBuilding")[0]
    matrix = ifcopenshell.util.placement.get_local_placement(
        building.ObjectPlacement
    )
    print("Building origin (X, Y, Z):", matrix[0][3], matrix[1][3], matrix[2][3])
     
    # For IFC 4: check map conversion
    map_conversions = ifc.by_type("IfcMapConversion")
    if map_conversions:
        mc = map_conversions[0]
        print(f"Eastings: {mc.Eastings}, Northings: {mc.Northings}")
        print(f"OrthogonalHeight: {mc.OrthogonalHeight}")
        crs = mc.TargetCRS
        print(f"CRS Name: {crs.Name}")
    else:
        print("No IfcMapConversion found — georeferencing not defined")

Failure criteria. Flag for correction if: (a) IfcBuilding placement has X or Y coordinates greater than 1,000 m; (b) IfcMapConversion is absent from an IFC 4 file where GIS integration is required; (c) two discipline models do not overlay within 10 mm when loaded without positioning adjustments; (d) RefElevation on IfcSite does not match the project benchmark.


4.2 Audit Point 2: GUID Stability Across Exports

Goal. Confirm that IfcGloballyUniqueId values are stable across successive exports, and that the StoreIFCGUID mechanism is active.

    Step 1: Verify StoreIFCGUID is enabled in the export setup.

    Open the Revit project, open the IFC export dialog (File → Export → IFC), click "Modify/Edit Setup," and confirm "Store IFC GUID in file after export" is checked. If it is not, enable it before the next export. Note: enabling it retroactively does not fix already-issued files; it only applies from the next export forward.

    Step 2: Check for the IFC GUID shared parameter in the project.

    After a successful export with StoreIFCGUID enabled, every exportable element will carry an IFC GUID instance parameter. Open the Properties panel for a wall, a column, and a door; confirm the parameter exists and contains a 22-character string. If the parameter is absent on some elements but present on others, the export may have been partial or the shared parameter file is not loaded.

    Step 3: Run a diff between two successive export files.

    Export the same model twice (without any model changes between exports) and diff the two .ifc files on GUID fields:

    import ifcopenshell
    import sys
     
    def extract_guids(path):
        """Return a dict mapping GlobalId → entity type + name."""
        ifc = ifcopenshell.open(path)
        result = {}
        for product in ifc.by_type("IfcProduct"):
            result[product.GlobalId] = {
                "type": product.is_a(),
                "name": product.Name or ""
            }
        return result
     
    file_a = extract_guids(sys.argv[1])   # Stage D issue
    file_b = extract_guids(sys.argv[2])   # Stage F issue
     
    # GUIDs present in A but not in B (deleted or drifted)
    lost = {g: v for g, v in file_a.items() if g not in file_b}
    # GUIDs present in B but not in A (new or drifted)
    gained = {g: v for g, v in file_b.items() if g not in file_a}
     
    print(f"Lost GUIDs: {len(lost)}")
    for g, v in list(lost.items())[:10]:
        print(f"  {g}: {v['type']} '{v['name']}'")
     
    print(f"\nGained GUIDs: {len(gained)}")
    for g, v in list(gained.items())[:10]:
        print(f"  {g}: {v['type']} '{v['name']}'")

    For a model with no design changes between the two exports, lost and gained should both be zero. Any non-zero count identifies elements whose GUIDs are not stable.

    Step 4: Investigate instability sources.

    For each GUID that drifted, check whether the element was: (a) split, (b) copied from another project, (c) on a workset that was detached and reattached, or (d) part of a group or assembly that was ungrouped and regrouped. These are the canonical instability triggers.

    Step 5: For high-stakes handovers, apply GUID freeze before issue.

    Where long-term GUID stability is critical (asset management, FM integration), the recommended practice is to run a "GUID freeze" export — an export solely for the purpose of populating the IFC GUID shared parameter across all elements — at a fixed model milestone, and to treat that parameter as read-only thereafter. Any element whose IFC GUID parameter is blank at handover should be investigated.

Failure criteria. Flag for correction if: (a) StoreIFCGUID is not enabled; (b) a diff between two exports with no design change shows any GUID drift; (c) any element in an asset register or FM-linked element schedule lacks an IFC GUID parameter value.


4.3 Audit Point 3: Pset Mapping Check

Goal. Confirm that the standardised Pset_* property sets required by the project EIR are present, correctly named, and contain the expected properties with correct values and data types.

    Step 1: Identify the required Psets from the project EIR or data drop schedule.

    Common requirements for a typical building project include: Pset_WallCommon (IsExternal, FireRating, AcousticRating, Reference), Pset_DoorCommon (IsExternal, FireRating, SecurityRating, AcousticRating), Pset_SpaceCommon (IsExternal, GrossPlannedArea, NetPlannedArea, OccupancyType), and Pset_SlabCommon (IsExternal, LoadBearing). Infrastructure projects additionally require Pset_DistributionChamberElementCommon, Pset_PipeSegmentCommon, etc.

    Step 2: Validate Psets in Solibri.

    Open the IFC in Solibri Model Checker. Navigate to the Checking tab and run the "IFC Property Check" ruleset. This ruleset verifies that required properties exist on required element types and optionally validates their data types. For a Pset audit:

    1. Filter to IfcWall elements in the components tree.
    2. Open the Info panel and switch to the Properties view.
    3. Verify that Pset_WallCommon appears as a property group (not Revit Type Parameters or Revit Wall Common).
    4. Confirm IsExternal is a Boolean, FireRating is a string, and Reference is populated.

    Step 3: Spot-check with IfcOpenShell for completeness.

    import ifcopenshell
    import ifcopenshell.util.element as util
     
    ifc = ifcopenshell.open("architecture.ifc")
     
    REQUIRED_PSETS = {
        "IfcWall":   {"Pset_WallCommon": ["IsExternal", "FireRating", "Reference"]},
        "IfcDoor":   {"Pset_DoorCommon": ["IsExternal", "FireRating"]},
        "IfcSpace":  {"Pset_SpaceCommon": ["IsExternal", "OccupancyType"]},
    }
     
    issues = []
     
    for ifc_class, pset_map in REQUIRED_PSETS.items():
        elements = ifc.by_type(ifc_class)
        for el in elements:
            psets = util.get_psets(el)
            for pset_name, required_props in pset_map.items():
                if pset_name not in psets:
                    issues.append(
                        f"MISSING PSET | {el.GlobalId} | "
                        f"{el.is_a()} '{el.Name}' | {pset_name}"
                    )
                    continue
                for prop in required_props:
                    if prop not in psets[pset_name]:
                        issues.append(
                            f"MISSING PROP | {el.GlobalId} | "
                            f"{el.is_a()} '{el.Name}' | "
                            f"{pset_name}.{prop}"
                        )
     
    print(f"Total issues: {len(issues)}")
    for issue in issues[:50]:
        print(issue)

    Step 4: Check for Revit-specific property set pollution.

    Open the IFC in a text editor (or FZK Viewer entity browser) and search for Revit Type Parameters and Revit Wall Type. These Revit-native property sets are exported when ExportInternalRevitPropertySets="true" in the export setup. Their presence is not wrong per se, but if they are the only location where fire rating, acoustic rating, and function data appear — instead of the standardised Psets — the mapping has failed.

    Step 5: Validate data types.

    A FireRating property should have type IfcLabel (string). A LoadBearing property should have type IfcBoolean. An AcousticRating should have type IfcLabel (it is a string code like "Rw 45", not a numeric). If a receiver's platform expects a boolean for IsExternal and the file contains IfcLabel('TRUE'), the receiver's filter will fail silently. Check a sample of each critical property for type correctness using IfcOpenShell's NominalValue attribute.

Failure criteria. Flag for correction if: (a) any required Pset_* is absent from more than 5% of the element type it should apply to; (b) required properties appear only in Revit Type Parameters instead of the standard Pset; (c) any critical Boolean property (IsExternal, LoadBearing) has a string type value; (d) Pset_* names are non-standard variants such as PSet_ (capital S), Pset_WallsCommon (incorrect plural), or contain trailing spaces.


4.4 Audit Point 4: Classification Audit

Goal. Confirm that IfcClassificationReference entries are present on all elements that the EIR requires to carry classification codes, and that the codes are valid references to the declared classification system.

    Step 1: Identify the required classification system.

    Confirm from the EIR whether the project uses Uniclass 2015 (UK), OmniClass (US/Australia), MasterFormat, or a bespoke client system. The EIR should also specify which tables are required — e.g., Uniclass Tables Ss (Systems) and Pr (Products), or OmniClass Table 21 (Elements) and Table 22 (Work Results).

    Step 2: Verify the IfcClassification header entity.

    Every classification system referenced in the file should appear as an IfcClassification entity:

    #300 = IFCCLASSIFICATION($,'2015','2024-01-01','Uniclass 2015',
      $,'https://uniclass.thenbs.com');
    #301 = IFCCLASSIFICATIONREFERENCE(
      'https://uniclass.thenbs.com/facet/Ss/node/Ss_20_10_30',
      'Ss_20_10_30','External walls','Uniclass 2015',#300,$);
    #302 = IFCRELASSOCIATESCLASSIFICATION(
      '1234567890abcdefghijklmn',$,$,$,(#100),#301);

    #302 is the relationship that assigns classification #301 to wall #100. In FZK Viewer, browse to IfcRelAssociatesClassification to see how many elements have classifications assigned.

    Step 3: Check element coverage in IfcOpenShell.

    import ifcopenshell
     
    ifc = ifcopenshell.open("architecture.ifc")
     
    # Collect all classification associations
    classified_guids = set()
    for rel in ifc.by_type("IfcRelAssociatesClassification"):
        ref = rel.RelatingClassification
        # Can be IfcClassificationReference or IfcClassification
        for obj in rel.RelatedObjects:
            classified_guids.add(obj.GlobalId)
     
    # Count elements that should be classified
    should_be_classified = ifc.by_type("IfcBuildingElement")
    missing = [
        el for el in should_be_classified
        if el.GlobalId not in classified_guids
    ]
     
    print(f"Elements requiring classification: {len(should_be_classified)}")
    print(f"Classified: {len(should_be_classified) - len(missing)}")
    print(f"Missing classification: {len(missing)}")
     
    # Show a sample of missing elements by type
    from collections import Counter
    missing_by_type = Counter(el.is_a() for el in missing)
    for ifc_class, count in missing_by_type.most_common(10):
        print(f"  {ifc_class}: {count} elements missing classification")

    Step 4: Validate code format.

    For Uniclass 2015, valid codes follow the pattern Ss_20_10_30 (table prefix, underscore-separated two-digit groups). For OmniClass Table 22, the pattern is 22-03 11 11. Regex-validate the Identification attribute of each IfcClassificationReference against the expected pattern. An element with OmniClass Number: 23.30.10.00 in Revit should produce an IfcClassificationReference with that identification string — but if the Revit parameter was populated with 23-30.10.00 (dash vs. dot inconsistency), the code is non-standard.

    Step 5: Verify the classification system URI.

    The Location attribute of IfcClassification should contain a dereferenceable URI to the classification system — e.g., https://uniclass.thenbs.com or https://www.omniclass.org. Blank Location attributes are technically valid but reduce machine-readability. For projects using buildingSMART Data Dictionary (bSDD) integration, the classification URI must match the bSDD namespace exactly.

Failure criteria. Flag for correction if: (a) IfcRelAssociatesClassification is absent from the file entirely; (b) more than 10% of IfcBuildingElement instances lack a classification reference; (c) IfcClassification.Name does not match the system declared in the EIR; (d) classification codes do not match the expected format pattern for the declared system; (e) IfcBuildingElementProxy elements (which often indicate Revit families with no correct IFC class mapping) are classified without first being correctly mapped to a real IFC class.


4.5 Audit Point 5: Quantity Verification

Goal. Confirm that Qto_* quantity sets are present, that quantity values match an independently computed reference, and that gross/net distinctions are correctly labelled.

    Step 1: Confirm base quantity export is enabled.

    Check the export setup: ExportBaseQuantities="true". Then verify the IFC file contains IfcElementQuantity instances. In IfcOpenShell:

    import ifcopenshell
     
    ifc = ifcopenshell.open("architecture.ifc")
     
    qtys = ifc.by_type("IfcElementQuantity")
    print(f"IfcElementQuantity instances: {len(qtys)}")
     
    # Check that Qto_ sets exist (IFC 4 naming)
    qto_sets = [q for q in qtys if q.Name.startswith("Qto_")]
    # Also check BaseQuantities naming (IFC 2x3 legacy)
    base_sets = [q for q in qtys if "BaseQuantities" in q.Name]
    print(f"  Qto_ sets (IFC 4 standard): {len(qto_sets)}")
    print(f"  BaseQuantities sets (IFC 2x3): {len(base_sets)}")
     
    # Sample a wall quantity set
    walls_with_qto = []
    for wall in ifc.by_type("IfcWall")[:5]:
        for rel in wall.IsDefinedBy:
            if rel.is_a("IfcRelDefinesByProperties"):
                pd = rel.RelatingPropertyDefinition
                if pd.is_a("IfcElementQuantity"):
                    walls_with_qto.append((wall.Name, pd.Name, pd.Quantities))
     
    for name, qset_name, quantities in walls_with_qto:
        print(f"\nWall: {name} | Qty Set: {qset_name}")
        for q in quantities:
            print(f"  {q.Name}: {q.LengthValue if hasattr(q, 'LengthValue') else q.AreaValue if hasattr(q, 'AreaValue') else q.VolumeValue}")

    Step 2: Cross-check wall quantities against Revit schedule.

    Create a Revit wall schedule with the following fields: Mark, Length, Area, Volume. Export as CSV. Compare the Length and Area values against the Qto_WallBaseQuantities.Length and Qto_WallBaseQuantities.GrossSideArea values from the IFC for a sample of 20–30 walls. Acceptable tolerance: ±1% for areas and volumes.

    Step 3: Verify gross/net distinction.

    In the IFC STEP text, search for Qto_WallBaseQuantities entries and confirm that both GrossVolume and NetVolume appear with different values for walls that have openings. If the values are identical for walls with doors or windows, the gross/net label swap bug is present:

    # Count Qto_WallBaseQuantities property instances in STEP file
    grep -c "Qto_WallBaseQuantities" architecture.ifc
     
    # Check for GrossVolume vs NetVolume divergence
    # (use Python for a proper parse; this is a quick sanity check)
    grep -A 20 "Qto_WallBaseQuantities" architecture.ifc | \
      grep -E "GrossVolume|NetVolume" | head -40

    Step 4: Verify units.

    The IfcUnitAssignment entity at the top of the file declares the project units. Confirm that the declared length unit matches the model unit (typically millimetres for Revit models):

    #8 = IFCSIUNIT(*,.LENGTHUNIT.,.MILLI.,.METRE.);

    Then spot-check a wall's Qto_WallBaseQuantities.Length value: for a 5,000 mm wall, the value should be 5000.0 (millimetres), not 5.0 (metres) and not 5000000.0 (micrometres). A 1,000× error in quantity values is a clear unit conversion bug and must be reported before issue.

    Step 5: For space quantities, cross-check against room schedule.

    Spaces (rooms) carry Qto_SpaceBaseQuantities. The GrossFloorArea value should match the Revit Area parameter for that room within ±0.5%. Significant discrepancies indicate that the space boundary algorithm used for IFC export (none / 1st level / 2nd level) is computing area differently from Revit's native room area calculation.

Failure criteria. Flag for correction if: (a) no IfcElementQuantity instances are present (export base quantities is off); (b) GrossVolume equals NetVolume for any element with openings; (c) any quantity value is more than 10% different from the Revit schedule for the same element; (d) the unit for length quantities is inconsistent with the declared IfcUnitAssignment; (e) Qto_SpaceBaseQuantities.GrossFloorArea differs from Revit room area by more than 1%.


4.6 Audit Point 6: Geometry Simplification Testing

Goal. Confirm that the exported geometry is closed (manifold), geometrically faithful to the authoring model within agreed tolerance, and does not contain tessellation artefacts that will affect downstream use.

    Step 1: Run the buildingSMART Validation Service.

    Upload the IFC to validation.buildingsmart.org. The service checks STEP syntax, schema conformance, formal propositions, and normative rules. Geometry errors — invalid swept areas, degenerate faces, self-intersecting solids — will often produce schema-level violations that the service catches. A pass here is a necessary but not sufficient condition for geometry quality.

    Step 2: Run geometry validation in IfcOpenShell.

    IfcOpenShell's geometry engine processes the same solids that downstream tools will process. Driving it programmatically reveals elements that fail to produce valid geometry:

    import ifcopenshell
    import ifcopenshell.geom
     
    ifc = ifcopenshell.open("architecture.ifc")
     
    settings = ifcopenshell.geom.settings()
    settings.set(settings.USE_WORLD_COORDS, True)
     
    failures = []
    iterator = ifcopenshell.geom.iterator(settings, ifc)
     
    if iterator.initialize():
        while True:
            try:
                shape = iterator.get()
                # shape.geometry.verts and shape.geometry.faces are
                # available if geometry was successfully created
                if not shape.geometry.verts:
                    failures.append({
                        "guid": shape.guid,
                        "type": shape.type,
                        "reason": "empty geometry"
                    })
            except RuntimeError as e:
                failures.append({
                    "guid": getattr(iterator.get(), "guid", "unknown"),
                    "reason": str(e)
                })
            if not iterator.next():
                break
     
    print(f"Geometry failures: {len(failures)}")
    for f in failures[:20]:
        print(f"  {f.get('type', '?')} {f.get('guid', '?')}: {f['reason']}")

    Step 3: Check tessellation quality for curved elements.

    Curved elements — pipes, round columns, circular slabs, dome roofs — are most vulnerable to tessellation over-simplification. In the viewer, select a circular column and count the number of faces on the cylindrical surface. At TessellationLevelOfDetail=0.5 (default), a typical circular column should have 24–36 faces around its circumference. Fewer than 12 faces will cause visible faceting and may affect clearance clash checks.

    If the project involves MEP coordination with round ductwork or pipework, increase TessellationLevelOfDetail to 0.7 or above for the MEP discipline models. The file size increase is acceptable relative to the clash-detection accuracy improvement.

    Step 4: Verify complex element families.

    The elements most likely to produce invalid geometry on export are: in-place families, stairs with custom stringers, curtain wall panels with complex profiles, railings with swept path geometry, and adaptive components. For each category of complex element in the model:

    1. Export the model.
    2. Load in Solibri and navigate to that element in the tree.
    3. Visually inspect for missing faces, exploded geometry, or elements at (0,0,0).
    4. In the Solibri "Issues" view, run "Components with no geometry" check to get a list.

    Elements that export with no geometry in IFC but display correctly in Revit are typically in-place families or geometry that the exporter cannot convert. These should be converted to loadable families before handover.

    Step 5: Compare bounding boxes.

    A quick volumetric sanity check: compare the bounding box of the IFC export against the bounding box of the Revit model. Large discrepancies (> 5% in any dimension) indicate that geometry has been displaced or that elements are being placed at incorrect locations.

    import ifcopenshell
    import ifcopenshell.geom
    import numpy as np
     
    ifc = ifcopenshell.open("architecture.ifc")
    settings = ifcopenshell.geom.settings()
    settings.set(settings.USE_WORLD_COORDS, True)
     
    all_verts = []
    iterator = ifcopenshell.geom.iterator(settings, ifc)
    if iterator.initialize():
        while True:
            shape = iterator.get()
            verts = shape.geometry.verts
            if verts:
                # verts is a flat array [x0,y0,z0, x1,y1,z1, ...]
                pts = np.array(verts).reshape(-1, 3)
                all_verts.append(pts)
            if not iterator.next():
                break
     
    if all_verts:
        all_pts = np.vstack(all_verts)
        bbox_min = all_pts.min(axis=0)
        bbox_max = all_pts.max(axis=0)
        print(f"Bounding box MIN: {bbox_min}")
        print(f"Bounding box MAX: {bbox_max}")
        print(f"Extents (X,Y,Z): {bbox_max - bbox_min}")

    If the Z extent is, for example, 3,000 times the expected building height, an element is sitting at a grossly incorrect elevation — almost always due to a coordinate offset or a family with an incorrect insertion point.

Failure criteria. Flag for correction if: (a) buildingSMART Validation Service returns any ERROR-level finding (warnings may be acceptable depending on EIR); (b) IfcOpenShell geometry iterator fails on more than 0.5% of elements by count; (c) Solibri "Components with no geometry" check returns any element that should have geometry; (d) any element is located more than 500 m from the model bounding box centroid (displacement artefact); (e) curved elements have fewer than 12 faces per 360° circumference.


5. Anti-Patterns

5.1 "The Viewer Renders Fine, So Ship It"

This is the most dangerous anti-pattern in IFC production. IFC viewers — even sophisticated ones like Solibri — are optimised to render geometry, not to validate information content. A viewer will happily display a wall that has no Pset_WallCommon, no fire rating, no classification reference, and a GUID that changes every time the model is exported. It will render it beautifully. It will even let you hover over it and see its properties — the Revit-native properties that the exporter writes by default, not the standardised Psets that the EIR requires.

The "viewer renders fine" heuristic catches roughly 20% of IFC issues — the class of issues where geometry is so badly broken that the viewer cannot display it. It misses 80%: coordinate offsets (if the offset is consistent across all elements), GUID drift (invisible in a viewer), Pset misses (properties are present, just wrong ones), classification misses (no classification is not a rendering error), quantity errors (not displayed in the default view), and tessellation artefacts that only manifest in clash detection.

The corrective discipline is to treat IFC QA as a data audit, not a visual inspection. Visual inspection of the 3D model in a viewer is the last step of the audit, not the only step.

5.2 Ignoring Schema Version

A significant fraction of IFC files issued in practice are stamped IFC2X3 in their FILE_SCHEMA but contain entities or property patterns that only exist in IFC 4. This happens when the Revit IFC export configuration was set to IFC 2x3 but the project team manually added IFC 4 property sets to the User-Defined Property Set file. The result is a file that claims 2x3 conformance but fails schema validation — which means strict validators will reject it and strictly conformant import tools may misparse entity attributes.

The obverse problem also occurs: teams set the export to IFC 4 because it was "newer and better" without verifying that their receiving tools support IFC 4. Structural analysis tools, cost management platforms, and FM systems often have IFC 4 support listed in their product documentation but not actually tested in certification. The buildingSMART certified software list (https://www.buildingsmart.org/compliance/software-certification/ifc/) is the definitive reference; if the receiver is not on that list for the target schema version, issue in IFC 2x3 Coordination View 2.0 until you have verified compatibility.

For IFC 4.3 specifically: as of mid-2026, Revit 2024 and 2025 export IFC 4.3 Reference View, but certified receiving tools for IFC 4.3 are still a minority of the market. The buildingSMART IFC 4.3 software implementations page lists 101 self-reported implementations as of 2026, but self-reporting is not certification. Verify your receiving chain before issuing 4.3.

5.3 No Cross-Tool Verification

The IFC specification defines what data should be in a file. The IFC exporter produces what the authoring tool can put in a file. The receiving tool imports what it chooses to import. The gap between "should," "can," and "chooses" is large enough to lose a project coordination session in.

Cross-tool verification means opening the IFC in at least two different applications before issue — one being the tool the receiver will actually use. If the structural consultant uses Tekla Structural Designer for their coordination model, you should open your architectural IFC in Tekla before issuing it. If the FM platform is Archibus, request a sample import test on a representative slice of the model before the full handover.

The anti-pattern is to test only in the same tool family (Revit opens its own IFC) or only in generic viewers. Revit's IFC import uses the same exporter codebase in reverse and is therefore likely to succeed on things that other tools trip over. Generic viewers are tuned for geometry rendering and do not exercise property set and classification parsing.

5.4 Per-Issue Export with Different Settings

Each IFC issue should use an identical, version-controlled export setup configuration file. A common anti-pattern: the BIM Coordinator exports Stage D using one setup (saved in their local AppData folder), and a junior team member exports Stage F using a different setup (the Revit default, with StoreIFCGUID off, ExportBaseQuantities off, and a different coordinate base). The two issues are incompatible in ways that are not obvious from the filenames.

Best practice: check the export setup XML into the project's common data environment alongside the IFC files, name it with the project number and the target format (e.g., PROJ-001_IFC2x3_CV2.ifc_setup.xml), and reference it in the BEP. Make it a condition of any IFC issue that the setup file is on record.

5.5 Exporting Linked Models as a Single File Without Coordination

Revit allows linked models to be exported as a single merged IFC. This is convenient but hazardous: the merged export uses a single coordinate system and a single GUID namespace. If the structural model was linked using "Origin to Origin" but the MEP model was linked using "Shared Coordinates," the merge will silently offset the MEP geometry. The resulting IFC will look correct in a viewer and fail spectacularly in coordination.

Export each discipline model separately, confirm coordinate alignment as per Audit Point 1, and deliver a file set rather than a merged file. If the receiver requires a merged file, produce it only after the constituent models have passed their individual audits.


6. Case Studies

6.1 The Displaced Hospital Tower

A 12-storey hospital project in a major Australian city was nearing Stage D handover. The architectural BIM Manager issued the IFC for coordination with the structural and services consultants. The MEP coordinator loaded all three discipline models into Navisworks and discovered that the architecture model was displaced 2.3 metres north and 1.1 metres east relative to the structural model. Both models looked correct when opened individually.

Investigation revealed two distinct errors. First, the architectural model used "Shared Coordinates" as the IFC export origin, but the structural model used "Project Internal." The structural team had never established shared coordinates with the architectural model — they had simply set up their own project base point. Second, the architectural BIM team had moved the survey point without locking it, causing the survey point to drift from its intended location during the design development phase.

The coordinate audit (Audit Point 1 procedure) would have caught this in under 30 minutes. The remediation — reissuing the architectural IFC with correct coordinate settings and re-running the MEP clash detection — cost approximately 18 hours of BIM coordination time and delayed the Stage D submission by four days.

Lesson. Shared coordinates must be established at the project's first coordination session and documented in the BEP with explicit Easting, Northing, and AHD values. The IFC export setup must specify whether the origin is Survey Point, Project Base Point, or Internal Origin, and that choice must be identical across all discipline teams.

6.2 The GUID Drift and the Broken FM Integration

A commercial office tower project in the United Kingdom used IFC GUIDs as the primary keys for linking Revit elements to the client's CAFM platform during construction. The BIM Manager had enabled StoreIFCGUID on the first export and confirmed that the IFC GUID parameter was populated across all elements.

During Stage E, a significant programme of design change required splitting approximately 340 walls to accommodate revised structural grid alignment. The split operation created 340 new elements; the 340 original elements retained their GUIDs in the IFC GUID parameter, but the 340 new fragments had blank IFC GUID parameters because they were created after the initial GUID-freeze export.

The Stage E IFC issue was exported without running a GUID drift check. The CAFM platform imported the file and silently created 340 new asset records for the new wall fragments while the 340 original records retained their old GUID associations — which now pointed to wall halves that had been physically joined to different structural bays. The FM team discovered the issue 14 months after practical completion when preventive maintenance records began appearing against the wrong room zones.

Lesson. A GUID diff (Audit Point 2 procedure) between each successive issue would have flagged the 340 new blank GUIDs at Stage E issue. The correct remediation at that point would have been: (1) review the 340 new wall fragments and confirm their identity mapping; (2) manually populate the IFC GUID parameter for the new fragments; (3) re-export and confirm zero drift between the patched export and the previous issue.

6.3 The Missing Fire-Rating Data

A mixed-use development in Singapore required IFC handover to the building owner's facilities management contractor. The EIR specified that all IfcWall elements enclosing fire compartments must carry Pset_WallCommon.FireRating with values conforming to the project fire strategy report.

The BIM Manager ran a visual QA in Solibri and confirmed that wall elements looked correct. She did not run a Pset mapping check. The FM contractor loaded the IFC into their CAFM system and attempted to run a fire compartment integrity report. The report returned zero fire-rated walls.

The cause: in Revit, fire rating data was stored in the built-in parameter Fire Rating (with a space). The buildingSMART standard property name is FireRating (no space). The Revit IFC exporter's name-matching mechanism is exact. The Fire Rating parameter exported to a Revit Type Parameters property set under the name Fire Rating — present in the file, but invisible to any tool querying for Pset_WallCommon.FireRating.

The fix required: (1) creating a new shared parameter named exactly FireRating; (2) writing a Dynamo script to copy values from Fire Rating to FireRating across all wall types; (3) re-exporting the IFC. The total remediation effort was three working days. The Pset mapping check (Audit Point 3 procedure) would have caught this in the initial QA pass.

6.4 The Quantity Discrepancy That Became a Contract Dispute

A contractor on a healthcare project in the Netherlands used the IFC file's Qto_WallBaseQuantities.GrossVolume values to prepare a concrete volume schedule for subcontract tender. The quantities were approximately 12% higher than the QS's independently computed estimate. The contractor submitted a tender based on the IFC quantities. The subcontractor who won priced at a unit rate lower than market, expecting a higher-than-market volume. When the actual poured concrete was measured, it was 11.4% less than the IFC quantities suggested.

Investigation traced the discrepancy to a combination of two issues: a known bug in the Revit version used for export (pre-25.3) that over-reported GrossVolume by including the zone occupied by window frames as solid concrete, and a MethodOfMeasurement mismatch — the subcontractor's pricing assumed "gross as-formed" volume (no deductions for embedded steel), while the IFC quantities used a different method.

The Quantity Verification check (Audit Point 5 procedure), specifically the cross-check of IFC quantities against an independent schedule and the gross/net distinction check, would have surfaced the over-reporting before issue. The contract dispute required adjudication and was settled at 60% of the claimed difference — a direct financial consequence of unaudited quantity data in an issued IFC.


7. Limits and Caveats

7.1 The Audit Catches What the Standard Covers

The six-point audit is bounded by what the IFC schema defines. Vendor extensions — Revit-specific parameter sets, Archicad-specific element subtypes, Bentley-specific structural analysis properties — sit outside the standard. The audit will confirm that standardised properties are correctly mapped; it will not validate the completeness or accuracy of non-standard extensions. If the project's EIR references non-standard properties (which is legitimate in IFC 4's property set extension framework), those require a separate custom ruleset in Solibri or a project-specific IfcOpenShell script.

7.2 IFC 4.3 Adoption Is Patchy

As of mid-2026, IFC 4.3 is the ISO-published standard (ISO 16739-1:2024), but the certification landscape has not caught up. The buildingSMART certified software list shows IFC 4.3 certification for a minority of the platforms commonly used in practice. Self-reported IFC 4.3 support — listed on the buildingSMART implementations page — covers more tools, but self-reporting is not equivalent to tested interoperability.

For building projects (as opposed to infrastructure), the differences between IFC 4 and IFC 4.3 are primarily in schema cleanup and the infrastructure extensions — the core building element classes, property sets, and quantity sets are largely unchanged. Issuing IFC 4 (ADD2 TC1) for building projects remains the pragmatic choice until receiver certification for 4.3 is more widespread.

For infrastructure projects — roads, tunnels, bridges, ports — IFC 4.3 is the right target. Its IfcAlignment, IfcLinearPlacement, and IfcCivilElement additions are not backported to IFC 4, and civil coordination tools that support 4.3 (including recent versions of Civil 3D, Bentley OpenRoads, and Novapoint) produce far richer data in 4.3 than in 4.

7.3 The Audit Does Not Replace a Model Review

The six-point audit validates data compliance: coordinates, identifiers, properties, classifications, quantities, and geometry validity. It does not validate design intent. A wall at the wrong location will pass all six audit points if its coordinate is correctly represented in the IFC. A room with the wrong area allocation will pass if the area value in the IFC matches the incorrect Revit room definition. The audit is not a design review; it is a data hygiene check.

7.4 Revit Exporter Bugs Are Versioned

Several of the failure modes described in this article are linked to specific Revit exporter versions. The Gross/Net quantity label swap, the 1,000× unit conversion error, the ExportAsSameIfcSite displacement bug — all of these were present in specific builds and fixed in subsequent releases. The Autodesk revit-ifc GitHub repository (https://github.com/Autodesk/revit-ifc/releases) is the authoritative source for release notes. Before issuing an IFC from a Revit version you have not recently audited, check the release notes for your version against the current release to identify open known issues.

7.5 The Audit Assumes a Single-Phase Export

The audit procedures assume the IFC represents a single model state. Multi-phase or 4D-enabled IFC exports, where element states change across IfcPhase or IfcConstructionOrder entities, introduce additional complexity in GUID management (elements may have phase-conditional existence), quantity attribution (quantities may be phase-specific), and geometry (demolish/new/existing representations). The audit framework applies to each phase slice independently, but the additional relational complexity requires extended scripts and a more nuanced coverage analysis.

7.6 Information Delivery Specifications (IDS) Are the Next Layer

The six-point audit checks conformance against the IFC schema and buildingSMART standard property sets. It does not check conformance against project-specific requirements defined in an Employer's Information Requirements or a BIM Execution Plan. The buildingSMART Information Delivery Specification (IDS) standard provides a machine-readable format for expressing those project-specific requirements — which element types must carry which properties, which classification systems are mandatory, which quantity sets are required. An IDS file can be loaded directly into the buildingSMART Validation Service or tools like Bonsai (IfcOpenShell's authoring application) for automated, project-tailored compliance checking.

The six-point audit described in this article is a foundational baseline. For mature, high-information-value handovers, pair it with an IDS-driven check that encodes the project's specific EIR requirements into a verifiable specification file. The two approaches are complementary: the schema-level audit catches what the standard defines; the IDS check catches what the project requires.

7.7 BIM Execution Plan Alignment Is a Prerequisite

No audit procedure can compensate for an absent or vague BIM Execution Plan. The audit points in Section 4 all require documented reference values: agreed coordinate origin (Audit Point 1), a defined GUID stability policy (Audit Point 2), an EIR-specified Pset and property list (Audit Point 3), a declared classification system and table scope (Audit Point 4), a specified method of measurement for quantities (Audit Point 5), and agreed geometry fidelity requirements (Audit Point 6). If those reference values are not written down in the BEP before the project's first IFC issue, the audit becomes a set of checks against undocumented assumptions — and undocumented assumptions are where disputes begin.

The practical implication: if you are reading this article to prepare for an upcoming handover and you do not have a BEP that specifies all six of the above, the highest-value thing you can do right now is draft those specifications and get them agreed with your client and design team. The audit is then straightforward. Without them, the audit tells you what the file contains; it cannot tell you whether what it contains is correct.


8. Sources and Further Reading

The following primary sources were used in the preparation of this article. All URLs were verified accessible as of June 2026.

Standards and Specifications

  1. buildingSMART International. IFC 4.3.2.0 Documentation (ISO 16739-1:2024). The official specification and the normative reference for all IFC 4.3 entity definitions, property sets, and quantity sets cited in this article. Available at https://standards.buildingsmart.org/IFC/RELEASE/IFC4_3/ and with supplementary examples at https://ifc43-docs.standards.buildingsmart.org/

  2. buildingSMART International. IFC 4.0.2.1 Documentation (ISO 16739-1:2018). The current ISO-published IFC 4 specification, covering Pset_* property set definitions and Qto_* quantity set definitions. Available at https://standards.buildingsmart.org/IFC/RELEASE/IFC4/FINAL/HTML/

  3. buildingSMART International. IFC Schema Specifications — Release Notes and Version History. Documents the lineage from IFC 2x3 through 4.3, with release dates and ISO designations for each version. Available at https://technical.buildingsmart.org/standards/ifc/ifc-schema-specifications/

  4. ISO 10303-21:2016. Industrial automation systems and integration — Product data representation and exchange — Part 21: Implementation methods: Clear text encoding of the exchange structure. The base STEP physical file format standard underlying all IFC files. Referenced via https://www.loc.gov/preservation/digital/formats/fdd/fdd000448.shtml

  5. buildingSMART International. Implementation Guide for IFC Header Data, Version 1.0.2. Normative guidance on the STEP FILE_DESCRIPTION, FILE_NAME, and FILE_SCHEMA header entities required in every IFC file. Available at https://standards.buildingsmart.org/documents/Implementation/ImplementationGuide_IFCHeaderData_Version_1.0.2.pdf

Tools and Technical References

  1. Autodesk. IFC Export Setup Options — Revit 2024 Help. The canonical reference for Revit IFC export dialog settings. Available at https://help.autodesk.com/view/RVT/2024/ENU/?guid=GUID-E029E3AD-1639-4446-A935-C9796BC34C95

  2. Autodesk. revit-ifc GitHub Repository — Releases. Versioned release notes for the open-source Revit IFC exporter, including bug fixes referenced in Sections 3.5 and 7.4. Available at https://github.com/Autodesk/revit-ifc/releases

  3. IfcOpenShell Project. IfcOpenShell 0.8.x Documentation. The primary reference for the IfcOpenShell Python library used in all audit scripts in this article. Covers geometry processing, property set utilities, and the geometry iterator API. Available at https://docs.ifcopenshell.org/

  4. buildingSMART International. IFC Validation Service User Guide. Documents what the online validation service checks, how to use it, and its limitations relative to project-specific validation. Available at https://buildingsmart.github.io/validate/user/index.html

  5. BIM me UP. Revit, IFC and Coordinate Systems. A thorough practitioner-level treatment of Revit's four coordinate reference points and how each maps to the IFC coordinate hierarchy. Available at https://bim-me-up.com/en/revit-ifc-and-coordinate-systems/

  6. Evolve Consultancy. Revit IFC Export #6: Classifications. Detailed walkthrough of the five classification implementation methods in Revit and which produce true IfcClassificationReference entities. Available at https://evolve-consultancy.com/revit-ifc-export-6-classifications/

  7. BIM Corner. IFC Exports from Revit, Done Right: Settings, Mapping, and Less Headaches. Practitioner guidance on export configuration, common pitfalls, and category mapping. Available at https://bimcorner.com/ifc-exports-from-revit-done-right/

Further Reading