ripuz Posted March 13, 2014 Posted March 13, 2014 Hi! I would like to create a pdf each time a drawing is saved. My first thought was to use a reactor for this but in a reactor callback function one can not use 'command' ... I guess it´s not possible to create a pdf without using a 'command' (for example plot or publish)? Someone have another idea? Quote
Snownut Posted March 13, 2014 Posted March 13, 2014 If you want to include AutoSaves it needs to be a reactor. Quote
rkent Posted March 13, 2014 Posted March 13, 2014 2014 has an Auto publish, maybe it was there in 2012 also. Options, Plot and Publish, lower left for Auto Publish. Quote
jsowinski Posted March 13, 2014 Posted March 13, 2014 You're right about not being able to use "command" in a reactor, but I've had some luck using "vla-sendcommand". I set the plot function to accept the default prompts in a layout tab. I am using AutoCAD 2013 Architecture and the code worked for me. Hopefully this will help you. (defun endCommand (calling-reactor endcommandInfo / doc) (if (wcmatch (car endcommandInfo) "*SAVE") (progn (setq doc (vla-get-activedocument (vlax-get-acad-object))) (vla-sendcommand doc "-plot\r\r\r\r\r\r\r\r") ) ) ) ; END OF COMMAND REACTOR (vlr-command-reactor nil '((:vlr-commandEnded . endCommand))) Quote
Snownut Posted March 13, 2014 Posted March 13, 2014 I believe another option would be to redefine the "SAVE" command to include the plot function. Quote
BIGAL Posted March 14, 2014 Posted March 14, 2014 You can also edit the cui and add a plot function prior to doing the save, I would use a predefined lisp defun for the plot part http://www.cadtutor.net/forum/showthread.php?69132-Printing-LISP-Help...&highlight=Printing-LISP Quote
ripuz Posted March 14, 2014 Author Posted March 14, 2014 You're right about not being able to use "command" in a reactor, but I've had some luck using "vla-sendcommand". I set the plot function to accept the default prompts in a layout tab. I am using AutoCAD 2013 Architecture and the code worked for me. Hopefully this will help you. (defun endCommand (calling-reactor endcommandInfo / doc) (if (wcmatch (car endcommandInfo) "*SAVE") (progn (setq doc (vla-get-activedocument (vlax-get-acad-object))) (vla-sendcommand doc "-plot\r\r\r\r\r\r\r\r") ) ) ) ; END OF COMMAND REACTOR (vlr-command-reactor nil '((:vlr-commandEnded . endCommand))) Hi jsowinski, If a reactor fires when a command is executed and the reactors callback function executes a new command... that should be an infinite loop? Kind regards Quote
BlackBox Posted March 14, 2014 Posted March 14, 2014 (edited) 2014 has an Auto publish, maybe it was there in 2012 also. Options, Plot and Publish, lower left for Auto Publish. 1+ I've been using Autopublish since 2011. It has been invaluable to my work over the past few years. See AUTOMATICPUB sysvar. The only area Autpublish is greatly lacking, is context... It produces an electronic file for each-and-every-single drawing, regardless of the drawing being an exhibit, sheet, model/xref, etc. (no need to print the latter), which is why I developed this plug-in a few years ago, and recently published it at Autodesk Exchange for those who may be interested (it was selected by Autodesk as a 'featured new app' December 2013). Cheers Edited March 14, 2014 by BlackBox Quote
BlackBox Posted March 14, 2014 Posted March 14, 2014 If a reactor fires when a command is executed and the reactors callback function executes a new command... that should be an infinite loop? I cannot comment on the use of vla-SendCommand specifically, as I do not use that function, let alone in the context of a reactor... However, speaking to reactors generally, as most of my apps are event-driven: (Same sequencing applies to .NET Event Handlers) If the correct conditions are met within your callback, you first unregister your CommandWillStart Event, then hook the CommandEnded, CommandCancelled, and/or CommandFailed Events, and finally proceed to call/invoke what you need (i.e., vla-SendCommand, or in .NET SendStringToExecute, SendCommand, acedPostCommand, etc.). [Edit] - Once the CommandEnded, CommandCancelled, or CommandFailed event is raised, you unregister same, and register your CommandWillStart event again. Also note that sufficient code logic (testing for the correct command, etc.) may be sufficient to preclude an endless loop, despite the CommandWillStart event handler (callback) being evaluated each time a Command is invoked. Hope that makes (more?) sense? Quote
jsowinski Posted March 17, 2014 Posted March 17, 2014 Hi ripuz- Having a potential infinite loop is a good concern. However, the wildcard match in the endcommand function will only respond to "save" or "qsave". Otherwise it will ignore all other commands. As to executing a command inside the function. (such as "-plot") The vla-sendcommand will only process -plot one time. It won't place itself into a loop because "-plot" doesn't end with a "(q)save". I hope that makes sense. The internal command to plot a pdf is based on what the page setup manager is configured for in a layout tab. I thought it would be easier to just accept the default settings. However, it can be modified to a specific plotter/printer if needed. Thanks. Quote
ripuz Posted March 20, 2014 Author Posted March 20, 2014 Hi, First I'd like to thank you for all the answers. Here's a summary of what I came up with. I tried three different ways of doing this... 1. AutoPublish 2. VLA-SendCommand in a reactor 3. Redefine save command Code of "AutoPublish" solution. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; ;;;; Function to turn layers On or Off. ;;;; ;;;; Ex. ;;;; ;;;; In: (okg:LayerOn "SOSED_DESIGN" T) ;;;; ;;;; Out: Silent. ;;;; (defun okg:LayerOn (layer x) (if (not (vl-catch-all-error-p (setq layer (vl-catch-all-apply 'vla-item (list (vla-get-layers (vla-get-ActiveDocument (vlax-get-acad-object))) layer))))) (if x (vlax-put layer 'layeron 1) (vlax-put layer 'layeron 0) ) ) (princ) ) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; ;;;; Set current plot settings. ;;;; (command "-plot" "Y" "Model" "DWG To PDF.pc3" "ISO full bleed A3 (420.00 x 297.00 MM)" "Millimeter" "Landscape" "N" "E" "F" "C" "Y" "elmaster.ctb" "Y" "As displayed" "c:\\temp\\temp.pdf" "Y" "N") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; ;;;; AutoPublish Settings. ;;;; ; AutoPublish turned on (setvar "AUTOMATICPUB" 1) ; Publish on = Save (vl-registry-write "HKEY_CURRENT_USER\\Software\\Autodesk\\AutoCAD\\R18.2\\ACAD-A001:409\\Profiles\\Master Concept 11 (SWE)\\Dialogs\\AcAutoPublishOpts" "PublishOn" 0) ; Location = .\DWF and PDF(sub-folder relative to drawing folder) (vl-registry-write "HKEY_CURRENT_USER\\Software\\Autodesk\\AutoCAD\\R18.2\\ACAD-A001:409\\Profiles\\Master Concept 11 (SWE)\\Dialogs\\AcAutoPublishOpts" "PublishTo" 2) ; Include = Model (vl-registry-write "HKEY_CURRENT_USER\\Software\\Autodesk\\AutoCAD\\R18.2\\ACAD-A001:409\\Profiles\\Master Concept 11 (SWE)\\Dialogs\\AcAutoPublishOpts" "IncludeOption" 0) ; File format = PDF (vl-registry-write "HKEY_CURRENT_USER\\Software\\Autodesk\\AutoCAD\\R18.2\\ACAD-A001:409\\Profiles\\Master Concept 11 (SWE)\\Dialogs\\AcAutoPublishOpts" "EplotFormat" 3) ; Type = Single-sheet file (vl-registry-write "HKEY_CURRENT_USER\\Software\\Autodesk\\AutoCAD\\R18.2\\ACAD-A001:409\\Profiles\\Master Concept 11 (SWE)\\Dialogs\\AcAutoPublishOpts" "MultiSheetFile" 0) ; Layer information = Include (vl-registry-write "HKEY_CURRENT_USER\\Software\\Autodesk\\AutoCAD\\R18.2\\ACAD-A001:409\\Profiles\\Master Concept 11 (SWE)\\Dialogs\\AcAutoPublishOpts" "IncludeLayerInfo" 1) ; Merge control = Lines overwrite (vl-registry-write "HKEY_CURRENT_USER\\Software\\Autodesk\\AutoCAD\\R18.2\\ACAD-A001:409\\Profiles\\Master Concept 11 (SWE)\\Dialogs\\AcAutoPublishOpts" "MergeControl" 0) ; Password protection = Disabled (vl-registry-write "HKEY_CURRENT_USER\\Software\\Autodesk\\AutoCAD\\R18.2\\ACAD-A001:409\\Profiles\\Master Concept 11 (SWE)\\Dialogs\\AcAutoPublishOpts" "DwfPwdProtected" 0) (vl-registry-write "HKEY_CURRENT_USER\\Software\\Autodesk\\AutoCAD\\R18.2\\ACAD-A001:409\\Profiles\\Master Concept 11 (SWE)\\Dialogs\\AcAutoPublishOpts" "PromptForPwd" 0) ; Block information = Don´t include (vl-registry-write "HKEY_CURRENT_USER\\Software\\Autodesk\\AutoCAD\\R18.2\\ACAD-A001:409\\Profiles\\Master Concept 11 (SWE)\\Dialogs\\AcAutoPublishOpts" "IncludeBlockInfo" 0) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; ;;;; Reactors that will turn off a specific layer before pdf creation. ;;;; ; Load reactor if not already loaded. (if (not (member "AutoPublishStart" (mapcar 'vlr-data (cdar (vlr-reactors :vlr-command-reactor))))) (setq r:AutoPublishWillStart (vlr-command-reactor "AutoPublishStart" '((:vlr-CommandWillStart . rf:AutoPublishWillStart)))) ) ; Load reactor if not already loaded. (if (not (member "AutoPublishEnd" (mapcar 'vlr-data (cdar (vlr-reactors :vlr-command-reactor))))) (setq r:AutoPublishEnded (vlr-command-reactor "AutoPublishEnd" '((:vlr-commandEnded . rf:AutoPublishEnded)))) ) ; Callback function that will turn off a layer before AutoPublish. (defun rf:AutoPublishWillStart (reactor commandName) (if (= commandName "AUTOPUBLISH") ; Here you put anything you want to do before the pdf is created. ; An example could be a timestamp on the pdf, but in this case I turn a layer off. (okg:LayerOn "SOSED_DESIGN" nil) ) ) ; Callback function that will turn on a layer after AutoPublish. (defun rf:AutoPublishEnded (reactor commandName) (if (= commandName "AUTOPUBLISH") ; Put things back to normal. (okg:LayerOn "SOSED_DESIGN" T) ) ) Code of "VLA-SendCommand in a reactor" solution. (if (not a) (setq a (vlr-command-reactor nil '((:vlr-commandEnded . endCommand)))) ) (defun endCommand (calling-reactor endcommandInfo / doc filedia fileName) (if (wcmatch (car endcommandInfo) "SAVE,QSAVE,SAVEAS") (progn (setq filedia (getvar "filedia")) (setvar "filedia" 0) ;(okg:layeron "SOSED_DESIGN" nil) (setq fileName "C:\\temp\\test.pdf") (if (findfile fileName) (setq fileName (strcat fileName "\r\Y")) ) (setq doc (vla-get-activedocument (vlax-get-acad-object))) (vla-sendcommand doc (strcat "-plot\rY\rModel\rDWG To PDF.pc3\rISO full bleed A3 (420.00 x 297.00 MM)\rMillimeter\rLandscape\rN\rE\rF\rC\rY\relmaster.ctb\rY\rA\r" fileName "\rN\rY\r")) (setvar "filedia" filedia) ;(okg:layeron "SOSED_DESIGN" T) ) ) ) Code of "Redefine save command" solution. (defun c:QSave () ; PDF (AddSomePdfFunction) ; QSave (command "_.qsave") ) (defun c:Save () ; PDF (AddSomePdfFunction) ; Save (command "_.save") ) (defun c:SaveAs() ; PDF (AddSomePdfFunction) ; SaveAs (command "_.saveas") ) Summary in words: "1. AutoPublish" Solution worked well and everything I wanted to do worked. It´s relatively simple to perform desired actions before and after the pdf creation, such as turning off a layer before and turning it back on afterwards. I recommend this solution. "2. VLA-SendCommand in a reactor" Solution worked but it was hard to preform desired actions before and after pdf creation. Personally I don´t like to use sendcommand in any language. I don´t recommend this solution. "3. Redefine save command" Works good and you have complete control. At my workplace the save-commands are already redefined so I will not use this method this time. I recommend this solution. Quote
Snownut Posted March 20, 2014 Posted March 20, 2014 Glad to hear you are considering redefining the "SAVE" Command as a viable option. There is no need to be fearful of redefining ACAD commands to customize the platform for the particular users requirements, exactly the reason it was given so much flexibility in the first place. Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.