1 - Get Views
Firstly, let's get some views.
I will keep it simple and get views by name from a collection. And this can be a tricky step. Keep in mind that you might need to filter a few things out to get the right views. I will do the following:
Filter Views by ViewType (because we can have same view names across different types)
Filter ViewTemplates out.
* You could also filter views without View Filters if you want users to select view_from
I will keep it simple for this lesson and use a collector to get views and then match them with view names I need.
def get_view_by_name(view_name, view_type = ViewType.FloorPlan):
"""Get Views by exact Name."""
views = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Views).WhereElementIsNotElementType().ToElements()
views = [v for v in views if v.ViewType == view_type]
views = [v for v in views if not v.IsTemplate]
dict_views = {view.Name: view for view in views}
if view_name not in dict_views:
print('Could not find view by name: {}'.format(view_name))
else:
return dict_views[view_name]
view_from = get_view_by_name('Level 0', ViewType.FloorPlan)
view_to = get_view_by_name('Level 1', ViewType.FloorPlan)
💡You can make it more efficient by keeping collector outside, but I keep it simple for tutorial.
2 - Get View Filters
Once we have the view, we need to select some filters.
I don't always want to copy all available filters, so we will use a simple pyrevit.form - SelectFromList, so user can decide what they want to copy.
Here is the code snippet:
filter_ids = view_from.GetOrderedFilters()
filters = [doc.GetElement(f_id) for f_id in filter_ids]
sel_filters = forms.SelectFromList.show(filters,
multiselect=True,
name_attr='Name',
button_name='Select View Filters')
if not sel_filters:
forms.alert("No View Filters were Selected.\n"
"Please Try Again.", exitscript=True)
GetOrderedFilters()
Convert ElementIds to Filters
Create SelectFromList form
Ensure Filters selected
3 - Copy View Filters
Alright, it's time to do the magic.
To copy filters from view A to B we will need to read a few settings so we can set the same overrides and visibility controls.
Here is the code snippets for that:
with Transaction(doc, 'Copy ViewFilters') as t:
t.Start()
for view_filter in filters:
overrides = view_from.GetFilterOverrides(view_filter.Id)
view_to.SetFilterOverrides(view_filter.Id, overrides)
visibility = view_from.GetFilterVisibility(view_filter.Id)
enable = view_from.GetIsFilterEnabled(view_filter.Id)
view_to.SetFilterVisibility(view_filter.Id, visibility)
view_to.SetIsFilterEnabled(view_filter.Id, enable)
t.Commit()
🔓 Use Transaction to make changes
For Each Filter:
Get Filter Overrides
Set Filter Overrides (it will also create it)
Get Filter Visibility
Get IsFilterEnabled
Set these settings to new filter
And that should copy your view filters.
Final Snippet:
def get_view_by_name(view_name):
"""Get Views by exact Name."""
views = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Views).WhereElementIsNotElementType().ToElements()
dict_views = {view.Name:view for view in views}
if view_name not in dict_views:
print('Could not find view by name: {}'.format(view_name))
else:
return dict_views[view_name]
view_from = get_view_by_name('HG_UG 1_OK FFB')
view_to = get_view_by_name('HG_UG 1_OK FFB Copy 1')
filter_ids = view_from.GetOrderedFilters()
filters = [doc.GetElement(f_id) for f_id in filter_ids]
sel_filters = forms.SelectFromList.show(filters,
multiselect=True,
name_attr='Name',
button_name='Select View Filters')
if not sel_filters:
forms.alert("No View Filters were Selected.\n"
"Please Try Again.", exitscript=True)
with Transaction(doc, 'Copy ViewFilters') as t:
t.Start()
for view_filter in filters:
overrides = view_from.GetFilterOverrides(view_filter.Id)
view_to.SetFilterOverrides(view_filter.Id, overrides)
visibility = view_from.GetFilterVisibility(view_filter.Id)
enable = view_from.GetIsFilterEnabled(view_filter.Id)
view_to.SetFilterVisibility(view_filter.Id, visibility)
view_to.SetIsFilterEnabled(view_filter.Id, enable)
t.Commit()