Как создать аннотативный стиль / описание блока?

По результатам обсуждения статьи "О создании стилей".
Начиная с 2008 версии в dwg появилось понятие аннотативности. О пользе этой вещицы здесь говорить не будем, попробуем разобраться с тем, как создавать аннотативность для стиля или описания блока, и как ее удалять при необходимости.

Скажу честно - я разбирался именно со стилями, с объектами я не воевал. Может быть, потом как-нибудь и получится объекты победить, но пока загадывать не буду :)

Итак, поехали. Прежде всего: при работе со стилями намного проще работать через entmod, чем через vla-методы. По крайней мере у меня сложилось именно так.

В любом файле, создаваемом в AutoCAD начиная с 2008 версии (естественно, при условии, что шаблон не правился) создается как минимум 2 текстовых стиля - Standard (ну куда ж без него) и Annotative (или Аннотативный в русской локализации).

Если через (entget Style '("*")) снять все данные о стиле, становится видно, что вся разница только в группе -3:

Standard Annotatibe
1
2
3
4
5
6
7
8
9
'(-3
  ("AcadAnnotative"
   (1000 . "AnnotativeData")
   (1002 . "{")
   (1070 . 1)
   (1070 . 1)
   (1002 . "}")
   )
  )

Значит, для добавления аннотативности стилю достаточно просто добавить этот список?

Ну, как бы да, потому что на самом деле не совсем:
Во-первых, версия AutoCAD должна быть не ниже 2008.
Во-вторых, приложение "AnnotativeData" должно быть зарегистрировано в файле.
И, наконец, в третьих, объект должен быть неаннотативным. Это уже в принципе перестраховка, пока что AutoCAD не позволяет дважды на один и тот же элемент зарегистрировать одно и то же приложение. Но, как говорится, береженого Бог бережет, а небереженого конвой стережет.

Шаг первый. Проверяем версию AutoCAD. Один из вариантов - через (ver): перевести в верхний регистр, обрубить символы VISUALP и переконвертировать в число:

1
(atoi (vl-string-trim "VISUALP " (strcase (ver))))

Но можно же и уже готовым решением воспользоваться :) _lispru-acad-version.lsp. Для 2008 версии эта функция вернет значение 17.1. От этого и будем "отталкиваться".

Второй шаг целиком и полностью (для увеличения быстродействия) возложим на AutoCAD. Простая строчка (regapp "AnnotativeData") будет выполнена быстро и безболезненно.

И, наконец, третье. Собственно проверка на "уже-аннотативность". Вещь в принципе не очень обязательная, но для вящего спокойствия сделаем.

Предположим, что у нас а) есть указатель на преобразовываемый объект и б) этот указатель в ename-представлении.

Следовательно, можно проверку сделать так: если (assoc "AcadAnnotative" (cdr (assoc -3 (entget st '("*"))))) вернет не nil, значит, объект уже аннотативный.

Объединяя все вместе, получаем в первом приближении:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
(defun _lispru-ent-make-annotative (ent / res)
                                   ;|
*    Добавление аннотативности объекту
*    Параметры вызова:
  ent     ename-указатель на объект
|;

  (if
    (and (> (_lispru-acad-version) 17.)
         (not
           (assoc "AcadAnnotative" (cdr (assoc -3 (entget ent '("*")))))
           ) ;_ end of not
         ) ;_ end of and
     (progn
       (regapp "AcadAnnotative")
       (setq
         res (entmod
               (list (cons -1 ent)
                     '(-3
                       ("AcadAnnotative"
                        (1000 . "AnnotativeData")
                        (1002 . "{")
                        (1070 . 1)
                        (1070 . 1)
                        (1002 . "}")
                        )
                       )
                     ) ;_ end of list
               ) ;_ end of entmod
         ) ;_ end of setq
       ) ;_ end of progn
     ) ;_ end of if
  ) ;_ end of defun

Во втором приближении добавим дополнительный параметр - устанавливать аннотативность или нет:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
(defun _lispru-ent-make-annotative (ent make / res)
                                   ;|
*    Добавление аннотативности объекту
*    Параметры вызова:
  ent     ename-указатель на объект
  make    делать аннотативным или снимать аннотативность
|;

  (if
    (and (> (_lispru-acad-version) 17.0)
         (not
           (assoc "AcadAnnotative" (cdr (assoc -3 (entget ent '("*")))))
           ) ;_ end of not
         ) ;_ end of and
     (if make
       (progn
         (regapp "AcadAnnotative")
         (setq
           res (entmod
                 (list (cons -1 ent)
                       '(-3
                         ("AcadAnnotative"
                          (1000 . "AnnotativeData")
                          (1002 . "{")
                          (1070 . 1)
                          (1070 . 1)
                          (1002 . "}")
                          )
                         )
                       ) ;_ end of list
                 ) ;_ end of entmod
           ) ;_ end of setq
         ) ;_ end of progn
       (setq res
              (entmod
                (append
                  (entget ent)
                  (list
                    (cons
                      -3
                      (append '(("AcadAnnotative"))
                              (vl-remove-if
                                (function
                                  (lambda (x)
                                    (= (car x "AcadAnnotative"))
                                    ) ;_ end of lambda
                                  ) ;_ end of function
                                (cdr (assoc -2 (entget ent '("*"))))
                                ) ;_ end of vl-remove-if
                              ) ;_ end of append
                      ) ;_ end of cons
                    ) ;_ end of list
                  ) ;_ end of append
                ) ;_ end of entmod
             ) ;_ end of setq
       ) ;_ end of if
     ) ;_ end of if
  ) ;_ end of defun

Конечно, код можно и дальше дополнять (например, добавить проверку на тип ent, на то, что он вообще принадлежит к соответствующим типам примитивов и т.д.), но у меня сейчас на это просто нет времени.

Исходные файлы кодов:
_lispru-ent-make-annotative.lsp; _lispru-acad-version.lsp. Для корректной работы в текущий документ должны быть загружены оба лиспа.



Комментарии

Есть 12 коммент. к “Как создать аннотативный стиль / описание блока?”
  1. Do$ пишет:

    Отлично! Думаю, пригодится не только мне! Спасибо!
    Не в укор, а с целью улучшения статьи: ссылки на файл не открываются, требуют авторизации. Или так и задумано? :)

  2. Кулик Алексей aka kpblc пишет:

    Спасибо :) Проверь, вроде сейчас уже должно нормально работать.

  3. Do$ пишет:

    Да, сейчас как надо!
    Кстати, в статье про сохранение данных в файле тоже есть такое.

  4. Кулик Алексей aka kpblc пишет:

    В той статье тоже вроде бы все исправил. Спасибо:)

  5. Makswell пишет:

    В коде функции _lispru-ent-make-annotative ошибка. Вместо (entget st '("*")) нужно (entget ent '("*"))

  6. Кулик Алексей aka kpblc пишет:

    Вроде исправил :) Спасибо :)

  7. VVA пишет:

    Алексей, ссылка на исходный файл кодов _lispru-ent-make-annotative.lsp никуда не ведет

  8. Кулик Алексей aka kpblc пишет:

    Спасибо, завтра проверю - сегодня уже сил нет никаких )))

  9. Кулик Алексей aka kpblc пишет:

    Исправил - вроде работает

  10. GeoBuilder пишет:

    (= (car x "AcadAnnotative")) ошибка нужно (= (car x) "AcadAnnotative")

  11. GeoBuilder пишет:

    Ну и во втором приближение не будет работать удаление аннотативности, т.к. первый If не пропустит туда объект с аннотативностью ;-)

  12. Кулик Алексей aka kpblc пишет:

    Выяснились интересные подробности: http://adn-cis.org/forum/index.php?topic=7494.new#new

Поделитесь своим мнением


Я не робот.