Search code examples
revit-api

C# Revit API, how to create a simple wall using ExternalCommand?


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

Solution

  • 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" );