OpenDCL Forums

OpenDCL => Show and Tell => Topic started by: jb on August 15, 2008, 09:57:12 AM

Title: Batch drawing processor
Post by: jb on August 15, 2008, 09:57:12 AM
This was originally posted over at theSwamp.org.

Using nothing more than a custom partial menu and OpenDCL!

Warning: this is a batch processing program that opens, modifies and closes drawings without giving you the opportunity to interact.  So before trying it out, set up a test folder with a few drawings in it.

How to use:
Unzip the files to a folder, making sure it's in AutoCAD's search path.  Menuload the partial menu, Batch.mns.  Now for some reason the menuload command doesn't load the corresponding .mnl file so you'll have to open up a fresh drawing to load the BatchProject.lsp.  Yes, this could also be done with an acadDoc.lsp in lieu of the menu.

The calling command is "Batchthis".

(http://i283.photobucket.com/albums/kk302/bothetraveler/Batch.jpg?t=1218812976)

The BatchProject.lsp file is pretty well documented (well extremely well documented for me!) so I won't go into much detail here.  The Batch.odcl file is the OpenDCL project definition file that is edited in the studio editor.  Batch.lsp is the compiled code that I cut and paste into BatchProject.lsp.  Now you can just use the Batch.lsp in the Studio Editor and do away with the Batch.odcl, but I like to keep them separate.  Why? well, once I accidental screwed up the OpenDCL lisp file in the VLIDE editor.  :oops:

The place in the lisp that you'll add the code that modifies the drawing is here:

(defun Batch:Process (/ )
      (dcl_Control_SetCaption
Batch_00_DWGName
(strcat "Processing " (getvar "dwgname"))
)
    ;run the process here - put your edit functions here

      (command "circle" "0,0,0" "50")

    ;close the document
      (command "close" "n")
      (princ)
      (princ)
)


You'll see that I use nothing fancy, just some command calls.  You can add any type of lisp stuff.  I'm going to set up some subs and just call them here like: (kb_EditTitleBLock) - stuff like that.

You'll also notice I just use (command "close" . . . ) to close the document.  This is a beta because I want to speed things up by processing all the drawings first and then use (vla-close to save and close all the processed drawings.  I haven't figured out haw to not close the calling document yet  - but I'm working on it.

Well, have at it and let me know what you think.

jb


Title: Re: Batch drawing processor
Post by: cmwade77 on August 26, 2008, 09:33:15 AM
Hopefully this works better than my attempt at doing something like this, I will have to take a look, thank you so much.
Title: Re: Batch drawing processor
Post by: jb on September 03, 2008, 05:56:58 AM
Had any luck?

Make sure to let us know if you come up with anything interesting!
Title: Re: Batch drawing processor
Post by: cmwade77 on September 15, 2008, 01:57:43 PM
This was a great starting point, unfortunately I do not believe mine would be of any interest, as it is so heavily customized for our office standards. But again, thank you to the OP, I still have a few bugs to iron out.
Title: Re: Batch drawing processor
Post by: cmwade77 on May 07, 2009, 03:20:32 PM
Ok, so now that 2010 no longer includes VBA, how can I open and close documents without using the VBASTMT, so that I don't have to install it for this one routine, so far everything that I have tried has failed miserably.
Title: Re: Batch drawing processor
Post by: jb on May 25, 2009, 08:59:42 AM
Owen . . . oh Owen . . .

Maybe the great one can roll the ARX function for opening a drawing into OpenDCL?  How hard would it be / would it conflict with a product(s) already on the market??
Title: Re: Batch drawing processor
Post by: owenwengerd on May 25, 2009, 09:43:50 AM
What exactly is the problem? I'll bet it can be solved with a little creative lisp.
Title: Re: Batch drawing processor
Post by: Fred Tomke on May 25, 2009, 11:27:46 AM
... sometimes I'll do such things via ObjectDBX

Code (autolisp) Select

(defun DBX_OPEN (strFile / strRel reaRel strDBX oDbx)
  (setq strRel (substr (getvar "ACADVER") 1 2))
  (setq reaRel (float strRel))
  (if (<= reaRel 15.0)
    (setq strDBX "ObjectDBX.AxDbDocument")
    (setq strDBX (strcat "ObjectDBX.AxDbDocument." strRel))
  ); if
 
  (if (vl-catch-all-error-p (setq oDbx (vl-catch-all-apply 'vla-GetInterfaceObject (list (vlax-get-acad-object) strDBX))))
    (setq oDbx nil)
    (if (vl-catch-all-error-p (vl-catch-all-apply 'vla-open (list oDbx strFile)))
      (progn
(vlax-release-object oDbx)
        (setq oDbx nil)
      ); progn
    ); if
  ); if
  oDbx
); DBX_OPEN

(defun LIST_LAYERS (strDWG / oDbx oLayers lstLayers)
  (setq oDbx (DBX_OPEN strDWG))
  (setq oLayers (vla-get-layers oDbx))
  (vlax-for oLayer oLayers
    (setq lstLayers (cons (vla-get-name oLayer) lstlayers))
    (vlax-release-object oLayer)
  ); vlax-for
  (vlax-release-object oLayers)
  (vl-catch-all-apply 'vla-close (list oDbx))
  (vlax-release-object oDbx)
  (setq lstLayers (vl-sort lstLayers '(lambda (a b) (< (strcase a) (strcase b)))))
  lstLayers
); LIST_LAYERS

(vl-load-com)
(LIST_LAYERS "MyDwg.dwg")


Fred
Title: Re: Batch drawing processor
Post by: Marco Jacinto on May 25, 2009, 01:16:44 PM
what i do to open and close a file (or a lot of them) is to open a second instance of AutoCAD and do all the batch processing here, having it invisible makes it looks like if it is in the same session of AutoCAD.
Title: Re: Batch drawing processor
Post by: jb on May 27, 2009, 10:41:28 AM
Owen the problem with lisp is because of document object dependency: vla-open returns to the calling document to complete, where as the VBA equivalent does not ( don't remember the syntax ).  I used the command "vbastmnt" to issue the open document function.  So, in 2010 if the VBA module isn't loaded I'm assuming the function fails ( don't have 2010 ).

To my knowledge there is no way to open a document with AutoLISP / VLISP and not return to dependent calling document.

Fred: I use ObjectDBX for a multiple of things and am well aware of it's potential, but it has some major problems with the Verticals ( I use Architecture ) so for this routine I wanted something with more control and access to the defined AEC commands.

jb
Title: Re: Batch drawing processor
Post by: owenwengerd on May 27, 2009, 11:36:06 AM
I've always used Marco's approach for batch processing (opening an invisible session of AutoCAD in the background). However, I think you could use (dcl_SendString) to duplicate the VBA Open functionality.
Title: Re: Batch drawing processor
Post by: Fred Tomke on May 27, 2009, 10:50:49 PM
Hi James,

Quoteit has some major problems with the Verticals

Oha, just to extend my knowledge: which problems this could be? Our customers use mainly Map and Civil, some Architecture, too.

Fred
Title: Re: Batch drawing processor
Post by: Kerry on May 28, 2009, 03:11:33 AM

Perhaps something like
Code (autolisp) Select

(defun c:OpenDwg ()
    ;; CodeHimbelongaKdub ©  May2009
    (vla-activate
        (vla-open (vla-get-documents
                      (vla-get-application (vlax-get-acad-object))
                  )
                  "c:\\Test_Drawing51.dwg"
        )
    )
)
Title: Re: Batch drawing processor
Post by: Kerry on May 28, 2009, 03:32:00 AM
Thank goodness for Copernic desktop Search
searched my hardrives for vla-activate
This was from Frank Whaley (fairly elderley :) ):-

Code (autolisp) Select

(defun cmdOpen (name)
  ;;; posted by Frank Whaley
  (vl-load-com)
  (if (= 0 (getvar "SDI"))
    (vla-activate (vla-open (vla-get-documents (vlax-get-acad-object)) name))
    (vla-sendcommand
        (vla-get-activedocument
            (vlax-get-acad-object))
                (strcat "(command \"_.OPEN\")\n" name "\n") )
  )
)
Title: Re: Batch drawing processor
Post by: jb on May 28, 2009, 12:30:38 PM
Fred: specifically with Styles and attached "extra" data such as materials, propertyset data, classifications, etc..  Say you have a door style with a classification defined.  When the door is imported via ObjectDBX, and the classification exists, a new classification is created: MyClass[1].  I ran into this along time ago and I think it happens with property data as well.  My work-around was to create a block with an object representing the style in the block and then use 'ImportBlock which brings the style in cleaner: but still won't work with classifications.  So I don't use classifications.

Owen: What argument to use with dcl_sendString? ".Open "?

jb
Title: Re: Batch drawing processor
Post by: owenwengerd on May 28, 2009, 01:30:33 PM
I didn't look at your original code, but presumably something like (dcl_SendString "FILEDIA 0 _OPEN \"MyDrawing.dwg\" FILEDIA 1 ").
Title: Re: Batch drawing processor
Post by: jb on May 29, 2009, 11:18:48 AM
Thanks Owen - when I have the time I'll give it a try.

Great Job! Sorry I can't be more involved.
Title: Re: Batch drawing processor
Post by: cmwade77 on May 29, 2009, 04:48:14 PM
Thank you all, I will also have to give it a try, I also think that once I have it all working, that it might now be something that is of some use to everyone on here and will post it, as it is now quite a powerful routine. Right now, I have it switching to SDI mode, but I prefer not to do that for various reasons.
Title: Re: Batch drawing processor
Post by: Kerry on May 29, 2009, 05:50:47 PM
Quote from: cmwade77 on May 29, 2009, 04:48:14 PM
< ... > Right now, I have it switching to SDI mode, but I prefer not to do that for various reasons.

yes, There is/was talk of eliminating SDI mode ...
http://through-the-interface.typepad.com/through_the_interface/2009/04/sdi-the-end-is-nigh.html (http://through-the-interface.typepad.com/through_the_interface/2009/04/sdi-the-end-is-nigh.html)
Title: Re: Batch drawing processor
Post by: cmwade77 on June 02, 2009, 12:09:56 PM
Quote from: Kerry Brown on May 28, 2009, 03:32:00 AM
Thank goodness for Copernic desktop Search
searched my hardrives for vla-activate
This was from Frank Whaley (fairly elderley :) ):-

Code (autolisp) Select

(defun cmdOpen (name)
  ;;; posted by Frank Whaley
  (vl-load-com)
  (if (= 0 (getvar "SDI"))
    (vla-activate (vla-open (vla-get-documents (vlax-get-acad-object)) name))
    (vla-sendcommand
        (vla-get-activedocument
            (vlax-get-acad-object))
                (strcat "(command \"_.OPEN\")\n" name "\n") )
  )
)


Unfortunately this does not seem to work, using SDI mode does, but this doesn't. I really want to get rid of SDI mode in my routine, it would help a lot. I have attached here in hopes that someone can help me out, I have tried various versions of the code. Please note that this is related to the Cleanup tab on here. As you can see we use this tool for a lot more than just batch scripting. Please note that as I have this posted, it is using SDI mode. This works and works well, but if SDI mode is to be removed, then it won't work anymore.
Title: Re: Batch drawing processor
Post by: Fred Tomke on June 02, 2009, 01:39:51 PM
Hi, cmwade77,

I tried to start, but it doesn't work because some functions are missing: DOS_GETDIR.
BTW, please test your dialog when resizing. The calendar control is very small at my desktop. Can you describe the steps what to do/click?

1. Make sure that your code will be loaded in all newly loaded drawings (for instance using vl-load-all).
2. Make sure that the dialog content or/and the variables are updated when the user switches between the drawings (using the event OnDocActivate).
3. Make sure that the dialog will be closed if all drawings are closed (using the event OnEnteringNoDocState).

ADN made a note towards recover:
QuoteKeep in mind the Recover command cannot be invoked using SendCommand()...

Fred
Title: Re: Batch drawing processor
Post by: Fred Tomke on June 02, 2009, 02:42:35 PM
cmwade77, I had a log try, but I'll give up now. I will try to built an own example for you to compare, but not now, I'm tired.
I'll be back soon.

Fred
Title: Re: Batch drawing processor
Post by: Kelie on June 02, 2009, 03:43:19 PM
Quote from: Fred Tomke on June 02, 2009, 01:39:51 PM

I tried to start, but it doesn't work because some functions are missing: DOS_GETDIR.


That's from a free tool DOSLib available at http://download.rhino3d.com/download.asp?id=doslib (http://download.rhino3d.com/download.asp?id=doslib)
Title: Re: Batch drawing processor
Post by: cmwade77 on June 02, 2009, 03:52:50 PM
Sorry, I forgot to post that DOSLib (which can also be downloaded at: http://www.en.na.mcneel.com/doslib.htm (http://www.en.na.mcneel.com/doslib.htm) ) is required for a lot of my functions. I am working on removing the dependency for this, but it is convenient.

The routine that I posted shouldn't be using Recover, I just had one set of stubborn files that I needed it for, but should be remarked out now, I will be doing something in the UI for that later.

To use the routine, you need to remark out anything you don't need in the c:rtools_bsr routine, there are a lot of powerful things going on there, but some are company specific of course.

Step by step instructions once you have done that:
Type rtools to open the palette
Make sure you only have one open drawing
Click on the cleanup tab
Select the folder that you have the files in that you want to cleanup
Select the folder that you want to copy the files to once you are done
Click Clean Now

Everything should be done automatically from this point, please note that the rtools_bsr routine does the following:

Converts all xrefs from overlay to attach
Changes all xref paths to relative
Changes the drawing from color based plotting to style based plotting (you may wish to remark out this line)
Changes all items to bylayer for color and plot style
Changes all layers to color 8 and to plot with a shaded plot style (again you may wish to modify this line)
Completely Purges the drawing

There are a few other items as well, but this is the basic overview of what it does as I have it setup now.
Title: Re: Batch drawing processor
Post by: Fred Tomke on June 02, 2009, 10:51:27 PM
Hm, I'm just thinking about doing these points by ObjectDBX or by script. RECOVER only works with script.
Fred
Title: Re: Batch drawing processor
Post by: Fred Tomke on June 03, 2009, 05:28:39 AM
Hi cmwade77, I send you something to test with MDI interface.
Yes, it is a completely different project to yours but maybe it fences your desires.

1. Selecting a source folder all the drawings in it will be shown in the list below.
2. Not existing folders will be created by Scripting.FileSystemObject object.
3. If no file is selected and you press Clean it up now! all the files will be cleaned.
4. If some files are selected only the selected files will be cleaned up.
5. If you doubleclick a file in the list this files will be cleaned.
6. The grid at the bottom shows the options what to clean or how the file is to be opened or saved.
7. The splitter between grid and listbox shows you how to work with the geometry (compare your settings with the settings of this project).
8. The grid will be replaced by a multiline textbox showing the protocol of current actions. This sample shows how to add line by line and making sure that the last line will be visible.
9. During the progress the button Clean it up now! turns to Stop it now! so the user has the chance to cancel the progress after the active loop. After clicking Stop it now! the button turns to Cancelling... until the progress stops.

The problem was the RECOVER command. In this case you have to work with scripts. But you can call your own cleaning operations from a script, too. You will find such a solution in this project. But to use this it is necessary to load the lisp in all files. One solution could be is calling (vl-load-all "clean.lsp") at the beginning (instead of load). Although the example from ADN shows multiple RECOVER commands within one script file it stops right before the next file will be opened. I took this negative experience to my advantage and created an option to exit the loop manually (as mentioned above at point 9).

My English is not good but I hope you understand my dialog.

Fred
Title: Re: Batch drawing processor
Post by: susanruswick on July 10, 2009, 06:13:00 PM
wow you sure know a lot about this stuff jb.
Title: Re: Batch drawing processor
Post by: jb on July 13, 2009, 09:00:48 AM
just enough to be extremely dangerous . . . ;)