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

ADN Club => AutoCAD .NET API => Тема начата: Кирилл Захаров от 14-03-2017, 21:16:43

Название: Выбор вложенных объектов секущей рамкой в Autocad через .NET
Отправлено: Кирилл Захаров от 14-03-2017, 21:16:43
Здравствуйте!
Я пытаюсь разобраться, как можно сделать выбор множества объектов, вложенных во внешнюю ссылку, секущей рамкой.
Я видел сообщения Александра Ривилиса на эту тему на форуме Autodesk Community: https://forums.autodesk.com/t5/net/selection-of-multiple-nested-entities/td-p/3750848?nobounce.
Он пишет, что можно использовать P/Invoke чтобы вызвать соответствующую функцию ObjectARX. У меня пока не хватает знаний, чтобы разобраться до конца как это делается, но я нашел еще один интересный пример на эту тему: http://adndevblog.typepad.com/autocad/2012/04/retrieving-nested-entities-under-cursor-aperture-using-net-api.html.
Используя этот пример, я попытался сделать выбор вложенных объектов рамкой, но пока не преуспел. Думаю, что я близок к решению. Привожу свой код:
Код - C# [Выбрать]
  1. using System;
  2. using Autodesk.AutoCAD.Runtime;
  3. using Autodesk.AutoCAD.ApplicationServices;
  4. using Autodesk.AutoCAD.DatabaseServices;
  5. using Autodesk.AutoCAD.Geometry;
  6. using Autodesk.AutoCAD.EditorInput;
  7. using System.Runtime.InteropServices;
  8.  
  9.  
  10. [assembly: CommandClass(typeof(Multiply_Nested_Select_Test.MyCommands))]
  11.  
  12. namespace Multiply_Nested_Select_Test
  13. {
  14.     public class MyCommands
  15.     {
  16.  
  17.  
  18.         [CommandMethod("SelectNestedTest", CommandFlags.Modal)]
  19.         public void MyCommand()
  20.         {
  21.             Document doc = Application.DocumentManager.MdiActiveDocument;
  22.             Editor ed = doc.Editor;
  23.             Database db = doc.Database;
  24.             XrefGraph xg = db.GetHostDwgXrefGraph(true);
  25.  
  26.             Point3d pt1 = new Point3d();
  27.             Point3d pt2 = new Point3d();
  28.             using (Transaction tr = db.TransactionManager.StartTransaction())
  29.             {
  30.                 SpecifySelectionWindow(out pt1, out pt2, db, ed);//Это метод для задания секущей рамки
  31.                 /////////////////////////////////////////////////////////////////////////////
  32.                 //Код выбора вложенных объектов рамкой
  33.  
  34.                 ResultBuffer resbuf = new ResultBuffer();
  35.  
  36.                 string arg = "_N:D";
  37.  
  38.                 IntPtr ptrPoint1 = Marshal.UnsafeAddrOfPinnedArrayElement(
  39.                     pt1.ToArray(), 0);
  40.                 IntPtr ptrPoint2 = Marshal.UnsafeAddrOfPinnedArrayElement(
  41.                     pt2.ToArray(), 0);
  42.  
  43.                 ArxImports.ads_name sset;
  44.  
  45.                 PromptStatus prGetResult = ArxImports.acedSSGet(
  46.                     arg, ptrPoint1, ptrPoint2, resbuf.UnmanagedObject, out sset);
  47.  
  48.                 int len;
  49.                 ArxImports.acedSSLength(ref sset, out len);
  50.                 ed.WriteMessage("\n" + len.ToString());
  51.                 /////////////////////////////////////////////////////////////////////////////
  52.                 tr.Commit();
  53.             }
  54.  
  55.            
  56.         }
  57.  
  58.         private static bool SpecifySelectionWindow(out Point3d pt1, out Point3d pt2, Database db, Editor adocEd)
  59.         {
  60.             pt1 = new Point3d();
  61.             pt2 = new Point3d();
  62.             Transaction tr = db.TransactionManager.StartTransaction();
  63.             using (tr)
  64.             {
  65.                 try
  66.                 {
  67.  
  68.                     PromptPointOptions ppo = new PromptPointOptions("\n\tSpecify a first corner: ");
  69.                     PromptPointResult ppr = adocEd.GetPoint(ppo);
  70.                     if (ppr.Status != PromptStatus.OK) return false;
  71.                     PromptCornerOptions pco = new PromptCornerOptions("\n\tOther corner: ", ppr.Value);
  72.                     PromptPointResult pcr = adocEd.GetCorner(pco);
  73.                     if (pcr.Status != PromptStatus.OK) return false;
  74.                     pt1 = ppr.Value;
  75.                     pt2 = pcr.Value;
  76.                     if (pt1.X == pt2.X || pt1.Y == pt2.Y)
  77.                     {
  78.                         adocEd.WriteMessage("\nInvalid point specification");
  79.                         return false;
  80.                     }
  81.  
  82.                     tr.Commit();
  83.                     return true;
  84.                 }
  85.                 catch (System.Exception ex)
  86.                 {
  87.                     adocEd.WriteMessage(ex.Message + "\n" + ex.StackTrace);
  88.                     return false;
  89.                 }
  90.             }
  91.         }
  92.  
  93.  
  94.     }
  95. //Класс в котором задаются методы для доступа к функциям ObjectARX, который я взял из примера
  96. class ArxImports
  97.     {
  98.         public struct ads_name
  99.         {
  100.             public IntPtr a;
  101.             public IntPtr b;
  102.         };
  103.  
  104.         [StructLayout(LayoutKind.Sequential, Size = 32)]
  105.         public struct resbuf { }
  106.  
  107.         [DllImport("accore.dll",
  108.             CallingConvention = CallingConvention.Cdecl,
  109.             CharSet = CharSet.Unicode,
  110.             ExactSpelling = true)]
  111.         public static extern PromptStatus acedSSGet(
  112.             string str, IntPtr pt1, IntPtr pt2,
  113.             IntPtr filter, out ads_name ss);
  114.  
  115.         [DllImport("accore.dll",
  116.             CallingConvention = CallingConvention.Cdecl,
  117.             CharSet = CharSet.Unicode,
  118.             ExactSpelling = true)]
  119.         public static extern PromptStatus acedSSFree(ref ads_name ss);
  120.  
  121.         [DllImport("accore.dll",
  122.             CallingConvention = CallingConvention.Cdecl,
  123.             CharSet = CharSet.Unicode,
  124.             ExactSpelling = true)]
  125.         public static extern PromptStatus acedSSLength(
  126.             ref ads_name ss, out int len);
  127.  
  128.         [DllImport("accore.dll",
  129.             CallingConvention = CallingConvention.Cdecl,
  130.             CharSet = CharSet.Unicode,
  131.             ExactSpelling = true)]
  132.         public unsafe static extern PromptStatus acedSSNameX(
  133.             resbuf** rbpp, ref ads_name ss, int i);
  134.        
  135.     }
  136.  
  137. }
  138.  

При использовании этого кода не выбирается ни одного объекта. Я думаю, мне нужно каким-то образом осуществить выполнение следующих функций ObjectARX:

Код - C++ [Выбрать]
  1. // switch on the multi selection of nested entities
  2. setAllowDuplicateSelection(curDoc(), true);  
  3. curDoc()->inputPointManager()->turnOnSubentityWindowSelection();
  4.  
(Взято из примера http://adndevblog.typepad.com/autocad/2012/08/acedssget-multi-select-in-n-mode.html)

Подскажите, пожалуйста, как можно решить эту проблему.
Название: Re: Выбор вложенных объектов секущей рамкой в Autocad через .NET
Отправлено: Александр Ривилис от 14-03-2017, 21:36:09
Код - C++ [Выбрать]
  1. curDoc()->inputPointManager()->turnOnSubentityWindowSelection();
эквивалентно
Код - C# [Выбрать]
  1. Application.DocumentManager.MdiActiveDocument.Editor.TurnSubentityWindowSelectionOn;
Код - C++ [Выбрать]
  1. curDoc()->inputPointManager()->turnOffSubentityWindowSelection();
эквивалентно
Код - C# [Выбрать]
  1. Application.DocumentManager.MdiActiveDocument.Editor.TurnSubentityWindowSelectionOff;
По поводу
Код - C++ [Выбрать]
  1. setAllowDuplicateSelection(curDoc(), true);
нужно посмотреть.

P.S.: Хотя я совсем не уверен, что это будет работать с внешними ссылками. Nested object - это вложенные объекты и обычно под этим подразумеваются объекты в блоках, а не во внешних ссылках.
Название: Re: Выбор вложенных объектов секущей рамкой в Autocad через .NET
Отправлено: Александр Ривилис от 14-03-2017, 21:39:17
P.S.: Убери из SpecifySelectionWindow всякое упоминание о транзакциях. Они там совершенно не нужны. Да и в MyCommand тоже.
Название: Re: Выбор вложенных объектов секущей рамкой в Autocad через .NET
Отправлено: Кирилл Захаров от 14-03-2017, 21:42:29
Да, это косяк с транзакцией) Спасибо за подсказки!
Название: Re: Выбор вложенных объектов секущей рамкой в Autocad через .NET
Отправлено: trir от 14-03-2017, 22:12:38
А в результате, что должно получится?
Название: Re: Выбор вложенных объектов секущей рамкой в Autocad через .NET
Отправлено: Кирилл Захаров от 14-03-2017, 22:18:59
Напишу когда и если получится
Название: Re: Выбор вложенных объектов секущей рамкой в Autocad через .NET
Отправлено: trir от 14-03-2017, 22:34:13
Ты пытаешься получить не существующие объекты
Название: Re: Выбор вложенных объектов секущей рамкой в Autocad через .NET
Отправлено: Кирилл Захаров от 14-03-2017, 22:41:26
Ты пытаешься получить не существующие объекты

Вы не правы. Объекты внешних ссылок присутствуют в базе данных чертежа так же как и объекты внутри блоков. И доступ к ним осуществляется аналогично.
Отсылаю вас к замечательной программе на лиспе, на которую я наткнулся однажды: http://lee-mac.com/nestedmove.html.
Посмотрите на анимацию, демонстрирующую работу программы. Все именно так и работает.
Название: Re: Выбор вложенных объектов секущей рамкой в Autocad через .NET
Отправлено: trir от 14-03-2017, 22:47:17
неа, они в разных Database
Название: Re: Выбор вложенных объектов секущей рамкой в Autocad через .NET
Отправлено: Кирилл Захаров от 14-03-2017, 22:59:25
Не буду с вами спорить
Название: Re: Выбор вложенных объектов секущей рамкой в Autocad через .NET
Отправлено: Александр Ривилис от 14-03-2017, 23:14:36
Код - C# [Выбрать]
  1.     [DllImport("accore.dll",
  2.         EntryPoint = "?setAllowDuplicateSelection@@YA?AW4ErrorStatus@Acad@@PAVAcApDocument@@E@Z",
  3.         CallingConvention = CallingConvention.Cdecl,
  4.         CharSet = CharSet.Unicode)]
  5.     public static extern Int32 setAllowDuplicateSelection32(IntPtr doc, [MarshalAs(UnmanagedType.I1)] bool bset);
  6.  
  7.     [DllImport("accore.dll",
  8.         EntryPoint = "?setAllowDuplicateSelection@@YA?AW4ErrorStatus@Acad@@PEAVAcApDocument@@E@Z",
  9.         CallingConvention = CallingConvention.Cdecl,
  10.         CharSet = CharSet.Unicode)]
  11.     public static extern Int32 setAllowDuplicateSelection64(IntPtr doc, [MarshalAs(UnmanagedType.I1)] bool bset);
  12.     public static Int32 setAllowDuplicateSelection(Document doc, bool bset)
  13.     {
  14.       if (IntPtr.Size == 8)
  15.         return setAllowDuplicateSelection64(doc.UnmanagedObject, bset);
  16.       else
  17.         return setAllowDuplicateSelection32(doc.UnmanagedObject, bset);
  18.     }
Название: Re: Выбор вложенных объектов секущей рамкой в Autocad через .NET
Отправлено: Александр Ривилис от 14-03-2017, 23:27:13
Я посмотрел что ты хочешь и понимаю, что у тебя таким образом ничего не получится. Увы. Т.е. задать точки и вызвать acedSSGet(L"_C",...) (это аналог Editor.SelectCrossingWindow в ObjectARX) и при этом получить вложенные примитивы (даже внутри одной базы, а уж тем более из Xref) нельзя. Этот метод не позволяет получить вложенные объекты. Можно только так:

Код - C# [Выбрать]
  1. using System;
  2. using Autodesk.AutoCAD.Runtime;
  3. using Autodesk.AutoCAD.ApplicationServices;
  4. using Autodesk.AutoCAD.DatabaseServices;
  5. using Autodesk.AutoCAD.Geometry;
  6. using Autodesk.AutoCAD.EditorInput;
  7. using System.Runtime.InteropServices;
  8.  
  9.  
  10. [assembly: CommandClass(typeof(Multiply_Nested_Select_Test.MyCommands))]
  11.  
  12. namespace Multiply_Nested_Select_Test
  13. {
  14.   public class MyCommands
  15.   {
  16.     [CommandMethod("SelectNestedTest", CommandFlags.Modal)]
  17.     public void MyCommand()
  18.     {
  19.       Document doc = Application.DocumentManager.MdiActiveDocument;
  20.       Editor ed = doc.Editor;
  21.       Database db = doc.Database;
  22.  
  23.       ResultBuffer resbuf = new ResultBuffer();
  24.  
  25.       string arg = "_:D:N";
  26.  
  27.       ArxImports.ads_name sset;
  28.       ed.TurnSubentityWindowSelectionOn();
  29.       ArxImports.setAllowDuplicateSelection(doc, true);
  30.       PromptStatus prGetResult = ArxImports.acedSSGet(
  31.           arg, IntPtr.Zero /* ptrPoint1 */, IntPtr.Zero /* ptrPoint2 */, resbuf.UnmanagedObject, out sset);
  32.       int len;
  33.       ArxImports.setAllowDuplicateSelection(doc, false);
  34.       ed.TurnSubentityWindowSelectionOff();
  35.       ArxImports.acedSSLength(ref sset, out len);
  36.       ed.WriteMessage("\n" + len.ToString());
  37.       /////////////////////////////////////////////////////////////////////////////
  38.     }
  39.   }
  40.   //Класс в котором задаются методы для доступа к функциям ObjectARX, который я взял из примера
  41.   class ArxImports
  42.   {
  43.     public struct ads_name
  44.     {
  45.       public IntPtr a;
  46.       public IntPtr b;
  47.     };
  48.  
  49.     [StructLayout(LayoutKind.Sequential, Size = 32)]
  50.     public struct resbuf { }
  51.  
  52.     [DllImport("accore.dll",
  53.         CallingConvention = CallingConvention.Cdecl,
  54.         CharSet = CharSet.Unicode,
  55.         ExactSpelling = true)]
  56.     public static extern PromptStatus acedSSGet(
  57.         string str, IntPtr pt1, IntPtr pt2,
  58.         IntPtr filter, out ads_name ss);
  59.  
  60.     [DllImport("accore.dll",
  61.         CallingConvention = CallingConvention.Cdecl,
  62.         CharSet = CharSet.Unicode,
  63.         ExactSpelling = true)]
  64.     public static extern PromptStatus acedSSFree(ref ads_name ss);
  65.  
  66.     [DllImport("accore.dll",
  67.         CallingConvention = CallingConvention.Cdecl,
  68.         CharSet = CharSet.Unicode,
  69.         ExactSpelling = true)]
  70.     public static extern PromptStatus acedSSLength(
  71.         ref ads_name ss, out int len);
  72.  
  73.     [DllImport("accore.dll",
  74.         CallingConvention = CallingConvention.Cdecl,
  75.         CharSet = CharSet.Unicode,
  76.         ExactSpelling = true)]
  77.     public unsafe static extern PromptStatus acedSSNameX(
  78.         resbuf** rbpp, ref ads_name ss, int i);
  79.  
  80.     [DllImport("accore.dll",
  81.         EntryPoint = "?setAllowDuplicateSelection@@YA?AW4ErrorStatus@Acad@@PAVAcApDocument@@E@Z",
  82.         CallingConvention = CallingConvention.Cdecl,
  83.         CharSet = CharSet.Unicode)]
  84.     public static extern Int32 setAllowDuplicateSelection32(IntPtr doc, [MarshalAs(UnmanagedType.I1)] bool bset);
  85.  
  86.     [DllImport("accore.dll",
  87.         EntryPoint = "?setAllowDuplicateSelection@@YA?AW4ErrorStatus@Acad@@PEAVAcApDocument@@E@Z",
  88.         CallingConvention = CallingConvention.Cdecl,
  89.         CharSet = CharSet.Unicode)]
  90.     public static extern Int32 setAllowDuplicateSelection64(IntPtr doc, [MarshalAs(UnmanagedType.I1)] bool bset);
  91.     public static Int32 setAllowDuplicateSelection(Document doc, bool bset)
  92.     {
  93.       if (IntPtr.Size == 8)
  94.         return setAllowDuplicateSelection64(doc.UnmanagedObject, bset);
  95.       else
  96.         return setAllowDuplicateSelection32(doc.UnmanagedObject, bset);
  97.     }
  98.   }
  99. }

При этом ты можешь выбирать объекты не только по одному, но и рамкой:

Название: Re: Выбор вложенных объектов секущей рамкой в Autocad через .NET
Отправлено: Кирилл Захаров от 15-03-2017, 00:14:42
Спасибо огромное, Александр!
Название: Re: Выбор вложенных объектов секущей рамкой в Autocad через .NET
Отправлено: Александр Ривилис от 15-03-2017, 00:48:52
Кирилл Захаров,
Хочешь сказать, что это тебя устраивает? Вообще-то это совсем не то, что ты спрашивал.
Название: Re: Выбор вложенных объектов секущей рамкой в Autocad через .NET
Отправлено: Кирилл Захаров от 15-03-2017, 01:40:17
Да, но я могу это использовать. С помощью добавления буквы S к строке selection mode я обеспечу чтобы пользователь мог только 1 раз либо выбрать рамкой либо одиночным кликом. Затем каким-нибудь образом проверю, что выбор сделан именно рамкой (пока не знаю как) и если выбор сделан неправильно буду возвращаться в цикле обратно.
Главная цель достигнута.
Название: Re: Выбор вложенных объектов секущей рамкой в Autocad через .NET
Отправлено: Александр Ривилис от 15-03-2017, 02:21:45
Затем каким-нибудь образом проверю, что выбор сделан именно рамкой (пока не знаю как) и если выбор сделан неправильно буду возвращаться в цикле обратно.
Узнать каким образом был сделан выбор можно используя данные acedSSNameX. Посмотри её описание в документации ObjectARX SDK.
Название: Re: Выбор вложенных объектов секущей рамкой в Autocad через .NET
Отправлено: Александр Ривилис от 15-03-2017, 02:41:22
Кстати, оттуда же ты можешь узнать и указанные пользователем угловые точки рамки.
Название: Re: Выбор вложенных объектов секущей рамкой в Autocad через .NET
Отправлено: Кирилл Захаров от 15-03-2017, 07:16:11
Еще раз благодарю вас, рыцарь ObjectARX :)
Название: Re: Выбор вложенных объектов секущей рамкой в Autocad через .NET
Отправлено: Кирилл Захаров от 16-03-2017, 16:56:36
К сожалению обнаружил, что при большом количестве выбираемых объектов во внешних ссылках выполнение метода ArxImports.acedSSGet происходит очень очень медленно. Я думаю, что это из-за того, что объекты в наборе очень много раз дублируются. Возможно причина не в этом?

Попробовал применить фильтр выбора. Например, такой:
Код - C# [Выбрать]
  1.  ResultBuffer resbuf = new ResultBuffer
  2.                 (
  3.                     new TypedValue(-4, "<and"),
  4.                     new TypedValue(0, "INSERT"),
  5.                     new TypedValue(8, "0"),
  6.                     new TypedValue(-4, "and>")
  7.                 );
  8.  
Пробовал и другие.
Но при этом все равно выбираются все объекты, попадающие в рамку. То есть фильтр полностью игнорируется. Что я делаю не так?
Название: Re: Выбор вложенных объектов секущей рамкой в Autocad через .NET
Отправлено: Александр Ривилис от 16-03-2017, 17:11:03
Я думаю, что это из-за того, что объекты в наборе очень много раз дублируются. Возможно причина не в этом?
Думаю что не в этом, а в сложности выбора.

Попробовал применить фильтр выбора. Например, такой:

На скорость выбора это скорее всего не повлияет.
Что касается фильтра, то попробуй такой:
Код - C# [Выбрать]
  1. ResultBuffer resbuf = new ResultBuffer
  2.                 (
  3.                     new TypedValue(0, "INSERT"),
  4.                     new TypedValue(8, "0"),
  5.                 );

Название: Re: Выбор вложенных объектов секущей рамкой в Autocad через .NET
Отправлено: Александр Ривилис от 16-03-2017, 17:22:57
Хотя вероятно для вложенных объектов этот фильтр не работает. Сейчас нет возможности проверить.
Название: Re: Выбор вложенных объектов секущей рамкой в Autocad через .NET
Отправлено: Кирилл Захаров от 16-03-2017, 17:34:19
Да, действительно. Вложенные объекты не фильтруются. В этом дело. Отбираются только сами внешние ссылки.
Название: Re: Выбор вложенных объектов секущей рамкой в Autocad через .NET
Отправлено: Кирилл Захаров от 16-03-2017, 17:38:16
Ладно, видимо мне придется отказаться от использования этого метода. Тем не менее, это было интересно.
Название: Re: Выбор вложенных объектов секущей рамкой в Autocad через .NET
Отправлено: Кирилл Захаров от 22-03-2017, 15:53:42
А в результате, что должно получится?

Хочу немного похвастаться, а заодно и поделиться опытом. У меня получилось сделать достаточно производительную программу, которая выбирает объекты внешних ссылок, но при этом все внешние ссылки имеют точку вставки 0,0,0, не повернуты и не отмасштабированы (то есть пересчет координат не требуется).
За основу я брал идею из темы на форуме swamp: http://www.theswamp.org/index.php?topic=27786.0. Там смысл в том, что если рамка выбора указывается при ортогональном виде сверху (ну то есть север наверху), то квадраты Extents искомых объектов либо полностью находятся внутри рамки выбора, либо проекции этих объектов на плоскость X0Y пересекают рамку выбора. А получить Extents всех объектов можно сплошным перебором.



Надеюсь, кому-то будет полезно ;)

Название: Re: Выбор вложенных объектов секущей рамкой в Autocad через .NET
Отправлено: Lemieux от 14-06-2022, 21:47:06
CommandFlags.Modal
А как получать выбранные объекты?
Название: Re: Выбор вложенных объектов секущей рамкой в Autocad через .NET
Отправлено: Александр Ривилис от 14-06-2022, 21:54:08
Lemieux,
Не понял вопроса.
Название: Re: Выбор вложенных объектов секущей рамкой в Autocad через .NET
Отправлено: Lemieux от 14-06-2022, 21:55:50
Lemieux,
Не понял вопроса.
Я не стал цитировать полностью ответ с решением (https://adn-cis.org/forum/index.php?topic=7683.msg25135#msg25135). Но мне не понятно как из функции acedSSGet получать объекты, которые выделил. Я пробовал по имени сета, но не получилось.
Название: Re: Выбор вложенных объектов секущей рамкой в Autocad через .NET
Отправлено: Александр Ривилис от 14-06-2022, 23:00:47
acedSSName/acedSSNameX тебе в помощь. Смотри описание в ObjectARX SDK.
Пример использования есть здесь: https://www.theswamp.org/index.php?topic=41569.0
Название: Re: Выбор вложенных объектов секущей рамкой в Autocad через .NET
Отправлено: Lemieux от 14-06-2022, 23:02:38
Смотри описание в ObjectARX SDK.
Я уже смотрел, но я просто не понимаю как всё это работает. Стыдно конечно.
Название: Re: Выбор вложенных объектов секущей рамкой в Autocad через .NET
Отправлено: Александр Ривилис от 14-06-2022, 23:05:29
Смотри описание в ObjectARX SDK.
Я уже смотрел, но я просто не понимаю как всё это работает. Стыдно конечно.
Пример использования есть здесь: https://www.theswamp.org/index.php?topic=41569.0
А все это растет отсюда: https://adndevblog.typepad.com/autocad/2012/04/retrieving-nested-entities-under-cursor-aperture-using-net-api.html
Название: Re: Выбор вложенных объектов секущей рамкой в Autocad через .NET
Отправлено: Lemieux от 14-06-2022, 23:30:43
Смотри описание в ObjectARX SDK.
Я уже смотрел, но я просто не понимаю как всё это работает. Стыдно конечно.
Пример использования есть здесь: https://www.theswamp.org/index.php?topic=41569.0
А все это растет отсюда: https://adndevblog.typepad.com/autocad/2012/04/retrieving-nested-entities-under-cursor-aperture-using-net-api.html
Спасибо, разобрался, но чувствую себя обезьяной. Что-то делаю, получается, но не понимаю, что за магия.
Название: Re: Выбор вложенных объектов секущей рамкой в Autocad через .NET
Отправлено: Александр Ривилис от 14-06-2022, 23:35:50
Спасибо, разобрался, но чувствую себя обезьяной. Что-то делаю, получается, но не понимаю, что за магия.
Это естественно, так ты начал программировать под AutoCAD с AutoCAD .NET API, которое есть только обертка над частью классов и функций ObjectARX. Поэтому если чего-то не хватает в AutoCAD .NET API приходится использовать P/Invoke для функций ObjectARX, если это возможно. И требуется разбираться как это работает в ObjectARX. Если бы ты начинал сразу с ObjectARX, то было бы конечно проще...
Название: Re: Выбор вложенных объектов секущей рамкой в Autocad через .NET
Отправлено: Lemieux от 16-06-2022, 07:54:35
А я правильно понимаю, что в AutoLisp есть аналог этой функции (ssget), а в .NET нет?
Название: Re: Выбор вложенных объектов секущей рамкой в Autocad через .NET
Отправлено: Александр Ривилис от 16-06-2022, 10:45:38
А я правильно понимаю, что в AutoLisp есть аналог этой функции (ssget), а в .NET нет?
Да. Но в Autolisp не полный аналог. Часть возможностей не поддерживается. Поэтому наиболее полные возможности именно в ObjectARX.
Название: Re: Выбор вложенных объектов секущей рамкой в Autocad через .NET
Отправлено: Lemieux от 24-06-2022, 16:05:26
А почему данный код может начать лагать через некоторые время, если много раз выделять и создавать примитивы?
Название: Re: Выбор вложенных объектов секущей рамкой в Autocad через .NET
Отправлено: Александр Ривилис от 24-06-2022, 19:18:10
А почему данный код может начать лагать через некоторые время, если много раз выделять и создавать примитивы?
Данный код - это какой? Причин может быть множество - это и баг в AutoCAD и баг в коде...
Название: Re: Выбор вложенных объектов секущей рамкой в Autocad через .NET
Отправлено: Lemieux от 24-06-2022, 19:53:29
А почему данный код может начать лагать через некоторые время, если много раз выделять и создавать примитивы?
Данный код - это какой? Причин может быть множество - это и баг в AutoCAD и баг в коде...
Вот этот https://adn-cis.org/forum/index.php?topic=10781.msg51298#msg51298
Но у меня на работе компьютер с 4 ГБ оперативной памяти и видеокарта NVidia 230, а дома с 16 и видеокарта GTX1080. И вот дома всё нормально работает.
В VS посмотрел выделение памяти, вроде память не плавает.
А лагает, когда вызывается метод acedSSGet. При нормальной работе примитив под курсором или рамкой подсвечивается сразу, а тут этот визуальный эффект происходит с задержкой. И последующее построение примитивов (точнее прорисовка на экране) происходит медленно.
Буду дальше вести наблюдение.