October 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 31  










« Updating a specific attribute inside a folder of AutoCAD drawings using RealDWG from .NET | Main | Purging registered application names in the current AutoCAD drawing using .NET »

August 10, 2007

Moving entities from one AutoCAD layer to another using .NET

Firstly I should apologise to those readers using RSS to access this site: I've been playing around with the configuration, to integrate FeedBurner but also to switch from publishing entire articles via RSS to publishing introductions - my posts are just too long, which seems to cause a problem for some RSS readers. So you may have received multiple versions of the same articles for the last few weeks - sorry about that.

For those of you who have not yet subscribed via RSS - please see the new options in the side-bar on the left: it should now be simpler for you to use your favourite RSS reader to pull down excerpts of the content I publish, rather than checking the site itself.

OK, now onto the real content. I had this question come in from António Rodrigues, an engineering student from Portugal:

I'm doing a project at school about hydraulics calculations, where i have get some data from AutoCAD. [...] I need to get all the objects from a single layer in the drawing, so i can use them to perform the calculations needed.

I put together some code for Antonio which uses Editor.SelectAll() with an appropriate SelectionFilter to get the list of entities on a particular layer. Just for fun I then extended the code to allow the user to enter a new layer name for these entities to be moved to.

Here's the C# code:

using Autodesk.AutoCAD.ApplicationServices;

using Autodesk.AutoCAD.DatabaseServices;

using Autodesk.AutoCAD.EditorInput;

using Autodesk.AutoCAD.Runtime;


namespace LayerTools

{

  public class Commands

  {

    [CommandMethod("CL")]

    public void ChangeLayerOfEntitiess()

    {

      Document doc =

        Application.DocumentManager.MdiActiveDocument;

      Database db = doc.Database;

      Editor ed = doc.Editor;


      // Ask the user for the layer name, allowing

      // spaces to be entered


      PromptStringOptions pso =

        new PromptStringOptions(

          "\nEnter name of layer to search for: "

        );

      pso.AllowSpaces = true;

      PromptResult pr =

        ed.GetString(pso);


      if (pr.Status != PromptStatus.OK)

        return;

      string layerName = pr.StringResult;


      // We won't validate whether the layer exists -

      // we'll just see what's returned by the selection.


      TypedValue[] tvs = new TypedValue[1];

      tvs[0] =

        new TypedValue((int)DxfCode.LayerName, layerName);

      SelectionFilter sf = new SelectionFilter(tvs);

      PromptSelectionResult psr = ed.SelectAll(sf);


      int count = 0;

      if (psr.Status == PromptStatus.OK)

        count = psr.Value.Count;


      if (psr.Status == PromptStatus.OK ||

          psr.Status == PromptStatus.Error)

      {

        // Display the count of entities on that layer


        ed.WriteMessage(

          "\nFound {0} entit{1} on layer \"{2}\".",

          count,

          count == 1 ? "y" : "ies",

          layerName

        );


        // If there are some on this layer,

        // prompt for the layer to move them to


        if (count > 0)

        {

          pso.Message =

            "\nEnter new layer for these entities " +

            "or return to leave them alone: ";

          pr =

            ed.GetString(pso);


          if (pr.Status != PromptStatus.OK ||

              pr.StringResult == "")

            return;

          string newLayerName = pr.StringResult;


          Transaction tr =

            db.TransactionManager.StartTransaction();

          using (tr)

          {

            // This time we do check whether

            // the layer exists


            LayerTable lt =

              (LayerTable)tr.GetObject(

                db.LayerTableId,

                OpenMode.ForRead

              );


            if (!lt.Has(newLayerName))

              ed.WriteMessage("\nLayer not found.");

            else

            {

              int changedCount = 0;


              // We have the layer table open, so let's

              // get the layer ID and use that


              ObjectId lid = lt[newLayerName];

              foreach (ObjectId id in psr.Value.GetObjectIds())

              {

                Entity ent =

                  (Entity)tr.GetObject(id, OpenMode.ForWrite);

                ent.LayerId = lid;

                // Could also have used:

                //  ent.Layer = newLayerName;

                // but this way is more efficient and cleaner

                changedCount++;

              }

              ed.WriteMessage(

                "\nChanged {0} entit{1} from " +

                "layer \"{2}\" to layer \"{3}\".",

                changedCount,

                changedCount == 1 ? "y" : "ies",

                layerName,

                newLayerName

              );

            }

            tr.Commit();

          }

        }

      }

    }

  }

}

Here's what happens when you run the CL command and use it to move entities from the "Dim" layer to "My new layer":

Command: CL

Enter name of layer to search for: Dim

Found 14 entities on layer "Dim".

Enter new layer for these entities or return to leave them alone: My new layer

Changed 14 entities from layer "Dim" to layer "My new layer".

TrackBack

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

Listed below are links to weblogs that reference Moving entities from one AutoCAD layer to another using .NET:

blog comments powered by Disqus

Feed/Share

10 Random Posts