ksperopoulos Posted December 4, 2012 Share Posted December 4, 2012 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? Quote Link to comment Share on other sites More sharing options...
BlackBox Posted December 4, 2012 Share Posted December 4, 2012 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. Quote Link to comment Share on other sites More sharing options...
ksperopoulos Posted December 4, 2012 Author Share Posted December 4, 2012 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! Quote Link to comment Share on other sites More sharing options...
BlackBox Posted December 4, 2012 Share Posted December 4, 2012 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. Quote Link to comment Share on other sites More sharing options...
irneb Posted December 5, 2012 Share Posted December 5, 2012 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? Quote Link to comment Share on other sites More sharing options...
ksperopoulos Posted December 5, 2012 Author Share Posted December 5, 2012 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. Quote Link to comment Share on other sites More sharing options...
BlackBox Posted December 5, 2012 Share Posted December 5, 2012 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 Quote Link to comment Share on other sites More sharing options...
ksperopoulos Posted December 8, 2012 Author Share Posted December 8, 2012 ...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. Quote Link to comment Share on other sites More sharing options...
BlackBox Posted December 8, 2012 Share Posted December 8, 2012 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. Quote Link to comment Share on other sites More sharing options...
ksperopoulos Posted December 19, 2012 Author Share Posted December 19, 2012 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) ) Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted December 19, 2012 Share Posted December 19, 2012 You may find it easier to use the CANNOSCALEVALUE System Variable: (getvar 'cannoscalevalue) FYI: Non-localisation prefixes ('_') are only required with commands. Quote Link to comment Share on other sites More sharing options...
ksperopoulos Posted December 19, 2012 Author Share Posted December 19, 2012 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. Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted December 19, 2012 Share Posted December 19, 2012 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) ) Quote Link to comment Share on other sites More sharing options...
BlackBox Posted December 19, 2012 Share Posted December 19, 2012 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). Quote Link to comment Share on other sites More sharing options...
BlackBox Posted December 19, 2012 Share Posted December 19, 2012 Very nice, Lee. Quote Link to comment Share on other sites More sharing options...
ksperopoulos Posted December 19, 2012 Author Share Posted December 19, 2012 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) ) Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted December 19, 2012 Share Posted December 19, 2012 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")) Quote Link to comment Share on other sites More sharing options...
ksperopoulos Posted December 19, 2012 Author Share Posted December 19, 2012 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? Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted December 19, 2012 Share Posted December 19, 2012 (edited) 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 May 14, 2013 by Lee Mac Fixed typo Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted December 19, 2012 Share Posted December 19, 2012 Very nice, Lee. Cheers dude Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.