PDA

View Full Version : PlotDwgs, a plot utility program


Terry Cadd
2007-06-15, 01:00 AM
I have recently revised PlotDwgs to be easier to customize by other AutoCAD users and AutoCAD departments. This version utilizes two global lists, which are located at the top of the PlotDwgs.lsp file. The lists are easy to edit, even by a non-programmer. PlotDwgs doesn’t use or require previous page setups, or layout plotter configuration settings. This makes it ideal for batch plotting a folder of customer drawings or other engineering firms’ drawings. In the main dialog, by selecting “Varies” for the paper size, the program determines the correct paper size and corresponding plotter to use for each layout. This version also includes the option of plotting all open drawings.

http://web2.airmail.net/terrycad/Images/PlotDwgs.gif

In order to make this version work for most global AutoCAD departments, a few company specific functions were removed, such as a plot stamp function for title blocks, and a Bill of Material utility which updates an Excel spreadsheet for the database. The program may be customized to meet your requirements, such as turning on or off certain layers when plotting. For the International AutoCAD users that use metric page sizes, search and replace A-Size through D-Size with your page size names, and also edit the PaperSize function, and change the values of the Widest~ variables accordingly. PlotDwgs is designed to work with AutoCAD 2000 and up.

TobyKanoby
2007-06-15, 11:48 PM
Terry may I borrow your plotter images for my own dialogues? I like your animation how did you get it into the thread page?

Terry Cadd
2007-06-16, 06:27 AM
Yes, you can use any of the images and functions that you need. I like to refer to it as sharing. You may include an image by using the format of:
(website image file location) .

abdulhuck
2007-06-16, 07:59 PM
Terry,

Thanks a lot for sharing.

Regards,

Abdul Huck

Filipe Francisco
2007-06-16, 08:21 PM
It looks to be a great program, I will try...

Thanks for sharing

Cheers,

Terry Cadd
2007-09-17, 07:23 PM
This weekend I revised a few of the functions in PlotDwgs.lsp. You can download the revised version from AutoLISP Exchange. It will also be included in Cadalyst for October.
Here is the website again: http://web2.airmail.net/terrycad
Regards,
Terry

ccowgill
2007-11-06, 05:31 PM
Is there an easy way to modify this routine so you can plot selected block definitions from within a block library drawing with the name of the block plotted as a caption across the bottom of the page? We are in the process of renaming our standard blocks, as the previous naming convention did not work as it was intended. doing such, we must re-print our standards book with the blocks and their proper names. Any help would be appreciated.

Thanks,

Terry Cadd
2007-11-07, 04:39 PM
Is this something that you might be able to tweak the plotstamp utility to do? Or are you just wanting the routine to place bottom centered text in the drawing block with the name of the block?

ccowgill
2007-11-07, 06:26 PM
Is this something that you might be able to tweak the plotstamp utility to do? Or are you just wanting the routine to place bottom centered text in the drawing block with the name of the block?

I dont know if plot stamp will work. the problem is, the blocks are not actually inserted into the drawing, just the definition. I really need to be able to go through the definitions, insert at 0,0 add caption directly below at a readable height, plot to 8x11 and then remove the block and text from the drawing.

Terry Cadd
2007-11-07, 06:58 PM
[just the definition?] Do you mean like a lsp routine is defining the blocks on the fly or what?

Opie
2007-11-07, 08:06 PM
[just the definition?] Do you mean like a lsp routine is defining the blocks on the fly or what?
I would assume the blocks are defined in the drawing. They are just not visibly placed in the drawing.

Terry Cadd
2007-11-07, 09:52 PM
Just off the press! I think this is what you are wanting. It creates a temp layout called PlotBlks to work from. I needed something like this about a month ago to show my boss the old and new versions of some blocks. You may tweak it as you wish to make it work like you want it.

(defun c:PB () (c:PlotBlks));Shortcut
(defun c:PlotBlks (/ AttReq# BlockName$ Height~ InsPt PlotList@ X-Max~ X-Mid~
X-Min~ Y-Mid~ Y-Min~)
(if (not *PlotterInfo@)
(load "PlotDwgs")
);if
(ReadPlotDwgs)
(foreach PlotList@ (reverse *PlotterInfo@)
(if (member "A-Size" PlotList@)
(setq *PlotDwgs@ (list (nth 0 PlotList@) "PlotBlks" "1"
(nth 3 PlotList@) (nth 4 PlotList@) (nth 1 PlotList@) (nth 2 PlotList@)
(nth 7 *PlotDwgs@) "Current Drawing" "0" "PlotBlks"
(nth 3 PlotList@) (nth 1 PlotList@) "PlotBlks")
);setq
);if
);foreach
(WritePlotDwgs)
(setq CurrentDrawing t)
(command "LAYOUT" "N" "PlotBlks");Option to use a layout tab to plot blocks
(command "LAYOUT" "S" "PlotBlks")
(command "LAYER" "S" "0" "");Optional layer for text
(setq AttReq# (getvar "ATTREQ"))
(setvar "ATTREQ" 0)
(foreach BlockName$ (GetBlockList)
(command "ERASE" "ALL" "")
(command "INSERT" BlockName$ "0,0" "" "" "")
(command "ZOOM" "E")
(setq Height~ (/ (distance (getvar "EXTMIN") (getvar "EXTMAX")) 50.0))
(setq X-Min~ (car (getvar "EXTMIN"))
X-Max~ (car (getvar "EXTMAX"))
X-Mid~ (+ X-Min~ (/ (- X-Max~ X-Min~) 2.0))
Y-Min~ (cadr (getvar "EXTMIN"))
Y-Mid~ (- Y-Min~ Height~)
InsPt (list X-Mid~ Y-Mid~)
);setq
(command "TEXT" "M" InsPt Height~ 0 BlockName$);The default font has no height set
(PlotDwgs)
);foreach
(setvar "ATTREQ" AttReq#)
(command "ERASE" "ALL" "")
(princ)
);defun c:PlotBlks

(defun GetBlockList (/ BlockList@ Block$ List@)
(if (setq List@ (tblnext "BLOCK" t))
(while List@
(setq Block$ (cdr (assoc 2 List@)))
(if (/= (substr Block$ 1 1) "*")
(setq BlockList@ (append BlockList@ (list Block$)))
);if
(setq List@ (tblnext "BLOCK"))
);while
);if
(if BlockList@
(setq BlockList@ (Acad_StrlSort BlockList@))
);if
BlockList@
);defun GetBlockList

ccowgill
2007-11-07, 09:59 PM
I would assume the blocks are defined in the drawing. They are just not visibly placed in the drawing.

Your assumption is exactly what I meant Terry, I will give your program a shot and see how well it works.

Terry Cadd
2007-11-07, 10:13 PM
It's getting it's default ctb Plot Style setting from the previous plot from PlotDwgs, so I recommend plotting an A-Size with your preferred ctb Plot Style selection. Else you can just hard code it in the PlotBlks.lsp file. The file it is reading in is C:\Temp\PlotDwgs.dat so you can just open it and review it.

ccowgill
2007-11-07, 10:15 PM
It's getting it's default ctb Plot Style setting from the previous plot from PlotDwgs, so I recommend plotting an A-Size with your preferred ctb Plot Style selection. Else you can just hard code it in the PlotBlks.lsp file. The file it is reading in is C:\Temp\PlotDwgs.dat so you can just open it and review it.

what about a defined page setup? I'll mess around with it when I get a chance. We still need to finish updating our blocks before we start reprinting our standards book.

ccowgill
2007-11-08, 05:13 PM
I got it working. Is there a way to modify it so I can get a list of all blocks in the block library, and deselect the ones we dont want to plot, using a dialog. I have no experience with dialogs, but I would really like to learn how to use them.

Terry Cadd
2007-11-08, 05:25 PM
Yes, I can direct the list into the second dialog that current allows you to select or unselect files in folders. But I won't be able to get around to it until later. I was a little surprised how quickly I was able to incorporate your request to plot blocks. My first thought was, "It wasn't meant for that.".

ccowgill
2007-11-08, 05:55 PM
it might help if I posted the code that I am using for this, I took your code and removed parts that referenced other programs. I ended up hardcoding the plot settings to get it to work for what I need.

(DEFUN C:PLOTBLOCK ()
(command "LAYOUT" "N" "PlotBlks");Option to use a layout tab to plot blocks
(command "LAYOUT" "S" "PlotBlks")
(command "LAYER" "S" "0" "");Optional layer for text
(setq AttReq# (getvar "ATTREQ"))
(setvar "ATTREQ" 0)
(foreach BlockName$ (GetBlockList)
(command "ERASE" "ALL" "")
(command "INSERT" BlockName$ "0,0" "" "" "")
(command "ZOOM" "E")
(setq Height~ (/ (distance (getvar "EXTMIN") (getvar "EXTMAX")) 50.0))
(setq X-Min~ (car (getvar "EXTMIN"))
X-Max~ (car (getvar "EXTMAX"))
X-Mid~ (+ X-Min~ (/ (- X-Max~ X-Min~) 2.0))
Y-Min~ (cadr (getvar "EXTMIN"))
Y-Mid~ (- Y-Min~ Height~)
InsPt (list X-Mid~ Y-Mid~)
);setq
(command "TEXT" "M" InsPt Height~ 0 BlockName$);The default font has no height set
(COMMAND "-PLOT" "Y" "" "SAVIN 2055.PC3" "Letter (8.5\" x 11\")" "" "LANDSCAPE" "" "e" "FIT" "CENTER" "" "ENGLISH8X11.CTB" "Y" "N" "N" "N" "N" "N" "Y")
);foreach
(setvar "ATTREQ" AttReq#)
(command "ERASE" "ALL" "")
(princ))
(defun GetBlockList (/ BlockList@ Block$ List@)
(if (setq List@ (tblnext "BLOCK" t))
(while List@
(setq Block$ (cdr (assoc 2 List@)))
(if (/= (substr Block$ 1 1) "*")
(setq BlockList@ (append BlockList@ (list Block$)))
);if
(setq List@ (tblnext "BLOCK"))
);while
);if
(if BlockList@
(setq BlockList@ (Acad_StrlSort BlockList@))
);if
BlockList@
);defun GetBlockList

Terry Cadd
2007-11-08, 06:42 PM
Well it looks like all you needed was a "jump start" and you're already on your way.
Here's a quick revision of the dialog you can use in your function above.
Just above the line: (foreach BlockName$ (GetBlockList)
Add the line: (setq SelectedBlks@ (SelectBlks))
Then change the line to: (foreach BlockName$ SelectedBlks@

Here is the rest of the code and dialog that you'll need for (SelectBlks).


(defun SelectBlks (/ Dcl_Id% BlockNames@ Return# SelectAll$ SelectedBlks@ Set_Vars: Verify_Info:)
(princ "\nCommand:\nMulti-select Blocks to plot:\n")(princ)
; Set_Vars: - Set dialog tiles and variables
(defun Set_Vars: (ListName$ VarName$ / SaveVar$)
(setq SaveVar$ (eval (read VarName$)))
(if (= VarName$ "SelectAll$")
(progn
(setq SelectAll$ $value)
(if (= SelectAll$ "1")
(setq SelectedBlks@ BlockNames@)
(setq SelectedBlks@ (list nil))
);if
(set_tile_list "BlockNames" BlockNames@ SelectedBlks@)
);progn
);if
(if (= ListName$ "BlockNames@")
(progn
(set_multilist_value "BlockNames@" "SelectedBlks@")
(setq SaveVar$ SelectAll$)
(if (equal SelectedBlks@ BlockNames@)
(setq SelectAll$ "1")
(setq SelectAll$ "0")
);if
(if (/= SelectAll$ SaveVar$)
(set_tile "SelectAll" SelectAll$)
);if
);progn
);if
(set_tile_list "BlockNames" BlockNames@ SelectedBlks@)
);defun Set_Vars:
; Verify_Info: - Verifies dialog information
(defun Verify_Info: ( )
(if (equal SelectedBlks@ (list nil))
(alert "Select one or more Blocks to plot.")
(done_dialog 1)
);if
);defun Verify_Info:
; Set Default Variables and List Values
(setq BlockNames@ (GetBlockList)
SelectedBlks@ (list nil)
SelectAll$ "0"
);setq
; Load Dialog SelectBlks
(setq Dcl_Id% (load_dialog "PlotBlks.dcl"));<<<<<< Change filename as required
(new_dialog "SelectBlks" Dcl_Id%)
; Set Dialog Initial Settings
(set_tile_list "BlockNames" BlockNames@ SelectedBlks@)
(set_tile "SelectAll" SelectAll$)
; Dialog Actions
(action_tile "BlockNames" "(Set_Vars: \"BlockNames@\" \"SelectedBlks@\" )")
(action_tile "SelectAll" "(Set_Vars: \"\" \"SelectAll$\" )")
(action_tile "accept" "(Verify_Info:)")
(setq Return# (start_dialog))
(unload_dialog Dcl_Id%)
(if (= Return# 0) (exit))
SelectedBlks@
);defun SelectBlks
;-------------------------------------------------------------------------------
; set_multilist_value - Sets SentVar$ to list of the items selected in SentList$
; Arguments: 2
; SentList$ = String of the list variable name
; SentVar$ = String of the variable name
; Syntax: (set_multilist_value "ListName" "Variable")
;-------------------------------------------------------------------------------
(defun set_multilist_value (SentList$ SentVar$ / SubList@)
(setq SubList@ (eval (read SentList$)))
(set (read SentVar$) (list (nth (atoi $value) SubList@)))
(setq $value (substr $value (+ (strlen (itoa (atoi $value))) 2)))
(while (/= $value "")
(set (read SentVar$) (append (eval (read SentVar$))
(list (nth (atoi $value) SubList@)))
);set
(setq $value (substr $value (+ (strlen (itoa (atoi $value))) 2)))
);while
);defun set_multilist_value
;-------------------------------------------------------------------------------
; set_tile_list - Sets a dialog popup_list or list_box tile to a list
; Arguments: 3
; KeyName$ = Key name of tile
; ListName@ = The list to set in tile
; Selected = An item in the ListNames@ or a list of items selected
; Syntax: (set_tile_list "TileName" '("A" "B" "C") "B")
; (set_tile_list "TileName" '("A" "B" "C") '("A" "C"))
; Returns: Sets Selected items in dialog popup_list or list_box tiles.
;-------------------------------------------------------------------------------
(defun set_tile_list (KeyName$ ListName@ Selected / Item)
(start_list KeyName$ 3)
(mapcar 'add_list ListName@)
(end_list)
(foreach Item (if (listp Selected) Selected (list Selected))
(if (member Item ListName@)
(set_tile KeyName$ (itoa (- (length ListName@) (length (member Item ListName@)))))
);if
);foreach
);defun set_tile_list



SelectBlks : dialog {
key = "Title";
label = " Plot Blocks in Drawing";
spacer;
: boxed_column {
label = "Multi-select Blocks to plot";
: list_box {
multiple_select = true;
key = "BlockNames";
height = 11.20;
fixed_height = true;
width = 27.92;
fixed_width = true;
}
spacer_0;
: row {
alignment = centered;
fixed_width = true;
spacer;
: toggle {
key = "SelectAll";
label = "Select all Blocks";
}
}
spacer_0;
}
: row {
: column {
: ok_button {
alignment = right;
width = 11;
}
}
: column {
: cancel_button {
alignment = left;
width = 11;
}
}
}
}// SelectBlks

ccowgill
2007-11-09, 01:34 PM
I have no experience with dialog boxes, how do I get it to load the new dialog, I saved it as a dcl, and loaded it, but it gives me this error:


Multi-select Blocks to plot:
; error: quit / exit abort

Terry Cadd
2007-11-10, 05:06 PM
On the following line be sure that the dialog filename is the same as what you decided to name your dialog dcl file.
So if you want to name it something other that PlotBlocks.dcl change it in this line in the AutoLISP code.

(setq Dcl_Id% (load_dialog "PlotBlocks.dcl"));<<<<<< Change filename as required

I've merged your code and mine into the two attached files: PlotBlocks.lsp and PlotBlocks.dcl
After loading PlotBlocks type "PlotBlocks" to run the function.

ccowgill
2007-11-13, 02:14 PM
works great, it made printing out our block library a breeze.

Terry Cadd
2008-07-19, 07:42 AM
I recently helped someone configure PlotDwgs for AutoCAD 2008. All that I requested from him was to plot two or three successful dialog plots followed by the command line version of the -PLOT command of the different sizes he uses. From that -PLOT text screen information I was able to email him the necessary configuration changes.

The most common problems that new users are having, is that they see a single slash "\" in the -PLOT text screen data, and they need to remember that AutoLISP needs to have double slashes "\\" for each single slash "\" that they see in the -PLOT text screen data.

I'd be glad to help you configure your settings for PlotDwgs. As mentioned above, all that I need is two or three successful dialog plots followed by the command line versions of the -PLOT command of the different sizes.

Regards,
Terry

ccowgill
2009-02-13, 07:53 PM
Is there a way to get this when you plot to automatically name the files if you are plotting to file? What I am trying to accomplish is the publish command, but it names all plots by their layout tab name. I know this would cause an issue if they were all called Layout1, but our standard is to rename layout tabs Job_NO-Sheet_NO (09-000-01, 09-000-02, etc.)
I want the plotfile name to be 09-000-01.plt

Terry Cadd
2009-02-14, 05:09 AM
Where there's a will, there's a work around. We've worked through a few challenges here, and there may be a viable alternative to fixing the dilemma with the naming convention of the Publish dialog. My first thought was to create a dialog function to run after the Publish dialog finishes. This new dialog function would list the *.plt files in the current drawing folder and have an edit box for the filename text that you would like to have removed. i.e. "Job_NO-Sheet_NO". The edit box will default to the common starting characters of all the files; otherwise it will just be blank. The RenameFile function below will do all the work in the background. Is this something that you think is worth looking in to? Someone else here may have a better alternative.
Terry

;-------------------------------------------------------------------------------
; RenameFile - Renames file in folder
; Arguments: 2
; OldFilename$ = Old filepath and filename
; NewFilename$ = New filepath and filename
; Returns: Renames file in folder
;-------------------------------------------------------------------------------
(defun RenameFile (OldFilename$ NewFilename$)
(if (findfile OldFilename$)
(if (= (vl-filename-directory OldFilename$) (vl-filename-directory NewFilename$))
(vl-file-rename OldFilename$ NewFilename$)
(alert (strcat "The files " OldFilename$ "\nand " NewFilename$ "\nmust be in the same folder."))
);if
(alert (strcat "The file " OldFilename$ " does not exist."))
);if
);defun RenameFile

ccowgill
2009-02-16, 02:08 PM
that's what I was thinking about doing if I couldnt get it to automatically name it as it went in. The problem is, how do I implement this. from what I can tell, I would have to have it grab the file name, strip everything left of the - and including the - and leave me with just the stuff on the right. However, we also use a - within the file name, separating the job number from the sheet number (09-000-01, and our other office X2009-01). other sheets are named by Eagle Point so they carry no dashes in the file name.

Terry Cadd
2009-02-16, 07:03 PM
We did something similar with your custom plot function. Here's just a few modifications to that one.
Terry
http://autolisp-exchange.com/images/RenamePlts.gif
Here's a quick view of the function. The attachments contain all the sub-functions and the dialog dcl file.

(defun c:RenamePlts (/ Dcl_Id% DwgPrefix$ FileName$ FolderFiles@ FolderName$
NewFilename$ OldFilename$ Prefix$ Return#)
(setq DwgPrefix$ (getvar "DWGPREFIX"))
(setq FolderName$ DwgPrefix$)
(if (> (nth 1 (DclTextWidth FolderName$)) 26);<-- change width here
(progn
(setq FolderName$ (strcat (substr FolderName$ 4) (substr FolderName$ 1 3) "..."))
(while (> (nth 1 (DclTextWidth FolderName$)) 26);<-- change width here
(setq FolderName$ (substr FolderName$ 2))
);while
(setq FolderName$ (strcat (substr FolderName$ (- (strlen FolderName$) 5))
(substr FolderName$ 1 (- (strlen FolderName$) 6)))
);setq
);progn
);if
(if (setq FolderFiles@ (vl-directory-files DwgPrefix$ "*.plt" 1))
(progn
(setq Prefix$ (CommonPrefix FolderFiles@))
(setq Dcl_Id% (load_dialog "RenamePlts.dcl"))
(new_dialog "RenamePlts" Dcl_Id%)
(set_tile "Title" " Rename Plt Files")
(set_tile "FolderName" FolderName$)
(set_tile_list "FileList" FolderFiles@ "")
(set_tile "RemovePrefix" "Remove Prefix")
(set_tile "EditPrefix" Prefix$)
(action_tile "EditPrefix" "(setq Prefix$ $value)")
(action_tile "accept" "(done_dialog 1)")
(setq Return# (start_dialog))
(unload_dialog Dcl_Id%)
(if (= Return# 0) (exit))
(foreach FileName$ FolderFiles@
(if (= (substr FileName$ 1 (strlen Prefix$)) Prefix$)
(progn
(setq OldFilename$ (strcat DwgPrefix$ FileName$))
(setq NewFilename$ (strcat DwgPrefix$ (substr FileName$ (1+ (strlen Prefix$)))))
(RenameFile OldFilename$ NewFilename$)
);progn
);if
);foreach
);progn
(alert (strcat "There are no plt files in the folder\n" DwgPrefix$ "."))
);if
(princ)
);defun c:RenamePlts

ccowgill
2009-02-17, 01:37 PM
the only problem is, the prefix isnt consistent, it varies on every sheet. The attached screen shot shows what the files should look like (plotted one at a time using AutoPlot to File) and the results after the publish command. I guess what I probably really need is a way to run my custom AutoPlot to file command on a selection of drawings.

And while I am thinking of it, how do you get your dialog boxes to appear in your message, not as an attached thumbnail?