Monday, February 7, 2011

[Revit API]–Hide Warnings in Revit using the API

The general rule ever since the Revit API was released, is that whatever you can do in the API, you can also do through the normal user interface.

In recent versions I’ve come across a few different examples of where the API is starting to let you do some things you can’t do through the interface (as far as I know – there may be a way I am missing!). One such example is interacting with warnings.

Revit 2011 introduced the new Failures API. This API lets you do two things:

1. Create new warnings within Revit

2. Respond to warnings reported by Revit.

I’m going to discuss option 2 today through a quick example. Lets say that you have a burning desire to place two walls in exactly the same position. Normally when you do this in Revit, you’ll get a warning that looks like the following:

image

Which you can ignore. This is a bit of a silly example, but in many offices there may be warnings in Revit which you ALWAYS accept, and therefore having them in the warnings menu simple messes up the signal to noise ratio, and could mean that real warnings get lost in the crowd.

To stop this warning from displaying, we can make use of the new failures API. To do this, we use an event called the FailuresProcessing event, so as per usual with events we need to make a new ExternalApplication and subscribe to that event:

 

public Result OnStartup(UIControlledApplication application)
{
    application.ControlledApplication.FailuresProcessing += ControlledApplication_FailuresProcessing;
    return Result.Succeeded;
}
 
public Result OnShutdown(UIControlledApplication application)
{
    application.ControlledApplication.FailuresProcessing -= ControlledApplication_FailuresProcessing;
    return Result.Succeeded;
}

Whenever Revit does its failures checks, which is at a number of points in time, including after making our wall, or when opening the warnings menu, our ControlledApplication_FailuresProcessing method will get called.

void ControlledApplication_FailuresProcessing(object sender, Autodesk.Revit.DB.Events.FailuresProcessingEventArgs e)
   {
       FailuresAccessor accessor = e.GetFailuresAccessor();
       IList<FailureMessageAccessor> messages = accessor.GetFailureMessages();
       foreach (FailureMessageAccessor failure in messages)
       {
           FailureDefinitionId failId = failure.GetFailureDefinitionId();
           if (failId == BuiltInFailures.OverlapFailures.WallsOverlap)
           {
               TaskDialog.Show("Deleting Failure", failure.GetDescriptionText());
               accessor.DeleteWarning(failure);
           }
       }
   }

In the code above, you get an object of type ‘FailuresAccessor’ which, funnily enough, lets you access the failures.

Then you can get all of the failure messages and loop through them, then I use the BuiltInFailures listings to match the unique ID of each failure with the one that I’m looking for, that is BuiltInFailures.OverlapFailures.WallsOverlap. The WallsOverlap property simply returns a FailureDefintionId which is used when a WallsOverlap failure is added, so by comparing this with our ID we can find the failures we are after.

If they match, I’m showing a task dialog (you may like to remove this, it’s just there for demonstration purposes) and deletes the warning.

If you load Revit and try to create walls again you’ll see:

image

and you won’t get the Revit warning. Take out the call to task dialog and you’ll always have the warning deleted silently – meaning it’s never displayed to the user. Fairly quickly and easily you can remove a certain failure from the list, and as long as your ExternalApplication is running in the background it will never show up.

This can only be used for warnings, so errors can’t be simply deleted, however the Failures API has some neat options to do with automatically resolving errors, but that’s a topic for another day.

No comments: