This entry was contributed by Adam Nagy, a member of DevTech EMEA based in Prague.
The question is really a combination of two problems:
- Selecting a subentity
- Selecting a nested entity
Selecting a subentity
First we should clarify what a subentity is:
A subentity is a pseudo entity which is a logical part of a real entity. In our sample drawing the solid is the real entity [AcDb3dSolid] and the edge is the pseudo entity (there is no AcDbEdge class). In AutoCAD we rely on IDs called GS (short for graphics system) markers to get to these subentities.
The ObjectARX help file contains a small piece of sample code showing how to highlight one of a solid's internal edges. Unfortunately, it does not work in shaded mode – always the face will be selected - and it will not find the subentity in the case of a nested entity.
Selecting a nested entity
Again, let’s start by defining things:
For the purposes of this article, we're defining a nested entity as an entity that is placed inside a block [AcDbBlockTableRecord] other than one of the internal layout blocks [e.g. Model Space].
We can use a standard function such as acedNEntSelP() to select a nested entity, which gives back the bottommost selected entity and all its nesting entities – you can find information about it in the ObjectARX help file. But what about the GS markers we need?
The two combined
We really need a function that can select the bottommost nested entity and also gives back the [correct] GS marker of the subentity.
Fortunately, there is such a function, the undocumented brother of acedNEntSelP(). It does exactly what we need and is called acedNEntSelPEx(). It gives back the correct GS marker (even in shaded mode), provides the list of nesting entities and gives back the selected bottommost nested entity. Not only does it select edges and return the GS marker as we have seen, it also picks through spaces. e.g. say you are in paper space with no model space selected, from that mode you can use this function to select an entity in model space.
In the attached drawing we have the following structure:
SolidBlock2 -> SolidBlock -> Solid
[SolidBlock2 contains a reference to SolidBlock, which contains the Solid entity].
When using acedNEntSelPEx() [or acedNEntSelP()], we will get back a result buffer that contains the selected entity’s nesting entities in the same order as getSubentPathsAtGsMarker() needs them – starting from the directly nesting entity going upwards until we reach the top-most nesting entity that contains all the others. In case where we select the solid in SolidBlock2 in our sample drawing, the path is:
- SolidBlock reference
- SolidBlock2 reference [which contains SolidBlock]
Now we just have to create an array filled with the above entities in the same order, but starting with the solid entity itself:
- Solid entity
- SolidBlock reference
- SolidBlock2 reference
We call the getSubentPathsAtGsMarker() function of the topmost nesting entity [SolidBlock2 reference] with the GS marker and the array we just created, and voilá, we get the correct subentity path that we need to highlight the subentity.
The attached project for Visual Studio 2005 (using ObjectARX 2007) contains both the help file code [in the "HelpfileSelect" command] and the rewritten code [in the "MySelect" command]:

Subscribe via RSS
I found your article while searching for info about nested entities. I have a similar problem that has me puzzled. I'm coding in VB.net using VS2005 and AutoCAD 2007.
I have a 3dface inserted in a block and this block is inserted several times in other blocks. I am trying to determine the objectID for the block insert of the 3dface. I can easily get the handle for the top level block or the handle for the 3dface but the Xdata I'm looking for is in the block insert of the 3dface. I can even get the handle of the 3dface block but I don't know how to get the objectID for the inserted 3dface block I picked in the graphics window.
Any help would be greatly appreciated as I can find very little help for vb.net and the AutoCAD API. Thnak you.
Posted by: Stuart Shaw | September 15, 2006 at 03:30 AM
Hi Kean:
thanks for nice code, but how to selecting the face of a solid3d in ObjectARX or .NET?
thanks.
Posted by: ahlzl | June 13, 2009 at 05:07 AM
Hi ahlzl,
Try looking into AcEdSolidSubentitySelector::selectFaces().
I haven't used it myself, but it should do what you want (from ObjectARX).
Regards,
Kean
Posted by: Kean Walmsley | June 15, 2009 at 10:01 AM
successful!
thanks again.
Posted by: ahlzl | June 24, 2009 at 01:52 PM