Revit APP Blog

Information on Revit APP.

Browsing Posts published in July, 2010

Following code shows how to create a dimension for a selected curve based element:

namespace myRevitApp
{
   [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
   [Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
   public class TestCommand : IExternalCommand
   {
      public Result Execute(ExternalCommandData commandData, ref string message, Autodesk.Revit.DB.ElementSet elements)
      {
         UIDocument uiDoc = commandData.Application.ActiveUIDocument;
         Application app = commandData.Application.Application;
         Document doc = uiDoc.Document;
         View view = doc.ActiveView;
         ViewType vt = view.ViewType;

         if (vt == ViewType.FloorPlan || vt == ViewType.Elevation)
         {
            Reference eRef = uiDoc.Selection.PickObject(ObjectType.Element, “Please pick a curve based element like wall.”);
            if (eRef != null && eRef.Element != null)
            {
               XYZ dirVec = new XYZ();
               XYZ viewNormal = view.ViewDirection;

               LocationCurve locCurve = eRef.Element.Location as LocationCurve;
               if (locCurve == null || locCurve.Curve == null)
               {
                  TaskDialog.Show(“Prompt”, “Selected element isn’t curve based!”);
                  return Result.Cancelled;
               }

               // location curve needs to be perpendicular to view normal
               XYZ dirCur = locCurve.Curve.get_EndPoint(0).Subtract(locCurve.Curve.get_EndPoint(1)).Normalize();
               double d = dirCur.DotProduct(viewNormal);
               if (d > -0.000000001 && d < 0.000000001)
               {
                  dirVec = dirCur.CrossProduct(viewNormal);
                  XYZ p1 = locCurve.Curve.get_EndPoint(0);
                  XYZ p2 = locCurve.Curve.get_EndPoint(1);
                  XYZ dirLine = XYZ.Zero.Add(p1);
                  XYZ newVec = XYZ.Zero.Add(dirVec);
                  newVec = newVec.Normalize().Multiply(3);
                  dirLine = dirLine.Subtract(p2);

                  p1 = p1.Add(newVec);
                  p2 = p2.Add(newVec);
                  // move the dimension line a little away the element’s curve
                  Line newLine = app.Create.NewLine(p1, p2, true);

                  ReferenceArray arrRefs = new ReferenceArray();
                  Options options = app.Create.NewGeometryOptions();
                  options.ComputeReferences = true;
                  options.DetailLevel = DetailLevels.Fine;
                  GeometryElement element = eRef.Element.get_Geometry(options);
                  GeometryObjectArray geoObjectArray = element.Objects;
                  //enum the geometry element
                  for (int j = 0; j < geoObjectArray.Size; j++)
                  {
                     GeometryObject geoObject = geoObjectArray.get_Item(j);
                     Solid solid = geoObject as Solid;
                     if (solid == null)
                        continue;

                     FaceArrayIterator fIt = solid.Faces.ForwardIterator();
                     while (fIt.MoveNext())
                     {
                        PlanarFace p = fIt.Current as PlanarFace;
                        if (p == null)
                           continue;

                        p2 = p.Normal.CrossProduct(dirLine);
                        if (p2.IsZeroLength())
                        {
                           arrRefs.Append(p.Reference);
                        }
                        if (2 == arrRefs.Size)
                        {
                           break;
                        }
                     }
                     if (2 == arrRefs.Size)
                     {
                        break;
                     }
                  }
                  if (arrRefs.Size != 2)
                  {
                     TaskDialog.Show(“Prompt”, “Couldn’t find enough reference for creating dimension”);
                     return Result.Cancelled;
                  }

                  Transaction trans = new Transaction(doc, “create dimension”);
                  trans.Start();
                  doc.Create.NewDimension(doc.ActiveView, newLine, arrRefs);
                  trans.Commit();
               }
               else
               {
                  TaskDialog.Show(“Prompt”, “Selected element isn’t curve based!”);
                  return Result.Cancelled;
               }
            }
         }
         else
         {
            TaskDialog.Show(“Prompt”, “Only support Plan View or Elevation View”);
         }

         return Result.Succeeded;
      }
   }
}

Revit 2011 API provides user methods to select objects or point.

You can get Selection object from  commandData.Application.ActiveUIDocument.Selection.

The Selection has following members to select:

  • PickElementsByRectangle: Prompts the user to select multiple elements by drawing a rectangle.
  • PickObject: Prompts the user to select one object.
  • PickObjects: Prompts the user to select multiple objects.
  • PickPoint: Prompts the user to pick a point on the active work plane.

You can use the return value for these functions to get the selection results. We already posted a doc (http://blog.revitapp.com/2010/06/the-new-way-to-select-elements/) for PickObject, others are similar to use.

There are many changes to the VSTA framework:

  1. Revit VSTA no longer depends on the proxy DLL. Macros are now written referencing RevitAPI.dll and RevitAPIUI.dll directly. This allows macros access to the full features of the Revit API, including generic methods, all events and other methods missing from the proxy previously.  Module templates have been updated accordingly, and the references will be added automatically when upgrading macros from previous releases.
  2. The entry point classes ThisApplication and ThisDocument have been adjusted to the direct reference of the API classes.  They also now represent UIApplication and UIDocument (instead of Application and Document).
  3. The Transaction and Regeneration attributes must be applied to the ThisApplication and ThisDocument class. Their meanings for VSTA are same as for external commands.  Module templates have been updated with default assignments, but upgraded modules must have these added manually.
  • A special AddInId attribute can be added to modules.  This allows VSTA macros to work with updaters.  When new modules are created this attributes is automatically generated with a random Guid.
  • The Module_Startup methods are now executed at the time when the module is first loaded (as the Revit application starts for Application-level macros, and as the document is loaded for document-level macros).

4. No transactions may be opended in the Module_Startup and Module_Shutdown methods.

New modules created in Revit 2011 should be “ready to code” – all framework changes have been incorporated into the templates.

Upgraded macros and modules will need to be adjusted to the framework changes mentioned above, as well as all of the API changes (namespace changes, modified APIs).

Revit doesn’t provide API to export/extract thumbnail from Revit files, especially Revit family files. However, there always is workaround in the world.

There is a very good article talking about this with detail, here is the link:

http://redbolts.com/blog/post/2008/12/01/Getting-your-Revit-thumbnails.aspx

If this isn’t work for you. There is another way: open the Revit file, export a bitmap then close it and use the bitmap according it. If anyone is interesting in this, I will write article later on this topic.

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.

All Revit API methods have been changed to throw subclasses of Autodesk.Revit.Exceptions.ApplicationException. Some Revit exceptions, such as

  • ArgumentException
  • InvalidOperationException
  • FileNotFoundException

closely mirror the corresponding .NET System exception types. However, some of them have subclasses which are unique to Revit, e.g.

  • AutoJoinFailedException
  • RegenerationFailedException
  • ModificationOutsideTransactionException

In addition, there is a special exception type called InternalException, which represents a failure path which was not anticipated. Exceptions of this type carry extra diagnostic information which can be passed back to Autodesk for diagnosis.

The class hierarchy for accessing the structural analytical model has been replaced. The new class hierarchy offers a more streamlined interface and more capabilities to read data and modify analytical model settings.

The following AnalyticalModel subclasses have been removed:

  • AnalyticalModel3D
  • AnalyticalModelFloor
  • AnalyticalModelFrame
  • AnalyticalModelLocation
  • AnalyticalModelWall

 

Access the data you used to find on those subclasses on the base AnalyticalModel class, as follows:

 Old property  Found on  New method  Notes
 .Curve  AnalyticalModelFrame  GetCurves()  If analytical model was approximated, .Curve would have previously returned non-approximated analytical model. Now GetCurves() will return approximated analytical model when analytical model is approximated. GetCurve() is a shortcut method returning the single curve.
 .Curves  AnalyticalModel3D, AnalyticalModelFloor, AnalyticalModelFrame, AnalyticalModelLocation, AnalyticalModelWall  GetCurves()  AnalyticalCurveType.ActiveCurves will return the analytical model displayed by Revit. Most of the time, this is what is desired.
 .Point  AnalyticalModelLocation  GetPoint()  GetCurves() can also be called, the return will be a single curve of almost 0-length containing the point.
 .Profile  AnalyticalModelFrame  GetSweptProfile()  
 .RigidLink  AnalyticalModelFrame  GetCurves(AnalyticalCurveType.RigidLinkHead) or GetCurves(AnalyticalCurveType.RigidLinkTail)  AnalyticalCurveType.RigidLinkHead retrieves the Rigid Link at the end, and AnalyticalCurveType.RigidLinkTail retrieves the Rigid Link at the start.
 .SupportData  AnalyticalModel3D, AnalyticalModelFloor, AnalyticalModelFrame, AnalyticalModelLocation, AnalyticalModelWall  GetAnalyticalModelSupports()  

Note that the curves returned from these new methods will not have their Reference properties set, and cannot be used for the properties like Curve.EndPointReference. Instead, you can obtain References to the curves and their endpoints through construction of an AnalyticalModelSelector object containing the necessary information.

The AnalyticalModel class offers new methods to access other Analytical Model properties, such as:

  • Adjustment information, both manual and automatic
  • Parameter information, including projection, hard points, approximation, and rigid links
  • Analytical offset

The AnalyticalModelProfile class has been replaced by the AnalyticalModelSweptProfile class, which offers similar contents to the original class.

The AnalyticalSupportData and AnalyticalSupportInfo classes have been replaced by collections of AnalyticalModelSupport objects. This new class offers the same information offered by AnalyticalSupportInfo, plus:

  • The support priority
  • The curve, point, and face providing support

The new AnalyticalSupportChecking interface offers the ability to run the check for unsupported structural elements. The new AnalyticalConsistencyChecking interface offers the ability to run a consistency check for the Analytical Model.

The results of both checks are added to the document as warnings.

Access the AnalyticalModel through the method GetAnalyticalModel() on Element. This replaces the AnalyticalModel property of Wall, Floor, ContFooting and FamilyInstance.

The integer values of the enumerated type AnalyticalSupportType have changed.  They no longer match the values returned for the built-in parameter BOUNDARY_CONDITIONS_TYPE, use the members of the enum BoundaryConditionsType instead.

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;
      }
   }
}

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