Search code examples
c#revit-apirevit

Why is PickObjects with Selection filter slows down my selection - PickObjects(ObjectTYpe, ISelectionFilter, String)


Why is PickOjects with Selection Filter slower than the PickObjects with out Selection Filter in IExternalCommand(Add-in). I try inputting code inside Revit Macro and see no difference in both methods.

My code is working fine(Please see below) The Only difference is the performance. PickObjects with Selection Filter feels a little slower and laggy.

Should i write my code differently? maybe my IselectionFilter is not a good write?

any help, comments, suggestion will greatly appreciated.

#region Namespaces
using System;
using System.Collections.Generic;
using System.Diagnostics;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
#endregion

namespace ConduitSizeShowInfo
{
    [Transaction(TransactionMode.Manual)]
    public class Command : IExternalCommand
    {
        public Result Execute(
          ExternalCommandData commandData,
          ref string message,
          ElementSet elements)
        {
            UIApplication uiapp = commandData.Application;
            UIDocument uidoc = uiapp.ActiveUIDocument;
            Application app = uiapp.Application;
            Document doc = uidoc.Document;

            try
            {
                //Filter Selection
                SelectElementsFilter conduitFilter = new SelectElementsFilter("Conduits");

                //Pick Multiple Conduits
                IList<Reference> selectedConduits = uidoc.Selection.PickObjects(ObjectType.Element, conduitFilter, "Please select conduits");

                //Show Conduit Size Information
                string showConduitSize = "";
                foreach (Reference conduit in selectedConduits)
                {
                    Element e = doc.GetElement(conduit);
                    Parameter conduitSize = e.LookupParameter("Size");
                    showConduitSize += e.Name + ": " + conduitSize.AsString() + Environment.NewLine;
                }
                TaskDialog.Show("Conduit Sizes", showConduitSize);
            }
            catch(Autodesk.Revit.Exceptions.OperationCanceledException)
            {
                return Result.Cancelled;
            }
            catch(Exception ex)
            {
                message = ex.Message;
                return Result.Failed;
            }

            return Result.Succeeded;
        }

        public class SelectElementsFilter : ISelectionFilter
        {
            static string CategoryName = "";

            public SelectElementsFilter(string name)
            {
                CategoryName = name;
            }

            public bool AllowElement(Element e)
            {
                if (e.Category.Name == CategoryName)
                    return true;
                return false;
            }

            public bool AllowReference(Reference r, XYZ p)
            {
                return false;
            }
        }
    }
}

Solution

  • You can speed up your selection filter (minimally) by checking the category element id instead of the category name. Comparing two integers is faster than comparing two strings.

    public bool Equals( Category x, Category y )
    {
      return x.Id.IntegerValue.Equals(
        y.Id.IntegerValue );
    }