I just wanted to learn Revit API and create a simple wall using ExternalCommand. But I cannot figure it out... I think my problem is here:
var symbolId = document.GetDefaultFamilyTypeId(new ElementId(BuiltInCategory.OST_Walls));
When I debug it symbolId
always -1.
Can you help me what is wrong with this code snippet?
public Autodesk.Revit.UI.Result Execute(
Autodesk.Revit.UI.ExternalCommandData command_data,
ref string message,
Autodesk.Revit.DB.ElementSet elements)
{
var document = command_data.Application.ActiveUIDocument.Document;
var level_id = new ElementId(1526);
// create line
XYZ point_a = new XYZ(-10, 0, 0);
XYZ point_b = new XYZ(10, 10, 10);
Line line = Line.CreateBound(point_a, point_b);
using (var transaction = new Transaction(doc))
{
transaction.Start("create walls");
Wall wall = Wall.Create(doc, line, level_id, false);
var position = new XYZ(0, 0, 0);
var symbolId = document.GetDefaultFamilyTypeId(new ElementId(BuiltInCategory.OST_Walls));
if (symbolId == ElementId.InvalidElementId) {
transaction.RollBack();
return Result.Failed;
}
var symbol = document.GetElement(symbolId) as FamilySymbol;
var level = (Level)document.GetElement(wall.LevelId);
document.Create.NewFamilyInstance(position, symbol, wall, level, StructuralType.NonStructural);
transaction.Commit();
}
return Result.Succeeded;
}
Work through the Revit API getting started material and all will be explained. That will save you and others many further questions and answers.
To address this specific question anyway, GetDefaultFamilyTypeId
presumably does not do what you expect it to for wall elements. In the GetDefaultFamilyTypeId
method API documentation, it is used for structural columns, a standard loadable family hosted by individual RFA files. Walls are built-in system families and behave differently. Maybe GetDefaultFamilyTypeId
only works for non-system families.
To retrieve an arbitrary (not default) wall type, use a filtered element collector to retrieve all WallType
elements and pick the first one you find.
Here is a code snippet that picks the first one with a specific name, from The Building Coder discussion on Creating Face Wall and Mass Floor :
WallType wType = new FilteredElementCollector( doc )
.OfClass( typeof( WallType ) )
.Cast<WallType>().FirstOrDefault( q
=> q.Name == "Generic - 6\" Masonry" );