外部コマンド

外部コマンド

開発者は、[外部ツール]メニューボタンに表示される外部コマンドを実装することにより、機能を追加することができます。

外部コマンドをロード、実行する

Revit で他のコマンドや編集モードがアクティブになっていない場合、登録されている外部コマンドが有効になります。コマンドを選択すると、コマンド オブジェクトが作成され、その Execute()メソッドが呼び出されます。このメソッドが Revit に値を返すと、コマンド オブジェクトが破棄されます。その結果、コマンド実行と次のコマンド実行の間はオブジェクトにデータを保持することができません。ただし、コマンド実行の間にもデータを保存する方法があります。たとえば、Revit の共有パラメータ メカニズムを使用すれば、Revit プロジェクトにデータを保存することができます。

外部コマンドは[外部ツール]メニューボタンの[外部ツール]パネルに追加するか、[アドイン]タブ、[解析]タブ、新しいカスタムのリボン タブなどにカスタムのリボン パネルとして追加することができます。これらの 2 つのアプローチの例については、「ウォークスルー: Hello World」と「ウォークスルー: Hello World リボン パネルを追加するウォークスルー: [Hello World]リボン パネルを追加」を参照してください。

外部ツール、リボン タブ、リボン パネルは起動時に初期化されます。初期化手順は次のとおりです。

  • Revit がマニフェスト ファイルを読み取り、次の内容を特定します。
    • 呼び出し可能な外部アプリケーション。
    • Revit の[外部ツール]メニューボタンに追加可能な外部ツール。
  • 外部アプリケーション セッションが[アドイン]タブにパネルとコンテンツを追加します。

IExternalCommand

IExternalCommand インタフェースを実装するオブジェクトを作成することで、外部コマンドを作成することができます。IExternalCommand インタフェースには、外部コマンドの主なメソッドである抽象メソッド Execute が 1 つあります。

Execute()メソッドには次の 3 つのパラメータがあります。

  • commandData (ExternalCommandData)
  • message (String)
  • elements (ElementSet)

commandData (ExternalCommandData)

ExternalCommandData オブジェクトは、外部コマンドが必要とする Application と View への参照を持ちます。すべての Revit データは外部コマンドのこのパラメータから直接的または間接的に取得されます。

たとえば、次のステートメントは、commandData パラメータから Autodesk.Revit.Document を取得するための方法を説明しています。

コード領域 3-1: アクティブなドキュメントを取得

Document doc = commandData.Application.ActiveUIDocument.Document;

次の表は ExternalCommandData パブリック プロパティを表しています。

表 1: ExternalCommandData パブリック プロパティ

プロパティ

説明

Application (Autodesk.Revit.UI.UIApplication)

外部コマンドの現在の UIApplication を表すオブジェクトを取得します。

JournalData

(IDictionary<String, String>>)

Revit ジャーナル ファイルのデータの読み取りや書き込みに使用できるデータ マップです。

View (Autodesk.Revit.DB.View)

外部コマンドの作業対象となっている View を表すオブジェクトを返します。

message (String):

外部コマンドは出力パラメータ メッセージを使用して、エラー メッセージを返します。文字列タイプのパラメータは外部コマンド処理で設定されます。Autodesk.Revit.UI.Result.Failed または Autodesk.Revit.UI.Result.Cancelled が返された場合に、メッセージ パラメータが設定されていると、エラー ダイアログが表示されます。

次のコード サンプルは、メッセージ パラメータの使用方法を表しています。

領域 3-2: エラー メッセージ文字列を設定

class IExternalCommand_message : IExternalCommand
{
        public Autodesk.Revit.UI.Result Execute(
                Autodesk.Revit.ExternalCommandData commandData, ref string message,
                Autodesk.Revit.ElementSet elements)
        {
                message = "Could not locate walls for analysis.";
                return Autodesk.Revit.UI.Result.Failed;
        }
}

前述の外部コマンドを実装すると、次のダイアログ ボックスが表示されます。

図 12: エラー メッセージ ダイアログ ボックス

elements (ElementSet):

Autodesk.Revit.UI.Result.Failed または Autodesk.Revit.UI.Result.Canceled が返されたときにパラメータ メッセージが空でない場合は、エラーまたは警告ダイアログ ボックスが表示されます。さらに、要素パラメータに要素が追加されると、これらの要素は画面上でハイライト表示されます。要素が返されるかどうかに関わらず、コマンドが失敗したときにはメッセージ パラメータを設定することをお勧めします。

次のコードは、事前に選択した壁をハイライト表示させます。

コード領域 3-3: 壁をハイライト表示

class IExternalcommand_elements : IExternalCommand
{
        public Result Execute(
                Autodesk.Revit.UI.ExternalCommandData commandData, ref string message,
                Autodesk.Revit.DB.ElementSet elements)
        {
                message = "Please note the highlighted Walls.";
                FilteredElementCollector collector = new FilteredElementCollector(commandData.Application.ActiveUIDocument.Document);
                ICollection<Element> collection = collector.OfClass(typeof(Wall)).ToElements();
                foreach (Element e in collection)
                {
                        elements.Insert(e);
                }

                return Result.Failed;
        }
}

戻り値

返される結果は、実行の失敗、成功、ユーザによるキャンセルのうちいずれかを示します。失敗した場合、Revit は外部コマンドによる変更を無効にします。

表 2: IExternalCommand.Result

メンバー名

説明

Autodesk.Revit.UI.Result.Succeeded

外部コマンドは正常に完了しました。Revit は外部コマンドによって行われたすべての変更を保持します。

Autodesk.Revit.UI.Result.Failed

外部コマンドはタスクの実行に失敗しました。Revit は外部コマンドが実行した操作を無効にします。Execute のメッセージ パラメータが設定されている場合は、Revit に「Error - cannot be ignored」の文字が記載されたダイアログが表示されます。

Autodesk.Revit.UI.Result.Cancelled

ユーザが外部コマンドをキャンセルしました。Revit は外部コマンドによって行われた変更を無効にします。Execute のメッセージ パラメータが設定されている場合は、Revit に「Warning - can be ignored」の文字が記載されたダイアログが表示されます。

次の例ではあいさつメッセージが表示され、ユーザは戻り値を選択できます。Revit アプリケーションへの入り口として Execute()メソッドを使用します。

コード領域 3-4: ユーザにプロンプトを表示

public Autodesk.Revit.UI.Result Execute(ExternalCommandData commandData, 
     ref string message, ElementSet elements)
{
        try
        {
                Document doc = commandData.Application.ActiveUIDocument.Document;
                UIDocument uidoc = commandData.Application.ActiveUIDocument;
                // Delete selected elements
                ICollection<Autodesk.Revit.DB.ElementId> ids = 
                        doc.Delete(uidoc.Selection.GetElementIds());

                TaskDialog taskDialog = new TaskDialog("Revit"); 
                taskDialog.MainContent = 
                        ("Click Yes to return Succeeded. Selected members will be deleted.\n" + 
                        "Click No to return Failed.  Selected members will not be deleted.\n" + 
                        "Click Cancel to return Cancelled.  Selected members will not be deleted.");
                TaskDialogCommonButtons buttons = TaskDialogCommonButtons.Yes | 
                        TaskDialogCommonButtons.No | TaskDialogCommonButtons.Cancel;
                taskDialog.CommonButtons = buttons;
                TaskDialogResult taskDialogResult = taskDialog.Show();

                if (taskDialogResult == TaskDialogResult.Yes)
                {
                        return Autodesk.Revit.UI.Result.Succeeded;
                }
                else if (taskDialogResult == TaskDialogResult.No)
                {
                        elements = uidoc.Selection.Elements;
                        message = "Failed to delete selection.";
                        return Autodesk.Revit.UI.Result.Failed;
                }
                else
                {
                        return Autodesk.Revit.UI.Result.Cancelled;
                }
        }
        catch
        {
                message = "Unexpected Exception thrown.";
                return Autodesk.Revit.UI.Result.Failed;
        }
}

IExternalCommandAvailability

このインタフェースを使用すると、外部コマンド ボタンを押すことができるかどうかをコントロールできます。IsCommandAvailable インタフェース メソッドは、Revit で選択した項目のカテゴリに一致するアプリケーションと一連のカテゴリを実装に渡します。通常は、選択したカテゴリをチェックして、実行するコマンドの基準に一致しているか確認するのに使用します。

この例では、アクセス チェックにより、アクティブな選択がない場合や少なくとも壁が 1 つ選択されている場合に、ボタンのクリックが可能となります。

コード領域 3-5: コマンドを使用できるかどうかを設定

public class SampleAccessibilityCheck : IExternalCommandAvailability
{
        public bool IsCommandAvailable(AutodeskAutodesk.Revit.UI.UIApplication applicationData,
                CategorySet selectedCategories)
        {
                // Allow button click if there is no active selection
                if (selectedCategories.IsEmpty)
                        return true;
                // Allow button click if there is at least one wall selected
                foreach (Category c in selectedCategories)
                {
                        if (c.Id.IntegerValue == (int)BuiltInCategory.OST_Walls)
                        return true;
                }
                return false;
        }
}