Create a 3d view showing only #Revit wall structural layers

A post in the forum mentions that “I have a list of Walls and I want to create a new View3D with the same walls but containing only the ‘Structure’ function layers”. We can do this nicely with the Part functionality and the Revit API.

public void ShowWallStructureOnly()
{
    var doc = this.ActiveUIDocument.Document;
    View3D view;
    using (Transaction t = new Transaction(doc, "create wall structure view"))
    {
        t.Start();
        view = View3D.CreateIsometric(doc, new FilteredElementCollector(doc)
                                        .OfClass(typeof(ViewFamilyType))
                                        .Cast<ViewFamilyType>()
                                        .First(q => q.ViewFamily == ViewFamily.ThreeDimensional).Id);
        if (doc.ActiveView is View3D)
        {
            view.SetOrientation(((View3D)doc.ActiveView).GetOrientation());
        }
        view.PartsVisibility = PartsVisibility.ShowPartsOnly;
        PartUtils.CreateParts(doc, new FilteredElementCollector(doc, view.Id).OfClass(typeof(Wall))
                              .Where(q => PartUtils.IsValidForCreateParts(doc, new LinkElementId(q.Id)) && !PartUtils.HasAssociatedParts(doc, q.Id))
                              .Select(q => q.Id).ToList());
        doc.Regenerate();
        var toHide = new List<ElementId>();
        foreach (var part in new FilteredElementCollector(doc, view.Id).OfClass(typeof(Part)))
        {
            // I expected DPART_ORIGINAL_TYPE would store the element id of the wall type
            // but it stores the wall type's name as a string
            var typeName = part.get_Parameter(BuiltInParameter.DPART_ORIGINAL_TYPE).AsString();
            
            var wallType = new FilteredElementCollector(doc)
                .OfClass(typeof(WallType))
                .Cast<WallType>()
                .First(q => q.Name == typeName);
            var layers = wallType.GetCompoundStructure().GetLayers();
            var parameter = part.get_Parameter(BuiltInParameter.DPART_LAYER_INDEX);
            if (parameter == null)
            {
                continue;
            }
            
            // I expected DPART_LAYER_INDEX would store the index as an integer
            // but it stores it as as string
            var layerInt = int.Parse(parameter.AsString());
            var layer = layers[layerInt - 1];
            if (layer.Function != MaterialFunctionAssignment.Structure)
            {
                toHide.Add(part.Id);
            }
        }
        if (toHide.Any())
           view.HideElements(toHide);
        t.Commit();
    }
    this.ActiveUIDocument.ActiveView = view;
}

An enhancement to this code could be to check the function of each wall type layer once, not once per wall.

4 thoughts on “Create a 3d view showing only #Revit wall structural layers

  1. Thank you for this nice sample. I summarised the functionality and thought my list of steps might be of interest to other as well, so here goes:

    – Create new 3D isometric view
    – Set parts visibility PartsVisibility.ShowPartsOnly
    – Create parts from all walls
    – For each part, retrieve its built-in parameter DPART_LAYER_INDEX
    – Convert from string to wall compound structure layer index
    – Hide part if its compound structure layer function differs from MaterialFunctionAssignment.Structure

    Cheers, Jeremy.

  2. Thank you Henry, this is a very intersting approach. I have another question is it possible to split walls by levels ?

  3. This makes total sense now, will cast my vote anyway, hopefull this will be addressed in future iterations. Thank you

Leave a comment