Тема: LISP. Печать массива форматок или выборочно из одного файла в пространстве модели.
; ********************** model_plot_2007.lsp ********************************************************* ; Программа распечатки регулярного массива одинаковых форматок ; из одного рисунка пространства модели или выборочно отдельных форматок. ; Может использоваться для распечатки рисунков большого формата на ; принтерах А3 и А4. ; Принтер и параметры печати должны быть заранее настроены в Windows ; и в AutoCAD'е. Желательно создать пользовательские форматы с нулевыми полями. ; Шаг столбцов или рядов можно задать как численно, так и указанием 2 точек. ; Шаги могут задаваться со знаком минус (-). Соответственно, и точки надо ; задавать против направления осей. ; Если задать шаги равными нулю, а количество форматок не равным нулю, ; то распечатается количество копий одной форматки, равное размеру массива ; форматок. ; Если, например, масштаб вывода на печать равен 1:100, то 100 — это ; знаменатель дроби и это число вводится в ответ на запрос программы. ; Размеры форматок задаются равными размерам листа бумаги. В программе ; эти размеры пересчитываются в область печати в соответствии с масштабом. ; Ясно, что, если распечатывается, скажем чертеж формата А1, то рисовать ; форматки не надо. ; Автор Владимир Громов. ; (defun C:MODEL_PLOT_2007 ( / ver echo kak pt1 scl dx dy dn orient m n stx stx1 stx2 sty sty1 sty2 pt2 dx1 dy1 pt11 ptx pt22 pty k flag plt_pdf k0) (if (vl-string-search "17.0" (getvar "ACADVER")) (progn (setq ver "a17") (princ "\n Обнаружен AutoCAD 2007.")) ) (setq echo (getvar "CMDECHO")) (setvar "CMDECHO" 0) (initget 6 "Массив Выборочно Отказ") (setq kak (getstring "\n Как будем печатать? [Массив/Выборочно/Отказ] <Массив>: ")) (if (= kak "") (setq kak "М")) (COND ((or (= kak "М") (= kak "В")) (if (= kak "М") (progn (initget 6) (setq pt1 (getpoint "\n Укажите левый нижний угол рамки (ENTER-Отказ): ")) (if pt1 (progn (initget 6) (setq scl (getstring "\n Масштаб печати (знаменатель дроби) <1>: ")) (if (= scl "") (setq scl "1")) (initget 7) (setq dx (* (getreal "\n Размер форматки (листа бумаги) по оси X (мм): ") (atoi scl))) (initget 7) (setq dy (* (getreal "\n Размер форматки (листа бумаги) по оси Y (мм): ") (atoi scl))) (initget "Да Нет") (setq dn (getkword "\n Задать опцию 'Вписать'? [Да/Нет] <Нет>: ")) (if (= dn "Да") (setq scl "_fit") (setq scl (strcat "1:" scl)) ) (cond ((> dy dx) (princ "\n Ориентация ПОРТРЕТ.") (setq orient "_P")) ((>= dx dy) (princ "\n Ориентация ПЕЙЗАЖ.") (setq orient "_L")) ) ; cond (initget 7) (setq m (getint "\n Число столбцов форматок вдоль оси X: ")) (initget 128 "Точки") (setq stx (getreal "\n Шаг по оси X в единицах рисунка с учетом знака или 2 точки [Точки] <Точки>: ")) (if (or (= stx nil) (= stx "Точки")) (progn (setq stx1 (getpoint "\n Укажите первую точку с учетом направления шага по X: ")) (setq stx2 (getpoint stx1 "\Укажите вторую точку для шага по X: ")) (cond ((> (car stx2) (car stx1)) (setq stx (distance stx1 stx2))) ((< (car stx2) (car stx1)) (setq stx (- 0 (distance stx1 stx2))))) ; cond )) ; progn if (initget 7) (setq n (getint "\n Число рядов форматок вдоль оси Y: ")) (initget 128 "Точки") (setq sty (getreal "\n Шаг по оси Y в единицах рисунка с учетом знака или 2 точки [Точки] <Точки>: ")) (if (or (= sty nil) (= sty "Точки")) (progn (setq sty1 (getpoint "\n Укажите первую точку с учетом направления шага по Y: ")) (setq sty2 (getpoint sty1 "\Укажите вторую точку для шага по Y: ")) (cond ((> (cadr sty2) (cadr sty1)) (setq sty (distance sty1 sty2))) ((< (cadr sty2) (cadr sty1)) (setq sty (- 0 (distance sty1 sty2))))) ; cond )) ; progn if (setq pt2 (list (+ (car pt1) dx) (+ (cadr pt1) dy))) ;Правый верхний угол первой рамки (setq dx1 0 dy1 0) (repeat n (repeat m (setq pt11 (list (+ (car pt1) dx1) (+ (cadr pt1) dy1))) (setq dx1 (+ dx1 stx)) (setq ptx (cons pt11 ptx)) ) ; repeat (setq dx1 0 dy1 (+ dy1 sty)) ) ; repeat (setq ptx (reverse ptx)) (setq dx1 0 dy1 0) (repeat n (repeat m (setq pt22 (list (+ (car pt2) dx1) (+ (cadr pt2) dy1))) (setq dx1 (+ dx1 stx)) (setq pty (cons pt22 pty)) ) ; repeat (setq dx1 0 dy1 (+ dy1 sty)) ) ; repeat (setq pty (reverse pty)) (if ver (progn (initget 6 "Принтер PDF") (setq plt_pdf (getstring "\n Печать на [Принтер/PDF встроенный] <Принтер>: ")) (if (= plt_pdf "") (setq plt_pdf "П")) (initget 5) (if (= plt_pdf "PDF") (setq k0 (getint "\n Начальный номер файла: "))) )) ; progn if (setq k 0) (repeat (* m n) (if (and ver (= plt_pdf "PDF")) (command "_PLOT" "_Y" "" "" "" "" orient "_N" "_W" (nth k ptx) (nth k pty) scl "" "_Y" "" "_Y" "_A" (strcat (getvar "DWGPREFIX") (vl-filename-base (getvar "DWGNAME")) "_0" (itoa (+ k0 k)) ".pdf") "_Y" "_Y") (command "_PLOT" "_Y" "" "" "" "" orient "_N" "_W" (nth k ptx) (nth k pty) scl "" "_Y" "" "_Y" "_A" "_N" "_Y" "_Y") ) ; if (setq k (1+ k)) ) ; repeat ) ; progn ) ; if pt1 ) ; prog kak ) ; if kak (if (= kak "В") (progn (setq flag T) (while flag (setq pt1 (getpoint "\n Укажите левый нижний угол рамки (ENTER-Хватит): ")) (if pt1 (progn (setq ptx (cons pt1 ptx)) (setq pt2 (getcorner pt1 "\n Укажите правый верхний угол рамки: ")) (setq pty (cons pt2 pty)) (setq dx (- (car pt2) (car pt1))) (setq dy (- (cadr pt2) (cadr pt1))) (princ "\n Размеры области печати: ") (princ dx) (princ " x ") (princ dy) (cond ((> dy dx) (princ "\ Ориентация ПОРТРЕТ.") (setq orient "_P")) ((>= dx dy) (princ "\ Ориентация ПЕЙЗАЖ.") (setq orient "_L")) ) ; cond ) ; progn if (setq flag nil) ) ; if ) ; while (if (and ptx pty) (progn (setq ptx (reverse ptx)) (setq pty (reverse pty)) (if ver (progn (initget 6 "Принтер PDF") (setq plt_pdf (getstring "\n Печать на [Принтер/PDF встроенный] <Принтер>: ")) (if (= plt_pdf "") (setq plt_pdf "П")) (initget 5) (if (= plt_pdf "PDF") (setq k0 (getint "\n Начальный номер файла: "))) )) ; progn if (initget 6) (setq scl (getstring "\n Масштаб печати (знаменатель дроби) <1>: ")) (if (= scl "") (setq scl "1")) (initget "Да Нет _Yes No") (setq dn (getkword "\n Задать опцию 'Вписать'? [Да/Нет] <Нет>: ")) (if (= dn "Y") (setq scl "_fit") (setq scl (strcat "1:" scl))) (setq n (length ptx)) (setq k 0) (repeat n (if (and ver (= plt_pdf "PDF")) (command "_PLOT" "_Y" "" "" "" "" orient "_N" "_W" (nth k ptx) (nth k pty) scl "" "_Y" "" "_Y" "_A" (strcat (getvar "DWGPREFIX") (vl-filename-base (getvar "DWGNAME")) "_0" (itoa (+ k0 k)) ".pdf") "_Y" "_Y") (command "_PLOT" "_Y" "" "" "" "" orient "_N" "_W" (nth k ptx) (nth k pty) scl "" "_Y" "" "_Y" "_A" "_N" "_Y" "_Y") ) ; if (setq k (1+ k)) ) ; repeat ) ; progn ) ; if ) ; progn ) ; if ) ((= kak "О") (princ "\n Печать отменена.")) ) ; cond (setvar "CMDECHO" echo) (princ) )
Если код программы будет сохранен в файле model_plot_2007.lsp, то макрос для кнопки или
пункта меню может иметь вид:
^C^C^P(if (not C:MODEL_PLOT_2007)(load "model_plot_2007")) MODEL_PLOT_2007
Рекомендации по использованию программы в AutoCAD 2007.
Если предполагается печатать форматки на встроенный в AutoCAD 2007 принтер PDF ("DWG To PDF.pc3"), то желательно в его настройках создать пользовательские форматы с нулевыми полями. Тогда можно будет обходиться без опции "Вписать" ("Fit"). Правда, у меня почему-то форматка в PDF сдвигается вправо и вверх. Пришлось в настройках печати установить смещение от начала (Plot offset) для А4 на -1 мм по X и на -3 мм по оси Y.
Центрировать не надо, вписывать не надо. Область печати — рамка (Window).
Не забыть задать стиль печати.
Параметры печати необходимо установить в диспетчере параметров листов ("Page Setup Manager"). Поскольку в программе многие параметры принимаются "по умолчанию", то при смене области печати необходимо установить новые параметры для печати. Это относится к тому случаю, если в одном файле находятся форматки разного размера.
При выводе на встроенный принтер PDF файлы создаются в той же папке, в которой
находится файл DWG, причем нумерация по порядку присутствует в имени файла.
Программа должна работать и версиях 2004-2006.
Еще рекомендации.
Для каждого рисунка DWG обязательно надо задать несколько наборов параметров листа.
Меню "Файл->Диспетчер параметров листов..." ("File->Page Setup Manager..."). По умолчанию там в списке всего одна строка: *Модель* (*Model*). Так вот, здесь надо сделать несколько наборов. Количество их зависит от количества форматок разного размера в рисунке и способа вывода (на печать или в PDF). Например, для проверки работы программы в AutoCAD 2007 я с помощью кнопки "Создать..." ("New...") подготовил два набора с именами: "Epson C62 Портрет" и "PDF А4 Портрет". У каждого из этих наборов свои настройки печати. Если бы у меня в рисунке находились бы еще форматки А3, то пришлось бы еще создать 2 набора, допустим, "HP DeskJet 1700 А3 Портрет" и "PDF А3 Портрет". А если бы еще присутствовали форматки с ориентацией "Пейзаж" ("Landscape"), то соответственно, пришлось бы еще создавать подобные наборы параметров со своими именами. Но когда наборы созданы, любой из них можно сделать текущим и запускать программу распечатки с ответами на запросы программы, соответствующими текущим папаметрам печати. В принципе, как я подозреваю, можно таким образом послать по очереди из одного рисунка пачками форматки разного размера. Конечно, "одного взмаха руки" тут не получится, но все же... Наборы параметров листов сохраняются в рисунке. Возможно, это и недостаток, потому что при передаче файлов другим пользователям может оказаться так, что у них нет соответствующих принтеров. Но это уже другая проблема.
Добавил в программу запрос на начальный номер файла при выводе его в PDF. Это относится к AutoCAD 2007. При использовании внешних конверторов эта возможность отключена. Проблема нумерации файлов там остается. Возможно, что-то там можно сделать в настройках драйверов этих конверторов. Например, в конвертере "Amyuni PDF Converter" можно задать папку для файлов вывода и предусмотреть добавление номера ID к имени файла. Полной автоматизации печати не будет, но зато вместо задания имени файла достаточно будет только нажимать "Enter".