Run DYnamo Script on entire folder of dwg's

Hello, I am looking to run a Dynamo script on 5,000 files. The script deletes one block and inserts another at certain coordinates, happy to share it. Is there a way to run this Batch on a whole folder of dwg’s? There’s a node Folder.get.contents.in.folder that is looking for forge folder, maybe I need to create one of those? This seems like something lots of folks would want. Thank You!

You can obtain contents in a directory using this combination of nodes.
Hope this helps!

3 Likes

@nick.turner66KAP from my experience, this is going to be tricky becuase Dynamo in Civil 3D only runs on the current DWG. There was some discussion about this in this post, maybe it helps:

Other thoughts from Paolo here:

Thanks guys! Patrick’s nodes worked great for getting all the dwg’s from the folder. When I connect it to ‘document’ or try other links it spits an error. If @Paolo_Emilio_Serra1 says it can’t do it, that’s a bummer. Seems like a key feature, looks like there is a Revit workflow folks have made but our Civil 3D AutoCAD crew is usually a step or two behind.

1 Like

@nick.turner66KAP Dynamo is designed to work only on the current Document of the host application (in Revit it makes sense especially because you have different objects between the Project and the Family editor). Also it is impacted by the binding / tracing mechanism. In truth, the Civil 3D implementation of Dynamo was trying to decouple the binding from the DYN and embed the results in the DWG. There is still some distance to cover before it works properly but the idea is there.
Both in Revit and Civil 3D the workflows to operate with multiple documents are possible if you can launch Dynamo from the host application without the user interface (like for Dynamo Player).
In Autodesk Consulting we developed a scheduler for Dynamo for Revit that allows to associate a sequence of graphs to execute on a list of Revit files at a given time during the day. The implementation of Dynamo for Civil 3D is quite different though and it is trickier to obtain the same results (although not impossible, didn’t have time or a project to investigate it thoroughly). The easy option is to use the AutoCAD/Civil 3D API via Python but I understand it could be daunting. The workflow you described at the beginning seems easy enough to migrate to Python.

2 Likes

Thanks @Paolo_Emilio_Serra1, I don’t imagine it would be as simple as making the directory path an ‘input’ in Dynamo player so you don;t have to launch the dwg’s. I am a beginner in Python, but with 5,000 dwg’s to do it on, I think I will need to do something with the API and python.

@nick.turner66KAP happy to help, let’s take the occasion to make it an instructional post for others too :slight_smile:

4 Likes

Awesome @Paolo_Emilio_Serra1, that would be really cool. It seems a widespread needed functionality to run a whole folder. This would be a nice simple script to do it with too. I will get in touch. :grinning:

@Paolo_Emilio_Serra1 do you use Python in Visual Studio for the API?

@nick.turner66KAP no I use PyCharm but it is my preference because it is free and has great features to manage Python projects

First of all let’s have a look at the logic behind it https://cawemo.com/share/cb5df7ef-45ee-482a-84f0-112b540a89ab (to zoom press CTRL and use the mouse wheel, to pan press the left mouse button and drag)

1 Like

From the logic it is possible to identify what are the main functions at play and what are the inputs to consider. In this case I’m using a pure AutoCAD API approach although it should be possible to simplify the code a bit calling the Dynamo nodes.

This is how it looks like at the end; it will produce also a Log file to double check the results.

The main function is the one that gets all the DWGs from the folder and subfolders recursively.
Python has the os.walk() method that does exactly what we need (L206-209)
For each DWG then it calls the inner function that does all the job.
In this case there a lot of inputs to be as flexible as possible. In Dynamo the CoordinateSystem method to create a BlockReference is basically providing the same inputs but it is using a single object to derive all of them.

There are a few best practices such as a “graceful failure” at the very beginning (L193): if not all the critical inputs are provided, the function returns its own instructions (the text from line 176-189).

The Current document (it could be an empty document) is stored to avoid Dynamo for Civil 3D complaining about the absence of a document at the end of the function, so before leaving it we just need to remember to restore the current document.

1 Like

In the inner function there is a first part to open a document in the background (L99). Once it has been opened for writing, we need to make it the Current Document (L100).

1 Like

What comes next is the core of the inner function and might have been done differently. I’ve tried to put together a little bit of everything to show how to safely access a document via context managers (the “with” statements to LockDocument, Database and Transaction), check and create layers, check and import a block from an external DWG, iterate through the Entities of the Model Space, test for the type of an Entity (isinstance() L146), erase an entity from the Database, create a BlockReference, deal with Transforms in AutoCAD API (Matrix3d objects L159-162) and finally add the new objects to the Database. After all that the transaction must be committed to validate the changes made and the Document must be saved in the same location.


1 Like

Here is the final Dynamo file with the references used. It could have been done in a different way, the main goal was to show how it is possible to run a script on multiple documents.
Run Function on multiple files.dyn (21.2 KB)

8 Likes

Awesome work Paolo. Great explanation of the logic.

Paolo, the script is opening one of the documents in the folder, but not replacing the block and giving this warning. Possibly I put incorrect inputs in?

@nick.turner66KAP Can you make sure that the source file for the new block is not in the folder and its subfolders? Basically the script was trying to modify the file that contains the title block, and hence the error.
Just add these lines in the replace_block_reference() (or download the file again).