.NET

Reply
Active Contributor
tcuneio
Posts: 39
Registered: ‎08-22-2007
Message 1 of 5 (193 Views)
Accepted Solution

trouble with GetSubentities()

193 Views, 4 Replies
04-29-2014 12:35 PM

I can use GetSubentities to get a SelectedSubObject on a simple 3D object but when I use the same code on a 3D object that is "complex" (created by adding and subtracting other 3D objects) I have some trouble.  I'm checking the SubentityType and it isn't returning a valid Type (edge, vertex, face) but rather Type {5}.  Is there some trick to using GetSubentities() for "complex" solids?

Here is some code that works fine on my side, I am testing that one a single box, then two boxes that have been united. Sorry I don't have the VB.Net version ready to send you:

 

[CommandMethod("EdgesColor")]
public void EdgesColor()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
PromptEntityOptions peo = new PromptEntityOptions("\nSelect a 3D solid: ");
peo.SetRejectMessage("\nInvalid selection...");
peo.AddAllowedClass(typeof(Solid3d), true);
PromptEntityResult per = ed.GetEntity(peo);
if (per.Status != PromptStatus.OK)
return;
using (Transaction Tx = db.TransactionManager.StartTransaction())
{
Solid3d solid = Tx.GetObject(per.ObjectId, OpenMode.ForWrite) 
as Solid3d; ObjectId[] ids = new ObjectId[] { per.ObjectId }; FullSubentityPath path = new FullSubentityPath( ids, new SubentityId(SubentityType.Null, IntPtr.Zero)); List<SubentityId> SubentIds = new List<SubentityId>(); using (Autodesk.AutoCAD.BoundaryRepresentation.Brep brep = new Autodesk.AutoCAD.BoundaryRepresentation.Brep(path)) { foreach (Autodesk.AutoCAD.BoundaryRepresentation.Edge edge in
brep.Edges) { SubentIds.Add(edge.SubentityPath.SubentId); } } short colorIdx = 1; foreach (SubentityId subentId in SubentIds) { Color color = Color.FromColorIndex(
ColorMethod.ByColor,
++colorIdx);
solid.SetSubentityColor(subentId, color); } Tx.Commit(); } }

 

Here are some blog posts I've been writting as well, they should be useful:

 

http://adndevblog.typepad.com/autocad/2012/03/selecting-solid3d-sub-entities.html

 

http://adndevblog.typepad.com/autocad/2012/07/accessing-sub-entities-using-assocperssubentityidpe-in-arx-or-net.html

 

Regards,

Philippe.

 

ADN Support Specialist
philippe.leefsma
Posts: 646
Registered: ‎06-02-2009
Message 2 of 5 (151 Views)

Re: trouble with GetSubentities()

05-01-2014 08:12 AM in reply to: tcuneio

Hi

 

Could you provide a simple document that contains a sample solid that we can test please? Also be specific about which subentity needs to be selected to reproduce the issue you are describing.

 

Thank you,

Philippe.



Philippe Leefsma
Developer Technical Services
Autodesk Developer Network

Active Contributor
tcuneio
Posts: 39
Registered: ‎08-22-2007
Message 3 of 5 (139 Views)

Re: trouble with GetSubentities()

05-01-2014 01:07 PM in reply to: philippe.leefsma

Here is the code I’m using – sorry for the work in progress.  I want to select edges and faces of 3D solids that will all be rectangular.  When I make a simple box and run the selection for an edge, I get the right result (it’s currently configured just to change the subentity color but I will want to do fillet, etc. as well).  When I return to the same object to run again and try a different edge, I get a PromptStatus error.  Also, if I union two solid3d boxes and try selecting an edge, I get an “eInvalidInput” error when it calls the sobj.SetSubentityColor method.  I commented out the type validation since it also fails.  The type returned is type Class {5} instead of edge.  I’m relatively new to programming so I’m assuming it’s something obvious.  What do you see?  I didn’t attach a drawing since it’s simple 3dSolid “box” objects that I’m testing on.

 

    Public Sub BullnoseEdge(ByVal radius As Double)

 

        Dim pso As New PromptSelectionOptions

        pso.MessageForAdding = vbLf & "Select an edge to Bullnose: "

        pso.SingleOnly = True

        pso.SinglePickInSpace = True

        pso.ForceSubSelections = True

 

        Dim psr As PromptSelectionResult = ed.GetSelection(pso)

 

        If psr.Status <> PromptStatus.OK Then

            MsgBox("Selection Failed.")

            Return

        End If

 

        Using trans As Transaction = db.TransactionManager.StartTransaction

 

            Dim pickedSolid As ObjectId

            Dim subEntID As SubentityId = GetSubentId(ed, trans, psr.Value, SubentityType.Edge, pickedSolid)

            Dim edgeIds As SubentityId() = New SubentityId() {subEntID}

            Dim rad As New DoubleCollection(radius)

            Dim startSetBack As New DoubleCollection(radius)

            Dim endSetBack As New DoubleCollection(radius)

            sobj = TryCast(trans.GetObject(pickedSolid, OpenMode.ForWrite), Solid3d)

            'sobj.FilletEdges(edgeIds, rad, startSetBack, endSetBack)

 

 

            Dim colorString As acDefaultColors = acDefaultColors.green

            Dim myColor As Color = Color.FromColorIndex(ColorMethod.ByColor, colorString)

            sobj.SetSubentityColor(subEntID, myColor)

 

            trans.Commit()

        End Using

    End Sub

 

 

    Private Function GetSubentId(ByVal ed As Editor, ByVal trans As Transaction, ByVal ss As SelectionSet, ByVal subType As SubentityType, ByRef pickedId As ObjectId) As SubentityId

        Dim retId As New SubentityId

 

        'should only be one object in the array

        Dim so As SelectedObject = ss(0)

 

        pickedId = so.ObjectId

 

        'access the selected object

        Dim pickedSolid As Solid3d = TryCast(trans.GetObject(so.ObjectId, OpenMode.ForRead), Solid3d)

 

        'get the array of subentities for the solid

        Dim sso As SelectedSubObject() = so.GetSubentities()

 

        'confirm the type selected matches the desired type

        'Dim selectedType As SubentityType = sso(0).FullSubentityPath.SubentId.Type

        'If selectedType = subType Then

        '    retId = sso(0).FullSubentityPath.SubentId

        'Else

        '    ed.WriteMessage(vbLf & "The selected sub entity was of type {0}.  Please select a {1}." & vbLf, selectedType, subType)

        '    Exit Function

        'End If

 

        retId = sso(0).FullSubentityPath.SubentId

 

        Dim subEntityPath As New FullSubentityPath(New ObjectId() {solid.ObjectId}, retId)

 

        Using ent As Entity = solid.GetSubentity(subEntityPath)

            ed.WriteMessage(vbLf & "Subentity Entity Type: " & ent.ToString)

        End Using

 

        Return retId

    End Function

 

End Class

ADN Support Specialist
philippe.leefsma
Posts: 646
Registered: ‎06-02-2009
Message 4 of 5 (124 Views)

Re: trouble with GetSubentities()

05-02-2014 03:28 AM in reply to: tcuneio

Here is some code that works fine on my side, I am testing that one a single box, then two boxes that have been united. Sorry I don't have the VB.Net version ready to send you:

 

[CommandMethod("EdgesColor")]
public void EdgesColor()
{
    Document doc = Application.DocumentManager.MdiActiveDocument;
    Database db = doc.Database;
    Editor ed = doc.Editor;

    PromptEntityOptions peo = new PromptEntityOptions("\nSelect a 3D solid: ");
    peo.SetRejectMessage("\nInvalid selection...");
    peo.AddAllowedClass(typeof(Solid3d), true);

    PromptEntityResult per = ed.GetEntity(peo);

    if (per.Status != PromptStatus.OK)
        return;

    using (Transaction Tx = db.TransactionManager.StartTransaction())
    {
        Solid3d solid = Tx.GetObject(per.ObjectId, OpenMode.ForWrite) 
as Solid3d; ObjectId[] ids = new ObjectId[] { per.ObjectId }; FullSubentityPath path = new FullSubentityPath( ids, new SubentityId(SubentityType.Null, IntPtr.Zero)); List<SubentityId> SubentIds = new List<SubentityId>(); using (Autodesk.AutoCAD.BoundaryRepresentation.Brep brep = new Autodesk.AutoCAD.BoundaryRepresentation.Brep(path)) { foreach (Autodesk.AutoCAD.BoundaryRepresentation.Edge edge in
brep.Edges) { SubentIds.Add(edge.SubentityPath.SubentId); } } short colorIdx = 1; foreach (SubentityId subentId in SubentIds) { Color color = Color.FromColorIndex(
ColorMethod.ByColor,
++colorIdx);
solid.SetSubentityColor(subentId, color); } Tx.Commit(); } }

 

Here are some blog posts I've been writting as well, they should be useful:

 

http://adndevblog.typepad.com/autocad/2012/03/selecting-solid3d-sub-entities.html

 

http://adndevblog.typepad.com/autocad/2012/07/accessing-sub-entities-using-assocperssubentityidpe-in...

 

Regards,

Philippe.

 



Philippe Leefsma
Developer Technical Services
Autodesk Developer Network

Active Contributor
tcuneio
Posts: 39
Registered: ‎08-22-2007
Message 5 of 5 (99 Views)

Re: trouble with GetSubentities()

05-02-2014 07:18 AM in reply to: tcuneio

Thanks for the code and the blogs.  I had reviewed those blogs (and others) before writing.  Your code works fine for selecting all the edges, but my problem comes in trying to select a single subentity with PromptSelectionResult forcing subselections.  The GetSubentities method of the SelectedObject doesn't seem to produce a proper result.  I can access a useable result with the simple box but I can't return to that box to select a second edge, nor can I get a good result on any edge from the "complex" solids.

Post to the Community

Have questions about Autodesk products? Ask the community.

New Post
Need installation help?

Start with some of our most frequented solutions or visit the Installation and Licensing Forum to get help installing your software.