Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Help to modify lisp routine

25 REPLIES 25
SOLVED
Reply
Message 1 of 26
ASCunningham
1697 Views, 25 Replies

Help to modify lisp routine

Could someone help me out with this. I've found this lisp routine posted online and I would like to make one change to it. Right now because are text styles are set at 0 height this routine doesn't work. What I would like is have it set the current textsyle to "ba" and then run the routine but I've not been able to figure out have to do this. Any help is greatly appreciated

;;;
 ;;; ct - inserts text on line or circle
 ;;;
 (defun C:CT (/ C_LAYER BOX TP1 TP2 PT1 BTST INS
 OBJNAME OBJLST ENT_TYP LS TEST FACTOR SPT
 ANG RAD SS
 ) ;_ end of /
 (setq OLDERR *ERROR*
 *ERROR* CTERR
 ) ;_ end of setq
 (setq C_LAYER (getvar "clayer"))
 (setvar "cmdecho" 0)
 (setq OTXT TXT)
 (if (= OTXT NIL)
 (setq OTXT "")
 ) ;_ end of if
 (setq TXT (getstring (strcat "\nEnter Text " "<" OTXT ">: ") t))
 (if (= TXT "")
 (setq TXT OTXT)
 ) ;_ end of if
 (setq BOX (textbox (list (cons 1 TXT)))
 TP1 (car BOX)
 TP2 (cadr BOX)
 ) ;_ end of setq
 (while (not
 (setq PT1 (nentsel "\nSelect point on Line, or Arc: "))
 ) ;_ end of not
 (princ "\nNothing selected, try again.")
 ) ;_ end of while
 (setq BTST (osnap (cadr PT1) "qui,ins"))
 (if (not BTST)
 (progn
 (setq INS (osnap (cadr PT1) "qui,nea")
 OBJNAME (car PT1)
 OBJLST (entget OBJNAME)
 ENT_TYP (cdr (assoc 0 OBJLST))
 LS (cdr (assoc 8 OBJLST))
 TEST (osnap INS "qui,cen")
 FACTOR (getvar "dimscale")
 T_STYLE (getvar "textstyle")
 ) ;_ end of setq
 (if (not TEST)
 (progn
 (setq SPT (cdr (assoc 10 OBJLST))
 ANG (atof (angtos (angle SPT INS) 0 4))
 ) ;_ end of setq
 (if (and (> ANG 90.0) (<= ANG 270.0))
 (setq ANG (- ANG 180.0))
 ) ;_ end of if
 (if (= ANG 180.0)
 (setq ANG 0.0)
 ) ;_ end of if
 ) ;_ end of progn
 ) ;_ end of if
 (if TEST
 (progn
 (setq ANG (atof (angtos (angle INS TEST) 0 4)))
 (if (> ANG 180.0)
 (setq ANG (- ANG 180.0))
 ) ;_ end of if
 ) ;_ end of progn
 ) ;_ end of if
 (setq RAD (+ (distance TP1 TP2) (* 0.06 FACTOR)))
 (command "circle" INS "d" RAD)
 (setq SS (entlast))
 (command "trim" SS "" INS "")
 (entdel SS)
 (if TEST
 (command "text" "style" T_STYLE "m" INS (- ANG 90.0) TXT)
 (command "text" "style" T_STYLE "m" INS ANG TXT)
 ) ;_ end of if
 (command "layer" "s" C_LAYER "")
 ) ;_ end of progn
 (princ "\n\n*** Select line or arc only. ***")
 ) ;_ end of if
 (setq *ERROR* OLDERR)
 (princ)
 ) ;_ end of defun

 (defun CTERR (S)
 (if (/= S "Function cancelled")
 (princ (strcat "\nError: " S))
 ) ;_ end of if
 (if OLDERR
 (setq *ERROR* OLDERR)
 ) ;_ end of if
 (command "layer" "s" C_LAYER "")
 (princ)
 ) ;_ end of defun 

 

25 REPLIES 25
Message 2 of 26
Kent1Cooper
in reply to: ASCunningham


@iam4phils wrote:

... I would like to make one change to it. Right now because are text styles are set at 0 height this routine doesn't work. What I would like is have it set the current textsyle to "ba" and then run the routine but I've not been able to figure out have to do this. Any help is greatly appreciated

....
  (setq ... ...  T_STYLE (getvar "textstyle") .... (command "text" "style" T_STYLE "m" INS (- ANG 90.0) TXT) (command "text" "style" T_STYLE "m" INS ANG TXT) ....

If your "ba" style is zero-height, you will need to provide an answer to the height prompt in the appropriate place in the Text commands.

 

As to the setting of the style, it seems odd to me that it would save the current Text style and then assign that with the style option in the Text commands, when it could just leave the style option out of the Text commands, since it's going to use the current Text style.  But in any case, you can get it to do what you want in several ways.  You could either:

 

A) [This is what I would probably do] Omit the setting of the T_STYLE variable entirely, and put your style name directly into the (command) functions in its place, i.e.:

 

(command "text" "style" "ba" "m" INS YourTextHeight (- ANG 90.0) TXT)

 

and similarly with the line below it, OR:

 

B) Leave it using a variable for the style, and change it to what you want where that is set:

 

(setq ....

  T_STYLE "ba"

....

(command "text" "style" T_STYLE "m" INS YourTextHeight (- ANG 90.0) TXT)

 

C) Omit the setting of the T_STYLE variable, set the current Text style with the System Variable, and omit it from the Text commands:

 

(setvar 'textstyle "ba")

(command "text" "m" INS YourTextHeight (- ANG 90.0) TXT)

 

[Those all depend on "ba" being a zero-height style.  If "ba" is a style with a defined height, leave out the YourTextHeight entries in all of the above suggestions.]

 

EDIT:  Consider whether you would want to change the current Text style back to what it was before the routine, which can be done by saving that first and re-setting it afterwards:

 

(setq t_style (getvar 'textstyle); save what it is beforehand

(setvar 'textstyle "ba"); make yours current

....

(command "text" "m" INS YourTextHeight (- ANG 90.0) TXT)

....

(setvar 'textstyle t_style); reset to what it was before

Kent Cooper, AIA
Message 3 of 26
ASCunningham
in reply to: ASCunningham

I would like to not have to enter a text size and have it set from the drawing dimscale. I’ve tried a few variations of this with no luck

 

(setq tsize (setvar "textsize" (* 0.09375 scl1))

(command "text" "style" "ba" "m" INS "textsize" (- ANG 90.0) TXT)

(command "text" "style" "ba" "m" INS "textsize" ANG TXT)

))

Message 4 of 26
dicra
in reply to: ASCunningham

If you are setting text size from dimscale, first you will have to save dimscale in variable. If scl1 is yours variable, first you have to do something like this:

 

(setq scl1 (getvar "dimscale"))

 

or you could do something like this, whit out storing dimscale to variable:

 

(setq tsize (setvar "textsize" (* 0.09375 (getvar "dimscale"))))

 

On this way you will save text size in variable tsize, so when you are using it in command you suppose to do something like this:

 

(command "text" "style" "ba" "m" INS tsize (- ANG 90.0) TXT)

 

Hope this is helpful...

 

 

 

Message 5 of 26
Kent1Cooper
in reply to: ASCunningham


@iam4phils wrote:

I would like to not have to enter a text size and have it set from the drawing dimscale. I’ve tried a few variations of this with no luck

 

(setq tsize (setvar "textsize" (* 0.09375 scl1))

(command "text" "style" "ba" "m" INS "textsize" (- ANG 90.0) TXT)

(command "text" "style" "ba" "m" INS "textsize" ANG TXT)

))


If you've set the current Text height with the System Variable, and the Text style you're using is zero-height so that the Text command will ask for a height, then you can just use Enter [an empty string of two double-quotes] at the height prompt to accept the default:

(command "text" "style" "ba" "m" INS "" (- ANG 90.0) TXT)

 

Also this:

(setq tsize (setvar "textsize" (* 0.09375 scl1))

is missing a right parenthesis, but can be just this:

(setvar "textsize" (* 0.09375 scl1))

But if you also need that tsize variable for something else, keep what you have and add a ) at the end to close the (setq) function.

Kent Cooper, AIA
Message 6 of 26
ASCunningham
in reply to: ASCunningham

Adding this

(setq tsize (setvar "textsize" (* 0.09375 (getvar "dimscale")))) worked

 however it also looks like I just could have used

(command "text" "style" "ba" "m" INS "" (- ANG 90.0) TXT)

Message 7 of 26
dicra
in reply to: ASCunningham

Well yes, you should use or: 

 

(setq tsize (* 0.09375 (getvar "dimscale"))

(command "text" "style" "ba" "m" INS tsize (- ANG 90.0) TXT)

 

or:

 

(setvar "textsize" (* 0.09375 (getvar "dimscale")))

(command "text" "style" "ba" "m" INS "" (- ANG 90.0) TXT)

 

whit this:

(setq tsize (setvar "textsize" (* 0.09375 (getvar "dimscale"))))

 

You are doing two things, setting system variable "textsize", and storing it to tsize

Message 8 of 26
ASCunningham
in reply to: Kent1Cooper

I've had one more request. We would like to have the command hold the text value entered and allow us to pick multiple points on a line for text placement and not have to repeat the entire command when its used.

;;;
 ;;; break_line_text - inserts text on line or circle
 ;;;
 (defun C:break_line_text (/ C_LAYER BOX TP1 TP2 PT1 BTST INS
 OBJNAME OBJLST ENT_TYP LS TEST FACTOR SPT
 ANG RAD SS
 ) ;_ end of /
 (setq OLDERR *ERROR*
 *ERROR* CTERR
 ) ;_ end of setq
 (setq C_LAYER (getvar "clayer"))
 (setvar "cmdecho" 0)
 (setq tsize (setvar "textsize" (* 0.09375 (getvar "dimscale"))))
 (setq OTXT TXT)
 (if (= OTXT NIL)
 (setq OTXT "")
 ) ;_ end of if
 (setq TXT (getstring (strcat "\nEnter Text " "<" OTXT ">: ") t))
 (if (= TXT "")
 (setq TXT OTXT)
 ) ;_ end of if
 (setq BOX (textbox (list (cons 1 TXT)))
 TP1 (car BOX)
 TP2 (cadr BOX)
 ) ;_ end of setq
 (while (not
 (setq PT1 (nentsel "\nSelect point on Line, or Arc: "))
 ) ;_ end of not
 (princ "\nNothing selected, try again.")
 ) ;_ end of while
 (setq BTST (osnap (cadr PT1) "qui,ins"))
 (if (not BTST)
 (progn
 (setq INS (osnap (cadr PT1) "qui,nea")
 OBJNAME (car PT1)
 OBJLST (entget OBJNAME)
 ENT_TYP (cdr (assoc 0 OBJLST))
 LS (cdr (assoc 8 OBJLST))
 TEST (osnap INS "qui,cen")
 FACTOR (getvar "dimscale")
 T_STYLE (getvar "textstyle")
 ) ;_ end of setq
 (if (not TEST)
 (progn
 (setq SPT (cdr (assoc 10 OBJLST))
 ANG (atof (angtos (angle SPT INS) 0 4))
 ) ;_ end of setq
 (if (and (> ANG 90.0) (<= ANG 270.0))
 (setq ANG (- ANG 180.0))
 ) ;_ end of if
 (if (= ANG 180.0)
 (setq ANG 0.0)
 ) ;_ end of if
 ) ;_ end of progn
 ) ;_ end of if
 (if TEST
 (progn
 (setq ANG (atof (angtos (angle INS TEST) 0 4)))
 (if (> ANG 180.0)
 (setq ANG (- ANG 180.0))
 ) ;_ end of if
 ) ;_ end of progn
 ) ;_ end of if
 (setq RAD (+ (distance TP1 TP2) (* 0.06 FACTOR)))
 (command "circle" INS "d" RAD)
 (setq SS (entlast))
 (command "trim" SS "" INS "")
 (entdel SS)
 (if TEST
 (command "text" "style" "ba" "m" INS tsize (- ANG 90.0) TXT)
 (command "text" "style" "ba" "m" INS tsize ANG TXT)
 ) ;_ end of if
 (command "layer" "s" C_LAYER "")
 ) ;_ end of progn
 (princ "\n\n*** Select line or arc only. ***")
 ) ;_ end of if
 (setq *ERROR* OLDERR)
 (princ)
 ) ;_ end of defun

 (defun CTERR (S)
 (if (/= S "Function cancelled")
 (princ (strcat "\nError: " S))
 ) ;_ end of if
 (if OLDERR
 (setq *ERROR* OLDERR)
 ) ;_ end of if
 (command "layer" "s" C_LAYER "")
 (princ)
 ) ;_ end of defun

 

Message 9 of 26
Kent1Cooper
in reply to: ASCunningham

Now that I look more at what that code does, beyond just the original question about working with the Text Style, I see that it's quite similar to something I have been toying with lately, triggered by a similar routine on another website.  It's further refining the fix-some-things routine I posted in a comment there [subject to the little correction in comment 6 (on the Next page)].  The further development is not quite ready, but should be soon, and it overcomes several things [no offense meant....] about yours that I notice:

 

Yours does several things in more complicated ways than necessary.  Were you aware that you can use a piece of Text as a Trim boundary, and if you pick a trimmable object inside it, it will take out the piece inside the Text's virtual "box"?  That can spare you all the calculation of the size of a Circle to surround it, and drawing it and using it as a Trim boundary and erasing it.  [Consider also whether to use text Masking instead....]

 

Yours calculates the Text angle by comparison of some Osnap results, differently for Lines and Arcs/Circles, even applying the results differently in alternative Text commands for the different selected-entity types.  That limits the operation to a few entity types, but there's one pretty easy catch-all way to find the direction at a given point of a whole lot of entity types [Lines/Circles/Arcs/Polylines/Ellipses/Splines/Xlines/Rays], which would allow you to do this with any of those, without separate Text angle calculations for different types.

 

Yours finds the selected object's entity type, but never uses it to restrict the selection.  It forbids some entity types [Text, Mtext, Blocks, Xrefs, etc.] by testing whether they have an insertion point, but it would accept selection of a lot of things it might not know what to do with, and in some cases that it might think it knows what to do with, but would give unexpected results.  For instance, a Polyline selected on an arc segment would, I think, work as expected, but if it was selected on a line segment, would establish its angle from the selection point toward the first vertex, regardless of which segment it was selected on.  On a Spline, it would also find the angle from the selection point toward the start, regardless of where selected.  An Ellipse would have a center, but unless picked at a quadrant point, the resulting Text wouldn't have the right angle.  [Those can all be overcome with the catch-all direction-finder.]

 

The one I've been working on allows all those different entity types, asks again if you miss or pick the wrong kind of thing, gives the User options on Text Style and Height, accounts for whether the chosen Style is fixed-height or not, and a few other things such as a more "modern" error-handling approach.  I hope to get it to allow multiple selections in one running, too.  I'll try to wrap it up soon and post it here, if others don't offer similar routines.

Kent Cooper, AIA
Message 10 of 26
Kent1Cooper
in reply to: Kent1Cooper


@Kent1Cooper wrote:

....  The further development is not quite ready, but should be soon.... 

The one I've been working on allows all those different entity types, asks again if you miss or pick the wrong kind of thing, gives the User options on Text Style and Height, accounts for whether the chosen Style is fixed-height or not, and a few other things such as a more "modern" error-handling approach.  I hope to get it to allow multiple selections in one running, too.  I'll try to wrap it up soon ....


IN PROGRESS:  The attached does everything except the multiple-selection thing, so far.  But since it reports its settings without prompting for each of them every time [you call for options to set things], you can run it to get things set up as you like, then just whap the space bar and pick another object, whap it again and pick, whap, pick, etc.  It does automatically repeat the select-objects-or-pick-options prompt until you pick a valid object to label, so it lets you set as many options as you like in one running.  I do plan to get it to automatically repeat the object selection, too, which I have done in other routines, so I just need to work it in [pretty easy if you don't mind requiring Escape to end it; more complicated for an <exit> option on Enter/space].  But see what you think of it so far.

 

It also has additional options not mentioned above for the User to choose: the width factor, and the Layer on which the Text goes, with choices for the Current Layer and the Selected object's Layer in addition to any specific Layer name they want to call for.

Kent Cooper, AIA
Message 11 of 26
ASCunningham
in reply to: Kent1Cooper


Thanks your lisp routine is a definite improvement. I did get "my" routine to work but like you noted it is out of date and yours is much better. I posted my finished routine but I would suggest everyone use your's.

(defun texinlinelec_specify (/ olderr oldcmd oldosmode stop tmp epl p e ang obj param w
h xy)
(vl-load-com)
(setq lay1 (getvar "clayer"))
(setq lay2 "E-LINE-IDEN") 
(setq tsz1 (getvar"textstyle"))
(command "style" "ba" "simplex" 0.0 "" "" "" "" "")
(setvar "regenmode" 1)
(command "layer" "m" lay2 "c" clr11 "" "")

(setq OTXT TXT) (if (= OTXT NIL) (setq OTXT "") ) ;_ end of if
 
(setq txt (getstring (strcat "\nEnter Text " "<" OTXT ">: ") t))
(if (= TXT "") (setq TXT OTXT) ) ;_ end of if
 
(if (not #PTLfactor)
(setq #PTLfactor 0.2)
)
(if (not #PTLheight)
(setq #PTLheight 0.09375)
)
(setq oldcmd (getvar "cmdecho")
oldosmode (getvar "osmode")
olderr *error*
)
(defun *error* (msg)
(if (not (member msg (list "Function cancelled")))
(princ (strcat "PTL Error: " msg))
)
(setvar "cmdecho" oldcmd)
(setvar "osmode" oldosmode)
(setq *error* olderr)
(princ)
)
(if
(= 'STR (type txt))
(progn
(setq #PTLtext txt)
(setq #PTLheight (* 0.09375 (getvar "dimscale")))
;(princ "\nSpecify Text height:<")
;(princ "> ")
;(setq tmp (getdist))
;(if tmp
;(setq #PTLheight tmp)
;)
(setvar "cmdecho" 0)
(setvar "osmode" 0)
(setq xy (textbox (list (cons 1 #PTLtext) (cons 40 #PTLheight)))
h (* #PTLfactor (abs (cadr (mapcar '- (cadr xy) (car xy)))))
w (+ h
(/ (abs (car (mapcar '- (cadr xy) (car xy)))) 2.0)
)
)
(while (setq epl (entsel "\nPick Point On Line:"))
(cond
((member (cdr (assoc 0 (entget (setq e (car epl)))))
(list "LINE" "LWPOLYLINE")
)
(setq
param (fix (vlax-curve-getParamAtPoint
(setq obj (vlax-ename->vla-object e))
(trans (setq p (osnap (cadr epl) "Near")) 1 0)
)
)
ang (angle
(trans (vlax-curve-getPointAtParam obj param) 0 1)
(trans (vlax-curve-getPointAtParam obj (1+ param))
0
1
)
)
)
(if (and (> ang (/ pi 2.0)) (<= ang (* pi 1.5)))
(setq ang (+ ang pi))
)
(command "_.break" e (polar p ang w) (polar p (+ pi ang) w))
(command "_.-text"
"m"
p
#PTLheight
(angtos ang (getvar "aunits"))
#PTLtext
)
)
(T (princ "\nNot support for this object type!!!"))
)
)
)
(princ "\nCannot Process!!! Check txt variable!!!")
)
(setvar "cmdecho" oldcmd)
(setvar "osmode" oldosmode)
(setvar "clayer" lay1)
(setvar "textstyle" tsz1)
(setq *error* olderr)
(princ)
)

 

Message 12 of 26
Kent1Cooper
in reply to: Kent1Cooper


@Kent1Cooper wrote:
....  I do plan to get it to automatically repeat the object selection, too....


Here's the latest, that works that way [keep picking objects to label/trim in the same way, or choosing options to change settings, until you Exit by hitting Enter/space/Escape].

 

I also added an internal Undo option, so as you go, if something doesn't come out as you wanted [e.g. you picked the wrong thing, or you'd rather the label were in a slightly different position], you can "back up" and undo individual labels/trims, without getting out of the command.  [After you finish the command, Undoing will undo the whole command's worth of labels/trims, which is analagous to the way the Line and Pline and probably some other commands work.]

 

If your work involves Coordinate Systems other than the World, it will have problems in some circumstances [see note near the top].  Otherwise, it seems to work in a way that, at least, I like and will have a use for, so I hope others will find it useful, too.

Kent Cooper, AIA
Message 13 of 26
ASCunningham
in reply to: ASCunningham

Kent, I like the new routine. I've been lookng at it and I cannot figure out to set a specific layer. I would like to define the layer in the lisp routine and have the text put onto that layer (i.e. M-ITEM-IDEN) when the "line layer" might be M-HOTW-RETN. So I would like to make it something other than current layer or layer of the line the text is going on. Any suggestions?

 

I guess I could make "M-ITEM-IDEN" the current layer, set the text to that and then restore the previous layer, but I cannot figure it out.

Message 14 of 26
Kent1Cooper
in reply to: ASCunningham


@iam4phils wrote:

Kent, I like the new routine. I've been lookng at it and I cannot figure out to set a specific layer. I would like to define the layer in the lisp routine and have the text put onto that layer (i.e. M-ITEM-IDEN) when the "line layer" might be M-HOTW-RETN. So I would like to make it something other than current layer or layer of the line the text is going on. Any suggestions?

 

I guess I could make "M-ITEM-IDEN" the current layer, set the text to that and then restore the previous layer, but I cannot figure it out.


Notice that when you choose the laYer option, the prompt says:

Text Layer or [Current/Selected-object's] ...

 

The or in there is the key -- you don't have only the Current or Selected-object's options to choose from, but can type any Layer name in in response to that prompt.  It will remember it for subsequent use in the same editing session.

 

If you always want it to offer that particular Layer as the initial default so that you don't usually need to specify it (while still allowing the User the option to choose a different Layer), just change this line near the top:

 

  (if (not *ltxtLay) (setq *ltxtLay "Selected-object's")); Layer

 

to this:

 

  (if (not *ltxtLay) (setq *ltxtLay "M-ITEM-IDEN")); Layer

 

That's what the instruction a little above that is all about:

;;  Edit the following as desired for your initial global-variable defaults:

so you may want to adjust some of the others, too.

 

And, if Selected-object's is not the initial default, you might want to add something to Make that Layer, in case it isn't already in the drawing, and similarly with your chosen text Style if it's not STANDARD.

Kent Cooper, AIA
Message 15 of 26
ASCunningham
in reply to: Kent1Cooper

Thanks, I was using....

 (if (not *ltxtLay) (setq M-ITEM-IDEN "Selected-object's")); Layer

 

Obviously, I wasn't awake yet this morning when I was trying to work on this. Thanks again, the lisp routine is great.

 

 

 

Message 16 of 26
Kent1Cooper
in reply to: ASCunningham


@iam4phils wrote:

Thanks, I was using....

 (if (not *ltxtLay) (setq M-ITEM-IDEN "Selected-object's")); Layer

 

Obviously, I wasn't awake yet this morning when I was trying to work on this. Thanks again, the lisp routine is great.


You're welcome.  Ahhh, the good ol' put-the-replacement-in-place-of-the-wrong-part syndrome....  I know it well.

Kent Cooper, AIA
Message 17 of 26
Kent1Cooper
in reply to: Kent1Cooper


@Kent1Cooper wrote:
....
Here's the latest, ...

[That one posted in Message 12 still had a few under-construction elements in it -- use this cleaned-up one instead.]

Kent Cooper, AIA
Message 18 of 26
ASCunningham
in reply to: Kent1Cooper

I'm getting "Error: bad argument type: numberp: nil" error when trying to run the command.

Message 19 of 26
Kent1Cooper
in reply to: ASCunningham


@iam4phils wrote:

I'm getting "Error: bad argument type: numberp: nil" error when trying to run the command.


If you don't change its initial default Text Style [see instructions in line 77], it requires that there be a Text Style called "ROMANS" -- that's my standard default, which is different from how I posted it before [I forgot to change that].  If you don't have that in your typical drawing, change that to "STANDARD" [or whatever Style exists that you want as an initial default] in line 78, and see whether that fixes it.

 

If not, how far does it get?  Does it get so far as to ask for a Text value at first use?  To narrow it down, try getting the values of the numerical global variables, and see whether any of those returns nil. Type:
!*lttStyHt

!*lttHt

!*lttWf

 

Kent Cooper, AIA
Message 20 of 26
ASCunningham
in reply to: ASCunningham

I forgot about replacing the textstyle. Works great, thanks.

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost