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".

 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章