« Autodesk University 2008: putting it to a vote | Main | Storing custom AutoCAD application settings in the Registry using .NET »
Finding all the AutoCAD entities on a particular layer using .NET
This question came in recently by email:
Is there a way to obtain the object IDs of all the object on a layer? I found the GetAllObjects() method of the Transaction object but it doesn't work.
That's right: GetAllObjects() will return the objects accessed via (or added to) the transaction - it has nothing to do with retrieving objects based on any particular property.
What you need to do is Editor.SelectAll(), the equivalent of acedSSGet("X") in ObjectARX and (ssget "X") in AutoLISP. You need the version where you pass in a SelectionFilter specifying the layer for which to search.
Here's some C# code doing just this, with the hard work encapsulated in a function (GetEntitiesOnLayer()) to make it easier to integrate into your code:
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
namespace EntitySelection
{
public class Commands
{
[CommandMethod("EOL")]
static public void EntitiesOnLayer()
{
Document doc =
Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
PromptResult pr =
ed.GetString("\nEnter name of layer: ");
if (pr.Status == PromptStatus.OK)
{
ObjectIdCollection ents =
GetEntitiesOnLayer(pr.StringResult);
ed.WriteMessage(
"\nFound {0} entit{1} on layer {2}",
ents.Count,
(ents.Count == 1 ? "y" : "ies"),
pr.StringResult
);
}
}
private static ObjectIdCollection
GetEntitiesOnLayer(string layerName)
{
Document doc =
Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
// Build a filter list so that only entities
// on the specified layer are selected
TypedValue[] tvs =
new TypedValue[1] {
new TypedValue(
(int)DxfCode.LayerName,
layerName
)
};
SelectionFilter sf =
new SelectionFilter(tvs);
PromptSelectionResult psr =
ed.SelectAll(sf);
if (psr.Status == PromptStatus.OK)
return
new ObjectIdCollection(
psr.Value.GetObjectIds()
);
else
return new ObjectIdCollection();
}
}
}
Running EOL simply counts the entities on a particular layer (the following is from running in the 3D House.dwg sample drawing):
Command: EOL
Enter name of layer: A-Beam
Found 1 entity on layer A-Beam
Command: EOL
Enter name of layer: A-Concrete
Found 1 entity on layer A-Concrete
Command: EOL
Enter name of layer: Furniture
Found 14 entities on layer Furniture
Command: EOL
Enter name of layer: Legs
Found 16 entities on layer Legs
It would be straightforward to do something more than just count the results of the GetEntitiesOnLayer() function, of course, or even to adapt the function to filter on other properties.
May 2, 2008 in AutoCAD, AutoCAD .NET, Drawing structure, Selection | Permalink
TrackBack
TrackBack URL for this entry:
http://www.typepad.com/t/trackback/876965/28566024
Listed below are links to weblogs that reference Finding all the AutoCAD entities on a particular layer using .NET:
Comments
Hi Kean,
This approach works fine for small amount of entities.
What I did for huge drawings was a solution using a database reactor and a map to store an AcDbObjectIdArray of entities for each Layer's AcDbObjectId which will be the map KEY.
The idea was to catch these events:
objectAppended
objectErased
objectModified
objectReAppended
objectUnAppended
For each notification, get the entity`s layer AcDbObjectId and add/remove into proper map entry array.
The result is a instant cache to get the entity list for each desired layer.
You can store this cache through an AcDbObject entry inside NOD or build it on the fly everytime you load the DWG. The last will cause a small delay when loading the drawing but will avoid the use of a custom entity or a XRecord entry.
Of course this cache must be per-document and MDI-aware.
Regards,
Fernando.
Posted by: Fernando Malard | May 1, 2008 6:36:55 AM
That's right - this will be adequate for many (if not most) cases, but when performance is an issue implementing a cache is the way to go.
Kean
Posted by: Kean | May 1, 2008 10:06:01 AM

Atom