Automate Creation of Models

Hello Dynamo forums

I am back again for some help. Please see the below for context and task criteria.

Context
I’m working on a Dynamo script to automate building envelope creation (walls, floors, roofs) for multiple structures simultaneously in Revit 2023. While my current script handles single-building workflows, I need help resolving three key issues and planning future enhancements.

Current Challenges

  1. Multi-Building Processing
  • Script only works with single building outlines
  • Need to process multiple model line groups simultaneously
  1. Roof Offset Geometry
  • Offset polycurves create rounded corners instead of sharp angles
  • Current method: PolyCurve.ByJoinedCurves with Curve.Offset
  1. Wall Top Constraint Mismatch
  • Walls default to “Unconnected” despite specifying top level
  • Workaround: Separate script to fix constraints (not ideal)

Technical Constraints & Capabilities

  • Limited to native nodes (no packages)
  • Basic Python understanding for custom nodes (no Revit API yet)
  • Willing to implement Python solutions with guidance - previous attempts via Perplexity unsuccessful

Future Enhancement Goals

  1. Group Management
  • Store model lines in building-specific groups
  • Auto-add generated elements to source groups
  1. Model Automation
  • Create separate Revit models from groups
  • Auto-align group origins to project coordinates

Software Versions
Revit version - 2023
Dynamo Core - 2.13.1.3887
Dynamo Revit - 2.13.1.3891

Task
The script should do the following once it is run through the Dynamo player.

  • Create walls from model lines + offsets
  • Create walls floors model lines + offsets
  • Create walls roofs model lines + offsets

Key Questions

  1. How to iterate through multiple building groups simultaneously?
  2. Best method for square-corner offsets with native nodes?
  3. Why does Wall.ByCurveAndHeight ignore level parameter?

Thanks in advance and look forward to hearing from you.

Summary




This is completely self imposed and a mistake in terms of how you approach Dynamo. Doubly so when you add in the next bullet point. It’s like saying ‘I need to build a complete for a large multi-family tower in Revit but without using any links and by the way I don’t know anything about things in the systems tab.’ The use of AI to try and get code is also going to slow you down (significantly compared to packages) and do more harm than good.

PolyCurve.ByGroupedCurves will build closed loops for you on this - in some cases you will have to extract the curves and manage them as a group goi g forward. You will have to manage list levels and lacing throughout the rest of the graph though. Do the primer exercises to learn that as AI tools will not help.

PolyCurve.OffsetMany has a boolean control for filleting outside corners or not.

I can not see where you used this as your graph image is too zoomed out. Read how to create an image of your workspace and highlight where you aren’t getting the result you are after. My gut tells me you should be using a Wall.ByCurveAndLevels node not a high based method though.

Hi @jacob.small

Thanks for your response, please see my comments below.

We have already discussed this in another post (Creating and Renaming Worksets without Packages) and is not self imposed. It is a limitation of where I work and the sensitivity of the environment. I am trying to overcome this by learning Python and the Revit API to combat the restrictions I currently have, I am really enjoying it at the moment. I am using AI as a guide not a solution

Summary

This text will be hidden

I have found the node and implemented it into my script have no issues when it comes to creating multiple floors but get a warning when the roofs are created. I have tried to search online why the roof are behaving differently with no luck. The script works with no issues when selecting only one outline.

Summary

I have had a look for this node within Dynamo and searched for some guidance online and cannot find it. I have tried getting around this by offsetting the lines outward then inward, this didn’t resolve the issue.

Apologies this was incorrect I am using Wall.ByCurveAndLevels and still getting unconnected top constraints. I am still using my work around to attach the top of the walls to my roof level.

I have recreated my graph below following the steps provided. From what I can tell there is no difference to the last screenshot, I am able to zoom in and see the same amount of detail.

Summary

1 Like

Didn’t realize we’d have the conversation all ready, but discussing the cost/benefit of enabling selected 3rd party packages with the person managing the environment is the way to go.

As an example, let’s say that after you populate your buildings you wanted to generate the best paths of travel between 10 points on site. The VASA package can do this today in about 20 minutes of setup time (or less). Authoring something like that yoruself would take an order of 20 days if you know C# well, 40 days if you know Python well, and a half year if you don’t know either. This presents your company with 3 options, which we’ll quickly cost estimate by assuming every hour spent costs $100 :

  1. Vet and deploy VASA the same way they vet and deploy Dynamo and Revit and get the production time down to 30 minutes. This requires the infosec team do some work, but it shouldn’t take more than a half day total to get a ‘yes’ or ‘no’, and a half hour to do the deployment. The net cost is $500 on this option and you get an automation and some degree of support as long as the package author maintains support..
  2. Custom author the code and vet and deploy that. We’ll assume they can bring in someone who knows Python well but the infosec team still needs to review that custom code and deploy it so you’re at 40 days and 5 hours of time which costs $32,500.
  3. Don’t automate anything and keep doing stuff via manual picks and clicks. If this was viable you wouldn’t be here so no need to do the math, but we’ll quickly note that the sunk cost is infinity as every project suffers.

Now is there $32500 worth of value in not having the automation? If it’s a one time thing, no. But if it’s a one time thing you don’t have to lock your walls to the roof level automatically; Build a schedule and make the change manually. if it’s a 10x thing I’d argue the solution is the same. If it’s a 10000x thing then we’re certainly in the ‘do it automatically’ range of things, and certainly the cost savings justifies the infosec team to validate the package.

That said we can give some guidance all the same, just don’t set this as a blocker right off the bat.

The node requests a LIST of curves as the outline. Since you’re providing polycurves it appears to be trying to join them all together. Try setting the curve input to @L1, and if that doesn’t work try using a PolyCurve.Curves node and setting the input to @L2.

You might need an update to Revit as this node was added in Dynamo 2.16.


If the company is concerned enough about security that they are restricting packages but they haven’t yet deployed Revit 2023.1 it’s a bad sign. You’re exposed to at least one CVE that prevents malicious actors being able to execute arbitrary code as if they were Revit. If you don’t have this, you’re going to have to work out the offset in another way - you’re looking at a BIG lift for that.

The node doesn’t actually constraint the value, but sets it to the correct height. Might not be super clear though. You can see where this happens in the source code here: DynamoRevit/src/Libraries/RevitNodes/Elements/Wall.cs at 5baf61bef428ec5dd287f98ec94599a4d9e2c26e · DynamoDS/DynamoRevit · GitHub

Fortunately the “fix” is just two new nodes rather than a separate branch as you have it now:


The added time is likely negligible as it’s still in one transaction, but if you’ve got bindings in the file things will slow down so be sure to read up on Element Binding.

Hi @jacob.small

Thanks for your response, please see my comments below.

No problem at all. The cost/benefits have been discussed already, unfortunately even with these considered there are processes involved and a great deal of time to get things through if at all. It took two years to get Revit 2023 approved and rolled out. Updates/hotfixes where not included as part of this request and approval so we are stuck on Revit 2023.0.

We are now in the process of getting Revit 2025 making sure is part of a managed service that will include all updates/hotfixes. I will have to wait until then to get access to the features included in Dynamo 2.16.

Thanks for the suggestions, I tried both with no luck. I have managed to resolve this by set Roof.ByOutlineTypeAndLevel @L1. I have realised I don’t need to offset the roofline, it is the walls that are the issue aligning to centre not finish face exterior.

I have been trying to align the outside face of the walls to the outline but haven’t had any luck. Instead I have manually offset the outlines and created these walls from these. I did try and automate the line offset but nothing seemed to happen.

I will have to wait until Revit 2025 before we can acquire this now.

Thanks for the advice I mage the change and it works as required now.

I will find some time to read this tomorrow, thanks for the link.

Todays Progress

I have been trying to create doors from a generic family placed at the locations I require. I was trying to do this with lines but it didn’t want to work. These issue I am having is for every wall each generic model is trying to be placed, i.e.100 walls x 4 generic models = 400 generic models placed.

I have tried to do some clever things with Geomerty.DoesIntersect with no luck, I think the answer now is with list maps but my eyes have gone square for today. I will come back tomorrow to resolve this.

Ideally once the placement of the doors is working I would then like to have 4 generic model types which I can associate with the corresponding door type:

  • Internal single
  • Internal double
  • External single
  • External double

Once this step is finished I will focus on moving the modelled elements into groups and then automate Revit file creation from each group. I am giving myself 2 more days to complete this before I will need to do this manually to his a programme deadline.

Use a door family not a generic model. You’re making your life 10x harder than it need be by going with generic.

Hi @jacob.small

I am aware of this I am using a generic model to mark where my doors are. The script I am writing should look for where the generic models are placed and intersect with walls, doors should be placed at these locations.

I am currently placing the doors multiple times in the x +/- and y +/- direct by how many walls there are. I have attached a screenshot of the script below.

Summary

Hi @jacob.small

I wanted to share an update on my ongoing script development—please see the attached screenshot for reference.

Recently, I discovered that selecting elements within the active view has helped resolve several issues I was experiencing. I’m currently testing two different approaches for marking door locations in my test model:

  • Approach 1: Using lines to indicate where I want doors placed.
  • Approach 2: Using generic models to indicate where I want doors placed.

In my test model, I’ve created walls and marked potential door locations using either a line or a generic model. Here’s what I’ve found so far:

  • When there’s only one marker (line or generic model) per wall:
    The script places doors exactly where I want them—everything works perfectly!
  • When there are multiple markers on a single wall:
    The script starts to misbehave. Doors are placed in incorrect locations, and sometimes not placed at all.

Based on this, I suspect the issue is that my script isn’t properly associating each marker (line or generic model) with the specific wall it’s placed on or in. I’m not sure how to best incorporate this association into my Dynamo workflow.

Has anyone tackled a similar challenge?

  • How can I reliably link each marker to its corresponding wall in Dynamo?
  • Are there nodes or methods you’d recommend for this kind of association?

Any advice, example scripts, or pointers to relevant resources would be greatly appreciated!

Thanks in advance for your help!

Summary

As I understand it, the process you have now is:

  1. Import some data
  2. Place a placeholder where the import indicates it should be
  3. Run a graph to generate walls, roofs, floors, doors from the imports (everything but the doors) and from the placeholder (the doors)

Why not do this instead:

  1. Import some data
  2. Run a graph to generate walls, roofs, floors
  3. Place the doors directly

Hi @jacob.small

Thanks for your response, please see my comments below.

Yes the imports are DWG plans from AutCAD. They are very basic all elements are represented by single lines. The contractor who created them removed all detail from the drawings i.e. wall thickness, windows and doors. The drawings were used for fire strategy planning. Because of this I was able to replace the basic blocks for the doors with a single line where the opening was.

Yes correct, I was able to explode the DWGs and repurpose the lines, eliminating the need to trace over the plans. Some things needed to be tidied up in Revit before running the script.

Essentially yes, I have attempted to create the doors from imported lines. I have also added placeholder generic models at the locations of each door.

Both options are producing the same results. Trying to place the doors from generic models was more of an experiment than anything else.

This is definitely an option but can you please confirm what you mean by ‘Place the doors directly’. Do you mean manually place the doors? I have now done this due to a deadline.

However I would still like to place the doors from the imported lines from CAD. There is another 30 or so buildings that need to be created for another site.

Are the graphs I have created to place the doors on the right track?

Yes, that is what I was getting to. The origin of the data (AutoCAD) and the that your had an automation method to swap them out (replacing a block) makes it simpler.

The difficulty with doing this by way of an automation is that your door symbols don’t have a 1-1 relationship with their wall.

Hi @jacob.small

Thanks for your response, I ended up placing the walls manually in the end as suggested.

The last things I would like to include in the script is adding the walls and floors to selected levels within my model. Is this something that can easily be done with the native Dynamo nodes.

Yes. All of the native creation nodes for walls and floors have an input for level, which can be used to achieve what you are after.

Hi @jacob.small

I will have a look at how to specify multiple levels at once, thanks for all your help with this.