December 2014

Sun Mon Tue Wed Thu Fri Sat
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      










« And now for a real birthday… | Main | Triangulating an AutoCAD sub-division mesh from a set of points using .NET »

June 24, 2009

Batch-processing AutoCAD drawings from LISP without SDI (take 2)

In this recent post we looked at an approach combining AutoLISP with a script generated on-the-fly to get around the fact that (command "_.OPEN" …) does nothing when SDI == 0. As mentioned in a comment in the post, I realised that the approach of using a single master script to do this is more prone to failure: a number of commands can cause scripts to stop executing, for instance, so it would be better practice to minimise the operations contained in a particular script to increase the application’s fault tolerance.

This modified approach was suggested by a member of our Engineering team in a recent thread (one that I came across after Monday’s post). It uses a data file to store a list of the drawings to process and only creates a script to load – and launch processing on – the next drawing in that list:

(defun C:BATCH(/ dwgs lsp-name data-name)

  (setq dwgs '("C:/A.DWG" "C:/B.DWG" "C:/C.DWG" "C:/D.DWG")

        lsp-name "c:/tmp.lsp"

        data-name "c:/dwgs.tmp"

  )

  (create-drawing-list data-name dwgs)

  (process-next-drawing data-name lsp-name "(create-circle)" T T)

  (princ)

)

 

(defun create-circle()

  (command "_.CIRCLE" "10,10,0" "5")

)

 

(defun create-drawing-list(data dwgs / f dwg)

 

  ;; Create data file containing the DWG names

 

  (setq f (open data-name "w"))

  (foreach dwg dwgs

    (write-line dwg f)

  )

  (close f)

)

 

;; Get the first drawing from the list, removing it

 

(defun get-next-drawing(data / dwg dwgs f)

 

  ;; Read in the whole list of DWGs

 

  (setq f (open data "r")

        dwgs '()

  )

  (while (setq dwg (read-line f))

    (setq dwgs (cons dwg dwgs))

  )

  (close f)

 

  ;; Reverse the list, take the head and write

  ;; back the remainder to the file

 

  (if (> (length dwgs) 0)

    (progn

      (setq dwgs (reverse dwgs)

            dwg (car dwgs)

            dwgs (cdr dwgs)

      )

 

      (setq f (open data "w"))

      (foreach dwg dwgs

        (write-line dwg f)

      )

      (close f)

    )

  )

  dwg

)

 

;; Process the current drawing and use a script to open

;; the next one in the list

 

(defun process-next-drawing(data lsp func save first / scr)

  (setq scr "c:/tmp.scr")

 

  ;; We only want to run the function if not the first

  ;; time called... the same for save

 

  (if (not first)

    (progn

      (eval (read func))

      (if save

        (command "_.QSAVE")

      )

    )

  )

 

  ;; Get the next DWG name from the file

 

  (setq dwg (get-next-drawing data))

 

  ;; If there is one, create a script to open it, reload

  ;; the application and process our function

 

  (if dwg

    (progn

      (create-script scr data dwg lsp save first)

      (command "_.SCRIPT" scr)

    )

 

    ;; For the last drawing we simply close it and

    ;; delete the now-empty data file

 

    (progn

      (vl-file-delete data)

      (vl-file-delete scr)

      (command "_.CLOSE")

    )

  )

) 

 

;; Create a script to close the current drawing and

;; open the next, calling back to our process function

;; (after having loaded the file that defines it)

 

(defun create-script(scr data dwg lsp save first / f)

  (setq f (open scr "w"))

  (if (not first)

    (write-line "_.CLOSE" f)

  )

  (write-line

    (strcat "_.OPEN \"" dwg "\"") f

  )

  (write-line

    (strcat "(load \"" lsp "\")") f

  )

  (write-line

    (strcat

      "(process-next-drawing \""

      data "\" \"" lsp "\" \"" func "\" "

      (if save "T" "nil") " nil)"

    )

    f

  )

  (close f)

  (princ)

)

I hope this is useful to people – as mentioned before, please do provide feedback on how/whether this works for you…

TrackBack

TrackBack URL for this entry:
http://www.typepad.com/services/trackback/6a00d83452464869e2011571501200970b

Listed below are links to weblogs that reference Batch-processing AutoCAD drawings from LISP without SDI (take 2):

blog comments powered by Disqus

Feed/Share

10 Random Posts