Ограничение на количество точек полигона для метода Editor.SelectCrossingPolygon

Автор Тема: Ограничение на количество точек полигона для метода Editor.SelectCrossingPolygon  (Прочитано 19551 раз)

0 Пользователей и 5 Гостей просматривают эту тему.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13898
  • Карма: 1790
  • Рыцарь ObjectARX
  • Skype: rivilis
Не помогла "прополка".
Жаль.
Тесты показали, что просто сперва возвращается ERRNO = 2, а на третьем-четвёртом запуске и далее - ERRNO = 0. Такое поведение в Civil 3D as AutoCAD 2017. Может быть Вы как раз это наблюдали в AutoCAD 2020?
Нет. У меня уже при первом запуске. Что я тебе могу посоветовать? Никогда не пользоваться Editor.SelectXXX методами. Причин почему на данном контуре не срабатывает выборка может быть множество. Одна из причин как ни странно может быть связана с разрешением экрана AutoCAD. Как работают все эти методы Editor.SelectXXX? Они работают с проекциями примитивов на некий виртуальный экран. В твоём случае вполне возможно, что в проекции начинают совпадать вершины контура выбора. Еще одна возможная причина - удалённость вершин контура от начала координат.
В данном случае вершина с номером 88 отстоит от соседней на 0.00003, что явно маловато при шестизначных значениях координат.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Отмечено как Решение Дмитрий Загорулькин 02-04-2019, 16:52:14

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13898
  • Карма: 1790
  • Рыцарь ObjectARX
  • Skype: rivilis
Дмитрий Загорулькин,
Попробуй такой вариант:
Код - 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.  
  8. // This line is not mandatory, but improves loading performances
  9. [assembly: CommandClass(typeof(TestSelectCP.MyCommands))]
  10.  
  11. namespace TestSelectCP
  12. {
  13.   public class MyCommands
  14.   {
  15.     const double FUZZ = 0.1;
  16.     [CommandMethod("TestCrossingPolygonSelection")]
  17.     public void TestCrossingPolygonSelectionCmd()
  18.     {
  19.       Document adoc = Application.DocumentManager.MdiActiveDocument;
  20.       Editor ed = adoc.Editor;
  21.  
  22.       PromptEntityOptions plineOpt = new PromptEntityOptions
  23.           ("\nВыберите полилинию-контур: ");
  24.  
  25.       plineOpt.SetRejectMessage("\nЭто не полилиния!");
  26.       plineOpt.AddAllowedClass(typeof(Polyline), true);
  27.       PromptEntityResult plineRes = ed.GetEntity(plineOpt);
  28.       if (plineRes.Status != PromptStatus.OK) return;
  29.  
  30.       Point3dCollection pts = new Point3dCollection();
  31.  
  32. #pragma warning disable CS0618 // Type or member is obsolete
  33.       using (Polyline pline = plineRes.ObjectId.Open(OpenMode.ForRead) as Polyline)
  34. #pragma warning restore CS0618 // Type or member is obsolete
  35.       {
  36.         for (int i = 0; i < pline.NumberOfVertices; i++)
  37.         {
  38.           Point3d p = pline.GetPoint3dAt(i);
  39.           // if (i == 0 || pts[i-1].DistanceTo(p) >= FUZZ) <--- Исправлено по наводке Дмитрия Загорулькина
  40.           if (pts.Count == 0 || pts[pts.Count-1].DistanceTo(p) >= FUZZ)
  41.             pts.Add(p);
  42.         }
  43.       }
  44.       // Повторять последнюю точку не нужно!!!
  45.  
  46.       if (pts[0].DistanceTo(pts[pts.Count - 1]) < FUZZ)
  47.       {
  48.         pts.RemoveAt(pts.Count - 1);
  49.       }
  50.  
  51.       //double dist = 1e+32;
  52.       //int iMindist = -1;
  53.       //for (int i = 0; i < pts.Count; i++)
  54.       //{
  55.       //  double dist1 = pts[i].DistanceTo(pts[(i + 1) % pts.Count]);
  56.       //  if (dist1 < dist) {
  57.       //    dist = dist1; iMindist = i;
  58.       //  }
  59.       //}
  60.       //ed.WriteMessage($"\ndist={dist} iMindist={iMindist}");
  61.       PromptSelectionResult selRes = ed.SelectCrossingPolygon (pts);
  62.       if (selRes.Status == PromptStatus.Error)
  63.       {
  64.         short code = (short)Application.GetSystemVariable("ERRNO");
  65.         Application.ShowAlertDialog($"Ошибка: {code}");
  66.         return;
  67.       }
  68.     }
  69.   }
  70.  
  71. }
  72.  
У меня он работает безошибочно на твоих полилиниях.
« Последнее редактирование: 02-04-2019, 16:40:53 от Александр Ривилис »
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13898
  • Карма: 1790
  • Рыцарь ObjectARX
  • Skype: rivilis
Иногда, кстати, вместо "Ошибка: 2" выводится "Ошибка: 93" - такого кода вообще нет в списке! Но воспроизвести при записи видео не получилось.
Код такой есть, но что он в данном случае значит - большой вопрос:
Код - C++ [Выбрать]
  1. #define  OL_EBADTYPE   93  /* Bad value type */
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Привалов Дмитрий

  • ADN Club
  • *****
  • Сообщений: 554
  • Карма: 119
Количество точек, правда, зашкаливает - больше тысячи. Может ли это быть причиной того, что метод не хочет работать?

Они работают с проекциями примитивов на некий виртуальный экран. В твоём случае вполне возможно, что в проекции начинают совпадать вершины контура выбора.

Очевидно это и есть ответ. Жаль, метод оказался еще менее надежным, чем предполагалось.
Мне вот стало интересно, а зачем вообще было эти методы реализовывать через проекции? Не понимаю плюсов такого решения.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13898
  • Карма: 1790
  • Рыцарь ObjectARX
  • Skype: rivilis
Мне вот стало интересно, а зачем вообще было эти методы реализовывать через проекции? Не понимаю плюсов такого решения.
Всё упирается в скорость выбора.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Привалов Дмитрий

  • ADN Club
  • *****
  • Сообщений: 554
  • Карма: 119
Всё упирается в скорость выбора.
Ну ладно выбираемые примитивы в пределах экрана спроецировали, но зачем понадобилось контур выбора проецировать и проверять что в него попало? Это ведь действительно накладывает ограничение на контур.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13898
  • Карма: 1790
  • Рыцарь ObjectARX
  • Skype: rivilis
но зачем понадобилось контур выбора проецировать и проверять что в него попало
Странный вопрос. Предложи другой вариант.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Привалов Дмитрий

  • ADN Club
  • *****
  • Сообщений: 554
  • Карма: 119
Странный вопрос. Предложи другой вариант.
Ну насколько я понял действительно спроецированные объекты получить быстрее. При этом насколько я помню, если объекты не совпадают по Z c контуром, то в эту выборку не попадут.
Проецировали бы не в экранную плоскость, а в плоскость контура, без пересчета его координат.

Оффлайн Дмитрий ЗагорулькинАвтор темы

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 738
У меня он работает безошибочно на твоих полилиниях.
Это странно - у Вас в коде в 39 строке ошибка логическая. Догадаетесь, что за ошибка? :)

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13898
  • Карма: 1790
  • Рыцарь ObjectARX
  • Skype: rivilis
Ну насколько я понял действительно спроецированные объекты получить быстрее.
Они уже спроецированы, а не в момент вызова Editor.SelectXXX. Быстрота не в их получении, а в скорости фильтрации спроецированных объектов. Как минимум мы перешли из 3D в 2D.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13898
  • Карма: 1790
  • Рыцарь ObjectARX
  • Skype: rivilis
Это странно - у Вас в коде в 39 строке ошибка логическая. Догадаетесь, что за ошибка? :)
Да. Вместо:
Код - C# [Выбрать]
  1. if (i == 0 || pts[i-1].DistanceTo(p) >= FUZZ)
должно быть:
Код - C# [Выбрать]
  1. if (pts.Count == 0 || pts[i-1].DistanceTo(p) >= FUZZ)
Но в данном случае сработало.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий ЗагорулькинАвтор темы

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 738

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13898
  • Карма: 1790
  • Рыцарь ObjectARX
  • Skype: rivilis
Очень тепло, но нет! :)
Ну видимо я сегодня плохо соображаю. Объясни.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Привалов Дмитрий

  • ADN Club
  • *****
  • Сообщений: 554
  • Карма: 119
Они уже спроецированы, а не в момент вызова Editor.SelectXXX. Быстрота не в их получении, а в скорости фильтрации спроецированных объектов. Как минимум мы перешли из 3D в 2D.
А ну ладно. Теперь стала понятнее внутрянка их работы и возможные ограничения.
Возможно разработчиков Civil 3D эти функции не устроили и они написали свои. Есть на это шанс?

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13898
  • Карма: 1790
  • Рыцарь ObjectARX
  • Skype: rivilis
Есть на это шанс?
Нет. Но никто тебе не мешает написать самому. Civil 3d (а точнее Map 3d) использует ObjectARX и AutoCAD .NET API.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение