Author Topic: Set 'NoPlot' of selected objects' Layers  (Read 1738 times)

0 Members and 1 Guest are viewing this topic.

keebo

  • Mosquito
  • Posts: 3
Set 'NoPlot' of selected objects' Layers
« on: January 15, 2020, 05:18:00 AM »
I'm looking to pick objects and have their layers set to no plot.

I dont have a full working understanding of Lisp (or any programming), but I've generally managed to fudge things together based on others hard work and some trial and error.... But not this time!!

More often than not i'll be selecting entities nested within a block/xref, so have been looking at doing it via 
Code: [Select]
(vla-put-Plottable objectLayer :vlax-False)
But this is my first foray in to VLA, and I can't get my head around the object grouping & syntax order.

I've tried lots of variations, so this might not be the 'closest' I've come, but the autocad error isnt really helping me figure things out. Currently I have;

Code: [Select]
(defun c:NoP ( / doc enm obj objLayer)
 (setq doc (vla-get-activedocument (vlax-get-acad-object)))
 (while (setq enm (car (nentsel)))
   (setq obj (vlax-ename->vla-object enm))
   (setq objLayer (vla-get-layer obj))
 )
 (vla-put-Plottable objLayer :vlax-False)
 (princ)
)

The autocad error returns the correct Layer name, but it's obviously not getting it the way I want it to.

Code: [Select]
Select object:  ; error: bad argument type: VLA-OBJECT "LayerName"
Do I need to look at retrieving a full list of layers at some point?
Is it failing because the Command is set up to get a list of layers, but then I'm processing it as if there's only one? Or am I just way off?

Thanks in advance for any pointers!

Dlanor

  • Bull Frog
  • Posts: 263
Re: Set 'NoPlot' of selected objects' Layers
« Reply #1 on: January 15, 2020, 07:02:35 AM »
You are correct up until the vla-put-plottable. This has to be enacted of the layer object from the layers collection with the name you've returned with vla-get-layer.

It also needs to be inside the while loop. 

Code - Auto/Visual Lisp: [Select]
  1. (defun c:NoP ( / doc lyrs enm lyr l_obj)
  2.         lyrs (vla-get-layers doc)
  3.   )
  4.   (while (setq enm (car (nentsel)))
  5.     (setq lyr (vla-get-layer (vlax-ename->vla-object enm))
  6.           l_obj (vla-item lyrs lyr)
  7.     )
  8.     (vla-put-Plottable l_obj :vlax-False)
  9.   );end_while
  10.   (princ)
  11. )
  12.  

keebo

  • Mosquito
  • Posts: 3
Re: Set 'NoPlot' of selected objects' Layers
« Reply #2 on: January 15, 2020, 07:13:19 AM »
Perfect! Thank you very much!

Lee Mac

  • Seagull
  • Posts: 12502
  • London, England
Re: Set 'NoPlot' of selected objects' Layers
« Reply #3 on: January 15, 2020, 01:48:58 PM »
FWIW, note that you needn't necessarily stray into Visual LISP & ActiveX to accomplish this - here is an example using Vanilla AutoLISP:
Code - Auto/Visual Lisp: [Select]
  1. (defun c:test ( / e x )
  2.     (while (setq e (car (nentsel "\nSelect object whose layer should not be plotted: ")))
  3.         (setq x (entget (tblobjname "layer" (cdr (assoc 8 (entget e))))))
  4.         (entmod (subst '(290 . 0) (assoc 290 x) x))
  5.     )
  6.     (princ)
  7. )

John Kaul (Se7en)

  • Administrator
  • Needs a day job
  • Posts: 9673
Re: Set 'NoPlot' of selected objects' Layers
« Reply #4 on: January 15, 2020, 04:43:55 PM »
Here is a list of those AutoLisp layer group codes for your reference.
Code: [Select]
;;
;; LAYER group codes
;;
;; Group codes -   Description
;;
;; 100 - Subclass marker (AcDbLayerTableRecord)
;;
;; 2  -   Layer name
;;
;; 70 - Standard flags (bit-coded values):
;; 1  = Layer is frozen; otherwise layer is thawed
;; 2  = Layer is frozen by default in new viewports
;; 4  = Layer is locked
;; 16 = If set, table entry is externally dependent on an xref
;; 32 = If both this bit and bit 16 are set, the externally
;;      dependent xref has been successfully resolved
;; 64 = If set, the table entry was referenced by at least
;;      one entity in the drawing the last time the drawing
;;      was edited. (This flag is for the benefit of AutoCAD
;;      commands. It can be ignored by most programs that
;;      read DXF files and need not be set by programs that
;;      write DXF files)
;;
;; 62 - Color number (if negative, layer is off)
;;
;; 6 - Linetype name
;;
;; 290 - Plotting flag. If set to 0, do not plot this layer
;;
;; 370 - Lineweight enum value
;;
;; 390 - Hard-pointer ID/handle of PlotStyleName object
;;

Also a fun routine a friend coded up once came to mind (not sure why), so I thought I'd post it just for fun.

Code - Auto/Visual Lisp: [Select]
  1. (defun layerActions (actions layerName / layer laylst flags color plot)
  2.   ;; SMadsen on 06-27-2003
  3.   ;; 0 = no action
  4.   ;; 1 = freeze
  5.   ;; 2 = thaw
  6.   ;; 4 = off
  7.   ;; 8 = on
  8.   ;; 16 = lock
  9.   ;; 32 = unlock
  10.   ;; 64 = plot on
  11.   ;; 128 = plot off
  12.   ;;
  13.   ;; Simply adding the values determines the actions taken by the function. For example:
  14.   ;;
  15.   ;;  (layerActions (+ 8 32 64) "myLayer") will turn on "myLayer", unlock it and enable plotting (I hope).
  16.   (cond ((setq layer (tblobjname "LAYER" layerName))
  17.          (setq laylst (entget layer)
  18.                flags  (cdr (assoc 70 laylst))
  19.                color  (cdr (assoc 62 laylst))
  20.                plot   (cdr (assoc 290 laylst)))
  21.          (cond ((= (logand actions 2) 2) (setq flags (logior flags 1)))
  22.                ((= (logand actions 1) 1) (setq flags (- flags (logand flags 1)))))
  23.          (cond ((= (logand actions 8) 8) (setq color (- (abs color))))
  24.                ((= (logand actions 4) 4) (setq color (abs color))))
  25.          (cond ((= (logand actions 32) 32) (setq flags (logior flags 4)))
  26.                ((= (logand actions 16) 16)(setq flags (- flags (logand flags 4)))))
  27.          (cond ((= (logand actions 64) 64) (setq plot 1))
  28.                ((= (logand actions 128) 128) (setq plot 0)))
  29.          (setq laylst (subst (cons 70 flags)(assoc 70 laylst) laylst)
  30.                laylst (subst (cons 62 color)(assoc 62 laylst) laylst)
  31.                laylst (subst (cons 290 plot)(assoc 290 laylst) laylst))
  32.          (entmod laylst)
  33.          )
  34.         )
  35.   (princ)
  36.   )
TheSwamp.org (serving the CAD community since 2003)

Donate to TheSwamp.org

keebo

  • Mosquito
  • Posts: 3
Re: Set 'NoPlot' of selected objects' Layers
« Reply #5 on: January 20, 2020, 05:10:32 AM »
Thanks Lee & John. All very useful information that I'm sure will come in handy going forward.

rkmcswain

  • Swamp Rat
  • Posts: 963
Re: Set 'NoPlot' of selected objects' Layers
« Reply #6 on: January 20, 2020, 11:03:05 AM »
FWIW, note that you needn't necessarily stray into Visual LISP & ActiveX to accomplish this - here is an example using Vanilla AutoLISP:
Code - Auto/Visual Lisp: [Select]
  1. (defun c:test ( / e x )
  2.     (while (setq e (car (nentsel "\nSelect object whose layer should not be plotted: ")))
  3.         (setq x (entget (tblobjname "layer" (cdr (assoc 8 (entget e))))))
  4.         (entmod (subst '(290 . 0) (assoc 290 x) x))
  5.     )
  6.     (princ)
  7. )


Nice @LeeMac

Lee Mac

  • Seagull
  • Posts: 12502
  • London, England
Re: Set 'NoPlot' of selected objects' Layers
« Reply #7 on: January 20, 2020, 12:47:34 PM »
Thanks  :-)

John Kaul (Se7en)

  • Administrator
  • Needs a day job
  • Posts: 9673
Re: Set 'NoPlot' of selected objects' Layers
« Reply #8 on: January 20, 2020, 01:42:08 PM »
Playing around waiting for an email. Not tested.

Code - Auto/Visual Lisp: [Select]
  1. (defun ent-layer-to-no-plot ( ent )
  2.   (cond
  3.     ( (null ent)
  4.      (ent-layer-to-no-plot (car (nentsel (strcat "\nSelect an object: ")))))
  5.     ( (eq (type ent) 'ENAME)
  6.      (ent-layer-to-no-plot (entget (tblobjname "layer" (cdr (assoc 8 (entget ent)))))))
  7.     ( (eq (type ent) 'LIST)
  8.      (entmod (subst '(290 . 0) (assoc 290 ent) ent)))
  9.     )
  10.   (princ)
  11.   )
  12. (ent-layer-to-no-plot nil)
TheSwamp.org (serving the CAD community since 2003)

Donate to TheSwamp.org

John Kaul (Se7en)

  • Administrator
  • Needs a day job
  • Posts: 9673
Re: Set 'NoPlot' of selected objects' Layers
« Reply #9 on: January 21, 2020, 10:25:39 AM »
A day later--AutoCAD installed--and I gave my function above a quick test. It works (yay!).

Aside: I had a few minutes in between tasks yesterday and this thread was in my unread feed so I picked a mini challenge for myself in creating a function with no variables. Recursion was a simple solution to this but I thought I'd mention that this function is no more "efficient/smaller/etc." then one that does (assuming that a function that creates variables cleans up after itself).
TheSwamp.org (serving the CAD community since 2003)

Donate to TheSwamp.org