О НЕКОРРЕКТНОСТИ ПРОСТАНОВКИ РАЗМЕРОВ ОКРУЖНОСТИ БАЗОВЫМИ ФУНКЦИЯМИ AUTOLISP

Автор Тема: О НЕКОРРЕКТНОСТИ ПРОСТАНОВКИ РАЗМЕРОВ ОКРУЖНОСТИ БАЗОВЫМИ ФУНКЦИЯМИ AUTOLISP  (Прочитано 9642 раз)

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

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

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

  • ADN OPEN
  • Сообщений: 2
  • Карма: 0
  • Skype: KON--2009
Рассматривается ситуация, когда при заданном масштабе изображения в системе AutoCAD геометрия объекта не полностью отображается на экране. В этом случае не происходит образмеривание окружностей базовыми функциями AutoLISP: dimradius, dimdiametr. Проблема снимается выбором масштаба полного вписывания объекта в графическую зону экрана. Применение функций vl расширенного AutoLISP позволяет игнорировать масштаб отображения геометрии на экране.

Ключевые слова: AutoCAD, AutoLISP, dimradius, dimdiametr, vlКлючевые слова: AutoCAD, AutoLISP, dimradius, dimdiametr, vl



В  ходе применения языка AutoLISP для создания приложений в среде AutoCAD было замечено «странное» поведение функций простановки размеров окружностей и дуг: при определенных ситуациях они появляются, а при других – приложение требует интерактивного достраивания. В Интернете подобная ситуация четко не описана. В результате изучения различных факторов нами выдвинуто предположение о влиянии области зуммирования на корректность построения радиальных размеров.

(command "_limits" "" "210,297")
(command "_zoom" "_w" "-10,-10" "90,90")
(command "_erase" "_all" "")
(COMMAND "_rectang" "-10,-10"  "90,90" "")
...............................
(command "_dimlinear" p6 p8 "@ 10,0")
(command "_dimlinear" p6 p10 "@ 20,0")
(command "_dimradius" p15  "@ 20,0")
...............................
Рисунок 1

Рассмотрим упрощенную ситуацию,  возникающую при программном (рисунок 1) построении радиального размера правой верхней дуги на рисунке 2. Как видно из рисунка, дуга не появляется, а программа зависает.

Рисунок 2

Из фрагмента кода на AutoLISP видно, что задан формат А4, затем область отображения на экране формата выбрана рамкой в границах: -10,-10 и 90,90. Для визуального отображения выбранной области искусственно строится прямоугольник тех же размеров (рисунок 2).  Отметим, что положение ожидаемого радиального размера дуги выходит за пределы выбранной зоны зуммирования. Линейные размеры также не попадают в эту область, но формируются.
Предположив, что только радиальные размеры чувствительны к попаданию в область зуммирования, изменим программный код: расширим область зуммирования, задав ее в границах 190, 190 (рисунок 3). В результате выполнения такой программы в окне AutoCAD получим корректное отображение радиального размера (рисунок 4).
((command "_limits" "" "210,297")
(command "_zoom" "_w" "-10,-10" "190,190")
(command "_erase" "_all" "")
(COMMAND "_rectang" "-10,-10"  "190,190" "")
...............................
(command "_dimlinear" p6 p8 "@ 10,0")
(command "_dimlinear" p6 p10 "@ 20,0")
(command "_dimradius" p15  "@ 20,0")
...............................
Рисунок 3

Теперь, оставив ту же «неблагоприятную» область зуммирования в границах -10,-10 90,90 , воспользуемся расширенными возможностями AutoLISP (рисунок 5), которые предоставляются после подгрузки библиотеки (vl-load-com). Программирование радиального размера в этом случае «утяжеляется», но, как видим на рисунке 6, размер формируется и, как выяснилось, не зависит от выбора области зуммирования.

Рисунок 4

(vl-load-com)
(command "_limits" "" "210,297")
(command "_zoom" "_w" "-10,-10" "90,90")
(command "_erase" "_all" "")
(COMMAND "_rectang" "-10,-10"  "90,90" "")
...............................
(command "_dimlinear" p6 p8 "@ 10,0")
(command "_dimlinear" p6 p10 "@ 20,0")
...............................
...............................
(setq modelspace
(vla-get-modelspace
(vla-get-activedocument(vlax-get-acad-object))))
(setq centr (vlax-3d-point p13))
(setq arcpoint (vlax-3d-point p15))
(setq leng 20.0)
(vlax-invoke-method modelspace 'adddimradial centr arcpoint leng)
Рисунок 5


Рисунок 6

Таким образом, при программной реализации прикладных систем на базе AutoCAD функциональным языком AutoLISP [1] следует, видимо, полностью вписывать окно формата в графическую зону экрана интерфейса.


СПИСОК ЛИТЕРАТУРЫ
1. Калачёв О.Н. Интерактивное моделирование размерных изменений заготовки при проектировании технологического процесса механообработки // Информационные технологии. 2001. № 2. С. 10-14, 58.




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

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

Оффлайн Дима_

  • ADN Club
  • ****
  • Сообщений: 473
  • Карма: 66
Красиво изложили, но к сожалению совсем не ознакомились с вопросом - у Вас первая "ошибка чайника" (прошу не считать это как оскорбление на себя). Как уже указал Александр - это привязки, которые надо либо отключить, либо использовать "префикс" "_non".
при программной реализации прикладных систем на базе AutoCAD функциональным языком AutoLISP
Это ошибочное утверждение свойственно студенту которого в качестве "попутной" лекции ознакомили с автолиспом (это не Ваша вина - а автора той древней методички - которая приобрела широкую популярность в интернетах у тех-же студентов, автора я кстати видел лично, человек не плохой - но автолисп знает очень не глубоко) - дело в том, что представленную вами программу на автолиспе - назвать таковой можно только формально, реально это "использование затычки для имитации действий юзера" - я имею в виду командные методы - на практике их никто не использует для построений примитивов - кроме тех. же студентов, которым надо сдать курсовую по методичке.


Отмечено как Решение Александр Ривилис 22-05-2018, 13:44:28

Оффлайн ElpanovEvgeniy

  • ADN
  • *
  • Сообщений: 8
  • Карма: 2
    • elpanov.com
  • Skype: ElpanovEvgeniy
Добрый день KON.
Владимир передал ваш запрос мне, но попросил перевести все обсуждение на форум.
Действительно, вы верно разобрались в работе с чертежом из LISP.
Для начала немного теории…
Вариант программы, которая повторяет действия пользователя при работе с чертежом через интерфейс.
На примере простановки размеров, пользователь указывает одним кликом дугу, вторым место размещения размера. В это время AutoCAD самостоятельно находит объект, который необходимо образмерить, необходимый сегмент, если это полилиния, ее центр, радиус, и создается размер из центра в точку, в которой была выбрана дуга или дуговой сегмент полилинии. Далее автоматически происходит связывание вновь созданного размера с объектом реакторами. Именно эти реакторы позволяют размеру изменяться, после изменения самого объекта. Как пример, проставляем размер на дуговой сегмент (рисунок 1),


 выделяем сегмент и перетаскиваем сегмент за среднюю точку дуги (рисунок 2).


 Связанный размер автоматически изменяется (рисунок 3).


Как мы видим на рисунке 3, центр из которого проставлен размер, его местоположение и значение изменились.

   В AutoCAD доступно создавать размеры, сами по себе. Никак не связанные с объектами чертежа. Это неправильно. Такие размеры не отслеживают изменений. В AutoCAD есть специальная команда для проверки чертежа и нахождения таких размеров. Над такими размерами появляется значок с восклицательным знаком (рисунок 4).


Теперь про подход к программной работе с чертежом. Для Lisp доступно три подхода.

1.   Создание объектов и редактирование выполняется с использованием командной строки. Этот подход вы использовали в своем коде:
Код - Auto/Visual Lisp [Выбрать]
  1. (command "_limits" "" "210,297")
  2. (command "_zoom" "_w" "-10,-10" "90,90")
  3. (command "_erase" "_all" "")
  4. (command "_rectang" "-10,-10" "90,90" "")
2.   AutoCAD это большая база данных. Lisp может напрямую работать с большинством записей в этой базе. Записи называются DXF. В справки из LISP редактора, достаточно поискать dxf в разделе для разработчиков и сразу найдется огромное количество информации по кодам и структуре хранения данных. Для просмотра dxf любого объекта, достаточно выполнить код:
Код - Auto/Visual Lisp [Выбрать]
  1. (entget(car(entsel "\n Укажите любой объект на чертеже: ")))

 Например, создадим вашу полилинию с использованием прямой записи в dxf:
Код - Auto/Visual Lisp [Выбрать]
  1. (setq e (entmakex '((0 . "LWPOLYLINE")
  2.                     (100 . "AcDbEntity")
  3.                     (100 . "AcDbPolyline")
  4.                     (90 . 9);; количество вершин
  5.                     (70 . 1);; замкнутая
  6.                     (10 20.0 20.0);; первая вершина
  7.                     (10 80.0 20.0);; вторая вершина
  8.                     (42 . 0.414214);; кривизна второго сегмента
  9.                     (10 100.0 40.0)
  10.                     (10 100.0 60.0)
  11.                     (42 . -1.0)
  12.                     (10 100.0 100.0)
  13.                     (10 100.0 120.0)
  14.                     (42 . 0.414214)
  15.                     (10 80.0 140.0)
  16.                     (10 60.0 140.0)
  17.                     (42 . -0.5)
  18.                     (10 20.0 100.0)
  19.                    )
  20.         )
  21. )

3.   Создание объектов с использованием объектной модели AutoCAD. Этот подход вы так же использовали в последнем примере, когда создавали размер:
Код - Auto/Visual Lisp [Выбрать]
  1. (setq p13 (getpoint "\n Centr point") p15(getpoint"\n Arc point"))
  2. (setq modelspace (vla-get-modelspace (vla-get-activedocument (vlax-get-acad-object))))
  3. (setq centr (vlax-3d-point p13))
  4. (setq arcpoint (vlax-3d-point p15))
  5. (setq leng 20.0)
  6. (vlax-invoke-method modelspace 'adddimradial centr arcpoint leng)

стоит отметить, что функция vlax-invoke-method обобщенная и можно вызвать adddimradial напрямую:
Код - Auto/Visual Lisp [Выбрать]
  1. (vla-adddimradial modelspace centr arcpoint leng)

Когда создается размер без привязки к полилинии, AutoCAD не делает его ассоциативным и размер остается непривязанным.

В приложении программа, создающая тестовую полилинию с дуговыми сегментами, создает на все дуговые сегменты ассоциативные размеры радиусов. Программа работает в чертеже, в котором уже создавались радиусные размеры, поскольку программе необходимо подгрузить надстройку для работы с радиусными размерами. Программа проверяет наличие этой библиотеки. Для запуска программы наберите в командной строке «test»  без кавычек.


Код - Auto/Visual Lisp [Выбрать]
  1. (defun c:test (/ CEN DICTIONARY DIMASSOC DIMENSION LWPOLY P1 P2 P3 X1)
  2.   ;;************************************************************************************************************************
  3.   ;; Программа написана и протестирована в AutoCAD 2015
  4.   ;;
  5.   ;;В программе создается тестовая полилиния и проставляются на ней радиальные размеры.
  6.   ;;
  7.   ;;************************************************************************************************************************
  8.   (defun eea-test-regapp (/ flag)
  9.     ;;************************************************************************************************************************
  10.     ;;   Подпрограмма проверяет загрузку надстройки "ACAD_DSTYLE_DIMRADIAL_EXTENSION"
  11.     ;;************************************************************************************************************************
  12.     (vlax-for a (vla-get-RegisteredApplications (vla-get-ActiveDocument (vlax-get-acad-object)))
  13.       (if (= "ACAD_DSTYLE_DIMRADIAL_EXTENSION" (vla-get-name a))
  14.         (setq flag t)
  15.       )
  16.     )
  17.     flag
  18.   )
  19.   (defun eea-add-dictionary (lst a)
  20.     ;;************************************************************************************************************************
  21.     ;;   Подпрограмма добавляет дополнительные поля - словари в DXF объектов
  22.     ;;   программа не универсальная и вставляет список сразу после метки (HANDEL) объекта.
  23.     ;;************************************************************************************************************************
  24.     (entmod (append (reverse (member (assoc 5 lst) (reverse lst))) a (cdr (member (assoc 5 lst) lst))))
  25.   )
  26.   (if (eea-test-regapp)
  27.     (progn (defun eea-add-dictionary (lst a)
  28.              (entmod (append (reverse (member (assoc 5 lst) (reverse lst))) a (cdr (member (assoc 5 lst) lst))))
  29.            )
  30.            ;;************************************************************************************************************************
  31.            ;;   создаем полилинию, как в примере задания.
  32.            ;;************************************************************************************************************************
  33.            (setq LWPOLY (entmakex '((0 . "LWPOLYLINE")
  34.                                     (100 . "AcDbEntity")
  35.                                     (100 . "AcDbPolyline")
  36.                                     (90 . 9)                ; количество вершин
  37.                                     (70 . 1)                ; замкнутая
  38.                                     (10 20.0 20.0)          ; первая вершина
  39.                                     (10 80.0 20.0)          ; вторая вершина
  40.                                     (42 . 0.414214)         ; кривизна второго сегмента
  41.                                     (10 100.0 40.0)
  42.                                     (10 100.0 60.0)
  43.                                     (42 . -1.0)
  44.                                     (10 100.0 100.0)
  45.                                     (10 100.0 120.0)
  46.                                     (42 . 0.414214)
  47.                                     (10 80.0 140.0)
  48.                                     (10 60.0 140.0)
  49.                                     (42 . -0.5)
  50.                                     (10 20.0 100.0)
  51.                                    )
  52.                         )
  53.            )
  54.            (foreach par '(1.6 3.5 5.5 7.5)                  ;(setq par 1.6)
  55.              ;;************************************************************************************************************************
  56.              ;; par - в этой переменной будет храниться параметр точки на полилинии, через которую необходимо провести размер.
  57.              ;; параметры по умолчанию начинаются с нуля и каждое целое число обозначает вершин полилинии.
  58.              ;; например 0,5 обозначает середину первого сегмента.
  59.              ;; 0,25 - четверть длины первого сегмента вдоль него.
  60.              ;;************************************************************************************************************************
  61.              (setq p1  (vlax-curve-getPointAtParam LWPOLY (fix par)) ;начало указанного сегмента
  62.                    p2  (vlax-curve-getPointAtParam LWPOLY par) ;точка на которую указывает PAR
  63.                    p3  (vlax-curve-getPointAtParam
  64.                          LWPOLY
  65.                          (if (= (1+ (fix par)) (vlax-curve-getEndParam LWPOLY)) ; конец сегмента.
  66.                            ;; если полилиния замкнутая то используется нулевой параметр.
  67.                            ;; код не предусматривает незамкнутые полилинии.
  68.                            0
  69.                            (1+ (fix par))
  70.                          )
  71.                        )                                    ; точка в конце сегмента
  72.                    cen (polar p3
  73.                               (+ (angle p3 p2) (setq x1 (- (angle p1 p3) (angle p1 p2))) (* pi -0.5))
  74.                               (/ (distance p2 p3) (sin x1) 2.)
  75.                        )
  76.                        ;; центр дуги сегмента. Математику можно посмотреть по ссылке:
  77.                        ;; http://elpanov.com/index.php?id=35
  78.              )
  79.              ;;************************************************************************************************************************
  80.              ;;   создаем объект размер
  81.              ;;************************************************************************************************************************
  82.              (setq DIMENSION (entmakex (list '(0 . "DIMENSION") ; размер
  83.                                              '(100 . "AcDbEntity")
  84.                                              '(67 . 0)
  85.                                              '(410 . "Model")
  86.                                              '(8 . "0")
  87.                                              '(100 . "AcDbDimension")
  88.                                              '(280 . 0)
  89.                                              (cons 10 cen)  ; центр
  90.                                              (cons 11 p2)   ; точка на дуговом сегменте
  91.                                              '(12 0.0 0.0 0.0)
  92.                                              '(70 . 36)
  93.                                              '(1 . "")
  94.                                              '(71 . 5)
  95.                                              '(72 . 1)
  96.                                              '(41 . 1.0)
  97.                                              '(42 . 20.0)
  98.                                              '(73 . 0)
  99.                                              '(74 . 0)
  100.                                              '(75 . 0)
  101.                                              '(52 . 0.0)
  102.                                              '(53 . 0.0)
  103.                                              '(54 . 0.0)
  104.                                              '(51 . 0.0)
  105.                                              '(210 0.0 0.0 1.0)
  106.                                              '(3 . "ISO-25")
  107.                                              '(100 . "AcDbRadialDimension")
  108.                                              '(13 0.0 0.0 0.0)
  109.                                              '(14 0.0 0.0 0.0)
  110.                                              (cons 15 p2)   ; точка на дуговом сегменте
  111.                                              '(16 0.0 0.0 0.0)
  112.                                              '(40 . 0.0)
  113.                                              '(50 . 0.0)
  114.                                              (list -3
  115.                                                    '("ACAD" (1000 . "DSTYLE") (1002 . "{") (1070 . 288) (1070 . 1) (1002 . "}"))
  116.                                                    (list "ACAD_DSTYLE_DIMRADIAL_EXTENSION"
  117.                                                          '(1070 . 387)
  118.                                                          '(1070 . 1)
  119.                                                          '(1070 . 388)
  120.                                                          (cons 1040 (angle cen p1))
  121.                                                          '(1070 . 390)
  122.                                                          (cons 1040 (angle cen p3))
  123.                                                    )
  124.                                              )
  125.                                        )
  126.                              )
  127.              )
  128.              ;;************************************************************************************************************************
  129.              ;;   создаем реактор на изменение размера после изменения полилинии
  130.              ;;************************************************************************************************************************
  131.              (setq DIMASSOC (entmakex (list '(0 . "DIMASSOC") ; реактор
  132.                                             '(100 . "AcDbDimAssoc")
  133.                                             (cons 330 DIMENSION) ; размер
  134.                                             '(90 . 2)
  135.                                             '(70 . 0)
  136.                                             '(71 . 0)
  137.                                             '(1 . "AcDbOsnapPointRef")
  138.                                             '(72 . 3)
  139.                                             (cons 331 LWPOLY) ; полилиния
  140.                                             '(73 . 2)
  141.                                             (cons 91 (1+ (fix par))) ; номер сегмента
  142.                                             '(40 . 0.0)
  143.                                             '(10 0.0 0.0 0.0)
  144.                                             '(75 . 0)
  145.                                       )
  146.                             )
  147.              )
  148.              ;;************************************************************************************************************************
  149.              ;; создаем словарь, где хранятся все ассоциативные связи
  150.              ;;************************************************************************************************************************
  151.              (setq DICTIONARY
  152.                     (entmakex (list '(0 . "DICTIONARY")     ; словарь
  153.                                     (cons 330 DIMENSION)    ; размер
  154.                                     '(100 . "AcDbDictionary")
  155.                                     '(280 . 1)
  156.                                     '(281 . 1)
  157.                                     '(3 . "ACAD_DIMASSOC")
  158.                                     (cons 360 DIMASSOC)     ; реактор
  159.                               )
  160.                     )
  161.              )
  162.              ;;************************************************************************************************************************
  163.              ;; Во время создания объектов мы не записали в них все связи, поскольку невозможно записать в связь объект до его создания.
  164.              ;; Теперь прописываем во все объекты все связи.
  165.              ;;************************************************************************************************************************
  166.              ;;
  167.              ;; Изменяем реактор и прописываем в него словарь
  168.              ;;
  169.              ;;************************************************************************************************************************
  170.              (entmod (subst (cons 330 DICTIONARY) (assoc 330 (entget (HANDENT "1"))) (entget DIMASSOC)))
  171.              (eea-add-dictionary
  172.                (entget DIMASSOC)
  173.                (list '(102 . "{ACAD_REACTORS") (cons 330 DICTIONARY) '(102 . "}"))
  174.              )
  175.              ;;************************************************************************************************************************
  176.              ;; изменяем размер, прописываем в него словарь
  177.              ;;************************************************************************************************************************
  178.              (eea-add-dictionary
  179.                (entget DIMENSION)
  180.                (list '(102 . "{ACAD_XDICTIONARY")
  181.                      (cons 360 DICTIONARY)
  182.                      '(102 . "}")
  183.                      '(102 . "{ACAD_REACTORS")
  184.                      (cons 330 DIMASSOC)
  185.                      '(102 . "}")
  186.                )
  187.              )
  188.              ;;************************************************************************************************************************
  189.              ;; изменяем саму полилинию
  190.              ;;************************************************************************************************************************
  191.              (eea-add-dictionary
  192.                (entget LWPOLY)
  193.                (list '(102 . "{ACAD_XDICTIONARY")
  194.                      (cons 360 DICTIONARY)
  195.                      '(102 . "}")
  196.                      '(102 . "{ACAD_REACTORS")
  197.                      (cons 330 DIMASSOC)
  198.                      '(102 . "}")
  199.                )
  200.              )
  201.              ;;************************************************************************************************************************
  202.              ;; обновляем полилинию и размер
  203.              ;;************************************************************************************************************************
  204.              (entupd LWPOLY)
  205.              (entupd DIMENSION)
  206.              (princ)
  207.            )
  208.     )
  209.     (alert
  210.       "\nПеред работой программы создайте хотя бы один радиальный размер,\n для подгрузки необходимых библиотек в AutoCAD.\nЭтот размер далее не нужен."
  211.     )
  212.   )
  213. )
  214.  
На вссякий случай, программу прикладываю к сообщению.


Результат работы программы (рисунок 5),


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

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

  • ADN OPEN
  • Сообщений: 2
  • Карма: 0
  • Skype: KON--2009
Спасибо Евгений! Отличная информация для вдумчивых студентов, и мне не повредит.