Chamfering the selected edge of an AutoCAD solid using .NET

Another piece of code culled from an email from Balaji Ramamoorthy, from DevTech India. I did a little refactoring and formatting, to fit the blog. Thanks, Balaji! 🙂

The below C# code demonstrates how to use Solid3d.ChamferEdges() with a user-selected edge and face. Balaji has also provided code to determine the edge and face programmatically – without the user needing to select anything – using the Brep API. I expect to show that approach in a subsequent post.

using Autodesk.AutoCAD.ApplicationServices;

using Autodesk.AutoCAD.DatabaseServices;

using Autodesk.AutoCAD.EditorInput;

using Autodesk.AutoCAD.Runtime;

using System;

 

namespace SolidEditing

{

  public class Commands

  {

    [CommandMethod("EC")]

    public void EdgeChamfer()

    {

      Document doc =

        Application.DocumentManager.MdiActiveDocument;

      Database db = doc.Database;

      Editor ed = doc.Editor;

 

      // Select an edge

 

      PromptSelectionOptions pso =

        new PromptSelectionOptions();

      pso.MessageForAdding = "\nSelect edge to chamfer";

      pso.SingleOnly = true;

      pso.ForceSubSelections = true;

 

      PromptSelectionResult psrEdge = ed.GetSelection(pso);

 

      if (psrEdge.Status != PromptStatus.OK)

        return;

 

      // Select a face

 

      pso.MessageForAdding =

        "\nSelect the face to which the edge belongs";

      pso.SinglePickInSpace = true;

 

      PromptSelectionResult psrFace = ed.GetSelection(pso);

 

      if (psrFace.Status != PromptStatus.OK)

        return;

 

      try

      {

        Transaction tr =

          db.TransactionManager.StartTransaction();

        using (tr)

        {

          ObjectId edgeSolId, faceSolId;

 

          // Get the subentity Id for the edge and the face

 

          SubentityId edgeId =

            GetSubentity(

              ed, tr, psrEdge.Value, SubentityType.Edge,

              out edgeSolId

            );

 

          SubentityId faceId =

            GetSubentity(

              ed, tr, psrFace.Value, SubentityType.Face,

              out faceSolId

            );

 

          // We also have the Ids of their containing solids,

          // so we can check they belong to the same one

 

          if (edgeSolId == faceSolId && edgeSolId != ObjectId.Null)

          {

            Solid3d solid =

              tr.GetObject(edgeSolId, OpenMode.ForWrite)

              as Solid3d;

            if (solid != null)

            {

              // Here's where we actually chamfer the edge

              // with hard-coded values

 

              SubentityId[] edgeIds =

                new SubentityId[] { edgeId };

              solid.ChamferEdges(edgeIds, faceId, 0.5, 1.0);

            }

            tr.Commit();

          }

        }

      }

      catch (Autodesk.AutoCAD.Runtime.Exception ex)

      {

        ed.WriteMessage(ex.Message);

      }

    }

 

    public static SubentityId GetSubentity(

      Editor ed, Transaction tr, SelectionSet ss,

      SubentityType type, out ObjectId solId

    )

    {

      SubentityId retId = new SubentityId();

 

      // Should have only one object in the array

 

      SelectedObject so = ss[0];

 

      // We set our out parameter to the owning solid's ObjectId

 

      solId = so.ObjectId;

 

      // Access the solid via the transaction passed in

 

      Solid3d solid =

        tr.GetObject(so.ObjectId, OpenMode.ForRead)

        as Solid3d;

 

      // Get its subentities

 

      SelectedSubObject[] sso = so.GetSubentities();

 

      // Get their first subentity's type

 

      SubentityType subentityType =

        sso[0].FullSubentityPath.SubentId.Type;

 

      // See if it's of the type we want

 

      if (subentityType == type)

      {

        retId = sso[0].FullSubentityPath.SubentId;

      }

      else

      {

        ed.WriteMessage(

          "\nInvalid Subentity Type: {0}, " +

          "Expecting a {1} to be selected.\n",

          subentityType, type.ToString()

        );

      }

 

      return retId;

    }

  }

}

We'll use a simple box to test the code:

A simple box

Here's what happens when we run the EC command to chamfer each of the top edges (selecting the top face, each time):

Now with chamfered top edges

2 responses to “Chamfering the selected edge of an AutoCAD solid using .NET”

  1. thanks!

    but have two question:
    1、AutoCAD 2008, ChamferEdges function error!
    2、AutoCAD 2012, frist run Program OK,second run Select face fail!!

  2. I'm not surprised about it not working with AutoCAD 2008 (I assume this code uses an API that was introduced since then).

    Are you selecting a face rather than an edge for the second run on 2012? In which case that is also not very surprising (although it depends on whether the "fail" is a crash or handled gracefully by the app).

    Kean

Leave a Reply to Kean Walmsley Cancel reply

Your email address will not be published. Required fields are marked *