LISP Help, Beginner, Intermediate, Delete layer listed in file

LISP Help, Beginner, Intermediate, Delete layer listed in file

J__A
Enthusiast Enthusiast
3,641 Views
16 Replies
Message 1 of 17

LISP Help, Beginner, Intermediate, Delete layer listed in file

J__A
Enthusiast
Enthusiast

Hi folks, Smiley Happy

 

I have an problem where i export drawings daily with (simple script) to change settings but theres one thing i can't solve, which is very time consuming. Deleting stuff that is"temporary things" in my drawings.

 

1. Is it possible to make an lisp that search an txt.doc or other file-extension for layer names and deleted all layers listed in this specific file, "no matter if its blocks or objectives or other things under this layer in the drawing".

 

2. If not: mby its possible to delete all layers including name "XXX-Building-B" while there might be 1000 layers named "XXX-Building-B-XXX" to do directly from the lisp routine

 

I would personally prefer something like an text doc so other ppl can edit the list fast.

If u have any ideas or inputs plz add them Smiley Very Happy / Regards A

0 Likes
Accepted solutions (2)
3,642 Views
16 Replies
Replies (16)
Message 2 of 17

ronjonp
Mentor
Mentor

Here is a quick example:

(defun c:foo nil
  (vlax-for a (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object)))
    (if	(= 0 (vlax-get a 'isxref))
      (vlax-for	b a
	(if (and (vlax-write-enabled-p b) (wcmatch (strcase (vla-get-layer b)) "*XXX-BUILDING-B*"))
	  (vl-catch-all-apply 'vla-delete (list b))
	)
      )
    )
  )
  (princ)
)
(vl-load-com)
0 Likes
Message 3 of 17

J__A
Enthusiast
Enthusiast

Thx @ronjonp  just to clearify autocad is a new platform for me.
I can see how the functions are working, i cant test it right now but just an thougt, what if its an freezed layer? 

 

Also any idea or input on my thoughts about layer list document, like a plain text document to type in the XXX-BUILDING-B and follow up by other names??

 

In your lisp part: 

(if (and (vlax-write-enabled-p b) (wcmatch (strcase (vla-get-layer b)) "*XXX-BUILDING-B*"))

how would i call it to search for more layers, does it need to be a new function? / A

 

0 Likes
Message 4 of 17

ronjonp
Mentor
Mentor

Give this a try .. there are examples at the bottom how to use different filters for names.

(defun _foo (lnames / d)
  (vlax-for a (vla-get-layers (setq d (vla-get-activedocument (vlax-get-acad-object))))
    ;; Unlock layers that are not xref
    (or (wcmatch (vla-get-name a) "*|*") (vlax-put a 'lock 0))
  )
  (vlax-for a (vla-get-blocks d)
    (if	(= 0 (vlax-get a 'isxref))
      (vlax-for	b a
	(if (and (vlax-write-enabled-p b) (wcmatch (strcase (vla-get-layer b)) (strcase lnames)))
	  (vl-catch-all-apply 'vla-delete (list b))
	)
      )
    )
  )
  (princ)
)
(vl-load-com)
;; Usage below
;; WCMATCH reference
;; http://help.autodesk.com/view/ACD/2020/ENU/?guid=GUID-EC257AF7-72D4-4B38-99B6-9B09952A53AD
;; 
;; Delete layers that have 'XXX-BUILDING-B' in them
(_foo "*XXX-BUILDING-B*")
;; Delete layers A B & C
(_foo "A,B,C")
;; Delete layers that have RON or have ICE CREAM at the end
(_foo "*RON*,*ICE CREAM")
Message 5 of 17

J__A
Enthusiast
Enthusiast

Thank u a lot @ronjonp , makes sense.

I will try it tomorrow and +rep, i will let you know Smiley Very Happy

 

Would it be possible to add some variables or a repeat function with audit?

I could then remove some lines form my plain dumb "text script". hehe

 

Was thinking something like this but im not sure how it would work in lisp routines.

 

(setvar 'Clayer "0")
     (repeat 4
           (vla-purgeall
  (vlax-for a (vla-get-layers (setq d (vla-get-activedocument (vlax-get-acad-object)))))))

 

0 Likes
Message 6 of 17

ВeekeeCZ
Consultant
Consultant

Just a quick idea. How about use a Layer Group Filter instead of file. Put all the useless layers there... That could be easily maintained, you know just drag-n-drop layers there.. And then, after all work's done, just dump all the trash inside by a routine.

0 Likes
Message 7 of 17

ronjonp
Mentor
Mentor

There is also some code I posted HERE, that may give you ideas for cleanup. All you really need is a list of what needs to happen and most likely it can be done in one routine.

0 Likes
Message 8 of 17

J__A
Enthusiast
Enthusiast

Thx for your input @ВeekeeCZ 

I like it sounds like it might be something to work with, would remove a few lines and mby make the lisp smarter..

Is it possible to make an routine to remove everything in that layer group then?

 

Gonna try @ronjonp solution and update below. 

0 Likes
Message 9 of 17

J__A
Enthusiast
Enthusiast

Thx for the link @ronjonp , i tried what you posted above "lisp" and it gets the job done on my sample drawing.

If you or @ВeekeeCZ have time and could help me out regarding finishing it up.

 

The idea @ВeekeeCZ added might be the way to go, I was watching the autocad guid but this lisp would take me ages to do myself. I will post "list below".

 

We put up a layer filter group we call the group: ( Temp-filters )

 

Run the lisp xxx it does the following:

 

Clayer 0 or w/e layer we define to go to.

Unlock and unfreeze all layers that is in the activedoc

Removes everything in the ( Temp-filters ) group "if its possible to do?" / otherwise back to @ronjonp  original lisp.

Once done it Purgeall and retry a few times and audit.    

 

Please feel free to add what you think might be useful Smiley Happy / AJ

0 Likes
Message 10 of 17

ronjonp
Mentor
Mentor
Accepted solution

@J__A wrote:

Thx for the link @ronjonp , i tried what you posted above "lisp" and it gets the job done on my sample drawing.

If you or @ВeekeeCZ have time and could help me out regarding finishing it up.

 

The idea @ВeekeeCZ added might be the way to go, I was watching the autocad guid but this lisp would take me ages to do myself. I will post "list below".

 

We put up a layer filter group we call the group: ( Temp-filters )

 

Run the lisp xxx it does the following:

 

Clayer 0 or w/e layer we define to go to.

Unlock and unfreeze all layers that is in the activedoc

Removes everything in the ( Temp-filters ) group "if its possible to do?" / otherwise back to @ronjonp  original lisp.

Once done it Purgeall and retry a few times and audit.    

 

Please feel free to add what you think might be useful Smiley Happy / AJ


This should do what you want, all you need to add is your 'temp-filters' for layer names.

(defun _foo (lnames / d)
  ;; Set current layer to 0
  (setvar 'clayer "0")
  (vlax-for a (vla-get-layers (setq d (vla-get-activedocument (vlax-get-acad-object))))
    ;; Unlock and thaw all layers
    (vlax-put a 'lock 0)
    (vlax-put a 'freeze 0)
  )
  (vlax-for a (vla-get-blocks d)
    (if	(= 0 (vlax-get a 'isxref))
      (vlax-for	b a
	;; Delete item on layers that match your filter
	(if (and (vlax-write-enabled-p b) (wcmatch (strcase (vla-get-layer b)) (strcase lnames)))
	  (vl-catch-all-apply 'vla-delete (list b))
	)
      )
    )
  )
  ;; Purge 3 times
  (repeat 3 (vla-purgeall d))
  ;; Audit
  (vla-AuditInfo d :vlax-true)
  (princ)
)
(vl-load-com)
;; Usage below
;; WCMATCH reference
;; http://help.autodesk.com/view/ACD/2020/ENU/?guid=GUID-EC257AF7-72D4-4B38-99B6-9B09952A53AD
;; 
(_foo "YOUR,TEMP,FILTERS,HERE")
0 Likes
Message 11 of 17

ВeekeeCZ
Consultant
Consultant
Accepted solution

Just to clarify. There are two different things with Layer Filters. Layer Properties Filters and Layer Group Filters. The first ones are defined by a list of property filters... (like your name filter "*XXX-BUILDING-B*"), the latter is just a list of layers. Those two cannot be combined and they are different in the way to manage. 

 

The following code works with Layer Group Filter only (yet)... just thinking this is more suitable for the job. You can still use @ronjonp' foo for layer property filters.

 

(vl-load-com)

(defun c:RemoveTempLayers ( / fgname lnames)

  (setq fgname "Temp-filters")

  (if (setq lnames (:LayerGroupLayerList fgname))
    (_foo (apply 'strcat (mapcar '(lambda (l) (strcat l ",")) lnames)))
    (princ "\nNo layers found."))
  (princ)
  )  
  

(defun :LayerGroupLayerList (name / obj dict item ent def lst)

  (if (and (setq obj (vla-get-layers (vla-get-activedocument (vlax-get-acad-object))))
	   (= (vla-get-hasextensiondictionary obj) :vlax-true)
	   (setq obj (vla-GetExtensionDictionary obj))
	   (not (vl-catch-all-error-p
		  (setq dict (vl-catch-all-apply 'vla-item (list obj "AcLyDictionary"))))))
    (vlax-for itm dict
      (if (and (setq ent (vlax-vla-object->ename itm))
	       (setq def (entget ent))
	       (= (type (cdr (assoc 1 def))) 'STR)
	       (= (cdr (assoc 300 def)) name)
	       )
        (setq lst (if (wcmatch (strcase (cdr (assoc 1 def))) "ACLYLAYERGROUP")
                    (vl-remove nil (mapcar '(lambda (l) (cdr (assoc 2 (entget (cdr l)))))
                                           (vl-remove-if-not '(lambda (x) (= 330 (car x))) (member (cons 300 name) def))))
                    nil ;(cdadr (member (cons 300 name) def))
                    ))))) 
  lst)


;; by RJP

(defun _foo (lnames / d)

  ;; Set current layer to 0
  (setvar 'clayer "0")
  
  (vlax-for a (vla-get-layers (setq d (vla-get-activedocument (vlax-get-acad-object))))
    ;; Unlock and thaw all layers
    (vlax-put a 'lock 0)
    (if (/= (vla-get-name a) (getvar 'clayer)) ;;beekee
      (vlax-put a 'freeze 0)))
 
  
  (vlax-for a (vla-get-blocks d)
    (if	(= 0 (vlax-get a 'isxref))
      (vlax-for	b a
	;; Delete item on layers that match your filter
	(if (and (vlax-write-enabled-p b) (wcmatch (strcase (vla-get-layer b)) (strcase lnames)))
	  (vl-catch-all-apply 'vla-delete (list b))))))

  ;; Purge 3 times
  (repeat 3 (vla-purgeall d))
  ;; Audit
  (vla-AuditInfo d :vlax-true)
  (princ)
)
0 Likes
Message 12 of 17

ronjonp
Mentor
Mentor

@ВeekeeCZ  Good catch on the current layer thaw ... forgot about that quirk. 

 

I'd probable 'sledgehammer' it like so 🙂

(foreach p '(lock freeze) (vl-catch-all-apply 'vlax-put (list a p 0)))
0 Likes
Message 13 of 17

J__A
Enthusiast
Enthusiast

This is great, Smiley LOL  opened a new world for me.

Thank you for the help and effort both @ronjonp and @ВeekeeCZ +++rep 

 

Quick Note:

I was doing some tests today, it does the job i just need to set it up better, but it seems to have a problem with unuseed layers and blocks.

Even if i put this layer x that isnt used in the layer filter or layer group.

 

I tried both of your codes posted above so im assuming its something from my side causing this problem,

the thing is when i use normal "purgeall" in commandline it removes both the "unuseed layer and blocks".

 

I tried to follow the lisp routine but cant figure it out why it doesnt "rinse" the layer or block. 

You got any thoughts or ideas what im missing?  / AJ

0 Likes
Message 14 of 17

ronjonp
Mentor
Mentor

I don't think vla-purgeall removes as many things as the command call. If the command version works better, just add:

(command "_.-purge" "_a" "*" "_n")

to the code and comment out the vla-purgeall lin :).

0 Likes
Message 15 of 17

J__A
Enthusiast
Enthusiast

Thx for clarifying this, makes it easier to catch up for "newcomers"  🙂

Yes the layer group will do what i want for now. I will laborate a bit more with them both once i have time.

 

I also sent u an pm regarding something else i saw you have been involved in on the forums,
it doesnt belong to this topic.   (:   / regards AJ

0 Likes
Message 16 of 17

J__A
Enthusiast
Enthusiast

You are probably right, unless theres something not working 100% on my side...

I first added an extra line for the purge to the script but i changed it and works flawless now!  🙂

 

Yet again thx for all the help both @ronjonp and @ВeekeeCZ 

0 Likes
Message 17 of 17

ronjonp
Mentor
Mentor

@J__A wrote:

You are probably right, unless theres something not working 100% on my side...

I first added an extra line for the purge to the script but i changed it and works flawless now!  🙂

 

Yet again thx for all the help both @ronjonp and @ВeekeeCZ 


Glad to help 🙂

0 Likes