Creating a simple associative AutoCAD array along a path using .NET

I'm not sure why it's taken me so long to get around to posting this code. It was originally developed by Philippe Leefsma for last year's Developer Days, to demonstrate a very interesting API added to AutoCAD 2012. Looking back, it appears it was covered in this DevTV session, posted when AutoCAD 2012 was announced, so the information has been there for some of you to find, at least.

Anyway, as many of you will know, associative arrays are an extremely powerful feature within AutoCAD that allow you to create impressive results. You can create rectangular, polar and path-based arrays, and not just in 2D: in 3D, too.

My ultimate goal is to do something fun with arrays from inside a jig (yes, being driven by Kinect ;-). But let's start, today, with a simple array along a path with hardcoded parameter values.

Here's a subset of Philippe's original code that creates a simple associative array of multiple entities (a line and circle) along a spline path:

using Autodesk.AutoCAD.ApplicationServices;

using Autodesk.AutoCAD.DatabaseServices;

using Autodesk.AutoCAD.Geometry;

using Autodesk.AutoCAD.Runtime;

 

namespace AssociativeArrays

{

  public class Commands

  {

    [CommandMethod("AAP")]

    public void CreateAssocArrayPath()

    {

      Database db =

        Application.DocumentManager.MdiActiveDocument.Database;

 

      Transaction tr =

        db.TransactionManager.StartTransaction();

      using (tr)

      {

        BlockTable bt =

          (BlockTable)tr.GetObject(

            db.BlockTableId, OpenMode.ForRead

          );

 

        BlockTableRecord btr =

          (BlockTableRecord)tr.GetObject(

            bt[BlockTableRecord.ModelSpace],

            OpenMode.ForWrite

          );

 

        // Add profile entities: a Circle and a Line

 

        Circle cir =

          new Circle(

            new Point3d(-10, 0, 0),

            new Vector3d(0, 0, 1),

            1.0

          );

        cir.ColorIndex = 3; // Green

 

        btr.AppendEntity(cir);

        tr.AddNewlyCreatedDBObject(cir, true);

 

        Line ln =

          new Line(

            new Point3d(-11, -1, 0),

            new Point3d(-9, 1, 0)

          );

        ln.ColorIndex = 3; // Green

 

        btr.AppendEntity(ln);

        tr.AddNewlyCreatedDBObject(ln, true);

 

        // Add path entity: a Spline, in this case

 

        double fitTol = 0.0;

        int order = 4;

 

        // An array of doubles to define the points

        // in our spline

 

        double[] ptAr =

          new double[]{

            -6.8447, 0.9430,  0,

            -5.1409, -3.0562, 0,

            -2.4095, 2.1049,  0,

            3.4590, -3.9479, 0,

            7.1370, 6.3472,  0

          };

 

        // We'll add the points to a collection

 

        Point3dCollection pts = new Point3dCollection();

 

        for (int i = 0, j = 0; i < ptAr.Length / 3; i++)

        {

          pts.Add(new Point3d(ptAr[j++], ptAr[j++], ptAr[j++]));

        }

 

        // Create the spline path and add it to the database

 

        Spline sp = new Spline(pts, order, fitTol);

 

        btr.AppendEntity(sp);

        tr.AddNewlyCreatedDBObject(sp, true);

 

        // Offset the Circle, Line and Spline by a fixed amount

 

        Matrix3d offset =

          Matrix3d.Displacement(new Vector3d(60, 10, 0));

 

        cir.TransformBy(offset);

        ln.TransformBy(offset);

        sp.TransformBy(offset);

 

        ObjectIdCollection srcEnts = new ObjectIdCollection();

 

        srcEnts.Add(cir.ObjectId);

        srcEnts.Add(ln.ObjectId);

 

        // Take the base point as the center of our Circle

 

        VertexRef basePt = new VertexRef(cir.Center);

 

        // Set some variables to define parameters for our path

 

        int itemCount = 6;

        double itemSpacing =

          sp.GetDistanceAtParameter(sp.EndParam) / itemCount;

        double rowSpacing = 0.0;

        double levelSpacing = 0.0;

        int rowCount = 0;

        int levelCount = 0;

        double rowElevation = 0.0;

 

        // Create the parameters for our associative path array

 

        AssocArrayPathParameters pars =

          new AssocArrayPathParameters(

            itemSpacing,

            rowSpacing,

            levelSpacing,

            itemCount,

            rowCount,

            levelCount,

            rowElevation

          );

 

        pars.Method =

          AssocArrayPathParameters.MethodType.Measure;

 

        pars.Path = new EdgeRef(sp);

 

        // Create the associative array itself

 

        AssocA
rray
array =

          AssocArray.CreateArray(

            srcEnts,

            basePt,

            pars

          );

 

        // Evaluate the array

 

        AssocManager.EvaluateTopLevelNetwork(db, null, 0);

 

        tr.Commit();

      }

    }

  }

}

Here's what's created by the AAP command:

Our associative array along a path

And just to show it's associative, here's what happens when we grip-stretch the spline path:

And yes, we are associative

7 responses to “Creating a simple associative AutoCAD array along a path using .NET”

  1. I was created array entity by array command of autocad.I used LI command , return base point ,for example is A point. Then i edit it ; i set base point is a new value , and I used LI command , return base point is no change.How is base point ? How to get base point ? ( i used AcDbAssocArrayActionBody::getSourceBasePoint ,just return that A point )

    1. HT,

      Your question isn't really about code in this post (as far as I can tell) and so qualifies as a support question. Which means it needs to be posted to the relevant online discussion group rather than this blog.

      Regards,

      Kean

      1. Thanks you ! Because I just want have fastest answer ! Can I have your skype acc and of Philippe Leefsma or address email of both ?

  2. Dhananjay Dixit Avatar

    Associativity between 3dSolid and hatch: Is there a way using .net or ObjectARX to define associtivity between 3dSolid and a hatch pattern, I am creating 3dsolid and putting a hatch pattern in it top face. I need them associated/connected with each other so that when I move 3dsolid, hatch pattern also moves with it.

    1. You could do it, with enough work. Search my blog for the "linking circles" series.

      Kean

  3. Hi Kean,
    I am new to VB.net
    I am trying to create an array of entity along a selected group of connected polyline.
    I started by prompt the user to select the line group with 'promptselectionoption'.
    Then, i found it hard to get the sum of length for all selected with the promptselctionresult, in order to calculate the total no of entity will be required to array along the connected lines (since total no of entity is one of the parameter in AssocArrayPathParameters).
    I am not sure if I am working in the right direction.
    It would be grateful if you can give me some recommendations.
    Thanks in advance.

    1. Hi Daphne,

      Unfortunately I don't have time to provide technical support. Please post your question to the AutoCAD .NET forum.

      Thank you,

      Kean

Leave a Reply

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