<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-4001721146719322746</id><updated>2026-11-11T03:58:31.665+01:00</updated><category term="DynamoBim"/><category term="Python"/><category term="IronPython"/><category term="Revit"/><category term="RevitAPI"/><category term="AutodeskExpertElite"/><category term="PythonNet"/><category term="Dynamo"/><category term="AutodeskCommunity"/><category term="CPython3"/><category term="PythonNet3"/><category term="BIM"/><category term="CPython"/><category term="Revit API"/><category term="WPF"/><category term="Pandas"/><category term="Vecteurs"/><category term="DataFrame"/><category term="DataTable"/><category term="DotNet"/><category term="DynamoDS API"/><category term="DynamoWin"/><category term="Excel"/><category term="Famille"/><category term="IFC"/><category term="IronPython3"/><category term="Linq"/><category term="PLINQ"/><category term="Produit Vectoriel"/><category term="PythonNetSerie"/><category term="Vectors"/><category term="contextManager"/><category term="module"/><category term="scipy"/><category term="Autocad"/><category term="Catégorie"/><category term="DesignReview"/><category term="Liste"/><category term="Nomenclatures"/><category term="PeriodicMode"/><category term="framework .Net"/><category term=".Net"/><category term=".Net Interface"/><category term="ACC"/><category term="APS"/><category term="Algorithme"/><category term="BIM360"/><category term="Barre de Progression"/><category term="Calque"/><category term="Chemins de Câble"/><category term="Courbe"/><category term="DWFx"/><category term="DWG"/><category term="DataSet"/><category term="Delaunay"/><category term="Design Review"/><category term="DoEvents"/><category term="Décorateur"/><category term="Euroclasses"/><category term="Export"/><category term="Filtres"/><category term="Fittting"/><category term="Formules"/><category term="Geometry"/><category term="Group"/><category term="Handler"/><category term="HorsSujetBIM"/><category term="IA"/><category term="IfcOpenShell"/><category term="IronPython2"/><category term="Lacing"/><category term="Lignes"/><category term="List"/><category term="MVVM"/><category term="NFC 15-100"/><category term="OLE"/><category term="OpenAI"/><category term="Package"/><category term="Parallal"/><category term="Parallèle"/><category term="Paramètres de Projet"/><category term="Polygon"/><category term="Revit &amp; Sélections"/><category term="Selection"/><category term="UltraLeap"/><category term="ViewFilter"/><category term="WinForm"/><category term="WorkSets"/><category term="alphashape"/><category term="logger"/><category term="logging"/><category term="olefile"/><category term="xml"/><category term="+="/><category term=".Net 8"/><category term=".Net API Inheritance"/><category term="2024"/><category term="2025"/><category term="3DView"/><category term="AVF"/><category term="Aggregate"/><category term="AlignedBoundingBox"/><category term="Annotations"/><category term="Aplatir"/><category term="Assembly"/><category term="Attestation de Conformité Verte"/><category term="Audio"/><category term="Autodesk.Revit.DB.Analysis"/><category term="AverageCurve"/><category term="BeautifulSoup"/><category term="Bilan de Puissance"/><category term="Binding"/><category term="Bitmap"/><category term="BoundingBox"/><category term="BrowserOrganization"/><category term="ByMinimum.Volume"/><category term="Cables"/><category term="Canalisation"/><category term="Chemin de cable"/><category term="Chute de tension"/><category term="Class"/><category term="Classe"/><category term="CleanText"/><category term="Collaboration"/><category term="Coller"/><category term="Commandes Vocales"/><category term="Compilation"/><category term="Construction"/><category term="Consuel"/><category term="Coordonnées"/><category term="Copier"/><category term="Coupe"/><category term="CropBox"/><category term="CrossProduct"/><category term="Curve"/><category term="DBSCAN"/><category term="DataGrid"/><category term="Debogage"/><category term="Debug"/><category term="Decorateur"/><category term="Deep Learning"/><category term="Dialux"/><category term="Dialux Evo"/><category term="Dispatcher"/><category term="DynamoCore"/><category term="ERP"/><category term="Eclairement"/><category term="ElementType.Name"/><category term="Enumerable"/><category term="Espace de Nom"/><category term="Event"/><category term="FacingOrientation"/><category term="Fenetre"/><category term="Filter"/><category term="FilteredElementCollector"/><category term="Flatten"/><category term="GC.Collect"/><category term="GenericZones"/><category term="GetBoundaryFaceInfo"/><category term="Graham"/><category term="Géométrie"/><category term="HTML"/><category term="HTTP request"/><category term="Hachures"/><category term="HandOrientation"/><category term="HelixToolKit"/><category term="HostFace"/><category term="IRVE"/><category term="IValueConverter"/><category term="ImportInstance"/><category term="Incendie"/><category term="Interfaces"/><category term="IsInside"/><category term="Json"/><category term="Keras"/><category term="LeapMotion"/><category term="Listes"/><category term="Listes imbriquées"/><category term="Lux"/><category term="Légendes"/><category term="Macro"/><category term="Mandelbrot"/><category term="Markdown"/><category term="Memory"/><category term="Microsoft"/><category term="Model Checker"/><category term="Namespace"/><category term="Net Core"/><category term="Nomenclature"/><category term="OpenXML"/><category term="Ouverture"/><category term="Parralelisme"/><category term="Point"/><category term="Points"/><category term="Polyligne"/><category term="Porte"/><category term="PowerBi"/><category term="PreviewImage"/><category term="Produit Scalaire"/><category term="Purge"/><category term="Python Nested List"/><category term="Python3"/><category term="RAG"/><category term="RPC"/><category term="Raccord"/><category term="Rapport"/><category term="Reflection"/><category term="Revit API 2027"/><category term="Revit version"/><category term="SQL"/><category term="Schedule"/><category term="ScheduleDefinition"/><category term="ScheduleField"/><category term="Script"/><category term="Section"/><category term="Serialization"/><category term="SharpDevellop"/><category term="Sorted"/><category term="SpatialElementGeometryCalculator"/><category term="Speech Recognition"/><category term="Surcharge Opérateurs"/><category term="Tensorflow"/><category term="Transform"/><category term="TransientDisplay"/><category term="Unicode"/><category term="UnicodeDecodeError"/><category term="Utilance"/><category term="VSCode"/><category term="Version"/><category term="ViewRange"/><category term="ViewSchedule"/><category term="ViewSection"/><category term="Visualiseur"/><category term="Vues"/><category term="WebRequest"/><category term="WebView2"/><category term="Word"/><category term="Zones HVAC"/><category term="Zones Système"/><category term="autocomplétion"/><category term="bs4"/><category term="clr"/><category term="colinear"/><category term="cosine_similarity"/><category term="cosinus"/><category term="dir"/><category term="dll"/><category term="documentation"/><category term="débogage"/><category term="exception handling"/><category term="import"/><category term="inspect"/><category term="level"/><category term="list level"/><category term="matplotlib"/><category term="members"/><category term="mshtml"/><category term="ndarray"/><category term="operator"/><category term="out Parameter"/><category term="pip"/><category term="pyc"/><category term="pyd"/><category term="requests"/><category term="shapely"/><category term="skLearn"/><category term="sympy"/><category term="tesseract"/><category term="timeit"/><category term="tkinter"/><category term="visibilité &amp; graphisme"/><category term="with"/><category term="Électricité"/><title type='text'>VoltaDynaBim</title><subtitle type='html'>De l&#39;électron à l&#39;octet&#xa;</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='https://voltadynabim.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/4001721146719322746/posts/default?max-results=3&amp;redirect=false'/><link rel='alternate' type='text/html' href='https://voltadynabim.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='https://www.blogger.com/feeds/4001721146719322746/posts/default?start-index=4&amp;max-results=3&amp;redirect=false'/><author><name>Cyril</name><uri>http://www.blogger.com/profile/08389811365235224682</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgY3Iz0xq8QpQu6njnL6IyeBXjbJyBFxD1nsxDcqUHlCs3yQZih7HlcLEre3RYjOSPnDg544905lHz4K6SHzbXgmdITwUktyM_FTkcYSINI0wkNhXcYX_4i9Kx4176Mxm4/s113/1608331968791.jfif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>127</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>3</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-4001721146719322746.post-7759107225784895110</id><published>2026-10-25T16:22:54.240+01:00</published><updated>2026-10-25T16:26:00.660+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="AutodeskCommunity"/><category scheme="http://www.blogger.com/atom/ns#" term="AutodeskExpertElite"/><category scheme="http://www.blogger.com/atom/ns#" term="Pandas"/><category scheme="http://www.blogger.com/atom/ns#" term="PythonNet3"/><category scheme="http://www.blogger.com/atom/ns#" term="WebView2"/><category scheme="http://www.blogger.com/atom/ns#" term="WPF"/><title type='text'>[Dynamo += Python] WPF + WebView2</title><content type='html'>&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
  &lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhw4DZ7L79KbG8Ui4NtWzMsH491o2pR0fEOg6sGm7VHN8j_znjhsqOuR23OVsXdo8A-0KWf8EWW-UV_ZvQpijmE7l1tIQTnjiCJfeBjqWSUeUAvVZAtBK2L-d-PkiglAHuMv0jVf2ZG5FBlai9N7NWLFmuqEg8_roYuEW8Gbzg2OK95v8gOQe2wFuwYVYba/s1536/14f9cf30-f956-47b0-8b14-770a5b4ab6ee.jpg&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1024&quot; data-original-width=&quot;1536&quot; height=&quot;266&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhw4DZ7L79KbG8Ui4NtWzMsH491o2pR0fEOg6sGm7VHN8j_znjhsqOuR23OVsXdo8A-0KWf8EWW-UV_ZvQpijmE7l1tIQTnjiCJfeBjqWSUeUAvVZAtBK2L-d-PkiglAHuMv0jVf2ZG5FBlai9N7NWLFmuqEg8_roYuEW8Gbzg2OK95v8gOQe2wFuwYVYba/w400-h266/14f9cf30-f956-47b0-8b14-770a5b4ab6ee.jpg&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: georgia; font-size: large;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
  &lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;Comment utiliser WebView2 dans une interface WPF avec PythonNet3&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;div&gt;
  &lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;#DynamoBIM #Revit #Python #RevitAPI #WPF #WebView2&amp;nbsp;
    #Pandas&amp;nbsp;#AutodeskExpertElite #AutodeskCommunity&amp;nbsp;&lt;a href=&quot;https://www.autodesk.com/expert-elite/&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot; target=&quot;_blank&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;50&quot; data-original-width=&quot;50&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEj3-npK4uFyHO9Jdk1NzGPoAjxdblUqzui38L8IBpDGyX0dDTXo3OBnvhvS6oVUjAG6kfD7A_qqKaQjE8v28_wy5vmOy5U9kZPzONBbbMdor19FAtuGqqbKxAn9OG44-MxLgH-XbEhq5xFuNxMUjUy8oJTZkmfy5sMt_lkdL1LqS0jmkFH7ojjLqzN5vf73=s16000&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;
  &lt;div style=&quot;text-align: right;&quot;&gt;
    &lt;span style=&quot;color: #2b00fe; font-family: georgia; font-size: medium;&quot;&gt;&lt;i&gt;if this article is not in your language, use the Google Translate
        widget ⬈ (&lt;a href=&quot;#bottom&quot;&gt;bottom of page for Mobile version&lt;span&gt; &lt;/span&gt;&lt;/a&gt;&lt;a href=&quot;#bottom&quot;&gt;⬇&lt;/a&gt;)&lt;/i&gt;&lt;/span&gt;
  &lt;/div&gt;
  &lt;br /&gt;&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
  &lt;span style=&quot;color: red; font-family: georgia; font-size: medium;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;/div&gt;
&lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;Savez-vous que l&#39;assembly &lt;code class=&quot;nocode&quot; style=&quot;background: rgb(240, 240, 240); border-radius: 3px; border: 1px solid rgb(208, 208, 208); font-family: courrier; font-size: 17.3333px; padding-left: 2px; padding-right: 2px; text-align: justify;&quot;&gt;Microsoft.Web.WebView2.Core&lt;/code&gt; est disponible dans le
  contexte Dynamo ? , ce qui permet en conséquence d&#39;utiliser&amp;nbsp;WebView2 dans
  vos interfaces WPF.&lt;/span&gt;&lt;div&gt;
  &lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
  &lt;ul style=&quot;text-align: left;&quot;&gt;
    &lt;li&gt;
      &lt;span style=&quot;color: #2b00fe; font-family: georgia; font-size: medium;&quot;&gt;&lt;u&gt;Explication&lt;/u&gt;&lt;/span&gt;
    &lt;/li&gt;
  &lt;/ul&gt;
&lt;/h3&gt;
&lt;div&gt;
  &lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;&lt;div&gt;
      Par rapport à &lt;code class=&quot;nocode&quot; style=&quot;background: rgb(240, 240, 240); border-radius: 3px; border: 1px solid rgb(208, 208, 208); font-family: courrier; font-size: 17.3333px; padding-left: 2px; padding-right: 2px; text-align: justify;&quot;&gt;WebBrowser&lt;/code&gt; (obsolète), &lt;code class=&quot;nocode&quot; style=&quot;background: rgb(240, 240, 240); border-radius: 3px; border: 1px solid rgb(208, 208, 208); font-family: courrier; font-size: 17.3333px; padding-left: 2px; padding-right: 2px; text-align: justify;&quot;&gt;WebView2&lt;/code&gt; peut sembler plus complexe à
      programmer, mais il offre la puissance, la sécurité et la compatibilité
      totale d&#39;un moteur Web moderne (Chromium).
      &lt;br /&gt;
      &lt;div&gt;&lt;br /&gt;&lt;/div&gt;
    &lt;/div&gt;
    &lt;div&gt;&lt;br /&gt;&lt;/div&gt;
    &lt;div&gt;La mise en œuvre de WebView2 nécessite de gérer plusieurs étapes.&lt;/div&gt;
    &lt;div style=&quot;text-align: left;&quot;&gt;
      &lt;ol style=&quot;text-align: left;&quot;&gt;
        &lt;li&gt;Créer ou récupérer un &lt;code class=&quot;nocode&quot; style=&quot;background: rgb(240, 240, 240); border-radius: 3px; border: 1px solid rgb(208, 208, 208); font-family: courrier; font-size: 17.3333px; padding-left: 2px; padding-right: 2px; text-align: justify;&quot;&gt;CoreWebView2Environment&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;Initialiser le contrôle de façon asynchrone.&lt;/li&gt;&lt;li&gt;Attendre que le moteur soit chargé via&amp;nbsp;&lt;code class=&quot;nocode&quot; style=&quot;background: rgb(240, 240, 240); border-radius: 3px; border: 1px solid rgb(208, 208, 208); font-family: courrier; font-size: 17.3333px; padding-left: 2px; padding-right: 2px; text-align: justify;&quot;&gt;CoreWebView2InitializationCompleted&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;Charger le HTML.&lt;/li&gt;&lt;li&gt;Déclarer / Gérer les événements JavaScript/.NET &lt;br /&gt;(création d&#39;un pont via
            &lt;code class=&quot;nocode&quot; style=&quot;background: rgb(240, 240, 240); border-radius: 3px; border: 1px solid rgb(208, 208, 208); font-family: courrier; font-size: 17.3333px; padding-left: 2px; padding-right: 2px; text-align: justify;&quot;&gt;CoreWebView2.WebMessageReceived&lt;/code&gt;).&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;/span&gt;&lt;p style=&quot;text-align: left;&quot;&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;Avec WebView2, nous devons attendre que CoreWebView2 soit prêt. Ce
      surcoût de code vient du cycle de vie plus explicite du navigateur.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;&lt;span&gt;En revanche, une fois le pont configuré, nous disposons d&#39;une interface
        plus moderne et plus flexible.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;&lt;span&gt;L&#39;événement JavaScript&amp;nbsp;&lt;code class=&quot;nocode&quot; style=&quot;background: rgb(240, 240, 240); border-radius: 3px; border: 1px solid rgb(208, 208, 208); font-family: courrier; font-size: 17.3333px; padding-left: 2px; padding-right: 2px; text-align: justify;&quot;&gt;chrome.webview.postMessage(...)&lt;/code&gt;&amp;nbsp;envoie un &quot;message&quot; à
        Python/.NET. En retour, .NET peut exécuter du JavaScript ou envoyer un
        message à la page. Cela facilite la création d&#39;une interface web pilotée
        par Revit.&lt;/span&gt;
    &lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;/p&gt;
  &lt;h3 style=&quot;text-align: left;&quot;&gt;
    &lt;ul style=&quot;text-align: left;&quot;&gt;
      &lt;li&gt;
        &lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;&lt;b&gt;&lt;u&gt;Exemple&lt;/u&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/h3&gt;
  &lt;p style=&quot;text-align: left;&quot;&gt;
    &lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;&lt;span&gt;Voici un exemple avec un DataFrame Pandas et la bibliothèque open-source
      de visualisation de données Plotly.&lt;/span&gt;
  &lt;/span&gt;&lt;/p&gt;
  &lt;p style=&quot;text-align: left;&quot;&gt;
    &lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;&lt;span&gt;Nous passons ici par une &lt;/span&gt;&lt;a href=&quot;https://voltadynabim.blogspot.com/2023/08/dynamo-python-pandas-dataframe-extension.html&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;classe d&#39;extension Pandas&lt;/a&gt;&lt;span&gt;
      pour créer des propriétés dynamiques d&#39;un DataFrame, puis les afficher dans une fenêtre WPF.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;&lt;br /&gt;vidéo&lt;/span&gt;
  &lt;/p&gt;
  &lt;iframe allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; allowfullscreen=&quot;&quot; frameborder=&quot;0&quot; height=&quot;400&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; src=&quot;https://www.youtube.com/embed/qMc-VBNH_HU?si=nQ7LU3BGuozGWw8Q&quot; title=&quot;YouTube video player&quot; width=&quot;640&quot;&gt;&lt;/iframe&gt;
  &lt;p&gt;
    &lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;.&lt;br /&gt;&lt;/span&gt;
  &lt;/p&gt;
&lt;/div&gt;
&lt;div id=&quot;content-spoiler&quot;&gt;
&lt;button&gt;Code Spoiler&lt;/button&gt;&lt;/div&gt;
&lt;div id=&quot;spoilerpanel&quot;&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;font size=&quot;2.5pt&quot;&gt;
import clr
import sys
import System
#import net library
from System import Array
from System.Collections.Generic import List, IList, Dictionary

from System import Environment
from System.IO import Path, Directory
from System import Action
from System.Threading.Tasks import Task
#import Revit API
clr.AddReference(&#39;RevitAPI&#39;)
import Autodesk
from Autodesk.Revit.DB import *
import Autodesk.Revit.DB as DB
#import specify namespace
from Autodesk.Revit.DB.Electrical import *

clr.AddReference(&#39;RevitAPIUI&#39;)
import Autodesk.Revit.UI as RUI
from Autodesk.Revit.UI import *


#import transactionManager and DocumentManager (RevitServices is specific to Dynamo)
clr.AddReference(&#39;RevitServices&#39;)
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
uidoc = uiapp.ActiveUIDocument

clr.AddReference(&quot;System.Core&quot;)
clr.ImportExtensions(System.Linq)

clr.AddReference(&quot;System.Reflection&quot;)
from System.Reflection import BindingFlags

clr.AddReference(&quot;System.Xml&quot;)
clr.AddReference(&quot;PresentationFramework&quot;)
clr.AddReference(&quot;System.Xml&quot;)
clr.AddReference(&quot;PresentationCore&quot;)
clr.AddReference(&quot;System.Windows&quot;)
import System.Windows.Controls 
from System.Windows.Controls import *
import System.Windows.Controls.Primitives 
from System.Collections.Generic import List
from System.IO import StringReader
from System.Xml import XmlReader
from System.Windows import LogicalTreeHelper 
from System.Windows.Markup import XamlReader, XamlWriter
from System.Windows import Window, Application
from System.Windows.Media.Imaging import BitmapCacheOption, BitmapCreateOptions, TransformedBitmap
from System.Windows.Media import ScaleTransform
from System.Windows import Application, WindowState

clr.AddReference(&quot;Microsoft.Web.WebView2.Core&quot;)
from Microsoft.Web.WebView2.Core import CoreWebView2Environment

import os
import tempfile
import time
import json
import traceback
import pandas as pd
import re
import plotly.express as px
import plotly.graph_objects as go


APPDATADIR = Environment.GetFolderPath( Environment.SpecialFolder.LocalApplicationData)


class MainForm(Window):
    __namespace__ = &quot;Dynamo.PandasViewer_WxeZ74&quot;
    #
    init_htmlDf = &quot;&quot;&quot;\
        &amp;lt;html&amp;gt;
        &amp;lt;head&amp;gt;
        &amp;lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=9&quot;&amp;gt;
        &amp;lt;style&amp;gt; 
          table, th, td {font-size:10pt; border:1px solid black; border-collapse:collapse; text-align:left;}
          th, td {padding: 5px;}
          tr:nth-child(even) {background: #E0E0E0;}
          tr:hover {background: silver; cursor: pointer;}
        &amp;lt;/style&amp;gt;
        &amp;lt;/head&amp;gt;
          &amp;lt;body&amp;gt;
          &amp;lt;/body&amp;gt;
        &amp;lt;/html&amp;gt;
        &quot;&quot;&quot;
    string_xaml = &#39;&#39;&#39;
    &amp;lt;Window
        x:Name=&quot;PandasViewerForm&quot;
        xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
        xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;
        xmlns:wv2=&quot;clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf&quot;
        Title=&quot;PandasViewer&quot;
        Width=&quot;600&quot;
        Height=&quot;540&quot;
        MinWidth=&quot;300&quot;
        MinHeight=&quot;200&quot;
        WindowStartupLocation=&quot;CenterScreen&quot;
        ResizeMode=&quot;CanResizeWithGrip&quot;&amp;gt;
    
        &amp;lt;Grid&amp;gt;
            &amp;lt;wv2:WebView2
                x:Name=&quot;webBrowser1&quot;
                HorizontalAlignment=&quot;Stretch&quot;
                VerticalAlignment=&quot;Stretch&quot;/&amp;gt;
        &amp;lt;/Grid&amp;gt;
    &amp;lt;/Window&amp;gt;&#39;&#39;&#39;
  
    def __init__(self):
        super().__init__()
        self.htmlDf = self.init_htmlDf
        self._core = None
        self._pending_html = None
        self._initialized = False
        self.start_time = time.time()
        # Solution with PythonNetFixer module
        xr = XmlReader.Create(StringReader(MainForm.string_xaml))
        self.root = XamlReader.Load(xr) 
        # copy attributes from the root window to self (NOT NECESSARY if you used WPF_Utils.LoadComponent(self, string_xaml))
        for prop_info in self.root.GetType().GetProperties():
            if prop_info.CanWrite:
                try:
                    setattr(self, prop_info.Name, prop_info.GetValue(self.root)) 
                except Exception as ex:
                    print(ex, f&quot;{prop_info.Name=}&quot;)
        self.InitializeComponent()
        
    def InitializeComponent(self):
        reader = XmlReader.Create(StringReader(MainForm.string_xaml))
        while reader.Read():
            # Check if it&#39;s an element node
            if reader.NodeType == System.Xml.XmlNodeType.Element:
                # Check for x:Name attribute
                name = next((reader.GetAttribute(x) for x in [&quot;x:Name&quot;, &quot;Name&quot;] if reader.GetAttribute(x) is not None ), None)
                if name:
                    uiElement = LogicalTreeHelper.FindLogicalNode(self.root, name)
                    if uiElement:
                        setattr(self, name, uiElement)
        #
        self.ContentRendered  += self.WindowRendered

        self.Loaded += self.On_loaded
        self.webBrowser1.CoreWebView2InitializationCompleted += self.On_Initialized

            
    def WindowRendered(self, sender, e):
        print(f&quot;UI show in {time.time() - self.start_time} seconds&quot;)
        
    def On_loaded(self, sender, e):
        if getattr(self, &quot;_webview_started&quot;, False):
            return
        self._webview_started = True
    
        try:
            folder = Path.Combine(APPDATADIR, &quot;DynamoPandasViewer&quot;, &quot;WebView2&quot;)
            Directory.CreateDirectory(folder)
    
            task = CoreWebView2Environment.CreateAsync(None, folder, None)
    
            def completed(t):
                def apply():
                    if t.IsFaulted:
                        print(&quot;WebView2 error:&quot;, t.Exception)
                    else:
                        self.webBrowser1.EnsureCoreWebView2Async(t.Result)
    
                self.Dispatcher.BeginInvoke(Action(apply))
    
            self._environment_continuation = task.ContinueWith(
                Action[Task](completed)
            )
        except Exception:
            print(traceback.format_exc())
    
    
    def On_Initialized(self, sender, e):
        if not e.IsSuccess:
            print(&quot;WebView2 initialization failed:&quot;, e.InitializationException)
            return
    
        self._core = self.webBrowser1.CoreWebView2
        self._core.WebMessageReceived += self.On_web_message
        self.Navigate_to_html(getattr(self, &quot;_pending_html&quot;, None) or self.htmlDf)
    
    
    def Navigate_to_html(self, html):
        if self._core is None:
            self._pending_html = html
            return
        #
        path = os.path.join(tempfile.gettempdir(), f&quot;dynamo_plotly_viewer.html&quot;)
        #
        with open(path, &quot;w&quot;, encoding=&quot;utf-8&quot;) as f:
            f.write(str(html))
    
        self._core.Navigate(&quot;file:///&quot; + path.replace(&quot;\\&quot;, &quot;/&quot;))
    
    
    def On_web_message(self, sender, e):
        try:
            message = json.loads(e.TryGetWebMessageAsString())
            if message.get(&quot;type&quot;) != &quot;selectElement&quot;:
                return
    
            value = str(message.get(&quot;elementId&quot;, &quot;&quot;))
            if value.isdigit():
                elemId = ElementId(int(value))
                uidoc.Selection.SetElementIds(List[ElementId]([elemId]))
                uidoc.ShowElements(List[ElementId]([elemId]))
        except Exception:
            print(traceback.format_exc())
        
    #@property
    def get_HtmlText(self):
        return self.htmlDf
        
    def set_HtmlText(self, value):
        self.htmlDf = value
        if self._core is None:
            self._pending_html = value
        else:
            self.Navigate_to_html(self.htmlDf)
    
    HtmlText = clr.clrproperty(str, get_HtmlText, set_HtmlText)
        

    def ResetHtml(self):
        self.HtmlText = self.init_htmlDf
    
    
@pd.api.extensions.register_dataframe_accessor(&quot;viewer&quot;)
class HtmlAccessor:

    def __init__(self, df_obj):
        self._obj = df_obj

    def _get_base_html(self):
        html_content = getattr(viewerForm, &quot;htmlDf&quot;, &quot;&quot;)
        if not html_content or &quot;&amp;lt;/body&amp;gt;&quot; not in html_content:
            return &quot;&amp;lt;html&amp;gt;&amp;lt;body&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&quot;
        return html_content

    def Show(self, n=0, label=&quot;&quot;):
        html_df = self._get_base_html()

        df_to_show = self._obj if n == 0 else self._obj.head(n)
        html_to_add = df_to_show.to_html()

        if label:
            html_to_add = f&quot;&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;{label}&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&quot; + html_to_add

        updated_html = re.sub(
                r&quot;&amp;lt;/body&amp;gt;&quot;, html_to_add + r&quot;&amp;lt;br&amp;gt;&amp;lt;hr&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/body&amp;gt;&quot;, html_df, flags=re.I
        )

        viewerForm.HtmlText = updated_html
        viewerForm.htmlDf = updated_html
        
    def Plot3D(self, contours_points=None):
        
        post_script = &quot;&quot;&quot;
            document.getElementById(&#39;{plot_id}&#39;).on(&#39;plotly_click&#39;, e =&amp;gt; {
                const id = e.points[0].customdata?.[0];
                if (id != null &amp;amp;&amp;amp; window.chrome?.webview)
                    window.chrome.webview.postMessage(JSON.stringify({
                        type: &#39;selectElement&#39;, elementId: String(id)
                    }));
            });
        &quot;&quot;&quot;
        df = self._obj
        cfg = df.attrs.get(&quot;plot3d&quot;, {})
    
        fig = px.scatter_3d(
            df,
            x=cfg.get(&quot;x&quot;, &quot;X&quot;),
            y=cfg.get(&quot;y&quot;, &quot;Y&quot;),
            z=cfg.get(&quot;z&quot;, &quot;Z&quot;),
            color=cfg.get(&quot;color&quot;, &quot;Name&quot;),
            size=cfg.get(&quot;size&quot;, &quot;Power&quot;),
            size_max=100,
            hover_data=cfg.get(&quot;hover_data&quot;, [&quot;ElementId&quot;, &quot;Name&quot;, &quot;Power&quot;]),
            custom_data=[&quot;ElementId&quot;]
        )
    
        for i, pts in enumerate(contours_points or []):
            x, y, z = zip(*[(p.X, p.Y, p.Z) for p in pts])
            fig.add_trace(go.Scatter3d(
                x=x, y=y, z=z, 
                mode=&quot;lines&quot;,
                name=f&quot;Contour sol {i + 1}&quot;,
                line=dict(color=&quot;gray&quot;, width=1),
                hoverinfo=&quot;skip&quot;
            ))
    
        html = fig.to_html(full_html=True, include_plotlyjs=True, post_script=post_script)
    
        html = re.sub(
            r&quot;&amp;lt;/body&amp;gt;&quot;, lambda m: html + m[0],
            self._get_base_html(), count=1, flags=re.I
        )
    
        viewerForm.HtmlText = viewerForm.htmlDf = html
        

def find_viewer():
    app = Application.Current

    if app is None:
        return None, None

    for window in app.Windows:
        print(window.Title)
        try:
            if window.Title != &quot;PandasViewer&quot;:
                continue
            # The WebView2 control is declared in the XAML.
            web = window.FindName(&quot;webBrowser1&quot;)

            if web is None:
                _web = getattr(window, &quot;webBrowser1&quot;, None)
                _htmlText = getattr(window, &quot;HtmlText&quot;, None)
            #
            if _web is not None and _htmlText is not None:
                return window, _web

        except Exception:
            continue
    return None, None


viewerForm, webView = find_viewer()

if viewerForm is None :
    viewerForm = MainForm()
    viewerForm.Title = &quot;PandasViewer&quot;
    viewerForm.Show()

else:
    viewerForm.ResetHtml()
    
    if not viewerForm.IsVisible:
        viewerForm.Show()

    if viewerForm.WindowState == WindowState.Minimized:
        viewerForm.WindowState = WindowState.Normal

    viewerForm.Activate()
     
    
def get_floor_contours(xdoc):
    return [
        points
            for f in FilteredElementCollector(xdoc).OfClass(Floor).WhereElementIsNotElementType()
                for r in HostObjectUtils.GetTopFaces(f)
                    for face in [f.GetGeometryObjectFromReference(r)]
                        if face.Area &amp;gt; 50
                            for points in [[p for loop in face.GetEdgesAsCurveLoops() for c in loop for p in c.Tessellate()]]
                                if len(points) &amp;gt;= 3
    ]

lnkinstance = UnwrapElement(IN[0])
doc_lnk = lnkinstance.GetLinkDocument()

all_panels = (FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_ElectricalEquipment).WhereElementIsNotElementType()
            .Where(System.Func[DB.Element, System.Boolean](lambda e : e.Symbol.Family.get_Parameter(BuiltInParameter.FAMILY_CONTENT_PART_TYPE).AsInteger() == 14))\
            .ToList()

)

df = pd.DataFrame([], columns=[&quot;ElementId&quot;, &quot;X&quot;, &quot;Y&quot;, &quot;Z&quot;, &quot;Power&quot;, &quot;Name&quot;])


for panel in all_panels:
    loc = panel.Location.Point
    power_str = panel.get_Parameter(BuiltInParameter.RBS_ELEC_PANEL_TOTALLOAD_PARAM).AsValueString()
    print(power_str)
    power = float(re.search(r&quot;([0-9]+(?:\.[0-9]+)?)\s*&quot;, power_str).group(1))
    df.loc[len(df) + 1] = [panel.Id.Value, loc.X, loc.Y, loc.Z, power, panel.Name]
    
df.viewer.Show(label=&quot;list of Electrical Panel&quot;)   
contours = get_floor_contours(doc_lnk)    
df.viewer.Plot3D(contours)

OUT = repr(df)

&lt;/font&gt;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
  &lt;ul style=&quot;text-align: left;&quot;&gt;
    &lt;li&gt;
      &lt;span style=&quot;color: #2b00fe; font-family: georgia; font-size: medium;&quot;&gt;&lt;b&gt;&lt;u&gt; Comparaison avec WebBrowser &lt;/u&gt;&lt;/b&gt;&lt;/span&gt;
    &lt;/li&gt;
  &lt;/ul&gt;
&lt;/h3&gt;
&lt;br /&gt;

&lt;table style=&quot;border-collapse: collapse; border: 1px solid rgb(203, 213, 225); color: #263238; font-family: &amp;quot;Segoe UI&amp;quot;, Arial, sans-serif; font-size: 14px; width: 100%;&quot;&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th style=&quot;background-color: #1b2b3a; border: 1px solid rgb(203, 213, 225); color: white; padding: 12px; text-align: left;&quot;&gt;
        Fonctionnalité
      &lt;/th&gt;
      &lt;th style=&quot;background-color: #263b50; border: 1px solid rgb(203, 213, 225); color: white; padding: 12px; text-align: left;&quot;&gt;
        WebBrowser classique
      &lt;/th&gt;
      &lt;th style=&quot;background-color: #176b52; border: 1px solid rgb(203, 213, 225); color: white; padding: 12px; text-align: left;&quot;&gt;
        WebView2
      &lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr style=&quot;background-color: white;&quot;&gt;
      &lt;td style=&quot;border: 1px solid rgb(203, 213, 225); font-weight: bold; padding: 10px;&quot;&gt;
        Afficher HTML / CSS
      &lt;/td&gt;
      &lt;td style=&quot;border: 1px solid rgb(203, 213, 225); padding: 10px;&quot;&gt;Oui&lt;/td&gt;
      &lt;td style=&quot;border: 1px solid rgb(203, 213, 225); color: #176b52; padding: 10px;&quot;&gt;
        Oui
      &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr style=&quot;background-color: #f0f4f8;&quot;&gt;
      &lt;td style=&quot;border: 1px solid rgb(203, 213, 225); font-weight: bold; padding: 10px;&quot;&gt;
        Afficher Plotly 3D
      &lt;/td&gt;
      &lt;td style=&quot;border: 1px solid rgb(203, 213, 225); padding: 10px;&quot;&gt;
        Possible, mais moteur ancien
      &lt;/td&gt;
      &lt;td style=&quot;border: 1px solid rgb(203, 213, 225); color: #176b52; padding: 10px;&quot;&gt;
        Oui, Chromium moderne
      &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr style=&quot;background-color: white;&quot;&gt;
      &lt;td style=&quot;border: 1px solid rgb(203, 213, 225); font-weight: bold; padding: 10px;&quot;&gt;
        Rotation et zoom 3D
      &lt;/td&gt;
      &lt;td style=&quot;border: 1px solid rgb(203, 213, 225); padding: 10px;&quot;&gt;
        Dépend de la version d&#39;IE
      &lt;/td&gt;
      &lt;td style=&quot;border: 1px solid rgb(203, 213, 225); color: #176b52; padding: 10px;&quot;&gt;
        Oui
      &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr style=&quot;background-color: #f0f4f8;&quot;&gt;
      &lt;td style=&quot;border: 1px solid rgb(203, 213, 225); font-weight: bold; padding: 10px;&quot;&gt;
        Clic sur une sphère (&lt;code&gt;plotly_click&lt;/code&gt;)
      &lt;/td&gt;
      &lt;td style=&quot;border: 1px solid rgb(203, 213, 225); padding: 10px;&quot;&gt;
        Dépend de la compatibilité JavaScript
      &lt;/td&gt;
      &lt;td style=&quot;border: 1px solid rgb(203, 213, 225); color: #176b52; padding: 10px;&quot;&gt;
        Oui
      &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr style=&quot;background-color: white;&quot;&gt;
      &lt;td style=&quot;border: 1px solid rgb(203, 213, 225); font-weight: bold; padding: 10px;&quot;&gt;
        JavaScript → Python/.NET
      &lt;/td&gt;
      &lt;td style=&quot;border: 1px solid rgb(203, 213, 225); padding: 10px;&quot;&gt;
        &lt;code&gt;ObjectForScripting&lt;/code&gt;
      &lt;/td&gt;
      &lt;td style=&quot;border: 1px solid rgb(203, 213, 225); color: #176b52; padding: 10px;&quot;&gt;
        &lt;code&gt;WebMessageReceived&lt;/code&gt;
      &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr style=&quot;background-color: #f0f4f8;&quot;&gt;
      &lt;td style=&quot;border: 1px solid rgb(203, 213, 225); font-weight: bold; padding: 10px;&quot;&gt;
        Python/.NET → JavaScript
      &lt;/td&gt;
      &lt;td style=&quot;border: 1px solid rgb(203, 213, 225); padding: 10px;&quot;&gt;
        &lt;code&gt;InvokeScript()&lt;/code&gt;
      &lt;/td&gt;
      &lt;td style=&quot;border: 1px solid rgb(203, 213, 225); color: #176b52; padding: 10px;&quot;&gt;
        &lt;code&gt;ExecuteScriptAsync()&lt;/code&gt;
      &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr style=&quot;background-color: white;&quot;&gt;
      &lt;td style=&quot;border: 1px solid rgb(203, 213, 225); font-weight: bold; padding: 10px;&quot;&gt;
        Initialisation asynchrone du moteur
      &lt;/td&gt;
      &lt;td style=&quot;border: 1px solid rgb(203, 213, 225); padding: 10px;&quot;&gt;
        Non, généralement plus simple
      &lt;/td&gt;
      &lt;td style=&quot;border: 1px solid rgb(203, 213, 225); color: #176b52; padding: 10px;&quot;&gt;
        Oui
      &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr style=&quot;background-color: #f0f4f8;&quot;&gt;
      &lt;td style=&quot;border: 1px solid rgb(203, 213, 225); font-weight: bold; padding: 10px;&quot;&gt;
        Compatibilité avec les bibliothèques JS modernes
      &lt;/td&gt;
      &lt;td style=&quot;border: 1px solid rgb(203, 213, 225); padding: 10px;&quot;&gt;
        Limitée
      &lt;/td&gt;
      &lt;td style=&quot;border: 1px solid rgb(203, 213, 225); color: #176b52; font-weight: bold; padding: 10px;&quot;&gt;
        Excellente
      &lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;br /&gt;&lt;br /&gt;&lt;span&gt;&lt;!--more--&gt;&lt;/span&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;&lt;span style=&quot;font-size: medium;&quot;&gt;« C’est le temps que tu as perdu pour ta rose qui fait ta rose si importante. »&amp;nbsp;&lt;br /&gt;Le Petit Prince (chapitre 21)&amp;nbsp;&lt;/span&gt;&lt;/i&gt;&lt;span style=&quot;font-size: medium;&quot;&gt;&lt;i&gt;Antoine de Saint-Exupéry,&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;

  &lt;div&gt;
    &lt;a id=&quot;bottom&quot;&gt; &lt;/a&gt;
  &lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='https://voltadynabim.blogspot.com/feeds/7759107225784895110/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='https://voltadynabim.blogspot.com/2026/10/dynamo-python-wpf-webview2.html#comment-form' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/4001721146719322746/posts/default/7759107225784895110'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/4001721146719322746/posts/default/7759107225784895110'/><link rel='alternate' type='text/html' href='https://voltadynabim.blogspot.com/2026/10/dynamo-python-wpf-webview2.html' title='[Dynamo += Python] WPF + WebView2'/><author><name>Cyril</name><uri>http://www.blogger.com/profile/08389811365235224682</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgY3Iz0xq8QpQu6njnL6IyeBXjbJyBFxD1nsxDcqUHlCs3yQZih7HlcLEre3RYjOSPnDg544905lHz4K6SHzbXgmdITwUktyM_FTkcYSINI0wkNhXcYX_4i9Kx4176Mxm4/s113/1608331968791.jfif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhw4DZ7L79KbG8Ui4NtWzMsH491o2pR0fEOg6sGm7VHN8j_znjhsqOuR23OVsXdo8A-0KWf8EWW-UV_ZvQpijmE7l1tIQTnjiCJfeBjqWSUeUAvVZAtBK2L-d-PkiglAHuMv0jVf2ZG5FBlai9N7NWLFmuqEg8_roYuEW8Gbzg2OK95v8gOQe2wFuwYVYba/s72-w400-h266-c/14f9cf30-f956-47b0-8b14-770a5b4ab6ee.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4001721146719322746.post-7913101339573004529</id><published>2026-09-30T12:33:33.776+02:00</published><updated>2026-09-30T12:33:33.776+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="DataTable"/><category scheme="http://www.blogger.com/atom/ns#" term="GenericZones"/><category scheme="http://www.blogger.com/atom/ns#" term="PythonNet"/><category scheme="http://www.blogger.com/atom/ns#" term="Revit API 2027"/><category scheme="http://www.blogger.com/atom/ns#" term="Zones HVAC"/><category scheme="http://www.blogger.com/atom/ns#" term="Zones Système"/><title type='text'>[Dynamo + Python] Revit 2027 : HVAC Zone → GenericZone (Migration API)</title><content type='html'>&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
  &lt;span style=&quot;font-family: georgia; font-size: large;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
  &lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeqFXLUXbypsOSjuRSseh6f82IKsulGQ1LS1qxEEo4Mhh0nIoCnqGRbrB6y7FrmgxASQ93Va5oxqpDehDWEQQQHLw-SDIcFicg7VHwl7oabwCD87TIXeAY7NjCysUvGAeUXcp4ZP9nYCfvairJ7ASQbtNTRc3Ue-GHxukrOfC0Eo3HHdSn9zN2Qjk2iDKO/s460/Generic%20zone.jpg&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;383&quot; data-original-width=&quot;460&quot; height=&quot;333&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeqFXLUXbypsOSjuRSseh6f82IKsulGQ1LS1qxEEo4Mhh0nIoCnqGRbrB6y7FrmgxASQ93Va5oxqpDehDWEQQQHLw-SDIcFicg7VHwl7oabwCD87TIXeAY7NjCysUvGAeUXcp4ZP9nYCfvairJ7ASQbtNTRc3Ue-GHxukrOfC0Eo3HHdSn9zN2Qjk2iDKO/w400-h333/Generic%20zone.jpg&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;br /&gt;&lt;span style=&quot;font-family: georgia; font-size: large;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;
  &lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;Comment retrouver les zones systèmes (ex CVC) qui sont attachées aux
    espaces avec Revit 2027&amp;nbsp;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;div&gt;
  &lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;#DynamoBIM #Revit #Python #RevitAPI #GenericZone #Revit API 2027&amp;nbsp; &amp;nbsp; &amp;nbsp;#AutodeskExpertElite #AutodeskCommunity&amp;nbsp;&lt;a href=&quot;https://www.autodesk.com/expert-elite/&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot; target=&quot;_blank&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;50&quot; data-original-width=&quot;50&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEj3-npK4uFyHO9Jdk1NzGPoAjxdblUqzui38L8IBpDGyX0dDTXo3OBnvhvS6oVUjAG6kfD7A_qqKaQjE8v28_wy5vmOy5U9kZPzONBbbMdor19FAtuGqqbKxAn9OG44-MxLgH-XbEhq5xFuNxMUjUy8oJTZkmfy5sMt_lkdL1LqS0jmkFH7ojjLqzN5vf73=s16000&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;
  &lt;div style=&quot;text-align: right;&quot;&gt;
    &lt;span style=&quot;color: #2b00fe; font-family: georgia; font-size: medium;&quot;&gt;&lt;i&gt;if this article is not in your language, use the Google Translate
        widget ⬈ (&lt;a href=&quot;#bottom&quot;&gt;bottom of page for Mobile version&lt;span&gt; &lt;/span&gt;&lt;/a&gt;&lt;a href=&quot;#bottom&quot;&gt;⬇&lt;/a&gt;)&lt;/i&gt;&lt;/span&gt;
  &lt;/div&gt;
  &lt;br /&gt;&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
  &lt;span style=&quot;color: red; font-family: georgia; font-size: medium;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;/div&gt;
&lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;Les Zones Système (GenericZones) viennent remplacer les Zones HVAC .&amp;nbsp;&lt;/span&gt;
&lt;div&gt;
  &lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
  &lt;div&gt;
    &lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;&lt;span&gt;&lt;i&gt;Sur des projets existants, elles sont désormais automatiquement
        converties lors de l’ouverture des projets Revit 2027.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Parmi
        les changements notables :&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;&lt;span&gt;&lt;br /&gt;
        &lt;ul style=&quot;text-align: left;&quot;&gt;
          &lt;li&gt;
            &lt;span&gt;les HVAC Zones deviennent obsolètes&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
          &lt;li&gt;
            &lt;span&gt;Les espaces MEP peuvent être situés dans plusieurs zones.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;span&gt;Les zones dépendent d&#39;un seul niveau (impossibilité de créer une
              zone sur plusieurs niveaux).&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;span&gt;Les zones peuvent être :&lt;/span&gt;
          &lt;/li&gt;
          &lt;ul&gt;
            &lt;ul&gt;&lt;li&gt;&lt;span&gt;soit attaché aux espaces&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;soit basées sur une esquisse&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;
            
          &lt;/ul&gt;&lt;li&gt;Les Zones Système (GenericZones) sont des zones analytiques.&lt;/li&gt;
        &lt;/ul&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEiNWWedOgGdb40Pt86ZNI-PpVm9KYhEZQqZ2Hc4eSJTzlXsg0W8SLMedWxrAoMDcvyXCtBgLTWllnut_t7HzNGZmenRw1GxlTV7wMykouxaQe5wggMeih064KKg3WWQXQ8_no-puTowO0IeFeEdp7CiUuRAnTqtEAqxef2tR3N7NN2WO_VcxdgXEiEH7XVV&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;711&quot; data-original-width=&quot;838&quot; height=&quot;543&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEiNWWedOgGdb40Pt86ZNI-PpVm9KYhEZQqZ2Hc4eSJTzlXsg0W8SLMedWxrAoMDcvyXCtBgLTWllnut_t7HzNGZmenRw1GxlTV7wMykouxaQe5wggMeih064KKg3WWQXQ8_no-puTowO0IeFeEdp7CiUuRAnTqtEAqxef2tR3N7NN2WO_VcxdgXEiEH7XVV=w640-h543&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;div&gt;&lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;
      &lt;/span&gt;
      &lt;div&gt;
        &lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;Il en résulte plusieurs modifications dans l&#39;API&lt;/span&gt;
      &lt;/div&gt;
      &lt;div&gt;
        &lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
        &lt;table style=&quot;border-collapse: collapse; font-family: sans-serif; width: 100%;&quot;&gt;
          &lt;thead&gt;
            &lt;tr style=&quot;background-color: #f2f2f2;&quot;&gt;
              &lt;th style=&quot;border: 1px solid rgb(221, 221, 221); padding: 8px; text-align: left;&quot;&gt;
                Migration / Item
              &lt;/th&gt;
              &lt;th style=&quot;border: 1px solid rgb(221, 221, 221); padding: 8px; text-align: left;&quot;&gt;
                Details
              &lt;/th&gt;
            &lt;/tr&gt;
          &lt;/thead&gt;
          &lt;tbody&gt;
            &lt;tr&gt;
              &lt;td style=&quot;border: 1px solid rgb(221, 221, 221); padding: 8px;&quot;&gt;
                Propriété et BIC dépréciés&lt;/td&gt;
              &lt;td style=&quot;border: 1px solid rgb(221, 221, 221); padding: 8px;&quot;&gt;
                &lt;code&gt;Autodesk.Revit.DB.Mechanical.Space.Zone&lt;/code&gt;,
                &lt;code&gt;BuiltInCategory:OST_HVAC_Zones&lt;/code&gt;
              &lt;/td&gt;
            &lt;/tr&gt;
            &lt;tr&gt;
              &lt;td style=&quot;border: 1px solid rgb(221, 221, 221); padding: 8px;&quot;&gt;
                a utilisé en remplacement&lt;/td&gt;
              &lt;td style=&quot;border: 1px solid rgb(221, 221, 221); padding: 8px;&quot;&gt;
                &lt;code&gt;GenericZone&lt;/code&gt;&amp;nbsp;+&amp;nbsp;&lt;code&gt;GetSpaceIds()&lt;/code&gt;
              &lt;/td&gt;
            &lt;/tr&gt;
          &lt;/tbody&gt;
        &lt;/table&gt;
        &lt;br /&gt;
      &lt;/div&gt;
      &lt;div&gt;
        &lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
      &lt;/div&gt;
      &lt;div&gt;
        &lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
      &lt;/div&gt;
      &lt;div&gt;
        &lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;&lt;div&gt;
            Voici un exemple qui combine deux méthodes pour retrouver les
            espaces, tout en stockant le tout dans une Datatable pour faire une
            recherche rapide par &lt;code class=&quot;nocode&quot; style=&quot;background: rgb(240, 240, 240); border-radius: 3px; border: 1px solid rgb(208, 208, 208); font-family: courrier; font-size: 17.3333px; padding-left: 2px; padding-right: 2px; text-align: justify;&quot;&gt;ElementId&lt;/code&gt; via &lt;code class=&quot;nocode&quot; style=&quot;background: rgb(240, 240, 240); border-radius: 3px; border: 1px solid rgb(208, 208, 208); font-family: courrier; font-size: 17.3333px; padding-left: 2px; padding-right: 2px; text-align: justify;&quot;&gt;Select()&lt;/code&gt;&amp;nbsp;
          &lt;/div&gt;
          &lt;div&gt;&lt;br /&gt;&lt;/div&gt;
          &lt;div&gt;&lt;b&gt;1. Zones basées sur des espaces&lt;/b&gt;&lt;/div&gt;
          &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;blockquote style=&quot;border-color: currentcolor; border-image: none; border-style: none; border-width: medium; margin: 0px 0px 0px 40px; padding: 0px; text-align: left;&quot;&gt;
  &lt;div&gt;
    &lt;div&gt;
      &lt;div&gt;
        &lt;div&gt;
          &lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;&lt;div&gt;La méthode la plus rapide consiste à utiliser :&lt;/div&gt;&lt;/span&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;
&lt;div&gt;
  &lt;div&gt;
    &lt;div&gt;
      &lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;/span&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;blockquote style=&quot;border-color: currentcolor; border-image: none; border-style: none; border-width: medium; border: none; margin: 0px 0px 0px 40px; padding: 0px;&quot;&gt;
  &lt;div&gt;
    &lt;div&gt;
      &lt;div&gt;
        &lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;&lt;div style=&quot;text-align: left;&quot;&gt;
            &lt;code class=&quot;nocode&quot; style=&quot;background: rgb(240, 240, 240); border-radius: 3px; border: 1px solid rgb(208, 208, 208); font-family: courrier; font-size: 17.3333px; padding-left: 2px; padding-right: 2px; text-align: justify;&quot;&gt;spaceIds = genericZone.GetSpaceIds()&lt;/code&gt;
          &lt;/div&gt;&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;
&lt;blockquote style=&quot;border-color: currentcolor; border-image: none; border-style: none; border-width: medium; border: none; margin: 0px 0px 0px 40px; padding: 0px;&quot;&gt;
  &lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;/span&gt;
&lt;/blockquote&gt;
&lt;blockquote style=&quot;border-color: currentcolor; border-image: none; border-style: none; border-width: medium; border: none; margin: 0px 0px 0px 40px; padding: 0px;&quot;&gt;
  &lt;div&gt;
    &lt;div&gt;
      &lt;div&gt;
        &lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;&lt;div style=&quot;text-align: left;&quot;&gt;
            Chaque ElementId correspond à un espace associé à la zone.
          &lt;/div&gt;&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;
&lt;div&gt;
  &lt;div&gt;
    &lt;div&gt;
      &lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
        &lt;div&gt;&lt;b&gt;2. Zones basées sur une esquisse&lt;/b&gt;&lt;/div&gt;
        &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/span&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;blockquote style=&quot;border-color: currentcolor; border-image: none; border-style: none; border-width: medium; margin: 0px 0px 0px 40px; padding: 0px; text-align: left;&quot;&gt;
  &lt;div&gt;
    &lt;div&gt;
      &lt;div&gt;
        &lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;&lt;span&gt;&lt;div&gt;
            Les zones créées à partir d&#39;un contour ne possèdent pas
            d&#39;association directe avec les espaces.
          &lt;/div&gt;&lt;/span&gt;
      &lt;/span&gt;&lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div&gt;
    &lt;div&gt;
      &lt;div&gt;
        &lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;&lt;span&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/span&gt;
      &lt;/span&gt;&lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div&gt;
    &lt;div&gt;
      &lt;div&gt;
        &lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;&lt;div&gt;L&#39;alternative consiste à :&lt;/div&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/blockquote&gt;
&lt;div&gt;
  &lt;div&gt;
    &lt;div style=&quot;text-align: left;&quot;&gt;
      &lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;&lt;span&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;
          &lt;ul&gt;
            &lt;ul&gt;&lt;li&gt;récupérer le polygone de la zone&amp;nbsp;&lt;/li&gt;&lt;/ul&gt;
          &lt;/ul&gt;
        &lt;/ul&gt;
        &lt;ul style=&quot;text-align: left;&quot;&gt;
          &lt;ul&gt;
            &lt;ul&gt;&lt;li&gt;récupérer le point de calcul de chaque espace et vérifier si ce
              dernier est dans le polygone (avec l&#39;API Dynamo&amp;nbsp;&amp;nbsp;&lt;code class=&quot;nocode&quot; style=&quot;background: rgb(240, 240, 240); border-radius: 3px; border: 1px solid rgb(208, 208, 208); padding-left: 2px; padding-right: 2px; text-align: justify;&quot;&gt;Polygon.ContainmentTest()&lt;/code&gt;&amp;nbsp;)
            &lt;/li&gt;&lt;/ul&gt;
          &lt;/ul&gt;
        &lt;/ul&gt;&lt;/span&gt;
    &lt;/span&gt;&lt;/div&gt;

    &lt;div&gt;&lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
    &lt;div&gt;
      &lt;pre class=&quot;prettyprint&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;font size=&quot;2.5pt&quot;&gt;
import clr
import System
from System.Collections.Generic import List
from System.Linq import Enumerable
from System.Collections.Generic import IEnumerable

clr.AddReference(&#39;ProtoGeometry&#39;)
from Autodesk.DesignScript.Geometry import *
import Autodesk.DesignScript.Geometry as DS

clr.AddReference(&#39;RevitAPI&#39;)
import Autodesk
import Autodesk.Revit.DB as DB
from Autodesk.Revit.DB import *
from Autodesk.Revit.DB.Analysis import *

clr.AddReference(&#39;RevitServices&#39;)
import RevitServices
from RevitServices.Persistence import DocumentManager
doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
uidoc = uiapp.ActiveUIDocument
app = uiapp.Application
sdkNumber = int(app.VersionNumber)

clr.AddReference(&#39;RevitNodes&#39;)
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)
clr.ImportExtensions(Revit.GeometryReferences)

clr.AddReference(&#39;System.Data&#39;)
from System.Data import *

clr.AddReference(&quot;System.Core&quot;)
clr.ImportExtensions(System.Linq)


import traceback
input_space = UnwrapElement(IN[0])

fecSpace = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_MEPSpaces).WhereElementIsNotElementType().ToElements()

def get_ZoneGetSpaceIds(zone):
    try:
        if zone.GeometricDefinition == ZoneGeometricDefinition.Spaces:
            return zone.GetSpaceIds()
        else:
            zone_sketch = doc.GetElement(zone.GetSketchId())
            profile : DB.CurveArrArray = zone_sketch.Profile
            zone_polygon = DS.Polygon.ByPoints([c.GetEndPoint(0).ToPoint() for c in profile[0]])
            level1Filter = ElementLevelFilter(zone.LevelId)
            fecLvlSpaceId = (
                FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_MEPSpaces).WhereElementIsNotElementType().WherePasses(level1Filter)
                .Where(System.Func[System.Object, System.Boolean](lambda space: space.Area &amp;gt; 0 and isinstance(space.Location, DB.LocationPoint)) )
                .Where(System.Func[System.Object, System.Boolean](lambda space: zone_polygon.ContainmentTest(space.Location.Point.ToPoint() ) ))
                .Select[System.Object, DB.ElementId](System.Func[System.Object, DB.ElementId](lambda x: x.Id))
                .ToList()
            )
            return fecLvlSpaceId
    except Exception as ex:
        print(traceback.format_exc())
        return List[ElementId]()

if sdkNumber &amp;lt; 2027:
    OUT = [[s.Name , s.Zone.Name ] for s in fecSpace]
else:
    # Global variable DataTable                                
    dt_zone = DataTable(&quot;GZone&quot;)
    dt_zone.Columns.Add(&#39;SpaceId&#39;, DB.ElementId)
    dt_zone.Columns.Add(&#39;SpaceIdValue&#39;, System.Int64)
    dt_zone.Columns.Add(&#39;Zone&#39;, DB.Analysis.GenericZone)     
    dt_zone.Columns.Add(&#39;ZoneName&#39;, System.String)  
    #
    dt_zone.BeginLoadData()
    lst_zones = (
                FilteredElementCollector(doc).OfClass(GenericZone)
                .SelectMany[DB.Element, DB.ElementId, DataRow](
                                                System.Func[DB.Element, IEnumerable[DB.ElementId]](lambda z : get_ZoneGetSpaceIds(z) ),
                                                System.Func[DB.Element, DB.ElementId, DataRow](lambda z, space_id : dt_zone.Rows.Add(space_id, space_id.Value, z, z.Name)
                                                ))
                .ToList()
    )
    
    dt_zone.EndLoadData()
    #
    #OUT = [[s.Name , dt_zone.Select(f&quot;[SpaceIdValue] = &#39;{s.Id.Value}&#39;&quot;).Cast[DataRow]().FirstOrDefault() ] for s in fecSpace]
    # 
    out = []
    for s in fecSpace:
        dataRow_spaces = dt_zone.Select(f&quot;[SpaceIdValue] = &#39;{s.Id.Value}&#39;&quot;).Cast[DataRow]()#.FirstOrDefault() 
        if dataRow_spaces is not None:
            out.append([s.Name, [r[&#39;ZoneName&#39;] for r in dataRow_spaces] ])
            
    if input_space is not None:
        dataRow_spaces = dt_zone.Select(f&quot;[SpaceIdValue] = &#39;{input_space.Id.Value}&#39;&quot;).Cast[DataRow]()
        print(len(list(dataRow_spaces)))
        dataRow_ZDM = dt_zone.Select(f&quot;[SpaceIdValue] = &#39;{input_space.Id.Value}&#39; AND [ZoneName] Like &#39;%ZDM%&#39;&quot;).Cast[DataRow]().FirstOrDefault() 
        dataRow_ZDA = dt_zone.Select(f&quot;[SpaceIdValue] = &#39;{input_space.Id.Value}&#39; AND [ZoneName] Like &#39;%ZDA%&#39;&quot;).Cast[DataRow]().FirstOrDefault() 
        if dataRow_spaces is not None:
            out.insert(0, [
                            input_space.Name, 
                            [r[&#39;ZoneName&#39;] for r in dataRow_spaces], 
                            dataRow_ZDM[&#39;ZoneName&#39;] if dataRow_ZDM is not None else None,
                            dataRow_ZDA[&#39;ZoneName&#39;] if dataRow_ZDA is not None else None
                        ])
    OUT = out
&lt;/font&gt;&lt;/code&gt;&lt;/pre&gt;
      . .
    &lt;/div&gt;
    &lt;div&gt;&lt;br /&gt;&lt;/div&gt;
    &lt;span&gt;&lt;!--more--&gt;&lt;/span&gt;
    &lt;div&gt;&lt;br /&gt;&lt;/div&gt;
    &lt;div&gt;
      &lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;&lt;i&gt;« Ce n’est pas que nous ayons peu de temps, c’est que nous en perdons
          beaucoup. »&lt;br /&gt;&lt;/i&gt;&lt;/span&gt;&lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;Sénèque&lt;/span&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
  ...
  &lt;a id=&quot;bottom&quot;&gt;&lt;/a&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='https://voltadynabim.blogspot.com/feeds/7913101339573004529/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='https://voltadynabim.blogspot.com/2026/09/dynamo-python-revit-2027-hvac-zone.html#comment-form' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/4001721146719322746/posts/default/7913101339573004529'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/4001721146719322746/posts/default/7913101339573004529'/><link rel='alternate' type='text/html' href='https://voltadynabim.blogspot.com/2026/09/dynamo-python-revit-2027-hvac-zone.html' title='[Dynamo + Python] Revit 2027 : HVAC Zone → GenericZone (Migration API)'/><author><name>Cyril</name><uri>http://www.blogger.com/profile/08389811365235224682</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgY3Iz0xq8QpQu6njnL6IyeBXjbJyBFxD1nsxDcqUHlCs3yQZih7HlcLEre3RYjOSPnDg544905lHz4K6SHzbXgmdITwUktyM_FTkcYSINI0wkNhXcYX_4i9Kx4176Mxm4/s113/1608331968791.jfif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeqFXLUXbypsOSjuRSseh6f82IKsulGQ1LS1qxEEo4Mhh0nIoCnqGRbrB6y7FrmgxASQ93Va5oxqpDehDWEQQQHLw-SDIcFicg7VHwl7oabwCD87TIXeAY7NjCysUvGAeUXcp4ZP9nYCfvairJ7ASQbtNTRc3Ue-GHxukrOfC0Eo3HHdSn9zN2Qjk2iDKO/s72-w400-h333-c/Generic%20zone.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4001721146719322746.post-4527036482983012636</id><published>2026-09-04T23:50:00.000+02:00</published><updated>2026-09-05T13:53:48.466+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="AutodeskExpertElite"/><category scheme="http://www.blogger.com/atom/ns#" term="DynamoBim"/><category scheme="http://www.blogger.com/atom/ns#" term="Export"/><category scheme="http://www.blogger.com/atom/ns#" term="IFC"/><category scheme="http://www.blogger.com/atom/ns#" term="Revit API"/><title type='text'>[Dynamo += Python] Export IFC : configurations Utilisateur (MAJ 05/09/2026)</title><content type='html'>&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
  &lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEheNCMuJClyySo2riXYwP2paAn--xN4axsaCmmR58pn48A9VUQecyl4Fq_8MpxUy_MBtOuD3CAYjv5_GsD685g35K65ajQEUpuzMNS0Z64L5Kv5os6joVOxC2gqevp5nDYpDZsQ3KOYMLF3_Wqw7szRiTgPoNRRZPRdkQbigIONHzM4f7NdMOlLpGGMr5Su&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;1024&quot; data-original-width=&quot;1024&quot; height=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEheNCMuJClyySo2riXYwP2paAn--xN4axsaCmmR58pn48A9VUQecyl4Fq_8MpxUy_MBtOuD3CAYjv5_GsD685g35K65ajQEUpuzMNS0Z64L5Kv5os6joVOxC2gqevp5nDYpDZsQ3KOYMLF3_Wqw7szRiTgPoNRRZPRdkQbigIONHzM4f7NdMOlLpGGMr5Su=w400-h400&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;
  &lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;Une astuce pour obtenir les données des configurations d&#39;Export IFC&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;div&gt;
  &lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;#DynamoBIM #Revit #Python #RevitAPI #IFC #ConfigurationIFC
    #AutodeskExpertElite&amp;nbsp;#AutodeskCommunity&amp;nbsp;&lt;a href=&quot;https://www.autodesk.com/expert-elite/&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot; target=&quot;_blank&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;50&quot; data-original-width=&quot;50&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEj3-npK4uFyHO9Jdk1NzGPoAjxdblUqzui38L8IBpDGyX0dDTXo3OBnvhvS6oVUjAG6kfD7A_qqKaQjE8v28_wy5vmOy5U9kZPzONBbbMdor19FAtuGqqbKxAn9OG44-MxLgH-XbEhq5xFuNxMUjUy8oJTZkmfy5sMt_lkdL1LqS0jmkFH7ojjLqzN5vf73=s16000&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;
  &lt;div style=&quot;text-align: right;&quot;&gt;
    &lt;span style=&quot;color: #2b00fe; font-family: georgia; font-size: medium;&quot;&gt;&lt;i&gt;if this article is not in your language, use the Google Translate
        widget ⬈ (&lt;a href=&quot;#bottom&quot;&gt;bottom of page for Mobile version&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/a&gt;&lt;a href=&quot;#bottom&quot;&gt;⬇&lt;/a&gt;)&lt;/i&gt;&lt;/span&gt;
  &lt;/div&gt;
  &lt;br /&gt;&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;color: red; font-family: georgia; font-size: medium;&quot;&gt;&lt;b&gt;MAJ 05/09/2026 : Mise à jour pour Revit 2027&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;color: red; font-family: georgia; font-size: medium;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;Dans le présent article, depuis Revit, nous cherchons à récupérer les données
  des configurations utilisateur d&#39;export IFC.&lt;/span&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
  &lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEgXueGzeiBl4VwrEPXsVaTD6LW5V7sAxbNCwA_73iFlDOBwOcO6SeLgvK0lqzdipDPGIp19opoP5soQpJxu9xOcyzE1QSaeUZLjPXdoUDKyUDE1Y7VafyIXX_6ZJ9InqMUDh0J4A9Mshs2_a4WOIGuHT22-JCg6zV-9ZVVX9qy1rmM6ofGGfBei3r35FXpL&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;440&quot; data-original-width=&quot;722&quot; height=&quot;390&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEgXueGzeiBl4VwrEPXsVaTD6LW5V7sAxbNCwA_73iFlDOBwOcO6SeLgvK0lqzdipDPGIp19opoP5soQpJxu9xOcyzE1QSaeUZLjPXdoUDKyUDE1Y7VafyIXX_6ZJ9InqMUDh0J4A9Mshs2_a4WOIGuHT22-JCg6zV-9ZVVX9qy1rmM6ofGGfBei3r35FXpL=w640-h390&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;
  &lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;
    Le but étant de permettre un export IFC depuis Dynamo suivant une
    configuration précise sans avoir à faire un export-import de celle-ci (au
    format json)
  &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
  &lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
  &lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;Le code Python&amp;nbsp;&lt;/span&gt;
&lt;/p&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;font size=&quot;2.5pt&quot;&gt;

import clr
import sys
import System

# Import RevitAPI
clr.AddReference(&quot;RevitAPI&quot;)
import Autodesk
from Autodesk.Revit.DB import *
import Autodesk.Revit.DB as DB
from Autodesk.Revit.Attributes import *
from Autodesk.Revit.DB.IFC import *


clr.AddReference(&quot;RevitServices&quot;)
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)


IFCExportConfiguration = None
IFCExportConfigurationsMap = None
pf_path = System.Environment.GetFolderPath(System.Environment.SpecialFolder.ProgramFilesX86)
pf_data_path = System.Environment.GetFolderPath(System.Environment.SpecialFolder.CommonApplicationData)
ifc_bundle_path = &quot;{0}\\Autodesk\\ApplicationPlugins\\IFC {1}.bundle\\Contents\\{1}&quot;.format(pf_data_path, sdkNumber)
if System.IO.Directory.Exists(ifc_bundle_path):
    print(&quot;pass1&quot;)
    sys.path.append(ifc_bundle_path)
    if sdkNumber &amp;lt; 2027:
        clr.AddReference(&quot;IFCExporterUIOverride&quot;)
        from BIM.IFC.Export.UI import IFCExportConfigurationsMap, IFCExportConfiguration, IFCCommandOverrideApplication
    else:
        clr.AddReference(&quot;Revit.IFC.Export&quot;)
        from Revit.IFC.Export.Utility import IFCExportConfigurationsMap, IFCExportConfiguration
        clr.AddReference(&quot;IFCExporterUIOverride&quot;)
        from BIM.IFC.Export.UI import IFCCommandOverrideApplication
else:
    ifc_addin_path = &quot;{}\\Autodesk\\Revit {}\\AddIns\IFCExporterUI&quot;.format(pf_path, sdkNumber)
    if System.IO.Directory.Exists(ifc_addin_path):
        print(&quot;pass2&quot;)
        sys.path.append(ifc_addin_path)
        clr.AddReference(&quot;Autodesk.IFC.Export.UI&quot;)
        from BIM.IFC.Export.UI import IFCExportConfigurationsMap, IFCExportConfiguration, IFCCommandOverrideApplication

import json

ifc_dict_config = {}
if IFCExportConfigurationsMap is not None:
    idfdocA = IFCCommandOverrideApplication.TheDocument
    if idfdocA is None:
        propinfo = clr.GetClrType(IFCCommandOverrideApplication).GetProperty(&#39;TheDocument&#39;)
        propinfo.SetValue(None, doc)
    configurationsMap = IFCExportConfigurationsMap(doc)
    configurationsMap.AddBuiltInConfigurations()
    configurationsMap.AddSavedConfigurations({})
    
    for config in configurationsMap.Values:
        dict_ifc_version_str = {&quot;IFC_Version_str&quot;: config.IFCVersion.ToString() }
        dict_config = json.loads(config.SerializeConfigToJson())
        # merge dictionaries
        merge_dict_3 = dict(dict_ifc_version_str,**dict_config)
        ifc_dict_config[config.Name] = merge_dict_3
  
OUT = ifc_dict_config

&lt;/font&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;
  &lt;li&gt;
    &lt;b&gt;&lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;Note 1&lt;/span&gt;&lt;/b&gt;
  &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;
  &lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;il existe 2 addin export IFC, celui de base (qui est livré d&#39;origine avec
    Revit) et celui que l&#39;on met à jour manuellement par la suite via le
    &lt;a href=&quot;https://github.com/Autodesk/revit-ifc&quot; target=&quot;_blank&quot;&gt;Repo Github d&#39;Autodesk&lt;/a&gt;, ce dernier vient remplacer le 1er, mais ne partage pas le même
    dossier.&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
  &lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;Il faut donc veiller à charger la bonne assembly (voir code ci
    dessus)&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;
  &lt;li&gt;
    &lt;b&gt;&lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;Note 2&lt;/span&gt;&lt;/b&gt;
  &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;
  &lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;Une petite explication concernant ces lignes&lt;/span&gt;&lt;br /&gt;
&lt;/p&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;font size=&quot;2.5pt&quot;&gt;
idfdocA = IFCCommandOverrideApplication.TheDocument
if idfdocA is None:
	propinfo = clr.GetClrType(IFCCommandOverrideApplication).GetProperty(&#39;TheDocument&#39;)
	propinfo.SetValue(None, doc)
&lt;/font&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;
  &lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;
    Ces lignes de code effectuent une opération de réflexion (.NET Reflection)
    pour modifier dynamiquement la propriété
    &lt;code class=&quot;nocode&quot; style=&quot;background: rgb(240, 240, 240); border-radius: 3px; border: 1px solid rgb(208, 208, 208); padding-left: 2px; padding-right: 2px; text-align: justify;&quot;&gt;TheDocument&lt;/code&gt;
    d&#39;une instance de la classe
    &lt;code class=&quot;nocode&quot; style=&quot;background: rgb(240, 240, 240); border-radius: 3px; border: 1px solid rgb(208, 208, 208); padding-left: 2px; padding-right: 2px; text-align: justify;&quot;&gt;IFCCommandOverrideApplication&lt;/code&gt;.
  &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
  &lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;
    Le but de ces lignes est de s&#39;assurer que l&#39;application d&#39;exportation IFC
    &lt;code class=&quot;nocode&quot; style=&quot;background: rgb(240, 240, 240); border-radius: 3px; border: 1px solid rgb(208, 208, 208); padding-left: 2px; padding-right: 2px; text-align: justify;&quot;&gt;IFCCommandOverrideApplication&lt;/code&gt;
    est configurée pour utiliser le document Revit actuel (doc) comme contexte
    pour l&#39;exportation. Cela peut être nécessaire si l&#39;application d&#39;exportation
    IFC n&#39;est pas automatiquement configurée pour utiliser le bon document Revit
    ou si vous devez réaffecter explicitement le document cible pour
    l&#39;exportation dans des scénarios spécifiques.
  &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;Résultat&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
  &lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEj4o3CUj1ftaUTrZ6BcucHMvMaDjdj2kr0XHQprlLZjL5E9Ok5QrGOSeod-hbuVfmgCRFI_Li_aBAwBdDxvRjQ-_sl2M9av5bsF_M46Q4xcCp9G9whTo2KNAEAjfeZJ8ZBlyPgCMvSadaoIbhwvKYoy7O-viYTb5j-umgMwiwqjQCq-UurRwBlEdlnM_CUg&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;872&quot; data-original-width=&quot;1127&quot; height=&quot;495&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEj4o3CUj1ftaUTrZ6BcucHMvMaDjdj2kr0XHQprlLZjL5E9Ok5QrGOSeod-hbuVfmgCRFI_Li_aBAwBdDxvRjQ-_sl2M9av5bsF_M46Q4xcCp9G9whTo2KNAEAjfeZJ8ZBlyPgCMvSadaoIbhwvKYoy7O-viYTb5j-umgMwiwqjQCq-UurRwBlEdlnM_CUg=w640-h495&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;Export IFC à partir des valeurs d&#39;une configuration&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
  &lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;&lt;span&gt;Vous pouvez ensuite compléter le script dynamo en rajoutant par exemple
      le nœud &lt;/span&gt;&lt;b&gt;Export IFC&lt;/b&gt;&lt;span&gt; du package&amp;nbsp;&lt;/span&gt;&lt;b&gt;GeniusLoci&amp;nbsp;&lt;/b&gt;&lt;/span&gt;
&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
  &lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEhC_qVYNvhVb49oSLBQgKolH_zAI6DPvzLZgb4Po51EYdf80wFvR3HUcoXWetycPaiOnTBTMwdweYyrFwShB7xMB_qZVfNqHOYZN6tpBZYXVvRkppl3GCROQobjE6Q3E3tKmS2WFNZX7NH8e_u4EYBwqNEbyuul2Xbgz9hpy0_mhAqO3zQWfBNSNzkGdMpM&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;881&quot; data-original-width=&quot;1893&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEhC_qVYNvhVb49oSLBQgKolH_zAI6DPvzLZgb4Po51EYdf80wFvR3HUcoXWetycPaiOnTBTMwdweYyrFwShB7xMB_qZVfNqHOYZN6tpBZYXVvRkppl3GCROQobjE6Q3E3tKmS2WFNZX7NH8e_u4EYBwqNEbyuul2Xbgz9hpy0_mhAqO3zQWfBNSNzkGdMpM=s16000&quot; /&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;br /&gt;&lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;Export IFC direct à partir d&#39;un&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;IFCExportConfiguration&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: georgia; font-size: large;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;Une autre solution consiste de transférer les valeurs une instance d&#39;un
IFCExportConfiguration&amp;nbsp;vers une instance IFCExportOptions avec la méthode&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp; Void UpdateOptions(Autodesk.Revit.DB.IFCExportOptions, Autodesk.Revit.DB.ElementId)&lt;/div&gt;&lt;/span&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
  &lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
    &lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEh79uPsYC7ATaPXvUkGUPBS4Y8losAEhA-o8Vi80TRW0m1feTzEamRHbq32BRDibL1IOitK_yNjta8OeqlhunqxuP3n2UlMwUSvGTg7X_3hUFCf9VM46qoCnr3CR2e6fQ24FaAfDUyQTd3szYbPkz1I68BEwEbB7ulztT4k7zYtLPISFe3Xql1va8pjuKlS&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;500&quot; data-original-width=&quot;1509&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEh79uPsYC7ATaPXvUkGUPBS4Y8losAEhA-o8Vi80TRW0m1feTzEamRHbq32BRDibL1IOitK_yNjta8OeqlhunqxuP3n2UlMwUSvGTg7X_3hUFCf9VM46qoCnr3CR2e6fQ24FaAfDUyQTd3szYbPkz1I68BEwEbB7ulztT4k7zYtLPISFe3Xql1va8pjuKlS=s16000&quot; /&gt;&lt;/a&gt;
  &lt;/div&gt;
  &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;
  &lt;p&gt;&lt;/p&gt;
  
.&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;&lt;b&gt;CODE 1 (extraction des configurations)&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;.
&lt;pre class=&quot;prettyprint&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;font size=&quot;2.5pt&quot;&gt;
import clr
import sys
import System

# Import RevitAPI
clr.AddReference(&quot;RevitAPI&quot;)
import Autodesk
from Autodesk.Revit.DB import *
import Autodesk.Revit.DB as DB
from Autodesk.Revit.Attributes import *
from Autodesk.Revit.DB.IFC import *


clr.AddReference(&quot;RevitServices&quot;)
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)


IFCExportConfiguration = None
IFCExportConfigurationsMap = None
pf_path = System.Environment.GetFolderPath(System.Environment.SpecialFolder.ProgramFilesX86)
pf_data_path = System.Environment.GetFolderPath(System.Environment.SpecialFolder.CommonApplicationData)
ifc_bundle_path = &quot;{0}\\Autodesk\\ApplicationPlugins\\IFC {1}.bundle\\Contents\\{1}&quot;.format(pf_data_path, sdkNumber)
if System.IO.Directory.Exists(ifc_bundle_path):
    print(&quot;pass1&quot;)
    sys.path.append(ifc_bundle_path)
    if sdkNumber &amp;lt; 2027:
        clr.AddReference(&quot;IFCExporterUIOverride&quot;)
        from BIM.IFC.Export.UI import IFCExportConfigurationsMap, IFCExportConfiguration, IFCCommandOverrideApplication
    else:
        clr.AddReference(&quot;Revit.IFC.Export&quot;)
        from Revit.IFC.Export.Utility import IFCExportConfigurationsMap, IFCExportConfiguration
        clr.AddReference(&quot;IFCExporterUIOverride&quot;)
        from BIM.IFC.Export.UI import IFCCommandOverrideApplication
else:
    ifc_addin_path = &quot;{}\\Autodesk\\Revit {}\\AddIns\IFCExporterUI&quot;.format(pf_path, sdkNumber)
    if System.IO.Directory.Exists(ifc_addin_path):
        print(&quot;pass2&quot;)
        sys.path.append(ifc_addin_path)
        clr.AddReference(&quot;Autodesk.IFC.Export.UI&quot;)
        from BIM.IFC.Export.UI import IFCExportConfigurationsMap, IFCExportConfiguration, IFCCommandOverrideApplication

import json

ifc_dict_config = {}
if IFCExportConfigurationsMap is not None:
    idfdocA = IFCCommandOverrideApplication.TheDocument
    if idfdocA is None:
        propinfo = clr.GetClrType(IFCCommandOverrideApplication).GetProperty(&#39;TheDocument&#39;)
        propinfo.SetValue(None, doc)
    configurationsMap = IFCExportConfigurationsMap(doc)
    configurationsMap.AddBuiltInConfigurations()
    configurationsMap.AddSavedConfigurations({})
    
    for config in configurationsMap.Values:
        dict_ifc_version_str = {&quot;IFC_Version_str&quot;: config.IFCVersion.ToString() }
        dict_config = json.loads(config.SerializeConfigToJson())
        # merge dictionaries
        merge_dict_3 = dict(dict_ifc_version_str,**dict_config)
        ifc_dict_config[config.Name] = merge_dict_3
  
OUT = ifc_dict_config
&lt;/font&gt;&lt;/code&gt;&lt;/pre&gt;    
      
.&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;&lt;b&gt;CODE 2 (Export IFC)&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: georgia; font-size: medium;&quot;&gt;Actuellement (sous Pythonnet3 + Revit 2027.1 ) une erreur se produit avec &lt;code class=&quot;nocode&quot; style=&quot;background: rgb(240, 240, 240); border-radius: 3px; border: 1px solid rgb(208, 208, 208); font-family: courrier; font-size: 17.3333px; padding-left: 2px; padding-right: 2px; text-align: justify;&quot;&gt;Document.Export(String, String, IFCExportOptions)&lt;/code&gt; , une solution de contournement consiste à utiliser la Reflection.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;.
&lt;pre class=&quot;prettyprint&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;font size=&quot;2.5pt&quot;&gt;
import clr
import sys
import System
from System.Collections.Generic import *

clr.AddReference(&#39;ProtoGeometry&#39;)
from Autodesk.DesignScript.Geometry import *


clr.AddReference(&quot;System.Reflection&quot;)
from System.Reflection import BindingFlags

clr.AddReference(&quot;System.Core&quot;)
clr.ImportExtensions(System.Linq)

# Import RevitAPI
clr.AddReference(&quot;RevitAPI&quot;)
import Autodesk
from Autodesk.Revit.DB import *
import Autodesk.Revit.DB as DB
from Autodesk.Revit.Attributes import*
from Autodesk.Revit.DB.IFC import*

# Import DocumentManager and TransactionManager
clr.AddReference(&quot;RevitServices&quot;)
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
app = uiapp.Application
uidoc = DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument
sdkNumber = int(app.VersionNumber)

IFCExportConfiguration = None
IFCExportConfigurationsMap = None
pf_path = System.Environment.GetFolderPath(System.Environment.SpecialFolder.ProgramFilesX86)
pf_data_path = System.Environment.GetFolderPath(System.Environment.SpecialFolder.CommonApplicationData)
ifc_bundle_path = &quot;{0}\\Autodesk\\ApplicationPlugins\\IFC {1}.bundle\\Contents\\{1}&quot;.format(pf_data_path, sdkNumber)
if System.IO.Directory.Exists(ifc_bundle_path):
    sys.path.append(ifc_bundle_path)
    if sdkNumber &amp;lt; 2027:
        clr.AddReference(&quot;IFCExporterUIOverride&quot;)
        from BIM.IFC.Export.UI import IFCExportConfigurationsMap, IFCExportConfiguration, IFCCommandOverrideApplication
    else:
        clr.AddReference(&quot;Revit.IFC.Export&quot;)
        from Revit.IFC.Export.Utility import IFCExportConfigurationsMap, IFCExportConfiguration
        clr.AddReference(&quot;Revit.IFC.Common&quot;)
        from Revit.IFC.Common.Extensions import IFCClassificationMgr
        clr.AddReference(&quot;IFCExporterUIOverride&quot;)
        from BIM.IFC.Export.UI import IFCCommandOverrideApplication
else:
    ifc_addin_path = &quot;{}\\Autodesk\\Revit {}\\AddIns\IFCExporterUI&quot;.format(pf_path, sdkNumber)
    if System.IO.Directory.Exists(ifc_addin_path):
        print(&quot;pass2&quot;)
        sys.path.append(ifc_addin_path)
        clr.AddReference(&quot;Autodesk.IFC.Export.UI&quot;)
        from BIM.IFC.Export.UI import IFCExportConfigurationsMap, IFCExportConfiguration, IFCCommandOverrideApplication
        
        
def exportIfc(current_doc, pathfolder, name, ifcExportConfig, view3DId=ElementId.InvalidElementId):
    global error
    #
    if name.endswith(&quot;.rvt&quot;):
        name = name.replace(&quot;.rvt&quot;, &quot;.ifc&quot;)
    #
    #When using transactions with documents other than the primary document,better luck creating transactions from scratch.
    TransactionManager.Instance.ForceCloseTransaction()
    # define options
    options = IFCExportOptions()
    if ifcExportConfig is not None :
        #Define the of a 3d view to export
        
        # copy settings of the myIFCExportConfiguration to the IFCExportOptions
        if sdkNumber &amp;lt; 2027:
            exportViewId = ElementId.InvalidElementId # or None -&amp;gt; add view in options
            ifcExportConfig.UpdateOptions(options, exportViewId)
        else:
            # Revit 2027 and above
            if view3DId == ElementId.InvalidElementId:
                ifcExportConfig.UseActiveViewGeometry = False
                ifcExportConfig.VisibleElementsOfCurrentView = False
            else:
                ifcExportConfig.VisibleElementsOfCurrentView = True
                ifcExportConfig.ActiveViewId = view3DId
            #
            if ifcExportConfig.ExportUserDefinedPsets:
                userDefinedPsetsFileName = System.IO.Path.GetFileName(ifcExportConfig.ExportUserDefinedPsetsFileName)
                ifcExportConfig.ExportUserDefinedPsetsFileName = System.IO.Path.Combine(pathfolder, userDefinedPsetsFileName)
            #
            if ifcExportConfig.ExportUserDefinedPsets:
                userDefinedParameterMappingFileName = System.IO.Path.GetFileName(ifcExportConfig.ExportUserDefinedParameterMappingFileName)
                ifcExportConfig.ExportUserDefinedParameterMappingFileName = System.IO.Path.Combine(pathfolder, userDefinedParameterMappingFileName)
                
            ifcExportConfig.UpdateOptions(current_doc, options, view3DId, False)
            # call this before the Export IFC transaction starts, as it has its own transaction.
            IFCClassificationMgr.DeleteObsoleteSchemas(current_doc)
    
    #
    t = Transaction(current_doc, &#39;Export IFC&#39;)
    t.Start()
    failureOptions = t.GetFailureHandlingOptions()
    failureOptions.SetClearAfterRollback(False)
    t.SetFailureHandlingOptions(failureOptions)
    #
    try:
        #
        current_doc.Regenerate()
        result = current_doc.GetType().InvokeMember(&quot;Export&quot;, BindingFlags.InvokeMethod , None, current_doc, (pathfolder, name, options) )
    except Exception as ex:
        print(ex)
        t.RollBack()
        t.Dispose()
        return 0
    else:
        t.RollBack() # instead of t.Dispose()
        t.Dispose()
        return pathfolder + &#39;\\&#39; + name
        
        
ifc_config_map = IN[0]
pathfolder = IN[1]
name = IN[2]
ifc_config_name = IN[3]

ifcExportConfig = ifc_config_map[ifc_config_name]

exportIfc(doc, pathfolder, name, ifcExportConfig)

&lt;/font&gt;&lt;/code&gt;&lt;/pre&gt;&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;
    &lt;tbody&gt;
      &lt;tr&gt;
        &lt;td style=&quot;text-align: center;&quot;&gt;
          &lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjX4HgFuJk4zVeKpNmwucWpZreKpzZOBpQqo_radBVXbUZASA0RgV22C7l3quNPgcMCJfm4gIZe9PC5ixaV4VB9JF_lAUIXwyUHCfYloj467kxIu_FiQlmI3Cjkr9cMPEsTVCVV5MSDjfYBLCz3dMSCYkJWbxA-WeOXrhvXBJLi95lgin6RQk-CK0lwozNS/s1024/le%20monde%20se%20divise%20en%202%20categories.png&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;1024&quot; data-original-width=&quot;1024&quot; height=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjX4HgFuJk4zVeKpNmwucWpZreKpzZOBpQqo_radBVXbUZASA0RgV22C7l3quNPgcMCJfm4gIZe9PC5ixaV4VB9JF_lAUIXwyUHCfYloj467kxIu_FiQlmI3Cjkr9cMPEsTVCVV5MSDjfYBLCz3dMSCYkJWbxA-WeOXrhvXBJLi95lgin6RQk-CK0lwozNS/w400-h400/le%20monde%20se%20divise%20en%202%20categories.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;
        &lt;/td&gt;
      &lt;/tr&gt;         
      &lt;tr&gt;
        &lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;
          &lt;i&gt;Le monde se divise en deux catégories......&lt;br /&gt;NWC&amp;nbsp; VS&amp;nbsp;
            IFC&lt;br /&gt;Close&amp;nbsp; VS&amp;nbsp; Open&lt;br /&gt;sans hôte&amp;nbsp; VS&amp;nbsp;
            hôte par face&lt;br /&gt;Modèle Générique&amp;nbsp; VS&amp;nbsp; Site&lt;br /&gt;Etc...&lt;br /&gt;&lt;br /&gt;La
            meilleure, c&#39;est celle qui fait avancer le projet…&lt;br /&gt;&lt;br /&gt;&lt;/i&gt;
        &lt;/td&gt;
      &lt;/tr&gt;
    &lt;/tbody&gt;
  &lt;/table&gt;
  &lt;br /&gt;
  &lt;p&gt;&lt;/p&gt;
  &lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;/div&gt;
  &lt;br /&gt;&lt;br /&gt;
  &lt;p&gt;&lt;/p&gt;
  &lt;div&gt;
    &lt;a id=&quot;bottom&quot;&gt; &lt;/a&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='https://voltadynabim.blogspot.com/feeds/4527036482983012636/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='https://voltadynabim.blogspot.com/2024/04/dynamo-python-export-ifc-configurations.html#comment-form' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/4001721146719322746/posts/default/4527036482983012636'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/4001721146719322746/posts/default/4527036482983012636'/><link rel='alternate' type='text/html' href='https://voltadynabim.blogspot.com/2024/04/dynamo-python-export-ifc-configurations.html' title='[Dynamo += Python] Export IFC : configurations Utilisateur (MAJ 05/09/2026)'/><author><name>Cyril</name><uri>http://www.blogger.com/profile/08389811365235224682</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgY3Iz0xq8QpQu6njnL6IyeBXjbJyBFxD1nsxDcqUHlCs3yQZih7HlcLEre3RYjOSPnDg544905lHz4K6SHzbXgmdITwUktyM_FTkcYSINI0wkNhXcYX_4i9Kx4176Mxm4/s113/1608331968791.jfif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/a/AVvXsEheNCMuJClyySo2riXYwP2paAn--xN4axsaCmmR58pn48A9VUQecyl4Fq_8MpxUy_MBtOuD3CAYjv5_GsD685g35K65ajQEUpuzMNS0Z64L5Kv5os6joVOxC2gqevp5nDYpDZsQ3KOYMLF3_Wqw7szRiTgPoNRRZPRdkQbigIONHzM4f7NdMOlLpGGMr5Su=s72-w400-h400-c" height="72" width="72"/><thr:total>0</thr:total></entry></feed>