Revit API Forum
Welcome to Autodesk’s Revit API Forums. Share your knowledge, ask questions, and explore popular Revit API topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Highlight large number of elements in View

4 REPLIES 4
SOLVED
Reply
Message 1 of 5
evidalpe
304 Views, 4 Replies

Highlight large number of elements in View

I want to highlight a list of elements in a View, so I created the following method:

        public static void HighlightElementsInView(Document doc, View view, List<ElementId> eIds)
        {
            OverrideGraphicSettings overrideGraphicSettings = new OverrideGraphicSettings();
            overrideGraphicSettings.SetProjectionLineColor(new Color(255, 0, 0));
            overrideGraphicSettings.SetSurfaceForegroundPatternColor(new Color(255, 0, 0));

            using(TransactionGroup transactionGroup = new TransactionGroup(doc, "Highlight Elements in View " + view.Name))
            {
                transactionGroup.Start();

                if(view.CanBePrinted)
                {
                    foreach(ElementId eId in eIds)
                    {
                        using(Transaction transaction = new Transaction(doc, "Highlight Element " + eId.IntegerValue))
                        {
                            transaction.Start();
                            view.SetElementOverrides(eId, overrideGraphicSettings);
                            transaction.Commit();
                        }
                    }
                }

                transactionGroup.Assimilate();
            }
        }

 

This works fine, but when the number of elements is large (e.g. 15000), the process takes ages or the program crashes. Is there a way to optimize this?
I'm kind of missing a method like "SetElementsOverride" that takes a List of elements and only uses a transaction to modify them all.

4 REPLIES 4
Message 2 of 5
SimonaQQ
in reply to: evidalpe

large number

Message 3 of 5
Mohamed_Arshad
in reply to: evidalpe

HI @evidalpe 


 I have seen two things in your code, 

  • you have used nested transaction inside the loop. Basically Transaction inside the loop will increase your memory consumption and leads to crash.
  • And If you have large number elements, Kindly use While loop instead of foreach loop. I have modified your program little bit, kindly execute the code in your end and share your feedback.

Reference Code:

 

Approach -01 

 

 public static void HighlightElementsInView(Document doc, View view, List<ElementId> eIds)
        {
            OverrideGraphicSettings overrideGraphicSettings = new OverrideGraphicSettings();
            overrideGraphicSettings.SetProjectionLineColor(new Color(255, 0, 0));
            overrideGraphicSettings.SetSurfaceForegroundPatternColor(new Color(255, 0, 0));

            var enumurator = eIds.GetEnumerator();

            using (Transaction transaction = new Transaction(doc, "Highlight Element"))
            {
                transaction.Start();

                while (enumurator.MoveNext())
                {
                    ElementId eId = enumurator.Current;

                    view.SetElementOverrides(eId, overrideGraphicSettings);
                }

                transaction.Commit();
            }

        }

 

 

Approach -02

 

 public static void HighlightElementsInView(Document doc, View view, List<ElementId> eIds)
        {
            OverrideGraphicSettings overrideGraphicSettings = new OverrideGraphicSettings();
            overrideGraphicSettings.SetProjectionLineColor(new Color(255, 0, 0));
            overrideGraphicSettings.SetSurfaceForegroundPatternColor(new Color(255, 0, 0));

            using (TransactionGroup transactionGroup = new TransactionGroup(doc, "Highlight Elements in View " + view.Name))
            {
                transactionGroup.Start();

                using (Transaction transaction = new Transaction(doc, "Highlight Element"))
                {
                    transaction.Start();

                    if (view.CanBePrinted)
                    {
                        foreach (ElementId eId in eIds)
                        {
                            view.SetElementOverrides(eId, overrideGraphicSettings);
                        }
                    }

                    transaction.Commit();
                }

                transactionGroup.Assimilate();
            }
        }

 

 

Additional Links about Nested Transactions : https://forums.autodesk.com/t5/revit-api-forum/looped-transactions-only-committing-the-first-object/... 

 

Kindly use time stamp to get best executing time among the above code.
Hope this will helps 🙂

Thanks & Regards,
Mohamed Arshad K
Message 4 of 5
evidalpe
in reply to: Mohamed_Arshad

@Mohamed_Arshad those two approaches improve a lot the performance, so I'm accepting that as a good response, thanks.

My mistake was assuming that each view.SetElementOverrides(eId, overrideGraphicSettings); call needed to be encapsulated in a transaction, so the nesting was the issue. I didn't know that you can modify all elements in a single transaction without crashing. Of course you miss the possibility of undoing each transaction one by one but that does not make sense for a large number of elements.

Between approach 1 and 2, 1 seems to perform a bit better, but just one important note: the enumerator needs to be disposed after its usage.

Message 5 of 5
Mohamed_Arshad
in reply to: evidalpe

Hi @evidalpe 

 

According to C#, typically don't need to manually dispose of the IEnumerator obtained from a collection using the GetEnumerator method.

 

As you told In our case we manually using an IEnumerator  and want to ensure proper resource cleanup, it's a good practice to call its Dispose method or we can use using() statements.

 

Thank you for the complete conversation @evidalpe 

Thanks & Regards,
Mohamed Arshad K

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Rail Community


Autodesk Design & Make Report