Dynamo
Primer for v2.0
English
English
  • About
  • Introduction
    • What is Dynamo & How Does It Work?
    • Primer User Guide, Dynamo Community & Platform
  • Setup for Dynamo
  • User Interface
    • Workspace
    • Library
  • Nodes and Wires
  • Essential Nodes & Concepts
    • Index of Nodes
    • Geometry for Computational Design
      • Geometry Overview
      • Vector, Plane & Coordinate System
      • Points
      • Curves
      • Surfaces
      • Solids
      • Meshes
    • The Building Blocks of Programs
      • Data
      • Math
      • Logic
      • Strings
      • Color
    • Designing with Lists
      • What's a List
      • Working with Lists
      • Lists of Lists
      • n-Dimensional Lists
    • Dictionaries in Dynamo
      • What is a Dictionary
      • Dictionary Nodes
      • Dictionaries in Code Blocks
      • Revit Use-Cases
  • Custom Nodes & Packages
    • Custom Nodes
      • Custom Node Introduction
      • Creating a Custom Node
      • Publishing to Your Library
    • Packages
      • Package Introduction
      • Package Case Study - Mesh Toolkit
      • Developing a Package
      • Publishing a Package
      • Zero-Touch Importing
  • Dynamo for Revit
    • The Revit Connection
    • Selecting
    • Editing
    • Creating
    • Customizing
    • Documenting
  • Dynamo for Civil 3D
    • The Civil 3D Connection
    • Getting Started
    • Node Library
    • Sample Workflows
      • Roads
        • Light Pole Placement
      • Land
        • Service Placement
      • Utilities
        • Rename Structures
      • Rail
        • Clearance Envelope
      • Surveying
        • Point Group Management
    • Advanced Topics
      • Object Binding
      • Python and Civil 3D
    • Dynamo Player
    • Useful Packages
    • Resources
  • Dynamo in Forma Beta
    • Set Up Dynamo Player in Forma
    • Add and Share Graphs in Dynamo Player
    • Run Graphs in Dynamo Player
    • Dynamo compute service differences with Desktop Dynamo
  • Coding in Dynamo
    • Code Blocks and DesignScript
      • What's a Code Block
      • DesignScript Syntax
      • Shorthand
      • Functions
    • Geometry with DesignScript
      • DesignScript Geometry Basics
      • Geometric Primitives
      • Vector Math
      • Curves: Interpolated and Control Points
      • Translation, Rotation, and Other Transformations
      • Surfaces: Interpolated, Control Points, Loft, Revolve
      • Geometric Parameterization
      • Intersection and Trim
      • Geometric Booleans
      • Python Point Generators
    • Python
      • Python Nodes
      • Python and Revit
      • Setup Your Own Python Template
    • Language Changes
  • Best Practices
    • Graph Strategies
    • Scripting Strategies
    • Scripting Reference
    • Managing Your Program
    • Efficiently Working With Large Data Sets In Dynamo
  • Sample Workflows
    • Getting Started Workflows
      • Parametric Vase
      • Attractor Points
    • Concept Index
  • Developer Primer
    • Build Dynamo from Source
      • Build DynamoRevit from Source
      • Managing and Updating Dependencies in Dynamo
    • Developing for Dynamo
      • Getting Started
      • Zero-Touch Case Study - Grid Node
      • Executing Python Scripts in Zero-Touch Nodes (C#)
      • Going Further with Zero-Touch
      • Advanced Dynamo Node Customization
      • Using COM (interop) types in Dynamo Packages
      • NodeModel Case Study - Custom UI
      • Updating your Packages and Dynamo Libraries for Dynamo 2.x
      • Updating your Packages and Dynamo Libraries for Dynamo 3.x
      • Extensions
      • Defining Custom Package Organization for Dynamo 2.0+
      • Dynamo Command Line Interface
      • Dynamo Integration
      • Developing For Dynamo For Revit
      • Publish a Package
      • Build a Package from Visual Studio
      • Extensions as Packages
    • Pull Requests
    • Testing Expectations
    • Examples
  • Appendix
    • Frequently Asked Questions
    • Visual Programming and Dynamo
    • Resources
    • Release Notes
    • Useful Packages
    • Example Files
    • Host Integration Map
    • Download PDF
    • Dynamo Keyboard Shortcuts
Powered by GitBook
On this page
  • API Documentation
  • Code Template
  • Example
  • Goal
  • Dataset
  • Solution Overview
  • Review API Documentation
  • Get All Catchments
  • Unwrapping Objects
  • Python Script
  • Create PolyCurves
  • Result
  • IronPython vs. CPython
Edit on GitHub
Export as PDF
  1. Dynamo for Civil 3D
  2. Advanced Topics

Python and Civil 3D

PreviousObject BindingNextDynamo Player

Last updated 1 year ago

While Dynamo is extremely powerful as a tool, it is also possible to go beyond nodes and wires and write code in textual form. There are two ways that you can do this:

  1. Write DesignScript using a Code Block

  2. Write Python using a Python node

This section will focus on how to leverage Python in the Civil 3D environment to take advantage of the AutoCAD and Civil 3D .NET APIs.

Take a look at the Python section for more general information about using Python in Dynamo.

API Documentation

Both AutoCAD and Civil 3D have several APIs available that enable developers like you to extend the core product with custom functionality. In the context of Dynamo, it is the Managed .NET APIs that are relevant. The following links are essential to understanding the structure of the APIs and how they work.

As you move through this section, there may be some concepts that you are unfamiliar with, such as databases, transactions, methods, properties, etc. Many of these concepts are core to working with the .NET APIs and are not specific to Dynamo or Python. It is beyond the scope of this section of the Primer to discuss these items in detail, so we recommend frequently referring to the above links for more information.

Code Template

When you first edit a new Python node, it will be pre-populated with template code to get you started. Here's a breakdown of the template with explanations about each block.

  1. Imports the sys and clr modules, both of which are necessary for the Python interpreter to function properly. In particular, the clr module enables .NET namespaces to be treated essentially as Python packages.

  2. Loads the standard assemblies (i.e., DLLs) for working with the managed .NET APIs for AutoCAD and Civil 3D.

  3. Adds references to standard AutoCAD and Civil 3D namespaces. These are equivalent to the using or Imports directives in C# or VB.NET (respectively).

  4. The node's input ports are accessible using a pre-defined list called IN. You can access the data in a specific port using its index number, for example dataInFirstPort = IN[0].

  5. Gets the active Document and Editor.

  6. Locks the Document and initiates a Database transaction.

  7. This where you should place the bulk of your script's logic.

  8. Uncomment this line to commit the transaction after your main work is done.

  9. If you want to output any data from the node, assign it to the OUT variable at the end of your script.

Want to customize? You can modify the default Python template by editing the PythonTemplate.py file located in C:\ProgramData\Autodesk\C3D <version>\Dynamo.

Example

Let's work through an example to demonstrate some of the essential concepts of writing Python scripts in Dynamo for Civil 3D.

Goal

Dataset

Here are examples files that you can reference for this exercise.

Solution Overview

Here's an overview of the logic in this graph.

  1. Review the Civil 3D API documentation

  2. Select all of the Catchments in the document by layer name

  3. "Unwrap" the Dynamo Objects to access the internal Civil 3D API members

  4. Create Dynamo points from AutoCAD points

  5. Create PolyCurves from the points

Let's go!

Review API Documentation

Get All Catchments

Now we can start building our graph logic. The first thing to do is get a list of all the Catchments in the Document. There are nodes available for this, so we don't need to include it in the Python script. Using nodes provides better visibility for someone else that might read the graph (versus burying lots of code in a Python script), and it also keeps the Python script focused on one thing: returning the boundary points of the Catchments.

Note here that the output from the All Objects on Layer node is a list of CivilObjects. This is because Dynamo for Civil 3D doesn't currently have any nodes for working with Catchments, which is the whole reason why we need to access the API through Python.

Unwrapping Objects

Before we go further, we need to briefly touch on an important concept. In the Node Library section, we discussed how Objects and CivilObjects are related. To add a little more detail to this, a Dynamo Object is a wrapper around an AutoCAD Entity. Similarly, a Dynamo CivilObject is a wrapper around a Civil 3D Entity. You can "unwrap" an Object by accessing its InternalDBObject or InternalObjectId properties.

Dynamo Type
Wraps

Object Autodesk.AutoCAD.DynamoNodes.Object

Entity Autodesk.AutoCAD.DatabaseServices.Entity

CivilObject Autodesk.Civil.DynamoNodes.CivilObject

Entity Autodesk.Civil.DatabaseServices.Entity

As a rule of thumb, it is generally safer to get the Object ID using the InternalObjectId property and then access the wrapped object in a transaction. This is because the InternalDBObject property will return an AutoCAD DBObject that is not in a writable state.

Python Script

Here's the complete Python script that does the work of accessing the internal Catchment objects are getting their boundary points. The highlighted lines represent those that are modified/added from the default template code.

Click on the underlined text in the script for an explanation of each line.

# Load the Python Standard and DesignScript Libraries
import sys
import clr

# Add Assemblies for AutoCAD and Civil3D
clr.AddReference('AcMgd')
clr.AddReference('AcCoreMgd')
clr.AddReference('AcDbMgd')
clr.AddReference('AecBaseMgd')
clr.AddReference('AecPropDataMgd')
clr.AddReference('AeccDbMgd')



# Import references from 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 *

# Import references from Civil3D
from Autodesk.Civil.ApplicationServices import *
from Autodesk.Civil.DatabaseServices import *



# The inputs to this node will be stored as a list in the IN variables.
 = 

 


    


    
    
adoc = Application.DocumentManager.MdiActiveDocument
editor = adoc.Editor

with adoc.LockDocument():
    with adoc.Database as db:
        
        with db.TransactionManager.StartTransaction() as t:
                          
                
                                
                
                    
                                        
                    
                    
                        
                        
                    
            
            # Commit before end transaction
            
            pass
            
# Assign your output to the OUT variable.

As a rule of thumb, it is a best practice to include the bulk of your script logic inside a transaction. This ensures safe access to the objects that your script is reading/writing. In many cases, omitting a transaction can cause a fatal error.

Create PolyCurves

At this stage, the Python script should output a list of Dynamo points that you can see in the background preview. The last step is to simply create PolyCurves from the points. Note that this could also be accomplished directly in the Python script, but we've intentionally put it outside the script in a node so that it is more visible. Here's what the final graph looks like.

Result

And here's the final Dynamo geometry.

IronPython vs. CPython

Just a quick note here before we wrap up. Depending on which version of Civil 3D you are using, the Python node may be configured differently. In Civil 3D 2020 and 2021, Dynamo used a tool called IronPython to move data between .NET objects and Python scripts. In Civil 3D 2022, however, Dynamo transitioned to use the standard native Python interpreter (aka CPython) instead that uses Python 3. Benefits of this transition include access to popular modern libraries and new platform features, essential maintenance, and security patches.

Get the boundary geometry of all Catchments in a drawing.

Before we start building our graph and writing code, it's a good idea to take a look at the Civil 3D API documentation and get a sense of what the API makes available to us. In this case, there's a that will return the boundary points of the Catchment. Note that this property returns a Point3dCollection object, which is not something that Dynamo will know what to do with. In other words, we won't be able to create a PolyCurve from a Point3dCollection, so eventually we'll need to convert everything to Dynamo points. More on that later.

Mission accomplished!

You can read more about this transition and how to upgrade legacy scripts on the . If you want to keep using IronPython, then you will simply need to install the DynamoIronPython2.7 package using the Dynamo Package Manager.

🎯
🎉
property in the Catchment class
Dynamo Blog
visual programming
AutoCAD .NET API Developer's Guide
AutoCAD .NET API Reference Guide
Civil 3D .NET API Developer's Guide
Civil 3D .NET API Reference Guide
15KB
Python_Catchments.dyn
961KB
Python_Catchments.dwg
The default Python template in Civil 3D
Getting all of the Catchments in the Document by layer
The final graph
The resulting Dynamo PolyCurves for the Catchment boundaries