Revit Dynamo
Free Programs
This website provides Revit Dynamo scripts for free, for both personal and commercial use.
You may use the scripts freely, but any illegal or inappropriate use is prohibited.
We are not responsible for any damages or issues that arise from the use of the scripts.
This website is not affiliated with Autodesk, Inc.
"Generate Grids in Revit" Dynamo Program
Downlaod : Click this icon
The following Python program is used within the Dynamo program above.
# Import the required library
import clr
# Dynamoの入力リストを取得
data = IN[0] # IN[0] は Dynamo ノードの入力に接続されたデータ
# 入力がリストかどうかを確認し、値を合計
if isinstance(data, list):
total = sum(data)
else:
total = "Input is not a list!"
# 出力を Dynamo ノードに渡す
OUT = total
"Generate levels in Revit" Dynamo Program
Downlaod : Click this icon
The following Python program is used within the Dynamo program above.
# Python Script for Dynamo
# Inputs:
# intervals: list of interval values (from Number Sliders)
# base_elevation: starting elevation for the first level
import clr
clr.AddReference('RevitServices')
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
# Get inputs
intervals = IN[0]
base_elevation = IN[1] if len(IN) > 1 else 0
# Calculate cumulative elevations
elevations = [base_elevation]
for interval in intervals:
next_elevation = elevations[-1] + interval
elevations.append(next_elevation)
# Remove the first elevation if it's the base level
# If you want to exclude base, uncomment the next line
# elevations = elevations[1:]
# Output the elevations
OUT = elevations
"Generate Columns in Revit" Dynamo Program
Downlaod : Click this icon
The following Python program is used within the Dynamo program above.
import sys
curves = IN[0]
xDir = []
yDir = []
for c in curves:
start = c.StartPoint
end = c.EndPoint
dx = end.X - start.X
dy = end.Y - start.Y
# もしdxの絶対値がdyより大きければX方向、それ以外はY方向とする
if abs(dx) > abs(dy):
xDir.append(c)
else:
yDir.append(c)
OUT = xDir, yDir
"Check which views the linked CAD file is placed in" Dynamo Program
Downlaod : Click this icon
The following Python program is used within the Dynamo program above.
import clr
# 必要なライブラリの参照を追加
clr.AddReference('RevitAPI')
clr.AddReference('RevitServices')
from Autodesk.Revit.DB import *
from RevitServices.Persistence import DocumentManager
import System
# 現在のドキュメントを取得
doc = DocumentManager.Instance.CurrentDBDocument
# Dynamoの入力ポートからターゲットのCADファイル名を取得(例:"example.dwg")
target_cad_name = IN[0] # 入力ポート0
# ImportInstance要素を収集
import_instances = FilteredElementCollector(doc).OfClass(ImportInstance).ToElements()
# デバッグ情報:取得したImportInstanceの数を表示
import_instance_count = len(import_instances)
# 結果を格納するリスト
views_with_target_cad = []
debug_info = [] # デバッグ情報を格納するリスト
for instance in import_instances:
# リンクされたCADファイルかどうかを確認
try:
is_linked = instance.IsLinked
except:
# Revit 2019以前の場合の代替手段
is_linked = False
link_param = instance.get_Parameter(BuiltInParameter.IMPORT_IS_LINKED)
if link_param:
is_linked = link_param.AsInteger() == 1
# デバッグ情報:リンクの状態を表示
debug_info.append("Instance ID {}: IsLinked = {}".format(instance.Id, is_linked))
if not is_linked:
continue # リンクされていない場合はスキップ
# ImportInstanceのタイプ(ImportSymbol)を取得
symbol = doc.GetElement(instance.GetTypeId())
# symbolがNoneでないことを確認
if symbol is None:
debug_info.append("Instance ID {}: symbol is None".format(instance.Id))
continue
# ImportSymbolの名前を取得(get_Name()メソッドを使用)
symbol_name = symbol.get_Name()
debug_info.append("Symbol ID {}: Name = {}".format(symbol.Id, symbol_name))
# ファイル名を比較(大文字小文字を無視)
cad_file_name = symbol_name # シンボル名をCADファイル名として使用
if cad_file_name.lower() == target_cad_name.lower():
# 配置されているビューを取得
view_id = instance.OwnerViewId
if view_id != ElementId.InvalidElementId:
view = doc.GetElement(view_id)
views_with_target_cad.append(view)
debug_info.append("Instance ID {}: Match found in View ID {}".format(instance.Id, view.Id))
else:
debug_info.append("Instance ID {}: File name does not match.".format(instance.Id))
# 出力
OUT = (views_with_target_cad, debug_info, "Total ImportInstances: {}".format(import_instance_count))
"Review Print Set" Dynamo Program
Downlaod : Click this icon
The following Python program is used within the Dynamo program above.
# 必要な名前空間をインポート
import clr
clr.AddReference('RevitAPI') # Revit APIを使用するための参照を追加
clr.AddReference('RevitServices') # DynamoとRevit間のやりとり用
from Autodesk.Revit.DB import * # Revit APIのクラスをインポート
from RevitServices.Persistence import DocumentManager # 現在のRevitドキュメントを取得
# 現在のドキュメントを取得
doc = DocumentManager.Instance.CurrentDBDocument
# ViewSheetSet(保存された印刷セット)のコレクションを取得
collector = FilteredElementCollector(doc) # 全ての要素をフィルタリング
collector.OfClass(ViewSheetSet) # クラスがViewSheetSetに一致する要素を取得
view_sheet_sets = collector.ToElements() # 取得した要素をリストとして格納
# エクセル出力用のリストを作成
excel_data = [] # エクセルデータを格納するリスト
header = ['Print Set Name', 'View/Sheet Name'] # エクセルのヘッダー行
excel_data.append(header) # ヘッダーをデータリストに追加
# 各印刷セットに含まれるビューやシートを取得
for vss in view_sheet_sets:
set_name = vss.Name # 印刷セットの名前を取得
# 印刷セットに含まれるビューやシートのコレクションを取得
view_set = vss.Views # Viewsプロパティでビューセットを取得
# ビューやシートが存在する場合のみ処理
if view_set.Size > 0: # ビューセットのサイズが0より大きい場合
for view in view_set: # ビューセット内の各ビュー/シートを反復
if view is not None: # ビュー/シートが存在する場合のみ処理
row = [set_name, view.Name] # 印刷セット名とビュー/シート名をリスト化
excel_data.append(row) # データリストに行を追加
else:
# ビューやシートがない場合、ログ用のメッセージを作成(必要に応じて使用)
pass # ここでは何も行わない
# 結果をOUTに出力(Dynamoのエクセル出力ノードに直接接続可能)
OUT = excel_data
"Get Wall Names Adjacent to Rooms" Dynamo Program
Downlaod : Click this icon
The following Python program is used within the Dynamo program above.
import clr
# Revit/Dynamoの基本参照設定
clr.AddReference('RevitServices')
from RevitServices.Persistence import DocumentManager
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import SpatialElementBoundaryOptions, Wall
doc = DocumentManager.Instance.CurrentDBDocument
# IN[0]: 部屋リスト (Roomエレメントのリスト)
rooms = UnwrapElement(IN[0]) # ここでアンラップするだけで十分
# Boundaryオプション生成
options = SpatialElementBoundaryOptions()
result = []
for room in rooms:
# 部屋名を取得
room_name = room.LookupParameter("名前").AsString()
# 部屋のレベル名を取得
level = room.Level
level_name = level.Name if level else "なし"
# 部屋からboundary segmentsを取得
boundary_segments = room.GetBoundarySegments(options)
# 現在の部屋に接している壁情報をまとめるリスト
room_walls = []
if boundary_segments: # 部屋に境界がある場合のみ処理
for loop in boundary_segments:
for seg in loop:
element_id = seg.ElementId
element = doc.GetElement(element_id)
# 壁要素かどうかを型で判定
if isinstance(element, Wall):
wall_type_name = element.Name
wall_id = element.Id.IntegerValue
room_walls.append([wall_type_name, wall_id])
# 現在の部屋の名前、レベル情報、壁情報を蓄積
result.append([level_name, room_name, room_walls])
# レベル名→部屋名の順にソート
sorted_result = sorted(result, key=lambda x: (x[0], x[1]))
OUT = sorted_result
"Generate schedules and place on sheets" Dynamo Program
Downlaod : Click this icon
The following Python program is used within the Dynamo program above.
import clr
# Dynamo Revitノード用設定
clr.AddReference("RevitServices")
from RevitServices.Persistence import DocumentManager
clr.AddReference("RevitNodes")
import Revit
# UnwrapElementを使用するために必要
from Revit.Elements import *
# Revit API 参照
clr.AddReference("RevitAPI")
from Autodesk.Revit.DB import ElementId, ViewSchedule
doc = DocumentManager.Instance.CurrentDBDocument
# IN[0] は Dynamo上のScheduleViewラッパーオブジェクト(単数またはリスト)
input_views = IN[0] if isinstance(IN[0], list) else [IN[0]]
output_templates = []
for v in input_views:
# DynamoのScheduleViewはラッパーになっているため、UnwrapElementで実体のRevit要素を取得
rv = UnwrapElement(v) # これでrvはAutodesk.Revit.DB.ViewSchedule型のはず
# rvがViewScheduleであればViewを継承しておりViewTemplateIdが取得可能
template_id = rv.ViewTemplateId
if template_id != ElementId.InvalidElementId:
template_view = doc.GetElement(template_id)
output_templates.append(template_view)
else:
output_templates.append(None)
OUT = output_templates
The following Python program is used within the Dynamo program above.
import clr
clr.AddReference("RevitServices")
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
clr.AddReference("RevitAPI")
from Autodesk.Revit.DB import *
# これを追加しないと UnwrapElement が正常に働かない場合がある
clr.AddReference("RevitNodes")
import Revit
from Revit.Elements import *
doc = DocumentManager.Instance.CurrentDBDocument
schedules_2d = IN[0]
templates_1d = IN[1] if isinstance(IN[1], list) else [IN[1]]
def flatten_list(data):
result = []
for x in data:
if isinstance(x, list):
result.extend(flatten_list(x))
else:
result.append(x)
return result
TransactionManager.Instance.EnsureInTransaction(doc)
# schedules_2d は「二次元を想定」しているが、内部にさらにネストがあるかもしれないので
# 各サブリスト(row)をフラット化したうえで、templates_1d と zip する
for row in schedules_2d:
row_flat = flatten_list(row)
if len(row_flat) == len(templates_1d):
for s, t in zip(row_flat, templates_1d):
rs = UnwrapElement(s)
rt = UnwrapElement(t)
if rs and rt:
rs.ViewTemplateId = rt.Id
else:
# 要素数が合わないなら何もしない
pass
TransactionManager.Instance.TransactionTaskDone()
OUT = schedules_2d
The following Python program is used within the Dynamo program above.
# -*- coding: utf-8 -*-
import clr
# RevitServices
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
# RevitNodes(GeometryConversionなどを使う場合に必要)
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.GeometryConversion) # Dynamo Geometry → Revit Geometry 変換用
# RevitAPI
clr.AddReference("RevitAPI")
from Autodesk.Revit.DB import *
# Dynamo の IN, OUT
doc = DocumentManager.Instance.CurrentDBDocument
# --- 入力パラメータを取得 ---
sheets = IN[0] # シート (ViewSheet) のリスト
schedules_by_sheet = IN[1] # スケジュール (ViewSchedule) の「リストのリスト」
points = IN[2] # Dynamo の Point 型 (Autodesk.DesignScript.Geometry.Point) のリスト
# Revit API の UnitUtils を使用するために UnitTypeId をインポート
from Autodesk.Revit.DB import UnitUtils, UnitTypeId
# トランザクション開始 (Dynamo の TransactionManager)
TransactionManager.Instance.EnsureInTransaction(doc)
results = []
try:
# シートごとにループ
for i, sheet in enumerate(sheets):
sheet_unwrapped = UnwrapElement(sheet)
# i番目シート用のスケジュール一覧
schedule_list = schedules_by_sheet[i]
# スケジュールごとにループ
for j, sched in enumerate(schedule_list):
sched_unwrapped = UnwrapElement(sched)
# Dynamo の Point を取り出す
dynamo_point = points[j] # 例えば [Point1, Point2, ...]
# Dynamo の Point から X, Y を取得(ミリメートル単位)
x_mm = dynamo_point.X
y_mm = dynamo_point.Y
# Revit API の UnitUtils を使用して mm を内部単位(フィート)に変換
x_ft = UnitUtils.ConvertToInternalUnits(x_mm, UnitTypeId.Millimeters)
y_ft = UnitUtils.ConvertToInternalUnits(y_mm, UnitTypeId.Millimeters)
# シート上なので Z = 0
pos_xyz = XYZ(x_ft, y_ft, 0)
# スケジュールをシートに配置
schedule_instance_id = ScheduleSheetInstance.Create(
doc, # Document
sheet_unwrapped.Id, # シートID (ElementId)
sched_unwrapped.Id, # スケジュールビューID (ElementId)
pos_xyz # XYZ座標
)
results.append(schedule_instance_id)
# 正常終了でコミット
TransactionManager.Instance.TransactionTaskDone()
OUT = results
except Exception as e:
# 失敗時もコミット扱い (※ロールバックできないのが Dynamo 標準の TransactionManager)
TransactionManager.Instance.TransactionTaskDone()
OUT = "Error: " + str(e)
"Extract Filter Details from All Schedules" Dynamo Program
Downlaod : Click this icon
The following Python program is used within the Dynamo program above.
# -*- coding: utf-8 -*-
import clr
# Revit への参照設定
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
clr.AddReference("System")
clr.AddReference("System.Collections")
clr.AddReference("RevitAPI")
from Autodesk.Revit.DB import *
# 追加で System.Enum を使うため
from System import Enum
doc = DocumentManager.Instance.CurrentDBDocument
collector = FilteredElementCollector(doc).OfClass(ViewSchedule)
all_schedules = list(collector)
table_data = []
table_data.append(["ScheduleName", "FieldName", "FilterType", "Value"])
for vs in all_schedules:
schedule_def = vs.Definition
schedule_name = vs.Name
filter_count = schedule_def.GetFilterCount()
# フィルターがない場合
if filter_count == 0:
table_data.append([schedule_name, "No Filters", "", ""])
continue
# フィルターがある場合
for i in range(filter_count):
f = schedule_def.GetFilter(i)
field_id = f.FieldId
field_name = schedule_def.GetField(field_id).GetName()
# 'f.FilterType' が int になっている可能性があるので Enum.GetName で変換
filter_type_int = f.FilterType # ここが int のケース
filter_type_name = Enum.GetName(ScheduleFilterType, filter_type_int) # "Equal", "NotEqual", etc.
# フィルター値を取得
if f.IsDoubleValue:
rule_value = f.GetDoubleValue()
elif f.IsStringValue:
rule_value = f.GetStringValue()
elif f.IsElementIdValue:
rule_value = f.GetElementIdValue()
else:
rule_value = None
table_data.append([schedule_name, field_name, filter_type_name, rule_value])
OUT = table_data