Model elements are generally part of the building and have geometry. In this lab we will implement a filter to retrieve all model elements, i.e. Revit element instances with a 3D geometrical representation. There are several possible approaches to retrieving these elements. Here, we will present a method that loops over all document elements uses a combination of different criteria to ensure that only valid model elements are selected. The criteria applied to each element are:
The preview legend components inadvertently acquired geometry that is accessible through the API in Revit 2010. Previously, that check was not neccessary.
The comparison of the element category with the built-in preview legend components one can be achieved by simply comparing the former's element id value with the latter cast to an integer.
Add a standard external command implementation to the Labs2 module to iterate over all document elements:
#region Lab2_2_ModelElements public class Lab2_2_ModelElements : IExternalCommand { public CmdResult Execute( ExternalCommandData commandData, ref string message, ElementSet elements ) { Application app = commandData.Application; Document doc = app.ActiveDocument; ElementIterator it = doc.Elements; string s = string.Empty; int count = 0; while( it.MoveNext() ) { Element e = it.Current as Element; } s = "There are " + count.ToString() + " model elements:" + s; LabUtils.InfoMsg( s ); return CmdResult.Failed; } } #endregion // Lab2_2_ModelElements
#Region "Lab2_2_ModelElements" 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 Dim app As Application = commandData.Application Dim doc As Document = app.ActiveDocument Dim it As ElementIterator = doc.Elements Dim s As String = String.Empty Dim count As Integer = 0 Do While (it.MoveNext()) Dim e As Element = it.Current Loop s = "There are " & count & " model elements:" & s MsgBox(s) Return IExternalCommand.Result.Failed End Function End Class #End Region
Compile and link the project and update the Revit.ini file accordingly (cf. 'Add_to_Revit_ini.txt'), or load the command with the help of Add-in Manager.
Once this is up and running, you can explore how to add the filter criteria discussed above to skip all the thousands of unwanted non-model elements. Here is one example of the while loop enhanced to apply that filter. First, we need to declare a gloabl variable or two to compare the preview legend components category:
public class Lab2_2_ModelElements : IExternalCommand { BuiltInCategory _bicPreviewLegendComponent = BuiltInCategory.OST_PreviewLegendComponents; public CmdResult Execute( ExternalCommandData commandData, ref string message, ElementSet elements ) { Application app = commandData.Application; Document doc = app.ActiveDocument; ElementIterator it = doc.Elements; string s = string.Empty; int count = 0; Geo.Options opt = app.Create.NewGeometryOptions(); int iBic = (int) _bicPreviewLegendComponent; while( it.MoveNext() ) { Element e = it.Current as Element; if ( !(e is Symbol) && !(e is FamilyBase) && (null != e.Category) && ( iBic != e.Category.Id.Value ) && (null != e.get_Geometry( opt )) ) { ++count; s += string.Format( "\r\n Category={0}; Name={1}; Id={2}", e.Category.Name, e.Name, e.Id.Value.ToString() ); } } s = "There are " + count.ToString() + " model elements:" + s; LabUtils.InfoMsg( s ); return CmdResult.Failed; } }
Public Class Lab2_2_ModelElements Implements IExternalCommand Dim _bicPreviewLegendComponent As BuiltInCategory = BuiltInCategory.OST_PreviewLegendComponents Public Function Execute( _ ByVal commandData As ExternalCommandData, _ ByRef message As String, _ ByVal elements As ElementSet) _ As IExternalCommand.Result _ Implements IExternalCommand.Execute Dim app As Application = commandData.Application Dim doc As Document = app.ActiveDocument Dim it As ElementIterator = doc.Elements Dim s As String = String.Empty Dim count As Integer = 0 Dim opt As Geometry.Options = app.Create.NewGeometryOptions Dim iBic As Integer = _bicPreviewLegendComponent Do While (it.MoveNext()) Dim e As Element = it.Current If Not (TypeOf e Is Symbol) _ And Not (TypeOf e Is FamilyBase) _ And Not (e.Category Is Nothing) _ And Not (iBic = e.Category.Id.Value) Then Dim geo As Geometry.Element = e.Geometry(opt) If Not (geo Is Nothing) Then count = count + 1 s += vbCrLf & " Category=" & e.Category.Name & "; Id=" & e.Id.Value.ToString End If End If Loop s = "There are " & count & " model elements:" & s MsgBox(s) Return IExternalCommand.Result.Failed End Function End Class
Run the command, examine and discuss the elements obtained before and after filtering, and what the various items in the filter statement mean, with the course instructor and your peers.
next previous home copyright © 2007-2009 jeremy tammik, autodesk inc. all rights reserved.