GetBoundingBox в некоторых случаях возвращает неверные значения

Автор Тема: GetBoundingBox в некоторых случаях возвращает неверные значения  (Прочитано 2999 раз)

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

Оффлайн Алексей КуликАвтор темы

  • Administrator
  • *****
  • Сообщений: 773
  • Карма: 121
Доброго всем. Прислали тут файлик, в нем 3 твердых тела (во вложении). Первым было создано с цветом 1, остальные получены копированием и поворотом. Пытаюсь для каждого получить BoundingBox следующим кодом (писал "на коленке", так что приношу извинения за качество кода):
Код - Auto/Visual Lisp [Выбрать]
  1. (vl-load-com)
  2.  
  3. (defun tt (/ selset obj minp maxp err)
  4.   (if (vl-catch-all-error-p
  5.         (setq err (vl-catch-all-apply
  6.                     (function
  7.                       (lambda ()
  8.                         (if (= (type (setq selset (vl-catch-all-apply
  9.                                                     (function
  10.                                                       (lambda ()
  11.                                                         (ssget)
  12.                                                         ) ;_ end of lambda
  13.                                                       ) ;_ end of function
  14.                                                     ) ;_ end of vl-catch-all-apply
  15.                                            ) ;_ end of setq
  16.                                      ) ;_ end of type
  17.                                'pickset
  18.                                ) ;_ end of =
  19.                           (progn
  20.                             (setq selset (apply (function append)
  21.                                                 (mapcar
  22.                                                   (function
  23.                                                     (lambda (x / _min _max)
  24.                                                       (vla-getboundingbox (vlax-ename->vla-object x) '_min '_max)
  25.                                                       (mapcar (function vlax-safearray->list) (list _min _max))
  26.                                                       ) ;_ end of lambda
  27.                                                     ) ;_ end of function
  28.                                                   ((lambda (/ tab item)
  29.                                                      (repeat (setq tab  nil
  30.                                                                    item (sslength selset)
  31.                                                                    ) ;_ end setq
  32.                                                        (setq tab (cons (ssname selset (setq item (1- item))) tab))
  33.                                                        ) ;_ end of repeat
  34.                                                      tab
  35.                                                      ) ;_ end of lambda
  36.                                                    )
  37.                                                   ) ;_ end of mapcar
  38.                                                 ) ;_ end of apply
  39.                                   minp   (list (apply (function min) (mapcar (function car) selset))
  40.                                                (apply (function min) (mapcar (function cadr) selset))
  41.                                                (apply (function min) (mapcar (function caddr) selset))
  42.                                                ) ;_ end of list
  43.                                   maxp   (list (apply (function max) (mapcar (function car) selset))
  44.                                                (apply (function max) (mapcar (function cadr) selset))
  45.                                                (apply (function max) (mapcar (function caddr) selset))
  46.                                                ) ;_ end of list
  47.                                   obj    (vla-addbox
  48.                                            (vla-get-modelspace (vla-get-activedocument (vlax-get-acad-object)))
  49.                                            (vlax-3d-point (mapcar (function (lambda (a b) (* 0.5 (+ a b)))) minp maxp))
  50.                                            (+ (apply (function -) (mapcar (function car) (list maxp minp))) );50)
  51.                                            (+ (apply (function -) (mapcar (function cadr) (list maxp minp))) );50)
  52.                                            (+ (apply (function -) (mapcar (function caddr) (list maxp minp))) );25)
  53.                                            ) ;_ end of vla-AddBox
  54.                                   ) ;_ end of setq
  55.                             (vla-put-color obj 1)
  56.                             ) ;_ end of progn
  57.                           ) ;_ end of if
  58.                         ) ;_ end of lambda
  59.                       ) ;_ end of function
  60.                     ) ;_ end of VL-CATCH-ALL-APPLY
  61.               ) ;_ end of setq
  62.         ) ;_ end of VL-CATCH-ALL-ERROR-P
  63.     (progn
  64.       (setq obj nil)
  65.       (princ (strcat "\nError : " (vl-catch-all-error-message err)))
  66.       ) ;_ end of progn
  67.     ) ;_ end of if
  68.   obj
  69.   ) ;_ end of defun
Результаты-то есть, но возникает полное ощущение, что AutoCAD каким-то образом "помнит" о начальном положении 3dsolid'a и вычисляет BoundingBox в 2 шага: сначала получается Box для исходного положения тела, потом - дополнительным поворотом и возвращаются новые результаты. Собственно вопросы: Где я ошибаюсь? Если я не ошибаюсь, то как это победить? И можно ли вообще? Тянет ли на баг?
Благодарствую :)

P.S. Проблема обнаружена в 2015, в 2013 и 2014 ее нет.
« Последнее редактирование: 23-07-2014, 14:58:03 от Александр Ривилис »
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

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

  • Administrator
  • *****
  • Сообщений: 8579
  • Карма: 1047
  • Рыцарь ObjectARX
  • Skype: rivilis
Тянет ли на баг?
P.S. Проблема обнаружена в 2015, в 2013 и 2014 ее нет.
Если в предыдущих версиях не было, то конечно тянет на баг. Отправляй! Я не проверял, но наверняка такое же будет и в ObjectARX/.NET
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Алексей КуликАвтор темы

  • Administrator
  • *****
  • Сообщений: 773
  • Карма: 121
Передал в ADN DevHelp - сообщили о том, что ошибку удалось повторить. Посмотрим, что будет дальше :)
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн ElpanovEvgeniy

  • ADN
  • *
  • Сообщений: 8
  • Карма: 2
    • elpanov.com
  • Skype: ElpanovEvgeniy
Собственно вопросы: Где я ошибаюсь? Если я не ошибаюсь, то как это победить? И можно ли вообще? Тянет ли на баг?
Благодарствую

Привет, Алексей!
Думаю, на баг не тянет - твердое тело описывается гранями, ребрами итд, где все имеет свои системы координат, а так же списком базовых точек - считай вершин, т.е которые с привязкой конечная точка. Итого, акад действительно активно использует для тел относительные системы координат. Точнее можно определить габариты облака точек - вершин, но для каждой (читай не плоской) грани вычисляются габариты в относительной системе...

Для быстрого и корректного определения габаритов сложных тел, нужна довольно сложная математика!
Тот, кто правильно указывает на мои ошибки, — мой учитель
тот, кто правильно отмечает мои верные поступки, — мой друг
тот, кто мне льстит, — мой враг.
/Сунь Цзы/

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

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

Оффлайн ElpanovEvgeniy

  • ADN
  • *
  • Сообщений: 8
  • Карма: 2
    • elpanov.com
  • Skype: ElpanovEvgeniy
Ты как всегда прав!
Тот, кто правильно указывает на мои ошибки, — мой учитель
тот, кто правильно отмечает мои верные поступки, — мой друг
тот, кто мне льстит, — мой враг.
/Сунь Цзы/

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

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

Оффлайн yurms

  • ADN OPEN
  • Сообщений: 5
  • Карма: 0
Для быстрого и корректного определения габаритов сложных тел, нужна довольно сложная математика!
  Можно про это поподробней! пожалуйста..  в свете решений на VBA?
           я вижу несколько способов определения габаритов твердых тел которые можно разделить на три класса
1) твердые тела в исходных примитивах (не испорченные) откликаются на  свойство ob.SolidType например "ящик" - с ними все ясно...
2) Ортогональные Твердые тела с какими-то модификациями дырочками и вырезами-GetBoundingBox- дает правильный результат
3) повернутые в пространстве твердые тела с модификациями -габарит определяется по "Базовой линии"-по объектной ПСК самой большой плоскости объекта с самой длинной гранью - Поворотом копии Объекта обратной матрицей трансформации USC с последующей GetBoundingBox
  основная трудность различить 2-й тип от 3-его..   потому как определять все тела по третьему способу долго выходит при большом количестве солидов в сцене
    ВОПРОС!:- Можно ли узнать обьектную ПСК тридесолида не взрывая его на составляющие.. и определить её ортогональность- тем самым подтвердить результат второго метода и не прибегать к третьему???
      почемуто любой запрос на объектную систему координат для тридесолида вызывает ошибку.. а с плоскостями работает!

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

  • Administrator
  • *****
  • Сообщений: 8579
  • Карма: 1047
  • Рыцарь ObjectARX
  • Skype: rivilis
Цитата: Александр Ривилис от 04-08-2014, 20:50:33

    Для быстрого и корректного определения габаритов сложных тел, нужна довольно сложная математика!

  Можно про это поподробней! пожалуйста..  в свете решений на VBA?
1. Это не моя цитата, а Евгения Елпанова.
2. Это раздел VisualLisp, а не VBA
3. Средств AutoCAD VBA недостаточно для того, чтобы влезть внутрь 3DSOLID. Нужен или ObjectARX или AutoCAD .NET API
ВОПРОС!:- Можно ли узнать обьектную ПСК тридесолида не взрывая его на составляющие.. и определить её ортогональность- тем самым подтвердить результат второго метода и не прибегать к третьему???
У 3DSOLID нет объектной системы координат (OCS). Её в принципе нет как и у любого другого неплоского примитива. В лучшем случае можно получить момент инерции 3DSOLID (метод MomentOfInertia) и главные оси тела (метод PrincipalDirections)
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Алексей КуликАвтор темы

  • Administrator
  • *****
  • Сообщений: 773
  • Карма: 121
Интересно, какая "объектная" ПСК будет для, например, сферы?
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн yurms

  • ADN OPEN
  • Сообщений: 5
  • Карма: 0
Интересно, какая "объектная" ПСК будет для, например, сферы?
  сфера это первый случай у них ОСS от сотворения зависит..как создавали объект так и тянется

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

  • Administrator
  • *****
  • Сообщений: 8579
  • Карма: 1047
  • Рыцарь ObjectARX
  • Skype: rivilis
Интересно, какая "объектная" ПСК будет для, например, сферы?
  сфера это первый случай у них ОСS от сотворения зависит..как создавали объект так и тянется
Нет у неё OCS. Как и у любого другого 3DSOLID.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Владимир Шу

  • ADN Club
  • ****
  • Сообщений: 415
  • Карма: 95
Средств AutoCAD VBA недостаточно для того, чтобы влезть внутрь 3DSOLID.
Уточню. Штатных средств. Если подходить не штатными, то вот тут http://adn-cis.org/forum/index.php?topic=8448.0 показано, как выгрузить dxf для отдельного примитива, из dxf файла можно вытащить описание 3dsolid в формате ACIS (*.sat), а вот тут https://forums.autodesk.com/t5/net/3d-solid-dxf/td-p/6827926 можно найти ссылку с описанием этого формата. Распарсить данные из dxf файла и получит требуемые данные.
Правда, я бы таким заниматься не стал бы, проще AutoCAD .NET API выучить.