Revit APP Blog

Information on Revit APP.

Browsing Posts in Coding

Very simple DWG import code:

public Result Execute(ExternalCommandData commandData, ref string message, Autodesk.Revit.DB.ElementSet elements)
{
   Document curDoc = commandData.Application.ActiveUIDocument.Document;
   Transaction transaction = new Transaction(curDoc, “Import DWG”);
   transaction.Start();

   DWGImportOptions options = new DWGImportOptions();
   options.Placement = Autodesk.Revit.DB.ImportPlacement.Origin;
   options.OrientToView = true;
   options.View = curDoc.ActiveView;
   Element element = null;
   if (curDoc.Import(@”C:\Temp\Test.dwg”, options, out element))
      transaction.Commit();
   else
      transaction.RollBack();

   return Result.Succeeded;
}

This code only shows very simple way to import a dwg file. The DWGImportOptions contains many properties which you can use and test to get what the best you want.

Export

1 comment

Revit API provides almost all functionalities for exporting, most time exporting is tedious work and API developer can do a lot here. The only problem is to know what the end user real needs. To write export code, it’s relative simple. Let’s use a simple example to demostrate: export current view as a dwf file. The code is:

namespace myRevitApp
{
   [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
   [Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
   public class Class1 : IExternalCommand
   {
      public Result Execute(ExternalCommandData commandData, ref string message, Autodesk.Revit.DB.ElementSet elements)
      {
         Document curDoc = commandData.Application.ActiveUIDocument.Document;
         Transaction transaction = new Transaction(curDoc, “Export_To_DWF”);
         transaction.Start();
         bool exported = false;

         ViewSet views = new ViewSet();
         views.Insert(curDoc.ActiveView); // add more views if you want to add more.

         // if you want other format, just use different export options, such as: DWGExportOptions
         // Only keep in mind that different options may contain different properties
         // check the setting dialog for manual export, you can know almost all the properties mean
         DWFExportOptions options = new DWFExportOptions();
         options.ExportObjectData = true;
         options.ExportingAreas = false;
         options.MergedViews = false;
         options.ImageFormat = DWFImageFormat.Lossless;
         options.ImageQuality = DWFImageQuality.Default;
         exported = curDoc.Export(@”C:\temp”, “test.dwf”, views, options);
         transaction.Commit();

         if (exported)
            return Result.Succeeded;
         else
            return Result.Failed;
      }
   }
}

Revit 2011 API provides user ways to create their own ribbon panel & buttons. Plus the shortcut capability, it makes addins similar as built-in functionalities. To add your own ribbon stuff, you only need to implement the IExternalApplication interface, and in the OnStartup function, write code like this:

public Result OnStartup(UIControlledApplication uiControlledApplication)
{
   // The location of this command assembly
   string assemblyPath = System.Reflection.Assembly.GetExecutingAssembly().Location;

   // begin to create custom Ribbon panel and command buttons.
   // create a Ribbon panel.
   RibbonPanel myPanel = uiControlledApplication.CreateRibbonPanel(“MyRibbonPanel”);

   // the button in the new panel
   PushButton pushButton = myPanel.AddItem(new PushButtonData(“MyPushButton”, “Command1″, assemblyPath, typeof(Command1).FullName)) as PushButton;
   pushButton.ToolTip = “Command1″;
   // the large image uses for tooltip
   Command1.LargeImage = new BitmapImage(new Uri(Path.Combine(buttonImageDir, “Command1_Large.bmp”)));
   // image uses for the button
   Command1.Image = new BitmapImage(new Uri(Path.Combine(buttonImageDir, “Command1_Small.bmp”)));

   RadioButtonGroupData radioButtonGroupData = new RadioButtonGroupData(“TypeSelector”);
   RadioButtonGroup radioButtonGroup = (RadioButtonGroup)(myPanel.AddItem(radioButtonGroupData));
   ToggleButton toggleButton = radioButtonGroup.AddItem(new ToggleButtonData(“Type1″, “Type1″, assemblyPath, “MyApp.Type1″));
   toggleButton.LargeImage = new BitmapImage(…large image uri);
   toggleButton.Image = new BitmapImage(…image uri);
   toggleButton = radioButtonGroup.AddItem(new ToggleButtonData(“Type2″, “Type2″, assemblyPath, “MyApp.Type1″));
   toggleButton.LargeImage = new BitmapImage(…large image uri);
   toggleButton.Image = new BitmapImage(…image uri);

   return Result.Succeeded;
}

Go to the SDK\Samples\Ribbon\CS folder to get more detail examples.

If you want to use images added in the solution (so you don’t need external image file when deployment), you can add all needed image files in projects and set their “Build Action” in property as “Embedded Resource”, and get the ImageSource using following code:

System.IO.Stream file = app.GetManifestResourceStream(namespace + “.” + imageName);
PngBitmapDecoder bd = new PngBitmapDecoder(file, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);

 Please replace the namespace with your own namespace name.

Revit 2011 API exposed many new application events that API developer can use. The whole list of events is:

Name Description
DocumentChanged Subscribe to the DocumentChanged event to be notified when Revit document has changed.
DocumentClosed Subscribe to the DocumentClosed event to be notified immediately after Revit has finished closing a document.
DocumentClosing Subscribe to the DocumentClosing event to be notified when Revit is just about to close a document.
DocumentCreated Subscribe to the DocumentCreated event to be notified immediately after Revit has finished creating a new document.
DocumentCreating Subscribe to the DocumentCreating event to be notified when Revit is just about to create a new document.
DocumentOpened Subscribe to the DocumentOpened event to be notified immediately after Revit has finished opening a document.
DocumentOpening Subscribe to the DocumentOpening event to be notified when Revit is just about to open a document.
DocumentPrinted Subscribe to the DocumentPrinted event to be notified immediately after Revit has finished printing a view or ViewSet of the document.
DocumentPrinting Subscribe to the DocumentPrinting event to be notified when Revit is just about to print a view or ViewSet of the document.
DocumentSaved Subscribe to the DocumentSaved event to be notified immediately after Revit has finished saving a document.
DocumentSavedAs Subscribe to the DocumentSavedAs event to be notified immediately after Revit has finished saving document with a new file name.
DocumentSaving Subscribe to the DocumentSaving event to be notified when Revit is just about to save a document.
DocumentSavingAs Subscribe to the DocumentSavingAs event to be notified when Revit is just about to save the document with a new file name.
DocumentSynchronizedWithCentral Subscribe to the DocumentSynchronizedWithCentral event to be notified immediately after Revit has finished synchronizing a document with central file.
DocumentSynchronizingWithCentral Subscribe to the DocumentSynchronizingWithCentral event to be notified when Revit is just about to synchronize a document with central file.
FailuresProcessing Subscribe to the FailuresProcessing event to be notified when failures are being processed at the end of transaction.
FileExported Subscribe to the FileExported event to be notified immediately after Revit has finished exporting files of formats supported by the API.
FileExporting Subscribe to the FileExporting event to be notified when Revit is just about to export files of formats supported by the API.
FileImported Subscribe to the FileImported event to be notified immediately after Revit has finished importing a file of format supported by the API.
FileImporting Subscribe to the FileImporting event to be notified when Revit is just about to import a file of format supported by the API.
ViewPrinted Subscribe to the ViewPrinted event to be notified immediately after Revit has finished printing a view of the document.
ViewPrinting Subscribe to the ViewPrinting event to be notified when Revit is just about to print a view of the document.

When the event will be post is decribed in the description part. Most cases, you could know what the event is through its name directly.

Use the event is very simple, let’s use the DocumentOpened event as example, the event handler should be added when revit startup, so we need an external application instead of external command to handle this. New a file and write code as:

using System;

using Autodesk.Revit;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Events;
using Autodesk.Revit.UI;

namespace myRevitApp
{
   [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Automatic)]
   [Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
   public class MyApp : IExternalApplication
   {
      public Result OnStartup(UIControlledApplication uiControlledApplication)
      {
         uiControlledApplication.ControlledApplication.DocumentOpened += new EventHandler<DocumentOpenedEventArgs>(docOpen);
         return Result.Succeeded;
      }

      private void docOpen(object sender, DocumentOpenedEventArgs e)
      {
         Autodesk.Revit.ApplicationServices.Application app = sender as Autodesk.Revit.ApplicationServices.Application;
         UIApplication uiApp = new UIApplication(app);
         Document doc = uiApp.ActiveUIDocument.Document;
         // show document name
         TaskDialog.Show(“Doc path name”, doc.PathName);
      }

      public Result OnShutdown(UIControlledApplication application)
      {
         return Result.Succeeded;
      }
   }
}

And the .addin file should be like:

<?xml version=”1.0″ encoding=”utf-16″ standalone=”no”?>
<RevitAddIns>
  <AddIn Type=”Application”>
    <Name>myRevitApp</Name>
    <Assembly>C:\Project\myRevitApp.dll</Assembly>
    <AddInId>7cbae747-78f9-4dd5-ac92-a94f6229f9b3</AddInId>
    <FullClassName>myRevitApp.MyApp</FullClassName>
  </AddIn>
</RevitAddIns>

 Then build the solution and run, a task dialog will show up when you open a document.

In previous blog, we said that user can retrieve one parameter from an element through Element.get_Parameter(…) function.

Revit API also provides properties for API developer to get all parameters of an element, the two properties are:
Element.Parameters
Element.ParametersMap

Both properties contain all public parameters the element has, however, they also differ a little and we should use them in different ways.

The first property Parameters returns a set of Parameter, we can use this if we want to iterate all public parameters. The code would like:
   ParameterSetIterator it = Element.Parameters.ForwardIterator();
   while (it.MoveNext())
   {
      Parameter param = it.Current as Parameter;
      // Maybe check some conditiones like param.Definition, StorageType etc.
      // do something for param…
   }
The second property ParametersMap returns a map of Parameters, whose key is the name of the parameter. So if we want to retrieve several parameters from element through their name, use this property would be better (get_Parameter can also achieve this, however, that function will iterate all parameters each time it calls). The code looks like:
   ParameterMap paramMap = eRef.Element.ParametersMap;
   if (paramMap.Contains(“ParamA”))
   {
      Parameter param = paramMap.get_Item(“ParamA”);
      // do something for param …
   }
   if (paramMap.Contains(“ParamB”))
   {
      Parameter param = paramMap.get_Item(“ParamB”);
      // do something for param …
   }
   if (paramMap.Contains(“ParamC”))
   {
      Parameter param = paramMap.get_Item(“ParamC”);
      // do something for param …
   }
Attention: Check whether the map contains the parameter before get it, otherwise, it will throw an exception if the name is not found.

You have several ways to retrieve element parameters’ name/value/type etc. Let’s use one simple example to show this. If you want to get one parameter from an element, usually you can through the BuiltInParameter enum or the parameter’s name. Through the BuiltInParameter is efficient and can avoid string localization problem, try to use this way if you can. The detail code is:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using Autodesk.Revit;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;

namespace myRevitApp
{
   public class WallFilter : ISelectionFilter
   {
      /// <summary>
      /// Allow Wall to be selected
      /// </summary>
      /// <param name=”element”>A candidate element in selection operation.</param>
      /// <returns>Return true for wall. Return false for non wall element.</returns>
      public bool AllowElement(Element element)
      {
         return element is Wall;
      }

      /// <summary>
      /// Allow all the reference to be selected
      /// </summary>
      /// <param name=”refer”>A candidate reference in selection operation.</param>
      /// <param name=”point”>The 3D position of the mouse on the candidate reference.</param>
      /// <returns>Return true to allow the user to select this candidate reference.</returns>
      public bool AllowReference(Reference refer, XYZ point)
      {
         return true;
      }
   }

   [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
   [Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
   public class Class1 : IExternalCommand
   {
      public Result Execute(ExternalCommandData commandData, ref string message, Autodesk.Revit.DB.ElementSet elements)
      {
         // Select elements. Click “Finish” or “Cancel” buttons on the dialog bar to complete the selection operation.
         List<ElementId> elemDeleteList = new List<ElementId>();
         WallFilter wfilter = new WallFilter();
         Reference eRef = commandData.Application.ActiveUIDocument.Selection.PickObject(ObjectType.Element, wfilter, “Please pick a wall.”);
         if (eRef != null && eRef.Element != null)
         {
            // Get parameter through builtin parameter enum, this is efficient, use this way if you know the parameter enum
            Parameter param = eRef.Element.get_Parameter(BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS);
            if (param != null)
            {
               TaskDialog.Show(“My Revit APP”, “Wall comments: ” + param.AsValueString());
            }
            else
            {
               TaskDialog.Show(“My Revit APP”, “Cannot find wall comments!”);
            }
            // Get parameter through name
            param = eRef.Element.get_Parameter(“Length”);
            if (param != null)
            {
               TaskDialog.Show(“My Revit APP”, “Wall Length through name: ” + param.AsValueString());
            }
            else
            {
               TaskDialog.Show(“My Revit APP”, “Cannot find wall Length parameter through name!”);
            }
         }
         return Result.Succeeded;
      }
   }
}

Revit 2011 API provides more for task dialog, we can extend our example code based on http://blog.revitapp.com/2010/06/use-revit-like-task-dialog/.

Add following code below the line in Class1 (taskDialog.MainContent = “The name of the selected element is:” + eRef.Element.Name;)

   // Add commmandLink to task dialog
   taskDialog.AddCommandLink(TaskDialogCommandLinkId.CommandLink1, “View category name”);
   taskDialog.AddCommandLink(TaskDialogCommandLinkId.CommandLink2, “View element ID”);

 Revit API supports up to 4 command links. And add code to deal with the command link, add code below line (TaskDialogResult tResult = taskDialog.Show();)

   if (TaskDialogResult.CommandLink1 == tResult)
   {
      TaskDialog subDlg = new TaskDialog(“Category Name”);
      if (eRef.Element.Category == null)
         subDlg.MainInstruction = “No category”;
      else
         subDlg.MainInstruction = “Category name: ” + eRef.Element.Category.Name;

      subDlg.Show();
   }
   else if (TaskDialogResult.CommandLink2 == tResult)
   {
      // a simpler way to show a task dialog
      TaskDialog.Show(“Element ID”, “Element ID: ” + eRef.Element.Id.ToString());
   }

The main task dialog looks like:

Revit 2011 API provides better UI for interactive use. Here we start from the simpliest one.

Based on our previous application (http://blog.revitapp.com/2010/06/get-selected-elements/), replace the MessageBox line:

MessageBox.Show(elem.Name);   // Pop message box to show element’s name

with following code:

   // Creates a Revit task dialog to communicate information to the interactive user.
   TaskDialog taskDialog = new TaskDialog(“My Revit APP”);
   taskDialog.MainInstruction = “My Revit APP”;
   taskDialog.MainContent = “The name of the selected element is:” + eRef.Element.Name;

   // Set common buttons and default button. If no CommonButton or CommandLink is added,
   // task dialog will show a Close button by default.
   taskDialog.CommonButtons = TaskDialogCommonButtons.Close;
   taskDialog.DefaultButton = TaskDialogResult.Close;

   // Set footer text. Footer text is usually used to link to the help document.
   taskDialog.FooterText = “<a href=\”
http://bbs.revitapp.com\”>Click here for the Revit APP discussion group</a>”;

   TaskDialogResult tResult = taskDialog.Show();

Build the project and run Revit. You can see the new task dialog like this:

Powered by WordPress Web Design by SRS Solutions © 2012 Revit APP Blog Design by SRS Solutions