Use F# Directly in Revit

Still struggling to load a native F# module directly as a Revit add-in? Ralf Huvendiek had a quick look at this issue and created all three different flavours of external commands implemented in F# that can be called directly as external Revit tools:

  1. Defined in a namespace.
  2. Defined in a module.
  3. Defined in a module within a namespace.

The problem I had when calling F# via C# is caused by the line specifying 'module BuildingCoder', which generates the strange class names. But even those strange names can be entered and will work in the Revit.ini file.

The decorated name defined for the Execute method in the derived class by adding the interface prefix to it is also no problem. Apparently, the CLR ignores the name and uses some other method, maybe a position within a table, to determine what method to look up and call.

Here is Ralf's implementation of the three external command classes and their Execute methods; please watch out for the overly long lines in the F# source code ... you may have to copy and paste to an editor to see the full text:

Namespace

#light

namespace RevitAddin

open Autodesk.Revit

type RevitAddin() =
  interface Autodesk.Revit.IExternalCommand with
    member public this.Execute( cData, strMessage : string byref, aElements ) =
      strMessage <- "Hello world from RevitAddin.RevitAddin"
      Autodesk.Revit.IExternalCommand.Result.Failed

Module

#light

module RevitAddinModule

type RevitAddin() =
  interface Autodesk.Revit.IExternalCommand with
    member public this.Execute( cData, strMessage : string byref, aElements ) =
      strMessage <- "Hello world from RevitAddinModule.RevitAddin"
      Autodesk.Revit.IExternalCommand.Result.Failed

Module within Namespace

#light

namespace RevitAddin

module RevitAddinModule

type RevitAddin() =
  interface Autodesk.Revit.IExternalCommand with
    member public this.Execute( cData, strMessage : string byref, aElements ) =
      strMessage <- "Hello world from RevitAddin.RevitAddinModule.RevitAddin"
      Autodesk.Revit.IExternalCommand.Result.Failed

The corresponding Revit.ini entries for loading the three external commands thus defined look like this:

[ExternalCommands]
ECCount=3

ECName1=F# 1
ECDescription1=F# in namespace
ECAssembly1=...\RevitAddin.dll
ECClassName1=RevitAddin.RevitAddin

ECName2=F# 2
ECDescription2=F# in module
ECAssembly2=...\RevitAddin.dll
ECClassName2=RevitAddinModule+RevitAddin

ECName3=F# 3
ECDescription3=F# in namespace and module
ECAssembly3=...\RevitAddin.dll
ECClassName3=RevitAddin.RevitAddinModule+RevitAddin

The three dots need to be replaced by the full path name of your assembly.

Here is the complete Visual Studio 2008 F# solution FsRevitAddin.zip.

So nothing more to stop you from checking out this exciting new functional language and creating a Revit-based entry for Kean's F# programming contest.

Several people asked how I retrieved the full class name including namespace prefix from Reflector. In my installation, the full name of the declaring type is listed in the bottom panel when you select a class or method:

Reflector displaying the full class name

3DS Max, Maya and MotionBuilder Training

Rendering is another topic of interest to some Revit developers, so please note that the Media and Entertainment team are inviting all interested parties to a series of free online trainings to learn 3ds Max, Maya or MotionBuilder APIs in just one hour a day during the March, April and May time frame.

Lunedi Sera in Verona

Last night was very enjoyable ... I took a yoga class with Marco in the Scuola Massalungo, opposite the faculty of economy in the Zona Universitá, then had an enjoyable meal in the eminently recommendable Osteria al Duca in Via Arche Scaligere 2, where I met Mauro Neri and had my 'realest' Italian conversation so far, for a couple of hours ... perfect preparation for the first Revit API introduction in Italiano today.