How do you select drawing elements in AutoLISP?

How do you select drawing elements in AutoLISP?

sgrafSXXCW
Explorer Explorer
693 Views
11 Replies
Message 1 of 12

How do you select drawing elements in AutoLISP?

sgrafSXXCW
Explorer
Explorer

I am new to AutoLISP and programming.  The following code is supposed to turn green any object I select, but it doesn't let me select anything.  What is going on?  Thanks.
(defun c:ChangeColorToGreen ()
(setq obj (car (entsel "\nSelect an object: "))) ; Prompt the user to select an object

(if obj
(progn
(setq color 3) ; Green color code

; Modify the object's properties to change its color to green
(if (setq oldProps (entget obj))
(progn
(setq newProps (subst (cons 62 color) (assoc 62 oldProps) oldProps))
(entmod newProps)
(redraw)
(princ "\nObject color changed to green.")
)
)
)
(princ "\nNo object selected. Nothing changed.")
)
(princ)
)

0 Likes
694 Views
11 Replies
Replies (11)
Message 2 of 12

pendean
Community Legend
Community Legend
Layers locked? Layer 0 not thawed?

Down and Dirty version of your LISP...

(defun c:ChangeColorToGreen ()
(setq a (ssget))
(command "change" a "" "p" "color" "3" "")
);end
0 Likes
Message 3 of 12

CADaSchtroumpf
Advisor
Advisor

Group 62 for color is optional, if not set it means the entity has the color of the layer: meaning this would be equivalent to (62 . 256).
It is necessary to check the existence of this color code.

(defun c:ChangeColorToGreen ( / obj color oldProps newProps)
  (setq obj (car (entsel "\nSelect an object: "))) ; Prompt the user to select an object
  (if obj
    (progn
    (setq color 3) ; Green color code
    ; Modify the object's properties to change its color to green
    (if (setq oldProps (entget obj))
      (progn
        (if (assoc 62 oldProps)
          (setq newProps (subst (cons 62 color) (assoc 62 oldProps) oldProps))
          (setq newProps (append oldProps (list (cons 62 color))))
        )
        (entmod newProps)
        (redraw)
        (princ "\nObject color changed to green.")
      )
    )
    )
    (princ "\nNo object selected. Nothing changed.")
  )
  (princ)
)
0 Likes
Message 4 of 12

MrJSmith
Advocate
Advocate

@sgrafSXXCW You have several issues. First you are doing a entity selection, sounds like you probably want an ssget selection set? Where you select multiple objects at once? Secondly, your method only works if the object already has a color associated with it. If it is the default "ByLayer" then dxf code 62 will not exist and so you can't substitute it. You could add it to the entity list though.

 

Personally, I find modifying colors easier in VLAX because of that issue. Example:

(defun c:changeColor ( / color ss ct vlaObj)
	(setq color 3) ;You wanted green
	(print "Select some objects....")
	(setq ss (ssget))
	(if ss
		(progn
			(setq ct 0)
			(repeat (sslength ss)
				(setq vlaObj (vlax-ename->vla-object (ssname ss ct)))
				(vl-catch-all-apply 'vla-put-color (list vlaObj color))
				(setq ct (+ 1 ct))
			)
			(print "All selected objects have color updated!")
		)
		(print "You didn't select any objects....")
	)
	(princ)
)

 

Note: Some objects would require additional functionality due to their complex nature. This includes blocks, both types of leaders, dimensions, etc.

Message 5 of 12

Kent1Cooper
Consultant
Consultant

@CADaSchtroumpf wrote:

Group 62 for color is optional, if not set it means the entity has the color of the layer: ....
It is necessary to check the existence of this color code.


You can do this without checking for that:  just (append) a 62-code entry onto the end of the entity data list, and being later in the list, it will "win" over an earlier 62 entry if there is one, or it will just add that if there isn't, so checking is not needed:

(setq newProps (append oldProps (list (cons 62 color))))

Kent Cooper, AIA
Message 6 of 12

Kent1Cooper
Consultant
Consultant

@sgrafSXXCW wrote:

.... it doesn't let me select anything.  ....


Is that really what you mean?  That is, do you get your nothing-selected message when you pick something?  Or does it, in fact, let you select things, but it just doesn't change their color?  [Either the locked-Layer or the 62-code business could be the explanation if that's what's happening.]

Kent Cooper, AIA
Message 7 of 12

Kent1Cooper
Consultant
Consultant

@pendean wrote:
.... Down and Dirty version of your LISP...
.... (command "change" a "" "p" "color" "3" "") ....

Even downer and dirtier:

(command "_.chprop" a "" "_color" 3 "")

 

The CHPROP command is a conflation of the CHANGE command with its Properties option into a shortcut command.  [And the color number can be used without quotation marks, though it accepts them because accepting text strings allows color names such as "red," or "ByLayer" or "ByBlock".]

Kent Cooper, AIA
Message 8 of 12

CADaSchtroumpf
Advisor
Advisor

@Kent1Cooper  a écrit :

@CADaSchtroumpf wrote:

Group 62 for color is optional, if not set it means the entity has the color of the layer: ....
It is necessary to check the existence of this color code.


You can do this without checking for that:  just (append) a 62-code entry onto the end of the entity data list, and being later in the list, it will "win" over an earlier 62 entry if there is one, or it will just add that if there isn't, so checking is not needed:

(setq newProps (append oldProps (list (cons 62 color))))


It actually works...
In my logic I would have been afraid of getting a bad list to submit to (entmod)

Message 9 of 12

Kent1Cooper
Consultant
Consultant

@CADaSchtroumpf wrote:

@Kent1Cooper  a écrit :

.... You can do this without checking for that:  just (append) a 62-code entry ...:

It actually works...
In my logic I would have been afraid of getting a bad list to submit to (entmod)


Yes, it conveniently works for most only-once entries such as for color, linetype [which must be loaded in the drawing*], layer, even Block name, etc., though not all -- e.g. not Hatch pattern names for some reason.  But obviously it's not for entries that might occur more than once in an entity data list, such as 10-code entries for Polyline vertices.  I was afraid of the same thing the first time I encountered this, but I've seen it used numerous times in routines here.  Interestingly, if you do it for the Layer and give it one that doesn't yet exist, it will create the Layer in the process, using default color, linetype, etc.

 

* On the linetype, if it's in AutoCAD's definition file, the CHPROP approach is preferable to (subst) or (append) and (entmod), because with such a linetype, it is not necessary for it to be loaded into the drawing already -- the command will find it.

Kent Cooper, AIA
Message 10 of 12

sgrafSXXCW
Explorer
Explorer

Wow.  Thanks to everyone for your input.  I have a lot more to learn than I thought.  I had no idea about the 62, for example.

0 Likes
Message 11 of 12

john.uhden
Mentor
Mentor

@sgrafSXXCW ,

IMHO, you may get yourself into a predicament with your variable naming.

I think most of us use OBJ for a vla-object.

Most of the old-timers (I guess myself included) use:

(setq E (car (entsel))) ;; for an entity name

and

(setq ENT (entget E)) ;; for the entity data

and, of course

(setq OBJ (vlax-ename->vla-object E))

 

But I think your problem may be, as recently discussed, is assuming that every entity has a 62 code.  Not true... (62 . 256) "BYLayer" is never present because that is the default, so you can't subst for something that isn't present.  But as I have been taught by the better people here you can (append ent (cons 62 3)) whether the 62 code exists or not.

BTW, if that is an example of your current AutoLisp skills, you are doing admirably well!

John F. Uhden

0 Likes
Message 12 of 12

john.uhden
Mentor
Mentor

@Kent1Cooper ,

I think that I am one of the grammar experts around here, but you are apparently our vocabulary expert.

First it was "indubitably" and now it's "conflation."  I had to look it up and found it's totally apropos.  Thanks!! 😀

John F. Uhden

0 Likes