14 mai 2023

[Dynamo+=Python] Un peu d'ordre dans les Filtres de Vue






Trier l'ordre des filtres de Vues ?

#ViewFilter #RevitAPI #DynamoBIM #order
if this article is not in your language, use the Google Translate widget ⬈ (bottom of page for Mobile version )


L'ordre des filtres de vue est crucial dans Revit, car il détermine la façon dont les éléments sont affichés dans la vue.

Cependant, la réorganisation des filtres de vue peut parfois être fastidieuse. Dans cet article, je vous propose comment utiliser Python et l'API Revit pour redéfinir rapidement l'ordre des filtres de vue dans Revit.

  • Présentation du script

Le script prend en entrée une ou plusieurs Vues, si aucune autre entrée est ajoutée avec cette configuration, l'ordre des filtres sera de type alphanumérique.



Si l'on souhaite un ordre autre qu'alphanumérique, une seconde entrée peut être ajoutée, avec une liste avec un ordre prédéfinie des noms de filtre de vues

Exemple avec un Gabarit de Vue



Exemple avec une Vue




Ici, j'utilise une classe Python (concept de la POO ) afin de regrouper différentes propriétés de filtres de vue au sein d'un même objet Python

Le code Python (fonctionne avec tous les moteurs Python)

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
Note: 
Depuis Revit 2021 il est possible obtenir le réel ordre des listes des filtres avec la méthode  GetOrderedFilters()


0 commentaires:

Enregistrer un commentaire