Revit plugins updates and new features

As usual during this time of the year, I published the new version of my plugins for Revit.

Align

The big improvement this year is the ability to align any type of elements, annotations or tags. I must thank Deyan Nenov and his large contribution to the source code for this new feature.

From now on, you can select any kind of element and align or distribute them evenly. This feature use the bounding box of the element in the view as a reference.

Align or distribute all elements

The Align command is still view-dependent, so using it in section view or in a plan view will not have the same effect on the overall position of a given element. A word of caution however, the align function can be unreliable in a 3D view.

View-dependent align functions

Of course, you can still use it to align or distribute your tags and annotations, and it even works with viewports:

Align viewports

Along with these improvement, Align now fully support Area tags, and a few bugs have been eliminated. You can now use Align even if on tag without a leader, and multi-leader text are now fully supported, and some selection subtlety have been introduced.

Align tags and texts

I haven’t tested it with all categories, if you find something weird, please let me know, I would be happy to fix it.

You can find this new version on the Autodesk App Store.

Room Finishing

Along with the support for Revit 2018, I corrected an issue where a skirting board was created even if the room was not bound by a wall. From now on, Room Finishing will not create a skirting board along room bounding lines.

Support room with room boundary lines

Room Finishing is also available on the App Store.

Time Stamper

The Time Stamper plugin got a few improvements this year along with the usual bug smashing.

You can now choose between applying your time stamp to every element, or just the one visible in the view. This will give you the ability to filter on which element you want to apply a stamp.

You can also choose to keep or override an existing value, this should help you keep the history of a given element.

A few bugs where corrected, making the creation of the four shared parameters far more reliable. Groups are now supported.

Support for groups

Time Stamper is now available here.

These new versions are now available on the Autodesk App Store. Don’t hesitate to report any issue you might find in them or ask for improvement.

These plugins are open source, you can find the source code here, here and here. Feel free to use it on your own project or contribute to these projects.

Modeling a neighborhood with Flux Site Extractor, GIS data and Revit

Since my last post, I kept on working on urban development. I particularly think about importing GIS data into our usual authoring tools. My experience with Infraworks was interesting, but it is still difficult to use this data in a Revit model.

The most promising resource out there for creating a context in a Revit model is the Flux Site Extractor. You select an area, add some features to extract and send them to a Flux project.

The Flux Site Extractor interface

After retrieving this data in my Flux Site Project, I use the Flux Dynamo nodes to get the topography as a mesh, extract the vertices of this mesh as points and use these points to create a toposurface in Revit.

Creating a toposurface from the Flux Site Extractor

Building profiles and heights came from OpenStreetMap, and aren’t accurate enough to be used for site analysis. But I am using building profiles to draw on a plan view the footprint of every building retreived with Flux. This will help me futher down the road to align my buildings on the toposurface.

Buildings footprints drawn in a plan view

I found more accurate data on the parisian buildings on the APUR Open Data plateform. I download this data as a shapefile containing every building in Paris.

Obviously, this dataset is too large to be imported as it in Revit. I am using QGIS, an open source GIS application, to extract a subset of this file. To do so, I draw a polygon encompassing the few city blocks I want to retrieve and use the “Clip” function to create a new shapefile containing only the selected buildings.

Isolate the propers city blocks

I am using the DynamoGIS package to import this shapefile into Revit. These nodes allow me to read the file and extract the shapes of the buildings.

The most difficult thing here was to include inner boundaries in a building shape. These boundaries are not taken into account by the Surface.ByPatch node. I manage to split the first surface (the largest) using the inner curve. This allow me to create the hollowed surface.

Highlight of inner boundaries

The DynamoGIS include nodes to query any value associated with shapes. I am using them to retrieve building heights in the dataset and extrude my buildings at their proper height.

Since it is GIS data, I am using a nice tip from LandArch to move my geometry near the project base point, and make it usable in Revit.

I am using the FamilyInstance.ByGeometry node from the great Spring nodes of Dimitar Venkov to create the buildings as mass families.

This Dynamo definition create a mass family for every building in the shapefile, extruded up to its actual height. Combined with the toposurface created with Flux, this look like an actual neighborhood, where you can think about massing and site integration directly in Revit.

Site integration of a project

This process still has a few issues. The buildings aren’t adjusted at the toposurface and aligning them with the toposurface created with the Flux Site Extractor involve some manipulations. I still have some work to do on this process to streamline it, and get a more accurate representation of an existing site.

Another view of the project

 

Linking documents to a model

These days, there is a lot of ideas around using a building information model for facilities management. Among these ideas, a recurring theme is to integrate documents, mostly technical sheets, directly into the model.

Aside from the fact that I don’t see how a model build to design, analyse, and coordinate a building could be use directly in facilities management, there is also some non-trivial technical problems to overcome to have any documents properly linked to your model, whether you are using Revit, Navisworks, or an IFC viewer.
Below is a list of these technical problems, and some though on how to solve them.

Adding a link in Revit

Adding a link in Revit is fairly straightforward, you just have to use a “URL” parameter (shared or built in), and type in your link. Since a technical sheet is generally the same for every building element of a given type, it makes more sense to me to add it in a type parameter.

Door Type URL parameter

Door Type URL parameter

As you can see, I type in a relative path to my technical documentation, this allows me to move around the entire “As-built documentation” folder (models and technical sheets in PDF) without breaking the links. I end up with a pretty simple folder structure, with a model at its root, and the technical sheets nicely ordered in one folder per category.

The folder structure

The folder structure

If you click on the small “…” button in Revit, your linked technical document will immediately open in the associate viewer, here, Acrobat Reader.

How to open the linked technical sheet

How to open the linked technical sheet

Adding a link without Revit

Selecting equipment and material is generally done through spreadsheets or building economy software, and by people who could not be proficient with Revit. Therefore, I have searched for solution to do it outside Revit.
The new Flux Scheduler is an application based on Flux, which allows us to create online schedules from data uploaded through the Revit Flux plugin.

The Flux Scheduler

The Flux Scheduler

By using this Flux Scheduler, I could upload my doors on Flux, create a door schedule directly on Flux, use Excel to add the URL link, and upload back these values in Revit

Type the URL in Excel before uploading them in Revit

Type the URL in Excel before uploading them in Revit

Delivering a Navisworks model

Once exported to Navisworks, the “Link” button will display a small link button on every linked object, which open the linked technical sheet.

The link in Navisworks

The link in Navisworks

However, you must keep your Navisworks model in the same location in your “As-Build Documentation” folder structure as your initial Revit model to keep the relative links functional. In our case, we end up with the following folder structure:

The folder structure with a Navisworks model

The folder structure with a Navisworks model

Delivering an IFC model

If you export this Revit model to IFC, and open it in Solibri Model Viewer, you can display the link, but not click on it. However, by writing a “\” before the link in Revit, Solibri Model Viewer recognize it as link and you can open the technical sheet with a click. This could obviously become problematic in Revit, since when you add this “\”, Revit doesn’t recognize the link anymore.

The clickable link in Solibri

The clickable link in Solibri

Tekla BIMSight, on the other hand, couldn’t recognized any of those links as a clickable item.

As you can see, they are many ways to link documents to a model and retrieve them in a viewer, and a few things could go wrong along the way. So, before starting anything, I would recommend to make sure you can link or embedded documents in your deliverables and structure these deliverables accordingly.

Room Finishes Update

I keep on working on my Revit add-ins. After Align, it is now Room Finishes who have been updated to support Revit 2017. Along with this update, I also have integrated some new features.

First of all, Room Finishes now support all kind of units. You just have to type your dimension with its unit symbol, and the plugin will convert it in a floor height or a skirting board height. The plug-in will now also use the default length unit of your model.

interface

I have to thanks Brian Winterscheidt for this update, who was kind enough to contribute to my plug-in on Github, and point me to the Revit unit conversion system available in the API.

The other major update is the ability to join skirting board with their supporting wall. You can now join both geometries automatically. This enable one of the most wanted feature, the ability to cut the skirting board around the door.

Just select “Join geometry” before running the command, and every skirting board will be joined with its host wall.

join

This feature could generate its fair share of warning, so I have remove every related error message. You will now be able to run this command without having to dismiss every warning that come up.

I also add some minor UI improvements, like the ability to resize the window, or sorting wall type names by alphabetical order to be able to quickly find the specific wall type you have created for your skirting board or your floor finish.

Of course, Room Finishes is still open source, the entire code can be found on Github.

This plug-in is already available on the Autodesk App Store. If you like it, don’t hesitate to write a nice comment or add a few stars, it always means so much to me!

Align Tag Update

It is this time of the year again, and I have finally take the time to update Align on the App Store for the new version of Revit.

However, there is more in this than a simple version update, and this new release is packed with improvement, both small and large.

The main change reside in the alignment method. In the previous version of Align Tag, I was using the center point of a given tag as a reference to align tag (either left or right). To improve on the alignment of tags of various sizes, I now use the bounding box of the tag.

AlignSolution

Tags will now properly align themselves along their right or left side, regardless of their size or origin point.

Align

However, if you want something similar to the older version, you can use the new Align Center and Align Midlle commands, which will use the center of the tag as a reference.

This new alignment method is more in line with what can be found on solutions like PowerPoint, or Adobe Illustrator, and will allows you to neatly arrange your tag whatever their size or origin point.

Another important improvement is the long awaited support for Text. You can now align Text along with Tag, using the same command.

While I was at it, I also add support for Keynote tag, Room Tag and Space Tag, basically every tag. The Area Tag is still missing, but can be expected for the next version.

However, this support came at a cost, and I have to drop the support for Revit 2015 and prior. So, if you are still using this version, you will have to keep the old Align plugin.

There is also a handful of small UI improvement that I hope will help you.

Aligned tags are now kept selected after running the command so you can align them in another direction right away.

Your Align commands are also one click closer to you! The interface have been artfully arranged in a new tab to keep every icon directly accessible in the ribbon.

icons1

Under the hood, I have rewrote a large part of the code to support more types of annotation elements, and I hope to be able to use this new framework for more complex manipulations, including in the Arrange Tags function.

Of course, Align Tag is still open source, the entire code can be found on Bitbucket.

This plug-in is already available on the Autodesk App Store. If you like it, don’t hesitate to write a nice comment or add a few stars, it always means so much to me!

Bridge design

One of my colleague is currently working on bridge design with Revit. I have to admit, my first reaction was more like “Revit is not fit for bridge modeling, period”. But after some thought, I found Revit to be a pretty interesting solution to design these kind of infrastructures.

The main issue is that even a simple bridge has a rather complex geometry, with a double-curved alignment and potentially a variable cross section. There is various possibilities to create this kind of geometry in Revit, I will present only one of them here.

This entire article is mostly inspired by the work of Matthias Stark, from Autodesk, and its great AU 2015 class.

The alignment

The first issue we ran into while designing our bridge is the inability for Revit to create a real double-curved, 3D curve.
This is why I create my alignment in Rhino, and use Grasshopper to create a list of X, Y and Z coordinates that define points along my alignment. Another solution is presented by Matthias Stark in his class, where he is using AutoCAD Civil 3D to export the coordinates of the alignment in an Excel spreadsheet.

Once I have all my coordinates in an Excel file, I use a simple definition in Dynamo to create a series of reference points in a Mass family, and use these points to create a curve representing my alignment.

Alignement

I also make sure that units in my Revit mass family are consistent with the unit of my alignment coordinates points.

The cross section

To create the cross section shape of my bridge, I use an adaptive family with a single adaptive point, which will be placed on our alignment.

The keep our cross section properly aligned with our bridge axe, I use the “Orient to” parameter of the adaptive point. By setting it to “Global (z) the Host (xy)”, I make sure than the X and Y axes (Red and Green) will follow my alignment, while the Z axe will stay vertical.

axesI make a few try before getting it right, but I was finally able to properly align my adaptive component with the divided path. Since the X (Red) axis will be tangent to the alignment, I had to draw my cross section in the “Center (Left/Right)” plane of the adaptive family.

adaptiveFamily

Modeling

The rest of the modeling is pretty straightforward. After placing the first adaptive component on a divided path based on our alignment, just select Repeat to place one on every division point, then decompose the Repeat pattern and create a form.

repeat

form

To create the cavity inside the bridge deck, I use the same divided path to place two cavity profiles (right and left) and create two void forms to cut into the bridge deck.

voidForms

Section View

The main issue with this mass family is around dimensions. If you try to add dimensions directly on the Mass family in a section view, these dimensions will be anchored on the wrong point.

firstSection

To be able to create section view anyway, I am using the adaptive component loaded in the Mass family. I make it visible in the project and draw a detail line along one of them. This detail line allows me to draw a section view perfectly aligned with my adaptive component

sectionView

Since my section is perfectly aligned with my profile, it appears in the view and can be used as a reference for the dimensions. I temporary hide my mass family, place the necessary dimensions and show again the mass.

With this workaround, I was able to create a simple section view, with the proper dimensions.

section

Matthias Stark also present in his class an entire detailing process using Dynamo, and that I still have to explore this part. But his approach to bridge modeling allows me to create a great first draft, and I will keep on digging this solution.

Measuring ceiling heights

I recently have to measure the actual headroom of every room in an architectural model, and copy this value in a room parameter.

Instead of checking manually every room, I create a small Dynamo definition, based on the most underrated node in Dynamo, Raybounce.

The Raybounce.ByOriginDirection is basically a laser rangefinder for Dynamo. It works with an origin point and a direction, and give in return the first intersecting element, along with the point of intersection. It is pretty powerful, and its uses range from basic measurements to advanced Line Of Sight Analysis.

UsingRaybounce

Using DynamoMEP, I retrieve every room in the model, and create a grid of points in each of them. These points are arbitrary spaced 50 cm apart, and serve as origin points for my Raybounce node.

RetriveRooms

Furthermore, in order to avoid that my laser beams hit the floor, I move my origin points 1 cm above the floor level.

MoveOriginPoints

The Raybounce.ByOriginDirection use these points, a Z vector as a direction and a 3D view. Since only elements visible in this view will be detected, I hide doors and stairs to remove interferences with these elements.

RayBounce

Along with the intersection point, the Raybounce.ByOriginDirection return the origin point that I filter out with a boolean mask.

FilterPoints

Points

I also make use of the List.Map node to perform any kind of operation (Flatten, Sort …) on the sublist containing the points while keeping them grouped by lists corresponding to the original rooms.

ListMap

I finally calculate the headroom height, and retrieve the shortest one for each room. I pass this value to the Limit Offset parameter of the corresponding room.

CalculateHeadRoom

Initially, every room’s Limit Offset is 2m.

Before

After running the Dynamo script, every Limit Offset is updated to reflect the actual minimum headroom in each room. Since we have a sloped roof, the minimum headroom is not necessarily the ceiling, but can be the lower part of the roof.

After

Using the Raybounce node can be quite challenging, especially when it comes to sorting the resulting points, but it is totally worth the effort. You will find here the Dynamo definition, feel free to use it for your own project.

This was also the occasion for me to update DynamoMEP for Dynamo 1.0, and add a Grid function to create a nice array of point in a Room or a Space. As usual, you will find these updates in the Dynamo Package Manager.

Wall Openings (again)

I am kind of obsessed with wall openings. The entire process of asking a structural engineer for holes in its beloved wall to let ducts and pipes goes through has always been a rather frustrating experience.

After my first article about a semi-automated way for placing an opening family, here is my latest attempt at creating the perfect opening family.

A good opening family must have the following features:

  • hosted on a wall, a slab or a beam
  • visible in a 3D view
  • fully parametric
  • schedulable
  • sharable in its own model
  • a nice 2D representation

Lets explore these features.

To host them, but still keep the ability to share them in their own model, I use the Generic Model Face Base family template to create my opening family. This template allows me place my opening on any wall, slab or beam, even if they are in a linked model.

In this Generic Model, I create the Opening subcategory, where I will place every element of my opening. This will allow me to fine tune the display of my openings in my model.

I create a bunch of reference planes, and drive them with three shared parameters, Width, Height and Depth. These reference planes help me constrain the Void Form that will cut the host. This void form will create an actual hole in the wall or slab, and will allow me to perform accurate clash detections after integrating these openings.

To be able to see my opening in a 3D view, I draw some Model Lines to outline the general shape of the opening, and place them in the “Opening” subcategory. These Model Lines are only visible in 3D.

3D View

The 2D representation is a pretty complex subject, and I have yet to find the perfect solution. After some experiences with Model lines, I have switched to annotations elements. These annotations elements are drawn in two nested families, one for the projection symbol, the other for the cut symbol.

These annotation families are drawn in a Generic Model, with the “Opening” subcategory, in order to follow the same graphical rules than the main family.

I also use Masked Regions to draw filled patterns, and use the Generic Model Override in a plan view to fill them with black. I am not entirely satisfied with this solution, but the workaround involve Detail Items, and I don’t want to deal with two different categories.

PlanSection 1

Section 2

To display the elevation of my opening family in a tag, or a schedule, I create two shared parameter, Top Elevation and Bottom Elevation.

As I was searching for a solution to calculate the elevation, I notice a feature I wasn’t aware of, the “Schedule Level”, present since at least Revit 2015, that allow us to define a reference level. Revit use it to automatically calculate the corresponding elevation. Since this elevation cannot be used directly in a schedule or a tag, I use a Dynamo definition to update elevation values in my shared parameters. This Dynamo definition perform some simple calculation to retrieve Top and Bottom elevations, and send these values in the corresponding shared parameter.

Dynamo

My work with wall openings is far from complete, and subjects like sharing these openings, and managing their modifications are still pending. You will find here the different families, models and Dynamo definition used in this article, feel free to use or improve on them.

Using Dynamo for MEP Design – Part 2

This is the second part of my article, originally published in the official magazine of Autodesk User Group International, AUGIWorld.

Link between terminals and the main duct.

To fully exploit Duct sizing capabilities in Revit, we generally need a fully connected network between the mechanical equipment and Air Terminals. But drawing every duct for the entire networks from source to terminal can be time consuming and not relevant in the early phase of a project, when architectural layout is subject to major changes.

A possibility is to use Dynamo to virtually link every terminal to a placeholder family that will collect and sum Airflows in a given area and send the sum to a placeholder family used to perform duct sizing calculations on the main branch.

figure7

Revit provide us the Connect the main duct to “M_Rectangular Duct Connector – Supply Air – Air Terminal”. This is a generic terminal that will simulate the rest of the terminals. We connect this generic terminal to our main branch, and use it to simulate the rest of the duct networks.

The following Dynamo definition sums airflows of the selected Air Terminal and pass the value in the Airflow parameter of the placeholder family. This placeholder family now simulate the airflow of all selected air terminals. Since this family is connected to the main duct networks, we can now perform duct sizing for the main branch, without having to model the entire duct layout.

figure8

A word of warning anyway, since this placeholder family is integrated into the system, flow sum for the duct system is multiplied by two, since Revit count both the airflow of every air terminal and the airflow coming from the placeholder family.

Dynamo File

From Specified Airflow to actual terminal Flow

Another example of the power of Dynamo come when linking Air terminal to their enclosing MEP Space. In this example, we will see how to retrieve the required airflow in a given MEP Space, and distribute this value on every air terminal enclosed in this space.

We start by finding all MEP Space, and retrieving their “Specified Supply Airflow”. We also get all Air terminals, and use the Space.IsInSpace node to find if a given terminal is in the space. We make sure to set up the lacing of this node to “Cross Product” in order to test every Air Terminal with every MEP Space. This give us multiple lists of true or false indicating whether a given Air Terminal is in the space. With the usual combination of List.AllIndiceOf and GetItemAtIndex, we find our air terminals grouped by their enclosing space. We count the number of these terminals in each group, and use this count and a division to get the specified airflow on each terminal. The List.OfRepetedItem give us an instance of this specified airflow by terminal. We finally apply these value to these terminals with the Element.SetParameterByValue.

figure9

As we update the Specified Airflow of each MEP Spaces, this value will be divided by the number of terminal in the space, and applied to the said terminals.

figure10

Dynamo File

Terminal Max Flow

Another application of Dynamo is the real-time checking for max values in a given terminal equipment. In this example, we will check whether the airflow of a given terminal is below is max value, and highlight in red when the airflow is above the max value. In some way, this is similar to the conditional formatting function in Excel, except we are doing it directly into Revit.

We start by finding all air terminal unit in Revit with the “All Elements Of Category” node. Using the GetParameterValueByName, we get the Airflow on each of these air terminal. Since the Maximum Airflow is a type parameter, we use the FamilyInstance.Type node to retrieve the family type, then use again the GetParameterValueByName to find the “Max Flow”.

We can now compare this two values, and use the List.FilterByBooleanMask to find all terminals where Airflow is above the Max Airflow.

figure11

The last step is to override the color of these terminals to override by color to highlight the results.

figure12

This fairly simple example showcase the possibilities of Dynamo combined with the proper Revit objects library.

Dynamo File

Conclusion

Through these five examples, we see how to use Dynamo to enhance your calculation powers in Revit. It is clear by now that Revit is far more than a modeling tool, and once combined with Dynamo, it opens a lot possibilities for mechanical engineers.
Finally, I want to give my deepest thanks to Andrew Duncan, from Arup, for its great Autodesk university courses, where I get most of my inspiration for these examples.

Using Dynamo for MEP Design – Part 1

This two parts post was originally published in the official magazine of Autodesk User Group International, AUGIWorld.

Most examples of Dynamo focus on computational design and complex geometries. Many see Dynamo as a tool for creating complex geometry, and consider it from an architectural perspective. But Dynamo can be the powerful ally of every trade, all along the project life. By harnessing the data manipulation capabilities of Dynamo, you can largely improve on the current calculation features of Revit, and create new workflow for designing directly in Revit.

Through five use cases, I will present you some ideas for using Dynamo for mechanical engineering.

I will assume that you are already familiar with the interface and have a general understanding of how Dynamo works. Most examples below can be realized with “out of the box” Dynamo nodes, but to shorten my graph, I will make use of the following packages:

I will also use my own package, DynamoMEP, to manipulate Rooms and Spaces. All these packages are of course freely available on the Dynamo Package Manager. If Dynamo doesn’t include a lot of functionalities around Room, Space and Mechanical Equipment, I use extensively the Package Manager to enhance these functionalities and create new workflows for mechanical engineers.

A final word, try these examples on small models before running them in production, and work in “Manual” mode, a few graph I will use are quite hungry for memory.

Link between Room and Spaces

Rooms and Spaces are essential for everything from room names and numbers to energy modeling. And before anything else, you have to retrieve any architectural room and convert it into an MEP Space to be able to work with it. You can of course use the “Place Spaces automatically” function of Revit, but this does not match exactly every architectural room with a MEP Space, and lack some basic functionalities. To improve on this, you can use a few Dynamo nodes to create a MEP Space for every room in a given linked file.

figure1
The procedure focus on retrieving every room from the architectural linked file (with the Element.GetFromLinkedFile) and using these rooms to create a matching space using the Space.ByPoint node from DynamoMEP.

figure2

You can also retrieve parameters values from these architectural rooms and paste them into your newly created Spaces using the Element.SetParameterByName node.

figure3

As rooms evolve in the architectural model, you will be able to recreate on the fly the corresponding Spaces. However, be careful not to duplicate an existing space.

Dynamo File

Link between Excel and Spaces

One of the most featured use of Dynamo is the link with Excel spreadsheets. Theses nodes link two of our most used design tools, Excel and Revit.

For the mechanical engineer, this provide the ability to add programmatic values directly in Revit Spaces. In the following example, I will show you how to load the specified airflow value from an Excel spreadsheet. I will make extensive use of Dynamo lists, and present some ways to manipulate them.

We start with a path to an Excel file, and use it to feed the Excel.ReadFromFile node. This node read line by line the content of our Excel file. We remove the first line, the header, with the List.RestOfItems node, and use the Transpose node to convert our list of Excel rows into a list of Excel columns. By now, each list in our Dynamo node represent an Excel column.

figure4

With the List.GetItemAtIndex, we retrieve a list containing all MEP Space number and a list with their associate airflow.

To feed the “Specified Supply Airflow” parameter of our modeled Spaces, we need match them with the Space number in our Excel spreadsheet. To do so, we start by retrieving them (All Element of Category node), and get their number (Element.GetParameterValueByName).

The node List.FirstItemOf give us the row number of each of these Space Number in our Excel file. For each of our existing MEP Space in our model, we can now get the corresponding row in Excel.

figure5

Using the List.GetItemAtIndex, we get the required Airflow value in the Excel Spreadsheet. Before pasting them into Revit with the Element.SetParameterByName, we convert them to cubic foot, since Dynamo always work in Feet.

figure6

The entire business of retrieving values from Excel spreadsheet is generally only a matter of list, and nodes like Transpose, GetItemAtInded and FirstIndexOf are quite useful here. If this example only cover the specified airflow, it can of course be extended to every kind of data sorted in an Excel spreadsheet.

Just make sure that your MEP Space numbers match between your Excel file and your Revit model, since any discrepancy will make the FirstIndexOf fail.

Dynamo File

Next week, stay tuned for the second part of this post, where all secrets of airflow and terminals will be revealed.