Announcements

Starting in December, we will archive content from the community that is 10 years and older. This FAQ provides more information.

Lisp for Creating a Legend: Need Help with specifying spacing

ISG-mpower
Contributor
Contributor

Lisp for Creating a Legend: Need Help with specifying spacing

ISG-mpower
Contributor
Contributor

Hello, 

 

I have a lisp routine which will create a legend of specified lines used in a drawing, but I need some help specifying the spacing between each line of text. I need a specific distance of 0.168 between each line of text. Here is the routine:

 

(defun C:LEGEND ( / *error* acdoc acobj an co e hs ht i la lst lt p p1 p2 p3 space ss st ro dr)
(vl-load-com)
(setq acObj (vlax-get-acad-object)
acDoc (vla-get-activedocument acObj)
space (vlax-get acDoc (if (= 1 (getvar 'cvport)) 'PaperSpace 'ModelSpace))
)
(vla-startundomark acDoc)

;;;;;; Error function ;;;;;;;;;
(defun *error* (msg)
(and
msg
(not (wcmatch (strcase msg) "*CANCEL*,*QUIT*,*BREAK*"))
(princ (strcat "\nError: " msg))
)
(if (and a (not (vlax-erased-p a))) (vla-delete a))
(vla-endundomark acDoc)
(princ)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(setq st (entget (tblobjname "style" (getvar 'textstyle)) '("AcadAnnotative"))
an (member '(1070 . 1) (cdr (member '(1070 . 1) (cadr (assoc -3 st)))))
hs (cdr (assoc 40 st))
ro (angle '(0 0 0) (trans (getvar "UCSXDIR") 0 (trans '(0 0 1) 1 0 T)))
dr (trans '(0 0 1) 1 0 T)
)
(if
an
(setq ht (/ (if (> hs 0) hs 3.0) (cond ((getvar 'cannoscalevalue)) (1.0))))
(setq ht (* (if (> hs 0) hs 3.0) (getvar 'ltscale)))
)
(if
(setq ss (ssget))
(progn
(repeat (setq i (sslength ss))
(setq
e (entget (ssname ss (setq i (1- i))))
la (cdr (assoc 8 e))
lt (cdr (assoc 6 e))
co (cdr (assoc 62 e))
)
(if
(not (member (list la lt co) lst))
(setq lst (cons (list la lt co) lst))
)
)
(setq lst (vl-sort lst '(lambda (a b) (< (car a) (car b)))))
(if
(setq p (getpoint "\nSpecify insert point: "))
(foreach x lst
(setq p1 (trans p 1 0)
p2 (trans (polar p 0.0 (* 10 ht)) 1 0)
p3 (trans (polar p 0.0 (* 11 ht)) 1 0)
)
(entmake
(list
'(0 . "LINE")
(cons 8 (car x))
(cons 10 p1)
(cons 11 p2)
(cons 6 (cond ((cadr x)) ("ByLayer")))
(cons 62 (cond ((caddr x)) (256)))
)
)
(vla-put-textalignmentpoint
(vlax-ename->vla-object
(entmakex
(list
'(0 . "TEXT")
(cons 8 (car x))
(cons 6 (cond ((cadr x)) ("ByLayer")))
(cons 62 (cond ((caddr x)) (256)))
'(100 . "AcDbText")
(list 10 0 0 0)
(cons 40 ht)
(cons 1 (car x))
(cons 50 ro)
(cons 7 (getvar 'textstyle))
(cons 72 0)
(list 10 0 0 0)
(cons 210 dr)
(cons 73 2)
)
)
)
(vlax-3d-point p3)
)
(setq p (polar p (/ pi -2.0) (* 2 ht)))
)
)
)
)
(*error* nil)
(princ)
)

0 Likes
Reply
Accepted solutions (4)
2,651 Views
24 Replies
Replies (24)

ISG-mpower
Contributor
Contributor

Attached is the code with proper formatting:

0 Likes

rgrainer
Collaborator
Collaborator
Accepted solution

(setq p (polar p (/ pi -2.0) (* 2 ht)))

You could try adjusting the portion code: (* 2 ht) try a number different than 2 and see what happens.
it look like ht is your current text height. try changing that and see what happens.

0 Likes

ISG-mpower
Contributor
Contributor

That was it. Thank you šŸ™‚

0 Likes

ISG-mpower
Contributor
Contributor

My next question on the subject is how do I specify the names of the lines be created using Title Case and not all uppercase? Also, I want all of the names of the lines to be placed on a specific layer (TEXTG), is that possible?

0 Likes

ISG-mpower
Contributor
Contributor

Furthermore, I would like to add to the LISP the ability to select all blocks and include their symbol and description in the legend above the lines. Is this possible?

0 Likes

rgrainer
Collaborator
Collaborator
Accepted solution

Layer name on a specific layer? Is that possible?......
near the bottom of the lisp, look for:


(entmakex
(list
'(0 . "TEXT")
(cons 8 (car x)) .......change this line to  ------>   '(8 . "TEXTG")
(cons 6 (cond ((cadr x)) ("ByLayer")))


0 Likes

rgrainer
Collaborator
Collaborator

Lee Mac has a nice program named "block-count" or "bcount" or something like that. 

0 Likes

ISG-mpower
Contributor
Contributor

You've been very helpful. Thank you. I appreciate your time. It is nice to be able to make a program run the way you want it do.

0 Likes

ISG-mpower
Contributor
Contributor
Accepted solution

Actually, changing that line to '(8."TEXTG") didn't seem to work. 

 

I input (cons 8 (cond ((cadr x)) ("TEXTG"))) and that seems to work. I'm not sure I understand exactly what this code is doing in order to place the text on the "TEXTG" layer I have, but it works and I am good with it.

0 Likes

rgrainer
Collaborator
Collaborator

It might be easier to just adjust the name of your layers before running the legend maker:


;CapFirst.lsp by Ken Alexander
;from Autodesk Customisation Newsgroup
;7 September 2002
;Routine to rename layer names with a Capital as the first
;letter and all others lower case.

(defun C:CapFirst (/ fl rl new)
(vl-load-com)
(vlax-for x (vla-get-layers
(vla-get-activedocument (vlax-get-acad-object)))
(setq fl (substr (vla-get-name x) 1 1)
rl (substr (vla-get-name x) 2)
new (strcat (strcase fl) (strcase rl T)))
(vla-put-name x new))
(princ)
)

0 Likes

rgrainer
Collaborator
Collaborator

Sorry, try this instead:
(cons 8 "TEXTG")

0 Likes

ISG-mpower
Contributor
Contributor

Ok @rgrainer . I am close with this routine, but I am having trouble specifying the length of the lines that are created. Right now they are too short. I would have to lengthen them every time I use this routine. It seems like this routine is doing some transformation of coordinates and such, but I feel like I have tried changing every variable to change the line length and I can do, but they end up angled and whatnot. Any help?

0 Likes

rgrainer
Collaborator
Collaborator
Accepted solution

Here's a solution, not very elegant, but it should help you:

find this place in your code:

 

[code]

(setq lst (vl-sort lst '(lambda (a b) (< (car a) (car b)))))

[add this line below it------>] (setq ht1 (* ht 3))
(if
(setq p (getpoint "\nSpecify insert point: "))
(foreach x lst
(setq p1 (trans p 1 0)
p2 (trans (polar p 0.0 (* 10 ht1)) 1 0) [;;;; change both instances of the ht to ht1]
p3 (trans (polar p 0.0 (* 11 ht1)) 1 0) [;;;;; same here]
)

[code]

(* ht 3);;;;;;; try a different number  here to get the line length you need

also check your osnap and make sure it is off before running the command.

 

 

0 Likes

ISG-mpower
Contributor
Contributor

Great! It is perfect. Thank you.

 

Just so I understand better, what is this (setq ht1 (* ht 3)) saying in the routine exactly?

 

And so the 10 and 11 in these is what was causing a fixed length?

p2 (trans (polar p 0.0 (* 10 ht1)) 1 0) [;;;; change both instances of the ht to ht1]
p3 (trans (polar p 0.0 (* 11 ht1)) 1 0) [;;;;; same here]

0 Likes

rgrainer
Collaborator
Collaborator

You're welcome

 

Just so I understand better, what is this (setq ht1 (* ht 3)) saying in the routine exactly?

 

ht is set earlier in the routine and it is the height of the current text style. So what I did is just to create a variable named "ht1" which is just doing some math.....  " * " is multiply, the value of "ht" by 3. 

10 is the assoc value for start of a line and 11 is the endpoint of that line. 

You will need to be aware of your current text style before running this function in the future.

or put something like this in the routine that sets the current style to what you want the legend text to be:
(command "style" "arial" "arial.ttf" 0 "" "" "" "" "")

except you don't want the height to be 0. set it to whatever you are using now.

Let me ask you; what are you using this for? Plumbing, mechanical or ?

0 Likes

ISG-mpower
Contributor
Contributor
I see. So you are adding the numerical value of the text height to both the starting point and endpoint of the line to make it a longer line? So that is why the lines will be associated with the text style. Luckily I only ever use the same text style for the purposes this routine will be used for, but thank you for the heads up.

I'm using this to create an automatic legend routine for all of the lines, polylines, arcs, and blocks that are used in the model space. I already had the block routine portion complete and it is great, but I use various linetypes that have text shapes in the line segment which don't show up unless the line is at least a specific length. Hence the need to lengthen them in this routine.

0 Likes

rgrainer
Collaborator
Collaborator

What i was getting at is trying to find out what is the discipline of your work? Can you tell me what that is?

I'm trying to understand what it is you are doing with a legend that is being created this way. How many linetypes will be in a typical job that you do? 10, 50, 100? I hope you don't mind me asking this.


In my work (surveying) I have a few pre-made legend blocks that show all the linetypes I could ever need. 

One is the default linetypes which is used on almost all work produced. It has about a dozen items in it. It's a dynamic block which allows for display states to show more or less items depending on the product/type of map I create. I have another one for underground utilities (like you have: lines with text character(s) at certain intervals) and I use that when required. All my symbols are also in a block and in about 5 minutes I'll edit the block per job to show only the symbols that are being used.  Could you use blocks for your legends?

0 Likes

Bryan-Kelley
Enthusiast
Enthusiast

Hello Everyone,

 

  I am very interested in this thread due to a need from one of the teams here.  I'm looking for a routine that would gather all the blocks in the drawing, and place another insertion of them, either in model space or paper space, for each occurrence.

 

  For example, if there are 7 Blocks of A and 4 Blocks of B within the drawing, I'd like to place a copy of each and every one of them in one location within the drawing.  This would be used to create labels to go to a laser cutter for the team without the need of them to rekey in data after searching through a large printed drawing with multiple pages.  Ideally the Blocks would all be touching and all text would be aligned with the World X-Axis.

 

BryanKelley_1-1678469850828.png

 

Thank you,

Bryan

Thanks,
Bryan

Bryan Kelley | Sr. CAD Administrator | Columbia Machine | www.colmac.com
0 Likes

Sea-Haven
Mentor
Mentor

Its looking very tricky, have a google for "Nesting Autocad lisp" may produce a solution.

0 Likes