Here we will look at Propagating all the Grids in View using Dynamo/Python and the DatumPlane class. If you are unsure what the DatumPlane class is refer to the Intro to Datum Planes.

This is pretty much the same as the Built-In Ribbon tools for Propagating Extents but allows you to make this part of your Dynamo Workflow… Lets get to the code…

What we will make

PropagateExtents.JPG

This takes the ActiveView, gets all the views that the Grids can be Propagated to and then Propagates to all those views.

Get Propagation Views

GetPropagationViews.JPG

Here we will get all views that the Grids in the view passed in can Propagate to.

#import references...
import clr
 
# Import DocumentManager...
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
doc = DocumentManager.Instance.CurrentDBDocument

# Import RevitAPI
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *
 
# Import System Collections...
import System
from System.Collections.Generic import *

#############   DEFINITIONS START  ###############
# Convert to list if singleton...
def tolist(obj1):
    if hasattr(obj1,"__iter__"): return obj1
    else: return [obj1]
#############   DEFINITIONS END  ###############

# IN-Variables 
view = tolist(UnwrapElement(IN[0]))[0]

# Collector - Get all Grids in View...
grids = FilteredElementCollector(doc, view.Id).OfCategory(BuiltInCategory.OST_Grids)
 
# Get Propagation Views from Datum Plane Element...
vList = [UnwrapElement(g).GetPropagationViews(view) for g in grids] 

# Flatten list and convert to .Net list...
vList = list(set([item for sublist in vList for item in sublist]))

# Get View Elements from View Ids then sort by Name...
outList = [doc.GetElement(id) for id in vList]
outList.sort(key=lambda x: x.Name, reverse=False)

# Return Propagation Views...
OUT = outList

The DatumPlane class has a Method GetPropagationViews() which takes an argument of View and returns an ISet of ElementId. We are also converting this list into a .Net list using the list() function while at the same time flattening and making distinct lists using the set() function. I won’t go into detail of these functions as they are well detailed on other sites.

We have also used a lamda expression to sort by name, I will admit, I am not an expert in this, but this site is pretty good at explaining. Basically, what I am doing here is sorting the View Elements by their Name Property.

Propagate all Grids in View

PropagateGrids.JPG

This is somewhat simpler than the last script. We will be using the DatumPlane Method PropagateToViews() to Propagate the each Grid in the Ideal View to the TargetView(s). The PropagateToViews() Method takes two arguments as shown below…

public void PropagateToViews(
	View view,
	ISet<ElementId> parallelViews
)

Note how it is asking for an ISet of ElementId, we need to do something a little special here. Instead of just using an Array or List of ElementId as we usually would, we need to use the .Net System.Collections.Generic.HashSet class. Here is the line of code where we use it…

# Get ISet of TargetViews ElementID's...
tViewIds = HashSet[ElementId]([tv.Id for tv in targetViews])

Also, note how it is a Public Void, this means that the Method doesn’t return any values. If you ever see Methods that are Void, these will always return null. With that said, the rest is pretty simple and the full code is as follows…

import clr
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
 
# Import DocumentManager and TransactionManager
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
 
# Import RevitAPI
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *
 
clr.AddReference("System.Core")
from System.Collections.Generic import HashSet

import sys
pyt_path = r'C:\Program Files (x86)\IronPython 2.7\Lib'
sys.path.append(pyt_path)
 
#############   DEFINITIONS START  ###############
 
def tolist(obj1):
    if hasattr(obj1,"__iter__"): return obj1
    else: return [obj1]
 
#############   DEFINITIONS END  ###############
 
# declare IN-Variables 
view = tolist(UnwrapElement(IN[0]))[0]
targetViews = tolist(UnwrapElement(IN[1]))
 
# declare OUT-Variables
outList = []
 
#Collector - Get all grids in view...
grids = FilteredElementCollector(doc, view.Id).OfCategory(BuiltInCategory.OST_Grids)
 
# Get ISet of TargetViews ElementID's...
tViewIds = HashSet[ElementId]([tv.Id for tv in targetViews])
 
# Open a new Transaction to make changed to the Revit Document...
TransactionManager.Instance.EnsureInTransaction(doc)
# Loop through all the Grids in View...
for g in grids:
    try:
        g.PropagateToViews(view, tViewIds)
        outList.append("Grid " + g.Name + " - Propagation Succeeded")
    except Exception, e:
        outList.append("Grid " + g.Name + " - Propagation Failed" + "\n - " + e.message)
# Close Transaction and commit changes...
TransactionManager.Instance.TransactionTaskDone()

# Return the results...
OUT = outList

So, that’s how it is done! You can now Propagate those Grids! Also, you now know how to handle ISet, how to convert to .net lists, flatten lists, make them unique and see how lamba expressions work. I’ll create a Cheat-Sheet post with little helper functions like this all in one place to make it easier, if it isn’t on here when you are looking, just nag me until it is done! 🙂

Advertisement