LISP for editing XREF layers with specific Description?

LISP for editing XREF layers with specific Description?

Anonymous
Not applicable
2,144 Views
11 Replies
Message 1 of 12

LISP for editing XREF layers with specific Description?

Anonymous
Not applicable

When plotting drawing definitions, we often have many unnecessary layers visible that we don't need on the final plot, namely layers that contain the word "Rives" (= demolish) in the description. These take time to edit manually and it would be nice to have a button that turns all of those layers off, as well as making them unplottable and selecting VP Freeze in Layer Properties Manager.

 

Some help coding this would be greatly appreciated.

0 Likes
Accepted solutions (2)
2,145 Views
11 Replies
Replies (11)
Message 2 of 12

cadffm
Consultant
Consultant

Where is your current code? Where do you need help?

 

Iterate thru all Layers, Layernames with a pipe"|" are XRef-Layers,

check the xdata of AcAecLayerStandard application,

check the name of the description, if match to "*Rivas*", thats your Layer..

 

For AutoLISP:

iterate with TBLNEXT

Description is the second dxf code 1000 from AcAecLayerStandard application

Set DXF 290 to1 (non-plot)

Use the VPLAYER to VPFREEZE them (or create a list of Layernames, which you apply layer all in one step with VPLAYER command)

 

(entget(tblobjname "LAYER" "0")'("AcAecLayerStandard")))
(-1 . <Objektname: 7ff6127bc900>)
(0 . "LAYER")
(5 . "10")
(102 . "{ACAD_XDICTIONARY")
(360 . <Objektname: 7ff6127ec240>)
(102 . "}")
(330 . <Objektname: 7ff6127bc820>)
(100 . "AcDbSymbolTableRecord")
(100 . "AcDbLayerTableRecord")
(2 . "0")
(70 . 0)
(62 . 7)
(6 . "Continuous")
(290 . 1)
(370 . -3)
(390 . <Objektname: 7ff6127bc8f0>)
(347 . <Objektname: 7ff6127bcee0>)
(348 . <Objektname: 0>)
(-3 ("AcAecLayerStandard" (1000 . "") (1000 . "hello"))

 

Where exactly do you need more help?

Sebastian

0 Likes
Message 3 of 12

cadffm
Consultant
Consultant

I see (now) you have a code which handle with XREF-Layers, => Re: LSP/SCR button for selecting and lock all XREFs

so you can use this construct as base and add/edit what you want.

 

Sebastian

0 Likes
Message 4 of 12

Anonymous
Not applicable

This is my current code:

 

(vl-load-com)

(defun c:lockallxrefs (/ *error* c_doc c_lyrs lyr_name)

	(defun *error* ( msg ) 
		(if (and c_doc (= 8 (logand 8 (getvar 'UNDOCTL)))) (vla-endundomark c_doc))
		(if (not (wcmatch (strcase msg) "*BREAK*,*CANCEL*,*EXIT*")) (princ (strcat "\nOops an Error : " msg " occurred.")))
		(princ)
	);end_defun_*error*

	(setq c_doc (vla-get-ActiveDocument (vlax-get-acad-object))
        c_lyrs (vla-get-layers c_doc)
	);end_setq

	(if (and c_doc (= 8 (logand 8 (getvar 'UNDOCTL)))) (vla-endundomark c_doc))
	(vla-startundomark c_doc)

	(vlax-for lyr c_lyrs
    (setq lyr_name (vla-get-name lyr)) 
    (if (= (vla-get-lock lyr) :vlax-false)
      (if (or (wcmatch lyr_name "XREF" )
              (wcmatch lyr_name "XR-*" )
          )
	(progn
          (vla-put-lock lyr :vlax-true)
          (cond (t (COMMAND "-layer" "_tr" 50 lyr_name ""))
          );end_cond      
        );end_progn
      );end_if
    );end_if
  );end_for
	(if (and c_doc (= 8 (logand 8 (getvar 'UNDOCTL)))) (vla-endundomark c_doc))
	(princ)
);end_defun

Still not that used to coding, so I'm not sure exactly which variable is which.

0 Likes
Message 5 of 12

dlanorh
Advisor
Advisor

Sorry I can't help at the moment but this

(vlax-for lyr c_lyrs
    (setq lyr_name (vla-get-name lyr)) 
    (if (= (vla-get-lock lyr) :vlax-false)
      (if (or (wcmatch lyr_name "XREF" )
              (wcmatch lyr_name "XR-*" )
          )
	(progn
          (vla-put-lock lyr :vlax-true)
          (cond (t (COMMAND "-layer" "_tr" 50 lyr_name ""))
          );end_cond      
        );end_progn
      );end_if
    );end_if
  );end_for

Is the main loop through the layers, and you need to

(setq description (vla-get-description lyr))

 

then wcmatch the description string for what you are looking for using wildcards allowing for it being at the start, at the end or in the middle of the string.

 

Hope this helps

I am not one of the robots you're looking for

0 Likes
Message 6 of 12

dlanorh
Advisor
Advisor

Do you want the VP Freeze to work for a specific layout or all layouts in the drawing?

I am not one of the robots you're looking for

0 Likes
Message 7 of 12

Anonymous
Not applicable

For all layouts. We only use one layout per dwg, so it doesn't need to be specific. Rather those layers don't risk showing at all when plotting, regardless of settings.

0 Likes
Message 8 of 12

dlanorh
Advisor
Advisor
Thanks. two further questions.
Are there multiple viewports per layout or just one?
Do you want this as a separate lisp or integrating into the previous one?

I am not one of the robots you're looking for

0 Likes
Message 9 of 12

dlanorh
Advisor
Advisor
Accepted solution

Try this :

 

(vl-load-com)

(defun c:XRO (/ *error* c_doc c_lyrs lyr_name lyr_desc lyrs_str t_mode)

	(defun *error* ( msg )
    (if (and t_mode (/= t_mode (getvar 'tilemode))) (setvar 'tilemode t_mode))
		(if (and c_doc (= 8 (logand 8 (getvar 'UNDOCTL)))) (vla-endundomark c_doc))
		(if (not (wcmatch (strcase msg) "*BREAK*,*CANCEL*,*EXIT*")) (princ (strcat "\nOops an Error : " msg " occurred.")))
		(princ)
	);end_defun_*error*

	(setq c_doc (vla-get-activedocument (vlax-get-acad-object))
        c_lyrs (vla-get-layers c_doc)
	);end_setq

	(if (and c_doc (= 8 (logand 8 (getvar 'UNDOCTL)))) (vla-endundomark c_doc))
	(vla-startundomark c_doc)

	(vlax-for lyr c_lyrs
    (setq lyr_name (vlax-get-property lyr 'name)
          lyr_desc (vlax-get-property lyr 'description)
    );end_setq          
    (cond ( (or (wcmatch lyr_desc "Rives*")  ;These wcmatch functions are case sensitive. This line tests if it is the first word in the description
                (wcmatch lyr_desc "*Rives*") ;If this is picking up parts of words try using "* Rives *" in place of "*Rives*". This tests if it is somewhere in the middle
                (wcmatch lyr_desc "*Rives")  ;This tests if it is the last word in the description 
            );end_or
            (vlax-put-property lyr 'layeron :vlax-false)  
            (vlax-put-property lyr 'plottable :vlax-false)  
            (if lyrs_str
              (setq lyrs_str (strcat lyrs_str "," lyr_name)); This builds a string of layer names separated by comma for passing to the vplayer command
              (setq lyrs_str lyr_name)
            );end_if              
          );end_layer_description_contains_Rives_sub_cond
    );end_cond      
  );end_for
  (setq t_mode (getvar 'tilemode))
  (if (/= t_mode 0) (setvar 'tilemode 0));set paperspace
  (vl-cmdf "_.vplayer" "_F" lyrs_str "_A" "")
  (if (= t_mode 1) (setvar 'tilemode t_mode));reset tilemode
	(if (and c_doc (= 8 (logand 8 (getvar 'UNDOCTL)))) (vla-endundomark c_doc))
	(princ)
);end_defun

It can be run from modelspace or paperspace. If run from modelspace you will probably notice a flicker as it changes to paperspace and back.

 

I am not one of the robots you're looking for

0 Likes
Message 10 of 12

Anonymous
Not applicable

 Works nicely! Thanks!

 

The only thing missing is also checking the "New VP Freeze" icon for selected layers. I'd add it in myself, but I don't know the code command for it:

(vl-load-com)

(defun c:XRO (/ *error* c_doc c_lyrs lyr_name lyr_desc lyrs_str t_mode)

	(defun *error* ( msg )
    (if (and t_mode (/= t_mode (getvar 'tilemode))) (setvar 'tilemode t_mode))
		(if (and c_doc (= 8 (logand 8 (getvar 'UNDOCTL)))) (vla-endundomark c_doc))
		(if (not (wcmatch (strcase msg) "*BREAK*,*CANCEL*,*EXIT*")) (princ (strcat "\nOops an Error : " msg " occurred.")))
		(princ)
	);end_defun_*error*

	(setq c_doc (vla-get-activedocument (vlax-get-acad-object))
        c_lyrs (vla-get-layers c_doc)
	);end_setq

	(if (and c_doc (= 8 (logand 8 (getvar 'UNDOCTL)))) (vla-endundomark c_doc))
	(vla-startundomark c_doc)

	(vlax-for lyr c_lyrs
    (setq lyr_name (vlax-get-property lyr 'name)
          lyr_desc (vlax-get-property lyr 'description)
    );end_setq          
    (cond ( (or (wcmatch lyr_desc "Rives*")  ;These wcmatch functions are case sensitive. This line tests if it is the first word in the description
                (wcmatch lyr_desc "*Rives*") ;If this is picking up parts of words try using "* Rives *" in place of "*Rives*". This tests if it is somewhere in the middle
                (wcmatch lyr_desc "*Rives")  ;This tests if it is the last word in the description 
            );end_or
            (vlax-put-property lyr 'layeron :vlax-false)  
            (vlax-put-property lyr 'plottable :vlax-false)
            (vlax-put-property lyr 'newvpfreeze :vlax-true)?
            (if lyrs_str
              (setq lyrs_str (strcat lyrs_str "," lyr_name)); This builds a string of layer names separated by comma for passing to the vplayer command
              (setq lyrs_str lyr_name)
            );end_if              
          );end_layer_description_contains_Rives_sub_cond
    );end_cond      
  );end_for
  (setq t_mode (getvar 'tilemode))
  (if (/= t_mode 0) (setvar 'tilemode 0));set paperspace
  (vl-cmdf "_.vplayer" "_F" lyrs_str "_A" "")
  (if (= t_mode 1) (setvar 'tilemode t_mode));reset tilemode
	(if (and c_doc (= 8 (logand 8 (getvar 'UNDOCTL)))) (vla-endundomark c_doc))
	(princ)
);end_defun 

 

0 Likes
Message 11 of 12

dlanorh
Advisor
Advisor
Accepted solution

Almost, but it's not as logical as that. Robot Happy

 

It's

 

(vlax-put-property lyr 'viewportdefault :vlax-true)

I am not one of the robots you're looking for

0 Likes
Message 12 of 12

Anonymous
Not applicable

Thank you! Perfect! Smiley Happy

0 Likes