タイトル: 外部ツールでAutodesk.Revit.Documentを取得する方法
SEOタイトル: 外部ツールから Revit Document を取得する完全ガイド — IExternalCommand / .addin / Dynamo
| この記事の要点 |
|
大前提: Revit プロセス内でしか触れない
Revit API の Autodesk.Revit.DB.Document は、Revit.exe プロセス内でロードされた DLL からのみアクセスできます。スタンドアロン .exe を作って「外部から .rvt を開いて要素を読みたい」という直接アクセスはサポートされていません(ライセンス的にも技術的にも)。
したがって「外部ツール」とは正確には「Revit にロードされる外部 DLL(アドイン)」を指します。
方法 1: IExternalCommand を実装
最も基本的なアドイン作成パターン:
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
[Transaction(TransactionMode.Manual)]
[Regeneration(RegenerationOption.Manual)]
public class HelloRevit : IExternalCommand
{
public Result Execute(
ExternalCommandData commandData,
ref string message,
ElementSet elements)
{
// ★ Document 取得の基本形
UIApplication uiApp = commandData.Application;
UIDocument uiDoc = uiApp.ActiveUIDocument;
Document doc = uiDoc.Document;
TaskDialog.Show("Revit", $"ファイル: {doc.Title}");
// 壁の数を数える
int wallCount = new FilteredElementCollector(doc)
.OfCategory(BuiltInCategory.OST_Walls)
.WhereElementIsNotElementType()
.Count();
TaskDialog.Show("Revit", $"壁の数: {wallCount}");
return Result.Succeeded;
}
}
方法 2: .addin マニフェストで登録
DLL を Revit にロードさせるための XML を %ProgramData%\Autodesk\Revit\Addins\2024\ に配置します:
<?xml version="1.0" encoding="utf-8"?>
<RevitAddIns>
<AddIn Type="Command">
<Name>HelloRevit</Name>
<Assembly>C:\Tools\MyRevitAddin.dll</Assembly>
<AddInId>12345678-1234-1234-1234-123456789012</AddInId>
<FullClassName>MyNamespace.HelloRevit</FullClassName>
<VendorId>ABCD</VendorId>
<VendorDescription>My Company</VendorDescription>
</AddIn>
</RevitAddIns>
ファイル拡張子は .addin。Revit 起動時に自動でロードされ、「アドイン」タブにコマンドが追加されます。
方法 3: IExternalApplication でリボン登録
毎回コマンドメニューから選ばせるのが面倒なら、リボン UI にボタンを追加:
public class MyApp : IExternalApplication
{
public Result OnStartup(UIControlledApplication app)
{
string tabName = "MyTab";
app.CreateRibbonTab(tabName);
var panel = app.CreateRibbonPanel(tabName, "Tools");
var btn = new PushButtonData(
"HelloBtn",
"Hello",
Assembly.GetExecutingAssembly().Location,
"MyNamespace.HelloRevit");
panel.AddItem(btn);
return Result.Succeeded;
}
public Result OnShutdown(UIControlledApplication app)
{
return Result.Succeeded;
}
}
方法 4: バッチ処理(OpenDocumentFile)
ユーザー操作なしで複数 .rvt を処理する場合は Application.OpenDocumentFile():
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
Application app = commandData.Application.Application;
string[] files = Directory.GetFiles(@"C:\Projects", "*.rvt");
foreach (var file in files)
{
Document doc = app.OpenDocumentFile(file);
try
{
int walls = new FilteredElementCollector(doc)
.OfCategory(BuiltInCategory.OST_Walls)
.Count();
File.AppendAllText(@"C:\report.txt", $"{file}: {walls}\n");
}
finally
{
doc.Close(false);
}
}
return Result.Succeeded;
}
Document 取得パターン比較
| 取得方法 | シーン | 注意 |
|---|---|---|
commandData.Application.ActiveUIDocument.Document | ユーザー操作時の現在開いてる .rvt | もっとも一般的 |
app.Application.OpenDocumentFile(path) | バッチ処理で複数 .rvt | 処理後 Close 必須 |
app.Application.Documents | 開かれている全 Document を列挙 | Family Document も含む |
RevitLinkInstance.GetLinkDocument() | リンクされた .rvt の Document | 編集不可(読み取り専用) |
doc.IsFamilyDocument | .rfa か .rvt かの判定 |
Dynamo からのアクセス
Dynamo はビジュアルプログラミング環境ですが、内部的に Revit API を呼び出しています:
# Dynamo の Python Script ノード
import clr
clr.AddReference('RevitAPI')
clr.AddReference('RevitServices')
from Autodesk.Revit.DB import FilteredElementCollector, BuiltInCategory
from RevitServices.Persistence import DocumentManager
doc = DocumentManager.Instance.CurrentDBDocument
walls = FilteredElementCollector(doc) \
.OfCategory(BuiltInCategory.OST_Walls) \
.WhereElementIsNotElementType() \
.ToElements()
OUT = len(walls)
pyRevit からのアクセス
pyRevit は Python で書ける軽量アドインフレームワーク:
# pyRevit の Python スクリプト
from pyrevit import revit, DB
doc = revit.doc
uidoc = revit.uidoc
walls = DB.FilteredElementCollector(doc) \
.OfCategory(DB.BuiltInCategory.OST_Walls) \
.WhereElementIsNotElementType() \
.ToElements()
for w in walls:
print(w.Name)
RevitLookup ツール
RevitLookup(オープンソース)は要素のプロパティをツリービューで覗き見できる必須デバッグツールです:
- GitHub: jeremytammik/RevitLookup
- 要素を選択して「Snoop Current Selection」
- 全プロパティと値、関連要素を再帰的にブラウズ可能
- BuiltInCategory・パラメータ名・型 ID 等の確認に最適
注意事項とベストプラクティス
- Transaction: ドキュメントを変更する場合は
new Transaction(doc, "name")で囲む - Disposable: 多くの Revit API オブジェクトは IDisposable → using で囲む
- UI スレッド: Document 操作は UI スレッドからのみ。バックグラウンドスレッド NG
- API バージョン: Revit 2024 用 DLL は 2023 では動かない(多くの場合)→ バージョン別ビルド
- テスト: 開発中はデバッガをアタッチして F5、または RevitAddInUtility で自動再ロード
FAQ
Q: PowerShell や Python から外部プロセスとして Revit を操作したい
A: 公式には不可能です。Revit Server や Forge / Autodesk Platform Services(APS)を使ったクラウド API なら外部から .rvt を扱えます。
Q: Revit を起動せずに .rvt を読みたい
A: 公式 API では不可。サードパーティの ODA BimRv SDK(Open Design Alliance)が独自に .rvt を解析できますが、別ライセンスが必要。
Q: .addin が読み込まれない
A: 配置先パスと FullClassName のスペル、Assembly のパス、AddInId の GUID 重複を確認。Revit のログ journal ファイルにエラーが出ます。