Kean Walmsley


  • About the Author
    Kean on Google+

April 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      







« Advanced jigging with AutoCAD .NET - adding keywords | Main | Finding the location of a .NET module »

November 21, 2006

Two methods for selecting entities at a particular location

This entry was contributed by an old friend who recently rejoined the ADN team, Jeremy Tammik. Jeremy has been in and around the Autodesk family for many years - he actually delivered the first ever ARX training in San Rafael, back when it was still called ARX - and I'm very pleased he chose to rejoin our team earlier this year. It also happens to be Jeremy's birthday this coming weekend (on Sunday 26th November), for anyone who's interested. :-)

The question came in from an ADN member and revolved around the need to select objects at a particular location from an AutoCAD .NET application. Here's Jeremy's response...

I see two approaches for selecting all entities of a given type in a crossing window.

One approach is to use the predefined EditorInput.SelectCrossingWindow() method, which is similar to the built-in AutoCAD user interactive selection method. This has the advantage of being fast in a big database with many entities, because it makes use of clever internal algorithms to filter away all entities that are not applicable. The disadvantage is that it only works in the currently visible part of the screen.

Another approach is more programmatic: to iterate over the entire database and select all applicable entities yourself. This approach could be more complex, depending on the type of entity being selected (it's not always easy to establish whether a complex entity is located at a particular point).

I have appended the complete source for a project containing an example of each approach, one selecting text entities, the other selecting lines.

Here is the relevant C# code:

using Autodesk.AutoCAD.ApplicationServices;

using Autodesk.AutoCAD.DatabaseServices;

using Autodesk.AutoCAD.EditorInput;

using Autodesk.AutoCAD.Geometry;

using Autodesk.AutoCAD.Runtime;


namespace SelectCrossing

{

  public class Commands

  {

    /// <summary>

    /// Demonstrates the SelectCrossingWindow()

    /// method of Autodesk.AutoCAD.EditorInput.

    /// 

    /// This example selects all text

    /// entities at a given point.

    /// </summary>

    [CommandMethod("WinEd")]

    public void SelectCrossingEditor()

    {

      Editor ed =

        Application.DocumentManager.MdiActiveDocument.Editor;

      try

      {

        PromptPointOptions ptOpts =

          new PromptPointOptions(

            "\nPick a point at which to select all text entities: "

          );

        PromptPointResult ptRes =

          ed.GetPoint(ptOpts);

        if (PromptStatus.OK == ptRes.Status)

        {

          Point3d p = ptRes.Value;

          Point3d p1 =

            new Point3d(p.X - 0.01, p.Y - 0.01, 0.0);

          Point3d p2 =

            new Point3d(p.X + 0.01, p.Y + 0.01, 0.0);

          TypedValue[] values =

            {

              new TypedValue(

                (int)DxfCode.Start,

                "TEXT"

              )

            };

          SelectionFilter filter =

            new SelectionFilter(values);

          PromptSelectionResult res =

            ed.SelectCrossingWindow(p1, p2, filter);

          SelectionSet ss =

            res.Value;

          int n = 0;

          if (ss != null)

          {

            n = ss.Count;

          }

          ed.WriteMessage(

            string.Format(

              "\n{0} text entit{1} selected.",

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

            )

          );

        }

      }

      catch (System.Exception e)

      {

        ed.WriteMessage("\nException {0}.", e);

      }

    }


    /// <summary>

    /// Demonstrate how to select entities

    /// by iterating over the model space.

    /// 

    /// The example selects all line

    /// entities at a given point.

    /// </summary>

    [CommandMethod("WinDb")]

    public void SelectCrossingDatabase()

    {

      Document doc =

        Application.DocumentManager.MdiActiveDocument;

      Editor ed =

        doc.Editor;


      try

      {

        PromptPointOptions ptOpts =

          new PromptPointOptions(

            "\nPick a point at which to select all lines: "

          );

        PromptPointResult ptRes = ed.GetPoint(ptOpts);

        if (PromptStatus.OK == ptRes.Status)

        {

          ObjectIdCollection ids =

            new ObjectIdCollection();

          Point3d p = ptRes.Value;

          Database db = doc.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.ForRead

              );

            foreach( ObjectId id in btr )

            {

              DBObject obj =

                tr.GetObject( id, OpenMode.ForRead );

              Line dbLine = obj as Line;

              if (dbLine != null)

              {

                LineSegment3d lineSegment =

                  new LineSegment3d(

                    dbLine.StartPoint,

                    dbLine.EndPoint

                  );

                PointOnCurve3d q =

                  lineSegment.GetClosestPointTo(p);

                if (p.DistanceTo( q.Point ) < 0.01)

                {

                  ids.Add( dbLine.ObjectId );

                }

              }

            }

            tr.Commit();

          }

          int n = ids.Count;

          ed.WriteMessage(

            string.Format(

              "\n{0} line{1} selected.",

              n, 1 == n ? "" : "s"

            )

          );

        }

      }

      catch( System.Exception e )

      {

        ed.WriteMessage("\nException {0}.", e);

      }

    }

  }

}

TrackBack

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

Listed below are links to weblogs that reference Two methods for selecting entities at a particular location:

blog comments powered by Disqus

10 Random Posts