программный выбор рамкой

Автор Тема: программный выбор рамкой  (Прочитано 13308 раз)

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

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: программный выбор рамкой
« Ответ #15 : 21-12-2017, 17:16:27 »
Не забывай, что точка вообще очень хитрый и нестандартный примитив, у которой обычно размер зависит от масштаба изображения.
Мой тебе совет - прекрати играться с acedSSGet со всеми опциями в видимой области. Никакой стабильности не будет. Особенно в больших координатах (как у тебя). Думаю, что R-Tree в твоём случае могло бы помочь.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: программный выбор рамкой
« Ответ #16 : 21-12-2017, 18:01:59 »
итого в сухом остатке. RTERROR - это нормальный ответ функции acedSSGet (чисто моё умозаключение. в хелпе вообще этот вопрос обошли стороной), если она ничего не находит
Это для меня вполне очевидно. Я думал, что для тебя тоже, хотя смотрел на вот эти "пассажи" с недоумением:

Код - C++ [Выбрать]
  1. //-> выборка по первой точке
  2. Adesk::Int32 len = 0L;
  3. int res = acedSSLength(ent1, &len);
  4. if (res != RTNORM || len == 0)  ////// <- тут то чего ловить????
  5. {// возможно объект 1 а не несколько
  6.  
  7.         if (acdbGetObjectId(eId, ent1) == Acad::eOk)
  8.         {// а вдруг в выборке все-таки есть 1 объект
  9.                 if (!eId.isNull())
  10.                 {//объект есть
  11.                         if (!resIds.contains(eId)) // проверяем нет ли его уже в нашем выходном массиве
  12.                                 resIds.append(eId);
  13.                 }
  14.         }
  15. }
  16. else
  17. {
  18.         for (int i = 0; i < len; i++)
  19.         {
  20.                 if (ads_ssname(ent1, i, one_ent) != RTNORM)continue;
  21.                 if (acdbGetObjectId(eId, one_ent) != Acad::eOk)continue;
  22.                 if (!eId.isNull())
  23.                 {
  24.                         if (!resIds.contains(eId)) // проверяем нет ли его уже в нашем выходном массиве
  25.                                 resIds.append(eId);
  26.                 }
  27.         }
  28. }
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Николай ГорловАвтор темы

  • ADN
  • *
  • Сообщений: 238
  • Карма: 34
Re: программный выбор рамкой
« Ответ #17 : 22-12-2017, 11:33:29 »
Цитировать
Я думал, что для тебя тоже, хотя смотрел на вот эти "пассажи" с недоумением
та дално, знакомьтесь, это затычка :):):). и там проверяется возврат не acedSSGet, а acedSSLength. в каких-то старых автокадах была проблема, если в выборку (ну например был вызов ssget для выбора рамкой любых объектов, и пользователь выбирал не рамкой, а просто ткнул в один объект и успокоился) попадал 1 объект, то начинались чудеса. в современных версиях не проверял, но спокойней, когда эта затычка есть. в лучшем случае внутрь программа никогда не зайдет :)

Не забывай, что точка вообще очень хитрый и нестандартный примитив, у которой обычно размер зависит от масштаба изображения.
а это тут при чем? я на вход подаю две точки рамки (XYZ а не AcDbPoint) и этой рамкой, с жестко мной заданными точками ищу захват куска отрезка рамкой. а сама рамка каким-то хитрожо странным образом увеличивается в размерах, что позволяет получить вхождение куска отрезка в контур большее количество раз (а не только тем точкам, рамки которых в действительности могут захватить отрезок)

объясню на примере.
пусть строю рамку 1x1 вокруг точки (0,0). и я хочу получить все объекты, которые попадают в контур({-1,-1},{-1,1},{1,1},{1,-1},{-1,-1}). есть отрезок, проходящий через координату (10,10). так вот в зависимости от масштаба отображения моя рамка способна захватить этот отрезок. я не знаю, что они там употребляют, но я тоже такое хочу :):):)
и так работает опция "_C". путем умозаключений можно предположить, что опция "_W" работает так же (не проверял).

опция "_CP" работает правильно только в том случае, если extents базы включает в себя максимально возможные координаты будущей отрисовки. и это я проверил лично. вчера вечером программно увеличил extents базы текущего (нового) чертежа программно перед рисованием, выставил вид по extents тоже программно (не командой автокада а кодом на С++) а потом нарисовал точки в пустом чертеже. итого 5м 25с.
то же самое рисование занимает полторы минуты если объект есть ФИЗИЧЕСКИ по координатам, где будет проходить поиск рамкой.
вот не похоже это на "ожидаемое поведение", даже с учетом запрещенных препаратов :)

PS: может автодеск напрячь ))) 3 года уже не напрягал )))

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: программный выбор рамкой
« Ответ #18 : 22-12-2017, 12:38:55 »
в лучшем случае внутрь программа никогда не зайдет :)
Как раз таки зайдёт и почему-то будет считать, что ent1 это не набор, а отдельный примитив.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Николай ГорловАвтор темы

  • ADN
  • *
  • Сообщений: 238
  • Карма: 34
Re: программный выбор рамкой
« Ответ #19 : 22-12-2017, 16:08:53 »
Как раз таки зайдёт и почему-то будет считать, что ent1 это не набор, а отдельный примитив.
:) убрал вообще, чтоб не смущать. в конкретном случае пользы от этой затычки нет, т.к. пользователя лишили возможности тыкать по экрану. "не заходит" - это я имел ввиду, что в resIds не добавляется. ну да ладно.

по поводу R-Tree. это оно? https://ru.wikipedia.org/wiki/R-%D0%B4%D0%B5%D1%80%D0%B5%D0%B2%D0%BE_(%D1%81%D1%82%D1%80%D1%83%D0%BA%D1%82%D1%83%D1%80%D0%B0_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85) тануна ))), для команды, которая всего-то затягивает точки из текстового файла по координатам - это круто. тем более, что для формирования дерева мне все-равно нужен один пробег по БД. Уж лучше тогда std::map использовать. так сказать, дешево и сердито. но хочется использовать автокад хотя б для таких простых заданий. а то получается, что объемы посчитать внутри 3D сетей - автокад не тянет, т.к. сети создает криво (сам создал, сам сказал что кривая и в расчет ее брать нельзя), объекты выбрать - тоже не к нему, блоки между чертежами тягать - лучше своими методами а не командами автокада...


так что вот новый вариант тестового проекта со всеми изменениями. даже на английский перевел :) на всякий случай :):):)

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: программный выбор рамкой
« Ответ #20 : 22-12-2017, 18:12:37 »
что для формирования дерева мне все-равно нужен один пробег по БД.
Он у тебя займёт максимум несколько секунд. А на том файле, что ты генерировал в предыдущей версии программы, доли секунды.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение