Создание размерного стиля
В предыдущей части был рассмотрен вариант создания текстового стиля. Там все достаточно просто и универсально: хоть через entmake, хоть через ActiveX: как хочешь, так и создавай. С размерным стилем ситуация немного иная…
Я не знаю, почему, но факт остается фактом: ActiveX-методов настройки (не создания, а именно настройки!) размерного стиля не существует. Поэтому приходится разбираться именно с dxf-представлением и работать с ним.
Рассмотрим DXF-представление размерного стиля (пока рассматривается только один размерный стиль, без т.н. “подчиненных” – о них разговор впереди).
Если честно, я не хотел бы полностью дублировать DXF Reference – там все описано достаточно четко. Кроме нескольких моментов, которые лично я в свое время не сразу понял.
Это касается групп 5 (dimblk), ныне 342; 341, 343 и 344 группы. С группой 340 такой проблемы не возникло.
Напомню, что каждая из этих групп регулирует.
| Группа | Пояснение |
| 340 | ename-указатель на текстовый стиль, используемый в размерном для простановки значений. Можно получить как
(tblobjname "style" <ИмяСтиля>) |
| 341 | ename-указатель на описание блока, используемого в качестве засечки для выносок (leader). Получить можно как
(tblobjname "block" <ИмяБлока>) |
| 342..344 | То же, что и предыдущая строка, но уже как засечки для обычных размеров |
Казалось бы, все просто и ненавязчиво. Сначала создается текстовый стиль, потом на него получается указатель и вставляется в 340 группу. Только вот указатели на описания блоков портят радужность картины…
Блок, используемый в качестве засечки, на момент создания размерного стиля уже должен существовать в файле. Поэтому попробуем сделать так:
(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"))
(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
)
((tblobjname "block" name))
(t
(vla-add (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object)))
(vlax-3d-point '(0. 0. 0.))
name
) ;_ end of vla-add
(tblobjname "block" name)
)
) ;_ end of cond
) ;_ end of defun
В результате, например, создание стиля, использующего в качестве засечек архитектурные (_ArchTick), будет выглядеть наподобие:
(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. Без вариантов.
Материалы для проектирования, работы и разработки (и не только в AutoCAD)
По функции _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”)
“Засечка”
_$
Так обратно-то надо вернуть
Насчет “перевода” значений системных переменных (убил бы локализаторов!):
Команда: DIMBLK
Новое значение DIMBLK, или . если по умолчанию < "Нет">:
Команда: (setvar “dimblk”"_ArchTIck”)
“_ArchTIck”
Команда: DIMBLK
Новое значение DIMBLK, или . если по умолчанию < "ДвЗасечка">:
Почему функция вернула nil – пока не понял, надо разбираться.