Need help understanding Define DXF function

Need help understanding Define DXF function

Anonymous
Not applicable
1,816 Views
13 Replies
Message 1 of 14

Need help understanding Define DXF function

Anonymous
Not applicable

I need a little help in understanding this code:

 

;; Define DXF function
(defun dxf (code elist)
(cdr (assoc code elist))
); end function dxf

 

I see this code in quite a few lisp routines including some older routines at my office. Am i understanding this correctly that you are defining a function called DXF. You are given the function two arguments which are "code" and "elist"? code is the dxf code and elist is just the name of an entity list? You are creating a dotted pair using the assoc function, then using the cdr function  to return the elist? 

 

you can then call dxf later in the routine and supply it with another dxf code and another entity list? Is that the purpose of this code or does it do something else?

0 Likes
Accepted solutions (1)
1,817 Views
13 Replies
Replies (13)
Message 2 of 14

CodeDing
Advisor
Advisor
Accepted solution

@Anonymous ,

 

To help understand your function, let's first cover what a DXF code is:

- A DXF code is a number (an integer), and this number will ALWAYS be paired with another piece of information. Together these 2 items will create a Dotted Pair. Every entity in AutoCAD is composed of many dotted pairs. These dotted pairs, together, store all information necessary to identify how an entity is built / constructed.

 

Now, since we need to be able to build entities and likewise retrieve entity information, we need to categorically save or search for this information in some orderly fashion. The DXF codes maintain this order. This means that if know how to interpret what piece of information is attached with the DXF code in our Dotted Pair, then we can make use of it.

 

Let's look at a quick example:

If you look at THIS list of DXF codes, we can see that DXF group code 8 represents the layer name. Now that we know this information (and also remember that DXF code = ALWAYS part of a dotted pair), if we were to locate a dotted pair with a DXF code of 8, we will also know that the other piece of information in that dotted pair will be the layer name!

It would look like this:

(8 . "Defpoints")

(Now, remember, the second piece is merely the layer name and will not always be "Defpoints")

 

Awesome, now we know how to interpret our dotted pairs! So what about your function? Ok, so now we have to throw some more info into the mix.

 

Using this line of code, we can select an entity and return its list of entity information (in this case we select a LINE):

(entget (car (entsel "\nSelect an Entity: ")))

Example return:
((-1 . <Entity name: 1bbd1d0>) (0 . "LINE") (330 . <Entity name: 1bbd0c8>) (5 . "6A") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "0") (100 . "AcDbLine") (10 1.0 2.0 0.0) (11 6.0 5.0 0.0) (210 0.0 0.0 1.0))

Nice, look at those Dotted Pairs! This is sometimes called an entity list. We can use our DXF code references to find out what all those numbers mean inside this entity list.

But how can we extract the layer name from this elist (entity list)? Well, we can use your function!

If we pass the layer DXF code (the number 8) and the elist to your function, it will use the ASSOC function to search the elist for a dotted pair containing your provided DXF code, then return the second piece of information from that dotted pair (using the CDR function).

It would look like this:

(dxf 8 ((-1 . <Entity name: 1bbd1d0>) (0 . "LINE") (330 . <Entity name: 1bbd0c8>)
(5 . "6A") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "0") (100 . "AcDbLine")
(10 1.0 2.0 0.0) (11 6.0 5.0 0.0) (210 0.0 0.0 1.0)))

This would return:
"0"

Layer name is 0! (it looks like a lot, but this is merely your code = 8 & elist = [all the items associated with the entity])

 

HERE is a really great and thorough document for DXF codes (save it for later).

 

While your function is a simple one, it may help you to learn how to access entity information in a simplistic manner.

 

Hope this helps. Best,

~DD

Message 3 of 14

Anonymous
Not applicable

Thanks,

I am familiar with at least some of the DXF codes. The thing that i noticed was that this exact code is in a lot of different  lisp routines that i have come across online and in my office. I was curious as to why this was. 

In our case, once we have this function defined we use it to build a list of layers that is in a specific drawing.

 

;;CREATE LIST OF LAYERS IN THE DRAWING
(SETQ l1 (tblsearch "layer" "0" T))
(while l1
(setq lays (cons (strcase (dxf 2 l1)) lays))
(setq l1 (tblnext "layer"))
)

 

So, i guess i was correct in my thinking that code is an argument that is the DXF code which gets passed to the function DXF and elist is also an argument that contains the entity info of what the dxf code is referencing which also. gets passed to the function . Here is our display routine if anyone cares to look at it.

 

 

0 Likes
Message 4 of 14

CodeDing
Advisor
Advisor

@Anonymous ,

 

I had never seen this dxf function before you posted it. While I understand it's purpose, it does not appear to provide enough value to have it'its own function definition since the code it replaces is not much longer or harder to understand:

(dxf code elist)
Same as: (cdr (assoc code elist))
Message 5 of 14

ronjonp
Mentor
Mentor

FWIW I'd put a little error checking into it and pass the ename to it:

(defun dxf (code ename)
  (if (= 'ename (type ename))
    (cdr (assoc code (entget ename)))
  )
)
0 Likes
Message 6 of 14

Anonymous
Not applicable

I thought it was just so it could be used later in the routine. In our routine its used to build a list of layers in a drawing. When i googled the code to try and understand it, i found multiple other routines that had the exact same code. That's why i was curious as to why that was.

0 Likes
Message 7 of 14

ronjonp
Mentor
Mentor

Another thing to note is ASSOC will work on lists that are NOT dotted pairs too 🙂

 

Try it:

(setq l '((1 2 3) (4 56) (7 "Yup 7") ("Yup 8" 8 9 10 11 12)))
(foreach i (mapcar 'car l) (print (assoc i l)))
0 Likes
Message 8 of 14

Moshe-A
Mentor
Mentor

@Anonymous  hi,

 

and more things to know about cdr, dotted pair and lists. while most of the data returned by (entget) are dotted pair, some are not, like points.

 

(10 1.0 2.0 0.0)

 

the difference is seen by CDR function

if you call cdr on a dotted pair, the return value would be an atom (the second  item in the list which may be any data there...e.g integer, real or a string)

if you call cdr on a list (like a point) the return value is a list (the point => 'decapitate' the first dxf item)

 

Moshe

 

 

 

 

 

 

 

 

 

 

0 Likes
Message 9 of 14

dgorsman
Consultant
Consultant

I've only seen it in one place myself, some widely available and very old shareware-type LISP.  The source wasn't very good e.g. variables not localized and poorly named.  I've seen copies where it's obvious the entire file was copied, support functions and all, so the end user has multiple functions with the same name and usually the same function content.

 

As mentioned it's not a very good use of a function.  It doesn't do anything other than saving a handful of characters, which is debatable since spreading the nested function calls over several lines makes it more readable. 

----------------------------------
If you are going to fly by the seat of your pants, expect friction burns.
"I don't know" is the beginning of knowledge, not the end.


0 Likes
Message 10 of 14

Anonymous
Not applicable

Thanks for the feedback everyone. I'm still learning this stuff so i appreciate the help and the suggestions.Maybe the person who created our routine found the code online than used it in the multiple routines that we have. when i started researching it i did find it in a couple of different places so that's why i was wondering about it. Anyway, thanks everyone. 

0 Likes
Message 11 of 14

ВeekeeCZ
Consultant
Consultant

It's not so rarely seen. I searched my disk and found about 10 routines with this, even from respected authors.

 

Funny that I came across this interesting comment:

;;; GETVAL - returns the group value of an entity.
;;; like the wellknown (dxf) function but accepts all kinds of
;;; entity representations (ename, entget list, entsel list)
Message 12 of 14

Anonymous
Not applicable

So it sounds like this function is useless if "GETVAL" does the same thing and more.


@ВeekeeCZ wrote:

It's not so rarely seen. I searched my disk and found about 10 routines with this, even from respected authors.

 

Funny that I came across this interesting comment:

;;; GETVAL - returns the group value of an entity.
;;; like the wellknown (dxf) function but accepts all kinds of
;;; entity representations (ename, entget list, entsel list)



0 Likes
Message 13 of 14

ronjonp
Mentor
Mentor

IMO you should structure your subfunctions to do a certain task and be diligent about filtering what you're going to pass to them. If you have a function that does a bunch of conditional checks but the input is always the same you're adding unnecessary overhead. That's just me though.

 

That being said here is a sledgehammer approach 🙂

 

(defun dxf (code something)
  (if something
    (cdr (assoc	code
		(cond ((= 'ename (type something)) (entget something))
		      ((and (= 'list (type something)) (vl-every 'vl-consp something)) something)
		      ((= 'vla-object (type something)) (entget (vlax-vla-object->ename something)))
		)
	 )
    )
  )
)
;; Examples
(dxf 10 (car (entsel)))
;; Don't miss your pick!
(dxf 10 (vlax-ename->vla-object (car (entsel))))
(dxf 10 '((8 . 3) (10 0. 0. 0.)))

 

 

0 Likes
Message 14 of 14

Anonymous
Not applicable

Thanks for the code samples. That's a good thing to keep in mind. I did not create this routine, but in the future i will do my best to use the best practices. My office has a bunch of legacy routines that were created before i arrived. We also have another routine called "AVP" that  analyzes a viewport and creates an asci file of layers to be turned on for a specific display type like a construction floor plan or a reflected ceiling plan. Maybe we could probably do the same thing with layer states, but this is how we have done things for awhile.

0 Likes