Python y Civil 3D

Aunque Dynamo es extremadamente eficaz como herramienta de programación visual, también es posible ir más allá de los nodos y los cables, y escribir código en forma de texto. Existen dos formas de hacerlo:

  1. Escribir DesignScript mediante un bloque de código

  2. Escribir Python mediante un nodo de Python

Esta sección se centrará en cómo aprovechar Python en el entorno de Civil 3D para sacar partido de las API de .NET de AutoCAD y Civil 3D.

Consulte la sección Python para obtener información sobre cómo usar Python en Dynamo.

Documentación de las API

Tanto AutoCAD como Civil 3D disponen de varias API que permiten a desarrolladores como usted ampliar el producto principal con funciones personalizadas. En el contexto de Dynamo, lo pertinente son las API de .NET administrado. Los siguientes vínculos son esenciales para conocer la estructura de las API y su funcionamiento.

Manual para desarrolladores de las API de .NET de AutoCAD

Manual de referencia de las API de .NET de AutoCAD

Manual para desarrolladores de las API de .NET de Civil 3D

Manual de referencia de las API de .NET de Civil 3D

A medida que avance por esta sección, es posible que haya algunos conceptos con los que no esté familiarizado, como bases de datos, transacciones, métodos, propiedades, etc. Muchos de estos conceptos son fundamentales para trabajar con las API de .NET y no son específicos de Dynamo o Python. Está fuera del alcance de esta sección del manual abordar estos temas en detalle, por lo que se recomienda consultar con frecuencia los vínculos anteriores para obtener más información.

Plantilla de código

Al editar por primera vez un nuevo nodo de Python, este se rellenará previamente con el código de la plantilla para que pueda empezar. A continuación, se muestra un desglose de la plantilla con explicaciones sobre cada bloque.

  1. Importa los módulos sys y clr, que son necesarios para que el intérprete de Python funcione correctamente. En concreto, el módulo clr permite que los espacios de nombres de .NET se traten básicamente como paquetes de Python.

  2. Carga los ensamblajes estándar (es decir, los archivos DLL) para trabajar con las API de .NET administrado para AutoCAD y Civil 3D.

  3. Añade referencias a espacios de nombres estándar de AutoCAD y Civil 3D. Equivalen a las directivas using o Imports de C# o VB.NET (respectivamente).

  4. Se puede acceder a los puertos de entrada del nodo mediante una lista predefinida denominada IN. Puede acceder a los datos de un puerto específico mediante su número de índice como, por ejemplo, dataInFirstPort = IN[0].

  5. Obtiene el documento y el editor activos.

  6. Bloquea el documento e inicia una transacción de base de datos.

  7. Aquí debe colocar la mayor parte de la lógica de la secuencia de comandos.

  8. Anule los comentarios de esta línea para confirmar la transacción una vez que haya terminado el trabajo principal.

  9. Si desea generar datos del nodo, asígnelo a la variable OUT al final de la secuencia de comandos.

¿Desea personalizar la plantilla? Puede modificar la plantilla de Python por defecto. Para ello, edite el archivo PythonTemplate.py ubicado en C:\ProgramData\Autodesk\C3D <version>\Dynamo.

Ejemplo

Veamos un ejemplo para mostrar algunos de los conceptos básicos de la escritura de secuencias de comandos de Python en Dynamo for Civil 3D.

Objetivo

🎯 Obtenga la geometría de contorno de todas las cuencas vertientes de un dibujo.

Conjunto de datos

A continuación, encontrará archivos de ejemplo que puede consultar para este ejercicio.

Descripción general de la solución

A continuación, se ofrece una descripción general de la lógica de este gráfico.

  1. Consultar la documentación de la API de Civil 3D

  2. Seleccionar todas las cuencas vertientes del documento por nombre de capa

  3. "Desenvolver" los objetos de Dynamo para acceder a los miembros internos de la API de Civil 3D

  4. Crear puntos de Dynamo a partir de puntos de AutoCAD

  5. Crear PolyCurves a partir de los puntos

¡Empecemos!

Consultar la documentación de la API

Antes de empezar a crear el gráfico y escribir el código, conviene echar un vistazo a la documentación de la API de Civil 3D y hacerse una idea de lo que esta pone a nuestra disposición. En este caso, hay una propiedad de la clase Catchment que devolverá los puntos de contorno de la cuenca vertiente. Tenga en cuenta que esta propiedad devuelve un objeto Point3dCollection, que Dynamo desconoce cómo utilizar. En otras palabras, no podremos crear una PolyCurve a partir de un objeto Point3dCollection, por lo que al final tendremos que convertirlo todo en puntos de Dynamo. Ya abordaremos este tema más adelante.

Obtener todas las cuencas vertientes

Ahora podemos empezar a crear la lógica del gráfico. Lo primero que hay que hacer es obtener una lista de todas las cuencas vertientes del documento. Hay nodos disponibles para ello, por lo que no necesitamos incluirla en la secuencia de comandos de Python. El uso de nodos proporciona una mejor visibilidad para otra persona que pueda leer el gráfico (en lugar de incluir mucho código en una secuencia de comandos de Python), y, además, mantiene la secuencia de comandos de Python centrada en un único objetivo, devolver los puntos límite de las cuencas vertientes.

Observe que la salida del nodo All Objects on Layer es una lista de CivilObjects. Esto se debe a que Dynamo for Civil 3D no dispone actualmente de ningún nodo que permita trabajar con cuencas vertientes, que es el motivo por el que necesitamos acceder a la API a través de Python.

Desenvoltura de objetos

Antes de continuar, debemos abordar brevemente un concepto importante. En la sección Biblioteca de nodos, se ha explicado cómo se relacionan los objetos y CivilObjects. Para añadir algo más de detalle, un objeto de Dynamo es una envoltura alrededor de una entidad de AutoCAD. De forma similar, un CivilObject de Dynamo es una envoltura alrededor de una entidad de Civil 3D. Puede "desenvolver" un objeto. Para ello, acceda a sus propiedades InternalDBObject o InternalObjectId.

Tipo de DynamoEnvolturas

Objeto Autodesk.AutoCAD.DynamoNodes.Object

Entidad Autodesk.AutoCAD.DatabaseServices.Entity

CivilObject Autodesk.Civil.DynamoNodes.CivilObject

Entidad Autodesk.Civil.DatabaseServices.Entity

Por regla general, es más seguro obtener el ID de objeto mediante la propiedad InternalObjectId y, a continuación, acceder al objeto envuelto en una transacción. Esto se debe a que la propiedad InternalDBObject devolverá un DBObject de AutoCAD que no se encuentra en estado de escritura.

Secuencia de comandos de Python

A continuación, se muestra la secuencia de comandos completa de Python que realiza el trabajo de acceder a los objetos de cuenca vertiente internos para obtener sus puntos de contorno. Las líneas resaltadas representan las que se han modificado o añadido a partir del código de plantilla por defecto.

Haga clic en el texto subrayado en la secuencia de comandos para obtener una explicación de cada línea.

# Cargar las bibliotecas de normas y DesignScript de Python
import sys
import clr

# Añadir ensamblajes para AutoCAD y Civil 3D
clr.AddReference('AcMgd')
clr.AddReference('AcCoreMgd')
clr.AddReference('AcDbMgd')
clr.AddReference('AecBaseMgd')
clr.AddReference('AecPropDataMgd')
clr.AddReference('AeccDbMgd')



# Importar referencias de 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 *

# Importar referencias de Civil 3D
from Autodesk.Civil.ApplicationServices import *
from Autodesk.Civil.DatabaseServices import *

from Autodesk.DesignScript.Geometry import Point as DynPoint

# Las entradas de este nodo se almacenarán como una lista en las 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)
            
            # Validar antes de finalizar la transacción
            
            pass
            
# Asigne la salida a la variable OUT.
OUT = output

Como regla general, es recomendable incluir la mayor parte de la lógica de la secuencia de comandos en una transacción. De este modo, se garantiza un acceso seguro a los objetos que la secuencia de comandos está leyendo o escribiendo. En muchos casos, omitir una transacción puede provocar un error grave.

Crear PolyCurves

En esta fase, la secuencia de comandos de Python debería generar una lista de puntos de Dynamo que se pueden ver en la vista preliminar en segundo plano. El último paso consiste en crear simplemente PolyCurves a partir de los puntos. Tenga en cuenta que esto también podría hacerse directamente en la secuencia de comandos de Python, pero lo hemos puesto intencionadamente fuera de ella en un nodo para que resulte más visible. Este es el aspecto del gráfico final.

Resultado

Y esta es la geometría final de Dynamo.

🎉 ¡Misión cumplida!

Comparación de IronPython y CPython

Apenas una nota rápida aquí antes de terminar. En función de la versión de Civil 3D que esté utilizando, es posible que el nodo de Python se haya configurado de forma diferente. En Civil 3D 2020 y 2021, Dynamo utilizaba una herramienta denominada IronPython para desplazar datos entre objetos .NET y secuencias de comandos de Python. Sin embargo, en Civil 3D 2022, Dynamo realizó la transición al intérprete nativo de Python estándar (también conocido como CPython) que utiliza Python 3. Las ventajas de esta transición incluyen el acceso a las bibliotecas modernas más conocidas y a las nuevas funciones de la plataforma, el mantenimiento esencial y los parches de seguridad.

Puede obtener más información sobre esta transición y sobre cómo actualizar las secuencias de comandos existentes en el blog de Dynamo. Si desea seguir utilizando IronPython, solo tendrá que instalar el paquete de DynamoIronPython2.7 mediante Dynamo Package Manager.

  1. Esta línea obtiene la clase específica que necesitamos de la biblioteca de geometría de Dynamo. Tenga en cuenta que aquí se especifica import Point as DynPoint en lugar de import *, ya que este último elemento provocaría conflictos de nombres.

  2. Aquí especificamos exactamente el puerto de entrada que contiene los datos que deseamos en lugar del elemento IN por defecto, que hace referencia a la lista completa de todas las entradas.

Last updated