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

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

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

Тема содержит сообщение с Решением. Нажмите здесь чтобы посмотреть его.

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 738
Здравствуйте!
Столкнулся со странным поведением метода - возвращает PromptStatus.Error. Количество точек, правда, зашкаливает - больше тысячи. Может ли это быть причиной того, что метод не хочет работать? Есть ли какое-то ограничение у него на количество точек?

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

  • Administrator
  • *****
  • Сообщений: 13898
  • Карма: 1790
  • Рыцарь ObjectARX
  • Skype: rivilis
Количество точек, правда, зашкаливает - больше тысячи. Может ли это быть причиной того, что метод не хочет работать? Есть ли какое-то ограничение у него на количество точек?
Официально точно никаких ограничений нет. Я бы предположил самопересечение контура (или касание его ребер).
P.S.: Надеюсь, что ты проверил, что все точки полигона в видимой области AutoCAD, так как PromptStatus.Error означает, что ничего не выбрано.
Можно еще попробовать проанализировать системную переменную ERRNO.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 738
Хм, а точек даже меньше тысячи...
Прикладываю контур.

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

  • ADN Club
  • *****
  • Сообщений: 554
  • Карма: 119
Прикладываю контур.
1. Как был получен контур? У тебя участки(сегменты) между вершинами не прямолинейные. см. между 1 и 2 вершиной еще одна точка лежащая на дуге ;-)
1.1 Возможно SelectCrossingPolygon не любит радиусы вообще.
1.2 Радиусы сегментов похоже заданы не корректно, pltools пишет радиус 25900 не знаю каких единиц.
2. Ну и на всякий случай проверь, что зуммирование экрана сработало как надо, перед вызовом Editor.SelectCrossingPolygon.

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 738
Контур построен с помощью оффсета от трассы проектируемой дороги или сети.
Конечно же кривые не любит. Он зараза такая вообще про них не в курсе - только коллекцию точек принимает :).
С радиусами там всё верно. При таком радиусе кривая становится почти прямой, что и наблюдается местами.
Я из этого контура вытягиваю коллекцию вершин и передаю в метод.
На самом деле, задачу уже решил с помощью PLTools - упростил, спрямил, прополол. В итоге с 390 точками метод справился. Теперь остался только спортивный интерес - почему этот исходный контур не обработался?

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

  • ADN Club
  • *****
  • Сообщений: 554
  • Карма: 119
Я из этого контура вытягиваю коллекцию вершин и передаю в метод.
Возможно тебе нужно добавить замыкающую вершину, т.к. полилиния была замкнута, а ты передаешь массив вершин, и получаешь разрыв контура. Т.е. в конце массива добавить точку с координатами 1й точки.

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 738
Я понял. Пример кода - лучше тысячи слов! :)
В приложенном файле чёрный контур - исходный, красный - полученный из исходного преобразованием дуг в прямые. Оба выдают ошибку с кодом 2: Invalid entity or selection set name.
Код - C# [Выбрать]
  1. [CommandMethod("TestCrossingPolygonSelection")]
  2. public void TestCrossingPolygonSelectionCmd()
  3. {
  4.     Document adoc = Application.DocumentManager.MdiActiveDocument;
  5.     Editor ed = adoc.Editor;
  6.  
  7.     PromptEntityOptions plineOpt = new PromptEntityOptions
  8.         ("\nВыберите полилинию-контур: ");
  9.  
  10.     plineOpt.SetRejectMessage("\nЭто не полилиния!");
  11.     plineOpt.AddAllowedClass(typeof(Polyline), true);
  12.     PromptEntityResult plineRes = ed.GetEntity(plineOpt);
  13.     if (plineRes.Status != PromptStatus.OK) return;
  14.  
  15.     Point3dCollection pts = new Point3dCollection();
  16.  
  17. #pragma warning disable CS0618 // Type or member is obsolete
  18.     using (Polyline pline = plineRes.ObjectId.Open(OpenMode.ForRead) as Polyline)
  19. #pragma warning restore CS0618 // Type or member is obsolete
  20.     {
  21.         for (int i = 0; i < pline.NumberOfVertices; i++)
  22.         {
  23.             pts.Add(pline.GetPoint3dAt(i));
  24.         }
  25.     }
  26.  
  27.     if (!pts[0].IsEqualTo(pts[pts.Count - 1]))
  28.     {
  29.         pts.Add(pts[0]);
  30.     }
  31.  
  32.     PromptSelectionResult selRes = ed.SelectCrossingPolygon(pts);
  33.     if (selRes.Status == PromptStatus.Error)
  34.     {
  35.         short code = (short)Application.GetSystemVariable("ERRNO");
  36.         Application.ShowAlertDialog($"Ошибка: {code}");
  37.         return;
  38.     }
  39. }
  40.  

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

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

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

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

чет типа такого, перед вызовом SelectCrossingPolygon и аналогичных методов из Editor
иначе он возвращает ошибку:

Код - C# [Выбрать]
  1. //Зуммирование вида
  2. Point2d min2d = new Point2d(MinX, MinY);
  3. Point2d max2d = new Point2d(MaxX, MaxY);
  4. ViewTableRecord view = new ViewTableRecord();
  5. view.CenterPoint = min2d + ((max2d - min2d) / 2.0);
  6. view.Height = max2d.Y - min2d.Y;
  7. view.Width = max2d.X - min2d.X;
  8. ed.SetCurrentView(view);

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 738
В боевом коде есть. В тестовом - это лишнее нагромождение. Можно же просто зуммировать перед запуском команды. Тут дело 100% не в зуме.

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 738
Я бы предположил самопересечение контура (или касание его ребер).
Всё, нашел - была одна совпадающая вершина. Вы оказались правы.

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

  • Administrator
  • *****
  • Сообщений: 13898
  • Карма: 1790
  • Рыцарь ObjectARX
  • Skype: rivilis
Я бы предположил самопересечение контура (или касание его ребер).
Всё, нашел - была одна совпадающая вершина. Вы оказались правы.
Я уже как раз начинал тестировать, но ты успел раньше. :) Кстати, в AutoCAD 2020, на котором я начал тестировать, при selRes.Status == PromptStatus.Error системная переменная ERRNO остаётся равной 0, что не есть хорошо...
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN Club
  • *****
  • Сообщений: 554
  • Карма: 119
Кстати, в AutoCAD 2020, на котором я начал тестировать
Ну хот в кратце, по секрету можно нам рассказать. Значимые изменения будут от 2019?

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

  • Administrator
  • *****
  • Сообщений: 13898
  • Карма: 1790
  • Рыцарь ObjectARX
  • Skype: rivilis
Кстати, в AutoCAD 2020, на котором я начал тестировать
Ну хот в кратце, по секрету можно нам рассказать. Значимые изменения будут от 2019?
Эта версия уже официально вышла и уже есть её анонсы. Например, в первую очередь для программистов, здесь: https://adndevblog.typepad.com/autocad/2019/03/autocad-2020-quick-overview.html
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 738
Хм... Прошу прощения, ошибся. Не помогла "прополка". У меня в окошке стало появляться "Ошибка: 0". Я посмотрел коды ошибок - No Error. Обрадовался и решил что всё ОК. А то что
Код - C# [Выбрать]
  1. selRes.Status == PromptStatus.Error
как-то упустил из виду на радостях. Тесты показали, что просто сперва возвращается ERRNO = 2, а на третьем-четвёртом запуске и далее после обработки полилинии командой PL-VxOpt из PLTools - ERRNO = 0. Причём, обработана только одна полилиния, а ERRNO = 0 выдаёт на обеих. Такое поведение в Civil 3D as AutoCAD 2017. Может быть Вы как раз это наблюдали в AutoCAD 2020?

Иногда, кстати, вместо "Ошибка: 2" выводится "Ошибка: 93" - такого кода вообще нет в списке! Но воспроизвести при записи видео не получилось.