Comment gérer les états des sous projets en Python avec l'API Revit ?
Suite à une idée d'amélioration, voici un exemple de script permettant de gérer l'ouverture et la fermeture des sous-projets d'une maquette liée tout-en-IronPython 😁 (avec une interface Winform)
Le seul moyen à ce jour pour changer les états des sous-projets d'une maquette liée via l'API Revit c'est de rechargé le lien avec une configuration via la méthode LoadFrom().
Dans l'exemple ci-après, on crée une configuration par défaut où les sous projets "utilisateur" sont fermés. Puis on ouvre ceux que l'on souhaite avec la méthode Open()
WorksetConfiguration(WorksetConfigurationOption.CloseAllWorksets)
Pour ceux qu'ils souhaitent ce script peut être encore amélioré avec l'intégration d'un TreeNode regroupant l'ensemble des maquettes liées (mode collaboratif activé), ou chaque nœud principal serait une maquette liée.
J'en profite pour y introduire un bref exemple de gestion multi-langage sur une Interface User grâce à l'API Revit
if app.Language == Autodesk.Revit.ApplicationServices.LanguageType.French
import clr
import sys
#import Revit API
clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *
#import net library
clr.AddReference('System')
from System.Collections.Generic import List
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
#Get Important vars
doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
app = uiapp.Application
clr.AddReference('System.Drawing')
clr.AddReference('System.Windows.Forms')
import System.Drawing
import System.Windows.Forms
from System.Drawing import *
from System.Windows.Forms import *
class WksetLnkUtils(Form):
def __init__(self):
rvtLinkInst = FilteredElementCollector(doc).OfClass(RevitLinkInstance)
self._dictRvtInstance = {}
for x in rvtLinkInst:
_lkdoc = x.GetLinkDocument()
if _lkdoc.IsWorkshared:
self._dictRvtInstance[x.Name] = x
self._dictWkset = {}
self.rvtRvtlinkType = None
self.out = None
self.InitializeComponent()
def InitializeComponent(self):
self._groupBox1 = System.Windows.Forms.GroupBox()
self._checkedListBox1 = System.Windows.Forms.CheckedListBox()
self._buttonOpen = System.Windows.Forms.Button()
self._buttonClose = System.Windows.Forms.Button()
self._comboBoxRvtLink = System.Windows.Forms.ComboBox()
self._groupBox2 = System.Windows.Forms.GroupBox()
self._groupBox1.SuspendLayout()
self._groupBox2.SuspendLayout()
self.SuspendLayout()
#
# groupBox1
self._groupBox1.Controls.Add(self._checkedListBox1)
self._groupBox1.Location = System.Drawing.Point(30, 123)
self._groupBox1.Name = "groupBox1"
self._groupBox1.Size = System.Drawing.Size(361, 423)
self._groupBox1.TabIndex = 0
self._groupBox1.TabStop = False
self._groupBox1.Text = "Select Workset"
#
# checkedListBox1
self._checkedListBox1.FormattingEnabled = True
self._checkedListBox1.Items.Clear()
self._checkedListBox1.Location = System.Drawing.Point(16, 42)
self._checkedListBox1.Name = "checkedListBox1"
self._checkedListBox1.Size = System.Drawing.Size(326, 361)
self._checkedListBox1.TabIndex = 0
#
# buttonOpen
self._buttonOpen.Location = System.Drawing.Point(60, 560)
self._buttonOpen.Name = "buttonOpen"
self._buttonOpen.Size = System.Drawing.Size(300, 40)
self._buttonOpen.TabIndex = 1
if app.Language == Autodesk.Revit.ApplicationServices.LanguageType.French:
self._buttonOpen.Text = "Ouvrir les sous-projets selectionnés \n(les autres seront fermés)"
else:
self._buttonOpen.Text = "Open Selected Worksets (others will be close)"
self._buttonOpen.UseVisualStyleBackColor = True
self._buttonOpen.Click += self.ButtonOpenClick
#
# buttonClose
self._buttonClose.Location = System.Drawing.Point(60, 620)
self._buttonClose.Name = "buttonClose"
self._buttonClose.Size = System.Drawing.Size(300, 40)
self._buttonClose.TabIndex = 1
if app.Language == Autodesk.Revit.ApplicationServices.LanguageType.French:
self._buttonClose.Text = "Fermer les sous-projets selectionnés \n(les autres seront ouverts)"
else:
self._buttonClose.Text = "Close Selected Worksets (others will be open)"
self._buttonClose.UseVisualStyleBackColor = True
self._buttonClose.Click += self.ButtonCloseClick
#
# comboBoxRvtLink
self._comboBoxRvtLink.Items.AddRange(System.Array[System.Object](self._dictRvtInstance.keys()))
self._comboBoxRvtLink.FormattingEnabled = True
self._comboBoxRvtLink.Location = System.Drawing.Point(19, 41)
self._comboBoxRvtLink.Name = "comboBoxRvtLink"
self._comboBoxRvtLink.Size = System.Drawing.Size(323, 24)
self._comboBoxRvtLink.TabIndex = 2
self._comboBoxRvtLink.SelectedIndexChanged += self.ComboBoxRvtLinkSelectedIndexChanged
#
# groupBox2
self._groupBox2.Controls.Add(self._comboBoxRvtLink)
self._groupBox2.Location = System.Drawing.Point(30, 17)
self._groupBox2.Name = "groupBox2"
self._groupBox2.Size = System.Drawing.Size(361, 89)
self._groupBox2.TabIndex = 3
self._groupBox2.TabStop = False
self._groupBox2.Text = "Select Revit Link"
#
# MainForm
self.ClientSize = System.Drawing.Size(430, 700)
self.Controls.Add(self._groupBox2)
self.Controls.Add(self._buttonClose)
self.Controls.Add(self._buttonOpen)
self.Controls.Add(self._groupBox1)
self.Name = "WksetLnkUtils"
self.Text = "Manage linked model Worksets"
self._groupBox1.ResumeLayout(False)
self._groupBox2.ResumeLayout(False)
self.ResumeLayout(False)
def setLinkstatut(self, wksetsId):
if self.rvtRvtlinkType is not None:
#create WorksetConfiguration with CloseAllWorksets by default
wkstConfig = WorksetConfiguration(WorksetConfigurationOption.CloseAllWorksets)
lstWksetId = List[WorksetId](wksetsId)
wkstConfig.Open(lstWksetId)
loada = self.rvtRvtlinkType.LoadFrom(self.mpath, wkstConfig)
self.out = loada.LoadResult
wkstConfig.Dispose()
def ButtonOpenClick(self, sender, e):
wksetsId = [ self._dictWkset.get(wksetnam) for wksetnam in self._checkedListBox1.CheckedItems]
self.setLinkstatut(wksetsId)
def ButtonCloseClick(self, sender, e):
self.wksetsId = []
#get items are not checked for open others Worksets
setDiff = set(self._checkedListBox1.Items) - set(self._checkedListBox1.CheckedItems)
wksetsId = [ self._dictWkset.get(wksetnam) for wksetnam in setDiff]
self.setLinkstatut(wksetsId)
def ComboBoxRvtLinkSelectedIndexChanged(self, sender, e):
rvtLinkInstance = self._dictRvtInstance.get(sender.Text)
self.rvtRvtlinkType = doc.GetElement(rvtLinkInstance.GetTypeId())
_linkdoc = rvtLinkInstance.GetLinkDocument()
_worksetTable = _linkdoc.GetWorksetTable()
self.mpath = _linkdoc.GetWorksharingCentralModelPath()
lstPreview = WorksharingUtils.GetUserWorksetInfo(self.mpath)
self._dictWkset = {item.Name : _worksetTable.GetWorkset(item.Id).Id for item in lstPreview }
self._checkedListBox1.Items.Clear()
self._checkedListBox1.Items.AddRange(System.Array[System.Object](self._dictWkset.keys()))
objForm = WksetLnkUtils()
objForm.Show()
OUT = 0
Excellent. Je vais l'essayer de suite. Merci
RépondreSupprimerAdding
RépondreSupprimer# -*- coding: latin-1 -*-
and it works well in a pyrevit toolbar
Bonjour Cyril, excellent script! Quelles sont les modifications à faire pour que ce script fonctionne avec des maquettes hébergées sur le BIM360 (cloud)? De mon côté le script fonctionne seulement sur les maquettes sur un réseau "local". Merci!
RépondreSupprimerBonjour,
SupprimerActuellement je n'ai pas accès à BIM360, donc je ne sais
(je suppose qu'il faut utiliser la méthode 'LoadFrom Method (ExternalResourceReference, WorksetConfiguration)')
Je mettrai l'article à jour si le cas se présente