A blog for developers programming with Autodesk platforms, particularly AutoCAD and Forge. With a special focus on AR/VR and IoT.

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

{

publicclassCommands

{

[CommandMethod("EC")]

publicvoid EdgeChamfer()

{

Document doc =

Application.DocumentManager.MdiActiveDocument;

Database db = doc.Database;

Editor ed = doc.Editor;

// Select an edge

PromptSelectionOptions pso =

newPromptSelectionOptions();

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)

asSolid3d;

if (solid != null)

{

// Here's where we actually chamfer the edge

// with hard-coded values

SubentityId[] edgeIds =

newSubentityId[] { edgeId };

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

}

tr.Commit();

}

}

}

catch (Autodesk.AutoCAD.Runtime.Exception ex)

{

ed.WriteMessage(ex.Message);

}

}

publicstaticSubentityId GetSubentity(

Editor ed, Transaction tr, SelectionSet ss,

SubentityType type, outObjectId solId

)

{

SubentityId retId = newSubentityId();

// 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)

asSolid3d;

// 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:

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