Создание размерного стиля

В предыдущей части был рассмотрен вариант создания текстового стиля. Там все достаточно просто и универсально: хоть через entmake, хоть через ActiveX: как хочешь, так и создавай. С размерным стилем ситуация немного иная...

Я не знаю, почему, но факт остается фактом: ActiveX-методов настройки (не создания, а именно настройки!) размерного стиля не существует. Поэтому приходится разбираться именно с dxf-представлением и работать с ним.
Рассмотрим DXF-представление размерного стиля (пока рассматривается только один размерный стиль, без т.н. "подчиненных" - о них разговор впереди).
Если честно, я не хотел бы полностью дублировать DXF Reference - там все описано достаточно четко. Кроме нескольких моментов, которые лично я в свое время не сразу понял.
Это касается групп 5 (dimblk), ныне 342; 341, 343 и 344 группы. С группой 340 такой проблемы не возникло.
Напомню, что каждая из этих групп регулирует.

Группа Пояснение
340 ename-указатель на текстовый стиль, используемый в размерном для простановки значений. Можно получить как

1
(tblobjname "style" <ИмяСтиля>)
341 ename-указатель на описание блока, используемого в качестве засечки для выносок (leader). Получить можно как

1
(tblobjname "block" <ИмяБлока>)
342..344 То же, что и предыдущая строка, но уже как засечки для обычных размеров

Казалось бы, все просто и ненавязчиво. Сначала создается текстовый стиль, потом на него получается указатель и вставляется в 340 группу. Только вот указатели на описания блоков портят радужность картины...
Блок, используемый в качестве засечки, на момент создания размерного стиля уже должен существовать в файле. Поэтому попробуем сделать так:
Внимание! Код заменен 2019-12-16 на корректно работающий.

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
 (vl-load-com)

(defun _lispru-get-or-create-dimblock (name / err dimblk)
                                      ;|
*    Получение ename-указателя или создание блока с переданным именем
* Если name попадает под стандартные наименования:
"" || "_DOT"        || "_DOTSMALL" || "_DOTBLANK"    || "_ORIGIN"      ||
   || "_ORIGIN2"    || "_OPEN"     || "_OPEN90"      || "_OPEN30"      ||
   || "_CLOSED"     || "_SMALL"    || "_NONE"        || "_OBLIQUE"     ||
   || "_BOXFILLED"  || "_BOXBLANK" || "_CLOSEDBLANK" || "_DATUMFILLED" ||
   || "_DATUMBLANK" || "_INTEGRAL" || "_ARCHTICK"

*  То используется механизм через (setvar / getvar). В противном случае получается
* указатель на имеющийся блок с таким именем. Если такого блока нет, он создается
* пустым.
*    Примеры вызова:
(_lispru-get-or-create-dimblock "qwert")
(_lispru-get-or-create-dimblock "archtick")
|;

  (cond ((wcmatch (strcase (vl-string-left-trim "_" name))
                  (strcat """,DOT,DOTSMALL,DOTBLANK,ORIGIN,ORIGIN2,"
                          "OPEN,OPEN90,OPEN30,CLOSED,SMALL,"
                          "NONE,OBLIQUE,BOXFILLED,BOXBLANK,CLOSEDBLANK,"
                          "DATUMFILLED,DATUMBLANK,INTEGRAL,ARCHTICK"
                          ) ;_ end of strcat
                  ) ;_ end of wcmatch
         (if (vl-catch-all-error-p
               (setq err (vl-catch-all-apply
                           (function (lambda ()
                                       (setq dimblk (getvar "dimblk"))
                                       (if (= dimblk "")
                                         (setq dimblk ".")
                                         ) ;_ end of if
                                       (setvar "dimblk" (strcat "_" (vl-string-left-trim "_" name)))
                                       (setvar "dimblk" dimblk)
                                       (setq res (tblobjname "block" (strcat "_" (vl-string-left-trim "_" name))))
                                       ) ;_ end of lambda
                                     ) ;_ end of function
                           ) ;_ end of vl-catch-all-apply
                     ) ;_ end of setq
               ) ;_ end of vl-catch-all-error-p
           (setq res (tblobjname "block" (getvar "dimblk")))
           ) ;_ end of if
         (if res
           (cdr (assoc 330 (entget res)))
           ) ;_ end of if
         )
        ((tblobjname "block" name) (cdr(assoc 330 (entget (tblobjname "block" "_archtick")))))
        (t
         (vla-add (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object)))
                  (vlax-3d-point '(0. 0. 0.))
                  name
                  ) ;_ end of vla-add
         (cdr (assoc 330 (entget (tblobjname "block" name))))
         )
        ) ;_ end of cond
  ) ;_ end of defun

В результате, например, создание стиля, использующего в качестве засечек архитектурные (_ArchTick), будет выглядеть наподобие:

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
(entmakex (list
            (cons 0 "DIMSTYLE")
            (cons 100 "AcDbSymbolTableRecord")
            (cons 100 "AcDbDimStyleTableRecord")
            (cons 2 "DimStyleName")
            (cons 70 0)
            (cons 40 (getvar "dimscale")) ;dimscale
            (cons 41 2.5) ;dimsz   
            (cons 42 0.625) ;dimexo  
            (cons 43 3.75) ;dimdli   
            (cons 44 1.25) ;dimexe   
            (cons 45 0.5) ;dimrnd  
            (cons 46 0.0) ;dimdle  
            (cons 140 2.5) ;dimtxt   
            (cons 141 -2.5) ;dimcen  
            (cons 143 0.005) ;dimaltf
            (cons 145 0) ;dimtvp
            (cons 147 0.5) ;dimgap   
            (cons 72 0) ;dimlim
            (cons 73 0) ;dimtih  
            (cons 74 0) ;dimtoh  
            (cons 77 1) ;dimtad  
            (cons 78 8) ;dimzin  
            (cons 79 2) ;dimazin 
            (cons 170 0) ;dimalt
            (cons 172 1) ;dimtofl
            (cons 173 0) ;dimsah   
            (cons 174 0) ;dimtix
            (cons 175 1) ;dimsoxd
            (cons 176 0) ;dimclrd
            (cons 177 0) ;dimclre
            (cons 178 0) ;dimclrt
            (cons 179 1) ;dimadec
            (cons 271 0) ;dimdec   
            (cons 272 0) ;dimtdec
            (cons 275 1) ;dimaunit
            (cons 277 2) ;dimlunit
            (cons 278 44) ;dimdsep 
            (cons 279 0) ;dimtmove
            (cons 280 0) ;dimjust
            (cons 281 0) ;dimsd1
            (cons 282 0) ;dimsd2
            (cons 283 0) ;dimtolj
            (cons 284 8) ;dimtzin
            (cons 288 0) ;dimupt
            (cons 340 (tblobjname "style" (getvar "textstyle"))) ;dimtxtsty
            (cons 371 -2) ;dimlwd
            (cons 372 -2) ;dimlwe
            (cons 342 (_lispru-get-or-create-dimblock "_ArchTick"))
            (cons 343 (_lispru-get-or-create-dimblock "_ArchTick"))
            (cons 344 (_lispru-get-or-create-dimblock "_ArchTick"))
            ) ;_ end of list
          ) ;_ end of setq

Наверняка каждый видел картинку наподобие Размерные стили
Обратите внимание: для стиля SPDS есть так называемые "подстили", отвечающие за создание угловых размеров, обозначений радиусов, диаметров и выносок. Это регулируется, как ни странно, всего лишь именем стиля. Если основное имя размерного стиля получилось, например, "SPDS" (как на рисунке), то для угловых размеров, например, имя стиля будет "SPDS$2". Можно свести все в таблицу:

Символы, добавляемые к имени стиля Создаваемый размер
$0 Линейные размеры
$2 Угловые размеры
$3 Диаметры
$4 Радиусы
$6 Ординатные размеры
$7 Выноски и допуски

Под каждый "подстиль" могут существовать собственные настройки, и это нормально. Полный код создания размерного стиля я не пишу, оставляя эту задачу заинтересовавшимся.
Памятуя о том, что ActiveX-варианта представления размерного стиля не существует, настройку существующего размерного стиля придется осуществлять только через subst. Без вариантов.

Размещено в Код LISP, Новости, Функции LISP · Метки: ,



Комментарии

Есть 8 коммент. к “Создание размерного стиля”
  1. Makswell пишет:

    По функции _lispru-get-or-create-dimblock. Во фрагменте кода не понятно, почему подряд идут 2 setvar'а? В первом как бы получается нет никакого смысла?

    (setq dimblk (getvar "dimblk"))
    (setvar "dimblk"
    (strcat "_" (vl-string-left-trim "_" name))
    )
    (setvar "dimblk" dimblk)

    И ещё. В моём русском Автокаде 2008 твой код в частности ведёт себя так:
    _$ (_lispru-get-or-create-dimblock "archtick")
    nil
    _$ (getvar "dimblk")
    "Засечка"
    _$

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

    Так обратно-то надо вернуть :)
    Насчет "перевода" значений системных переменных (убил бы локализаторов!):
    Команда: DIMBLK

    Новое значение DIMBLK, или . если по умолчанию < "Нет">:

    Команда: (setvar "dimblk""_ArchTIck")
    "_ArchTIck"

    Команда: DIMBLK

    Новое значение DIMBLK, или . если по умолчанию < "ДвЗасечка">:

    Почему функция вернула nil - пока не понял, надо разбираться.

  3. Gontarski пишет:

    >Я не знаю, почему, но факт остается фактом: ActiveX-методов настройки (не создания, а именно >настройки!) размерного стиля не существует

    Это не факт, это Ваше предположение.

    'изменение размерных стилей
    Public Sub testDimStyle()
    Dim acDimStyle As AcadDimStyle
    Set acDimStyle = ThisDrawing.DimStyles.Item(0)

    ThisDrawing.ActiveDimStyle = acDimStyle
    Call ThisDrawing.SetVariable("DIMTXSTY", "Текстовый_Стиль2")
    acDimStyle.copyFrom ThisDrawing

    End Sub

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

    Отлично. Повторюсь: задача - настроить размерный стиль. Еще раз подчеркиваю - НАСТРОИТЬ!!! Установить засечки, их размер, установить текстовый стиль, аннотативность и т.п. Причем все (ну или какая-то часть) этих настроек должна отличаться от настроек предыдущего стиля.

  5. Gontarski пишет:

    В приведенном выше примере я как раз и настраиваю. Подчеркиваю - НАСТРАИВАЮ СУЩЕСТВУЮЩИЙ размерный стиль!!! Устанавливаю для него новый текстовый стиль с именем "Текстовый_Стиль2".

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

    Хорошо, уговорили :)

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

    Слегка пришлось подправить _lispru-get-or-create-dimblock :

    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
    (vl-load-com)

    (defun _lispru-get-or-create-dimblock (name / err dimblk)
                                          ;|
    *    Получение ename-указателя или создание блока с переданным именем
    * Если name попадает под стандартные наименования:
    "" || "_DOT"        || "_DOTSMALL" || "_DOTBLANK"    || "_ORIGIN"      ||
       || "_ORIGIN2"    || "_OPEN"     || "_OPEN90"      || "_OPEN30"      ||
       || "_CLOSED"     || "_SMALL"    || "_NONE"        || "_OBLIQUE"     ||
       || "_BOXFILLED"  || "_BOXBLANK" || "_CLOSEDBLANK" || "_DATUMFILLED" ||
       || "_DATUMBLANK" || "_INTEGRAL" || "_ARCHTICK"

    *  То используется механизм через (setvar / getvar). В противном случае получается
    * указатель на имеющийся блок с таким именем. Если такого блока нет, он создается
    * пустым.
    *    Примеры вызова:
    (_lispru-get-or-create-dimblock "qwert")
    (_lispru-get-or-create-dimblock "archtick")
    |;

      (cond ((wcmatch (strcase (vl-string-left-trim "_" name))
                      (strcat """,DOT,DOTSMALL,DOTBLANK,ORIGIN,ORIGIN2,"
                              "OPEN,OPEN90,OPEN30,CLOSED,SMALL,"
                              "NONE,OBLIQUE,BOXFILLED,BOXBLANK,CLOSEDBLANK,"
                              "DATUMFILLED,DATUMBLANK,INTEGRAL,ARCHTICK"
                              ) ;_ end of strcat
                      ) ;_ end of wcmatch
             (if (vl-catch-all-error-p
                   (setq err (vl-catch-all-apply
                               (function (lambda ()
                                           (setq dimblk (getvar "dimblk"))
                                           (if (= dimblk "")
                                             (setq dimblk ".")
                                             ) ;_ end of if
                                           (setvar "dimblk" (strcat "_" (vl-string-left-trim "_" name)))
                                           (setvar "dimblk" dimblk)
                                           (setq res (tblobjname "block" (strcat "_" (vl-string-left-trim "_" name))))
                                           ) ;_ end of lambda
                                         ) ;_ end of function
                               ) ;_ end of vl-catch-all-apply
                         ) ;_ end of setq
                   ) ;_ end of vl-catch-all-error-p
               (setq res (tblobjname "block" (getvar "dimblk")))
               ) ;_ end of if
             (if res
               (cdr (assoc 330 (entget res)))
               ) ;_ end of if
             )
            ((tblobjname "block" name) (cdr(assoc 330 (entget (tblobjname "block" "_archtick")))))
            (t
             (vla-add (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object)))
                      (vlax-3d-point '(0. 0. 0.))
                      name
                      ) ;_ end of vla-add
             (cdr (assoc 330 (entget (tblobjname "block" name))))
             )
            ) ;_ end of cond
      ) ;_ end of defun

    Функция может вернуть nil, если планируется использовать залитую стрелку: у этого блока мне пока не удалось получить указатель. Поэтому при entmake / entmakex придется пройтись по списку и "выкинуть" точечные пары, у которых второй элемент nil. vl-remove-if-not, к примеру, и вперед.

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

    Спасибо Browning Zed, который выполнил вменяемое тестирование на https://forum.dwg.ru/showthread.php?p=1842474 ! В исходный пост внесены корректировки, на мой код в комментариях можно не смотреть.

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


Я не робот.