Python et Civil 3D

Bien que Dynamo soit un outil de programmation visuelle extrêmement puissant, il est également possible d’aller au-delà des nœuds et des fils et d’écrire du code sous forme de texte. Vous pouvez procéder de deux manières :

  1. écrire en DesignScript à l’aide d’un bloc de code ;

  2. écrire en Python à l’aide d’un nœud Python.

Cette section se concentre sur la manière d’exploiter le langage Python dans l’environnement Civil 3D afin de tirer parti des API .NET d’AutoCAD et de Civil 3D.

Consultez la section Python pour plus d’informations sur l’utilisation du Python dans Dynamo.

Documentation de l’API

AutoCAD et Civil 3D disposent de plusieurs API qui permettent aux développeurs comme vous d’étendre le produit principal avec des fonctionnalités personnalisées. Dans le contexte de Dynamo, ce sont les API .NET gérées qui sont pertinentes. Les liens suivants sont essentiels pour comprendre la structure des API et leur fonctionnement.

Guide du développeur de l’API .NET d’AutoCAD

Guide de référence de l’API .NET d’AutoCAD

Guide du développeur de l’API .NET de Civil 3D

Guide de référence de l’API .NET de Civil 3D

Au fur et à mesure que vous avancez dans cette section, il est possible que vous rencontriez des concepts que vous ne connaissez pas, tels que les bases de données, les transactions, les méthodes, les propriétés, etc. La plupart de ces concepts sont essentiels pour travailler avec les API .NET et ne sont pas spécifiques à Dynamo ou au Python. Cette section du guide n’a pas pour objet d’examiner ces éléments en détail. Nous vous recommandons donc de vous reporter fréquemment aux liens ci-dessus pour plus d’informations.

Modèle de code

Lorsque vous modifiez un nouveau nœud Python pour la première fois, il est prérempli avec un modèle de code pour vous aider à démarrer. Voici une analyse du modèle avec des explications sur chaque bloc.

  1. Importe les modules sys et clr, qui sont tous deux nécessaires au bon fonctionnement de l’interpréteur Python. En particulier, le module clr permet de traiter les espaces nom .NET essentiellement comme des packages Python.

  2. Charge les assemblages standard (par exemple, les DLL) pour utiliser les API .NET gérées pour AutoCAD et Civil 3D.

  3. Ajoute des références aux espaces nom AutoCAD et Civil 3D standard. Celles-ci sont équivalentes aux directives using ou Imports en C# ou VB.NET (respectivement).

  4. Les ports d’entrée du nœud sont accessibles à l’aide d’une liste prédéfinie appelée IN. Vous pouvez accéder aux données d’un port spécifique à l’aide de son numéro d’index, par exemple dataInFirstPort = IN[0].

  5. Extrait le document et l’éditeur actifs.

  6. Verrouille le document et lance une transaction de base de données.

  7. Vous devez insérer l’essentiel de la logique de votre script ici.

  8. Supprimez le commentaire de cette ligne pour valider la transaction une fois votre travail principal terminé.

  9. Si vous souhaitez générer des données à partir du nœud, affectez-les à la variable OUT à la fin de votre script.

Envie de personnaliser ? Vous pouvez modifier le modèle Python par défaut en modifiant le fichier PythonTemplate.py situé dans C:\ProgramData\Autodesk\C3D <version>\Dynamo.

Exemple

Examinons un exemple pour démontrer certains des concepts essentiels de l’écriture de scripts Python dans Dynamo for Civil 3D.

Objectif

🎯 permet d’obtenir la géométrie des limites de contour de tous les bassins versants d’un dessin.

Ensemble de données

Voici des exemples de fichiers qui peuvent vous servir de référence pour cet exercice.

Présentation de la solution

Voici une présentation de la logique de ce graphique.

  1. Consulter la documentation relative à l’API Civil 3D

  2. Sélectionner tous les bassins versants du document par nom de calque

  3. « Déballer » les objets Dynamo pour accéder aux membres internes de l’API Civil 3D

  4. Créer des points Dynamo à partir de points AutoCAD

  5. Créer des polycourbes à partir des points

Allons-y !

Consulter la documentation relative à l’API

Avant de commencer à créer le graphique et à écrire le code, il est conseillé de consulter la documentation relative à l’API Civil 3D et de se familiariser avec ses fonctionnalités. Dans ce cas, il existe une propriété dans la classe Bassin versant qui renvoie les points de limite du contour du bassin versant. Notez que cette propriété renvoie un objet Point3dCollection, que Dynamo ne saura pas traiter En d’autres termes, vous ne pourrez pas créer de polycourbe à partir d’un Point3dCollection. Par conséquent, vous devrez éventuellement tout convertir en points Dynamo. Nous y reviendrons plus tard.

Obtenir tous les bassins versants

Vous pouvez maintenant commencer à construire la logique graphique. La première chose à faire est d’obtenir une liste de tous les bassins versants du document. Des nœuds sont disponibles pour cela, il n’est donc pas nécessaire de l’inclure dans le script en Python. L’utilisation de nœuds permet une meilleure visibilité pour quiconque lirait le graphique (au lieu d’ajouter beaucoup de code dans un script Python), et cela permet également au script Python de se concentrer sur une seule chose : renvoyer les points de limite des bassins versants.

Notez ici que la sortie du nœud Tous les objets du calque est une liste de CivilObjects. En effet, Dynamo for Civil 3D ne dispose pas actuellement de nœuds pour travailler avec des bassins versants, ce qui explique pourquoi nous devons accéder à l’API en Python.

Déballer des objets

Avant d’aller plus loin, il convient d’aborder brièvement un concept important. Dans la section node-library.md, nous avons vu comment les objets CivilObjects sont liés. Pour apporter un peu plus de détails, un objet Dynamo est un wrapper autour d’une entité AutoCAD. De même, un CivilObject Dynamo est un wrapper autour d’une entité Civil 3D. Vous pouvez « déballer » un objet en accédant à ses propriétés InternalDBObject ou InternalObjectId.

Type DynamoEnveloppes

Objet Autodesk.AutoCAD.DynamoNodes.Object

Entité Autodesk.AutoCAD.DatabaseServices.Entity

CivilObject Autodesk.Civil.DynamoNodes.CivilObject

Entité Autodesk.Civil.DatabaseServices.Entity

En règle générale, il est plus sûr d’obtenir l’ID de l’objet à l’aide de la propriété InternalObjectId, puis d’accéder à l’objet enveloppé dans une transaction. En effet, la propriété InternalDBObject renvoie un objet DBObject AutoCAD qui n’est pas accessible en écriture.

Script Python

Voici le script Python complet qui permet d’accéder aux objets internes du bassin versant et d’obtenir leurs point de limite. Les lignes en surbrillance représentent celles qui sont modifiées/ajoutées par rapport au modèle de code par défaut.

Cliquez sur le texte souligné dans le script pour obtenir une explication sur chaque ligne.

# Charger les bibliothèques standard de Python et DesignScript
import sys
import clr

# Ajouter des assemblages pour AutoCAD et Civil 3D
clr.AddReference(’AcMgd’)
clr.AddReference(’AcCoreMgd’)
clr.AddReference(’AcDbMgd’)
clr.AddReference(’AecBaseMgd’)
clr.AddReference(’AecPropDataMgd’)
clr.AddReference(’AeccDbMgd’)



# Importer des références à partir d’AutoCAD
from Autodesk.AutoCAD.Runtime import *
from Autodesk.AutoCAD.ApplicationServices import *
from Autodesk.AutoCAD.EditorInput import *
from Autodesk.AutoCAD.DatabaseServices import *
from Autodesk.AutoCAD.Geometry import *

# Importer des références à partir de Civil 3D
from Autodesk.Civil.ApplicationServices import *
from Autodesk.Civil.DatabaseServices import *

from Autodesk.DesignScript.Geometry import Point as DynPoint

# Les entrées de ce nœud seront stockées sous forme de liste dans les variables IN.
 = IN[0]

 

if objs is None:
    

if not isinstance(objs, list):
    
    
adoc = Application.DocumentManager.MdiActiveDocument
editor = adoc.Editor

with adoc.LockDocument():
    with adoc.Database as db:
        
        with db.TransactionManager.StartTransaction() as t:
            for obj in objs:              
                
                aeccObj = t.GetObject(id, OpenMode.ForRead)                
                
                    catchment = aeccObj
                                        
                    dynPnts = []
                    
                        pnt = DynPoint.ByCoordinates(acPnt.X, acPnt.Y, acPnt.Z)
                        
                    output.append(dynPnts)
            
            # Valider avant de terminer la transaction
            
            pass
            
# Attribuer la sortie à la variable OUT.
OUT = output

En règle générale, il est recommandé d’inclure l’essentiel de la logique de votre script dans une transaction. Cela garantit un accès sécurisé aux objets que votre script lit/écrit. Dans de nombreux cas, l’omission d’une transaction peut provoquer une erreur irrécupérable.

Créer des polycourbes

À ce stade, le script Python doit produire une liste de points Dynamo que vous pouvez voir dans l’aperçu en arrière-plan. La dernière étape consiste simplement à créer des polycourbes à partir des points. Notez que cette opération pourrait également être réalisée directement dans le script Python, mais vous l’avez intentionnellement placée en dehors du script dans un nœud afin qu’elle soit plus visible. Voici à quoi ressemble le graphique final.

Résultat

Et voici la géométrie Dynamo finale.

🎉 Mission accomplie !

Comparaison entre IronPython et CPython

Une petite remarque avant de conclure. Selon la version de Civil 3D que vous utilisez, le nœud Python peut être configuré différemment. Dans Civil 3D 2020 et 2021, Dynamo utilisait un outil appelé IronPython pour déplacer des données entre des objets .NET et des scripts Python. Cependant, dans Civil 3D 2022, Dynamo est passé à l’utilisation de l’interpréteur Python natif standard (également appelé CPython) qui utilisent Python 3. Les avantages de cette transition comprennent l’accès aux bibliothèques modernes les plus populaires et aux nouvelles fonctionnalités de la plateforme, la maintenance essentielle et les correctifs de sécurité.

Pour en savoir plus sur cette transition et sur la manière de mettre à jour les scripts existants, consultez le blog Dynamo. Si vous souhaitez continuer à utiliser IronPython, il vous suffit d’installer le package DynamoIronPython2.7 à l’aide du gestionnaire de package Dynamo.

  1. Cette ligne récupère la classe spécifique dont nous avons besoin à partir de la bibliothèque de géométries Dynamo. Notez que nous spécifions import Point as DynPoint ici au lieu de import *, car cette instruction introduit des conflits d’attribution de noms.

  2. Ici, nous spécifions exactement quel port d’entrée contient les données que nous voulons au lieu du IN par défaut, qui fait référence à la liste complète de toutes les entrées.

Last updated