28 juil. 2020

[Dynamo += Python] Ajouter ou Modifier un filtre dans une nomenclature




Travailler avec les filtres de nomenclature avec l'API Revit peut s'apparenter à première vue un peu à jeu de piste.

Pour y parvenir il faut utiliser plusieurs Classesvoici les grandes lignes des étapes à suivre.
  • pour ajouter un filtre de nomenclature
ViewSchedule (instance) → ScheduleDefinition → GetSchedulableFields → AddField → AddFilter → SetFilter

  • pour modifier un filtre de nomenclature
ViewSchedule (instance) → ScheduleDefinition → GetFilter → SetFilter


Détaillons avec un exemple.
Aux exemples que l'on peut trouver sur la toile, en voici un de plus en Python avec l'ajout ou la modification d'un filtre booléen





Le code Python ci-dessous modifie la valeur du filtre ayant pour paramètre "Nom du Parametre Booleen" avec la fonction finderFilter,  si le filtre n'est pas présent il est créé avec la fonction createFilter puis la valeur booléenne est établie.
  
import clr
import sys
import System

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


def findFilter(paraName, scheduleDef):
    filterCount = scheduleDef.GetFilterCount()
    for idx_filter in range(filterCount):
        schedFilter = scheduleDef.GetFilter(idx_filter)
        field_Id = schedFilter.FieldId 
        field = scheduleDef.GetField(field_Id)
        if field.GetName() == paraName:
            return idx_filter, schedFilter, field
    return None, None, None 
    
def createField(paraName, scheduleDef):
    #sub foncion
    def checkField(fieldToAdd):
        fieldIds = scheduleDef.GetFieldOrder()  
        for fieldId in fieldIds:
            field = scheduleDef.GetField(fieldId)
            if field.HasSchedulableField and field.GetSchedulableField() == fieldToAdd:
                return fieldId, field
        return None, None
    #
    # main function ##
    #
    fieldToAdd = None
    #get GetSchedulableField by Name
    lstAvailbleField = scheduleDef.GetSchedulableFields()
    for schField in lstAvailbleField:
        if schField.GetName(doc) == paraName:
            fieldToAdd = schField
            break
    #check if field is already added and find the corresponding fieldId
    fieldId, field = checkField(fieldToAdd)
    if fieldId is not None:
        return fieldId, field
    else:   
        #if not found add the corresponding field
        scheduleDef.AddField(ScheduleFieldType.Instance, fieldToAdd.ParameterId )
        doc.Regenerate()
        #then return the corresponding fieldId
        return checkField(fieldToAdd)
        
toDoList = lambda x : x if hasattr(x, '__iter__') else [x]

lstView = toDoList(UnwrapElement(IN[0]))
nameParaFilter = IN[1]
valueBool = IN[2]

TransactionManager.Instance.EnsureInTransaction(doc)
for v in lstView:
    if v.ViewType == ViewType.Schedule:
        scheduleDef = v.Definition 
        # get index, schedule filter and field
        idx_filter, schedFilter, field = findFilter(nameParaFilter, scheduleDef)
        if field is not None:
            if valueBool:
                schedFilter.SetValue(1)
            else:
                schedFilter.SetValue(0)
            scheduleDef.SetFilter(idx_filter, schedFilter)
        else:
            fieldId, field = createField(nameParaFilter, scheduleDef)
            if valueBool:
                newSchFilter = ScheduleFilter(fieldId, ScheduleFilterType.Equal, 1)
            else:
                newSchFilter = ScheduleFilter(fieldId, ScheduleFilterType.Equal, 0)     
            scheduleDef.AddFilter(newSchFilter)
        # hide the Field
        field.IsHidden  = True
TransactionManager.Instance.TransactionTaskDone()       
    
OUT = lstView
  • Un autre exemple pour modifier la mise en forme (Police, etc...)
 
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

#import Revit API
clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *

clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument

toFirst = lambda x : x.Item[0] if hasattr(x, "__iter__") else  x 
toList = lambda x : x if hasattr(x, "__iter__") else [ x ]
viewsSchedule = toList(UnwrapElement(IN[0]))
lineStyle = toFirst(UnwrapElement(IN[1]))

#create option for Override bottom Line
options = TableCellStyleOverrideOptions()
options.BorderLineStyle = False
options.BorderBottomLineStyle = True
options.BorderLeftLineStyle = False
options.BorderRightLineStyle = False
options.BorderTopLineStyle = False
#createTableStyle
tableStyle = TableCellStyle()
tableStyle.ResetOverride() 
tableStyle.SetCellStyleOverrideOptions(options)
tableStyle.BorderBottomLineStyle = lineStyle.GraphicsStyleCategory.Id

#Main
TransactionManager.Instance.EnsureInTransaction(doc)
for view in viewsSchedule:
	if view.ViewType == ViewType.Schedule:
		tableData = view.GetTableData()
		headerSect = tableData.GetSectionData(SectionType.Header)
		headerSect.SetCellStyle(tableStyle)
TransactionManager.Instance.TransactionTaskDone()	

OUT = viewsSchedule

0 commentaires:

Enregistrer un commentaire