Wednesday, July 8, 2009

Revit API Search Engine

Hi all,
I had an idea today whilst doing some research for an API program I'm attempting to create.  My normal procedure for this after exhausting my usual resources (SDK, RvtMgdDbg etc), is to search a few of the Revit API blogs out there, then AUGI, Autodesk.com forums etc.

I've found this 'Google custom search' feature that Google has now - you can setup your own search engine to only search certain sites. So I decided to create own with Revit API resources.

http://www.google.com/coop/cse?cx=003379886482190238526:wi7yjrtrkd8 is the full link. I’ve created a slightly easier redirect page at http://RevitAPISearch.RodH.org/

The blogs I’ve got there at the moment are:
http://redbolts.com/blog/
http://revit-programmer.blogspot.com/
http://thebuildingcoder.typepad.com/blog/
http://cadappdev.blogspot.com/
http://roddotnet.blogspot.com

I've added AUGI and Autodesk.com forums in there now, but I'm having trouble restricting the results to just Revit API sections..

http://discussion.autodesk.com/forum...pa?forumID=160
http://forums.augi.com/forumdisplay.php?f=218 are the two links I’ve inserted, and I can choose one of these options:
Include all pages this page links to
Include all partial sites this page links to
Include all sites this page links to

I've experimented with the first 2, and found they still seem to show up results from other forum sections, so I'll have to keep working on that.
My goal here is to try and narrow the results down to the API as much as possible - ie not find info about what buttons to click to insert columns in Revit when you are trying to do it programmatically.

If anyone would like to suggest sites to index please let me know! I’ve started a discussion about AUGI HERE.

Tuesday, July 7, 2009

How to use an app.config file in a DLL plugin (External Command)

This post relates to wider .Net app.config files and linked DLL’s, but more specifically, my instance was relating to the Revit API.

For those that don’t know, an app.config file is a nice, easy way of doing configuration for your applications in .net. You can use the System.Configuration namespace to quickly access an XML config file without needing to do any manual XML reading. Unfortunately, you can only have one app.config file per executable, so if you have DLL’s linked into your application, they cannot have their own app.config files.

Seeing as the Revit API is done by external .Net DLL files which are opened within the Revit environment, this applies to them as well.

At Bornhorst + Ward, we have all of our external commands on a central network share, and each staff members ini is edited (using a tool I’ve written) to point to these external commands. I’d previously tried to use app.config files, and found they weren’t working, it seems they weren’t looking for the correct file in that network directory.

The way around it for me, was to manually locate the app.config file in my code.

   1: /// <summary>
   2: /// Get the configuration for the supplied type
   3: /// </summary>
   4: /// <param name="type">type of class</param>
   5: /// <returns>a configuration</returns>
   6: public static System.Configuration.Configuration GetConfig(Type type)
   7: {
   8:     //workout app.config lokcation
   9:     string dllLocation = type.Assembly.Location + ".config";
  10:  
  11:     if (dllLocation == null)
  12:         throw new Exception("Could not find config file, add .config in DLL location");
  13:  
  14:     //create config
  15:     ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
  16:     fileMap.ExeConfigFilename = dllLocation;
  17:     System.Configuration.Configuration config = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
  18:  
  19:     return config;
  20: }

Seeing as app.config files on DLL’s are named dllName.dll.config this gave me an easy rule for finding the config file. I then used an ExeConfigurationFileMap pointed to that location to generate the Configuration. The ‘type’ parameter, is for me to supply a type (using typeof(ClassName)) to identify the correct dll – as this method for me was written in a separate helper dll which contains some commonly used functions for all of my tools.

Then, to access the properties in that file:

   1: /// <summary>
   2: /// Gets a specific config property
   3: /// </summary>
   4: /// <param name="key">the property to get</param>
   5: /// <param name="type">type of class asking - to get right assembly</param>
   6: /// <returns>value</returns>
   7: public static string GetConfigProperty(string key, Type type)
   8: {
   9:     System.Configuration.Configuration config = GetConfig(type);
  10:     return config.AppSettings.Settings[key].Value;
  11: }

I call that method, supply the typeof(ClassName) of the class calling it, and it gets the configuration from my previous method, and then uses an access method similar to the standard AppSettings class.

Now I can have .configs for all of my revit external commands and access them easily!

Monday, April 27, 2009

Revit: 2010 API Developer Guide

I stumbled across this document today whilst setting up my SDK Samples menus in Revit.

It’s located in the Revit 2010 SDK folder (there’s an extractable on the Revit disc to get this folder) and spotted the ‘Revit 2010 API Developer Guide’.

It’s a 315 page PDF with a whole heap of tutorials, code samples and tips for using the Revit API. It’s pretty much the user manual and seems to be exactly where a new Revit API user should start. This document is exactly what I dreamed of when I started developing with the Revit API a couple of years ago!

The section headings include:

  • Getting Started
  • Add-in Integration
  • Application and Document
  • Elements Essentials
  • Parameters
  • Collections
  • Editing Elements
  • Walls, Floors, Roofs and Openings
  • Family Instances
  • Family Creation
  • Datum and Information Elements
  • Annotation Elements
  • Sketching
  • Views
  • Material
  • Geometry
  • Place and Locations
  • Shared Parameters
  • Transactions
  • Events
  • Revit Architecture
  • Revit Structure
  • Revit MEP

If there isn’t anything there that interests you, you obviously aren’t interested in the Revit API. Props to Autodesk for putting this together!

Revit 2010: Parameter.Set – Unexpected Behaviour – Fixed in 2010

I previously wrote a blog post about unexpected behaviour from the Parameter.Set method in the Revit API.

What was happening was if you called Parameter.Set and set a value that was the same as the previous value (ie unchanged) it would return false. This caused problems with detecting when the operation failed (it didn’t fail, it did what we asked).

A note in the Revit Platform API Changes and Additions document confirms that this has been fixed in Revit 2010, and the more logical functionality has been introduced:

Parameter.Set return value when value is unchanged

Previously, Revit returned False if the input value for Parameter.Set was the same as the current value. Revit now returns True in this case.”

Wednesday, April 22, 2009

ASP.Net: Error executing child request for ChartImg.axd

Sorry to all Revit API readers, this one isn’t really relevant to you.

I’ve been working on an ASP.Net project, making use of the awesome free charting tools from Microsoft. I made a form that posts back and generates a column graph based on the inputs and some database calls. A problem I kept running into was an error message that says:
”Error executing child request for ChartImg.axd”

After looking around on the net and reading through some forum posts, I discovered to fix this you just need to make a small change to your web.config.

The problem arises as I was using postbacks to generate my chart, you must add support for this in your httpHandlers section of the web.config by changing:

   1: <add path="ChartImg.axd" verb="GET,HEAD" type="System.Web.UI.DataVisualization.Charting.ChartHttpHandler, System.Web.DataVisualization, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" validate="false"/>

To:

   1: <add path="ChartImg.axd" verb="GET,HEAD,POST" type="System.Web.UI.DataVisualization.Charting.ChartHttpHandler, System.Web.DataVisualization, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" validate="false"/>

The only change between the two is in the “verb=” property I added “,POST” to the end.

After this all should work fine.

Wednesday, April 8, 2009

How to create keyboard shortcuts to External Commands in Revit 2010

Seeing we now have the fancy ribbon interface in Revit 2010, the keyboard shortcuts files you have been using are obsolete. There is instructions in the file for how to setup normal shortcuts, however I ran into a problem when trying to point the shortcuts to my external commands.

An example of an line in the keyboard shortcut file is:

"VG"    ribbon:"View-Graphics-Visibility and Appearance"

As you can see, the ribbon item you want to shortcut to is pathed out using - as a separator. This works fine, but what happens when you want to use the “Add-Ins” tab?? (note the –)

The answer is, you use ‘Add_Ins’ instead. See an example here:

"HLWD"   ribbon:"Add_Ins-External Tools-External Tools-HelloWorld"

Also note the two external tools sections, these are because there is an external tools menu on the external tools panel.

Another thing to note is that unfortunately, the problem from Revit 2009 still remains, to create a keyboard shortcut to an API program, it must be an external command in the External Tools menu. You can’t create a keyboard shortcut to your own ribbon panels/menus/buttons. So even if you have created a nice looking ribbon panel for your program, you’re going to have to make an external command (and do the ini editing to register it). If anyone knows a workaround for this, please let me know, but I’d say it’s due to the order in which Revit loads things.

Problems activating Revit 2010 – Can’t find internet connection

Our office ran into this problem all through the beta, unfortunately looks like the issue is still there in the final release.

The issue is when you try to activate, a dialog tells you there is no internet connection available. I believe this is to do with firewall settings, port 443 and proxies. However after trying to get through our ISA firewall (which is set to allow 443) it doesn’t seem to work.

Seems a little strange given all other Autodesk products have activated perfectly for years, so I’m not too keen on opening ports to try and get it to work.

Not to worry though, there is a workaround. Firstly, get as far as you can go on the activation before it tells you it’s failed. Then go and get a coffee. Come back a couple of minutes later (should only take 20-30 seconds really) and your screen should now be telling you that it’s timed out, and will offer you a link to ‘retry’. For some reason, this link must point to a different method of activation, and works fine, just like Revit 2009 did.

Alternatively if you are a subscription customer, you could try getting the activation code yourself from the register.autodesk.com site.

Hope this helps someone who is pulling their hair out trying to activate Revit!