Now for the python script:
##CLR
Dynamo uses a version of python called IronPython which is capable of dealing with .NET libraries.
To interact with the Revit API we have to load an .NET assembly, a dll file named RevitAPI.dll, and for this we need the clr module from Iron Python. (http://ironpython.net/documentation/dotnet/)
Thus the first lines of the code looks like this:
import clr
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *
##Generic collections
If we look at the arguments of DivideParts, three of them are expected to be generic collection types:
ICollection<ElementId> elementIdsToDivide,
ICollection<ElementId> intersectingReferenceIds,
IList<Curve>
To access them we need to reference .NET System.Collections.Generic. The reference and the definition of the collections can be coded like this:
clr.AddReference('System')
from System.Collections.Generic import List
#Create a list for the wall and the divisionLines
wallList = List[ElementId]()
wallList.Add(wall.Id)
intersectionElementsIds = List[ElementId]()
curveArray = List[Curve](divisionLines)
##Document and transaction
The rest of the references are well explained in dynamos wiki page on github: https://github.com/DynamoDS/Dynamo/wiki/Python-0.6.3-to-0.7.x-Migration#revitapi
The first argument in DivideParts() is the document. Dynamo provides us with a documentmanager. In our script we are making changes to the Revit database, and then a Transaction is required. Here is how the document- and transaction manager are imported:
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
Here is how to get the current document:
doc = DocumentManager.Instance.CurrentDBDocument
The DivideParts method must be placed inside a Transaction like this:
TransactionManager.Instance.EnsureInTransaction(doc)
partDivide = PartUtils.DivideParts(doc, parts, intersectionElementsIds, curveArray, sketchPlane.Id)
TransactionManager.Instance.TransactionTaskDone()
##Geometry conversion and wrapping/unwrapping of elements
This is explained in the github wiki.
All Revit elements that lives in the dynamo world are wrapped, and needs to be unwrapped before the revit api can understand them. In our case the wall and the SketchPlane are Revit elements (you can tell because of the green labeled id number. Also the lines in dynamo needs to be converted to Revit-lines, including unit conversion since the Revit api works in decimal feet.
Here are the necessary references:
clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.GeometryConversion)
clr.ImportExtensions(Revit.Elements)
The elements are unwrapped with UnwrapElement() and the lines are converted with .ToRevitType() like this:
wall = UnwrapElement(IN[0])
divisionLines = [l.ToRevitType(True) for l in IN[1]]
sketchPlane = UnwrapElement(IN[2])
##The part splitting
From the Revit API documentation we find the PartUtils Class that provides us with the methods we need.
We have a wall and it need to be associated with a part that can ble divided. The if block checks if a part can be created from the wall, and if so, create it. (This takes care of walls that already are associated with a part). The next step is to get all the parts from the wall with PartUtils.GetAssociatedParts, finally the divisioning can be done with PartUtils.DivideParts
if PartUtils.AreElementsValidForCreateParts(doc, wallList):
createParts = PartUtils.CreateParts(doc, wallList)
doc.Regenerate()
parts = PartUtils.GetAssociatedParts(doc, wall.Id, 0, 0)
partDivide = PartUtils.DivideParts(doc, parts, intersectionElementsIds, curveArray, sketchPlane.Id)
##The complete python code
import clr
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *
clr.AddReference('System')
from System.Collections.Generic import List
clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.GeometryConversion)
clr.ImportExtensions(Revit.Elements)
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
#Preparing input from dynamo to revit
wall = UnwrapElement(IN[0])
divisionLines = [l.ToRevitType(True) for l in IN[1]]
sketchPlane = UnwrapElement(IN[2])
#Create a list for the wall and the divisionLines
wallList = List[ElementId]()
wallList.Add(wall.Id)
intersectionElementsIds = List[ElementId]()
curveArray = List[Curve](divisionLines)
#All actions that makes changes to the Revit database needs to be inside a Transaction
TransactionManager.Instance.EnsureInTransaction(doc)
if PartUtils.AreElementsValidForCreateParts(doc, wallList):
createParts = PartUtils.CreateParts(doc, wallList)
doc.Regenerate()
parts = PartUtils.GetAssociatedParts(doc, wall.Id, 0, 0)
partDivide = PartUtils.DivideParts(doc, parts, intersectionElementsIds, curveArray, sketchPlane.Id)
TransactionManager.Instance.TransactionTaskDone()
OUT = partDivide
##The dynamo file
partDivisionLines.dyn (21.7 KB)
##Screenshot