Try this version
- EDIT 29/04/2023 (code fixed for CPython3)
- EDIT 29/04/2023 (code fixed for _alphanum_key)
import clr
import sys
import re
import System
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *
import Autodesk.Revit.DB as DB
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
uidoc = uiapp.ActiveUIDocument
app = uiapp.Application
sdkNumber = int(app.VersionNumber)
class FilterUtils():
def __init__(self, view):
self._view = view
@property
def FilterIds(self):
filterIds = self._view.GetFilters()
return filterIds
@property
def FilterNames(self):
return [doc.GetElement(x).Name for x in self.FilterIds]
@property
def FilterOverrides(self):
return [self._view.GetFilterOverrides(x) for x in self.FilterIds]
@property
def FilterVisibity(self):
return [self._view.GetFilterVisibility(x) for x in self.FilterIds]
@property
def FilterEnabled(self):
if sdkNumber > 2020:
return [self._view.GetIsFilterEnabled(x) for x in self.FilterIds]
else:
return [None] * len(self.FilterIds)
def _alphanum_key(self):
convert = lambda text: int(text) if text.isdigit() else text.lower()
# apply the function only at the 1st items
alphanum_key = lambda key: [convert(c) for c in re.split('([0-9]+)', key[0])]
return alphanum_key
def SetFilterOrder(self, lst_newOrder_Name = []):
"""
set order by input list filter Name -> lst_newOrder_Name
if lst_newOrder_Name is empty -> set order by FilterName
reurn new order filter name
"""
lst_datafilters = list(zip(self.FilterNames, self.FilterIds, self.FilterOverrides, self.FilterVisibity, self.FilterEnabled))
if len(lst_newOrder_Name) == len(lst_datafilters):
lst_datafilters.sort(key = lambda x : lst_newOrder_Name.index(x[0]))
else:
lst_datafilters.sort(key = self._alphanum_key())
#
# remove filters
for i in self.FilterIds:
self._view.RemoveFilter(i)
#
# set the new order
for f_Name, fId, overrideVG, visuVG, fiEnabled in lst_datafilters:
self._view.AddFilter(fId)
self._view.SetFilterOverrides(fId, overrideVG)
self._view.SetFilterVisibility(fId, visuVG)
if fiEnabled is not None:
self._view.SetIsFilterEnabled(fId, fiEnabled)
return [x[0] for x in lst_datafilters]
toList = lambda x : x if hasattr(x, '__iter__') else [x]
lstViews = toList(UnwrapElement(IN[0]))
try:
lst_newOrder_Name = toList(IN[1])
except:
lst_newOrder_Name = []
TransactionManager.Instance.EnsureInTransaction(doc)
for v in lstViews:
objFi = FilterUtils(v)
newOrderFilters = objFi.SetFilterOrder(lst_newOrder_Name)
TransactionManager.Instance.TransactionTaskDone()
OUT = newOrderFilters