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

January 18, 2010

Sweeping an AutoCAD solid using .NET

Back in this previous post we looked at some code to sweep an AutoCAD surface using .NET. As I mentioned in a later update, it’s possible to also sweep an AutoCAD solid using .NET (since AutoCAD 2010: prior to that one had to use ObjectARX). I’ve just received a comment asking me to show how to do this, so I thought I’d cover that, today.

The code difference is tiny – we simply need to change the type of object we’re creating and call a different method with the same arguments.

Where for a SweptSurface we would do this…

SweptSurface ss = newSweptSurface();

ss.CreateSweptSurface(sweepEnt, pathEnt, sob.ToSweepOptions());

… for a Solid3d, we simply need to do this:

Solid3d sol = newSolid3d();

sol.CreateSweptSolid(sweepEnt, pathEnt, sob.ToSweepOptions());

In the below code I’ve added an additional prompt to the SAP command to ask the user whether to create a solid or a surface and then abstracted the logic slightly to create either entity type, setting the resulting entity to a generic Entity pointer that we can then add to the modelspace and our transaction. These are really the only changes – the rest of the code is identical to that shown previously.

Here’s the updated C# code:

using Autodesk.AutoCAD.ApplicationServices;

using Autodesk.AutoCAD.DatabaseServices;

using Autodesk.AutoCAD.EditorInput;

using Autodesk.AutoCAD.Runtime;

using Autodesk.AutoCAD.Geometry;

namespace SolidCreation

{

publicclassCommands

{

[CommandMethod("SAP")]

publicvoid SweepAlongPath()

{

Document doc =

Application.DocumentManager.MdiActiveDocument;

Database db = doc.Database;

Editor ed = doc.Editor;

// Ask the user to select a region to extrude

PromptEntityOptions peo1 =

newPromptEntityOptions(

"\nSelect profile or curve to sweep: "

);

peo1.SetRejectMessage(

"\nEntity must be a region, curve or planar surface."

);

peo1.AddAllowedClass(

typeof(Region), false);

peo1.AddAllowedClass(

typeof(Curve), false);

peo1.AddAllowedClass(

typeof(PlaneSurface), false);

PromptEntityResult per =

ed.GetEntity(peo1);

if (per.Status != PromptStatus.OK)

return;

ObjectId regId = per.ObjectId;

// Ask the user to select an extrusion path

PromptEntityOptions peo2 =

newPromptEntityOptions(

"\nSelect path along which to sweep: "

);

peo2.SetRejectMessage(

"\nEntity must be a curve."

);

peo2.AddAllowedClass(

typeof(Curve), false);

per = ed.GetEntity(peo2);

if (per.Status != PromptStatus.OK)

return;

ObjectId splId = per.ObjectId;

PromptKeywordOptions pko =

newPromptKeywordOptions(

"\nSweep a solid or a surface?"

);

pko.AllowNone = true;

pko.Keywords.Add("SOlid");

pko.Keywords.Add("SUrface");

pko.Keywords.Default = "SOlid";

PromptResult pkr =

ed.GetKeywords(pko);

bool createSolid = (pkr.StringResult == "SOlid");

if (pkr.Status != PromptStatus.OK)

return;

// Now let's create our swept surface

Transaction tr =

db.TransactionManager.StartTransaction();

using (tr)

{

try

{

Entity sweepEnt =

tr.GetObject(regId, OpenMode.ForRead) asEntity;

Curve pathEnt =

tr.GetObject(splId, OpenMode.ForRead) asCurve;

if (sweepEnt == null || pathEnt == null)

{

ed.WriteMessage(

"\nProblem opening the selected entities."

);

return;

}

// We use a builder object to create

// our SweepOptions

SweepOptionsBuilder sob =

newSweepOptionsBuilder();

// Align the entity to sweep to the path

sob.Align =

SweepOptionsAlignOption.AlignSweepEntityToPath;

// The base point is the start of the path

sob.BasePoint = pathEnt.StartPoint;

// The profile will rotate to follow the path

sob.Bank = true;

// Now generate the solid or surface...

Entity ent;

if (createSolid)

{

Solid3d sol = newSolid3d();

sol.CreateSweptSolid(

sweepEnt,

pathEnt,

sob.ToSweepOptions()

);

ent = sol;

}

else

{

SweptSurface ss = newSweptSurface();

ss.CreateSweptSurface(

sweepEnt,

pathEnt,

sob.ToSweepOptions()

);

ent = ss;

}

// ... and add it to the modelspace

BlockTable bt =

(BlockTable)tr.GetObject(

db.BlockTableId,

OpenMode.ForRead

);

BlockTableRecord ms =

(BlockTableRecord)tr.GetObject(

bt[BlockTableRecord.ModelSpace],

OpenMode.ForWrite

);

ms.AppendEntity(ent);

tr.AddNewlyCreatedDBObject(ent, true);

tr.Commit();

}

catch

{ }

}

}

}

}

Before we run the code, here are some helixes paths with circular profiles drawn planar to the plan view (as before, the sweep options take care of aligning the profile appropriately):

Now we can run the SAP command, choosing “SUrface” type for the profile & path on the left and “SOlid” for the profile & path on the right:

And now let’s see the results in a 3D, conceptual view of the drawing:

If you look carefully at the exposed end of the helices you’ll see that the one on the left (the surface) is open, which the one on the right (the solid) is closed.