List Railing Types

This 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:

Railing and stair types in project browser

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.


Comments

20 responses to “List Railing Types”

  1. It will be nice to get this famous “RvtMgdDbg” ;-)

  2. Hi Pierre,
    Thank you for a very good question! I have been waiting for that one for a long time!
    You can go to the Autodesk University web site at http://au.autodesk.com and search for “revit database”. That will take you to the presentation on the Revit database by Mikako Harada, which includes RvtMgdDbg in the class materials. The direct link is
    http://au.autodesk.com/?nd=class&session_id=1137
    The materials are named “Closer Look Revit Database additional materials”.
    You will have to register as a user at the AU web site to gain access to the materials.
    Oh, Stephen Preston just pointed out that a more direct link to the Revit 2009 version of RvtMgdDbg is provided on a publicly accessible ADN web page:
    http://download.autodesk.com/media/adn/RvtMgdDbg2009_0429_2008.zip
    Cheers, Jeremy.

  3. Hi Jeremy, just wondering if you know whether a new version of the RvtMgdDbg is/will be available for the forthcoming 2010 version. I am an ADN member.

  4. Dear Krispy,
    I am still unclear what I can and cannot discuss and publish here on the upcoming versions, so I will reply to you by mail.
    I would recommend you to ask such a question through DevHelp Online, which will guarantee you a response from our whole team and will not put you in risk of violating your NDA :-)
    Cheers, Jeremy.

  5. Dear Krispy,
    Actually, I can answer right here and now after all, because I just thought of searching for RvtMgdDbg on the ADN web site, et voila, it is right there, plain as pie, at your disposal.
    As you may be aware, RvtMgdDbg comes complete with source code, so in case of need, you can always recompile it yourself for any version you please.
    It does also occur that some specific properties on some specific objects throw exceptions. If you discover such a situation, I suggest you run RvtMgdDbg in the debugger and simply wrap the offending line in its own little try-catch handler so you can continue working with the rest of the data. If you make any fixes, we will be happy to hear about them through ADN. Thank you!
    Cheers, Jeremy.

  6. Great, thanks for the responses. Informative as always!!

  7. Hi Jeremy, thank you very much!!
    I used the second example in my proyect, I got 6 family simbols and now I want create a balcony with one family but it does not draw anything.
    Only draw if I insert a point, but if I use a line or curve, it does not draw.
    Thank you!!
    Berria

  8. Hi Berria,
    It is a pleasure, as always. I see your question and I also received you email, but I see no significant difference between the code in your email and the code listed above. I do not quite understand what you are trying to get at. As you can see from the discussion above and other similar topics in the past, I also always have to do some research to find out how to effectively create a new instance of a family. What research have you done so far for your balcony?
    Best regards, Jeremy.

  9. Hi Jeremy, I try do railing with diferents methols, but always the result is null.
    The code is this:
    List symbols = new List();
    BuiltInCategory bic = BuiltInCategory.OST_StairsRailingBaluster;
    CreationFilter cf = app.Create.Filter;
    Filter f1 = cf.NewCategoryFilter(bic);
    Filter f2 = cf.NewTypeFilter(typeof(FamilySymbol));
    Filter f3 = cf.NewLogicAndFilter(f1, f2);
    doc.get_Elements(f3, symbols);
    foreach (FamilySymbol s in symbols)
    {
    Debug.Print(
    “Family name={0}, symbol name={1}”,
    s.Family.Name, s.Name);
    }
    FamilySymbol symbolBaran = symbols[4] as FamilySymbol;
    XYZ p1 = new XYZ(17, 0, 0);
    XYZ p2 = new XYZ(33, 0, 0);
    Line curba = app.Create.NewLineBound(p1 ,p2);
    FamilyInstance Railing1 = doc.Create.NewFamilyInstance(curba, symbolBaran, nivel1, StructuralType.NonStructural);
    Best regards, Berria.

  10. Hi Berria,
    I am beginning to suspect that you actually meant railing when you said balcony in you previous messages?
    And I also get the impression I was unclear in my posting above.
    To create a railing, you have to select the railing symbols, not the railing baluster ones.
    So the category is OST_StairsRailing, not OST_StairsRailingBaluster.
    The railing object uses a Symbol to define its type, not a FamilySymbol.
    So the class to search for is Symbol, not FamilySymbol.
    The post above mentions this fact. I am looking at implementing code to insert a new railing instance.
    Cheers, Jeremy.

  11. Hi Berria,
    I took a closer look at your problem, and there is indeed an issue involved:
    As said, the railing object seems to use a Symbol to define its type, not a FamilySymbol.
    On the other hand, the NewFamilyInstance requires us to pass it a FamilySymbol instance.
    I am still exploring how to resolve this.
    Cheers, Jeremy.

  12. Hi Berria,
    I just noticed something else in the developer’s guide.
    Section 14 Sketching states that “To create elements or edit their profiles in Revit, you must first create sketch objects. Examples of elements that require sketches include:
    – Roofs
    – Floors
    – Stairs
    – Railings.”
    I will continue to explore this issue.
    Cheers, Jeremy.

  13. Hi Berria,
    An unpleasant and tentatively final update on this issue: apparently, it is currently not possible to create a railing through the API at all. The problem is that in the list of the railing types that we obtain above, all railing types that we would like to use to create the railing instance are Symbol instances, and not FamilySymbol ones. However, in order to call the NewFamilyInstance method, we need a FamilySymbol. I do not know of any workaround. Sorry for the bad news and thank you for your perseverance.
    Put differently, Stairs and Railings use system families and not component families, which is why it is failing. It needs yet to be exposed through the API.
    Cheers, Jeremy.

  14. Dear Berria,
    To follow up and wrap up this discussion, I implemented a new command named CmdNewRailing in The Building Coder sample solution which unfortunately does NOT create a new railing instance for the reasons explained above. It can be used to explore the reasons and the limits we encounter. It is available in version 1.0.0.27 of The Building Coder source code, in the post
    http://thebuildingcoder.typepad.com/blog/2009/02/list-linked-elements.html
    Cheers, Jeremy.

  15. Jeremy
    Is there anyway to get RvtMgdDbg 2010 version?
    I am not an ADN member, but would love to get into the API. I am an IT Manager / CAD Technician at.

  16. Dear Luke,
    I have to check with my colleagues first whether I can publish this.
    Regardless of that, the 2009 version of RvtMgdDbg is publicly available and includes source code, so if you have the pre-release 2010 version of Revit, there is nothing to stop you from porting the 2009 version to 2010 yourself:
    http://thebuildingcoder.typepad.com/blog/2009/02/rvtmgddbg.html
    Cheers, Jeremy.

  17. Hi Jeremmy. I found a way to create Railings using the API. First I pick an existing railing and create a group of it. Then copy the group, ungroup and change the railing location line. I did this to place railings over the top of walls in a perimeter fence.

  18. Dear Rolando,
    Thank you very much for this hint, I am sure that will be very interesting for others a well!
    Congratulations on solving this!
    By the way, the Revit 2013 API now provides an official stair and railing API, which should simplify things significantly:
    http://thebuildingcoder.typepad.com/blog/2012/03/revit-2013-and-its-api.html#4
    Cheers, Jeremy.

  19. Jack Zhu Avatar
    Jack Zhu

    Dear Rolando Hijar
    I want to create railing on top of walls Recently。
    According to the above point,I copy an existing railing in 【ElementTransformUtils.CopyElement】,although I Can’t change the railing loaction。
    Could you teach me related source code When convenient。
    Jack Zhu

  20. Jack Zhu Avatar
    Jack Zhu

    Dear Rolando Hijar
    I want to create railing on top of walls Recently。
    According to the above point,I copy an existing railing in 【ElementTransformUtils.CopyElement】,although I Can’t change the railing loaction。
    Could you teach me related source code When convenient。
    Jack Zhu

Leave a Reply