November 2014

Sun Mon Tue Wed Thu Fri Sat
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30            










« Adding an ObjectOverrule to stop AutoCAD objects from being erased using .NET | Main | Back in Munich »

December 13, 2011

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

blog comments powered by Disqus

Feed/Share

10 Random Posts