ADN Open CIS
Сообщество программистов Autodesk в СНГ

05/03/2014

Нахождение примитивов под курсором в момент выбора примитивов

Функция обратного вызова PointMonitor в .Net позволяет получить доступ к примитивам, находящимся внутри апертуры курсора, когда пользователь наводит мышь, однако эта возможность заблокирована в момент, когда выполняется Editor.GetEntity.

Существует обходной путь для этой ситуации, который использует P/Invoke для вызова ряда методов ObjectARX. Ниже приводится пример на C#.

Вложенные примитивы также могут детектироваться, как было сказано в предыдущей теме:

Получение вложенных примитивов под апертурой курсора с использованием .NET API

Код - C#: [Выделить]
  1. class ArxImports
  2. {
  3.     public struct ads_name
  4.     {
  5.         public IntPtr a;
  6.         public IntPtr b;
  7.     };
  8.  
  9.     [StructLayout(LayoutKind.Sequential, Size = 32)]
  10.     public struct resbuf { }
  11.  
  12.     [DllImport("accore.dll",
  13.         CallingConvention = CallingConvention.Cdecl,
  14.         CharSet = CharSet.Unicode,
  15.         ExactSpelling = true)]
  16.     public static extern PromptStatus acedSSGet(
  17.         string str, IntPtr pt1, IntPtr pt2,
  18.         IntPtr filter, out ads_name ss);
  19.  
  20.     [DllImport("accore.dll",
  21.         CallingConvention = CallingConvention.Cdecl,
  22.         CharSet = CharSet.Unicode,
  23.         ExactSpelling = true)]
  24.     public static extern PromptStatus acedSSFree(
  25.         ref ads_name ss);
  26.  
  27.     [DllImport("accore.dll",
  28.         CallingConvention = CallingConvention.Cdecl,
  29.         CharSet = CharSet.Unicode,
  30.         ExactSpelling = true)]
  31.     public static extern PromptStatus acedSSLength(
  32.         ref ads_name ss, out int len);
  33.  
  34.     [DllImport("accore.dll",
  35.         CallingConvention = CallingConvention.Cdecl,
  36.         CharSet = CharSet.Unicode,
  37.         ExactSpelling = true)]
  38.     public static extern PromptStatus acedSSName(
  39.         ref ads_name ss, int i, out ads_name name);
  40.  
  41.     [DllImport("acdb19.dll",
  42.         CallingConvention = CallingConvention.Cdecl,
  43.         CharSet = CharSet.Unicode,
  44.         ExactSpelling = true)]
  45.     public static extern ErrorStatus acdbGetObjectId(
  46.         out ObjectId id, ref ads_name name);
  47. }
  48.  
  49. static System.Collections.Generic.List<ObjectId>
  50.     FindAtPoint(Point3d worldPoint, bool selectAll = true)
  51. {
  52.     System.Collections.Generic.List<ObjectId> ids =
  53.         new System.Collections.Generic.List<ObjectId>();
  54.  
  55.     Document doc = Application.DocumentManager.MdiActiveDocument;
  56.  
  57.     Matrix3d wcs2ucs =
  58.         doc.Editor.CurrentUserCoordinateSystem.Inverse();
  59.  
  60.     Point3d ucsPoint = worldPoint.TransformBy(wcs2ucs);
  61.           
  62.     string arg = selectAll ? ":E" : string.Empty;
  63.           
  64.     IntPtr ptrPoint = Marshal.UnsafeAddrOfPinnedArrayElement(
  65.         worldPoint.ToArray(), 0);
  66.  
  67.     ArxImports.ads_name sset;
  68.  
  69.     PromptStatus prGetResult = ArxImports.acedSSGet(
  70.         arg, ptrPoint, IntPtr.Zero, IntPtr.Zero, out sset);
  71.  
  72.     int len;
  73.     ArxImports.acedSSLength(ref sset, out len);
  74.  
  75.     if (len <= 0)
  76.         return ids;
  77.           
  78.     for (int i = 0; i < len; ++i)
  79.     {
  80.         ArxImports.ads_name name;
  81.  
  82.         if (ArxImports.acedSSName(
  83.             ref sset, i, out name) != PromptStatus.OK)
  84.             continue;
  85.                
  86.         ObjectId id;
  87.  
  88.         if (ArxImports.acdbGetObjectId(
  89.             out id, ref name) != ErrorStatus.OK)
  90.             continue;
  91.  
  92.         ids.Add(id);
  93.     }
  94.  
  95.     ArxImports.acedSSFree(ref sset);
  96.  
  97.     return ids;
  98. }
  99.  
  100. Editor AdnEditor;
  101.  
  102. [CommandMethod("PointMonitorSelection")]
  103. public void PointMonitorSelection()
  104. {
  105.     Document doc = Application.DocumentManager.MdiActiveDocument;
  106.     Database db = doc.Database;
  107.     Editor ed = doc.Editor;
  108.  
  109.     try
  110.     {
  111.         AdnEditor = doc.Editor;
  112.  
  113.         AdnEditor.PointMonitor +=
  114.             FindUsingPointMonitor;
  115.        
  116.         PromptEntityOptions peo = new PromptEntityOptions(
  117.             "Выберите примитив: ");
  118.  
  119.         PromptEntityResult per = ed.GetEntity(peo);
  120.  
  121.         if (per.Status != PromptStatus.OK)
  122.             return;
  123.  
  124.         ObjectId id = per.ObjectId;
  125.  
  126.         ed.WriteMessage("\n - Выбрано " +
  127.             " Entity: " + id.ObjectClass.Name +
  128.             " Id: " + id.ToString());
  129.     }
  130.     catch(System.Exception ex)
  131.     {
  132.         ed.WriteMessage("\nИсключение: " + ex.Message);
  133.     }
  134.     finally
  135.     {
  136.         AdnEditor.PointMonitor -=
  137.             FindUsingPointMonitor;
  138.     }
  139. }
  140.  
  141. void FindUsingPointMonitor(object sender, PointMonitorEventArgs e)
  142. {
  143.     Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
  144.  
  145.     // Не работает пока идет выбор примитивов
  146.     //foreach (var subId in e.Context.GetPickedEntities())
  147.     //{
  148.     //    foreach (var id in subId.GetObjectIds())
  149.     //    {
  150.     //        ed.WriteMessage("\n - " +
  151.     //            " Entity: " + id.ObjectClass.Name +
  152.     //            " Id: " + id.ToString());
  153.     //    }
  154.     //}
  155.  
  156.     var ids = FindAtPoint(e.Context.RawPoint);
  157.  
  158.     foreach (var id in ids)
  159.     {
  160.         ed.WriteMessage("\n + " +
  161.             " Entity: " + id.ObjectClass.Name +
  162.             " Id: " + id.ToString());
  163.     }
  164. }

Источник: http://adndevblog.typepad.com/autocad/2014/02/detecting-entities-under-cursor-while-selection-is-running.html

Обсуждение: http://adn-cis.org/forum/index.php?topic=588

Опубликовано 05.03.2014