TheSwamp
Code Red => AutoLISP (Vanilla / Visual) => Topic started by: Amsterdammed on November 03, 2005, 07:48:54 AM
-
Hello,
I just ran the “Layer filter delete.lsp” from the post down here on this page and saw a dwg with the size of 2 MB limited to 400KB. So that is great.
Now I wonder:
We gave a lot of dwgs on our server, a lot of 3rd party dwgs with 20000+ layer filters, too.
Is there a way to approach the dwgs and run the “layer filter delete” WITHOUT opening the dwgs? (I know how to do it in a script with opening one for one).
Thanks in advance,
Bernd
-
you might be able to do it using ObjectDBX by importing the type libraries into vlisp
-
Here is one I put together for AutoCad 2000:
(defun LayerFiltersDelete (doc)
(vl-Catch-All-Apply
'(lambda ()
(vla-Remove
(vla-GetExtensionDictionary
(vla-Get-Layers doc)
)
"ACAD_LAYERFILTERS"
)
)
)
)
(defun w:*error* (msg)
(princ "\nError: ")
(princ msg)
(princ)
(if (and dbxdoc (not (vlax-object-released-p dbxdoc)))
(vlax-release-object dbxdoc)
)
(gc)
(princ)
)
(defun get_dwgs (path)
(mapcar '(lambda (x)
(mapcar '(lambda (y)
(strcat x "\\" y)
)
(vl-directory-files x "*.dwg" 1)
)
)
path
)
)
(defun c:lfd_odbx (/ kword folder file files dbxdoc of *error*)
(initget 1 "Yes No")
(setq kword (getkword
"Do you want to search in subdirectories? [Yes/No]: "
)
files (cond ((eq kword "Yes")
(apply 'append
(get_dwgs (*list_folders* (acet-ui-pickdir)))
)
)
((eq kword "No")
(setq file (getfiled "Select a File" "" "dwg" (+ 4 128)))
(car (get_dwgs (list (vl-filename-directory file))))
)
)
*error* w:*error*
)
(if (not (*DBX-Register*))
(*error* "Could not load the ObjectDBX Interface.")
)
(setq dbxdoc (vla-GetInterfaceObject
(vlax-get-acad-object)
"ObjectDBX.AxDbDocument"
)
)
(foreach f files
(setq of (vl-catch-all-apply
'(lambda ()
(vlax-invoke-method dbxdoc 'open f)
)
)
)
(if (vl-catch-all-error-p of)
(*error* (vl-catch-all-error-message of))
(progn
(LayerFiltersDelete dbxdoc)
(princ
(strcat "\nDeleting Layer Filters in " f)
)
(vla-saveas dbxdoc f)
)
)
)
(vlax-release-object dbxdoc)
(gc)
(princ)
)
-
Will,
I miss something in your code:
; error: no function definition: *LIST_FOLDERS*
Bernd
-
oops...sorry :oops:
Your actually missing some more too.
Just use this instead of what I posted earlier:
;;;
;;;Utilities to register ObjectDBX with AutoCAD 2K
;;;
(defun *DLLRegister* (dll)
(startapp "regsvr32.exe" (strcat "/s \"" dll "\""))
)
(defun *ProgID->ClassID* (ProgID)
(vl-registry-read
(strcat "HKEY_CLASSES_ROOT\\" progid "\\CLSID")
)
)
(defun *DBX-Register* (/ classname server)
(setq classname "ObjectDBX.AxDbDocument")
(cond
((*ProgID->ClassID* classname))
((and
(setq server (findfile "AxDb15.dll"))
(*DLLRegister* server)
(*ProgID->ClassID* classname)
)
(*ProgID->ClassID* classname)
)
((not (setq server (findfile "AxDb15.dll")))
(alert
"Error: Cannot locate ObjectDBX Type Library (AxDb15.dll)..."
)
)
(T
(*DLLRegister* classname)
(or
(*ProgID->ClassID* classname)
(alert
"Error: Failed to register ObjectDBX ActiveX services..."
)
)
)
)
)
;;;
;;;
;;;
(defun *layout_list* (/ lst)
(vlax-map-collection
(vla-get-layouts
(vla-get-activedocument (vlax-get-acad-object))
)
'(lambda (x) (setq lst (cons x lst)))
)
(cdr
(*sort* lst 'vla-get-taborder)
)
)
(defun *sort* (lst func)
(vl-sort lst
'(lambda (e1 e2)
(< ((eval func) e1) ((eval func) e2))
)
)
)
(defun LayerFiltersDelete (doc)
(vl-Catch-All-Apply
'(lambda ()
(vla-Remove
(vla-GetExtensionDictionary
(vla-Get-Layers doc)
)
"ACAD_LAYERFILTERS"
)
)
)
)
(defun w:*error* (msg)
(princ "\nError: ")
(princ msg)
(princ)
(if (and dbxdoc (not (vlax-object-released-p dbxdoc)))
(vlax-release-object dbxdoc)
)
(gc)
(princ)
)
(defun get_dwgs (path)
(mapcar '(lambda (x)
(mapcar '(lambda (y)
(strcat x "\\" y)
)
(vl-directory-files x "*.dwg" 1)
)
)
path
)
)
(defun c:lfd_odbx (/ kword folder file files dbxdoc of *error*)
(initget 1 "Yes No")
(setq kword (getkword
"Do you want to search in subdirectories? [Yes/No]: "
)
files (cond ((eq kword "Yes")
(apply 'append
(get_dwgs (*list_folders* (acet-ui-pickdir)))
)
)
((eq kword "No")
(setq file (getfiled "Select a File" "" "dwg" (+ 4 128)))
(car (get_dwgs (list (vl-filename-directory file))))
)
)
*error* w:*error*
)
(if (not (*DBX-Register*))
(*error* "Could not load the ObjectDBX Interface.")
)
(setq dbxdoc (vla-GetInterfaceObject
(vlax-get-acad-object)
"ObjectDBX.AxDbDocument"
)
)
(foreach f files
(setq of (vl-catch-all-apply
'(lambda ()
(vlax-invoke-method dbxdoc 'open f)
)
)
)
(if (vl-catch-all-error-p of)
(*error* (vl-catch-all-error-message of))
(progn
(LayerFiltersDelete dbxdoc)
(princ
(strcat "\nDeleting Layer Filters in " f)
)
(vla-saveas dbxdoc f)
)
)
)
(vlax-release-object dbxdoc)
(gc)
(princ)
)
-
Will,
indeed there were more missing.
But........... Sitll missing the *LIST_FOLDERS* function
Bernd
-
I get the same error as well Will.
When in doubt....search the forum :).
http://www.theswamp.org/forum/index.php?topic=3564.msg43226#msg43226
-
Hello,
I just ran the “Layer filter delete.lsp” from the post down here on this page and saw a dwg with the size of 2 MB limited to 400KB. So that is great.
Now I wonder:
We gave a lot of dwgs on our server, a lot of 3rd party dwgs with 20000+ layer filters, too.
Is there a way to approach the dwgs and run the “layer filter delete” WITHOUT opening the dwgs? (I know how to do it in a script with opening one for one).
Thanks in advance,
Bernd
Please be careful Amsterdammed, I've seen attempts at automatic fixes become automatic fubars. Backup your data, do exhaustive tests on representative sample data, have a recovery plan. You don't want to be the latest entry in this (http://www.theswamp.org/forum/index.php?topic=7494.msg94012#msg94012) thread.
-
Will,
So what the next step in troubleshooting when I get the error:
Error: Failed to register ObjectDBX ActiveX services...
Error: Could not load the ObjectDBX Interface.
Error: Automation Error. Problem in loading application
I changed the AxDb15.dll to AxDb16.dll since I'm on 2005.
So I did some searching in the registry and found that "ObjectDBX.AxDbDocument" is "ObjectDBX.AxDbDocument.16". Changed that but still getting the error:
Error: Automation Error. Problem in loading application
Thanks,
Ron
-
Right Micheael,
It still always scares me when a lot of things are done automatically. But we have everything on tape as back up, and I sure will not let a lisp run all over the server to change all the dwgs. But I will definitely use it for cleaning up 3rd party dwgs we use as xrefs.
But thanks for the reminder Michael, indeed I don’t want to join the “wound liking dogs” club.
Bernd
-
Sorry for the confusion guys:
This should work for 2000 and 2002:
;;;
;;;Utilities to register ObjectDBX with AutoCAD 2K
;;;
(defun *DLLRegister* (dll)
(startapp "regsvr32.exe" (strcat "/s \"" dll "\""))
)
(defun *ProgID->ClassID* (ProgID)
(vl-registry-read
(strcat "HKEY_CLASSES_ROOT\\" progid "\\CLSID")
)
)
(defun *DBX-Register* (/ classname server)
(setq classname "ObjectDBX.AxDbDocument")
(cond
((*ProgID->ClassID* classname))
((and
(setq server (findfile "AxDb15.dll"))
(*DLLRegister* server)
(*ProgID->ClassID* classname)
)
(*ProgID->ClassID* classname)
)
((not (setq server (findfile "AxDb15.dll")))
(alert
"Error: Cannot locate ObjectDBX Type Library (AxDb15.dll)..."
)
)
(T
(*DLLRegister* classname)
(or
(*ProgID->ClassID* classname)
(alert
"Error: Failed to register ObjectDBX ActiveX services..."
)
)
)
)
)
;;;
;;;
;;;
(defun *layout_list* (/ lst)
(vlax-map-collection
(vla-get-layouts
(vla-get-activedocument (vlax-get-acad-object))
)
'(lambda (x) (setq lst (cons x lst)))
)
(cdr
(*sort* lst 'vla-get-taborder)
)
)
(defun *sort* (lst func)
(vl-sort lst
'(lambda (e1 e2)
(< ((eval func) e1) ((eval func) e2))
)
)
)
(defun *list_folders* (path)
(defun get_folders (folder / f)
(mapcar '(lambda (x)
(cons (setq f (strcat folder "\\" x))
(apply 'append (get_folders f))
)
)
(cddr (vl-directory-files folder nil -1))
)
)
(cons path (apply 'append (get_folders path)))
)
(defun LayerFiltersDelete (doc)
(vl-Catch-All-Apply
'(lambda ()
(vla-Remove
(vla-GetExtensionDictionary
(vla-Get-Layers doc)
)
"AcLyDictionary"
)
)
)
)
(defun w:*error* (msg)
(princ "\nError: ")
(princ msg)
(princ)
(if (and dbxdoc (not (vlax-object-released-p dbxdoc)))
(vlax-release-object dbxdoc)
)
(gc)
(princ)
)
(defun get_dwgs (path)
(mapcar '(lambda (x)
(mapcar '(lambda (y)
(strcat x "\\" y)
)
(vl-directory-files x "*.dwg" 1)
)
)
path
)
)
(defun c:lfd_odbx (/ kword folder file files dbxdoc of *error* lst)
(initget 1 "Yes No")
(setq kword (getkword
"Do you want to search in subdirectories? [Yes/No]: "
)
files (cond ((eq kword "Yes")
(apply 'append
(get_dwgs (*list_folders* (acet-ui-pickdir)))
)
)
((eq kword "No")
(setq file (getfiled "Select a File" "" "dwg" (+ 4 128)))
(car (get_dwgs (list (vl-filename-directory file))))
)
)
*error* w:*error*
)
(if (not (*DBX-Register*))
(*error* "Could not load the ObjectDBX Interface.")
)
(setq dbxdoc (vla-GetInterfaceObject
(vlax-get-acad-object)
"ObjectDBX.AxDbDocument"
)
)
(foreach f files
(setq of (vl-catch-all-apply
'(lambda ()
(vlax-invoke-method dbxdoc 'open f)
)
)
)
(if (vl-catch-all-error-p of)
(setq lst (cons (vl-catch-all-error-message of) lst))
(progn
(LayerFiltersDelete dbxdoc)
(princ
(strcat "\nDeleting Layer Filters in " f)
)
(vla-saveas dbxdoc f)
)
)
)
(vlax-release-object dbxdoc)
(gc)
(if lst (princ lst))
(princ)
)
This should work for 2004:
(defun *layout_list* (/ lst)
(vlax-map-collection
(vla-get-layouts
(vla-get-activedocument (vlax-get-acad-object))
)
'(lambda (x) (setq lst (cons x lst)))
)
(cdr
(*sort* lst 'vla-get-taborder)
)
)
;;;
(defun *sort* (lst func)
(vl-sort lst
'(lambda (e1 e2)
(< ((eval func) e1) ((eval func) e2))
)
)
)
;;;
(defun *list_folders* (path)
(defun get_folders (folder / f)
(mapcar '(lambda (x)
(cons (setq f (strcat folder "\\" x))
(apply 'append (get_folders f))
)
)
(cddr (vl-directory-files folder nil -1))
)
)
(cons path (apply 'append (get_folders path)))
)
;;;
(defun LayerFiltersDelete (doc)
(vl-Catch-All-Apply
'(lambda ()
(vla-Remove
(vla-GetExtensionDictionary
(vla-Get-Layers doc)
)
"AcLyDictionary"
)
)
)
)
;;;
(defun w:*error* (msg)
(princ "\nError: ")
(princ msg)
(princ)
(if (and dbxdoc (not (vlax-object-released-p dbxdoc)))
(vlax-release-object dbxdoc)
)
(gc)
(princ)
)
;;;
(defun get_dwgs (path)
(mapcar '(lambda (x)
(mapcar '(lambda (y)
(strcat x "\\" y)
)
(vl-directory-files x "*.dwg" 1)
)
)
path
)
)
;;;
(defun c:lfd_odbx (/ kword folder file files dbxdoc of *error* lst)
(initget 1 "Yes No")
(setq kword (getkword
"Do you want to search in subdirectories? [Yes/No]: "
)
files (cond ((eq kword "Yes")
(apply 'append
(get_dwgs (*list_folders* (acet-ui-pickdir)))
)
)
((eq kword "No")
(setq file (getfiled "Select a File" "" "dwg" (+ 4 128)))
(car (get_dwgs (list (vl-filename-directory file))))
)
)
*error* w:*error*
)
(setq dbxdoc (vla-GetInterfaceObject
(vlax-get-acad-object)
"ObjectDBX.AxDbDocument.15"
)
)
(foreach f files
(setq of (vl-catch-all-apply
'(lambda ()
(vlax-invoke-method dbxdoc 'open f)
)
)
)
(if (vl-catch-all-error-p of)
(setq lst (cons (vl-catch-all-error-message of) lst))
(progn
(LayerFiltersDelete dbxdoc)
(princ
(strcat "\nDeleting Layer Filters in " f)
)
(vla-saveas dbxdoc f)
)
)
)
(vlax-release-object dbxdoc)
(gc)
(if lst (princ lst))
(princ)
)
This should work 2005 and 2006:
(defun *layout_list* (/ lst)
(vlax-map-collection
(vla-get-layouts
(vla-get-activedocument (vlax-get-acad-object))
)
'(lambda (x) (setq lst (cons x lst)))
)
(cdr
(*sort* lst 'vla-get-taborder)
)
)
;;;
(defun *sort* (lst func)
(vl-sort lst
'(lambda (e1 e2)
(< ((eval func) e1) ((eval func) e2))
)
)
)
;;;
(defun *list_folders* (path)
(defun get_folders (folder / f)
(mapcar '(lambda (x)
(cons (setq f (strcat folder "\\" x))
(apply 'append (get_folders f))
)
)
(cddr (vl-directory-files folder nil -1))
)
)
(cons path (apply 'append (get_folders path)))
)
;;;
(defun LayerFiltersDelete (doc)
(vl-Catch-All-Apply
'(lambda ()
(vla-Remove
(vla-GetExtensionDictionary
(vla-Get-Layers doc)
)
"ACAD_LAYERFILTERS"
)
)
)
)
;;;
(defun w:*error* (msg)
(princ "\nError: ")
(princ msg)
(princ)
(if (and dbxdoc (not (vlax-object-released-p dbxdoc)))
(vlax-release-object dbxdoc)
)
(gc)
(princ)
)
;;;
(defun get_dwgs (path)
(mapcar '(lambda (x)
(mapcar '(lambda (y)
(strcat x "\\" y)
)
(vl-directory-files x "*.dwg" 1)
)
)
path
)
)
;;;
(defun c:lfd_odbx (/ kword folder file files dbxdoc of *error* lst)
(initget 1 "Yes No")
(setq kword (getkword
"Do you want to search in subdirectories? [Yes/No]: "
)
files (cond ((eq kword "Yes")
(apply 'append
(get_dwgs (*list_folders* (acet-ui-pickdir)))
)
)
((eq kword "No")
(setq file (getfiled "Select a File" "" "dwg" (+ 4 128)))
(car (get_dwgs (list (vl-filename-directory file))))
)
)
*error* w:*error*
)
(setq dbxdoc (vla-GetInterfaceObject
(vlax-get-acad-object)
"ObjectDBX.AxDbDocument.16"
)
)
(foreach f files
(setq of (vl-catch-all-apply
'(lambda ()
(vlax-invoke-method dbxdoc 'open f)
)
)
)
(if (vl-catch-all-error-p of)
(setq lst (cons (vl-catch-all-error-message of) lst))
(progn
(LayerFiltersDelete dbxdoc)
(princ
(strcat "\nDeleting Layer Filters in " f)
)
(vla-saveas dbxdoc f)
)
)
)
(vlax-release-object dbxdoc)
(gc)
(if lst (princ lst))
(princ)
)
edit: Added functionality to print a list of drawings that were not changed.
-
Thanks will :).
One more question....how would one go about modifying this so it ignores readonly files rather than crashing the proggie?
-
Note that the use of ObjectDBX and saving the drawing loses the Drawing preview image. If you wish to maintain the image, see THIS (http://www.theswamp.org/forum/index.php?topic=7335.msg91135#msg91135) post that uses a helper app. If you need help implementing it just let me know.
ronjonp, you will need to wrap the Saveas line into a vl-catch-all-apply function. I would suggest placing the name of any file that cannot be saved into a text file so you know which ones were not modified.
-
Thanks will :).
One more question....how would one go about modifying this so it ignores readonly files rather than crashing the proggie?
I'll have to check into that. I came across that before but I don't remember what I did to resolve it.
-
...ronjonp, you will need to wrap the Saveas line into a vl-catch-all-apply function. I would suggest placing the name of any file that cannot be saved into a text file so you know which ones were not modified.
I think it is already done that way Jeff.
(setq of (vl-catch-all-apply
'(lambda ()
(vlax-invoke-method dbxdoc 'open f)
)
)
)
-
Edited the code above for new functionality to print a list of drawings that were not changed.
-
The other option would be to just ignore the ones you can't open:
(if (not (vl-catch-all-error-p of))
(progn
(LayerFiltersDelete dbxdoc)
(princ
(strcat "\nDeleting Layer Filters in " f)
)
(vla-saveas dbxdoc f)
)
)
-
I think it is already done that way Jeff.
So it is.....I didn't look at the code prior to posting, oops. However, you CAN open a read-only file without error.....it's when you save it that the error occurs. Hmmm, actually I don't get an error, just an alert box saying it can't be saved..... Should probably find a function to check if the file is RO and skip it if it is.....
-
Here is one I use.
(defun CheckOpen (FileName / test)
; Return T if not open.
(if (findfile FileName)
(if (setq test (open FileName "a"))
(progn
(close test)
T
)
)
)
)
Tim
-
Why won't this purge work in the dbx?
(defun LayerFiltersDelete (doc)
(vl-Catch-All-Apply
'(lambda ()
(vla-Remove
(vla-GetExtensionDictionary
(vla-Get-Layers doc)
)
"ACAD_LAYERFILTERS"
)
)
)
(vl-Catch-All-Apply
'(lambda ()
(vla-Remove
(vla-GetExtensionDictionary
(vla-Get-Layers doc)
)
"AcLyDictionary"
)
)
)
(vla-purgeall
(vla-get-activedocument
(vlax-get-acad-object)
)
)
)
-
(vla-purgeall
(vla-get-activedocument
(vlax-get-acad-object)
)
)
This is trying to purge the active document (drawing) instead of the one you open with ObjectDBX. Maybe try
(vla-PurgeAll Doc) since you use Doc as the argument. It might not work with ObjectDBX, but I'm not sure.
Tim
-
It might not work with ObjectDBX, but I'm not sure.
Tim
That's correct iirc, you have to analyze all the collections yourself and perform intelligent trapped deletes.
-
Just found on another forum:
Michael Puckett
Guest
[Post] Posted: Wed Jan 12, 2005 12:25 am Post subject: Re: ObjectDbx : Xref Detach kaput Reply with quote
Note to self: PurgeAll not available in ObjectDBX.
Hey! I know that guy! At least in cyberspace :).
-
That guy is a flake.
-
(defun DeleteFromCollection (Collection / )
; Delete all objects in a collection that can be deleted.
(vlax-for i Collection
(vl-catch-all-apply 'vla-Delete i)
)
)
I just posted this in another forum.
Tim
-
That's correct iirc, you have to analyze all the collections yourself and perform intelligent trapped deletes.
Thanks for the clarification.
Tim
-
(defun DeleteFromCollection (Collection / )
; Delete all objects in a collection that can be deleted.
(vlax-for i Collection
(vl-catch-all-apply 'vla-Delete i)
)
)
I just posted this in another forum.
Tim
I just posted this here. ;P
-
I just posted this in another forum.
Tim
OK, I give up........how did you come up with the user name of CiphDRMRS from Tim Willey???? (or vice versa...)
Oh, and welcome to the swamp!
-
Until I new it was Tim, I was thinking that he was the wife of a Dr. who specialized in treating syphilis, and who wasn't too sharp with spelling. Now I'm going to guess that he is a member of an organization called Ciphilitic Drummers (as most drummers are and few can spell)
-
Okay. My friends and I were starting a Hip-Hop group :-), and my nick was Cipher Ciph for short, and the group name was D.R.E.A.M.E.R.S. Back in the day you couldn't have a long screen name with aol, so I had to shorten it. I haven't changed it ever since, but I think I might have to soon because my parents (whose account it is) is getting cable, and leaving aol.
Can you guess how old I am? :lmao:
Tim
-
'm not sure which answer makes more sense...the contrived one by Dr.Wahr or the real one. :)
One guess..... 25
-
I liked his explaination also. :lol:
Close. 28 now.
Tim
-
Not to get off topic but, is it possible to plot with ObjectDBX?
-
No.
But I would really like to be proven wrong ...
-
But I would really like to be proven wrong ...
I know I can't do it for the subject at hand.... :|
but give me a while and I'm sure I will find something you did wrong ..... :laugh:
-
don't remember for sure but it seems like open drawing alliance or whatever they call themselves these days had something that could at least in theory allow plotting without opening Autocad.
-
Not to get off topic but, is it possible to plot with ObjectDBX?
No.
But I would really like to be proven wrong ...
I had a conversation from Autodesk once and they said you can only print using ObjectDBX if you sign up as an ObjectDBX Developer with Autodesk.
-
I had a conversation from Autodesk once and they said you can only print using ObjectDBX if you sign up as an ObjectDBX Developer with Autodesk.
Ch'Ching, $5000 entry fee (now called Real Dawg (http://usa.autodesk.com/adsk/servlet/index?siteID=123112&id=770257)).
-
I have downloaded the Open Design Alliance (formerly OpenDWG.org) toolkit for r2005. I haven't done anything with it but if someone can point me in a direction I will try to find out if it has anything to help.