I have an issue in setting view template to 3D view using python script.
The idea is to select multiple 3D views, apply different view templates to each views and export each view every time after applying view template.
The scripts runs without error…but no result.
I suspect the issue is with matching the collector view name & view template name. ( in the if loop)
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]
prefix = IN[2]
folder = IN[3]
views = []
index = 1
for i in IN[0]:
views.append(UnwrapElement(i))
# Start Transaction
TransactionManager.Instance.EnsureInTransaction(doc)
collector = FilteredElementCollector(doc).OfClass(View3D)#change to View3D
for i in collector:
if i.IsTemplate == True:
for v in viewtempname:
if i.Name == v:
viewtemp = i
for c in views:
c.ViewTemplateId = viewtemp.Id
vname = prefix + c.Name + str(index)
nop = NavisworksExportOptions()
nop.ExportScope = NavisworksExportScope.View
nop.ViewId = c.Id
doc.Export(folder,vname,nop)
index = index + 1
#for c, v in zip(viewelements,viewtemp):
#c.SetParameterByName(param, v)
#for c, v in zip(views,viewtemp):
# c.ViewTemplateId = v.Id
# vname = prefix + c.Name + str(index)
# nop = NavisworksExportOptions()
# nop.ExportScope = NavisworksExportScope.View
# nop.ViewId = c.Id
# doc.Export(folder,vname,nop)
# index = index + 1
# End Transaction
TransactionManager.Instance.TransactionTaskDone()
OUT = views
@varunbose@Mostafa_El_Ayoubi I’ve had luck with the View.ApplyViewTemplate node from the SteamNodes package. It seems you can’t retrieve 3D view templates but you can still apply them using the name of the view template.
@dana.g Very interesting …
So I took a look at the code inside that node and it turns out Dynamo python nodes will output the names of 3d view templates but not the templates themselves…
I found a way to only display 3D view templates (maybe a dropdown would be more apporpriate than a listview input), here’s the code I used:
import clr
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import*
clr.AddReference('RevitServices')
from RevitServices.Persistence import DocumentManager
doc = DocumentManager.Instance.CurrentDBDocument
tempnames = [v.Name for v in FilteredElementCollector(doc).OfClass(View).ToElements() if v.IsTemplate and v.ViewType == ViewType.ThreeD]
OUT = tempnames
That code to display 3D view templates is brilliant…
@dana.g Thanks…My scrip was a combination of Steam Node & Data Shape node with changes.
Changes I tried to do is…
Steam Node : Instead of applying 1 view template to different views, I tried to apply different view templates to 1 view (Because I am greedy…I tried multiple views before I post here…).
Data Shape Node: Because there will be multiple export from same view, I added a index to add to name before export.
Then I added Data Shape node under Steam Node in the loop itself, so that as soon as 1st view gets the 1st view template set, it will get exported, then apply next template for the same view & export until all view templates are applied. then jump to next view, do the same…and so on…
But don’t know what is the issue…
viewtempname = IN[1]
prefix = IN[2]
folder = IN[3]
views = []
index = 1
for i in IN[0]:
views.append(UnwrapElement(i))
# Start Transaction
TransactionManager.Instance.EnsureInTransaction(doc)
collector = FilteredElementCollector(doc).OfClass(View)
for x in viewtempname:
for i in collector:
if i.IsTemplate == True and i.Name == x:
viewtemp = i
for c in views:
c.ViewTemplateId = viewtemp.Id
vname = prefix + c.Name + str(index)
nop = NavisworksExportOptions()
nop.ExportScope = NavisworksExportScope.View
nop.ViewId = c.Id
doc.Export(folder,vname,nop)
index = index + 1
@Mostafa_El_Ayoubi they are accessible, it’s just that they cannot be wrapped into an object that Dynamo can pass around on canvas/between nodes. It’s still possible to use a Python node to get a 3D view template, apply it to whatever view etc. so long as you don’t try to output it from the Python node.
Why do you even need a 3D View template? You can apply a plan view template to a 3d view and it works just fine. Whatever the issue is, it’s just best to avoid these half-baked templates because they have no purpose.
Ps. I would consider what you are trying to accomplish. You are applying the view template to a 3D View. The idea here is that you apply that view template, and then export that view to Navisworks. It sounds honky dory in theory, but I have a feeling that for a View template to actually take effect it needs to regenerate the model. Try putting a doc.Regenerate() between view template being applied and the actual view getting exported.
I have a project where we have 4 zone…40 floors. I do clash detection per floor seperate for each zone. So I thought of making this script…And I thought I am too close with this to work…
I noticed that, after running this graph, even though I am not getting any NWC output, some views was getting a change in view template. Because its looping through different views & setting different view templates, I had a doubt that whether the loop was working or not.
So I added a message box in the loop to see, what is happening. (To show View Template ID after applying)
The result is that, the loop itself is working & Script can set different view templates to different views. See the video.
I was expecting a message after each view template is set. But I noticed that at some stage, when I close 1 message next pop up but no change but as soon as I close that 2 views get changed…There is something wrong there also. But It sure that this script is setting 3D View template to views.
But not exporting NWC after setting view template. So as @Konrad_K_Sobon advised I added doc.Regenerate() as soon as view template is set before it moves to Export code. But still no export.
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 *
clr.AddReference("RevitAPIUI")
from Autodesk.Revit.UI import TaskDialog
doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
app = uiapp.Application
uidoc=DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument
viewtempname = IN[1]
prefix = IN[2]
folder = IN[3]
views = []
index = 1
test1 = []
test2 = []
test3 = []
test4 = []
msgBox = TaskDialog
for i in IN[0]:
views.append(UnwrapElement(i))
# Start Transaction
TransactionManager.Instance.EnsureInTransaction(doc)
collector = FilteredElementCollector(doc).OfClass(View)
for x in viewtempname:
for i in collector:
if i.IsTemplate == True and i.Name == x:
viewtemp = i
test1.append(i.Name)
test2.append (x)
test3.append (i)
test4.append (viewtemp.Id)
for c in views:
doc.Regenerate()
c.ViewTemplateId = viewtemp.Id
doc.Regenerate()
msgBox.Show("Result",str(viewtemp.Id))
vname = prefix + c.Name + str(index)
nop = NavisworksExportOptions()
nop.ExportScope = NavisworksExportScope.View
nop.ViewId = c.Id
doc.Export(folder,vname,nop)
index = index + 1
# End Transaction
TransactionManager.Instance.TransactionTaskDone()
OUT = views,viewtemp,test1,test2,test3,test4,collector
When I added the message box just above the Export, it works fine. Means it “ignores” v=doc.Export(folder,vname,nop). Its finishing the loop, so not exiting at doc.Export…
for c in views:
doc.Regenerate()
c.ViewTemplateId = viewtemp.Id
doc.Regenerate()
#msgBox.Show("Result",str(viewtemp.Id))
vname = prefix + c.Name + str(index)
nop = NavisworksExportOptions()
nop.ExportScope = NavisworksExportScope.View
nop.ViewId = c.Id
msgBox.Show("Result",str(c.Id) + "--" + vname)
v=doc.Export(folder,vname,nop)
index = index + 1
@varunbose this will do what you want :
in my example I have three templates: one that only shows roofs, one that only shows floors and one for walls. The script applies all the selected templates to each selected 3D view you select and exports it to nwc.
the dyn : Change View Template_6 mod2.dyn (24.4 KB)
import clr
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import*
clr.AddReference('RevitServices')
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
def tolist(input):
if isinstance(input,list):
return input
else:
return [input]
views = UnwrapElement(tolist(IN[0]))
directorypath = IN[1]
templatenames = tolist(IN[2])
templates = []
templatescollector = [t for t in FilteredElementCollector(doc).OfClass(View).ToElements() if t.IsTemplate]
for i in templatescollector:
for tn in templatenames:
if i.Name == tn:
templates.append(i)
else:
pass
nop = NavisworksExportOptions()
nop.ExportScope = NavisworksExportScope.View
TransactionManager.Instance.ForceCloseTransaction()
for v in views:
for t in templates:
tr = Transaction(doc,t.Name)
tr.Start()
v.ViewTemplateId = t.Id
tr.Commit()
nop.ViewId = v.Id
doc.Export(IN[1],v.Name + t.Name,nop)
OUT = [t.Name for t in templates]
I’m a beginner in Revit and Dynamo, and do I see it right that the latest DYN here in this thread “View Template_6 mod2.dyn” is not ready to run, but need some modifications or additional packages?