Looping a complex algorithm

Hey guys,
I share the issue I’m addressing, hoping some of you masters have the answer.

I’m working on a long algorithm which works like this:

  1. Reads data from an excel file: each row of the file represents data for generating a different building. All the buildings are similar, but have differences (base dimensions, number of storeys, number of columns etc…
  2. Takes one row of the database a time (data for one building case)
  3. Generates base geometry for this building using lists
  4. Uses the base geometries to generate BIM elements and documentation in Revit
  5. Takes Revit views of the generated building and exports them on a specific folder

Everithing works fine. Now comes the difficult part…
It has to do this for hundreds of cases, so the full algorithm must LOOP: erase the building, return to start, read the next row in the database, generate a new building end export. It must loop till it has finished all the hundreds cases in the excel database.

I cannot put a full picture of the algorithm, is too long, but here’s a scheme:

I’m sure it can be done, but have no idea on how… Looping whole algorithms seems a difficult topic in dynamo…
Have you got any suggestions?
Thank you very much!!!

Use the export canvas as image button, camera icon in the upper right corner, after zooming in so you can easily read a node.

It’s not so necessary actually…
There are more than a hundred nodes.
The skeme i posted is a nice summary of the whole algorithm.
I’m just searching a way to looping the whole thing

There is almost certainly an easier way which doesn’t require the looping, but we can’t see what you’re actually doing so I can’t help.

Good luck.

3 Likes

Here I am…
I made a very very simplified version of the algorithm just to solve this looping thing. Here it is:

  1. At the left an Excel file is imported (also a simplified one), in which you find the project ID, base dimensions and number of storeys:
    2020.11.04_Loop issue 2b

  2. Now the slider at the top left is the one that controls the row in the excel file that goes in input in the algorithm.

  3. Geometry for slabs is create (green part)

  4. Slabs are created (light blue part)

  5. Some views are exported as PNG (pink part). Here I still need to introduce a routine that creates a new folder in wich the project files will be exported.

6. Here comes the unsolved issue: I have to erase all the BIM elements created, go back to start and restart the algorithm for the next row in the excel…

Any idea? I think some sort of loop is mandatory, but if you have an alternative solution i’m open…
Thank you very much!

Hey,

As you obviously know, Dynamo isn’t designed around looping, more of a left to right flow…

My thought from looking at your graph… Why not read all the data as a list… Create all the slabs… Then either create 1 view for each set and control the visibility, or use 1 view and sequentially control visibility as you export?

Hopefully that is useful.

Mark

I agree with what was said above (it’s always better to avoid loops in Dynamo).
However, I may have something that may help you (if loops is truly what you want). You could try something as described in the topic, you would “just” have to create a custom node that contains all your existing script. Hope this helps :slight_smile:

1 Like

Ok seeing the scope really helped here.

The best way to do this is going to be stepping into a more code driven aspect of Dynamo, because as @Mark.Ackerley mentioned Dynamo isn’t built for this type of action out of the box. The Revit API however is.

What is needed is a way to control transaction groups, including rolling back a group after getting a result. This is well outside of the currently exposed capabilities of Dynamo but isn’t out of the question in the environment thanks to the Python integration.

Look into transaction groups, and rolling them back. I had a post showing this in a generative design context (do this thing until you get a result), but I can’t find it at the moment.

Note that this will first require that you make ALL of your graph functionality in one python node, which in itself is a tall task.

2 Likes

Maybe could be an option for simpler algorithms.
The “true” algorithm I need to loop is way more complex than the one I’ve posted: it bulds a full building with all the elements and must be looped hundreds of times… Revit will crush immediately if i do it all in parallel with a list, I need true loops.
However I found a solution. I’ll post it… :slight_smile:

1 Like

So… I found a solution. Don’t know if it’s the most elegant one but for my case it’s perfect.
It’s a true loop solution, doesn’t use any python script and it’s all done with ootb dynamo nodes.

Basically I made a custom node for the generation part. inside are: geometry generation, BIM elements generation, export and archive, erase all BIM elements.
Inside the custom node the sequence of theese actions are managed by passthrough nodes (but you can do it in other ways)

Then in the main algorithm I read data from excel spreadsheet, pass one row a time to the custom node and loop the whole process with Loop While node.
I also have a switch to tell if it must loop the full list or just a part.

New folders for each project case are created on the go by the algorithm according to the project IDs i collect from the spreadsheet.
2020.11.11_Loop issue_solved3

Now time to implement it to the more complex algorithm and DB.

Hope this could be helpfull to someone!

9 Likes

That is great, congratulations!

There aren’t many examples of the loop while node so this is a fantastic addition, thank you for sharing :slight_smile:

Mark

Hi @rubenbosetti !

I would like to congratulate you on this very ingenious solution for looping an algorithm!
I have been trying to replicate your solution, because I have a very similar need (actually I think what I need is a bit more simple than what you did).
However, I can’t seem to get it to work properly and would like to ask for some help if possible.

Let’s say my model is just a rectangular room and the position of the 4 walls is defined by 2 dimensions labeled with 2 global parameters (Room width and Room depth).
My DB has 3 columns - Project ID, Room width and Room depth (and 20 rows with different values for each).
Then I need to export an image for each of the 20 cases.
So the difference is that I don’t actually need to Create geometry → Export image → Delete Geometry → Loop for the next row;
I just need to Set Global Parameters → Export Image → Loop for the next row.

I’ve built my graph exactly the same way you did, with a function Custom node that get’s looped (just changing the “Create/Delete” part for a “Set Global Parameters by Name” part.

When I run it, it does work - it creates an image for the chosen view in the desired directory and names the images according to the 20 names from the IDs column, so it is really looping.
However, all the images are the same image with the original dimensions…
It seems to wait until after the all the images have been exported, and only then is sets the Global Parameter with the values of the last row.
Passthroughs have been used on the right spots to ensure that it waits for the Global Parameters being set before exporting the images…

Do you have any insight as to why this is happening and what am I doing wrong?
I appreciate any help you can spare!

1 Like

Ehi @hepner !
So nice to see someone working in the same direction!
When I was doing some research on this, it was really hard to find info on some specific topic and one was exactly the one you’re adressing now.
You’ll have to deal with the misterious transactions nodes

Basically Dynamo is a coding environment that’s indipendent from Revit, although it can be integrated into it.
Some nodes perform operations inside Dynamo, like operations on variables, creating geometry and so on.
Other nodes are designed to make Revit do things. This is done by calling some functions from the Revit API. But the way this is done is a bit tricky: what I have understood is that Dynamo creates a list of operations that Revit has to perform (ex. create a slab, create a wall, modify the height of the created wall ecc…) and then it pushes these operations into Revit whenever the current transaction (between Dynamo and Revit) ends. When the transaction terminates, also Revit refreshes and all the required operations take place; so you will see appear, all at one time, all the requested elements.
So, what’s this transaction? Dynamo creates a global transaction with Revit that ends whenever the Dynamo script ends. So, Revit will perform the requested operations all at one time when the Dynamo script will end.

And here come some problems! There are cases in which you want to have more than one global transaction!

Take my example above:
1. create a slab, 2. create a wall, 3. modify the height of the created wall
In this script step 3 won’t work and you’ll get an error! As you have just one transaction, Revit will receive the three operations at the same time, will try to execute them and only AFTER this it will refresh and actually generate the elements.
So, it’s like Revit will try to modify a wall that’s still not there…

How to fix this?
You have to manually end the current transaction and begin another one BEFORE the wall gets modified:

  1. create a slab, 2. create a wall, 3. transaction end, 4. transacton start, 5. modify the height of the created wall.

Passthrougs are no use here. They just help you to set the order of exectution, but your problem arises when Dynamo has to pass informations to Revit and this is done by transactions.

In your case Revit has to refresh each time you request a modication to an element and then export, otherwise it will correctly loop, but without having actualy modified the elements!
So you have to end and restart the transaction before exporting inside the custom node.

Something like this:

Let me know if it works!

4 Likes

Hi @rubenbosetti !
Thank you for replying so fast and taking the time to give such a thorough explanation!
I really understood it, implemented it, and it works now! Such a simple solution… I’m as happy as a kid with a new toy…
I think the importance of the Transaction nodes really is not stressed enough around here for us begineers. I guess it’s something that is kind of taken for granted by those who can script custom nodes in Python…
Thanks again for your awesomeness!

1 Like

Good solution! I am struggling with the same issue. Where did you take a NEEVtestForLoop node? What does it do?

That is the custom node that contains the routine to be looped.
So just write whatever routine you want to loop into a custom node and put it there

1 Like