next previous home

2-3 Family Instances

Revit makes heavy use of families to define certain classes of elements. There are system families, which are built-in to Revit, and standard families, which are defined in external files with the filename extension *.rfa. Walls are defined using a system family, and windows by standard families. One way to get all walls or windows would be to use something like the GetAllModelElements() utility with an additional check on the category name. But we can achieve this task somewhat more elegantly and in a generic manner by coding the following two utilities within LabUtils class. The first one is specific for walls and uses a filter to obtain all walls in the document. It provides much better performance than the traditional iteration through the whole document elements collection. In addition, the code is easy to use and more succinct.

    /// <summary>
    /// Helper to get all walls using Revit 2009 filtering.
    /// </summary>
    public static List<Element> GetAllWalls( Application app )
    {
      List<Element> elements = new List<Element>();
      Filter filterType = app.Create.Filter.NewTypeFilter( typeof( Wall ) );
      app.ActiveDocument.get_Elements( filterType, elements );
      return elements;
    }
    ''' <summary>
    ''' Helper to get all walls using filter .
    ''' </summary>
    Shared Function GetAllWalls(ByVal app As Revit.Application) As List(Of Element)
        Dim elements As New List(Of Element)
        Dim filterType As Filter = app.Create.Filter.NewTypeFilter(GetType(Wall))
        Dim n As Integer = app.ActiveDocument.Elements(filterType, elements)
        Return elements
    End Function

The second utility function is generic and can be used for any category name for standard families, e.g. Windows, Furniture, etc.:

    /// <summary>
    /// Helper to get all standard family instances for a given category 
    /// using the filter features provided by the Revit 2009 API.
    /// </summary>
    public static List<Element> GetAllStandardFamilyInstancesForACategory(
      Application app,
      BuiltInCategory bic )
    {
      List<Element> elements = new List<Element>();
      Filter filterType = app.Create.Filter.NewTypeFilter( typeof( FamilyInstance ) );
      Filter filterCategory = app.Create.Filter.NewCategoryFilter( bic );
      Filter filterAnd = app.Create.Filter.NewLogicAndFilter( filterType, filterCategory );
      app.ActiveDocument.get_Elements( filterAnd, elements );
      return elements;
    }
    ''' <summary>
    ''' Helper to get all standard family instances for a given category
    ''' using the filter features provided by the Revit 2009 API.
    ''' </summary>
    Shared Function GetAllStandardFamilyInstancesForACategory( _
        ByVal app As Revit.Application, _
        ByVal bic As BuiltInCategory) _
    As List(Of Revit.Element)

        Dim elements As New System.Collections.Generic.List(Of Revit.Element)
        Dim filterType As Revit.Filter = app.Create.Filter.NewTypeFilter(GetType(FamilyInstance))
        Dim filterCategory As Revit.Filter = app.Create.Filter.NewCategoryFilter(bic)
        Dim filterCombination As Revit.Filter = app.Create.Filter.NewLogicAndFilter(filterCategory, filterType)
        Dim nRetVal As Integer = app.ActiveDocument.Elements(filterCombination, elements)
        Return elements

    End Function

Add a new command Lab2_3_AllWallsAndFamilyInstances to the Labs2 module to test these utilities:

  #region Lab2_3_AllWallsAndFamilyInstances
  /// <summary>
  /// List all walls and family instances.
  /// </summary>
  public class Lab2_3_AllWallsAndFamilyInstances : IExternalCommand
  {
    public CmdResult Execute(
      ExternalCommandData commandData,
      ref string message,
      ElementSet elements )
    {
      Application app = commandData.Application;

      // get all walls:
      List<Element> walls = LabUtils.GetAllWalls( app );
      string s = "All walls in the model:";
      foreach ( Wall wall in walls )
      {
        s += "\r\n  Id=" + wall.Id.Value.ToString()
          + "; Kind=" + wall.WallType.Kind.ToString()
          + "; Type=" + wall.WallType.Name;
      }
      LabUtils.InfoMsg( s );

      // get all doors (you can change it to eg Furniture or Windows...)
      // NOTE: Before 9.0, one had to hard-code the name which wouldn't work in other locales!
      // Dim catName As String = "Doors"
      // Since 9.0, there is enumeration which works with ALL locales
      BuiltInCategory bic = BuiltInCategory.OST_Doors;
      string catName = app.ActiveDocument.Settings.Categories.get_Item( bic ).Name;
      List<Element> familyInstances = LabUtils.GetAllStandardFamilyInstancesForACategory( app, bic );
      s = "All " + catName + " instances in the model:";
      foreach( FamilyInstance inst in familyInstances )
      {
        // For FamilyInstances, the element name property returns the type name:
        s += "\r\n  Id=" + inst.Id.Value.ToString() + "; Type=" + inst.Name;
      }
      LabUtils.InfoMsg( s );
      return CmdResult.Succeeded;
    }
  }
  #endregion // Lab2_3_AllWallsAndFamilyInstances
#Region "Lab2_2_ModelElements"
    ''' <summary>
    ''' List all model elements.
    ''' </summary>
    Public Class Lab2_2_ModelElements
        Implements IExternalCommand

        Public Function Execute( _
            ByVal commandData As ExternalCommandData, _
            ByRef message As String, _
            ByVal elements As ElementSet) _
        As IExternalCommand.Result _
        Implements IExternalCommand.Execute

            ' Call the utility
            Dim modelElems As ElementSet = LabUtils.GetAllModelElements(commandData.Application)

            ' List all elems
            Dim sMsg As String = "There are " & modelElems.Size & " model elements:"
            Dim elem As Revit.Element
            For Each elem In modelElems
                sMsg += vbCrLf & "  Category=" & elem.Category.Name & "; Id=" & elem.Id.Value.ToString
            Next
            MsgBox(sMsg)

            Return IExternalCommand.Result.Succeeded

        End Function
    End Class

#End Region

Compile and link the project and update the Revit.ini file accordingly. Or load the command with the help of Add-in Manager.

Run the command and examine and discuss the information displayed with the course instructor and your peers.

next previous home copyright © 2007-2008 jeremy tammik, autodesk inc. all rights reserved.