Jump to content

Set Text Size per VP Scale


ksperopoulos

Recommended Posts

I am wanting to set my textsize variable to a specific value depending on the viewport scale. I am thinking this can be done in a lisp by reading the vpscale and then processing it through some sort of an if, then statement. Am I along the right path or should I be looking in a different direction?

Link to comment
Share on other sites

  • Replies 23
  • Created
  • Last Reply

Top Posters In This Topic

  • ksperopoulos

    9

  • Lee Mac

    7

  • BlackBox

    6

  • irneb

    1

Not that this couldn't be done with code, but have you instead simply considered using Annotative text which you specify a "Paper Text Height" for, and the Viewport's Annotation Scale (which will also control the zoom scale in a one-way relationship) determines the actual size for you?

 

Just a thought.

Link to comment
Share on other sites

Believe me, if I could, I would. That is how we do all annotation outside of the vertical product we use on top of AutoCad. Their automatic annotation does not support annotative text or dimension styles. This drives me crazy!

Link to comment
Share on other sites

Well, in that case, methinks you'll be implementing a Command and DocManager Reactor combo (to handle MDI environment, SDI=0), and you'll need to check for Model Space, Paper Space, or PViewport Active to determine which 'scale' to use to programmatically update the TextSize system variable.

 

Oh, and you might throw in a SysVar, or Lisp Reactor as well, to watch for when other routines/users initiate changes in order to act accordingly. Just watch for loops.

Link to comment
Share on other sites

Also - do you have several text sizes? E.g. one for notes, another for view titles, another for area names, etc. How do you determine the final height of these?

 

The issue is that a text style with a height gets that height irrespective of the current TextSize system variable. It actually reverts back to the style's height each time text is drawn. It's only when the style's height = 0 when the TextSize variable has any effect. But when the style's height = 0, how do you know what this piece of text's final height is supposed to be? Thus you'll either have to hard-code each stylename=PS height or save such into a dictionary/xdata, but in either case all your styles' heights need to be = 0.

 

Then if you can use anno scale to set the viewport's height it might be a bit easier, since you can get to the VP's "zoom factor" through the CAnnoScaleValue system variable. Otherwise you'll need to calculate the VP's zoom e.g. from its DXF XData.

 

And then are you only concerned with placing text through a viewport? I.e. if you're in the Model tab do you ignore scale factor / CAnnoScale?

Link to comment
Share on other sites

I do have the text height of the style I want to change set to 0. I was thinking something simple...like if the viewport scale is set to 1/2"=1'-0" the text size would automatically adjust to 2 1/4". If the scale is set to 1/4"=1'-0", the text size would adjust to 4 1/2". Everything would be done from paperspace.

Link to comment
Share on other sites

This topic lends to an idea of mine that I have yet to bring to fruition for a .NET plug-in, that stores settings in XML, which allow for ObjectModified Event handlers to programmatically 'update' all annotation entities (i.e., Dims, Leaders, MText, MLeaders, Text, etc.) when those entities are placed/changed to a new layer based upon the user-defined settings in the XML.

 

Still trying to determine if it would be better to register entity level Event handlers, or the Database itself instead.

 

\tangent

Link to comment
Share on other sites

...methinks you'll be implementing a Command and DocManager Reactor combo...

 

If I understand the your links on these two reactors correctly, the Command reactor will start a chain of events that the DocManager reactor will respond to as long as the lisp is loaded in that particular drawing. So as long as I set up the Command reactor to watch the scale of the viewport, the DocManager reactor will automatically perform a specified command of my choice, right?

 

Sounds like what I want to do. Now the hard part....making it happen. Thanks for pointing me in the right direction.

Link to comment
Share on other sites

If I understand the your links on these two reactors correctly, the Command reactor will start a chain of events that the DocManager reactor will respond to as long as the lisp is loaded in that particular drawing. So as long as I set up the Command reactor to watch the scale of the viewport, the DocManager reactor will automatically perform a specified command of my choice, right?

 

Sounds like what I want to do. Now the hard part....making it happen. Thanks for pointing me in the right direction.

 

Not exactly... A Command Reactor will allow for you to call a function (aptly named a Callback), when the Command Reactor's Events fire (i.e., CommandWillStart, CommandEnded, etc.). For example, when you're in Paper Space, and activate a PViewport, the MSPACE Command is invoked (event when double clicking).

 

The Command Reactor will be responsible for calling your 'Reconcile' function (a function to determine which space is active; i.e., Model, Paper, or PViewport Active), within the current drawing (the ActiveDocument Object).

 

The DocManager Reactor will be responsible for calling your 'Reconcile' function when you switch drawings (Documents)... This allows for one Document to be in Paper space, and another to be in PViewport Active, and simply switching back and forth to call the 'Reconcile' function to programmatically take the necessary action(s).

 

The crux of this, is that the code must be loaded within each drawing opened (Document added to the DocumentCollection), in order for it to give the user the illusion that this just works automagically... I use AcadDoc.lsp to load these sort of customizations.

 

You sound like you're at that point where your mind has just been opened to the many possibilities that this sort of customization can offer, and the right time to allow you to 'discover' some for yourself... Give it a try, coding this yourself, and we'll be here when you get stuck. That (coding for yourself, and it not working, then having to learn how to fix it) will do more for you than I ever can. :thumbsup:

Link to comment
Share on other sites

  • 2 weeks later...

OK, this is not the way suggested above. I think I am too green in writing lisps to accomplish the reactor route. But I thought (after reading through some sections of the Afralisp site) I could try to at least utilize a conditional function. Am I not understanding how to use conditionals because the following is not working like I thought it would based on what I read.

 

(defun c:tsize (/ vps tsz)
 (setq vps (getvar "_cannoscale"))
 (setq tsz (cond
      ((= vps "1/8\042 = 1'-0\042") 9.000)
      ((= vps "1/4\042 = 1'-0\042") 4.500)
      ((= vps "1/2\042 = 1'-0\042") 2.250)
      ((= vps "3/4\042 = 1'-0\042") 1.500)
      ((= vps "1\042 = 1'-0\042") 1.125)
      ((= vps "1-1/2\042 = 1'-0\042") 0.750)
      (t nil)
      )
)
 (setvar "textsize" tsz)
 (command "_regenall")
 (princ)
 )

Link to comment
Share on other sites

Prior to this version, I did use CANNOSCALEVALUE. That ended up only returning the very last line of the conditional statement and wouldn't return any other value for the text size when I changed the scale of the viewport and then ran the program again.

Link to comment
Share on other sites

Here are two alternatives based on your code:

 

(defun c:tsize ( / tsz )
   (if
       (setq tsz
           (cdr
               (assoc (/ 1.0 (getvar 'cannoscalevalue))
                  '(
                       (96.0 . 9.000)
                       (48.0 . 4.500)
                       (24.0 . 2.250)
                       (16.0 . 1.500)
                       (12.0 . 1.125)
                       (08.0 . 0.750)
                   )
               )
           )
       )
       (setvar 'textsize tsz)
   )
   (princ)
)

 

(defun c:tsize ( / )
   (setvar 'textsize (/ 3.0 (* (getvar 'cannoscalevalue) 32.0)))
   (princ)
)

Link to comment
Share on other sites

Prior to this version, I did use CANNOSCALEVALUE. That ended up only returning the very last line of the conditional statement and wouldn't return any other value for the text size when I changed the scale of the viewport and then ran the program again.

 

Then perhaps you need to adjust the hard-coded values (Strings) you're testing against... I use Decimal, not what looks like Architectural units above... But for me, 1" = 20' (for example), actually returns "1\" = 20'" when I use (getvar 'cannoscale).

Link to comment
Share on other sites

This is what I have in my first version. The value I was getting when I found the CANNOSCALEVALUE was a long decimal number. I found it was the scale (in fraction format) divided by 12.

 

(defun c:tsize (/ vps tsz)
 (setq vps (getvar "_cannoscalevalue"))
 (setq tsz (cond
      ((= vps "0.010417") 9.000)
      ((= vps "0.020833") 4.500)
      ((= vps "0.041667") 2.250)
      ((= vps "0.062500") 1.500)
      ((= vps "0.083333") 1.125)
      ((= vps "0.125000") 0.750)
      (t nil)
      )
)
 (setvar "textsize" tsz)
 (command "_regenall")
 (princ)
 )

Link to comment
Share on other sites

The value I was getting when I found the CANNOSCALEVALUE was a long decimal number.

 

You have correctly understood that the CANNOSCALEVALUE System Variable holds a value of Double [REAL] data type, but yet you are comparing strings in the conditional statement in your code:

 

          ((= vps "0.010417") 9.000)
         ((= vps "0.020833") 4.500)
         ((= vps "0.041667") 2.250)
         ((= vps "0.062500") 1.500)
         ((= vps "0.083333") 1.125)
         ((= vps "0.125000") 0.750)

 

Also, as noted, the underscore non-localisation prefix is not required for System Variables:

 

(setq vps (getvar "[highlight][color=red]_[/color][/highlight]cannoscalevalue"))

Link to comment
Share on other sites

I'm not sure I am following a couple of items in your code Lee. If the apostrophe (') is supposed to signify a list, does this also act as a type of variable that you can call from? Here is what I am referring to:

 

                (assoc (/ 1.0 (getvar[color="red"] 'cannoscalevalue[/color]))
                 [color="red"] '[/color](
                       (96.0 . 9.000)
                       (48.0 . 4.500)
                       (24.0 . 2.250)
                       (16.0 . 1.500)
                       (12.0 . 1.125)
                       (08.0 . 0.750)
                   )

 

You also put the apostrophe before the system variable TEXTSIZE. Does it recall the second element of the list with your use of CDR?

 

Does any of this make sense?:?

Link to comment
Share on other sites

If the apostrophe (') is supposed to signify a list...

 

I'll stop you there ;)

 

The apostrophe does not signify a list. The apostrophe (or quote) is used to mark an expression as a literal - to be taken at 'face-value' - i.e. not evaluated by the AutoLISP interpreter.

 

Consider the following examples:

 

'(1 2 3 4 5) == (list 1 2 3 4 5)

Here, the quoted list of integers is equivalent to supplying the list function with 5 integer arguments.

 

'((1 . 2) (3 . 4)) == (list (cons 1 2) (cons 3 4))

Again, the quoted list structure is taken at 'face-value' as a list of dotted pairs. To construct this list using AutoLISP functions would require a combination of the list and cons functions, as shown.

 

_$ (setq x 4)
4
_$ (list 1 2 3 x)
(1 2 3 4)
_$ '(1 2 3 x)
(1 2 3 X)

This example demonstrates what is meant by such terms as 'literal' and 'face-value'.

 

Here we have assigned the symbol x a value of 4; in the first expression, the list function is supplied with 4 arguments: 1, 2, 3 & x. The variable x is hence evaluated by the list function and the list is returned (1 2 3 4).

 

When the list is quoted, it is marked as a literal and hence not evaluated; this results in the symbol x not being evaluated and remaining as a symbol in the list.

 

However, the apostrophe or quote is not just used with lists, as these examples demonstrate:

 

_$ (mapcar '+ '(1 2 3 4 5) '(6 7 8 9 10))
(7 9 11 13 15)

Here, the apostrophe is used to mark the function '+' as an argument for the mapcar function, and the two list arguments are also quoted as they do not contain expressions to be evaluated. (Consider that if the '+' function were not quoted, we would receive a 'bad function' error, since the '+' symbol would be evaluated to return a pointer to its function definition).

 

If you have an aversion to apostrophes, the above could equivalently be written as:

 

(mapcar (quote +) (quote (1 2 3 4 5)) (quote (6 7 8 9 10)))

Or, for optimisation when compiling to VLX/FAS, the function function may be used:

 

_$ (mapcar (function +) '(1 2 3 4 5) '(6 7 8 9 10))
(7 9 11 13 15)

Concerning the getvar / setvar examples: the apostrophe is used since the getvar / setvar functions can accept either a string or symbol argument:

 

_$ (getvar "osmode")
191
_$ (getvar 'osmode)
191

And so the symbol is quoted to be passed to the getvar (or setvar) function as an argument, rather than being evaluated.

 

As above, this could alternatively be written:

 

_$ (getvar (quote osmode))
191

Note that if the apostrophe was not used, the expression would be evaluated as:

 

_$ (getvar osmode)
; error: bad argument type: (or stringp symbolp): nil

Since the osmode symbol holds no value in the active document namespace.

 

Of course, we could assign a value to this symbol (just to confuse you):

 

_$ (setq osmode 'osmode)
OSMODE
_$ (getvar osmode)
191

Edited by Lee Mac
Fixed typo
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...