06 Feb 2016
Extract revision cloud data from Revit using Dynamo and Python.
Revit can schedule the following revision parameters in a title block family. However, instance parameters (Mark and Comments), sheet numbers, and sheet names are not supported out-of-the-box.
Dynamo and Python can expand on OOTB functionality to generate an itemized list of revisions including previously unavailable instance parameters, sheet numbers, and sheet names. The definition and code in this post will extract the following.
Part 1 of the definition collects all revision clouds and sheets within the active document and sends that information to a Python node.
The Python code filters through sheets and views-on-sheets, looking for revision clouds. It collects the revision cloud element, associated sheet, and referencing view.
# Python Code for Dynamo
# Input: Revision Clouds, Sheets
# Output: Matching Sheets, Matching Revision Clouds, Referencing Views
# Version 0.6
# Coded by Andrew King
# https://andrewkingme.com
#
# 2016-02-06 Version 0.1
# Hello World
#
# 2016-02-08 Version 0.2
# Output matchingrevisionclouds from Python node to avoid hidden element mismatch.
#
# 2016-02-14 Version 0.4
# Expanded Python code to output every instance of a revision cloud in every instance of a legend.
#
# 2016-02-16 Version 0.5
# Restructured code to reduce number of cycles.
# Eliminated the need for a separate legend/dependency path.
# Boolean selector for Revisions on Sheets/Revisions in Views on Sheets.
# Revit 2014 compatibility.
#
# 2016-02-25 Version 0.6
# Added category filter to improve FilteredElementCollector performace.
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
# Import RevitAPI
clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *
# Import DocumentManager and TransactionManager
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
# Assign input to the IN variables.
revisioncloudinput = UnwrapElement(IN[0])
sheetinput = UnwrapElement(IN[1])
revisionsonsheets = IN[2]
revisionsinviewsonsheets = IN[3]
matchingsheets = []
matchingrevisionclouds = []
referencingviews = []
# Look for revision clouds on sheets.
if revisionsonsheets == True:
for sheet in sheetinput:
for sheetelement in FilteredElementCollector(DocumentManager.Instance.CurrentDBDocument, sheet.Id).OfCategory(BuiltInCategory.OST_RevisionClouds):
for revisioncloud in revisioncloudinput:
if sheetelement.Id == revisioncloud.Id:
matchingsheets.append(sheet)
matchingrevisionclouds.append(revisioncloud)
referencingviews.append(sheet)
# Look for revision clouds in views on sheets.
if revisionsinviewsonsheets == True:
for sheet in sheetinput:
if DocumentManager.Instance.CurrentUIApplication.Application.VersionName == "Autodesk Revit 2014":
for viewport in sheet.GetAllViewports():
for view in [DocumentManager.Instance.CurrentDBDocument.GetElement(viewport)]:
for viewid in [DocumentManager.Instance.CurrentDBDocument.GetElement(view.ViewId)]:
for viewelement in FilteredElementCollector(DocumentManager.Instance.CurrentDBDocument, viewid.Id).OfCategory(BuiltInCategory.OST_RevisionClouds):
for revisioncloud in revisioncloudinput:
if viewelement.Id == revisioncloud.Id:
matchingsheets.append(sheet)
matchingrevisionclouds.append(revisioncloud)
referencingviews.append(viewid)
else:
for viewport in sheet.GetAllPlacedViews():
for view in [DocumentManager.Instance.CurrentDBDocument.GetElement(viewport)]:
for viewelement in FilteredElementCollector(DocumentManager.Instance.CurrentDBDocument, view.Id).OfCategory(BuiltInCategory.OST_RevisionClouds):
for revisioncloud in revisioncloudinput:
if viewelement.Id == revisioncloud.Id:
matchingsheets.append(sheet)
matchingrevisionclouds.append(revisioncloud)
referencingviews.append(view)
# Assign output to the OUT variable.
OUT = matchingsheets, matchingrevisionclouds, referencingviews
Notes on the Python code:
.OfCategory()
. On a large benchmark project (1400+ revision clouds), the process currently takes around 4 minutes to complete.IN[2]
and IN[3]
. Consider having your team place all revisions on sheets and turn off Revisions in Views on Sheets to increase speed.Part 2 of the definition extracts the relevant parameter values, builds an itemized list, sorts the list, and writes it to Excel.
Simple, efficient output of Revit revision cloud data.
The Dynamo graph writes directly to the Revision Data tab in Excel. Using a Pivot Table, the raw data is converted to a user friendly format.
Post updated to reflect Version 0.6 on 25 Feb 2016.
Update: 05 Mar 2020
I’m often asked if it would be possible to utilize .OwnerViewId
to pull sheet information directly from revision clouds. While this appears to work at the surface level, we will run into issues with Legends and Dependent Views. If your project utilizes revision clouds in views, the longer element collection route described above still makes the most sense. .OwnerViewId
is, however, a viable solution if you are certain your project only has revisions on sheets.
On large projects with heavy geometry, it is possible to run into long sheet generation times. In those instances, temporarily unloading User-Created worksets will significantly reduce run time. (Revision clouds are automatically placed on a view workset separate from user-created geometry.)
/AK at 22:12 UTC