Task 1 – Convert Revit Add-in to Design Automation Add-in
This task converts an add-in that runs on Revit to an add-in that runs on Design Automation.
Prerequisites for this task are:
- Visual Studio 2017 or Visual Studio 2019
- Revit 2018, Revit 2019, Revit 2020, Revit 2021, Revit 2022, Revit 2023 or Revit 2024: This is required to compile the changes into the add-in.
- Basic knowledge of C#
By the end of this task you will know how to convert a regular Revit add-in to one that runs on Design Automation.
Step 1 - Clone Git repository
Clone the Git Repository for the DeleteWalls Sample, go to the folder named Desktop_Version, and open DeleteWalls.sln in Visual Studio.
The DeleteWalls Sample Git repository contains the source code for an add-in named DeleteWalls. DeleteWalls reads a .rvt file and produces another .rvt file with all the walls deleted.
The repository contains two folders for two different versions of DeleteWalls. The folder named Desktop_Version contains a C# project that produces a typical Revit add-in that runs only on Revit. It does not run on Design Automation. The folder named Design-Automation_Version contains the same project, modified to run on Design Automation. The objective of this task is to start with the C# project in Desktop_Version and end up with the project in Design-Automation_Version.
Step 2 - Repair references
The C# project you cloned may expect to find RevitAPI.dll in a location that is different to where it resides on your computer. To eliminate the risk of a broken reference:
- Find RevitAPI.dll in your Revit install location and note its location.
- In Visual Studio, remove the reference to RevitAPI.dll.
- Add a reference to RevitAPI.dll, pointing to the location you noted down earlier.
Step 3 - Add a package reference to the DesignAutomationBridge DLL
Autodesk provides a library that contains the functionality an add-in needs to interface with Design Automation. This library is known as the Design Automation Bridge and is distributed as a NuGet package at https://www.nuget.org/packages/Autodesk.Forge.DesignAutomation.Revit.
- In Visual Studio, remove the reference to RevitAPIUI.dll.
- Insert a package reference to the Design Automation Bridge corresponding to the Revit version you want to run.
Please refer Microsoft Documentation for instructions.|Tip: When inserting the package reference using Visual Studio, search for
Autodesk.Forge.DesignAutomation.Revit
with the Include prerelease option selected.
Step 4 - Remove references to user interface elements
Since there is no UI interaction in Design Automation, you must remove all references to UI elements.
In the .cs file that implements your add-in (DeleteWalls.cs in this case):
- Remove the
using
directive to theAutodesk.Revit.UI
namespace and insert ausing
directive to theDesignAutomationFramework
namespace in its place.
using Autodesk.Revit.ApplicationServices; using Autodesk.Revit.DB; using DesignAutomationFramework;
- In the file DeleteWalls.addin, change
AddIn Type
fromcommand
toDBApplication
<?xml version="1.0" encoding="utf-8"?> <RevitAddIns> <AddIn Type="DBApplication"> <Name>DeleteWalls</Name> <Assembly>.\DeleteWalls.dll</Assembly> <AddInId>d7fe1983-8f10-4983-98e2-c3cc332fc978</AddInId> <FullClassName>DeleteWalls.DeleteWallsApp</FullClassName> <Description>"Deletes Walls"</Description> <VendorId>Autodesk</VendorId> <VendorDescription> </VendorDescription> </AddIn> </RevitAddIns>
Show More
Notes:
Whenever you are converting a Revit add-in in general, make sure that you:
- Remove references to
RevitAPIUI
or any code in theAutodesk.Revit.UI
namespace. These functions are not available in Design Automation and hence cannot be called.- Remove references to
WPF
,Windows Forms
, or any other UI-based libraries.
Step 5 - Convert IExternalApplication or IExternalCommand to IExternalDBApplication
Since there is no UI interaction in Design Automation, you can’t use the Revit UI to initiate commands.
In order to initiate commands with Design Automation, you must implement OnStartup
and OnShutdown
in your add-in.
These functions receive a ControlledApplication
instead of a UIControlledApplication
. The functions return an ExternalDBApplicationResult
object:
For this task, in DeleteWalls.cs
, implement OnStartup
and OnShutdown
as shown in the following code block.
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.DB;
using DesignAutomationFramework;
namespace DeleteWalls
{
[Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
public class DeleteWallsApp : IExternalDBApplication
{
public ExternalDBApplicationResult OnStartup(Autodesk.Revit.ApplicationServices.ControlledApplication app)
{
return ExternalDBApplicationResult.Succeeded;
}
public ExternalDBApplicationResult OnShutdown(Autodesk.Revit.ApplicationServices.ControlledApplication app)
{
return ExternalDBApplicationResult.Succeeded;
}
Step 6 - Add an event handler for DesignAutomationReady
DesignAutomationBridge
defines the event DesignAutomationReadyEvent
. The Revit engine raises the DesignAutomationReadyEvent
when it’s ready to run your add-in. The event handler is the entry point to your code.
- Set the success/failure argument to
DesignAutomationReadyEventArgs.Succeeded
so that Design Automation knows your code succeeded.
public class DeleteWallsApp : IExternalDBApplication { public ExternalDBApplicationResult OnStartup(Autodesk.Revit.ApplicationServices.ControlledApplication app) { DesignAutomationBridge.DesignAutomationReadyEvent += HandleDesignAutomationReadyEvent; return ExternalDBApplicationResult.Succeeded; } public void HandleDesignAutomationReadyEvent(object sender, DesignAutomationReadyEventArgs e) { e.Succeeded = true; DeleteAllWalls(e.DesignAutomationData); }
Show More
- Modify
DeleteAllWalls
to acceptDesignAutomationData
.
public static void DeleteAllWalls(DesignAutomationData data) { if (data == null) throw new ArgumentNullException(nameof(data)); Application rvtApp = data.RevitApp; if (rvtApp == null) throw new InvalidDataException(nameof(rvtApp)); string modelPath = data.FilePath; if (String.IsNullOrWhiteSpace(modelPath)) throw new InvalidDataException(nameof(modelPath)); Document doc = data.RevitDoc; if (doc == null) throw new InvalidOperationException("Could not open document."); using (Transaction transaction = new Transaction(doc)) { FilteredElementCollector col = new FilteredElementCollector(doc).OfClass(typeof(Wall)); transaction.Start("Delete All Walls"); doc.Delete(col.ToElementIds()); transaction.Commit(); } ModelPath path = ModelPathUtils.ConvertUserVisiblePathToModelPath("result.rvt"); doc.SaveAs(path, new SaveAsOptions()); }
Show More
- Delete the method
Execute
, which previously calledDeleteAllWalls
. This is no longer necessary.
During the execution of your add-in, all files you load from the disk or write to the disk must go into the Windows current working directory. In Design Automation for Revit, write access is limited to the current working directory and its children.
Step 7 - Handle failures encountered by Revit
When an add-in runs on Revit, the add-in uses the UI to communicate warnings and errors. Since there is no UI interaction in Design Automation, you must use an alternate strategy to handle failures.
For this walkthrough, you will use the default error handler. You don’t need to add any code to enable the default error handler because it comes by default with the Design Automation Bridge. The default error handler suppresses warnings and resolves errors automatically by applying the default options. If resolution of an error fails, it rolls back the failed action.
For more information refer Handling Revit Failures .
Step 8 - Build the add-in
- In Visual Studio, rebuild DeleteWalls.dll.
You should now have a Design Automation capable Revit add-in.
Additional notes
- Use the Design Automation for Revit Debug Tool to test the add-in locally. The Readme file in the Git repository provides instructions on how to test the add-in. You can also follow a video tutorial on how to use this tool on YouTube.
- Your application cannot use the network or write to any files outside of the current working directory (or a child folder of the working directory). Restrictions on Design Automation for Revit can be found here.
- If step 8 fails, you can download a Design Automation capable version of DeleteWalls.dll from here and continue with task 2.