Some View Templates not being found in Python/Dynamo

Some View Templates are not found in Dynamo:

List in Revit’s UI

not found

found

It seems that the same View Templates that aren’t found in the Python node are also not seen in the dropdown nodes from Archilab and DynaMEP

Python in the ViewTemplateByNameString node

import sys
import clr
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *

doc = DocumentManager.Instance.CurrentDBDocument

name = IN[0]
elem = []

views = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Views).ToElements()
for v in views:
	if v.IsTemplate:
		if v.Name == name:
			elem.append(v)

OUT = elem[0]

Any insights?

However, View.ApplyViewTemplate from SteamNodes works with given the same View Template name string that failed in the previous example. Its Python:

import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
# Import ToDSType(bool) extension method
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
# Import geometry conversion extension methods
clr.ImportExtensions(Revit.GeometryConversion)
# Import DocumentManager and TransactionManager
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
from System.Collections.Generic import *
# Import RevitAPI
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *

doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
app = uiapp.Application
uidoc=DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument

viewTempName = IN[1]
views = []
for i in IN[0]:
	views.append(UnwrapElement(i))

# Start Transaction
TransactionManager.Instance.EnsureInTransaction(doc)

collector = FilteredElementCollector(doc).OfClass(View)
for i in collector:
	if i.IsTemplate == True and i.Name == viewTempName:
		viewTemp = i

for i in views:
	i.ViewTemplateId = viewTemp.Id
		

# End Transaction
TransactionManager.Instance.TransactionTaskDone()

OUT=views

3D templates I assume?

You can use Python like the following to get the template names:

import clr
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import*
clr.AddReference('RevitServices')
from RevitServices.Persistence import DocumentManager
doc = DocumentManager.Instance.CurrentDBDocument

views = FilteredElementCollector(doc).OfClass(View3D)
viewTemplates = []

for v in views:
	if v.IsTemplate == True:
		viewTemplates.append(v.Name)

OUT = viewTemplates

To get the templates themselves you’ll have to fiddle around with element wrappers. I believe there is a custom node tucked away somewhere that’ll do it but can’t recall the package. Edit: try Springs, but no promises.

To add to this and clarify why that node works, the issue here isn’t API related in Revit but in Dynamo specifically. You can get and use/access 3D view templates in Python/C# etc but once they go to canvas they return nulls so generally most nodes exclude them unless they use them all within a Python/C# node (e.g. get by name, which is a good workaround).

1 Like

That is good for getting the Names but the Views themselves are null.

import clr
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import*
clr.AddReference('RevitServices')
from RevitServices.Persistence import DocumentManager
doc = DocumentManager.Instance.CurrentDBDocument

views = FilteredElementCollector(doc).OfClass(View3D).ToElements()
viewTemplates = []
viewDB = []

for v in views:
	if v.IsTemplate == True:
		viewTemplates.append(v.Name)
		viewDB.append(v)

OUT = viewTemplates,viewDB

If we use OfClass(View) then we only get the 2D Views returned and the 3D ones are null

I wonder what the fiddle is…

Ah, so those data work inside Python but we can’t get them out.

1 Like

As @GavinCrump points out, it’s a limitation within Dynamo as there’s no included wrapper for them. You either need to keep all workings related to the template within Python, or get their Ids or names and work with those within the Dynamo graph as the element itself willjust reports nulls inside the graph environment. I did have a check and it is Springs that has a node for them, it appears he’s written a custom wrapper of some sort in there to handle them. (Excuse my poor terminology and wait for the big boys to respond if you want more accurate details, that’s the gist of it anyway).

2 Likes

UniqueId returns something then we’d have to filter by that and manipulate inside of Python again, eh?

What is the name of the Springs node?

You could get their element Id as integers and then use the Python code…

Document.GetElement(ElementId(int))

…in later Python nodes to pass them down the canvas, but they wouldn’t serve much purpose outside the original block.

I think I solved it; based on Springs ꟿ Collect.View3DTemplates

import clr

clr.AddReference('RevitAPI')
import Autodesk.Revit.DB as DB

clr.AddReference('RevitServices')
from RevitServices.Persistence import DocumentManager
doc = DocumentManager.Instance.CurrentDBDocument

clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.Elements)


name = IN[0]
ueWrapper = None
wrappers = clr.GetClrType(Revit.Elements.ElementWrapper).GetMethods()
for w in wrappers:
	if w.ToString().startswith("Revit.Elements.UnknownElement"):
		ueWrapper = w
		break

fec = DB.FilteredElementCollector(doc).OfClass(DB.View3D)
OUT = []
for i in fec:
	if i.IsTemplate and i.Name == name:
		OUT.append(ueWrapper.Invoke(None, (i, True) ))
		break
OUT = OUT[0]

Clues from Get 3D view template - #15 by Ning_Zhou – found with the new Bing AI search engine.

I published it as a node: 3DViewTemplateByName

1 Like