Let’s say I had a wall in my model. Is there any way to get a list of all views and sheets that display this wall?
There’s got to be an easier way, but the only way I can think of would be to use Python to first get a collection of all views, then iterate over each view with a FilteredElementCollector(doc,view) to look at only the elements visible in the view and compare that to the element in question. If the element is is the collection, then pass the view on to the output since the element is visible in that view. If the collection does not contain the element, move on to the next iteration. As far as sheets go, once you have the views, just look at “VIEWER_SHEET_NUMBER” parameter of each view that passes the first test. The parameter will either be equal to “—” if the view is not on a sheet or it will tell you which sheet the view is on.
I’m interested to hear what the easy way is from one of the experts…
Thanks for the reply. Might be a little over my head, but the outline of steps you laid out in the process makes a lot of sense.
Based on Ben’s feedback. Here’s how this can be achieved with some custom nodes available on the package manager.
Awesome “deconstruction” John.
Here’s the Python method (sorry about the formatting):
import clr clr.AddReference("ProtoGeometry") from Autodesk.DesignScript.Geometry import * Import DocumentManager and TransactionManager clr.AddReference("RevitServices") import RevitServices from RevitServices.Persistence import DocumentManager from RevitServices.Transactions import TransactionManager Import RevitAPI clr.AddReference("RevitAPI") import Autodesk from Autodesk.Revit.DB import * dataEnteringNode = IN doc = DocumentManager.Instance.CurrentDBDocument elementz = UnwrapElement(IN) viewtemplates = list() views = list() viewcollector = FilteredElementCollector(doc).OfClass(View) sheetcollector = FilteredElementCollector(doc).OfClass(ViewSheet) for view in viewcollector: if view.IsTemplate == True: viewtemplates.append(view) else: views.append(view) viewmatches = list() for elem in elementz: elemcateg = elem.Category matchviews = list() for v in views: viewelems = list() viewelems = FilteredElementCollector(doc,v.Id).OfCategoryId(elemcateg.Id) for viewelem in viewelems: if viewelem.Id == elem.Id : matchviews.append(v) viewmatches.append(matchviews) sheetz = list() for sheet in sheetcollector: sheetz.append(sheet) elsheetmatches = list() for i in range(0,len(elementz)): elviewmatches = viewmatches[i] elsheets = list() for viewmatch in elviewmatches: sheetnum = viewmatch.get_Parameter(BuiltInParameter.VIEWER_SHEET_NUMBER).AsString() if sheetnum != '---': for sheetel in sheetz: if sheetel.get_Parameter(BuiltInParameter.SHEET_NUMBER).AsString() == sheetnum: elsheets.append(sheetel) elsheetmatches.append(elsheets) OUT = viewmatches, elsheetmatches
Stupid formatting. here’s the bulk of the code
That is awesome John! Thanks!
this looks promising and I want to try it, however, isn’t it a kind of “brute force” approach?
I mean, has anyone trying this on a project with hundreds of views and sheets?
I just did this method, generally, on a project with nearly 1,000 views and it took far too long. I’d like to see if there is a way to only have it crawl the views for a specific element type, or even a specific element, without collecting them all and then filtering.
I know that it is not exactly what you’re looking for but we had a go at this a while ago for all elements visible on sheet. I made one script, Dimitar V did it better, as shown below. Maybe you can use it for further development? Anyways, it would be cool if someone could try it on a larger project.
I am sure that my little script can be made to run more efficiently by tinkering with the loops and the order of the loops (I know it can…I’m just not able to make the edits and test right now).
That said, the OP stated that they were looking to find ALL views and sheets that showed a particular element or elements. That means you must collect all of the views and test each one to see if your element is visible. If you want to limit it to just plan views, or views on sheets, or any other subset of views then obviously the script will run faster, but it will not produce ALL views that show an element.
I do think that what you suggested regarding limiting the elements in view collectors to a particular category would be wise and help a lot in the speed.
I think this iteration through all views/elements is unavoidable
but I am wondering if ‘highlight in model’ is accessible via the API & if this would be more efficient or eliminate some csutom code ?
i.e when you select an element in a schedule
So I revisited the python script and made some changes (circled in red) that seemed to help the speed.
I tested this on a real project model (30 story bldg) with 1500 views, 100+ sheets, etc…
For a single element, it took between 3 and 4 seconds to find 73 views and 17 sheets that had that element visible. I then selected 240 elements and pressure tested it - it took 11 minutes to find all views and sheets with each of those elements visible (not a running list of views but a unique list for each of the 240 elements).
For comparison, the previous script took about 5 minutes for a single element on this same model…
I found a faster way without writing any Python myself.
First, get a list of all elements of a certain type in the model (Element.AllInstances). Then query which view owns the elements (Element.OwnerView). Finally, compare (List.Contains) the IDs of these views with the IDs of all views (List All Views) and filter the list of all views by the boolean mask of the comparison.
The Phyton you shared is probably faster but this worked too.
I think Element.OwnerView only works for 2D elements (Text, Detail items, Etc…). Model Elements do not appear have an “OwnerView”. So you approach works great (and likely faster than the Python) as long as the Types are not 3D elements…
Good to know! Yes, I was looking for 2D items so it worked well. I’ll have to keep your code bookmarked for when I need something for model elements… unless someone puts a node in the Package Manager first!
would it be possible to compare only views that are on sheets?
Hi, I’ve tested Ben’s Python Script and works perfectly. I’m quite newbie here with python coding so, I would like to ask if it is possible to make this work with elements from a linked file? I got only empty lists if i add to the Input elements from the “Get All Elements From Linked Model” node.
Thank you very much.
Element_Sheets.dyn (27.9 KB)
Any chance this image can be reposted? Can’t make it out…