Results 1 to 9 of 9

Thread: More efficient way of choosing drawing sheet elements

  1. #1
    100 Club
    Join Date
    2007-10
    Location
    Brisbane
    Posts
    138
    Login to Give a bone
    0

    Default More efficient way of choosing drawing sheet elements

    I'm trying to update shared paramaters on some drawing sheets, and at the moment I'm doing it as follows:
    - Loop through all elements
    - For each element, check that its category to see if it is "Drawing Sheets"
    - if so, loop through its parameters to find the sheet number
    - check its the one I want
    - loop through parameters again to find parameters I want and set them

    This takes like 20 seconds each time, obviously from looping htrough every single element on the file. This happens twice in what i'm trying to do, first time is on the load of the command which lists all the drawing sheets, and then when you want to make the changes it delays as well.

    Is there anyway to just go straight to drawing sheets?

  2. #2
    AUGI Addict
    Join Date
    2003-11
    Location
    New Zealand
    Posts
    1,116
    Login to Give a bone
    0

    Default Re: More efficient way of choosing drawing sheet elements

    If you're casting every element to check the category that is VERY slow. The most efficient way is:

    ElementIterator elemItor = _CommandData.Application.ActiveDocument.Elements;
    while(elemItor.MoveNext())
    {
    object currElement = elemItor.Current;
    if (currElement is Autodesk.Revit.Elements.ViewSheet)
    {
    ViewSheet currentViewSheet = currElement as ViewSheet;
    }
    }

    The other way, which relies on having a printer view set with all drawings sheets correctly updated is to use the activeDocument.ViewSheetsSets property. Which is blazingly quick.

    You also don't need to loop parameters to get the sheet number you can use BuiltInParameter.SHEET_NUMBER to get the parameter directly.And for your shared parameters get the shared parameter definitions once and then get each drawing sheets parameter using the definition.

    Doing all this should get it down to < 2secs unless your model is huge.

    HTH,

    Guy
    Last edited by GuyR; 2007-12-13 at 08:10 AM.

  3. #3
    100 Club
    Join Date
    2007-10
    Location
    Brisbane
    Posts
    138
    Login to Give a bone
    0

    Default Re: More efficient way of choosing drawing sheet elements

    Thanks mate! You're a legend.

    all I did was change
    //if (null != elem.Category && elem.Category.Name == "Drawing Sheets")
    if (elem is Autodesk.Revit.Elements.ViewSheet)
    the commented line to the one you suggested and it's dropped the time right down to an acceptable level.

    Thanks for your help once again!

  4. #4
    AUGI Addict
    Join Date
    2003-11
    Location
    New Zealand
    Posts
    1,116
    Login to Give a bone
    0

    Default Re: More efficient way of choosing drawing sheet elements

    I just want to clarify my response and explain further where the delays are occurring.It's also not clear in your reply if you eliminated both bottlenecks. The first is checking for only those objects you really need, in this case FamilyInstance. My naming confused the issue so sorry about that. This:

    object currElement = elemItor.Current;
    if (currElement is Autodesk.Revit.Elements.ViewSheet)

    Should more correctly be written as:

    object currObject = elemItor.Current;
    if (currObject is Autodesk.Revit.Elements.ViewSheet)

    because they're still objects. It's the next line where the cast occurs that you get the second hit:
    ViewSheet currentViewSheet = currObject as ViewSheet;

    So to summarise:

    1..Cast to Elements or Symbols only the objects you require, otherwise leave as objects.
    2.. Where possible check object category using Type checking rather using the elements category object.

    FWIW, Performance and querying the database is high on the API wishlist so hopefully we'll see some improvements in RAC2009 and beyond.

    HTH,

    Guy

  5. #5
    100 Club
    Join Date
    2004-02
    Location
    Brookline, MA
    Posts
    186
    Login to Give a bone
    0

    Default Re: More efficient way of choosing drawing sheet elements

    I'd have a slight suggestion:

    ElementFilterIterator efi = commandData.Application.ActiveDocument.get_Elements( typeof(Autodesk.Revit.Elements.ViewSheet) );

    while (efi.MoveNext())
    {
    Autodesk.Revit.Elements.ViewSheet sheet = efi.current as Autodesk.Revit.Elements.ViewSheet;

    // do something with "sheet"
    }

    using this approach, the ElementFilterIterator is guaranteed to return only the elements of ViewSheet type. While it is not currently faster than doing it the other way, Autodesk has said that this approach in future releases will be SIGNIFICANTLY faster than going through one by one.
    And, FWIW, I think it's better to specify what you want up front, so that you don't need another IF layer inside your while block.

    --------------------------
    Only potential down side to this:
    In a few cases I changed my code from your way to this way it didn't work. The reason is that if you were looking for all Views, you might be tempted to look for Autodesk.Revit.Elements.View. This works fine in the code where you cast it - including cases where the element is a subclass of View - such as ViewPlan.

    So while this works:

    View anyview = elementfilter.current as View;

    This:
    ElementFilterIterator efi = document.get_Elements( typeof(View) );

    does not - it will only find elements that are specifically of the View type, not ViewPlan or View3D or any of the other subclasses.

    (Sorry for the confusion - but after struggling with that once, I figured it was important to pass on).

    Since you're looking for ViewSheet, the code above will work just fine.

    Best Regards,
    Matt

  6. #6
    AUGI Addict
    Join Date
    2003-11
    Location
    New Zealand
    Posts
    1,116
    Login to Give a bone
    0

    Default Re: More efficient way of choosing drawing sheet elements

    Matt,

    Actually I think you summarised why currently I never recommend using ElementFilterIterator It's no faster and 9 times out of 10 you need more than one Type.

    I also think for the beginner it's slightly confusing in that the Object still needs to be cast. Had it used generics and the line became ViewSheet currSheet = efi.Current; that would have been cool. The API beginner will naturally look at the SDK samples. Unfortunately a lot of them do exactly what you shouldn't do which is cast every element and check the category. So I tend to labour the point about using 'is' to filter Types.

    While ElementFilterIterator might get faster in future, the single Type selection is a major limitation so they'll hopefully come up with something better and we've still got 5 months of RAC2008.

    HTH,

    Guy
    Last edited by GuyR; 2007-12-13 at 06:41 PM.

  7. #7
    100 Club
    Join Date
    2007-10
    Location
    Brisbane
    Posts
    138
    Login to Give a bone
    0

    Default Re: More efficient way of choosing drawing sheet elements

    Quote Originally Posted by GuyR View Post
    I just want to clarify my response and explain further where the delays are occurring.It's also not clear in your reply if you eliminated both bottlenecks. The first is checking for only those objects you really need, in this case FamilyInstance. My naming confused the issue so sorry about that. This:

    object currElement = elemItor.Current;
    if (currElement is Autodesk.Revit.Elements.ViewSheet)

    Should more correctly be written as:

    object currObject = elemItor.Current;
    if (currObject is Autodesk.Revit.Elements.ViewSheet)

    because they're still objects. It's the next line where the cast occurs that you get the second hit:
    ViewSheet currentViewSheet = currObject as ViewSheet;

    So to summarise:

    1..Cast to Elements or Symbols only the objects you require, otherwise leave as objects.
    2.. Where possible check object category using Type checking rather using the elements category object.

    FWIW, Performance and querying the database is high on the API wishlist so hopefully we'll see some improvements in RAC2009 and beyond.

    HTH,

    Guy
    I'm trying to work out exactly what you are talking about, I'm still a novice at all of this.
    Heres the code I was using, I made a test class which just displays a message box when it finds the right element.

    Document document = commandData.Application.ActiveDocument;
    Element elem;
    ElementIterator iter = document.Elements;
    // not sure what this is used for?:
    Category sheetCategory = document.Settings.Categories.get_Item(BuiltInCategory.OST_DrawingSheets);

    while (iter.MoveNext())
    {

    Object currElement = iter.Current;
    if (currElement is Autodesk.Revit.Elements.ViewSheet)
    {
    elem = iter.Current as Element;

    MessageBox.Show(elem.Category.Name.ToString());
    }

    }

    return IExternalCommand.Result.Succeeded;


    that is what you are suggesting correct?

    now what I had was somethign along the lines of:

    while (iter.MoveNext())
    {

    elem = iter.Current as Element;
    if (elem is Autodesk.Revit.Elements.ViewSheet)
    {
    MessageBox.Show(elem.Category.Name.ToString());
    }

    }

    so casting each as an element instead of the object. From my tests, both seem to take around 5 seconds to find the first drawing sheet... No noticeable differences.

    I'm also not sure what the sheetCategory was for in your original suggestion?

  8. #8
    AUGI Addict
    Join Date
    2003-11
    Location
    New Zealand
    Posts
    1,116
    Login to Give a bone
    0

    Default Re: More efficient way of choosing drawing sheet elements

    Sorry if I'm confusing you.The category definition was superfluous and you'll see I edited that particular post to remove it.

    See attached project for you to try, just gets all walls and rooms. To use the command select how many times you want to run each solution and then press Run. The looping just does a bit of averaging to make sure the numbers are as relevant as possible. The usual caveats apply when running these sorts of tests. Don't play mp3's etc while running the tests, and don't start Revit from the debugger When you run the command for the first time, ignore the first result. So typically I set the loop to 1 and run it for the first time. Then set the loop to 10-15 and run again.

    It's a quick hack and taken from a simple command I've used in the past for performance testing different options. I've modified it to give you something relevant to what you're doing. I've also commented the code to try and explain some of it. I typically use the conference project from the training files for tests. It has a bit of everything, a reasonable size without taking 5 minutes to load.

    The truth is I am splitting hairs not casting to Elements first, as I do in MyBest Typically MyBest solution is only about 1% faster than the Better solution. And this is dependent on what you're actually wanting to test. Semantically though it makes more sense to me leaving the current Revit object as an object as long as possible. And it's just as fast to write.

    HTH,

    Guy
    Attached Files Attached Files

  9. #9
    100 Club
    Join Date
    2007-10
    Location
    Brisbane
    Posts
    138
    Login to Give a bone
    0

    Default Re: More efficient way of choosing drawing sheet elements

    Quote Originally Posted by GuyR View Post
    Sorry if I'm confusing you.The category definition was superfluous and you'll see I edited that particular post to remove it.

    See attached project for you to try, just gets all walls and rooms. To use the command select how many times you want to run each solution and then press Run. The looping just does a bit of averaging to make sure the numbers are as relevant as possible. The usual caveats apply when running these sorts of tests. Don't play mp3's etc while running the tests, and don't start Revit from the debugger When you run the command for the first time, ignore the first result. So typically I set the loop to 1 and run it for the first time. Then set the loop to 10-15 and run again.

    It's a quick hack and taken from a simple command I've used in the past for performance testing different options. I've modified it to give you something relevant to what you're doing. I've also commented the code to try and explain some of it. I typically use the conference project from the training files for tests. It has a bit of everything, a reasonable size without taking 5 minutes to load.

    The truth is I am splitting hairs not casting to Elements first, as I do in MyBest Typically MyBest solution is only about 1% faster than the Better solution. And this is dependent on what you're actually wanting to test. Semantically though it makes more sense to me leaving the current Revit object as an object as long as possible. And it's just as fast to write.

    HTH,

    Guy
    Sorry I have taken so long to reply - I was on holidays, and then returned home sick

    Thanks alot for putting so much effort into the reply! A neat little benchmark!
    I've got my head around it now, in your worst one, checking the category is definately alot slower than casting the currentElement as the type we are looking for. 'Continue' is neat, I'd never heard of that before (I'd used break, but not continue).

    Thanks again, it runs great now

Similar Threads

  1. converting multi sheet drawing file into single drawing files
    By harryschoenauer in forum AutoCAD General
    Replies: 3
    Last Post: 2013-01-23, 07:36 PM
  2. Revisions on Sheet - Elements Filter
    By Michael Coviello in forum Revit - API
    Replies: 0
    Last Post: 2009-06-24, 04:14 PM
  3. Show all line drawing tools without choosing them from a flyout menu
    By revit.wishlist1942 in forum Revit Architecture - Wish List
    Replies: 4
    Last Post: 2008-06-07, 09:56 PM
  4. Turning off elements in 1 sheet only
    By kwong in forum Revit Architecture - General
    Replies: 4
    Last Post: 2005-09-29, 07:58 AM
  5. Moving elements to sheet
    By E-Key in forum Revit Architecture - General
    Replies: 4
    Last Post: 2005-08-26, 07:18 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •