パフォーマンス アドバイザ

パフォーマンス アドバイザ

Revit API のパフォーマンス アドバイザ機能は、ドキュメントを解析し、パフォーマンスの低下につながる可能性のある要素や設定についてユーザに警告を与えるように設計されています。パフォーマンス アドバイザ コマンドは一連の規則を実行し、その結果を標準の[警告を一覧表示]ダイアログに表示します。

パフォーマンス アドバイザの API は次の 2 つのクラスで構成されます。

パフォーマンス アドバイザ

PerformanceAdviser を使用すると、チェックする規則の追加や削除、規則の有効化や無効化、リストの規則に関する情報の取得、リスト内の一部やすべての規則の実行といった操作を実行できます。新しい規則を作成するアプリケーションは、アプリケーションの起動中に AddRule()を使用して新しい規則を登録し、アプリケーションのシャットダウン中に DeleteRule()を使用して登録解除すると想定されています。ExecuteAllRules()は指定されたドキュメントのリストにあるすべての規則を実行しますが、ExecuteRules()を使用するとドキュメント内の選択した規則を実行できます。どちらのメソッドも、ドキュメントで検出されたパフォーマンスの問題を説明するエラー メッセージのリストを返します。

次の例は、すべてのパフォーマンス アドバイザの規則をループさせ、ドキュメントにすべての規則を実行する方法を示します。

コード領域: パフォーマンス アドバイザ

//Get the name of each registered PerformanceRule and then execute all of them.
foreach (PerformanceAdviserRuleId id in PerformanceAdviser.GetPerformanceAdviser().GetAllRuleIds())
{
    string ruleName = PerformanceAdviser.GetPerformanceAdviser().GetRuleName(id);
}
PerformanceAdviser.GetPerformanceAdviser().ExecuteAllRules(document);

IPerformanceAdviserRule

パフォーマンス アドバイザの新しいルールを作成するには、IPerformanceAdviserRule インタフェースのインスタンスを作成します。規則は要素固有またはドキュメント全体の規則に設定できます。次のメソッドを実装する必要があります。

  • GetName() - 規則の名前を表す短い文字列
  • GetDescription() - 規則に関する 1 ~ 2 行の説明
  • InitCheck() - チェックの開始時にパフォーマンス アドバイザが一度呼び出すメソッド。規則が特定の要素ではなくドキュメント全体をチェックする場合は、このメソッドを使用してチェックを実行する必要があります。
  • FinalizeCheck() - チェックの終了時にパフォーマンス アドバイザが一度呼び出すメソッド。規則の実行中に発見された問題のある結果は、FailureMessage を使ってメッセージによって報告することができます
  • WillCheckElements() - 規則を個々の要素に実行する必要があるかどうかを示します
  • GetElementFilter() - チェックする要素を制限するためのフィルタを取得します
  • ExecuteElementCheck() - チェックする各要素に対してパフォーマンス アドバイザが呼び出すメソッドです

次のRevit API SDK Samples フォルダ内の PerformanceAdviserControl サンプルからの抜粋はドキュメント内の面が反転したドアを識別するために使用するカスタムの規則の実装を示しています(完全なクラスの実装についてはサンプル プロジェクトを参照してください)。

コード領域: IPerformanceAdviserRule を実装

public class FlippedDoorCheck : Autodesk.Revit.DB.IPerformanceAdviserRule
{
    #region Constructor
    /// <summary>
    /// Set up rule name, description, and error handling
    /// </summary>
    public FlippedDoorCheck()
    {
        m_name = "Flipped Door Check";
        m_description = "An API-based rule to search for and return any doors that are face-flipped";
        m_doorWarningId = new Autodesk.Revit.DB.FailureDefinitionId(new Guid("25570B8FD4AD42baBD78469ED60FB9A3"));
        m_doorWarning = Autodesk.Revit.DB.FailureDefinition.CreateFailureDefinition(m_doorWarningId, Autodesk.Revit.DB.FailureSeverity.Warning, "Some doors in this project are face-flipped.");
    }
    #endregion

    #region IPerformanceAdviserRule implementation
    /// <summary>
    /// Does some preliminary work before executing tests on elements.  In this case,
    /// we instantiate a list of FamilyInstances representing all doors that are flipped.
    /// </summary>
    /// <param name="document">The document being checked</param>
    public void InitCheck(Autodesk.Revit.DB.Document document)
    {
       if (m_FlippedDoors == null)
          m_FlippedDoors = new List<Autodesk.Revit.DB.ElementId>();
       else
          m_FlippedDoors.Clear();
       return;
    }
    
    /// <summary>
    /// This method does most of the work of the IPerformanceAdviserRule implementation.
    /// It is called by PerformanceAdviser.
    /// It examines the element passed to it (which was previously filtered by the filter
    /// returned by GetElementFilter() (see below)).  After checking to make sure that the
    /// element is an instance, it checks the FacingFlipped property of the element.
    ///
    /// If it is flipped, it adds the instance to a list to be used later.
    /// </summary>
    /// <param name="document">The active document</param>
    /// <param name="element">The current element being checked</param>
    public void ExecuteElementCheck(Autodesk.Revit.DB.Document document, Autodesk.Revit.DB.Element element)
    {
        if ((element is Autodesk.Revit.DB.FamilyInstance))
        {
             Autodesk.Revit.DB.FamilyInstance doorCurrent = element as Autodesk.Revit.DB.FamilyInstance;
             if (doorCurrent.FacingFlipped)
                 m_FlippedDoors.Add(doorCurrent.Id);
        }
         
    }

    /// <summary>
    /// This method is called by PerformanceAdviser after all elements in document
    /// matching the ElementFilter from GetElementFilter() are checked by ExecuteElementCheck().
    ///
    /// This method checks to see if there are any elements (door instances, in this case) in the
    /// m_FlippedDoor instance member.  If there are, it iterates through that list and displays
    /// the instance name and door tag of each item.
    /// </summary>
    /// <param name="document">The active document</param>
    public void FinalizeCheck(Autodesk.Revit.DB.Document document)
    {
        if (m_FlippedDoors.Count == 0)
            System.Diagnostics.Debug.WriteLine("No doors were flipped.  Test passed.");
        else
        {
            //Pass the element IDs of the flipped doors to the revit failure reporting APIs.
            Autodesk.Revit.DB.FailureMessage fm = new Autodesk.Revit.DB.FailureMessage(m_doorWarningId);
            fm.SetFailingElements(m_FlippedDoors);
            Autodesk.Revit.DB.Transaction failureReportingTransaction = new Autodesk.Revit.DB.Transaction(document, "Failure reporting transaction");
            failureReportingTransaction.Start();
            document.PostFailure(fm);
            failureReportingTransaction.Commit();
            m_FlippedDoors.Clear();
        }
    }
    
    /// <summary>
    /// Gets the description of the rule
    /// </summary>
    /// <returns>The rule description</returns>
    public string GetDescription()
    {
        return m_description;
    }

    /// <summary>
    /// This method supplies an element filter to reduce the number of elements that PerformanceAdviser
    /// will pass to GetElementCheck().  In this case, we are filtering for door elements.
    /// </summary>
    /// <param name="document">The document being checked</param>
    /// <returns>A door element filter</returns>
    public Autodesk.Revit.DB.ElementFilter GetElementFilter(Autodesk.Revit.DB.Document document)
    {
        return new Autodesk.Revit.DB.ElementCategoryFilter(Autodesk.Revit.DB.BuiltInCategory.OST_Doors);
    }

    /// <summary>
    /// Gets the name of the rule
    /// </summary>
    /// <returns>The rule name</returns>
    public string GetName()
    {
        return m_name;
    }

    /// <summary>
    /// Returns true if this rule will iterate through elements and check them, false otherwise
    /// </summary>
    /// <returns>True</returns>
    public bool WillCheckElements()
    {
        return true;
    }

    #endregion
}