This article is translated from an original source.
This is arguably the best article on using RevitAPI within Dynamo. First and foremost, thank you to the original author for this translation!
Input Variables
Starting from Dynamo version 0.7, the number of input variables accepted by Python script nodes can vary. In versions before 0.6, each input value required a separate variable. Now, multiple input values are bundled into a list called IN. You can access each input by its index—for example, IN[0] for the first input, IN[1] for the second, and so forth.
Here’s a simple example to count and sum input values using a loop:
count = 0
for number in IN:
count += number
OUT = count
RevitAPI Integration
To facilitate better interaction between Dynamo and RevitAPI, a comprehensive library has been developed.
Accessing Document and Application
You can access Revit documents through the DocumentManager class available in Dynamo’s libraries:
import clr
clr.AddReference(“RevitServices”)
import RevitServices
from RevitServices.Persistence import DocumentManager
doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
app = uiapp.Application
Working with Elements
In Dynamo, elements are wrapped by Revit classes. To manipulate them within Python scripts, use classes from the Revit.Elements namespace.
import clr
clr.AddReference(“RevitNodes”)
import Revit
from Revit.Elements import CurveByPoints, ReferencePoint
import System
startRefPt = IN[0]
endRefPt = IN[1]
refPtArray = System.Array[ReferencePoint]([startRefPt, endRefPt])
OUT = CurveByPoints.ByReferencePoints(refPtArray)
Direct Use of RevitAPI
To use RevitAPI directly, you need to unwrap the wrapped elements first. Use the TransactionManager class to ensure your operations are executed within Revit transactions. Afterwards, wrap the results for output.
import clr
clr.AddReference(“RevitAPI”)
import Autodesk
from Autodesk.Revit.DB import ReferencePointArray
clr.AddReference(“RevitServices”)
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
clr.AddReference(“RevitNodes”)
import Revit
clr.ImportExtensions(Revit.Elements)
startRefPt = UnwrapElement(IN[0])
endRefPt = UnwrapElement(IN[1])
doc = DocumentManager.Instance.CurrentDBDocument
TransactionManager.Instance.EnsureInTransaction(doc)
arr = ReferencePointArray()
arr.Append(startRefPt)
arr.Append(endRefPt)
cbp = doc.FamilyCreate.NewCurveByPoints(arr)
TransactionManager.Instance.TransactionTaskDone()
OUT = cbp.ToDSType(False)
Unwrapping Elements
All wrapped elements inherit from Revit.Elements.Element in the Revit.Elements namespace. This class provides the InternalElement property, which references the underlying RevitAPI element. Dynamo offers the UnwrapElement(element) function to extract the RevitAPI element from a wrapped element. If the input is not a wrapped element, it remains unchanged.
wrappedElement = IN[0]
unwrappedElement = UnwrapElement(wrappedElement)
Now, unwrappedElement can be used directly with RevitAPI.
Encapsulation
To interact properly with Revit nodes, any element returned from a Python script must be wrapped in a class from Revit.Elements.Element. This is achieved using the ToDSType(boolean) method. The boolean flag indicates whether the element already exists in the Revit document (True) or was created within the script (False).
import clr
clr.AddReference(“RevitNodes”)
import Revit
clr.ImportExtensions(Revit.Elements)
docPt = FetchRefPtFromDoc() # Hypothetical function to read a point
newPt = CreateNewRefPt() # Hypothetical function to create a new point
OUT = [
docPt.ToDSType(True), # Existing element
newPt.ToDSType(False) # Newly created element
]
Units Conversion
Dynamo uses meters for length units, whereas RevitAPI uses feet. This requires manual conversions when transforming geometry or length values:
metersToFeet = 0.3048
feetToMeters = 1 / metersToFeet
Convert length from Dynamo to Revit units:
dynamoUnitsLength = someDynamoLengthFunction()
revitUnitsLength = dynamoUnitsLength * metersToFeet
Convert length from RevitAPI to Dynamo units:
revitUnitsLength = someRevitLengthFunction()
dynamoUnitsLength = revitUnitsLength * feetToMeters
Geometric Objects
Revit geometry includes entities such as points and curves, which are Revit geometric objects. Dynamo-generated geometry is not directly compatible with Revit geometry, so conversion is necessary. Note that Dynamo uses meters while Revit uses feet for units. Dynamo provides the GeometryConversion tool to assist with this process.
To import GeometryConversion:
import clr
clr.AddReference(“RevitNodes”)
import Revit
clr.ImportExtensions(Revit.GeometryConversion)
Convert from Revit to Dynamo geometry:
dynamoGeometry = revitGeometryObject.ToProtoType()
Convert from Dynamo to Revit geometry:
revitGeometryObject = dynamoGeometry.ToRevitType()
The XYZ class in Revit represents a point but is not considered a geometric object. You can convert it as follows:
point = xyz.ToPoint()
vector = xyz.ToVector()
xyz = pointOrVector.ToXyz()
You can skip unit conversion by passing False to the methods ToRevitType(), ToProtoType(), ToXyz(), ToPoint(), and ToVector().
import clr
clr.AddReference(“RevitAPI”)
import Autodesk
clr.AddReference(“RevitNodes”)
import Revit
clr.AddReference(“RevitServices”)
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
clr.ImportExtensions(Revit.GeometryConversion)
clr.ImportExtensions(Revit.Elements)
xyz = IN[0].ToXyz()
doc = DocumentManager.Instance.CurrentDBDocument
TransactionManager.Instance.EnsureInTransaction(doc)
refPt = doc.FamilyCreate.NewReferencePoint(xyz)
TransactionManager.Instance.TransactionTaskDone()
OUT = refPt.ToDSType(False)
Transactions
Dynamo provides its own transaction framework that can be used within Python scripts. When working with RevitAPI transactions, utilize Dynamo’s TransactionManager class as follows:
TransactionManager.EnsureInTransaction(): Starts a Dynamo transaction
TransactionManager.TransactionTaskDone(): Ends the transaction
TransactionManager.ForceCloseTransaction(): Forces Dynamo to commit the transaction
import clr
clr.AddReference(“RevitServices”)
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
TransactionManager.Instance.EnsureInTransaction(doc)
refPt = doc.FamilyCreate.NewReferencePoint(XYZ(0, 0, 0))
TransactionManager.Instance.TransactionTaskDone()
You can also manage transactions using RevitAPI subtransactions. Unlike main transactions, subtransactions allow rollbacks for changes.













Must log in before commenting!
Sign Up