We demonstrated how to create custom Performance Advisor Rule (IPerformanceAdviserRule) before such as the WallCanNotBeTooShort and the WallCannotHaveManyDoors both from scratch and with the assistance of the Performance Advisor Rule Creator of RevitAddinWizard.
In this post, let us create another custom Performance Advisor Rule (IPerformanceAdviserRule), RoomTooSmall.
Here is the main class implementing the IPerformanceAdviserRule interface.
#region Namespaces
using System;
using System.Text;
using System.Linq;
using System.Xml;
using System.Reflection;
using System.ComponentModel;
using System.Collections;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Media.Imaging;
using System.Windows.Forms;
using System.IO;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Events;
using Autodesk.Revit.DB.Architecture;
using Autodesk.Revit.DB.Structure;
using Autodesk.Revit.DB.Mechanical;
using Autodesk.Revit.DB.Electrical;
using Autodesk.Revit.DB.Plumbing;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using Autodesk.Revit.UI.Events;
using Autodesk.Revit.Collections;
using Autodesk.Revit.Exceptions;
using Autodesk.Revit.Utility;
using RvtApplication = Autodesk.Revit.ApplicationServices.Application;
using RvtDocument = Autodesk.Revit.DB.Document;
#endregion
namespace RevitAddinCS1
{
public class RoomTooSmall : IPerformanceAdviserRule
{
private List<ElementId> mElementIds;
public static PerformanceAdviserRuleId RuleId = new PerformanceAdviserRuleId(new Guid("79704151-c1de-41cf-a978-5efe0330d3df"));
public static FailureDefinitionId FailureDefId = new FailureDefinitionId(new Guid("8337d3e9-b7aa-4e26-9fc4-9f7f9c9dd0d0"));
public RoomTooSmall()
{
//Construct the element list and the failure definition object.
mElementIds = new List<ElementId>();
FailureDefinition.CreateFailureDefinition(FailureDefId, FailureSeverity.Warning, "The room is too small.");
}
public void InitCheck(RvtDocument document)
{
//Clear the cached element list for this run.
mElementIds.Clear();
}
public void ExecuteElementCheck(RvtDocument document, Element element)
{
if (element is SpatialElement)
{
//TODO: add the element checking code below and collect the element of interest into the list. e.g.
Parameter p = (element as SpatialElement).get_Parameter(BuiltInParameter.ROOM_AREA);
if (p.AsDouble() < 9.0)
{
mElementIds.Add(element.Id);
}
}
}
public void FinalizeCheck(RvtDocument document)
{
//Set the failing elements as collected above and post the failure message as created at top.
if (mElementIds != null && mElementIds.Count > 0)
{
FailureMessage fm = new FailureMessage(FailureDefId);
fm.SetFailingElements(mElementIds);
PerformanceAdviser.GetPerformanceAdviser().PostWarning(fm);
}
}
public bool WillCheckElements()
{
//NOTE: by default the performance advisor rule will check elements. change it to false if necessary.
return true;
}
public ElementFilter GetElementFilter(RvtDocument document)
{
//NOTE: change the class filter if necessary.
return new ElementClassFilter(typeof(SpatialElement));
}
public string GetDescription()
{
return "RoomTooSmall";
}
public string GetName()
{
return "RoomTooSmall";
}
}
}
Here is the rule registration and un-registration code that can also be auto-generated by the Performance Advisor Rule Creator of RevitAddinWizard if opted.
public Result OnStartup(UIControlledApplication uiApp)
{
try
{
Autodesk.Revit.DB.PerformanceAdviser.GetPerformanceAdviser().AddRule(RoomTooSmall.RuleId, new RoomTooSmall());
return Result.Succeeded;
}
catch (Exception ex)
{
MessageBox.Show( ex.ToString() );
return Result.Failed;
}
}
public Result OnShutdown(UIControlledApplication uiApp)
{
try
{
Autodesk.Revit.DB.PerformanceAdviser.GetPerformanceAdviser().DeleteRule(RoomTooSmall.RuleId);
return Result.Succeeded;
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
return Result.Failed;
}
}
Here is the test code to execute the rule just in case.
PerformanceAdviser adviser = PerformanceAdviser.GetPerformanceAdviser();
PerformanceAdviserRuleId ruleId = RoomTooSmall.RuleId;
if (ruleId != null)
{
IList<FailureMessage> msgList = adviser.ExecuteRules(CachedDoc, new List<PerformanceAdviserRuleId> { ruleId });
Transaction tr = new Transaction(CachedDoc, "FailureMessage Posting");
tr.Start();
foreach (FailureMessage m in msgList)
{
CachedDoc.PostFailure(m);
}
tr.Commit();
}
Here is the checking result for some such rooms in the current Revit model.
If the room is selected and the Delete Checked… button is pressed, it will be removed from Revit model to meet the custom performance advisor rule.
A tip: The Room is not good at all for the Element Filter though it is indeed an Element in the Revit API. If it happened to be used, the following exception message would appear for us to bear in mind.
“Autodesk.Revit.Exceptions.ExternalApplicationException: Input type is of an element type that exists in the API, but not in Revit's native object model. Try using Autodesk.Revit.DB.SpatialElement instead, and then postprocessing the results to find the elements of interest.
Parameter name: type
at Autodesk.Revit.DB.PerformanceAdviser.ExecuteRules(Document document, IList`1 rules)”
The workaround is to use the SpatialElement as demonstrated. That makes the original design intent a little bit vague though. Maybe it would have made more sense to name the custom Performance Advisor Rule as SpatialElementTooSmall or something like that. I leave it to readers in case there is really such a need in real life or to add some more checking for the collected SpatialElement Elements.
Readers may have already noticed that most of the above code (about 95%) was automatically generated by the Performance Advisor Rule Creator of RevitAddinWizard. RevitAddinWizard will not only save our precious time but also guarantee that a valid Performance Advisor Rule (IPerformanceAdviserRule) will be there with wanted options and most already done nicely. It can be found and downloaded from the bottom link on the blog index page.
Again, the Performance Advisor Rule Creator of RevitAddinWizard is simply not a template with everything hard coded. It’s a creator or real-sense wizard providing good chances for users to set necessary options and automatically hooking up the auto-created custom Performance Advisor Rule into the system.
Recent Comments