Wednesday, March 15, 2017

Free Source Code: Collect all Rooms on a Given Level

From the Building Coder blog:

Collect all Rooms on a Given Level

From the Revit API discussion forum thread on collecting all rooms in level xx:

Question: How can I collect all rooms on a given level?

Answer 1: You can't collect Rooms directly, you need to collect SpatialElement instead, its parent class, and then post-process the results:

  public List<Room> GetRoomFromLevel( 
    Document document, 
    Level level )
    List<Element> Rooms 
      = new FilteredElementCollector( document )
        .OfClass( typeof( SpatialElement ) )
        .Where( room => room.GetType() == typeof( Room ) )

    return new List<Room>( Rooms.Where( room 
        => document.GetElement( room.LevelId ) == level )
      .Select( r => r as Room ) );

The Where and List<> stuff comes from the System.Collections.Generic namespace.

Answer 2: Here is a new method GetRoomsOnLevel that I added to The Building Coder samples release 2017.0.132.8 sporting some small improvements:

  #region Retrieve all rooms on a given level
  /// <summary>
  /// Retrieve all rooms on a given level.
  /// </summary>
  public IEnumerable<Room> GetRoomsOnLevel(
    Document doc,
    ElementId idLevel )
    return new FilteredElementCollector( doc )
      .OfClass( typeof( SpatialElement ) )
      .Where( e => e.GetType() == typeof( Room ) )
      .Where( e => e.LevelId.IntegerValue.Equals(
        idLevel.IntegerValue ) )
  #endregion // Retrieve all rooms on a given level

This is more efficient than the first version due to:
  • Elimination of ToList
  • Elimination of New List<>
  • Elimination of doc.GetElement

The reason you cannot filter directly for Room elements is explained in the discussion on filtering for a non-native class and in the remarks on the ElementClassFilter class.

There's more information available on the The Building Coder blog.

No comments: