# Clearance Envelope

<figure><img src="https://1734247194-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FY5ZuHF3yuXFWp1C46ZSo%2Fuploads%2Fgit-blob-08eb8cd428425a923af595cea18442b7936ffbdf%2FRail_ClearanceEnvelope_Player.gif?alt=media" alt=""><figcaption></figcaption></figure>

Developing kinematic envelopes for clearance validation is an important part of rail design. Dynamo can be used to generate solids for the envelope instead of creating and managing complex Corridor subassemblies to do the job.

## Goal

> :dart: Use a vehicle profile Block to generate clearance envelope 3D solids along a Corridor.

## Key Concepts

> * Working with Corridor Feature Lines
> * Transforming geometry between Coordinate Systems
> * Creating solids by lofting
> * Controlling node behavior with lacing settings

## Version Compatibility

{% hint style="success" %}
This graph will run on **Civil 3D 2020** and above.
{% endhint %}

## Dataset

Start by downloading the sample files below and then opening the DWG file and Dynamo graph.

{% file src="<https://1734247194-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FY5ZuHF3yuXFWp1C46ZSo%2Fuploads%2Fgit-blob-de22ab30746893bd0c0e7bbad9cdfe5bc81934cb%2FRail_ClearanceEnvelope.dyn?alt=media>" %}

{% file src="<https://1734247194-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FY5ZuHF3yuXFWp1C46ZSo%2Fuploads%2Fgit-blob-555200ae7db1ec786f8084e35bd0a17f3fbdc8dc%2FRail_ClearanceEnvelope.dwg?alt=media>" %}

## Solution

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

> 1. Get Feature Lines from the specified Corridor Baseline
> 2. Generate Coordinate Systems along the Corridor Feature Line at the desired spacing
> 3. Transform the profile Block geometry to the Coordinate Systems
> 4. Loft a solid between the profiles
> 5. Create the solids in Civil 3D

Let's go!

### Get Corridor Data

Our first step is to get Corridor data. We'll select the Corridor model by its name, get a specific Baseline within the Corridor, and then get a Feature Line within the Baseline by its point code.

<figure><img src="https://1734247194-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FY5ZuHF3yuXFWp1C46ZSo%2Fuploads%2Fgit-blob-ac149803f2fec120b34fecefe697b2cb5598c462%2FRail_ClearanceEnvelope_GetCorridorData.png?alt=media" alt=""><figcaption><p>Selecting the Corridor, baseline, and feature line</p></figcaption></figure>

### Generate Coordinate Systems

What we're going to do now is generate **Coordinate Systems** along the Corridor Feature Lines between a given start and end station. These Coordinate Systems will be used to align the vehicle profile Block geometry to the Corridor.

{% hint style="info" %}
If Coordinate Systems are new to you, take a look at the [2-vectors](https://primer2.dynamobim.org/5_essential_nodes_and_concepts/5-2_geometry-for-computational-design/2-vectors "mention") section.
{% endhint %}

<figure><img src="https://1734247194-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FY5ZuHF3yuXFWp1C46ZSo%2Fuploads%2Fgit-blob-f005dd000c839530bb8e664b761d858a45c2ebe9%2FRail_ClearanceEnvelope_CreateCoordinateSystems.png?alt=media" alt=""><figcaption><p>Getting Coordinate Systems along the Corridor Feature Lines</p></figcaption></figure>

> 1. Notice the little **XXX** in the bottom-right corner of the node. This means that the node's lacing settings are set to *Cross Product*, which is necessary to generate the Coordinate Systems at the same station values for both Feature Lines.

{% hint style="info" %}
If node lacing is new to you, take a look at the [1-whats-a-list](https://primer2.dynamobim.org/5_essential_nodes_and_concepts/5-4_designing-with-lists/1-whats-a-list "mention") section.
{% endhint %}

### Transform Block Geometry

Now we need to somehow create an array of the vehicle profiles along the Feature Lines. What we're going to do is transform the geometry from the vehicle profile Block definition using the **Geometry.Transform** node. This is a tricky concept to visualize, so before we look at the nodes, here's a graphic that shows what is going to happen.

<figure><img src="https://1734247194-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FY5ZuHF3yuXFWp1C46ZSo%2Fuploads%2Fgit-blob-e303adc517b5bf2951a8d04ae1c2675b1842eb53%2FRail_ClearanceEnvelope_TransformAnimation.gif?alt=media" alt=""><figcaption><p>A visualization of transforming geometry between Coordinate Systems.</p></figcaption></figure>

So essentially we're taking the Dynamo geometry from a *single* Block definition and moving/rotating it, all while creating an array along the Feature Line. Cool stuff! Here's what the node sequence looks like.

<figure><img src="https://1734247194-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FY5ZuHF3yuXFWp1C46ZSo%2Fuploads%2Fgit-blob-44c2996470bb14d4a59c7a418708593d00194ab2%2FRail_ClearanceEnvelope_Transform.png?alt=media" alt=""><figcaption></figcaption></figure>

> 1. This gets the Block definition from the Document.
> 2. These nodes get the Dynamo geometry of the Objects within the Block.
> 3. These nodes essentially define the Coordinate System that we are transforming the geometry *from.*
> 4. And finally, this node does the actual work of transforming the geometry.
> 5. Note the *Longest* lacing on this node.

And here's what we get in Dynamo.

<figure><img src="https://1734247194-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FY5ZuHF3yuXFWp1C46ZSo%2Fuploads%2Fgit-blob-28cd3b3dcb9a5f88df9b5bf620e61e6b087f89d9%2FRail_ClearanceEnvelope_Dynamo_Profiles.png?alt=media" alt=""><figcaption><p>The vehicle profile Block geometry after transforming</p></figcaption></figure>

### Generate Solids

Good news! The hard work is done. All we need to do now is generate solids between the profiles. This is easily accomplished with the **Solid.ByLoft** node.

<figure><img src="https://1734247194-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FY5ZuHF3yuXFWp1C46ZSo%2Fuploads%2Fgit-blob-ba0723c6e309707fd12e50c89983205a4a9725be%2FRail_PlaceTies_SolidByLoft.png?alt=media" alt="" width="325"><figcaption></figcaption></figure>

And here's the result. Remember that these are Dynamo solids - we still need to create them in Civil 3D.

<figure><img src="https://1734247194-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FY5ZuHF3yuXFWp1C46ZSo%2Fuploads%2Fgit-blob-28e91b1c436018bf6ecb7afe18ac32f11c78da6a%2FRail_ClearanceEnvelope_Dynamo_Solids.png?alt=media" alt=""><figcaption><p>The Dynamo solids after lofting</p></figcaption></figure>

### Output Solids to Civil 3D

Our final step is to output the generated solids into Model Space. We'll also give them a color to make them very easy to see.

<figure><img src="https://1734247194-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FY5ZuHF3yuXFWp1C46ZSo%2Fuploads%2Fgit-blob-bf5954f60f7c14543cee49ee5d1eefcd4b9648d0%2FRail_ClearanceEnvelope_SolidsToC3D.png?alt=media" alt=""><figcaption><p>Outputting the solids to Civil 3D</p></figcaption></figure>

### Result

Here's an example of running the graph using **Dynamo Player**.

<figure><img src="https://1734247194-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FY5ZuHF3yuXFWp1C46ZSo%2Fuploads%2Fgit-blob-08eb8cd428425a923af595cea18442b7936ffbdf%2FRail_ClearanceEnvelope_Player.gif?alt=media" alt=""><figcaption><p>Running the graph using Dynamo Player and seeing the results in Civil 3D</p></figcaption></figure>

{% hint style="info" %}
If Dynamo Player is new to you, take a look at the [dynamo-player](https://primer2.dynamobim.org/dynamo-for-civil-3d/dynamo-player "mention") section.
{% endhint %}

> :tada: Mission accomplished!

## Ideas

Here are some ideas for how you could expand the capabilities of this graph.

{% hint style="info" %}
Add the ability to use **different station ranges** separately for each track.
{% endhint %}

{% hint style="info" %}
**Split the solids** into smaller segments that could be analyzed individually for clashes.
{% endhint %}

{% hint style="info" %}
Check to see if the envelope solids **intersect with features** and color those that clash.
{% endhint %}
