September 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        








« Autodesk Design Review 2009 API documentation now available | Main | Sectioning an AutoCAD solid using .NET »

May 22, 2008

Sweeping an AutoCAD surface using .NET

AutoCAD 2007 introduced more advanced solid & surface modeling tools. This post takes a look at how to generate one particular type of surface: a SweptSurface, which is created by sweeping a profile (which could be a region, a planar surface or a curve) through a particular path (which must be a curve).

The below C# code shows how to sweep an object along a curved path to create a surface. Our SAP (for SweepAlongPath) command doesn't provide all the options of the standard SWEEP command, as the point is to show how to do this programmatically, not to duplicate standard AutoCAD functionality.

We're creating a SweptSurface in our code: it's also possible to sweep a similar entity along a path to create a Solid3d, but at the time of writing this is only exposed through ObjectARX (AcDb3dSolid::createSweptSolid()). If you have a strong need to create swept solids in AutoCAD using .NET, please send me an email.

using Autodesk.AutoCAD.ApplicationServices;

using Autodesk.AutoCAD.DatabaseServices;

using Autodesk.AutoCAD.EditorInput;

using Autodesk.AutoCAD.Runtime;

using Autodesk.AutoCAD.Geometry;


namespace SolidCreation

{

  public class Commands

  {

    [CommandMethod("SAP")]

    public void 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 =

        new PromptEntityOptions(

          "\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 =

        new PromptEntityOptions(

          "\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;


      // Now let's create our swept surface


      Transaction tr =

        db.TransactionManager.StartTransaction();

      using (tr)

      {

        try

        {

          Entity sweepEnt =

            tr.GetObject(regId, OpenMode.ForRead) as Entity;


          Curve pathEnt =

            tr.GetObject(splId, OpenMode.ForRead) as Curve;


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

          {

            ed.WriteMessage(

              "\nProblem opening the selected entities."

            );

            return;

          }


          // We use a builder object to create

          // our SweepOptions


          SweepOptionsBuilder sob =

            new SweepOptionsBuilder();


          // 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 surface...


          SweptSurface ss =

            new SweptSurface();


          ss.CreateSweptSurface(

            sweepEnt,

            pathEnt,

            sob.ToSweepOptions()

          );


          // ... 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(ss);

          tr.AddNewlyCreatedDBObject(ss, true);


          tr.Commit();

        }

        catch

        { }

      }

    }

  }

}

Here's an image of a very simple drawing I used to demonstrate the function. I started by creating a helix, and then copied it, essentially creating my two paths. I then drew a tiny circle at the end point of the first helix (not aligned to the path in any way - just flat in the World UCS - as the SweepOptions we choose will ask that the profile to be aligned automatically to the path), and drew a simple "S"-shaped spline at the end point of the second helix (I drew the spline elsewhere and moved it using the mid-point as a base point, selecting the end of the helix as the destination).

So we end up with two paths (both helixes) and their respective non-aligned profiles (one a circle, the other a spline):

Helix paths and profiles

I then ran the SAP command twice, selecting one of the profiles and its respective path each time. Here's the 2D wireframe view of what was created:

Swept surfaces - plan

To see the geometry better, I then changed to use the conceptual visual style and orbitted around to get a better 3D view:

Swept surfaces - 3D conceptual

Update

As mentioned in this post, Solid3d.CreateSweptSolid has now been implemented in AutoCAD 2010.

Update 2

And you can see the how to use Solid3d.CreateSweptSolid in this post.

TrackBack

TrackBack URL for this entry:
http://www.typepad.com/services/trackback/6a00d83452464869e200e5526b97ac8834

Listed below are links to weblogs that reference Sweeping an AutoCAD surface using .NET:

blog comments powered by Disqus

Feed/Share

10 Random Posts