Revit 2015 R2, UR4 and Dimension Prefix & Suffix

Today, let's take a quick look at the Revit product updates that were published last week and a discussion on workarounds for an issue making use of the dimension Prefix and Suffix properties:

Revit 2015 Release 2 and Revit 2015 Update Release 4

Two different Revit updates were released last week: Revit 2015 Release 2 (R2) and Revit 2015 Update Release 4 (UR4).

Revit 2015 R2 is a new version introducing new functionality, both in the product and API, available to subscription customers.

Revit 2015 UR4 is a normal update release and a subset of R2.

You can access the download sources for Revit 2015 UR4 on the Autodesk Revit product pages.

From a product point of view, the features and differences are explained by AEC Magazine and Doug Bowers Consulting.

To drill down in depth and for information on specific areas, please refer to the overview and links to detailed discussions on specific topics compiled by Jeff Pinheiro, The Revit Kid.

Finally, here are the direct pointers to the official lists of enhancements:

Revit 2015 Release 2 and Revit 2015 Update Release 4 API Enhancements

The API enhancements for these two different versions are identical.

For your convenience, here they are:

Dimension Prefix & Suffix Workarounds

Remy van den Bor of ICN Solutions ran into an issue accessing the dimension Prefix and Suffix properties and had an interesting discussion about it with Scott Wilson, providing several possible workarounds.

I hope you don't encounter the same issues; if you do, however, here are some hints on handling them:

Question: I noticed something strange with Revit dimensions in Revit 2014 and 2015.

I make a collection of dimensions. I want to check whether a prefix or suffix is used. When a value is found, put the value in a textbox.

The problem lies in the dim(seg).Prefix != null and dim(seg).Suffix != null part.

Lets say a dimension has a suffix "mm". When asking for dim.Prefix it will return "" (empty string).

BUT, when no prefix or suffix is used, Revit will throw an AccesViolation error and close down without a warning!

So, you cannot check dim.Prefix or dim.Suffix when no pre- or suffixes are set. The value will not be an empty string, it just crashes Revit.

The workaround I use for now is to check whether the dim.value is a double. If not, I know a prefix or suffix is used. If the value can be parsed to a double, I bypass the dim.prefix call.

Does anybody know how to solve this in a proper way?

Here is my workaround that seems to work. I check to see whether the dimseg.value is a string. If not, the crash can be avoided:

  private bool CheckVal( string val )
  {
    foreach( char c in val )
    {
      if( !char.IsDigit( c ) && c != '.' )
      {
        return true;
      }
    }
    return false;
  }

  // . . .

  if( CheckVal( dimseg.ValueString ) )
  {
    if( string.IsNullOrEmpty( txtPrefix.Text ) )
    {
      txtPrefix.Text = dimseg.Prefix;
    }
    if( string.IsNullOrEmpty( txtSuffix.Text ) )
    {
      txtSuffix.Text = dimseg.Suffix;
    }
  }

Answer by Scott: I devised a couple of workarounds for avoiding the crash while we wait for it to get looked at and hopefully remedied.

The first was quite tedious and involved independently building the dimension string exactly as you would get from ValueText using the dimension type properties and then checking that against the segment to determine whether any text modifiers existed.

That would be painful to implement and thankfully you don't have to, there's a much better way. If you assign a value to any of the text properties, it gives the API enough of a nudge that it wakes up and fixes the faulty properties in a similar way to what I was seeing with the UI editor.

So, before you attempt to access any of the potentially bugged properties, simply take one of the well behaved ones (such as .Above ) and re-assign its value to itself (so that no information is lost) and you're all good, no more crashing. I hope...

Change the last part of your code to:

  foreach( DimensionSegment dimseg in dim.Segments )
  {
    dimseg.Above = dimseg.Above; // Hello API, are you awake?
 
    if( string.IsNullOrEmpty( txtPrefix.Text ) )
    {
      txtPrefix.Text = dimseg.Prefix;
    }
    if( string.IsNullOrEmpty( txtSuffix.Text ) )
    {
      txtSuffix.Text = dimseg.Suffix;
    }
  }

Edit: Oh I see you already have a work around   :-) – Oh well, here's another!

By the way, simply checking for non-numerical characters in the ValueText is likely to include any segments that contain text due to unit suffixes and alternate units. These segments will still crash if accessed. Unless you have full control over the environment and are certain that no text could be present unless added manually, then I wouldn't use it in production code.

Response: I tried using Scott's "// Hello API, are you awake?" approach in Revit 2014, but it results in the same crash.

So that workaround only works for Revit 2015. I confirmed that it really does work there :-)