05/03/2014
Нахождение примитивов под курсором в момент выбора примитивов
Функция обратного вызова PointMonitor в .Net позволяет получить доступ к примитивам, находящимся внутри апертуры курсора, когда пользователь наводит мышь, однако эта возможность заблокирована в момент, когда выполняется Editor.GetEntity.
Существует обходной путь для этой ситуации, который использует P/Invoke для вызова ряда методов ObjectARX. Ниже приводится пример на C#.
Вложенные примитивы также могут детектироваться, как было сказано в предыдущей теме:
Получение вложенных примитивов под апертурой курсора с использованием .NET API
Код - C#: [Выделить]
- class ArxImports
- {
- public struct ads_name
- {
- public IntPtr a;
- public IntPtr b;
- };
- [StructLayout(LayoutKind.Sequential, Size = 32)]
- public struct resbuf { }
- [DllImport("accore.dll",
- CallingConvention = CallingConvention.Cdecl,
- CharSet = CharSet.Unicode,
- ExactSpelling = true)]
- public static extern PromptStatus acedSSGet(
- string str, IntPtr pt1, IntPtr pt2,
- IntPtr filter, out ads_name ss);
- [DllImport("accore.dll",
- CallingConvention = CallingConvention.Cdecl,
- CharSet = CharSet.Unicode,
- ExactSpelling = true)]
- public static extern PromptStatus acedSSFree(
- ref ads_name ss);
- [DllImport("accore.dll",
- CallingConvention = CallingConvention.Cdecl,
- CharSet = CharSet.Unicode,
- ExactSpelling = true)]
- public static extern PromptStatus acedSSLength(
- ref ads_name ss, out int len);
- [DllImport("accore.dll",
- CallingConvention = CallingConvention.Cdecl,
- CharSet = CharSet.Unicode,
- ExactSpelling = true)]
- public static extern PromptStatus acedSSName(
- ref ads_name ss, int i, out ads_name name);
- [DllImport("acdb19.dll",
- CallingConvention = CallingConvention.Cdecl,
- CharSet = CharSet.Unicode,
- ExactSpelling = true)]
- public static extern ErrorStatus acdbGetObjectId(
- out ObjectId id, ref ads_name name);
- }
- static System.Collections.Generic.List<ObjectId>
- FindAtPoint(Point3d worldPoint, bool selectAll = true)
- {
- System.Collections.Generic.List<ObjectId> ids =
- new System.Collections.Generic.List<ObjectId>();
- Document doc = Application.DocumentManager.MdiActiveDocument;
- Matrix3d wcs2ucs =
- doc.Editor.CurrentUserCoordinateSystem.Inverse();
- Point3d ucsPoint = worldPoint.TransformBy(wcs2ucs);
- string arg = selectAll ? ":E" : string.Empty;
- IntPtr ptrPoint = Marshal.UnsafeAddrOfPinnedArrayElement(
- worldPoint.ToArray(), 0);
- ArxImports.ads_name sset;
- PromptStatus prGetResult = ArxImports.acedSSGet(
- arg, ptrPoint, IntPtr.Zero, IntPtr.Zero, out sset);
- int len;
- ArxImports.acedSSLength(ref sset, out len);
- if (len <= 0)
- return ids;
- for (int i = 0; i < len; ++i)
- {
- ArxImports.ads_name name;
- if (ArxImports.acedSSName(
- ref sset, i, out name) != PromptStatus.OK)
- continue;
- ObjectId id;
- if (ArxImports.acdbGetObjectId(
- out id, ref name) != ErrorStatus.OK)
- continue;
- ids.Add(id);
- }
- ArxImports.acedSSFree(ref sset);
- return ids;
- }
- Editor AdnEditor;
- [CommandMethod("PointMonitorSelection")]
- public void PointMonitorSelection()
- {
- Document doc = Application.DocumentManager.MdiActiveDocument;
- Database db = doc.Database;
- Editor ed = doc.Editor;
- try
- {
- AdnEditor = doc.Editor;
- AdnEditor.PointMonitor +=
- FindUsingPointMonitor;
- PromptEntityOptions peo = new PromptEntityOptions(
- "Выберите примитив: ");
- PromptEntityResult per = ed.GetEntity(peo);
- if (per.Status != PromptStatus.OK)
- return;
- ObjectId id = per.ObjectId;
- ed.WriteMessage("\n - Выбрано " +
- " Entity: " + id.ObjectClass.Name +
- " Id: " + id.ToString());
- }
- catch(System.Exception ex)
- {
- ed.WriteMessage("\nИсключение: " + ex.Message);
- }
- finally
- {
- AdnEditor.PointMonitor -=
- FindUsingPointMonitor;
- }
- }
- void FindUsingPointMonitor(object sender, PointMonitorEventArgs e)
- {
- Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
- // Не работает пока идет выбор примитивов
- //foreach (var subId in e.Context.GetPickedEntities())
- //{
- // foreach (var id in subId.GetObjectIds())
- // {
- // ed.WriteMessage("\n - " +
- // " Entity: " + id.ObjectClass.Name +
- // " Id: " + id.ToString());
- // }
- //}
- var ids = FindAtPoint(e.Context.RawPoint);
- foreach (var id in ids)
- {
- ed.WriteMessage("\n + " +
- " Entity: " + id.ObjectClass.Name +
- " Id: " + id.ToString());
- }
- }
Обсуждение: http://adn-cis.org/forum/index.php?topic=588
Опубликовано 05.03.2014