Still at the Forge Accelerator in Rome and looking further into the Forge Design Automation API for Revit.
As mentioned yesterday, it is not yet available or documented, except to a closely restricted private beta. For more information on its current status, please refer to Mikako Harada's discussion of Design Automation for Revit.
However, you can stiil start preparing your add-in for the day when it comes:
Application
object Here are some aspects to consider:
Yesterday, as a first example step, we modified the StairsAutomations sample to avoid displaying any warnings, so the second item listed above is handled.
Today, we'll address most of the remaining ones:
We'll move the execution away from an external command and trigger it from the ApplicationInitialized
event instead.
In fact, we'll entirely remove all references to RevitAPIUI.dll
.
We'll also open the model file ourselves.
In Forge, a different system will be used, so you cannot later use the ApplicationInitialized
event there.
Design Automation for Revit continues doing setup past the point at which ApplicationInitialized
is raised.
For the time being, though, we can use it to just mimic the 'run automatically' behaviour.
The trickiest step for me was finding out how to access the Revit Application
object using only the IExternalDBApplication
interface, because that is apparently not documented anywhere at all.
I finally found the solution in a previous blog post
on automatically opening a project on start-up –
the sender
argument passed in to the ApplicationInitialized
can be cast to Application
.
That enables me to implement the entirely UI-independent DB application to drive the stairs creation utility class like this:
using System; using Autodesk.Revit.DB; using Autodesk.Revit.DB.Events; using Autodesk.Revit.ApplicationServices; namespace Revit.SDK.Samples.StairsAutomation.CS { /// <summary> /// Implement the Revit add-in IExternalDBApplication interface /// </summary> public class DbApp : IExternalDBApplication { string _model_path = "C:/a/vs/StairsAutomation/CS/Stairs_automation_2019_1.rvt"; /// <summary> /// The implementation of the automatic stairs creation. /// </summary> public void Execute( Document document ) { // Create an automation utility with a hardcoded // stairs configuration number StairsAutomationUtility utility = StairsAutomationUtility.Create( document, stairsConfigs[stairsIndex] ); // Generate the stairs utility.GenerateStairs(); ++stairsIndex; if( stairsIndex > 4 ) stairsIndex = 0; } void OnApplicationInitialized( object sender, ApplicationInitializedEventArgs e ) { // Sender is an Application instance: Application app = sender as Application; Document doc = app.OpenDocumentFile( _model_path ); if( doc == null ) { throw new InvalidOperationException( "Could not open document." ); } Execute( doc ); } public ExternalDBApplicationResult OnStartup( ControlledApplication a ) { // ApplicationInitialized cannot be used in Forge! a.ApplicationInitialized += OnApplicationInitialized; return ExternalDBApplicationResult.Succeeded; } public ExternalDBApplicationResult OnShutdown( ControlledApplication a ) { return ExternalDBApplicationResult.Succeeded; } private static int stairsIndex = 0; private static int[] stairsConfigs = { 0, 3, 4, 1, 2 }; } }
Note the absence of all references to the Autodesk.Revit.UI
namespace.
Now that we implement no external command, Revit complains that no external command is found:
That makes perfect sense, of course.
We need to adapt the add-in manifest and inform Revit that we are loading a DB application instead.
As an external application, it requires a Name
node:
We end up with the following add-in manifest file:
<?xml version="1.0" encoding="utf-8"?> <RevitAddIns> <AddIn Type="DBApplication"> <Assembly>StairsAutomation.dll</Assembly> <ClientId>4ce08562-a2e1-4cbf-816d-4923e1363a21</ClientId> <FullClassName>Revit.SDK.Samples.StairsAutomation.CS.DbApp</FullClassName> <Name>StairsAutomation</Name> <Description>A utility sample that creates a series of stairs, stairs runs and stairs landings configurations based upon predefined rules and parameters.</Description> <VendorId>ADSK</VendorId> </AddIn> </RevitAddIns>
There is not much more left to do now, really.
These are all that come to mind off-hand:
The first three we can address right away...
Oops, I almost forgot: You can download the modified SDK sample and examine every step I took in modifying it so far from and in the StairsAutomation GitHub repository.