Nate Holt's Blog

September 1, 2009

Nate’s Simple Autolisp – Lesson 005

Filed under: Tutorials — nateholt @ 12:20 am

Using (nentsel…) and changing an existing block insert instance

Here’s the real-world example (happened  yesterday) that triggers quick Lisp lesson number “005″.  The issue revolves around the color yellow.

The challenge

lisp005_01I reviewed some drawings from a client. Everything looked fine with dark background. But a light background, some of the attributed blocks were difficult to read - yellow ones. Very uncomfortable at best, bordering on impossible at worst.

Normally, I would just figure out what “layer” the attributed text was on and force that layer’s color from yellow to a better color.

 

But there was a problem. This block’s single yellow text attribute definition was not set up to have its COLOR display “ByLayer”. It was “hard-coded” to be yellow ALL the time.

How can we tell?… Here is the result of the AutoCAD “LIST” command on the upper “52″ bubble. Note that the single attribute, tag name BUBNUM, has been defined to always display as “YELLOW”.

autolisp005a

A Solution

Let’s fix this. What we’ll do now is build up a little AutoLISP tool to force a picked attribute to display in a different color. If you’d like to follow along “hands on”, download the above sample dwg file here. What we want our little AutoLISP tool to do is this: we pick on a yellow attribute. Our tool reads the attribute and, if the attribute’s color was NOT set up “BYLAYER”, changes its color to color “red”. This should show up nicely whether a dark or light background is selected.

Step-by-Step: Difference between (entsel) and (nentsel)

In each of the previous lessons here, here, here, and here we have looked at the AutoLisp (entsel) entity selection function.

With the example dwg file open/active on your screen, type this at the “Command:” prompt:

Command: (entsel) [Enter]
Select object: [pick on text in upper bubble] (<Entity name: 7ffffb04930> (-0.0405614 0.0279495 0.0))

The (entsel) function returns a two-element list: the first element is the entity name of the picked entity (i.e. the block insert instance) and the second element is the XY coordinate of the mouse pick point. We just want the entity name, the first element of this returned list. Use the AutoLISP “car” function to extract the first element. So, let’s do it again. Type this at the “Command:” prompt and pick on the upper bubble:

Command: (car (entsel)) [Enter]
Select object: [pick on text in upper bubble] <Entity name: 7ffffb04930>

Remember, just like in the previous lessons, we need to keep those “(” and “)” balanced out. For each “(” you add, you need to balance it with a “)”. Okay, good so far. Now let’s modify our “program” to open up the returned entity name with a call to “entget”:
 
Command: (entget (car (entsel))) [Enter]
Select object: [pick on text in upper bubble] ((-1 . <Entity name: 7ffffb04930>) (0 . “INSERT”) (330 . <Entity
name: 7ffffb039f0>) (5 . “18B”) (100 . “AcDbEntity”) (67 . 0) (410 . “Model”)
(8 . “0″) (100 . “AcDbBlockReference”) (66 . 1) (2 . “bubble”) (10 0.0 0.0 0.0)
(41 . 1.0) (42 . 1.0) (43 . 1.0) (50 . 0.0) (70 . 0) (71 . 0) (44 . 0.0) (45 .
0.0) (210 0.0 0.0 1.0))
 
Okay, so this is the available information returned when we picked on the block insert instance with (entsel). If you compare this cryptic list of data (the very top part below) with the upper part of the LIST command’s display when pick the same item (shown below beginning at the “list” command entry), you can see some of the potential data match-ups. Each piece of data is represented by a “dotted pair”. There is a lead number, referred to as the “DXF code”, identifies what the data on the right-hand side of the dot is associated with. We can guess at the ones shown here… they seem to match up:
 
autolisp005b
 
Here is a partial list of DXF codes (i.e. the left-hand number in each dotted pair). This is pulled from the Visual Lisp on-line HELP (topic = “DXF group codes in numerical order”).
 
autolisp005d
 
 
The problem
 
No problem getting information on the overall block insert instance itself. The problem is that we cannot get access to the attribute text embedded inside of the block insert instance… we cannot specifically “pick” on it.  No matter what we pick on the block insert, whether it is the circle part or the attribute part of the block, (entsel) always returns the entity name of the overall block insert. What we really need is a pick function that digs deeper into these complex entities and pulls out the “nested” sub-entity name of what we pick.
 
 
Selection of nested sub-entities with (nentsel)
 
This is where the AutoLISP function (nentsel) comes into play. It works like (entsel) but, if you pick on an entity that is part of an overall complex entity like a block insert instance or a multi-segment polyline, (nentsel) returns the picked sub-entity name, not the main overall entity name that (entsel) always returns.
 
So, let’s try it on the top bubble. Type this at the “Command:” prompt and pick on the text attribute inside of the top bubble block insert:
 
Command: (entget (car (nentsel))) [Enter]
Select object: [pick on text in upper bubble] ((-1 . <Entity name: 7ffffb04940>) (0 . “ATTRIB”) (330 . <Entity
name: 7ffffb04930>) (5 . “18C”) (100 . “AcDbEntity”) (67 . 0) (410 . “Model”)
(8 . “0″) (62 . 2) (100 . “AcDbText”) (10 -0.0606988 -0.0385562 0.0) (40 .
0.078125) (1 . “52″) (50 . 0.0) (41 . 1.0) (51 . 0.0) (7 . “Standard”) (71 . 0)
(72 . 4) (11 0.0 0.0 0.0) (210 0.0 0.0 1.0) (100 . “AcDbAttribute”) (280 . 0)
(2 . “BUBNUM”) (70 . 0) (73 . 0) (74 . 0) (280 . 0))
 
Okay, now compare the above data return from (entget (car (nentsel))) with the original “LIST” display on the whole bubble block insert. Note that the data returned due to the (nentsel) pick now points at the attribute itself, NOT the overall block insert instance as we saw with (entsel).
 
 
autolisp005c 
 
How do we know that the “62″ type identifies the entity “Color” assignment? Look at the bottom of the “DXF codes” listing. DXF code “62″ is associated with a fixed color assignment (i.e. not “ByBlock” or “ByLayer”). The value that is the right-hand part of the 62 dotted pair is the color number.
 
Our yellow attribute text is forced to remain yellow at all times because the BUBNUM attribute carries a (62 . 2) subrecord. Color yellow is color number 2!
 
Experiment – rewrite the attribute to color 1 – RED.
 
If we could only force this attribute’s (62 . 2) subrecord to be (62 . 1), then maybe it would turn “red”. Let’s try.
First step, we repeat the last command but we save the entity’s data in a variable we’ll call “old_data”. Type this at the Command: prompt.
 
Command:(setq old_data (entget (car (nentsel)))) [Enter]
Select object: [pick right on the attribute]((-1 . <Entity name: 7ffffb26940>) (0 . “ATTRIB”) (330 . <Entity
name: 7ffffb26930>) (5 . “18C”) (100 . “AcDbEntity”) (67 . 0) (410 . “Model”)
(8 . “0″) (62 . 2)(100 . “AcDbText”) (10 -0.0606988 -0.0385562 0.0) (40 .
0.078125) (1 . “52″) (50 . 0.0) (41 . 1.0) (51 . 0.0) (7 . “Standard”) (71 . 0)
(72 . 4) (11 0.0 0.0 0.0) (210 0.0 0.0 1.0) (100 . “AcDbAttribute”) (280 . 0)
(2 . “BUBNUM”) (70 . 0) (73 . 0) (74 . 0) (280 . 0))
 
Now we’re going to use a “substitution” AutoLISP function called “subst” along with a couple other cryptic fuctions “cons” and “assoc”. Type this at the Command: prompt.
 
Command: (setq new_data (subst (cons 62 1) (assoc 62 old_data) old_data)) [Enter]
((-1 . <Entity name: 7ffffb26940>) (0 . “ATTRIB”) (330 . <Entity name:
7ffffb26930>) (5 . “18C”) (100 . “AcDbEntity”) (67 . 0) (410 . “Model”) (8 .
“0″) (62 . 1)(100 . “AcDbText”) (10 -0.0606988 -0.0385562 0.0) (40 . 0.078125)
(1 . “52″) (50 . 0.0) (41 . 1.0) (51 . 0.0) (7 . “Standard”) (71 . 0) (72 . 4)
(11 0.0 0.0 0.0) (210 0.0 0.0 1.0) (100 . “AcDbAttribute”) (280 . 0) (2 .
“BUBNUM”) (70 . 0) (73 . 0) (74 . 0) (280 . 0))
 
Okay, now we have our new version of the entity’s data held in a variable called “new_data”.
 
One more step. We push this new version of the data back out to the entity. Type this at the Command: prompt.
 
Command: (entmod new_data) [Enter]

… and the attribute instantly changes from yellow (color 2) to red (color 1) !

autolisp005e

Wrapping all this into a little utility

That was instructive, but very painful. Let’s put all of these steps into a little ASCII text file, give it a “.lsp” extension, and APPLOAD it to use when needed.

Here it is using the Visual Lisp editor (any ASCII text editor can be used).

autolisp005g

APPLOAD the file and, when you need it, type ATTR2COLOR [Enter] at the Command: prompt. Change the color of as many “non-BYLAYER” colored attributes as you can pick!

About these ads

3 Comments »

  1. Excellent job of explaining the how and why. This has definately helped me out. Keep using this approach to sharing your knowldege. Thank you.

    Comment by Wayne — September 10, 2009 @ 8:49 am

  2. [...] (Note: previous postings: Lesson 001, Lesson 002, Lesson 003, Lesson 004, and Lesson 005) [...]

    Pingback by Nate’s Simple AutoLISP – Lesson 006 « AutoCAD Electrical Etcetera — September 26, 2009 @ 6:18 pm

  3. (defun c:zz ()
    (setq z2(getpoint “to point>>” (setq z1(getpoint “from point>>”)))
    ag(angle z1 z2)
    cn1(fix(/ (distance z1 z2) 0.6))
    )
    (while (> cn1 -1)
    (setq p1 z1
    p2 (polar z1 (+ ag (ang 0)) 0.3)
    p3 (polar p2 (+ ag (ang 270)) 2.5)
    p4 (polar z1 (+ ag (ang 270)) 2.5)
    )
    (plg p1 p2 p3 p4)
    (setq z1 (polar z1 ag 0.6)
    cn1 (- cn1 1))
    ))
    (defun plg (pt1 pt2 pt3 pt4)
    (entmake (list (cons 0 “LWPOLYLINE”)
    (cons 100 “AcDbEntity”)
    (cons 8 “ZEBRA”)
    (cons 100 “AcDbPolyline”)
    (cons 90 4)
    (cons 70 1)
    (append (list 10) pt1)
    (append (list 10) pt2)
    (append (list 10) pt3)
    (append (list 10) pt4)))
    )
    (defun ang (a)
    (* pi (/ a 180.0))
    )

    Comment by Ahmad Tarmizi — February 12, 2013 @ 1:14 pm


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

The Shocking Blue Green Theme. Create a free website or blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

Join 25 other followers

%d bloggers like this: