List Railing Types
Originally Published inThis is in response to a query from Berria on iterating over the railing types in the model. It is also once again about teaching how to fish, and not just feeding people, at least I hope so. If I want to list all the railing types, the best way to go is probably to define an API filter which retrieves them from the model for me. How do I design that filter? I start by opening a new model, inserting a railing, and examining it with RvtMgdDbg ↗. There I can easily determine that its built-in category is OST_StairsRailing. Therefore, I first thought that an API filter selecting all family symbols of this category should suffice. The project browser shows me the following stair and railing symbols in my current model:
I implemented a new external command CmdListRailingTypes to test this approach, with the following code:
Application app = commandData.Application;
Document doc = app.ActiveDocument;
CreationFilter cf = app.Create.Filter;
List<Element> symbols = new List<Element>();
BuiltInCategory bic
= BuiltInCategory.OST_StairsRailing;
Filter f1
= cf.NewCategoryFilter( bic );
Filter f2
= cf.NewTypeFilter( typeof( FamilySymbol ) );
doc.get_Elements( f, symbols );
foreach( FamilySymbol s in symbols )
{
Debug.Print(
"Family name={0}, symbol name={1}",
s.Family.Name, s.Name );
}
return CmdResult.Failed;
It makes use of a new alias for CreationFilter:
using CreationFilter
= Autodesk.Revit.Creation.Filter;
To my initial surprise, no symbols were found. I thereupon took a closer look at the symbols within the railings family in RvtMgdDbg and discovered that the category of the M_Baluster symbols is not OST_StairsRailing but OST_StairsRailingBaluster. Changing the value of the ‘bic’ variable to that built-in category returns some valid results:
Family name=M_Baluster - Square, symbol name=25mm
Family name=M_Baluster - Square, symbol name=20mm
Family name=M_Baluster - Round, symbol name=25mm
Family name=M_Baluster - Round, symbol name=20mm
This does still not include all the railing symbols listed in the browser, so I went back into RvtMgdDbg and searched for those as well. They were not listed in the FamilySymbol collection, but under Symbols, this time indeed with the category OST_StairsRailing.
Making use of this info, I implemented a second filter and iteration to retrieve and list Symbol objects like this:
bic = BuiltInCategory.OST_StairsRailing;
f1 = cf.NewCategoryFilter( bic );
f2 = cf.NewTypeFilter( typeof( Symbol ) );
f = cf.NewLogicAndFilter( f1, f2 );
doc.get_Elements( f, symbols );
n = symbols.Count;
Debug.Print( "{0}"
+ " OST_StairsRailing symbol{1}:",
n, Util.PluralSuffix( n ) );
foreach( Symbol s in symbols )
{
FamilySymbol fs = s as FamilySymbol;
Debug.Print(
"Family name={0}, symbol name={1}",
null == fs ? "<none>" : fs.Family.Name,
s.Name );
}
The result of this code is somewhat surprising too. The non-family symbols that we are looking for are retrieved now, just like we hoped, and we also retrieve the family symbols that we already saw above:
6 OST_StairsRailing symbols:
Family name=M_Baluster - Square, symbol name=25mm
Family name=M_Baluster - Square, symbol name=20mm
Family name=M_Baluster - Round, symbol name=25mm
Family name=M_Baluster - Round, symbol name=20mm
Family name=<none>, symbol name=900mm Pipe
Family name=<none>, symbol name=900mm Rectangular
This goes to show several things:
- You need to explore the model.
- You may get unexpected results.
I’ll just leave it at that for now.
Here is version 1.0.0.25 of the complete Visual Studio solution with the new CmdListRailingTypes command implementation.