Sangsen recently submitted a couple of comments which made it clear that a short overview of the new features of the Revit Structure 2012 API is overdue (see below for the Q & A).
Here is a description written by Joe Ye for our Spring 2011 ADN AEC newsletter:
This article discusses changes made to the Revit Structure 2012 API. We will quickly go over the list of items which have been changed, and look at the changes around rebar API in more detail.
The following is the list of changes made to the Revit Structure 2012 API:
Below, we discuss rebar changes.
If you have a code that creates a rebar shape in Revit Structure 2011, you will need to migrate it to use it in Revit Structure 2012. Here are the main changes in the steps to create a rebar shape:
In 2011,
In 2012,
In addition, the following methods are replaced by new ones:
Now, let's take a look at how to apply these changes to the rebar shape code, using our RST training labs code as an example. Here is the code for 2011, omitting some parameter definitions for simplicity:
// RstLab 4.1 code in Revit Structure 2011 [Transaction(TransactionMode.Manual)] [Regeneration(RegenerationOption.Manual)] public class RstLab4_1_CreateSimpleRebarShape : IExternalCommand { public Result Execute( ExternalCommandData commandData, ref string messages, ElementSet elements) { UIApplication uiApp = commandData.Application; Application app = uiApp.Application; Document doc = uiApp.ActiveUIDocument.Document; Transaction trans = new Transaction( doc, "Lab4_2" ); trans.Start(); // Create a newrebarshape. RebarShape oRebarShape = doc.Create.NewRebarShape(); oRebarShape.Name = RstUtils.msRebarShapeName; RebarShapeDefinitionBySegments shapeDef = oRebarShape.NewDefinitionBySegments( 5 ); // Add parameters with default value. // GetOrCreateSharedParameter() is a helper function. ExternalDefinition def = GetOrCreateSharedParameter("A"); Parameter pA = shapeDef.AddParameter(def, 280); // . . . shapeDef.AddConstraintParallelToSegment( 0, pA, false, false ); oRebarShape.set_HookAngle(0, 180); // . . . shapeDef.Commit(); trans.Commit(); shapeDef.CheckDefaultParameterValues( 0, 0 ); return Result.Succeeded; }
Several lines above require changes in 2012.
First, remove the lines with Create.NewRebarShape(). We will add code of creating rebar shape later on via new method later:
RebarShape oRebarShape = doc.Create.NewRebarShape(); // Remove these lines oRebarShape.Name = RstUtils.msRebarShapeName;
Replace the code creating RebarShapeDefinitionBySegments instance to use the constructor:
RebarShapeDefinitionBySegments shapeDef = oRebarShape.NewDefinitionBySegments( 5 ); // 2011
with this:
RebarShapeDefinitionBySegments shapeDef = new RebarShapeDefinitionBySegments( doc, 5 ); // 2012
The steps to create each shape segment are unchanged. However, in 2012, methods used to define rebar segment only accept ElementId as an argument instead of External Definition in 2011. Methods in RebarShapeParameters class provide a utility method to retrieve an element id of an external definition. We need to get the corresponding element id, and replace the reference to the parameter value (e.g., 'pA') with its corresponding ElementId variable (e.g., 'idA') in AddParameter() method a shape definition. For instance, original code like this:
// Add parameters with default value in 2011. ExternalDefinition def = GetOrCreateSharedParameter( "A" ); Parameter pA = shapeDef.AddParameter( def, 280 );
Will be modified like this:
// Add parameters with default value in 2012. ExternalDefinition def = GetOrCreateSharedParameter( "A" ); ElementId idA = RebarShapeParameters .GetOrCreateElementIdForExternalDefinition( doc, def ); shapeDef.AddParameter( idA, 280 );
The RebarShape class provides a static method to create a RebarShape instance in 2012. This method accommodates parameters to define the rebar shape's hook and hook angle. The methods to set hook properties are removed. Put all the rebar shape properties in the call to the Create method. After you have defined the rebar segment, add the following line to create the rebar shape:
RebarShape oRebarShape = RebarShape.Create( doc, shapeDef, null, RebarStyle.Standard, StirrupTieAttachmentType.InteriorFace, 180, RebarHookOrientation.Left, 180, RebarHookOrientation.Left, 0 );
The RebarShapeDefinitionBySegments.Commit method is removed in Revit 2012. You can simply delete it:
shapeDef.Commit(); // take out this line
That's it! Here is the final code in 2012, again keeping only one parameter to emphasize the changes we made:
// RstLab 4.1 code in 2012 // [Transaction(TransactionMode.Manual)] public class RstLab4_1_CreateRebarShape : IExternalCommand { public Result Execute( ExternalCommandData commandData, ref string messages, ElementSet elements ) { UIApplication uiApp = commandData.Application; Application app = uiApp.Application; Document doc = uiApp.ActiveUIDocument.Document; Transaction trans = new Transaction(doc, "Lab4_1"); trans.Start(); RebarShapeDefinitionBySegments shapeDef = new RebarShapeDefinitionBySegments(doc, 5); // Add parameters with default value. // GetOrCreateSharedParameter() is a helper function. ExternalDefinition def = GetOrCreateSharedParameter("A"); ElementId idA = RebarShapeParameters .GetOrCreateElementIdForExternalDefinition( doc, def); shapeDef.AddParameter(idA, 280); // . . . // Add constraints shapeDef.AddConstraintParallelToSegment(0, idA, false, false); // . . . // Create a newrebarshape. RebarShape oRebarShape = RebarShape .Create( doc, shapeDef, null, RebarStyle.Standard, StirrupTieAttachmentType.InteriorFace, 180, RebarHookOrientation.Left, 180, RebarHookOrientation.Left, 0 ); trans.Commit(); shapeDef.CheckDefaultParameterValues(0, 0); return Result.Succeeded; } }
All the API changes are documented in the 'Revit Platform API Changes and Additions.docx' and the 'What's New' section of the Revit API help file RevitAPI.chm provided with the Revit 2012 SDK. Please refer to those for more information about the usage of individual classes and methods.
Many thanks to Joe for this overview!
Some of the Revit Structure API changes were also discussed in the Revit 2012 API webcast and the associated materials.
Last but not least, Joe also took the time to answer Sangsen's questions:
A: After getting the analytical model from the BoundaryConditions instance, you can call the AnalyticalModel.GetElementId method to retrieve the id of the Host element family instance.
A: The big change to the analytical model in RST 2012 is the split of analytical model and its host physical model. The latter are now standalone elements.
Accordingly, the change of analytical model in Revit 2012 is that the AnalyticalModel class is derived from the Element class instead of the IDisposable interface. This means in Revit 2012, each AnalyticalModel instance is persistent and database resident. Previously, AnalyticalModel instances lived in transient memory only.
This affects the way to get the analytical model object. Now we can retrieve them using the element filtering mechanism via FilteredElementCollecotr. Previously the analytical model could only be retrieved from the host element.
With regard to the functionality of the AnalyticalModel class, new methods about alignment operation were introduced: GetAlignmentMethod, HasAlighment and SetAlignmentMethod.
The alignment option should work for a 2011 model opened in RST 2012.
A: The host physical component of a given analytical model can be obtained by the AnalyticalModel.GetElementId method. It returns the element id of the physical component.
Thank you very much again, Joe!