Selecting Solid3d sub-entities

By Philippe Leefsma

 

The following command illustrates a way to prompt user for subentity selection on a solid3d. It allows to select a single subentity and checks if the selected subentity type matches the specified type.

    <p class="MsoNormal" style="line-height: normal;margin: 0in 0in 0pt"><span style="font-family:;color:"><font color="#000000">After the subentity has been selected, it uses the Brep API and retrieve the Brep entity representing this subentity. Further methods of the Brep object can be invoked in order to analyze the properties of the subentity.</font></span></p>        <p class="MsoNormal" style="line-height: normal;margin: 0in 0in 0pt"><span style="font-family:;color:"><font color="#000000"></font></span></p>  <p class="MsoNormal" style="line-height: normal;margin: 0in 0in 0pt"><span style="font-family:;color:"><font color="#000000"></font></span></p>  <p class="MsoNormal" style="line-height: normal;margin: 0in 0in 0pt"><span style="font-family:;color:"><font color="#000000"></font></span></p>  <p class="MsoNormal" style="line-height: normal;margin: 0in 0in 0pt"><span style="font-family:;color:"><font face="Consolas"><font color="#008000" style="font-size: 9.5pt"></font></font></span></p>  <p class="MsoNormal" style="line-height: normal;margin: 0in 0in 0pt"><span style="font-family:;color:"><font face="Consolas"><font color="#008000" style="font-size: 9.5pt"></font></font></span></p>  <p class="MsoNormal" style="line-height: normal;margin: 0in 0in 0pt"><span style="font-family:;color:"><font face="Consolas"><font color="#008000" style="font-size: 9.5pt">//Command SubEntSelectBrep: Prompts user to select a single</font></font></span></p>  <p class="MsoNormal" style="line-height: normal;margin: 0in 0in 0pt"><span style="font-family:;color:"><font face="Consolas"><font color="#008000" style="font-size: 9.5pt">//solid sub-entity a</font></font></span><span style="font-family:;color:"><font face="Consolas"><font color="#008000" style="font-size: 9.5pt">nd filters type of sub-entity selected.</font></font></span><span style="font-family:"></span></p>  <p class="MsoNormal" style="line-height: normal;margin: 0in 0in 0pt"><span style="font-family:;color:"><font face="Consolas"><font color="#008000" style="font-size: 9.5pt">//Philippe Leefsma, Developer Technical Services. March 2012.</font></font></span></p>        <p class="MsoNormal" style="line-height: normal;margin: 0in 0in 0pt"><span style="font-family:;color:"><font color="#008000" face="Consolas"></font></span><span style="font-family:"></span></p>  <p class="MsoNormal" style="line-height: normal;margin: 0in 0in 0pt"><span style="font-family:"><font face="Consolas"><font color="#000000"><font style="font-size: 9.5pt">[</font></font><font style="font-size: 9.5pt"><span style="color:"><font color="#2b91af">CommandMethod</font></span><font color="#000000">(</font><span style="color:"><font color="#a31515">&quot;SubEntSelectBrep&quot;</font></span><font color="#000000">)]</font></font></font></span></p>  <p class="MsoNormal" style="line-height: normal;margin: 0in 0in 0pt"><font face="Consolas"><span lang="FR" style="font-family:;color:"><font color="#0000ff"><font style="font-size: 9.5pt">public</font></font></span><span lang="FR" style="font-family:"><font style="font-size: 9.5pt"><font color="#000000"> </font><span style="color:"><font color="#0000ff">void</font></span><font color="#000000"> SubEntSelectBrep()</font></font></span></font></p>  <p class="MsoNormal" style="line-height: normal;margin: 0in 0in 0pt"><span lang="FR" style="font-family:"><font face="Consolas"><font color="#000000" style="font-size: 9.5pt">{</font></font></span></p>  <p class="MsoNormal" style="line-height: normal;margin: 0in 0in 0pt"><span lang="FR" style="font-family:"><font face="Consolas"><span><font color="#000000"><font style="font-size: 9.5pt">&#160;&#160;&#160; </font></font></span><font style="font-size: 9.5pt"><span style="color:"><font color="#2b91af">Document</font></span><font color="#000000"> doc = </font><span style="color:"><font color="#2b91af">Application</font></span><font color="#000000">.DocumentManager.MdiActiveDocument;</font></font></font></span></p>  <p class="MsoNormal" style="line-height: normal;margin: 0in 0in 0pt"><font face="Consolas"><span lang="FR" style="font-family:"><span><font color="#000000"><font style="font-size: 9.5pt">&#160;&#160;&#160; </font></font></span></span><font style="font-size: 9.5pt"><span style="font-family:;color:"><font color="#2b91af">Database</font></span></font><span style="font-family:"><font color="#000000" style="font-size: 9.5pt"> db = doc.Database;</font></span></font></p>  <p class="MsoNormal" style="line-height: normal;margin: 0in 0in 0pt"><span style="font-family:"><font face="Consolas"><span><font color="#000000"><font style="font-size: 9.5pt">&#160;&#160;&#160; </font></font></span><font style="font-size: 9.5pt"><span style="color:"><font color="#2b91af">Editor</font></span><font color="#000000"> ed = doc.Editor;</font></font></font></span></p>  <p class="MsoNormal" style="line-height: normal;margin: 0in 0in 0pt"><span style="font-family:"><font face="Consolas"><font color="#000000" style="font-size: 9.5pt">&#160;</font></font></span></p>  <p class="MsoNormal" style="line-height: normal;margin: 0in 0in 0pt"><span style="font-family:"><font face="Consolas"><span><font color="#000000"><font style="font-size: 9.5pt">&#160;&#160;&#160; </font></font></span><font style="font-size: 9.5pt"><span style="color:"><font color="#2b91af">PromptKeywordOptions</font></span><font color="#000000"> pko = </font><span style="color:"><font color="#0000ff">new</font></span><font color="#000000"> </font><span style="color:"><font color="#2b91af">PromptKeywordOptions</font></span><font color="#000000">(</font></font></font></span></p>

        "\nSpecify sub-entity selection type:");

    pko.AllowNone = false;

    pko.Keywords.Add("Face");

    pko.Keywords.Add("Edge");

    pko.Keywords.Add("Vertex");

    pko.Keywords.Default = "Face";

 

    PromptResult pkr = ed.GetKeywords(pko);

 

    if (pkr.Status != PromptStatus.OK)

        return;

 

    SubentityType subentityType = SubentityType.Null;

 

    switch(pkr.StringResult)

    {

        case "Face":

            subentityType = SubentityType.Face;

            break;

        case "Edge":

            subentityType = SubentityType.Edge;

            break;

        case "Vertex":

            subentityType = SubentityType.Vertex;

            break;

        default:

            return;

    }

 

    PromptSelectionOptions pso = new PromptSelectionOptions();

    pso.MessageForAdding = "\nSelect solid " +

        pkr.StringResult + ": ";

    pso.SingleOnly = true;

    pso.SinglePickInSpace = true;

    pso.ForceSubSelections = true;

         

    PromptSelectionResult psr = ed.GetSelection(pso);

 

    if (psr.Status != PromptStatus.OK)

        return;

 

    SelectionSet ss = psr.Value;

 

    SelectedObject so = ss[0];

 

    if (!so.ObjectId.ObjectClass.IsDerivedFrom(

        RXClass.GetClass(typeof(Solid3d))))

    {

        ed.WriteMessage(

            "\nYou didn't select a solid, please try again…");

        return;

    }

 

    using (Transaction Tx = db.TransactionManager.StartTransaction())

    {

        Solid3d solid = Tx.GetObject(so.ObjectId, OpenMode.ForRead)

            as Solid3d;

 

        SelectedSubObject[] sso = so.GetSubentities();

 

        //Checks that selected type matches keyword selection

        if (subentityType != sso[0].FullSubentityPath.SubentId.Type)

        {

            ed.WriteMessage("\nInvalid Subentity Type: " +

                sso[0].FullSubentityPath.SubentId.Type +

                ", please try again…");

            return;

        }

 

        SubentityId subentityId = sso[0].FullSubentityPath.SubentId;

              

        //Creates subentity path to use with GetSubentity

        FullSubentityPath subEntityPath = new FullSubentityPath(

            new ObjectId[] { solid.ObjectId },

            subentityId);

 

        //Returns a non-database resident entity

        //that represents the subentity

        using (Entity entity = solid.GetSubentity(subEntityPath))

        {

            ed.WriteMessage("\nSubentity Entity Type: "

                + entity.ToString());

        }

 

        //Creates entity path to generate Brep object from it

        FullSubentityPath entityPath = new FullSubentityPath(

            new ObjectId[] { solid.ObjectId },

            new SubentityId(SubentityType
.Null, IntPtr.Zero));

 

        using (Brep brep = new Brep(entityPath))

        {

            switch (subentityType)

            {

                case SubentityType.Face:

 

                    foreach (

                        Autodesk.AutoCAD.BoundaryRepresentation.Face 

                            face in brep.Faces)

                    {

                        if (subentityId ==

                            face.SubentityPath.SubentId)

                        {

                            ed.WriteMessage("\nSurface: "

                                + face.Surface.ToString());

 

                            break;

                        }

                    }

                    break;

 

                case SubentityType.Edge:

 

                    foreach (

                        Autodesk.AutoCAD.BoundaryRepresentation.Edge

                           edge

                        in brep.Edges)

                    {

                        if (subentityId ==

                            edge.SubentityPath.SubentId)

                        {

                            ed.WriteMessage("\nCurve: " +

                                edge.Curve.ToString());

 

                            break;

                        }

                    }

                    break;

 

                case SubentityType.Vertex:

 

                    foreach (

                       Autodesk.AutoCAD.BoundaryRepresentation.Vertex

                           vertex

                        in brep.Vertices)

                    {

                        if (subentityId ==

                            vertex.SubentityPath.SubentId)

                        {

                            ed.WriteMessage("\nPoint: " +

                                PointToStr(vertex.Point));

 

                            break;

                        }

                    }

                    break;

 

                default:

                    break;

            }

        }

               

        Tx.Commit();

    }

}

 

//Small utility function

private string PointToStr(Point3d point)

{

    return "[" +

        point.X.ToString("F2") + ", " +

        point.Y.ToString("F2") + ", " +

        point.Z.ToString("F2")

        + "]";

}

    <p class="MsoNormal" style="line-height: normal;margin: 0in 0in 0pt"><a href="http://adndevblog.typepad.com/.a/6a0167607c2431970b0168e89a885d970c-pi"><img alt="pic" border="0" height="565" src="http://blog.autodesk.io/wp-content/uploads/2012/03/mt_imported_image_1759125847.jpg" style="background-image: none;border-right-width: 0px;padding-left: 0px;padding-right: 0px;display: inline;border-top-width: 0px;border-bottom-width: 0px;border-left-width: 0px;padding-top: 0px" title="pic" width="508" /></a></p>  &#160;</p>  <p>Contributed by </p>  <p>Philippe Leefsma, Developer Consultant.</p>  <p>Autodesk Developer Network.

Comments

4 responses to “Selecting Solid3d sub-entities”

  1. Konstantin Avatar
    Konstantin

    is it possible to highlight the selected face or edge of the 3Dsolid ??

  2. You can use “Entity.Highlight(FullSubentityPath, [MarshalAs(UnmanagedType.U1)] bool)”
    To highlight a sub-entity. Please refer to the help files for more details.

  3. Konstantin Avatar
    Konstantin

    Thanks Philippe,
    it already works !

  4. Konstantin Avatar
    Konstantin

    Hi Phillipe,
    I have noticed that the command returns an error message if
    you try to select solid3d subentities on COMPOSITE SOLIDS (unioned, subtracted, intersected) CREATED with “Solid history ON”.
    —–Invalid Subentity Type: Class, please try again…
    For NON composite solid primitives (BOX, CONE etc) the command functions as expected, independently of the history settings !

Leave a Reply to KonstantinCancel reply

Discover more from Autodesk Developer Blog

Subscribe now to keep reading and get access to the full archive.

Continue reading