Hi @c.poupin,
it’s possible to reorder naturally by name the existing filters in view ? . Thanks in advance
Cheers
[Edit Moderation]
related topic
Hi @c.poupin,
it’s possible to reorder naturally by name the existing filters in view ? . Thanks in advance
Cheers
[Edit Moderation]
related topic
Hi @paris
I add a method, you can try this
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 SetFilterOnTop(self, filterName):
try:
indexFilter = self.FilterNames.index(serachFilter)
except ValueError:
indexFilter = None
#
older = self.FilterNames[:]
if indexFilter is not None and len(self.FilterIds) > 0:
datafilters = zip(self.FilterIds, self.FilterOverrides, self.FilterVisibity, self.FilterEnabled)
datafilters.insert(0, datafilters.pop(indexFilter))
#
for i in self.FilterIds:
self._view.RemoveFilter(i)
#
for fId, overrideVG, visuVG, fiEnabled in 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 self.FilterNames
def __natural_sort(self, l):
convert = lambda text: int(text) if text.isdigit() else text.lower()
alphanum_key = lambda key: [convert(c) for c in re.split('([0-9]+)', key)]
return sorted(l, key=alphanum_key)
def SetNaturalOrder(self):
lst_datafilters = zip(self.FilterNames, self.FilterIds, self.FilterOverrides, self.FilterVisibity, self.FilterEnabled)
lst_datafilters.sort(key = lambda x : self.__natural_sort(x[0]))
#
for i in self.FilterIds:
self._view.RemoveFilter(i)
#
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 self.FilterNames
toList = lambda x : x if hasattr(x, '__iter__') else [x]
lstViews = toList(UnwrapElement(IN[0]))
try:
serachFilter = IN[1]
except:
serachFilter = ""
TransactionManager.Instance.EnsureInTransaction(doc)
for v in lstViews:
objFi = FilterUtils(v)
newOrderFilters = objFi.SetNaturalOrder()
TransactionManager.Instance.TransactionTaskDone()
OUT = newOrderFilters
Hi @c.poupin thank-you very much for your answer, what I have to feed into IN[1] ? the sorted list name choised?
Thanks in advance
Cheers
Try this version
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
Hi @c.poupin great, thanks for your answer it works as expected, the filters into views is now ordered but in the output of python node, the “newOrderFilters” is the old older
Hi,
thanks, I updated the code here
The script I made with dynamo didn’t work. While it was fine in the Dynamo window, the order in the template did not change.
![Dynamo Sort Names|690x176]
Template Name List Sort.dyn (16.3 KB)
Hi,
your dyn is not attached to your post
hi,
how can i use this script for section and 3d view?
Template Name List Sort.dyn (21.4 KB)
Script Kodu.txt (2.9 KB)
Hi @srknkklc
here a workaround
Python Script to get View Template and filters associated
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('RevitNodes')
import Revit
clr.ImportExtensions(Revit.Elements)
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)
def get_FiltersName(v):
lstFilterName = [doc.GetElement(fid).Name for fid in v.GetFilters()]
return ueWrapper.Invoke(None, (v, False)), lstFilterName
toList = lambda x : x if hasattr(x, '__iter__') else [x]
lst3DViews = toList(UnwrapElement(IN[0]))
ueWrapper = next((m for m in clr.GetClrType(Revit.Elements.ElementWrapper)\
.GetMethods() if m.Name == "Wrap"), None)
lst3dTemplate = [doc.GetElement(v.ViewTemplateId ) for v in lst3DViews]
OUT = [get_FiltersName(v) for v in lst3dTemplate]
hi,
Thank you for your interest. I tried what you did but it didn’t work for me. I want it to do the sorting in Section and 3d filter.
Is it possible to sort in plan section and 3d filter in one go. You can see the latest status in the attachment.
Template Name List Sort - 29.04.2023.dyn (24.9 KB)
If you want to sort by Name filters, put directly the list of view (there is an function to do that inside)
Python Script | ViewTemplate
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('RevitNodes')
import Revit
clr.ImportExtensions(Revit.Elements)
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)
def toList(x):
if isinstance(x, list):
return x
elif hasattr(x, "GetType") and x.GetType().GetInterface("IEnumerable") is not None:
return x
else :
return [x]
lst3DViews = toList(UnwrapElement(IN[0]))
ueWrapper = next((m for m in clr.GetClrType(Revit.Elements.ElementWrapper)\
.GetMethods() if m.Name == "Wrap"), None)
lst3dTemplate = [doc.GetElement(v.ViewTemplateId) for v in lst3DViews]
OUT = [ueWrapper.Invoke(None, (v, False)) for v in lst3dTemplate]
Python Script | sort Filters (code fixed)
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
Thank you c.poupin,
good working Code
Good day, I am wondering, is it ok that the old filtering ordering is changed. I tried this script but I should have the exact old filter ordering and new filter on the top of filter list, correct? but new filter goes on top but another filters set also maybe with sorting. But I would like to add new filter on top without changing previous filters ordering
Hi @viktornrozalite ,
here an example
create filter_v2.dyn (24.6 KB)
Note : this node does not return the ordered filters
thank for response, Is it means I can get ordered filters if using view template?
GetOrderedFilters returns all ordered filters for view, thanks. Not sure about why use code inside code block node