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:
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;
}
}
}