I am trying to set the background cut pattern and color for multiple elements in a view template. I started the attached, but I am stuck as to how to designate the override to background or foreground.
@cescobar, the problem in your code is that you are feeding a View Template instance into a node that expects a View.
If you desire to modify the cut pattern of a given category in multiple views you can set up a View Template with a Visibility/Graphic Override and apply it to the desired views to achieve it. And I believe using Dynamo would be counter-productive if not at all unfeasible.
Our office is transitioning to Revit 2019 and I need to adjust dozens of templates and they all require similar adjustments. I was hoping to be able to adjust the items I wanted in multiples templates at once.
Oh, I understand… Digging quickly through the Revit API Docs I wasn’t able to find a way to create or modify View Templates, so I think they are not accessible via the API, therefore inaccessible via Dynamo / Python (I could however be wrong, for my knowledge/experience with the API is not great).
And, as haven’t mentioned before, in the post you quoted before, the implementation is destined for modifying/creating materials and wouldn’t work for your situation.
And, excuse my curiosity, but what happened with your templates when migrating to R2019? I haven’t noticed any problems with mine so far (although mine are really simple).
We want to take advantage of the dual patterns to be able to show phasing and also the materials within categories such as walls, floors, ceilings, etc. Below is our goal:
Christian, I was wrong. After you mentioned your script worked partially for your purposes, I realized the API sees the ViewTemplate as the same thing as a View instance, therefore, it could be done. Also, the problem your script faces is that the Dynamo OOTB node for Graphic Override does not include the Foreground and Background property for patterns that came with the R2019. So, based on my previous code for modifying Materials, I the developed the one that follows, and I believe it suits your needs.
#PROTO_View/Viewtemplate Modification by category v1 (Color and Surface Pattern control)
# by David DĂłria (arq.david.doria@outlook.com)
import clr
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
### INPUTS
template = IN[0]
category = IN[1]
forePat = IN[2]
foreColor = IN[3]
bkgPat = IN[4]
bkgColor = IN[5]
def ToRevitColor(dynamoColor):
return Color(dynamoColor.Red, dynamoColor.Green, dynamoColor.Blue)
#Avoid instance input problem
if isinstance(template, list):
template = template
else: template = [template]
if isinstance(category, list):
category = category
else: category = [category]
if isinstance(forePat, list):
forePat = forePat
else: forePat = [forePat]
if isinstance(foreColor, list):
foreColor = foreColor
else: foreColor = [foreColor]
if isinstance(bkgPat, list):
bkgPat = bkgPat
else: bkgPat = [bkgPat]
if isinstance(bkgColor, list):
bkgColor = bkgColor
else: bkgColor = [bkgColor]
### CODE CORE
try:
TransactionManager.Instance.EnsureInTransaction(doc)
for t, cat, fP, fC, bP, bC in zip(template, category, forePat, foreColor, bkgPat, bkgColor):
#Create the OverrideGraphicSetting instance
over = OverrideGraphicSettings()
#Set foreground cut pattern
over.SetCutForegroundPatternId(UnwrapElement(fP).Id)
#Set foreground cut pattern color
over.SetCutForegroundPatternColor(ToRevitColor(fC))
#Set background cut pattern
over.SetCutBackgroundPatternId(UnwrapElement(bP).Id)
#Set background cut pattern color
over.SetCutBackgroundPatternColor(ToRevitColor(bC))
t = UnwrapElement(t)
t.SetCategoryOverrides(UnwrapElement(cat).Id, over)
TransactionManager.Instance.TransactionTaskDone()
OUT = "Graphics Overriden!"
except:
OUT = "Oops! Something went wrong"
You could copy the Python node, open it and delete the particular line of code you’d like to ignore for the category you are feeding in the IN[01] (the operations are commented and should be easy to identify).
Also, if the previous post solves your problem, I’d appreciate if you mark it as a solution.
Hello @David_Doria
I have similar problem as @cescobar had . I want to use the foreground and background overides, but not assign them to view templates but rather use them in View.SetFilterOverides node. The node I found only let’s me change the forground color and pattern.
Hey, @Peter_Heldes
The following code / script will help you achieve what you want. A simple adaptation on what I had before does the trick. Instead of passing categories, you should pass a Filter element, such as the one you have already set up.
#PROTO_View Category Filter Override Modification by category v1 (Color and Surface Pattern control)
# by David DĂłria (arq.david.doria@outlook.com)
import clr
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
### INPUTS
view = IN[0]
filter = IN[1]
forePat = IN[2]
foreColor = IN[3]
bkgPat = IN[4]
bkgColor = IN[5]
def ToRevitColor(dynamoColor):
return Color(dynamoColor.Red, dynamoColor.Green, dynamoColor.Blue)
#Avoid instance input problem
if isinstance(view, list):
view = view
else: view = [view]
if isinstance(filter, list):
filter = filter
else: filter = [filter]
if isinstance(forePat, list):
forePat = forePat
else: forePat = [forePat]
if isinstance(foreColor, list):
foreColor = foreColor
else: foreColor = [foreColor]
if isinstance(bkgPat, list):
bkgPat = bkgPat
else: bkgPat = [bkgPat]
if isinstance(bkgColor, list):
bkgColor = bkgColor
else: bkgColor = [bkgColor]
### CODE CORE
try:
TransactionManager.Instance.EnsureInTransaction(doc)
for v, filt, fP, fC, bP, bC in zip(view, filter, forePat, foreColor, bkgPat, bkgColor):
#Create the OverrideGraphicSetting instance
over = OverrideGraphicSettings()
#Set foreground cut pattern
over.SetCutForegroundPatternId(UnwrapElement(fP).Id)
#Set foreground cut pattern color
over.SetCutForegroundPatternColor(ToRevitColor(fC))
#Set background cut pattern
over.SetCutBackgroundPatternId(UnwrapElement(bP).Id)
#Set background cut pattern color
over.SetCutBackgroundPatternColor(ToRevitColor(bC))
v = UnwrapElement(v)
#t.SetCategoryOverrides(UnwrapElement(cat).Id, over)
v.SetFilterOverrides(UnwrapElement(filt).Id, over)
TransactionManager.Instance.TransactionTaskDone()
OUT = "Graphics Overriden!"
except:
OUT = "Oops! Something went wrong"
Thank you so much works perfectly I have one more questions. If I want to apply those overrides to multiple views and insert list of views into the first input then I have to match the list size od the colors and patterns right ? I did it using List.OfRepeatedItem but hen it makes it messy do you know of better way around it ?
I’ve tried all .dyn files but because of dynamo version some nodes doesn’t do the “trick” and because of my beginner experience I couldn’t tried.
BUT, if @David_Doria or anyone knows a different aproach for my issue, i’ll be glad for your help.
Here’s my struggle:
I have a technical design (image Left) with different foreground cut patterns by material / wall layers:
And i need to overried PATTERNS by MATERIAL to assign different solid colors to several materials in a certain view (image Right).
I’ve tried Revit PARTS and then filter then by material name, and it works BUT it’s really painfull if i change walls or any other procedure.
The big issue is to have a script that OVERRIDES Cut Patterns by Material in a specific View and do not change the entire model, because i need those two types of views (“original” and “override”).