June 24, 2006

Automatically Displaying a Viewport’s Scale

For those not using Project Navigator and the Callouts that are linked to a Model Space View, there are two ways to display the scale of a viewport that will update "semi-automatically". Users of Autodesk Architectural Desktop 2004 or later can use Formula properties to obtain and format the viewport scale. Users of Autodesk Architectural Desktop 2005 and later can use a field in Text, Mtext or an Attribute attached to a Block Reference. Each method has its advantages and disadvantages; use the method that works best for you and your workflow.

A sample file created in ADT 2006 that contains examples of both techniques has been posted to this thread in the Autodesk Architectural Desktop Dicussion Group. The content in that file is not meant to be finished content suitable for project use, but was developed solely to demonstrate that the ideas work. Testing of the content was fairly limited; should you choose to adapt any of it for your own use, please test it thoroughly to be certain it performs as you expect.

Fields
Setting up a field is certainly easier than setting up the formulas and tags. I used Dtext to hold the field, but you could add it to an attributed block just as easily. After adding the field or attributed block with the field, you will need to edit the field. Choosing the Object Field Name, use the Select Object button to select the desired viewport, select the Custom Scale Property and choose your desired Format. The 2006 version of the dialog can be seen in the image below.

I noted the following with respect to using fields:
  • Formatting in fields is "static" - you pick one of the given formats and that is how the scale is displayed. For example, Imperial "architectural" scales are usually given in terms of the distance that represents 1’-0" [1/4" = 1’-0"], while "engineering" scales are given as the distance that 1" represents [1" = 50’-0"]. There are formats for each type, but you would have to manually set that for each field. The 1" = #’ format only shows the distance as feet, not feet and inches.
  • If the scale factor of a viewport is close but not quite an exact "typical" scale, the value may round to a "typical" scale value, masking the error.
  • The #" = 1’-0" and #" = 1’ formats will always express any fractional number with a denominator that is 2 raised to some power [halves, quarters, eighths, etc.]. You will not get 1/10" = 1’-0", but 13/128" = 1’-0", which is not an exact expression of the scale.
  • 2006 and 2007 offer a formatting option, "Use scale name", that overcomes the previously mentioned issues by displaying scales that have been entered into the Scale List using the scale name. You will have to enter all of the scales you expect to use in the Scale List, but you would probably want to do that anyway. Viewport scales that do not match a value associated with a scale on the list are displayed as the raw custom scale number, making it easy to spot viewports which have "close, but not quite" scales. 2005 lacks this option, as well as the option to express Imperial scales as 1" = a number of feet.

Formulas
You can retrieve the CustomScale property for a viewport object using a Formula property that is part of a Property Set Definition attached to the viewport. You can then format that value however you like, provided you are willing to write the code to do so. There is also a StandardScale property, which returns an integer that is likely related to the Scale List, but in the time I spent looking at this, I was not able to work out how to take that number and use it to get the associated scale name.

The following assumptions were made in developing the sample Formula properties. If your situation varies, you may need to adjust the formulas to suit.
  • Drawing units for Imperial are inches and for Metric are millimeters. Other base units may require adjustments to compensate.
  • Metric scales are expressed as ratios of plotted units to real-world units, with one side or the other set to 1.
  • Imperial scales are expressed as fractions of an inch equal one foot, when the fractions of an inch can be given as a whole number of 256ths of an inch. The fraction is reduce to the lowest possible denominator. Otherwise, Imperial scales are given as 1" = a number of feet and inches.

The ViewportObjects Property Set Definition in the sample file contains the following properties:
  • DetailNumber - A text-type Manual property for entering a detail number.
  • DetailTitle - A text-type Manual property for entering a detail title.
  • Handle - An Automatic property that references the Handle automtatic property source. This property is used to get the viewport object in the ViewportScale Formula property.
  • Measurement - A Formula property that gets the value of the Measurement System Variable. This is used to determine if the viewport scale should be formatted for Imperial [value is 0] or Metric [value is 1].
  • ViewportScale - A Formula property that gets the value of the viewport's CustomScale property, and returns the inverse of that value.
  • ViewportScaleString - A Formula property that takes the value in the ViewportScale property and formats it, based on the Measurement property value and the ViewportScale value. Metric scales are expressed as a ratio of plotted units:real-world units. When each plotted unit represents more than one real-world unit [typical in architectural drawing], this results in 1:[scale factor]. For that rare case where you are showing a detail at larger than full-size, the scale is given as [1/scale factor]:1. Where Imperial scales can be expressed as a whole number of 256ths of an inch = 1'-0", that format is used, otherwise, the scale is expressed as 1" = feet and inches.

I chose to use two separate properties, one to get the scale value, and another to do the formatting, to make it easier to test these two functions. You could just as easily use one formula and eliminate any issues that might arise when reading the ViewportScale value into the ViewportScaleString property, such as the reduction of the precision to a maximum of eight decimal places.

The Measurement formula reads in the value of the MEASUREMENT System Variable, using this formula:
Set acadApp = GetObject(,"AutoCAD.Application")
RESULT = acadApp.ActiveDocument.GetVariable("MEASUREMENT")


The ViewportScale formula gets the viewport object using the Handle Automatic Property Source. Since viewports are in paper space, there will be no issue with the Handle source not working across externally referenced files; using Handle lets the same formula work in any version since the introduction of the Formula property in ADT 2004. Once the viewport object is in hand, getting the CustomScale object and taking its inverse is easily done.
Set acadApp = GetObject(,"AutoCAD.Application")
Set pViewportObj = acadApp.ActiveDocument.HandleToObject( "[Handle]" )
RESULT = 1 / pViewportObj.CustomScale


The ViewportScaleString property uses the value from the ViewportScale property and performs the formatting need to create the string to be displayed. As shown in the code below, the first test is for whether the drawing is using Metric or Imperial, based on the value in the Measurment property [MEASUREMENT System Variable value].
scaleFactor = [ViewportScale]

If [Measurement] = 1 Then
' Metric drawing
If scaleFactor > 1 Then
scaleFactor = Fix( scaleFactor * 10000.0 ) / 10000.0
RESULT = "1 : " & CStr( scaleFactor )
Else
inverseScaleFactor = Fix( 10000.0 / scaleFactor ) / 10000.0
RESULT = CStr( inverseScaleFactor ) & " : 1"
End If
Else
'Imperial drawing
'If 12.0/scaleFactor is a whole number of 256ths, return string as that
'fraction, reduced to lowest denominator = 1'-0"; otherwise, return string as
'1" = feet (and inches).

inchesPerFoot = 12.0 / scaleFactor
maxNumerator = inchesPerFoot * 256.0
If ( maxNumerator - Fix( maxNumerator ) ) = 0 Then
minNumerator = maxNumerator
powerOfTwo = 0
tempNumerator = minNumerator / 2.0
Do While tempNumerator - Fix ( tempNumerator ) = 0.0
powerOfTwo = powerOfTwo + 1
minNumerator = tempNumerator
If powerOfTwo = 8 Then
Exit Do
End If
tempNumerator = minNumerator / 2.0
Loop
minDenominator = 256.0 / 2^powerOfTwo
RESULT = minDenominator
wholeTotalInches = Fix ( minNumerator / minDenominator )
properInchesNumerator = minNumerator - ( wholeTotalInches * minDenominator )
wholeFeet = Fix ( wholeTotalInches / 12.0 )
wholeInches = wholeTotalInches - (wholeFeet * 12.0)

If wholeFeet = 0 Then
strWholeFeet = ""
Else
strWholeFeet = CStr( wholeFeet ) & "'-"
End If

If (wholeInches = 0) and (wholeFeet = 0) Then
strInches = CStr( properInchesNumerator ) & "/" & CStr( minDenominator )
Elseif properInchesNumerator = 0 Then
strInches = CStr( wholeInches )
Else
strInches = CStr( wholeInches ) & " " & CStr( properInchesNumerator ) & "/" & CStr( minDenominator )
End If

RESULT = strWholeFeet & strInches & Chr(34) & " = 1'-0" & Chr(34)

Else
wholeFeet = Fix( scaleFactor / 12.0 )
inches = ( Fix( ( scaleFactor - ( wholeFeet * 12.0) ) * 10000 ) / 10000 )
RESULT = "1" & Chr(34) & " = " & CStr(wholeFeet) & "'-" & CStr( inches ) & Chr(34)
End If
End If


Please note the following with regard to rounding: The ViewportScale property returns the inverse of the CustomScale property of the viewport, with up to eight-decimal places. The ViewportScaleString arbitrarily cuts off formatted Metric scales and Imperial scales using the 1" = feet and inches format to four decimal places without rounding. This should not be an issue if your viewport scale is a standard scale with a whole number scale factor; displaying some fractional value can help identify viewports that have been incorrectly set up or modified.

Updating of the Scales – Field and Formula
If you have read this far, you may have forgotten my use of the term "semi-automatic" way back in the first paragraph to describe the updating of the scale properties. Here is what I observed in my sample file, during the limited testing that I did. The values do not always update instantaneously; I did not test what would happen when plotting the file with a value that had not been updated. If you have all of the "Automatically update field values" options selected [User Preferences tab of the Options dialog] - including Plot - I would not expect to have a problem with fields, but you would certainly want to test this before using it in a production environment.
  • Changes made to the scale of a viewport using any of the following methods routinely did not automatically update the scale value in the Schedule Tag or in a field. REGEN [REGENALL from Model Space] updated a field in MTEXT; OBJRELUPDATE was often needed to update the Schedule Tag [and also works on fields].
    • ZOOM command in Model Space of the viewport [all options, including real time].
    • Rolling the mouse wheel in Model Space of the viewport.
    • Viewport Scale Control [a toolbar control that is a feature of the ACAD.cui Viewports toolbar], in Model Space or Paper Space. ADT does not include this toolbar, so this may not be an issue for you unless you have the ACAD.cui loaded, have transferred the Viewports toolbar to the ADT.cui or have added the Viewport Scale Control to a custom toolbar of your own.
  • Changes made to the scale by selecting the viewport in Paper Space and using the Properties palette appear to be udated immediately in a Schedule Tag; a REGEN is required to update a field. Note: On occasion, but not consistently, I have seen changes made using the Custom property not automatically update in a Schedule Tag. In these cases, a REGEN has updated that tag value.
  • Changes made to the scale by selecting the viewport in Paper Space and using the VP Scale list on the Drawing Window Status Bar appear to be updated immediately in a Schedule Tag; a REGEN is required to update a field. Note: On occasion, but not consistently, I have seen changes made using the Custom option not automatically update in a Schedule Tag. In these cases, a REGEN has updated that tag value.
  • Changes made to the scale in Model Space and using the VP Scale list on the Drawing Window Status Bar appear to be updated immediately in a Schedule Tag; a REGENALL is required to update a field [or change to Paper Space and use REGEN]. Note: On occasion, but not consistently, I have seen changes made using the Custom option not automatically update in a Schedule Tag. In these cases, a REGENALL has updated that tag value.

One other note of caution: Do not use this with multiple versions of Architectural Desktop running - not simply installed, but with separate instances of multiple versions actually running - on the same computer simultaneously. I experienced "lock ups", where not only the Schedule Tag, but the Property Data as displayed on the Properties palette, remained fixed on the initial value, even after saving, closing and reopening the file. Closing all but one instance of one version of Architectural Desktop and reopening the file restored the ability of the properties to update.

No comments: