Set of blue PVC pipe fittings isolated on dark background. Blue plastic water pipe. PVC accessories

Your Pipe Fittings Are Grey in IFC? Here’s Why (And How to Fix It)

How to guides By Jul 17, 2025 No Comments

You’ve exported your model to IFC. Pipes look great. Fittings? Grey. Again. What’s going on?

This one trips up a lot of teams, because pipe fittings in Revit don’t actually carry system data, even though they look like they do. So when you rely on system-assigned materials for your IFC exports, fittings get left behind.

Revit’s built-in exporter just shrugs and spits out default grey, meanwhile you’re left scratching your head.

A lot of teams set up their Revit templates so pipe colours are based on system type. They assign an appearance material to each system, and as they model, everything looks right, pipes and fittings included. Even when using filters instead of system materials, fittings appear to match because they inherit the look visually.

The catch? Fittings don’t actually contain system data. You never notice, because in Revit views and on prints, everything looks fine. But filters don’t export, and system materials are the lowest priority in IFC. So when you finally check your IFC file, bam! Grey fittings. And it’s only then you realise something’s gone wrong.

Updating to the latest Revit IFC Exporter didn’t resolve the issue. However, Autodesk’s support article confirmed that applying materials at the system level is the lowest priority in IFC exports. To fix this, we need to explicitly assign the material using the IfcSingleMaterialOverride parameter.

The Fix

You need to bypass Revit’s assumptions and assign the material directly using the IfcSingleMaterialOverride parameter. To do this, you need to:

  1. Create a new project parameter:
    • Name: IfcSingleMaterialOverride
    • Instance: Yes
    • Type: Text
    • Group under: Ifc Parameters
    • Apply to: Pipes and Pipe Fittings
image courtesy of Autodesk

Next comes the automation so you don’t go filling out the values manually. The basics of the process is to:

  • Collect all pipes and pipe fittings.
  • Grab the material from the connected pipe’s system.
  • Apply that material name as a string to the IfcSingleMaterialOverride parameter on each pipe and fitting.

Here’s a macro that does exactly that, no more grey ghosts in your IFC.

👇 Full C# macro below (just copy, paste, and run):

public void Override()
{
    UIDocument uidoc = this.ActiveUIDocument;
    Document doc = uidoc.Document;
    int pipeCount = 0;
    int fittingCount = 0;

    // Collect all pipe elements
    FilteredElementCollector pipeCollector = new FilteredElementCollector(doc);
    ICollection<Element> pipes = pipeCollector
        .OfCategory(BuiltInCategory.OST_PipeCurves)
        .WhereElementIsNotElementType()
        .ToElements();

    // Collect all pipe fitting elements
    FilteredElementCollector fittingCollector = new FilteredElementCollector(doc);
    ICollection<Element> pipeFittings = fittingCollector
        .OfCategory(BuiltInCategory.OST_PipeFitting)
        .WhereElementIsNotElementType()
        .ToElements();

    using (Transaction trans = new Transaction(doc, "Ifc Material Override"))
    {
        trans.Start();

        // Process pipe fittings
        foreach (Element fitting in pipeFittings)
        {
            FamilyInstance pipeFitting = fitting as FamilyInstance;
            if (pipeFitting != null && pipeFitting.MEPModel != null)
            {
                ConnectorSet connectors = pipeFitting.MEPModel.ConnectorManager.Connectors;
                foreach (Connector connector in connectors)
                {
                    MEPSystem system = connector.MEPSystem;
                    if (system != null)
                    {
                        ElementId systemTypeId = system.GetTypeId();
                        Element systemType = doc.GetElement(systemTypeId);
                        Parameter materialParam = systemType.LookupParameter("Material");
                        if (materialParam != null && materialParam.HasValue)
                        {
                            ElementId matId = materialParam.AsElementId();
                            Material mat = doc.GetElement(matId) as Material;
                            string materialName = mat != null ? mat.Name : "";
                            Parameter ifcOverrideParam = pipeFitting.LookupParameter("IfcSingleMaterialOverride");
                            if (ifcOverrideParam != null && !ifcOverrideParam.IsReadOnly)
                            {
                                ifcOverrideParam.Set(materialName);
                            }
                        }
                        break; // Found a system, no need to check other connectors
                    }
                }
            }
            fittingCount++;
        }

        // Process pipes
        foreach (Element pipe in pipes)
        {
            Pipe pipeElement = pipe as Pipe;
            if (pipeElement != null && pipeElement.MEPSystem != null)
            {
                MEPSystem system = pipeElement.MEPSystem;
                ElementId systemTypeId = system.GetTypeId();
                Element systemType = doc.GetElement(systemTypeId);
                Parameter materialParam = systemType.LookupParameter("Material");
                if (materialParam != null && materialParam.HasValue)
                {
                    ElementId matId = materialParam.AsElementId();
                    Material mat = doc.GetElement(matId) as Material;
                    string materialName = mat != null ? mat.Name : "";
                    Parameter ifcOverrideParam = pipeElement.LookupParameter("IfcSingleMaterialOverride");
                    if (ifcOverrideParam != null && !ifcOverrideParam.IsReadOnly)
                    {
                        ifcOverrideParam.Set(materialName);
                    }
                }
            }
            pipeCount++;
        }

        trans.Commit();
    }

    TaskDialog.Show("Ifc Material Override", "Overridden " + pipeCount + " pipes" + Environment.NewLine + "Overridden " + fittingCount + " pipe fittings");
}Code language: PHP (php)

⚙️ How It Works

✅ Pipes get their material from their MEP system type

✅ Fittings borrow the system data from a connected pipe

✅ All elements get the correct material applied to the IFC override

Set-and-forget. One macro, problem solved.

image courtesy of Autodesk

Relying on system-assigned materials works great until it doesn’t. This method gives you complete control and ensures fittings are never overlooked again. No more grey IFC exports. No more QA headaches.

If you’re using filters or view templates to colour systems, that’s actually my preferred method, and that’s fine for documentation, but it means nothing for your IFC.

To control IFC colour, you need to control materials.

Let me know if this approach solves your issue, or if you’ve hacked together another method that works better. Always keen to hear how others are handling dodgy exports.

No Comments

Leave a comment

Your email address will not be published. Required fields are marked *