Selecting Model Elements

by

in

This morning I woke up really early.
The hotel clock was set incorrectly, so when I woke up and looked at it, I thought I was much too late for my meeting.
I jumped out of bed, grabbed and packed all my things and ran out of the room to the lobby, where I noticed that it seemed rather quiet outside and the light was very soft and special in the early morning.
Up here in the north it does get light very early, though.
At least I noticed my error before actually getting out into the street.
Now I am unable to sleep, sitting in bed and writing this post.

The Revit API Introduction Lab 2-2 demonstrates how to select all model elements, i.e. elements which are visible on the graphics screen and represent physical parts in the building model.
This lab is part of the sample code used to explain the basics of programming Revit in the

Revit programming webcast
.
When updating this code for Revit 2010, I noticed that one change has occurred in Revit which causes this command to return incorrect results.
First let us have a look at the original version which worked properly in Revit 2009, and then discuss the changes I made for 2010.

In 2009, we used the following helper method to select all model elements:


public static ElementSet GetAllModelElements(
Application app )
{
ElementSet elems = app.Create.NewElementSet();
Geo.Options opt = app.Create.NewGeometryOptions();
ElementIterator iter = app.ActiveDocument.Elements;
while( iter.MoveNext() )
{
Element e = iter.Current as Element;
if( !( e is Symbol || e is FamilyBase ) )
{
if( null != e.Category )
{
if( null != e.get_Geometry( opt ) )
{
elems.Insert( e );
}
}
}
}
return elems;
}

It iterates over all elements in the active document and checks their class, category and geometry content to select the model elements.
The selected elements are stored in a new element set, which is returned to the caller.

When asking the elements for their geometry, a geometry options instance must be provided.
This argument cannot be null.
Otherwise, an exception will be thrown.
However, its detail level property and other properties may be left uninitialized.

The iterator type can be specified as either ElementIterator or IEnumerator.
The iterator returned by the document Elements property is in fact an ElementIterator instance.
This class is derived from the IEnumerator interface, and we only make use of the base class functionality, so an IEnumerator instance could be used just as well.

All the objects returned by the iterator are Autodesk.Revit.Element instances.
It would be nice to know that we only need to check for certain specific types of objects, derived from the Autodesk.Revit.Element class, for example FamilyInstance and HostObject classes.
Unfortunately, some Revit building model objects such as stairs are still represented in the API using the generic Autodesk.Revit.Element class, so this is not possible.
Instead, we use the inverse approach of eliminating certain element types which are not used for building model objects, namely the Symbol and FamilyBase classes.

All building model objects have a valid category and non-empty geometry, so those properties can be used reliably.

However, in Revit 2010, running the same code suddenly returns a number of unexpected objects, even in an empty model.

Legend Component Geometry

The reason for the change in behaviour in Revit 2010 is that legend component objects now also return geometry.
Since they are represented by Autodesk.Revit.Element instances, are not Symbol or ElementBase instances, and also have a valid category, they pass all the filters applied above in spite of not being model objects.
Here is a list of the legend component elements returned in Revit 2010 in an empty model (copy to an editor to see the full line length):


There are 50 model elements:
Name=Basic Wall : Generic - 150mm (Floor Plan); Category=Legend Components; Id=137075
Name=Basic Wall : Interior - 138mm Partition (1-hr) (Floor Plan); Category=Legend Components; Id=137076
Name=Basic Wall : Exterior - Brick and Block on Mtl. Stud (Floor Plan); Category=Legend Components; Id=137077
Name=Basic Roof : Generic Roof - 300mm (Section); Category=Legend Components; Id=137078
Name=Basic Roof : Generic Roof - 750mm (Section); Category=Legend Components; Id=137079
Name=Basic Roof : Generic Roof - 500mm (Section); Category=Legend Components; Id=137080
Name=Floor : Generic Floor - 400mm (Section); Category=Legend Components; Id=137081
Name=Basic Ceiling : Generic (Section); Category=Legend Components; Id=137082
Name=Basic Wall : Generic - 200mm (Floor Plan); Category=Legend Components; Id=137083
Name=Basic Wall : Generic - 250mm (Floor Plan); Category=Legend Components; Id=137084
Name=Basic Wall : Generic - 300mm (Floor Plan); Category=Legend Components; Id=137085
Name=Basic Wall : Generic - 375mm (Floor Plan); Category=Legend Components; Id=137086
Name=Basic Wall : Generic - 300mm Masonry (Floor Plan); Category=Legend Components; Id=137087
Name=Basic Wall : Generic - 200mm CMU (Floor Plan); Category=Legend Components; Id=137088
Name=Basic Wall : Generic - 150mm Masonry (Floor Plan); Category=Legend Components; Id=137089
Name=Basic Wall : Exterior - EIFS on Mtl Stud (Floor Plan); Category=Legend Components; Id=137090
Name=Basic Wall : Generic - 90mm Brick (Floor Plan); Category=Legend Components; Id=137091
Name=Basic Wall : Interior - 79mm Partition (1-hr) (Floor Plan); Category=Legend Components; Id=137092
Name=Basic Wall : Interior - 123mm Partition (1-hr) (Floor Plan); Category=Legend Components; Id=137093
Name=Basic Wall : Interior - 135mm Partition (2-hr) (Floor Plan); Category=Legend Components; Id=137094
Name=Basic Wall : Interior - 126mm Partition (2-hr) (Floor Plan); Category=Legend Components; Id=137095
Name=Basic Wall : Exterior - Brick on CMU (Floor Plan); Category=Legend Components; Id=137096
Name=Curtain Wall (Floor Plan); Category=Legend Components; Id=137097
Name=Floor : Wood Joist 220mm - Wood Finish (Section); Category=Legend Components; Id=137098
Name=Floor : Steel Bar Joist - VCT on LW Concrete  (Section); Category=Legend Components; Id=137099
Name=Basic Roof : Wood Rafter 184mm - Asphalt Shingles (Section); Category=Legend Components; Id=137100
Name=Basic Roof : Steel Truss - Insulation on Metal Deck- EPDM (Section); Category=Legend Components; Id=137101
Name=Basic Wall : Foundation - 300mm Concrete (Floor Plan); Category=Legend Components; Id=137102
Name=Basic Wall : Retaining - 300mm Concrete (Floor Plan); Category=Legend Components; Id=137103
Name=Basic Wall : Generic - 200mm - Filled (Floor Plan); Category=Legend Components; Id=137104
Name=Basic Roof : Generic Roof - 300mm - Filled (Section); Category=Legend Components; Id=137105
Name=Floor : Generic Floor - 400mm - Filled (Section); Category=Legend Components; Id=137106
Name=Compound Ceiling : 600 x 1200mm grid (Section); Category=Legend Components; Id=137107
Name=Compound Ceiling : 600 x 600mm grid (Section); Category=Legend Components; Id=137108
Name=Compound Ceiling : GWB on Mtl Stud (Section); Category=Legend Components; Id=137109
Name=Roof Soffit : Generic - 300mm (Section); Category=Legend Components; Id=137110
Name=Curtain Wall : Exterior Glazing (Floor Plan); Category=Legend Components; Id=137111
Name=Curtain Wall : Storefront (Floor Plan); Category=Legend Components; Id=137112
Name=Basic Wall : Exterior - Brick on Mtl. Stud (Floor Plan); Category=Legend Components; Id=137113
Name=Stacked Wall : Exterior - Brick Over Block w Metal Stud (Floor Plan); Category=Legend Components; Id=137114
Name=Basic Wall : Exterior - Block on Mtl. Stud (Floor Plan); Category=Legend Components; Id=137115
Name=Foundation Slab : 150mm Foundation Slab (Section); Category=Legend Components; Id=137116
Name=; Category=Legend Components; Id=137117
Name=; Category=Legend Components; Id=137118
Name=; Category=Legend Components; Id=137119
Name=; Category=Legend Components; Id=137120
Name=; Category=Legend Components; Id=137121
Name=; Category=Legend Components; Id=137122
Name=; Category=Legend Components; Id=137123
Name=; Category=Legend Components; Id=137124

These legend components are the keepers of the images displayed in the type preview dialog.
The graphical previews are new in 2010 and so the presence of these elements is also new.
The exposure of their geometry to the API is not intentional and may be removed again in future.
Their only function is to create and hold that one image, and the user has no other way to interact with them.

How can we improve our filter to eliminate these unwanted elements?

Since the legend components have a valid category, we could simply add that additional criterion to the list of properties that we are checking, for instance like this:


const string _CategoryNameLegendComponents
= "Legend Components";
if( !(e is Symbol)
&& !(e is FamilyBase)
&& (null != e.Category)
&& (_CategoryNameLegendComponents != e.Category.Name)
&& (null != e.get_Geometry(opt)) )
{
// . . .
}

Instead of using a string comparison on the category name, we could also determine the element id of the legend component category and compare that with each candidate element id.

However, both of these options would add yet another item to an already lengthy list of checks.

A simpler option that seems to work well in the tests I have run so far is to skip checking the object type at all, and replacing it by requiring a valid level, like this:


if( (null != e.Category)
&& (null != e.Level)
&& (null != e.get_Geometry(opt)) )

Besides being simpler and easier to understand, this check is probably also slightly more efficient.
It has not been extensively tested yet, so please let me know if you discover any situations in which it fails.

Here is the current version of the
Revit API introduction labs,
including the new version of Lab 2-2 to select all model elements using this criterion.
The labs are still in the process of being further updated and enhanced for the Revit 2010 API and its new features.
All of the labs are provided in two versions, one each for C# and VB.


Comments

48 responses to “Selecting Model Elements”

  1. Saeed Karshenas Avatar
    Saeed Karshenas

    Jeremy,
    As you know some Revit elements do not have a level. For example a wall footing does not have a level. So using your simpler option for selecting model elements will not find some elements that represent physical parts of a building model. Isn’t it?
    Thanks.

  2. Dear Saeed,
    Thank you very much for pointing this out. Indeed, absolutely right you are. So I guess the selection will have to be some more complicated combination accounting for several different groups of elements after all.
    Cheers, Jeremy.

  3. How Can we find below properties for stairs using c# code revit 2010?
    Elem_Room_ID,
    Elem_Room_Name,
    Elem_Room_Number etc.
    Please reply as soon as possible it’s urgent

  4. Hi Jeremy
    I want to get the location of the stairs and after that x,y points from the location curve.
    But the code i use show me null in the location curve.the code i use is below:
    Location LOC = tempRamps.Location as Location; LocationCurve Locrve = tempRamps.Location as LocationCurve;
    Here location is shown as Autodesk.Revit.Location but no value is shown and in location curve it is coming null.
    Will u plz tell me how can i get the location of stairs and ramps.
    Thanks in Advance
    Ritish

  5. Dear Ritish,
    I have news for you on the RAMP_SLOPE parameter: it is apparently declared but never used anywhere at all. It may be obsolete, or maybe it was never used at all.
    Regarding the location property on the stairs, I mentioned in my previous answer that I was observing the same behaviour as you describe. Unfortunately, the Location property of ramps appears not to be properly exposed. It does not contain a LocationPoint or LocationCurve instance, and therefore the data is probably inaccessible through the API.
    Please note that both stairs and ramps have not been completely exposed to the API yet, e.g. there is no method to create them through the API, and apparently the location is not available either.
    Therefore, you will have to resort to reading the geometry and trying to deduce the required points from that.
    Cheers, Jeremy.

  6. Hi Jeremy
    Thanks for your reply
    Can you please help me some code for getting the geometry elements of the stairs and ramps.
    As the code given in the .chm file and in blog http://thebuildingcoder.typepad.com/blog/2009/04/revit-api-cases-1.html do not work for me. Because in the example it is used for walls and i am unable to understand the parameter Option passed in get_geometry() method for stairs and ramps. I am confused what does the options means for stairs as in below code:
    Options opt = app.Create.NewGeometryOptions();
    NewGeometryOptions() is not getting in the code?
    I am using the below code:
    private void GetStairType(Autodesk.Revit.Document document)
    {
    // Create a Filter to get all the stairs in the document
    Autodesk.Revit.Creation.Filter filterCreator = document.Application.Create.Filter;
    // Stairs are type Element, so we don’t need to include derived types
    TypeFilter elementOnlyFilter = filterCreator.NewTypeFilter(typeof(Autodesk.Revit.Element), false);
    CategoryFilter stairsCategoryfilter = filterCreator.NewCategoryFilter(BuiltInCategory.OST_Stairs);
    Filter stairsFilter = filterCreator.NewLogicAndFilter(elementOnlyFilter, stairsCategoryfilter);
    // Apply the filter to the elements in the active document
    ElementIterator iterator = document.get_Elements(stairsFilter);
    iterator.Reset();
    while (iterator.MoveNext())
    {
    Autodesk.Revit.Element stair = iterator.Current as Autodesk.Revit.Element;
    if (null == stair.ObjectType)
    {
    string temp = “temp”;
    }
    else
    {
    string info = “Stair type is: ” + stair.ObjectType.Name;
    MessageBox.Show(info, “Revit”);
    }
    }
    }

  7. Hi Jeremy..
    We also get the same behaviuor of the stair elements(i.e. the location and room id comes out to be null). But we exported the revit file to ms access database through export feature of Revit Architecture 2010. It does not save the location and room id for the stair element.
    From here, can we say that the stair will not support these two properties.
    Waiting for your positive reply…

  8. Dear Ritish,
    One of the first things you can do is to explore the stair geometry with one of the Revit SDK sample geometry viewers, e.g. the ElementViewer sample. I just tried it out and it works fine. Then, you can also search for various examples of instantiating geometry options in the Revit SDK samples and The Building Coder sample code.
    Find all “NewGeometryOptions”, Match case, Whole word, Subfolders, Find Results 1, “Entire Solution”, “*”
    – CmdColumnRound.cs(121)
    – CmdEditFloor.cs(79)
    – CmdGetMaterials.cs(115)
    – CmdNestedInstanceGeo.cs(117)
    – CmdSlabBoundary.cs(110)
    – CmdSlabSides.cs(78)
    – CmdTransformedCoords.cs(44)
    – CmdWallBottomFace.cs(43)
    – CmdWallDimensions.cs(198)
    – CmdWallProfile.cs(126)
    Please also look at
    http://thebuildingcoder.typepad.com/blog/2008/09/geometry-viewer.html
    Cheers, Jeremy.

  9. Dear Arjun,
    Yes, I agree that the stair element location property is currently inaccessible.
    The stair element has simply not been fully exposed through the API yet.
    Sorry about that.
    Cheers, Jeremy.

  10. Hi jeremy,
    will u plz help me to get the
    1) rise and run,
    2) landing size
    3) headroom
    for a code compliant stairs.
    as I am unable to get these properties in the c# file.
    Thanks in Advance

  11. Dear Arjun,
    I do not know off-hand how to extract this data or whether it is possible at all. To explore that issue, you will have to build a sample model and use debugging and analysis tools such as RvtMgdDbg, the element lister and the built-in parameter checker. Their use is described in numerous blog posts, e.g.
    http://thebuildingcoder.typepad.com/blog/2008/11/exploring-element-parameters.html
    http://thebuildingcoder.typepad.com/blog/2009/02/locked-dimensioning.html
    Please explore this a bit yourself first and let us know if you run into any insurmountable obstacles. Thank you!
    Cheers, Jeremy.

  12. Hi Jeremy,
    I explored the links suggested by you but they proved to be of no use.I get the rise of stairs through built-in paramter “Stairs_Actual_Riser_Height” but I am failed to get the other parameters.
    All the best for your efforts.

  13. Hi Jeremy,
    I would like to pitch into this discussion.Stairs Rise is the height between the floors that the flight of stairs is spanning. Thus, I think we can take the elevation point(height) of the top level of the stairs as the “RISE OF STAIRS”.
    Now ,If we talk about the
    Run of Stairs, in theoretical terms, its the horizontal distance between first riser and last riser, does it have any relation with tread width of stairs?
    Please clarify my points.
    Thanks in advance…

  14. Dear Arjun,
    I am sorry to hear that. If you have used the tools I described and explored all the associated elements and their parameters and still not found access to the data you are looking for, chances are that it is not accessible, unfortunately.
    Cheers, Jeremy.

  15. Dear Shifali,
    Thank you very much for pitching in, and I think your points are pretty clear and make sense as they stand.
    They triggered some other ideas, such as analysing the stair geometry to determine these properties.
    To determine the stair rise, we could simply calculate the maximum difference between the Z coordinate or elevation of all its horizontal faces.
    To determine the stair run, we could calculate the maximum horizontal pairwise distance between all of its vertical faces, assuming it is a straight run.
    I don’t see why it would have any relation to the tread width, though.
    Cheers, Jeremy.

  16. Dear Jeremy,
    We can calculate the rise from elevation.I am not clear at my own point of Run of Stairs. As you are saying we can calculate it from maximum horizontal pairwise distance between all of its vertical faces, I dint get your point too…
    Can you explain it more?

  17. Hi Jeremy..
    I have one more query regarding stairs. We need to calculate the width for stairs. We get the Tread Width using Buil-In paramter “STAIRS_ATTR_TREAD_WIDTH”. According to us, the stairs width will be sum of tread width and railing width. But the Revit Architecture 2010 in the Instance properties dialogue shows the Width that is equal to tread width only. What should be the Final width of stairs?
    Please guide..

  18. Dear Shifali,
    I mean an approach similar to the one described in
    http://thebuildingcoder.typepad.com/blog/2008/10/slab-boundary.html
    http://thebuildingcoder.typepad.com/blog/2008/11/slab-side-faces.html
    http://thebuildingcoder.typepad.com/blog/2008/11/wall-elevation-profile.html
    http://thebuildingcoder.typepad.com/blog/2008/12/2d-polygon-areas-and-outer-loop.html
    http://thebuildingcoder.typepad.com/blog/2008/12/3d-polygon-areas.html
    See the overview in
    http://thebuildingcoder.typepad.com/blog/2009/04/cylindrical-column.html
    You can extract the solid from the stair geometry, identify all vertical surfaces, which will be either the sides of the stair or the vertical faces of the treads, and search for the pair of vertical surfaces with a maximal distance between the projections onto the horizontal XY plane. I would think that this distance will give you the run of the stairs, more or less.
    Cheers, Jeremy.

  19. Dear Shifali,
    I would say that what the final width of the stairs should be in your case depends completely on what purpose you are trying to achieve. If I look at the geometry of a stair, I see that it includes a long list of lines and three solids. You could try to determine the two largest planar faces of all the three solids and hope that those are parallel and represent the two outer sides of your staircase. In that case, the total width of the stairs would be the distance between them. This depends on the exact stair geometry and numerous other assumptions, of course.
    Cheers, Jeremy.

  20. Hi Jeremy,
    We are extracting the Revit file elements using revit API 2010 in c#. Our next task is to calculate the exit paths for each room element from door of rooms to Exit door of the file.we have calculated the path for the ground level of the revit project but we have to find the exit path of the “multi level Project”. How can we calculate this and move ahead. Plz help we need it urgently.

  21. Dear Arjun,
    Sounds like a very interesting issue. I don’t know exactly how your exit path is calculated or represented even for one level. Would you like to discuss your current solution for the ground floor in a guest blog post, so that we can understand what the problem is?
    Cheers, Jeremy.

  22. Hi Jeremy,
    will u send me the link for guest blog or your email Id, so that i can share it with you…
    Thanks in Advance

  23. Dear Arjun,
    I sent you a mail with the info. Thank you!
    Cheers, Jeremy.

  24. Hi Jeremy,
    I have received your reply to my query in the mail.
    Thank you so much.
    Regards,
    Arjun

  25. hi Jeremy,
    we are able to draw a line in a level using below Method:
    private static void CreateModelLine(Autodesk.Revit.Application app, XYZ p, XYZ q)
    {
    if (p.AlmostEqual(q))
    {
    throw new ArgumentException(
    “Expected two different points.”);
    }
    Line line = app.Create.NewLine(p, q, true);
    if (null == line)
    {
    throw new Exception(
    “Geometry line creation failed.”);
    }
    app.ActiveDocument.Create.NewModelCurve(line,
    NewSketchPlanePassLine(app, line));
    }
    private static SketchPlane NewSketchPlanePassLine(Autodesk.Revit.Application app, Line line)
    {
    XYZ p = line.get_EndPoint(0);
    XYZ q = line.get_EndPoint(1);
    XYZ norm;
    if (p.X == q.X)
    {
    norm = XYZ.BasisX;
    }
    else if (p.Y == q.Y)
    {
    norm = XYZ.BasisY;
    }
    else
    {
    norm = XYZ.BasisZ;
    }
    Plane plane = app.Create.NewPlane(norm, p);
    return app.ActiveDocument.Create.NewSketchPlane(plane);
    }
    That’s working fine for drawing solid lines. But we need to change the pattern of line from solid to dotted.
    please suggest a way to do it.
    Regards,
    Shifali

  26. Dear Shifali,
    As in most cases, to discover how to solve this using the Revit API, it will help to first explore how to solve this issue manually through the user interface.
    I would have a look at the visibility and graphics settings. Once you know the manual procedure, you can explore how to automate it.
    Cheers, Jeremy.

  27. Dear Jeremy,
    I checked it in User interface of Revit, we can change style of line from solid to demolished,dotted etc. So,I was finding some option to change the style of line of detail curve.
    Regards,
    Shifali

  28. Dear Shifali,
    I am unclear on what you are saying here. Have you found a solution? What is the exact approach you found? Or do you mean ‘searching for’ instead of ‘finding’? Thank you!
    Cheers, Jeremy.

  29. Dear Jeremy,
    I checked in Revit User Interface, in it we can change line style to demolished to make it of dotted pattern, but I am unable to do it through revit api in my program. Actually, my main motive is to highlight complete area spanned by detail arc in active document. So,I just wanted your help on this.
    Regards,
    Shifali

  30. Dear Shifali,
    The API cannot be used to create new line styles, but existing line styles can be applied to lines as follows.
    public class LineStyleTest : IExternalCommand
    {
    public IExternalCommand.Result Execute(
    ExternalCommandData commandData,
    ref string message,
    ElementSet elements )
    {
    ExternalCommandData cdata = commandData;
    Autodesk.Revit.Application app = commandData.Application;
    Document doc = app.ActiveDocument;
    XYZ startpt = new XYZ( 0, 0, 0 );
    XYZ endpt = new XYZ( 50, 50, 0 );
    Line line = app.Create.NewLineBound( startpt, endpt );
    DetailCurve detailCurve = app.ActiveDocument.Create.NewDetailCurve( doc.ActiveView, line );
    ElementArray lsArr = detailCurve.LineStyles;
    foreach( Autodesk.Revit.Element e in lsArr )
    {
    if( e.Name == “” )
    {
    detailCurve.LineStyle = e;
    break;
    }
    }
    return IExternalCommand.Result.Succeeded;
    }
    }
    Cheers, Jeremy.

  31. Dear Jeremy,
    Thanks for your reply to my above query. I got your point that we can not create a Line style through Revit API but we can apply the existing ones,like we change line color of detail arc using graphicstyles. I really feel bad on my part that I could not clarify my query in the above post.SO I just want to give a brief explanation of my problem.
    I am drawing the detail arcs in the active document(revit file).Now, I want to highlight the arc area, i.e. color fill the arc on the document after drawing it.At present, I am drawing model curves in the arc area, but this process takes a lot of time(around 10-20mins) which will not be acceptable to user.
    Can you please recommend any other way around to do this?

  32. Hi Jeremy,
    I am able to draw a model line using c# code in revit file.
    Will u please help me How can I:
    1) Delete the drawn model lines using c#?
    2) Hide or making the model lines invisible using c#?
    Thanks In advance
    Rocky

  33. Dear Shifali,
    First of all, how would you do it through the user interface? Whatever you do there you can try to reproduce programmatically. Some things do are not possible, however.
    You can also have a look at the post
    http://thebuildingcoder.typepad.com/blog/2009/04/create-an-area.html
    The associated comments are also interesting.
    An example of a hatched area created programmatically is shown in
    http://thebuildingcoder.typepad.com/blog/2009/02/boolean-operations-for-2d-polygons.html
    Cheers, Jeremy.

  34. Dear Rocky,
    You should be able to answer these questions yourself by searching the blog and other sources of information:
    http://thebuildingcoder.typepad.com/blog/2009/08/online-revit-api-help.html
    http://thebuildingcoder.typepad.com/blog/2009/10/revit-api-forums.html
    As a special personal Christmas present for you, here are some additional pointers anyway:
    Seven different posts discuss various aspects and usages of the Document.Delete method.
    A pretty recent post discusses element visibility in some depth, and mentions the Element.IsHidden method:
    http://thebuildingcoder.typepad.com/blog/2009/11/visible-elements.html
    Cheers, Jeremy.

  35. Hi Jeremy,
    After searching lots of blogs and other sites.I had try many methods but none of them gets succeed. :( .
    Please have a look in my work below:
    I am drawing model curves using the following code:
    private static void CreateModelLine(Autodesk.Revit.Application app, XYZ p, XYZ q)
    {
    if (p.AlmostEqual(q))
    {
    throw new ArgumentException(
    “Expected two different points.”);
    }
    Line line = app.Create.NewLine(p, q, true);
    //LinePattern lp = new LinePattern();
    if (null == line)
    {
    throw new Exception(
    “Geometry line creation failed.”);
    }
    app.ActiveDocument.Create.NewModelCurve(line,
    NewSketchPlanePassLine(app, line));
    }
    private static SketchPlane NewSketchPlanePassLine(Autodesk.Revit.Application app, Line line)
    {
    XYZ p = line.get_EndPoint(0);
    XYZ q = line.get_EndPoint(1);
    XYZ norm;
    if (p.X == q.X)
    {
    norm = XYZ.BasisX;
    }
    else if (p.Y == q.Y)
    {
    norm = XYZ.BasisY;
    }
    else
    {
    norm = XYZ.BasisZ;
    }
    Plane plane = app.Create.NewPlane(norm, p);
    return app.ActiveDocument.Create.NewSketchPlane(plane);
    }
    Now I want to delete all the model lines on another command click using below code.I am using following code, but it is not deleting the lines and giving errors at run time. Thereforei had commented all the stuff I had done.:
    private static void DeleteLines(Autodesk.Revit.Application revitApp, Document document)
    {
    Autodesk.Revit.Application app = revitApp;
    Document doc = document;
    Autodesk.Revit.Creation.Filter cf = app.Create.Filter;
    int count = 0;
    List elemSet = new List();
    string NewDrwanLine=”NewDrwanLine”;
    Filter f = cf.NewTypeFilter(typeof(ModelLine));
    int n = document.get_Elements(f, elemSet);
    bool Chk = true;
    try
    {
    //if (app.ActiveDocument.IsModified == true)
    //{
    // app.ActiveDocument.Settings.Categories.Erase(“Lines”);
    //}
    foreach (Element elemLine in elemSet)
    {
    if (elemLine.Category != null)
    {
    if (elemLine.Category.Name.ToString().IndexOf(“Lines”) !=-1)
    {
    //GraphicsStyle gs = new GraphicsStyle();
    //gs.GraphicsStyleCategory.LineColor = new Autodesk.Revit.Color(255, 0, 0);
    //elemLine.Category.GetGraphicsStyle(gs.GraphicsStyleType);
    //FamilyInstance inst = elemLine as FamilyInstance;
    //inst.SimilarObjectTypes.Erase(elemLine);
    //revitApp.ActiveDocument.Delete(elemLine);
    //app.ActiveDocument.Settings.Categories.Erase(elemLine.Category.Name);
    app.ActiveDocument.Settings.Categories.Erase(elemLine.Category.Id.Value.ToString());
    //elemLine.Category.LineColor.Green = lineColorGreen;
    //elemLine.Category.LineColor.Red = lineColorRed;
    //elemLine.GetVisibility().Equals(false);
    // break;
    }
    }
    count += 1;
    }
    }
    catch
    {
    throw;
    }
    }
    Note:
    1) I tried to remove the lines using delete method of active document, but its taking lot of time, which would not be acceptable to the user and gives error at runtime.
    2) tried to use Graphic style, just to change the color of line to white, so that lines can be hidden, but it throws null exception error.
    3) then i used erase method to erase the category of model lines, but it also throws exception at runtime.
    4) I am unable to set the vsisibility property of line to false. It was also showing that its read only.
    5) I had also used bewlo method to hide the element:
    static bool IsHiddenElementOrCategory(Element e, Autodesk.Revit.Elements.View v)
    {
    bool hidden = e.IsHidden(v);
    if (!hidden)
    {
    Category cat = e.Category;
    while (null != cat && !hidden)
    {
    hidden = !cat.get_Visible(v);
    cat = cat.Parent;
    }
    }
    return hidden;
    }
    But it also made me sad by throwing exception that unable to get visible prperty as it is read only.
    So i am unable to getting any way out to do so.
    Will u please tell me the exact way to hide or erase or delete the drwan lines..
    Thanks in advance
    Rocky

  36. Dear Rocky,
    I would simply use the Document.Delete method, which you apparently tried first and found to be slow.
    I would definitely recommend you not to use any of the other methods you describe.
    Deleting the category is impossible and makes no sense.
    Changing the colour to white or making the lines invisible if you in fact don’t want them to exist at all also sounds extremely wasteful of resources.
    Cheers, Jeremy.

  37. Cosmas Avatar
    Cosmas

    Hello Jeremy,
    I am using Revit.ActiveDocument.Element(ID), to try to get a structural floor element when I know its ID, but I get an exception: “Value does not fall within the expected range”. I checked the floor properties in RST and that ID exists. The same routine has worked for Beams and Columns, but not for floors! What is the problem?
    In addition, is there anyway to programmatically highlight elements in revit?
    Can a Hyperlink be attached to an element, so that when a revit element is clicked by the user, it jumps to the url.

  38. Dear Cosmas,
    1) No idea, that sounds strange. Have you looked at the element in RvtMgdDbg? Can it be selected using Modify > Element ID > Select by ID and then displayed in RvtMgdDbg using Snoop current selection?
    2) You can programmatically highlight an element by using the Document.ShowElements method. Another way is to add the element you want highlighted to the ElementSet argument of the Execute method of an external command and then return IExternalCommand.Result.Failed or Cancelled.
    3) Nope, not as far as I know. You could write an external command that implements that, but that would require two clicks from the user, one to select the element and another to launch your command.
    Cheers, Jeremy.

  39. Cosmas Avatar
    Cosmas

    Thank you Jeremy,
    I just found out that when using ActiveDocument.Element(ID), the ID has to be the UNIQUE ID, the regular ID does ot work!

  40. Dear Cosmas,
    Please look at the Document.Element property in the API help file:
    Retrieves an element from the document given an identifier. Overload List:
    – Element(ElementId) retrieves an element from the document given a Revit element id.
    – Element(String) retrieves an element from the document given a unique id string.
    That leaves no question open, at least not for me.
    Cheers, Jeremy.

  41. Hi Jeremy
    I am told this is impossible however I thought I’d ask anyway. I’d like to add a column of text to the keynote legend (translated version of the text, to automate the creation of bilingual docs.) While it’s simple to modify the tab delimited text file, there’s no apparent way to modify the visibility of this info in the keynote legend. Any thoughts?

  42. Dear Allan,
    Just as you say, I would be surprised if you could alter the visibility of this info in the keynote legend. However, I have heard of people adding simple text elements and detail lines to the Revit document to simulate tables, so there may be a way to achieve something similar. It would probably be pretty hard, though.
    Cheers, Jeremy.

  43. Hi jeremy,
    Will you please help me out to know How we know that exact stairs of both levels:
    E:g:- if there are two stairs on first level of the building then on second level how we can get these stairs?

  44. Dear Rocky,
    Thank you for your question. I wrote a new blog post to answer it in completeness:
    http://thebuildingcoder.typepad.com/blog/2010/04/retrieve-stairs-on-level.html
    Cheers, Jeremy.

  45. Hi Jeremy,
    I am using Revit API 2013, and as we know API 2013 has new features for Stairs. But i am still unable to find the stairs and location point of the stairs.
    Method i am using to find the stairs:
    Autodesk.Revit.DB.Document doc = document.Document;
    BuiltInCategory bic= BuiltInCategory.OST_Stairs;
    DataSet dsStairs = BALStairs.GetStairs(BOCommon.ProjectId);
    FilteredElementCollector collector = new FilteredElementCollector(doc);
    collector.OfCategory(bic);
    List stairs = new List();
    but it returns null value for stairs.
    Please help me out.
    Thanks in advance.

  46. Dear Nitin,
    You can use RevitLookup to discover the proper category to filter for the stairs you are interested in.
    Cheers, Jeremy.

Leave a Reply to NitinCancel reply

Discover more from Autodesk Developer Blog

Subscribe now to keep reading and get access to the full archive.

Continue reading