Creating a new Family Symbol
Originally Published inThis post is due to Joe Ye in our Beijing office. Many thanks, Joe! While proof reading my handouts for the Revit API tips and tricks session at AU, DE205-3 Enhancing Your Revit Add-In ↗, Joe pointed out that creating a new type or family symbol is a hot topic often asked by developers. It is not obvious from the Revit API help documentation or samples how to achieve this. It is simple to solve, though: one can use the Duplicate() method to create a new type, and then modify the parameters or properties required.
Here is an example in VB duplicating a wall type by doubling the thickness of each layer in its compound layer structure:
Public Function Execute( _
ByVal commandData As ExternalCommandData, _
ByRef message As String, _
ByVal elements As ElementSet) _
As IExternalCommand.Result _
Implements IExternalCommand.Execute
Try
Dim app As Application = commandData.Application
Dim doc As Document = app.ActiveDocument
Dim els As ElementSet = doc.Selection.Elements
Dim e As Element
Dim newWallTypeName As String _
= "NewWallType_with_Width_doubled"
For Each e In els
If TypeOf e Is Wall Then
Dim wall As Wall = e
Dim wallType As WallType
wallType = wall.WallType
Dim newWallType As WallType
newWallType = wallType.Duplicate(newWallTypeName)
Dim layers As CompoundStructureLayerArray
layers = newWallType.CompoundStructure.Layers
Dim layer As CompoundStructureLayer
For Each layer In layers
layer.Thickness *= 2
Next
wall.WallType = newWallType
Exit For
End If
Next
Return IExternalCommand.Result.Succeeded
Catch ex As Exception
message = ex.ToString()
Return IExternalCommand.Result.Failed
End Try
End Function
This command iterates over the currently selected elements. If a wall has been selected, its wall type is retrieved and duplicated to create a new wall type. In its compound layer structure, the thickness of every layer is doubled, and the new wall type is assigned to the selected wall. The command terminates as soon as the first selected wall has been processed.
Here is a different example in C# duplicating a column type, setting a new fixed value for its radius:
public CmdResult Execute(
ExternalCommandData commandData,
ref string message,
ElementSet elements )
{
Application app = commandData.Application;
Document doc = app.ActiveDocument;
string familyName = "Concrete-Round-Column";
Filter f = app.Create.Filter.NewFamilyFilter(
familyName );
List<RvtElement> families = new List<RvtElement>();
doc.get_Elements( f, families );
if( 1 > families.Count )
{
message = "No suitable family found.";
return CmdResult.Failed;
}
Family fam = families[0] as Family;
FamilySymbol famSym = null;
foreach( FamilySymbol fs in fam.Symbols )
{
famSym = fs;
break;
}
// create a new family symbol using Duplicate:
string newFamilyName = "NewRoundColumn 3";
FamilySymbol newFamSym = famSym.Duplicate(
newFamilyName ) as FamilySymbol;
// set the radius to a new value:
Parameter par = newFamSym.get_Parameter( "b" );
par.Set( 3 );
return CmdResult.Succeeded;
}