Importer des annotations Dwfx via l'API Revit
#DynamoBIM #Revit #Dwfx#Python #DesignReview
if this article is not in your language, use the Google Translate
widget ⬈ (bottom of page for Mobile version ⬇)
Qu'il soit utilisé comme support de synthèse, ou comme de contrôle ou d'autocontrôle avant publication, même si la tendance est le cloud (ACC), le dwfx a encore sa place dans la collaboration.
l'API Revit permet d'importer les annotations à partir d'un dwfx avec la méthode suivante :
Link Method (String, DWFImportOptions)
avec comme option une instance du constructeur DWFImportOptions
à noter qu'il est seulement possible d'importer des annotations Dwfx de Feuilles (pas de Vues)
le seul problème, c'est qu'il faut passer en arguments la liste des Feuilles concerne par le Dwfx 😕
le seul problème, c'est qu'il faut passer en arguments la liste des Feuilles concerne par le Dwfx 😕
La solution consiste à examiner le Dwfx et chercher les noms des Feuilles Revit dans
celui-ci.
Le Dwfx est effectivement une archive ; en analysant son contenu, on peut extraire les noms des feuilles du Dwfx à partir d'un fichier XML
manifest.xml
que l'on peut parser.
Voici donc un exemple de code Python pour passer en arguments la bonne
liste des vues
le code est compatible avec tous les moteurs Python
# Load the Python Standard and DesignScript Libraries
import clr
import re
import sys
import System
pyEngineName = sys.implementation.name
from System.Collections.Generic import List
clr.AddReference('RevitAPI')
import Autodesk
import Autodesk.Revit.DB as DB
clr.AddReference('System.Windows.Forms')
import System.Windows.Forms
from System.Windows.Forms import OpenFileDialog, DialogResult
clr.AddReference('RevitAPIUI')
from Autodesk.Revit.UI import TaskDialog, TaskDialogIcon
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Transactions import TransactionManager
from RevitServices.Persistence import DocumentManager
doc = DocumentManager.Instance.CurrentDBDocument
import zipfile
import xml.etree.ElementTree as ET
def get_xml_namespace(xmlelement):
m = re.match(r'\{.*\}', xmlelement.tag)
return m.group(0) if m else ''
lst_annotids = []
openFileDialog = OpenFileDialog()
openFileDialog.Filter = "Dwfx files (*.dwfx)|*.dwfx|All files (*.*)|*.*"
openFileDialog.RestoreDirectory = True
openFileDialog.Title = "Select dwfx file"
#
if openFileDialog.ShowDialog() == DialogResult.OK:
list_ViewSheet = List[DB.ViewSheet](DB.FilteredElementCollector(doc).OfClass(DB.ViewSheet).ToElements())
sheetViewIds = List[DB.ElementId]()
filePath = openFileDialog.FileName
import_dwfx = System.IO.Path.GetFileName(filePath)
# Start Read dwfx file with zipfile
lst_no_associate_views = []
with zipfile.ZipFile(filePath, mode="r") as archive:
for info in archive.infolist():
if info.filename.endswith("manifest.xml"):
# Read and parse the Xml content
xmlcontent = archive.read(info.filename)
root = ET.fromstring(xmlcontent)
xml_namespace = get_xml_namespace(root)
allSection = root.findall(".//{}Section".format(xml_namespace))
for sectionNode in allSection:
#
full_title = sectionNode.get("title")
if full_title is not None :
#
allressource = sectionNode.findall(".//{}Resource".format(xml_namespace))
for ressourceNode in allressource:
role = ressourceNode.get("role")
if "markup object" in role:
# find the good sheet with Title property
filter_title = System.Predicate[System.Object](lambda v : v.Title == full_title)
viewRvt = list_ViewSheet.Find(filter_title)
if viewRvt is not None:
sheetViewIds.Add(viewRvt.Id)
view_ids_founded = True
break
else:
lst_no_associate_views.append(full_title)
# sort by Title Name (same UI revit)
sheetViewIds = sorted(sheetViewIds, key = lambda xId : doc.GetElement(xId).Title)
sheetViewIds = List[ElementId](sheetViewIds)
print(sheetViewIds)
print(lst_no_associate_views)
# create a warning if dwfx has no associated views
if len(lst_no_associate_views) > 0:
# reset sheetViewIds
sheetViewIds = List[DB.ElementId]()
dialog = TaskDialog("Erreur Views")
dialog.MainInstruction = "Unassociated views, delete views (or rename correctly from Revit Sheets) below on the dwfx, save, then restart"
dialog.MainContent = "View to Delete or Rename on dwfx :\n\n-{}".format("-\n".join(lst_no_associate_views))
dialog.MainIcon = TaskDialogIcon.TaskDialogIconWarning
#
if pyEngineName == "ironpython":
dialog.Show()
else:
# unfortunately, the Show() method does not work with PythonNet2.5/CPython3 (overload issue).
from System.Reflection import BindingFlags
arguments = []
clr.GetClrType(dialog.GetType()).InvokeMember("Show", BindingFlags.InvokeMethod , None, dialog, arguments)
#
if len(sheetViewIds) > 0:
# Import dwfx and get annotation element IDs
TransactionManager.Instance.EnsureInTransaction(doc)
ops = DB.DWFImportOptions(sheetViewIds)
lst_annotids = doc.Link(filePath, ops)
TransactionManager.Instance.TransactionTaskDone()
doc.Regenerate()
# get some information
lstAnnot = [doc.GetElement(xId) for xId in lst_annotids]
lstAnnot = [[doc.GetElement(x.OwnerViewId),x.get_Parameter(DB.BuiltInParameter.MARKUPS_LABEL).AsString()] for x in lstAnnot]
OUT = lstAnnot
Bonnes fêtes de fin d'années et Bonne Année à tous ceux qui liront l'article à partir du 1ᵉʳ janvier
Bon, j'ai des corrections à faire moi 😊
Edit 11/2024
grosse mise en à jour de Design Review HotFix 8
grosse mise en à jour de Design Review HotFix 8
0 commentaires:
Enregistrer un commentaire