We have talked about how to manage Revit application events with C# a while back. Most of the Revit application event handlers are pretty straightforward to implement, but a few are not. The FailuresProcessing event handler is one of them. The FailuresProcessing API has a set of classes and methods, e.g. FailuresAccessor, FailureMessageAccessor, FailureDefinitionId, FailureSeverity, BuiltInFailures, GetFailureMessages(), GetFailureDefinitionId(), GetTransactionName(), and GetSeverity().
In addition, there are a few failure severities, Warning, Error and DocumentCorruption as the FailureSeverity enumerates out that we may want to address in different situations. The None of the FailureSeverity enum is not the concern of us at all, I believe. As the GetTransactionName() method indicates, we can also process failures in some specific transactions that we care about.
Ok, now let’s see how to implement a FailuresProcessing event handler.
First, we need to nail down what failures to take into account in the handler. For example, Revit will alert us when some overlapping elements are being created such as walls and rebars, but it might be what we exactly want in some cases. So, we are going to suppress all those overlap failures which ids can be found in the static class BuiltInFailures.OverlapFailures. We create such a list for the FailuresProcessing event handler to use:
private static List<FailureDefinitionId> FailureDefinitionIdList
{
get
{
List<FailureDefinitionId> list = new List<FailureDefinitionId>();
list.Add(BuiltInFailures.OverlapFailures.WallSpaceSeparationOverlap);
list.Add(BuiltInFailures.OverlapFailures.WallsOverlap);
list.Add(BuiltInFailures.OverlapFailures.WallRoomSeparationOverlap);
list.Add(BuiltInFailures.OverlapFailures.WallAreaBoundaryOverlap);
list.Add(BuiltInFailures.OverlapFailures.SpaceSeparationLinesOverlap);
list.Add(BuiltInFailures.OverlapFailures.RoomSeparationLinesOverlap);
list.Add(BuiltInFailures.OverlapFailures.LevelsOverlap);
list.Add(BuiltInFailures.OverlapFailures.DuplicateRebar);
list.Add(BuiltInFailures.OverlapFailures.DuplicatePoints);
list.Add(BuiltInFailures.OverlapFailures.DuplicateInstances);
list.Add(BuiltInFailures.OverlapFailures.CurvesOverlap);
list.Add(BuiltInFailures.OverlapFailures.AreaBoundaryLinesOverlap);
return list;
}
}
Second, we need to determine whether to address a specific transaction, a few, or all. Similar list can also be built up to make things neat. Here, we are going to take into account a single transaction and demonstrate its use case in some commented code.
Next, we access to the failure ids that the event is notifying us along the path FailuresProcessingEventArgs -> GetFailuresAccessor -> GetFailureMessages -> GetFailureDefinitionId. Now it is the time to check some information in detail to see if it is the right failure that we concern about including id and severity:
public static void AppEvent_FailuresProcessing_Handler(Object sender, EventArgs args)
{
FailuresProcessingEventArgs fpArgs = args as FailuresProcessingEventArgs;
FailuresAccessor accessor = fpArgs.GetFailuresAccessor();
//if( !accessor.GetTransactionName().Equals("MyCommand") )
//{
// return;
//}
foreach (FailureMessageAccessor msgAccessor in accessor.GetFailureMessages())
{
FailureDefinitionId id = msgAccessor.GetFailureDefinitionId();
if (!FailureDefinitionIdList.Exists( e => e.Guid.ToString() == id.Guid.ToString()) )
{
continue;
}
if (msgAccessor.GetSeverity() == FailureSeverity.Warning)
{
accessor.DeleteWarning(msgAccessor);
continue;
}
if (msgAccessor.GetSeverity() == FailureSeverity.Error)
{
accessor.DeleteWarning(msgAccessor);
continue;
}
if (msgAccessor.GetSeverity() == FailureSeverity.DocumentCorruption)
{
accessor.DeleteWarning(msgAccessor);
continue;
}
}
fpArgs.SetProcessingResult(FailureProcessingResult.Continue);
}
Last but not least, please do not forget to set the processing result through the SetProcessingResult() call of the FailuresProcessingEventArgs. Here we allow the involved operation to continue.
The code is rather short, but as can be seen quite a few factors have to be thought about and those relevant failure ids have to be found somewhere beforehand. The good news is that the RevitAddinWizard can help us do all of these through just a few clicks.
Links to some related articles:
Manage Revit Application Events of Revit API
Use RevitAddinWizard to Add Revit Application Event Handlers of Revit API
Implement Revit FailuresProcessing Event Hanlders of Revit API
Use RevitAddinWizard to Implement Revit FailuresProcessing Event Hanlders of Revit API
Manage Revit UIApplication Events
Manage Revit Document Events of Revit API - 3 Document Event Handler of RevitAddinWizard
Recent Comments