Friday, February 29, 2008

Revit 2009 API information

The gates are open, NDA is lifted, Revit 2009 API information is starting to come through, check out Matts blog with a heap of well written posts on some of the new features: http://cadappdev.blogspot.com/

Tuesday, February 19, 2008

Setting up a template for Revit API External Commands

Recently I have been commissioned to tap into the Autodesk Revit API, and create external commands for Revit Structure (Applies for Revit Architecture as well). Documentation is limited, and there are few experts in Australia at present.

I have used the AUGI Forum community, the API SDK Samples, and this API Webcast to get me going. If you plan on writing a lot of different external commands, then chances are, you're going to be best served with a Visual Studio template.

I'm still using Visual Studio 2005 with .Net 2.0, but I wouldn't imagine it would be much different in visual studio 2008. I am also using C#, rather than visual basic, as most of the examples are in C#, and it is my choice of language. To get you started, reading the introduction material in the API SDK is going to get you started, there is a word document there, then you will have a good idea of what I am doing.

First off, create a new project in Microsoft Visual Studio, just a Class Library will do, unless you want a dialog box in your template. Name it whatever you like (it gets changed when you make a template) and store it in a folder for your Revit commands. Normally here, I would right click on my assembly and go to properties and set a couple of things, but we will skip that step for now as those changes don't get saved in the template.

Now we need to import the RevitAPI file, go to Project > Add Reference, then browse to your Revit directory to find the RevitAPI.dll file, select it. Once it is imported, it will show up in the references folder, click 'RevitAPI' there and go to properties, change 'Copy to Output Directory' to 'Do not copy'. This stops a copy of the RevitAPI file, which is 5-10 mb being made each time.

There will be a default .cs file in your solution, named class1.cs or similar, change this to Command.CS (it doesn't really matter, however this is the format followed in the API samples). And then open it for editing. At the top, add 'using Autodesk.Revit;' to the using list. This tells the class that it will be using the RevitAPI file we imported. Now we need to tell it that this is going to be an external command, to do this, we inherit the IExternalCommand interface, by adding ": IExternalCommand" to the end of our class signature, making it: class Command : IExternalCommand Now, each IExternalCommand needs to supply a result, here is how we start the cogs of our command turning. In our class, create a 'public IExternalCommand.Result', as follows:
" public IExternalCommand.Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) {

} "
This should be nothing new if you have read the API documentation, but I am recapping it for you.

From here, your command will complete its actions, call other classes and methods, and then tell revit whether it succeeded or failed. Seeing as this is just a template, we just need to put the basic framework in, here's how i like to do it: "
try {
// Command does stuff here
return IExternalCommand.Result.Succeeded;
} catch (Exception ex)
{
MessageBox.Show("An error has occured in a this external command, please show this to your Revit Manager: \r\n " + ex.ToString());
return IExternalCommand.Result.Failed;
} "
As you can see, I have enclosed all of my code in Try Catch blocks, this is to make things end a little more neatly in case of a crash. You might like to cut your Try Catch block out while testing and learning, as the Visual Studio 2005 debugger has a hard time helping you when you use them, but make sure you put them back in. You also might not like to spit out the exception to the user, depends on the circumstances. You will also noticed I have added the return of IExternalCommand.Result.Succeeded in the try block, and Failed in the catch, so if an error occurs - the command fails, if not, it succeeds. That is how your command exits, when it reaches either of those lines of code.

Once you have done that, you might like to add some summary comments eg

///
/// Created by Rod Howarth (http://rodhowarth.com) for CLIENT
///
once you have done that, simply go to File > Export Template, and save it where you like. It will automatically be added to your Visual Studio templates. Access it again by going File > New Project > Visual C# (click on the heading) and then choose the template you named. Now you are all setup to start banging out some great Revit External Commands. I intend on blogging some more about the basic process as well as bits of peices of information I discover for myself along the way, in a bid to help increase the amount of Revit API help that is available online.