вопрос по сортировке отрисовки объектов с помощью AcDbSortentsTable

Автор Тема: вопрос по сортировке отрисовки объектов с помощью AcDbSortentsTable  (Прочитано 7538 раз)

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

Оффлайн begizАвтор темы

  • ADN Club
  • ***
  • Сообщений: 161
  • Карма: 8
  • Skype: begiz_i
Добрый день
появилась интересная задачка, с которой уже несколько дней не могу стравится

есть чертеж в котором на 2 слоях расположены объекты типа(строго) AcDbLine
эти объекты пересекаются произвольным образом, т.е. каждая линия может пересекать любое количество других линий

задача по определенной логике отрисовать эти линии в нужной последовательности. принцип логики определения последовательности не важен
на данный момент программа определеяет пересечения 2-х линий в точке и правельно их отрисовывает путем moveAbove/moveBelow

проблема в том что этих пересечений очень много, и поэтому возникло желание собрать всю последовательность в единый массив и за 1 раз их перерисовать через setRelativeDrawOrder
вот собстенно собрать всё в 1 массив и не получается,
потому что, как писал выше, на данный момент данные у меня только на точки пересечения 2 линий и об остальных пересечениях я как бы не знаю.
но так как линии могут пересекаться с лубым количеством других линий, то при добавлении очередной пары линий в массив, может получится что они уже там есть, и можно как то пересортировать его чтобы последовательность не нарушилась

Может ктото сталкивался или может направить как правельно этот вопрос решать?

Отмечено как Решение begiz 09-04-2021, 07:32:53

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
begiz,
Я вижу такую схему:
1) При помощи getRelativeDrawOrder получаешь массив AcDbObjectId всего что есть в блоке в том порядке, в котором они есть.
2) Двойной цикл по всем элементам этого массива - сравнение отрезков и swap каждой пары из в массива если не упорядочены.
3) setRelativeDrawOrder
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Альтернативный вариант:
Создать структуру вида
Код - C++ [Выбрать]
  1. struct  IDPP {
  2.  AcDbObjectId id;
  3.  AcGePoint3d p1, p2;
  4. }
  5. std::vector<IDPP> idpp;
Пройтись по всем отрезкам в блоке и заполнить массив idpp. После этого сортировка (std::sort) с твоей функцией сравнения.
Далее цикл по уже отсортированному idpp для создания AcDbObjectIdArray, используемого в  setRelativeDrawOrder
P.S.: Если в функции сравнения еще используется слой, то это придётся отразить в структуре IDPP.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн begizАвтор темы

  • ADN Club
  • ***
  • Сообщений: 161
  • Карма: 8
  • Skype: begiz_i
всё гениально и просто, спасибо Александр
попробовал 1 вариант.
с 1 прогоном по двоиному циклу не получилось, добавил еще 1 внешний для проверки были ли перестановки и за несколько раз сортировка получилась правельной.
вопрос насчет оптимальности, проверю на большом чертеже

Код - C++ [Выбрать]
  1. bool changes = true;
  2. while (changes)
  3. {
  4.         changes = false;
  5.         for (int i = 0; i < idArray.length(); i++)
  6.         {
  7.                 for (int j = 0; j < idArray.length(); j++)
  8.                 {
  9.                         if (i == j)
  10.                                 continue;
  11.                         if (needSwitchDrawOrder(idArray[i],idArray[j])) //страшная логика
  12.                         {
  13.                                 idArray.swap(i,j);
  14.                                 changes = true;  
  15.                         }
  16.                 }
  17.         }
  18. }
  19.  

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
begiz,
Вместо
Код - C++ [Выбрать]
  1. for (int j = 0; j < idArray.length(); j++)
должно быть
Код - C++ [Выбрать]
  1. for (int j = i + 1; j < idArray.length(); j++)
Если требуется еще и внешний цикл, то его не следует делать бесконечным. Я не знаю какае у тебя критерии для перестановки, но не исключаю, что в какой-то ситуации выхода из внешнего цикла не будет.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение