I can’t seem to get this to work. I am brand new to Dynamo and plan on going through all the tutorials but I have not yet so I apologize if I do not phrase my questions correctly.
If I try to run it based on the picture you provided, I get a warning on the codeblock for the ElOnSht defenition (which reads Warning: Method ‘_Map()’ not found) and a warning on the final codeblock in the script which reads (Warning: Method ‘ElOnSht()’ not found). Does the definition codeblock have to be special in order to work?
Per your original post, I downloaded the Elements in View(s) package which relied upon Turn Into List which, subsequently, has been rolled into clockwork as ReturnListOrSingleValue. I had to replace the TurnIntoList with ReturnListOrSingleValue in Elements In View(s) in order to get it not crash Dynamo when loaded. Unfortunately the two nodes are somewhat different. I will post a picture below, does it look right or do I need to modify it?
Regarding the picture you provided above, is that the entire script to accomplish placing all sheets that a view appears on or is that just a custom node that exists in your original script? I figured the picture you posted was the entire script but just wanted to make sure.
Hopefully these questions make sense…and thanks again!
P.S. Just to make sure you understand what I am actually trying to get from this script. I would like each view to have the OnSheet parameter showing other sheets it is referenced on.
I could be completely wrong about this but it seems like the issues lies in the Elements in View(s) node. I have tried both scripts shown in @jostein_olsen s pictures and they both screw up right after the Elements in Views node is used.
So my next question would be if anyone knows another way to accomplish the goal that I am aiming for? (Finding all sheets that a given view is referenced on and apply it to a parameter)
I was looking at this earlier. This might work but the goal is not to find all referring views but to find only referring views that exist on sheets and then write those sheet numbers to a parameter for said view. If there is a way to modify this to work for that goal, I am all for trying it. I just am not skilled enough (yet) to do the modification myself.
@rdeardorff if you look at the image of the graph, it is only searching through views that are on sheets because it is searching in views output from the Rhythm node Sheet.GetViewportsAndViews
Edit: and yes the graph can be added to so that it gets the sheet numbers and writes them to the view’s parameter value
Oh, ok. Then how might this fit into the workflow I am attempting (and failing) to achieve? Also, how would I modify it (do I have to?) to look at all views and not just drafting views (it appears to only be looking at drafting views but maybe I am wrong).
Edit: I am currently constructing the script from the post you linked BTW. Not being lazy, I promise!
It accepts all view types, you just feed the node a view name. That script is only capable of finding referring views for one view at a time, but here is a modification so that it will handle a list of multiple views:
import clr
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
doc = DocumentManager.Instance.CurrentDBDocument
views = UnwrapElement(IN[0])
names = IN[1]
if not isinstance(names, list):
names = [names]
refviews = []
def getRefs(sheetviews, vName):
refViews = []
for view in sheetviews:
viewColl = FilteredElementCollector(doc, view.Id).OfCategory(BuiltInCategory.OST_Viewers).ToElements()
for viewer in viewColl:
if viewer.Name == vName:
refViews.append(view)
return refViews
for name in names:
refviews.append(getRefs(views,name))
OUT = refviews
So you can do something like below and gather all views of the types you want into a list, then feed the Python script their names:
Sorry for the spam. I realized why I was getting an error. I didnt have any sections in my project. Once I added one and placed it on a sheet it worked fine. In the event a project didnt have (lets say) an elevation, is there a way to have dynamo leave those out so that it doesnt break the script?
Otherwise, now that it seems to be working, how do I get the sheet numbers into a parameter for each view?
If you’d uploaded a screen capture of where your graph broke, I could give better direction as to how/where in the graph this can be done - you could use either a List.Clean node or a Flatten node to eliminate any Empty Lists (which I assume you would have gotten from the View.GetByType node? If you just moved the Flatten node that is after the codeblock with “view.Name” in it, I believe it would have worked
Use Element.GetParameterValueByName with the Python script output views as the element, and “Sheet Number” as the parameter. Then Element.SetParameterValueByName with the views you input the names of into the Python script as the elements, and the Sheet Numbers as the values
Here is my attempt at getting the script to input data into a parameter. In my case, the parameter is called OnSheet. I was a little confused by your last sentence so I think I missed the last step.
Is it possible to sort the sheet numbers numerically and alphabetically prior to writing them into the parameter? i am sure it is but I am not sure where that step wants to sit in the order of things.
Can I send you a Starbucks giftcard? lol
Edit: One other question for you when you have time. I played around with it and it seems to be working perfectly except for one thing. It recognizes views referenced by sections but not referenced by View References. I am not sure that it really matters but I am curious if there is a way for the parameter to show all references of the view including View References.
A List.Sort node with the list input @L2 (hit the small arrow next to list on the node) before String.Join should work
View References behave differently than sections/elevation markers which can be observed by the differences when selecting them in Revit; A section/elev marks/call out when selected shows the view that it belongs to, whereas a View Reference shows the family/type of the View Reference element, with a parameter value of “Target view” indicating the view that is being referenced. It’d take me a bit to modify the Python script to process all types of these elements in one run, but when I get to it I will share here !
@rdeardorff I took a quick pass at it and this (messy) modified script seems to work:
import clr
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
doc = DocumentManager.Instance.CurrentDBDocument
sheetViews = UnwrapElement(IN[0])
views = UnwrapElement(IN[1])
refviews = []
def getRefs(sheetviews, refdview):
refViews = []
for view in sheetviews:
viewerColl = FilteredElementCollector(doc, view.Id).OfCategory(BuiltInCategory.OST_Viewers).ToElements()
for viewer in viewerColl:
if viewer.Name == refdview.Name:
refViews.append(view)
refColl = FilteredElementCollector(doc, view.Id).OfCategory(BuiltInCategory.OST_ReferenceViewer).ToElements()
for refviewer in refColl:
if refviewer.LookupParameter("Target view").AsElementId() == refdview.Id:
refViews.append(view)
return refViews
for view in views:
refviews.append(getRefs(sheetViews,view))
OUT = refviews
Note the changes that need to be made to the graph; the Python script now needs the view elements, and not their names, and there are some level changes on the nodes after the Python script: