Optimize Road Design with Dynamo for Civil 3D and Generative Design

With generative design it is possible to explore multiple scenarios and find the best solutions to the problem balancing multiple objectives. This article explains how to apply generative design and automation principles to optimize the design of a road network. The design starts from GIS inputs describing the site: its features such as the boundary, existing buildings, and streams of water. Using InfraWorks and Civil 3D, it is possible to create a model to start the definition of the design. Dynamo enables a computational design approach and defining modeling strategies to enable optimization. Finally, with Dynamo for Civil 3D, it is possible to create complex objects like alignments, profile, and corridors to curate the selected solutions and refine the modeling as needed.

Problem Statement

The goal is to find methods to leverage the generative design approach to generate options to connect key locations (defined by the designer) with a system of roads. The road cross section has a fixed width and fixed slopes for cut and fill. The design considers existing structures such as buildings, water streams, and, of course, the existing ground surface.

Figure 1. Example of a road system that connects key locations. 

The scope of this article is to focus more on the approach and show the new possible. There are working simplifications adopted to highlight critical steps in the approach. By no means this is the only way, or the “correct” way, to apply generative design for roads.

In this context, a road in the system is the combination of three types of elements:

  • A horizontal alignment, composed of straight lines and circular curves.

  • A vertical profile, defined along the alignment and composed of straight segments; the combination of alignment and profile generates the road baseline.

  • A set of cross sections, each of which attaches to the baseline on the mid-point of the horizontal segment representing the road pavement.

Figure 2. In this context, a road is defined by these three elements.

Key Considerations

Measurable objectives allow us to compare the performance of two different options. Below is a list of common objectives for road design optimization.


  • Number of clashes

  • Number of water stream crossings (a proxy for costs of extra structures like bridges and culverts)

  • Length

  • Absolute cut

  • Absolute fill

  • Cut/fill balance


  • Number of key locations served

  • Visibility

The result of the comparison of the objectives values is what allows us to rank options and guide the evolution of the study towards optimum solutions. They can even be in contrast with one another; quite often, there is no simple analytical “shortcut” to find the optimum for this kind of problems or it might be expensive to develop an algorithmic solution that is also flexible.

These are the reasons to solve these kinds of problems: it is more convenient to adopt an evolutionary strategy and, luckily, the technology to solve a multi-objective optimization exists in Generative Design in Revit (GDiR). This article illustrates how to leverage the technology in a road design context.

It might be surprising to the reader that in this approach there is tolerance for undesired options (e.g., with one or more clashes with buildings, or where no road serves one or more of the key locations).

This is a critical difference from other approaches that leverage, to various degrees, a form of automation or artificial intelligence. Different from machine learning applications, with generative design the goal is not to mimic what a designer does, but to explore a problem in search of optimal solutions.

These might be quite different from what a human would think of via leveraging their instincts or experience, and this is part of the value of an unbiased objective-driven approach.

The designer defines the strategy used in a generative design study, which allows suboptimal solutions because, over time, it will uncover the relationships among the design variables and performing solutions thanks to the evolutionary algorithm used by GDiR.

In this new paradigm, the designers’ creativity is in how they frame a problem, defining which strategies to adopt and what objectives to consider to set up a generative design study. New skills are required to unlock the potential of this approach.

Add the Data via InfraWorks and Civil 3D

It is beyond the scope of this article to give a detailed overview of InfraWorks and Civil 3D software for civil infrastructure design. The generative design capabilities for gradings in Civil 3D are not taking part in the workflow analyzed in this document.

Suffice to say that this software integration is key to acquire the necessary data to start the design. The proposed use case starts from InfraWorks connecting to the ArcGIS services and downloading the data of the context such as buildings, utilities, etc., and then it is transferred and refined in Civil 3D, integrating also other data sources (e.g., SHP files) or directly via designer input.

Want to share your knowledge?
Write an article for AU

Define the Logic in Dynamo for Civil 3D

Using Dynamo for Civil 3D it is possible to read the information contained in a DWG document, derive inputs, and combine them into a custom logic to create, for example, AutoCAD or Civil 3D objects. In this context, Dynamo for Civil 3D allows us to acquire the fixed inputs that will not change during a generative design study; for example, the existing ground mesh, the coordinates of the key locations, the boundary of the study area, etc.

In essence, Dynamo allows us to extract the underlying geometry entities from the inputs of AutoCAD and Civil 3D/Map 3D objects. This is a critical step of the generative design study as, at the time of writing, it is not possible to leverage the nodes that operate on AutoCAD or Civil 3D objects directly (e.g., calculate the profile projecting a horizontal alignment on the existing ground).

This is the reason optimizing a Civil 3D corridor directly is not allowed, but it is still possible to optimize its main geometrical components (alignment, profile, and cross sections definitions).

Civil 3D Toolkit

The Civil 3D toolkit is a free package for Dynamo for Civil 3D that contains extensions of the out-of-the-box nodes to cover more workflows in AutoCAD and Civil 3D using Dynamo. The user can install the package from the Dynamo Package Manager.

Related: Supercharge Your Dynamo Graph with Civil 3D Toolkit with Jowenn Lua

In this context, it facilitates the acquisition of information such as the geometries of Map 3D polygons and polylines or extracting a quick mesh representation of the existing ground. Unfortunately, at the time of writing, there is not much that we can do with a mesh via Dynamo nodes or via Dynamo packages. This is one of the reasons to develop an external Python module to deal with these kinds of geometry entities.

It also provides facilitations to directly create more complex objects such as alignments, profile, assemblies, and subassemblies and combine them into a Civil 3D corridor with baseline, regions, and targets. I refer to this usage of the Civil 3D Toolkit as “automation." For more information about the Civil 3D Toolkit, refer to Computational Design for Civil Engineers and the Dynamo Forum.

Leverage Generative Design in Revit and Use the Results in Civil 3D

To use Generative Design in Revit (GDiR), we need to first create the logic in a Dynamo graph and then export it with its dependencies for generative design. If there are any problems, the tool will report the corrective actions to take. During the export it is possible to add a description and a thumbnail to clearly identify the study and provide high-level documentation.

From the Revit user interface, under Manage, it is possible to launch generative design and create a new study. A list of the available studies will appear and selecting one of them will open the setup window from which it is possible to launch the study. Get more information on how to set up a generative design study.

When the study completes all the cycles or when the designer stops the calculations, the designer can select a solution from the GDiR interface and send it back to Dynamo. From here it is possible to leverage the same concept of serialization but in this case applying it to the output, or surrogate model, representing the Alignments and Profiles. These create the basic ingredients of Civil 3D objects that combined generate a Corridor.

Introduction to Dynamo and Computational Design

Dynamo is a platform that can define algorithms visually and the sequence of instructions are generated using blocks called nodes that perform predefined tasks, joined together in sequence using Connectors. A Dynamo algorithm is called a Graph to emphasize the visual programming approach which is one of the main differences between Dynamo and any other scripting language.

Figure 3: Visual programming in Dynamo. 

Dynamo is a sort of digital Swiss knife that can contain just the right blade for the job and even if it is very intuitive in the way it can be used, it is also highly effective. Another important characteristic of Dynamo is that, for whatever reason, if a particular blade should be missing, it supports several ways to either add one from a public repository of external packages or create more sophisticated functionalities using traditional scripting languages such as Python or C#.

Figure 4. Dynamo is a flexible platform for automation and visual programming that supports customization.

Dynamo commoditizes programming and brings it closer to the designers, taking care of the sophisticated operations such as handling databases and transactions, serializing changes, and updating the models rather than performing a “fire-and-forget” automation. Dynamo is in the sweet spot in between interactive tools such as Civil 3D or Revit and more traditional scripting languages to leverage product APIs.

Figure 5. Dynamo as low-hanging fruit of the tree of automation tools.

Dynamo can be found as a standalone application called Sandbox but also integrated with a host application such as Revit or Civil 3D. You can find more information about Dynamo integrations and where to get it by visiting

The community of Dynamo users has grown with a fast and steady pace, mostly because of the ease of use of visual programming and because the community started to collect and share useful sets of nodes for free. These are bundled into packages to extend Dynamo capabilities and simplify the creation of more sophisticated workflows and boost adoption and productivity.

The community is also proactively engaging in knowledge sharing on the Dynamo forums: necessary for anyone and everyone who wants to connect, learn, find creative solutions to problems, and contribute back.

Figure 6. The Dynamo Forum on the official website

In this context, Dynamo defines the computational strategies to generate options in the study and the same graph is used to specify the variables and their ranges as well as the logic to measure the objectives.

Leverage Python to Expand the Possibilities

Dynamo supports the execution of Python scripts. Python is closer to a traditional scripting language, and it is close to reading and writing English in that it has a simple syntax and yet is powerful. For more information on the language itself, visit this link, and to know how to leverage Python in Dynamo, visit this link.

At the time of writing, Dynamo supports two different versions of Python that are compatible with .NET (IronPython 2.7 and CPython 3.7). More information on the differences and the work in progress to improve the support can be found here.

During the development of the solution, it is convenient to write external Python modules for more complex functions that can be reused in other projects and load them inside Python nodes in Dynamo. GDiR leverages multiple processes that launch Dynamo Sandbox instances (e.g., a version of Dynamo that does not possess “host nodes” such as those specific to Civil 3D) and each of them supports the load of external modules. This can be used to leverage custom functionalities and existing libraries in the generative design study.

Using an external module allows us to also leverage a Python Integrated Development Environment (e.g., PyCharm) and have more functionalities than those available in the Python nodes in Dynamo.

A simple application of this approach is adding a logging capability to a custom function to capture errors, exceptions, warnings or simply to follow the execution of the code for timing purposes.

Open a text editor and save the file as in a folder of your choosing. In the file, copy the following code:

import logging
import os
import Tempie

FORMAT = '[%(asctime)s] %(levelname)s: %(processName)s [%(process)d]:
%(module)s.%(funcName)s %(message)s'
logging.basicConfig(filename=os.path.join(tempfile.gettempdir(), 'MyLog.txt'),
level=logging.DEBUG, format=FORMAT, datefmt='%Y/%m/%d %H:%M:%S')

def my_function(): # this is the function to call from Dynamo'Start')
     # do something here'End')
     return True

In Dynamo, open a new file and insert a Python Script node, right click, and select Edit.

In the Python editor, delete the content and paste the following, then edit the path to the folder that contains

Figure 7. Example of how to load an external Python module in Dynamo.

The code in the external module writes a file called MyLog.txt in the temporary folder and when my_function() is executed appends two INFO entries capturing when the function starts and when it ends like the following:

Figure 8. Example of custom logging.

In this example, other than the time of entry, there is the severity (ERROR, EXCEPTION, WARNING, INFO, DEBUG), the name of the process and its PID (in this case 34052), the name of the module containing the custom function, the function name, and the message.

In generative design, there are multiple processes running in parallel, so it is possible to check if there are any issues in one of them and more importantly why, capturing the error messages.

In this context, I have been developing my own modules in Python to facilitate some computationally expensive operations via recursion, dealing with Civil 3D objects without leveraging the Dynamo for Civil 3D nodes (e.g., find the projection of an alignment on the mesh of the existing ground), implementing algorithms such as those to solve the Minimum Spanning Tree (e.g., used to calculate the alignments), read and write custom JSON schemas to store fixed inputs, etc.

Optimization Overview

The generative design workflow starts with gathering the data about the problem to solve. The result is like the problem DNA: it contains the essential traits used to define a surrogate model to explore the design space. In the generate phase, the "recipe" to create a potential solution to the problem is defined—in other words, an algorithm that transforms inputs and variables into a candidate solution. At the beginning, a few candidates are generated randomly.

Each candidate solution is then evaluated against a set of criteria or objectives so that can be scored and ranked against the others. The generative design enters into a cycle in which the genetic algorithm guides the exploration of the design space. At each cycle, it collects information about the performance of the candidates and over time it will refine the quality of the proposed solutions.

At the end of the study, it is possible to navigate the results to gather a better insight into the problem, uncovering the correlation between inputs and outputs to select the combinations that produced the more interesting results.
The surrogate model can then be used as a starting point to further the detailing of the selected solution.

Figure 9. Overview of the generative design approach.

Define the Approach

To create abstract schemas of the processes, I recommend the Business Process Modeling Notation (BPMN 2.0) with the free online platform As a convention, I adopted the following syntax to capture the key components of the process:

Inputs—Parameters that the designer can change but that are fixed for the duration of the study:

I: <name>=<value> (e.g., I: Width=30m)

Variables—What parameters are considered as part of the design space to explore with generative design, specifying the ranges and the step and how they are affecting the elements in the model:

V: <name> [<lower>, <upper>] | <step> (e.g., V: Rotation [0,359] | 1)

Generate—A high-level description of what constitutes a surrogate model, used to validate an option with the necessary steps to create a candidate solution.

Evaluate—A collection of objectives used to measure as proxies for the fitness/quality of the candidate options, specifying for each one if they should be minimized (minus sign) or maximized (plus sign):

e.g., Area [+], Cost [-]

Evolve – This is when Generative Design in Revit takes over and starts exploring the problem and generating options.

Figure 10. Structure of a generative design workflow.

Serialize Data

GDiR offers the possibility to store information that is not changing during a study directly into the JSON structure of the study type. This is possible via the Data.Remember node and because the Dynamo file under the hood is based on a JSON schema, and a lot of work has been done to enable the serialization (in other words to convert to a stable representation) the geometry entities in Dynamo.

In this context, once the data from Civil 3D is embedded in the study type, it can be transferred to another application that launches GDiR.

Similarly, data can also be brought back to Civil 3D following the reversed workflow, storing the results of the optimization in new Data.Remember nodes. A good planning of the Dynamo graph can help find where exactly put these nodes to run a successful study, and in the most recent versions of GDiR there have been improvements to highlight where these should go.

The same can be obtained leveraging Python built-in capabilities to read and write JSON files. The difference is that the data is not embedded in the Dynamo graph but into a separate JSON  file decoupling the logic from the data, which is always a good thing to do, as it makes it easier to manage different versions of the study. The Python approach allows us also to develop custom Encoder objects and decoders functions for custom objects.

The code below defines the basic structure for a serialization module in Python.

Figure 11. Structure of a serialization module in Python.

Design a Surrogate Model

The surrogate model is an important part of the generative design workflow. In fact, after a careful analysis you might even change your point of view regarding what kind of objects you need to deal with. This happens quite often in real-world applications of generative design. The surrogate model is an abstract representation of a real problem, a simplification if you will, and as such it helps in focusing on the key features.

Want more? Download the full class handout to read on.

Paolo Emilio Serra is a construction engineer by trade. He worked as a BIM manager in an architectural firm for five years, and has been a principal implementation consultant for Autodesk since 2014. With Autodesk he has been delivering Customer Success Services to engineering companies, supporting BIM workflows and digital transformation in their business processes. His main areas of focus are automation, generative design, integration between AEC and ENI industries. He is an architecture enthusiast, Revit user since 2006, API and Dynamo knowledge seeker. He wrote the CivilConnection Dynamo package that creates dynamic relationships between Civil 3D and Revit for Linear Structures BIM workflows. He is also the co-creator of the Civil 3D Toolkit package for Dynamo for Civil 3D. He owns the Punto Revit blog.

Companion Class

This class will cover how to apply automation and generative design principles to optimize the design of a road network. The design starts from geographic information system (GIS) inputs, describing the site and its features, such as the boundary, existing buildings, and streams of water. Using InfraWorks software and Civil 3D software, it’s possible to create a model to start the definition of the design. Dynamo is used to apply a computational design approach and define modeling strategies to...

Share Article