Author Topic: Implementing SELECTCONNECTEDBRANCH for MEP  (Read 1265 times)

0 Members and 1 Guest are viewing this topic.

kaefer

  • Guest
Implementing SELECTCONNECTEDBRANCH for MEP
« on: November 29, 2011, 08:19:09 AM »
Starting with Sample\CS.NET\ShowConnectedParts (subtitled "Accessing the connection components of the Member class"), I thought it helpful to furnish a .NET implementation of a command which selects all connected objects. The inner workings are simple enough, but I'm wondering if there are performance implications or stack exhaustion issues.

Integrating a MessageFilter to enable user abort did no good: the time it takes to recurse through the objects is negligible compared to the time needed by the drawing editor to highlight/unhighlight the selected objects.

The other concern are the enumerators inside the recursion: if it goes deep enough the stack will bomb eventually.

Anyway, here's the code:
Code: [Select]
using System.Linq;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.Aec.Building.DatabaseServices;
using acadApp = Autodesk.AutoCAD.ApplicationServices.Application;

namespace SelectConnected
{
    public class SelectConnected
    {
        [CommandMethod("SelectAllConnectedParts")]
        public void SelectConnectedCommand()
        {
            Editor ed = acadApp.DocumentManager.MdiActiveDocument.Editor;
            Database db = acadApp.DocumentManager.MdiActiveDocument.Database;
            PromptEntityOptions prOptions = new PromptEntityOptions("\nPick object to select all connected objects: ");
            prOptions.SetRejectMessage("\nObject must be of type Member.");
            prOptions.AddAllowedClass(typeof(Member), false);
            PromptEntityResult prResult = ed.GetEntity(prOptions);
            if (prResult.Status != PromptStatus.OK)
                return;
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                ObjectIdCollection oidc = CollectConnected(prResult.ObjectId);
                ed.SetImpliedSelection(oidc.Cast<ObjectId>().ToArray());
                tr.Commit();
            }
        }
        internal void loop(ObjectIdCollection oidc, ObjectId id)
        {
            Member m = id.GetObject(OpenMode.ForRead, false) as Member;
            if (m != null)
                foreach (ConnectionComponentMember ccm in m.ConnectionComponentMembers)
                    foreach (ObjectId idnext in m.GetObjectsAtConnectionComponent(ccm))
                        if (!oidc.Contains(idnext))
                        {
                            oidc.Add(idnext);
                            loop(oidc, idnext);
                        }
        }
        public ObjectIdCollection CollectConnected(ObjectId id)
        {
            ObjectIdCollection oidc = new ObjectIdCollection();
            loop(oidc, id);
            return oidc;
        }
    }
}