Revit API: creating family instancesfamilyinstance

Preface

As a core of Revit, Family API provides good support. This article is my own understanding of the Family for my future inquiry and reference.

Create a family instance

The code is from the official Revit document.
If you find a way to create an element, it's mostly in Autodesk.Revit.Creation.Document.
The following are the interfaces related to creating family instances. Different parameters indicate that they are applicable to different family types. If you use the wrong interface, the family instance may be created successfully, but it may not behave properly. So make sure you understand the type of family you create.

namespace Autodesk.Revit.Creation
{
    public class Document : ItemFactoryBase
    {
        // Create family instance related interfaces
        public FamilyInstance NewFamilyInstance(DB.XYZ location, DB.FamilySymbol symbol, DB.Element host, Level level, StructuralType structuralType);
        public FamilyInstance NewFamilyInstance(DB.XYZ location, DB.FamilySymbol symbol, Level level, StructuralType structuralType);
        public FamilyInstance NewFamilyInstance(Curve curve, DB.FamilySymbol symbol, Level level, StructuralType structuralType);
    }
}

In ItemFactoryBase, there are nine other interfaces for creating family instances:

namespace Autodesk.Revit.Creation
{
    public class ItemFactoryBase : APIObject
    {
        // Create family instance related interfaces
        public FamilyInstance NewFamilyInstance(DB.XYZ location, DB.FamilySymbol symbol, DB.XYZ referenceDirection, DB.Element host, StructuralType structuralType);
        public FamilyInstance NewFamilyInstance(Face face, DB.XYZ location, DB.XYZ referenceDirection, DB.FamilySymbol symbol);
        public FamilyInstance NewFamilyInstance(Face face, Line position, DB.FamilySymbol symbol);
        public FamilyInstance NewFamilyInstance(DB.XYZ location, DB.FamilySymbol symbol, DB.Element host, StructuralType structuralType);
        public FamilyInstance NewFamilyInstance(Reference reference, Line position, DB.FamilySymbol symbol);
        public FamilyInstance NewFamilyInstance(DB.XYZ origin, DB.FamilySymbol symbol, View specView);
        public FamilyInstance NewFamilyInstance(Line line, DB.FamilySymbol symbol, View specView);
        public FamilyInstance NewFamilyInstance(Reference reference, DB.XYZ location, DB.XYZ referenceDirection, DB.FamilySymbol symbol);
        public FamilyInstance NewFamilyInstance(DB.XYZ location, DB.FamilySymbol symbol, StructuralType structuralType);
    }
}

Four examples

Here are four examples in the document, and other examples for you to browse:

  1. Host Based family - create a door on a wall
  2. Only one point is needed as a family of locations - create columns
  3. Families that require a location line - create beams
  4. Host Based family with location lines required - create reinforcement on Wall

Create a door on the wall

Use this interface with the host parameter:

public FamilyInstance NewFamilyInstance(DB.XYZ location, DB.FamilySymbol symbol, DB.Element host, Level level, StructuralType structuralType);

Steps:

  1. Find the FamilySymbol of all doors
  2. Create family instance FamilyInstance in different places on the wall
void CreateDoorsInWall(Autodesk.Revit.DB.Document document, Wall wall)
{
    // get wall's level for door creation
    Level level = document.GetElement(wall.LevelId) as Level;

    FilteredElementCollector collector = new FilteredElementCollector(document);
    ICollection<Element> collection = collector.OfClass(typeof(FamilySymbol))
                                               .OfCategory(BuiltInCategory.OST_Doors)
                                               .ToElements();
    IEnumerator<Element> symbolItor = collection.GetEnumerator();

    double x = 0, y = 0, z = 0;
    while (symbolItor.MoveNext())
    {
        FamilySymbol symbol = symbolItor.Current as FamilySymbol;
        XYZ location = new XYZ(x, y, z);
        FamilyInstance instance = document.Create.NewFamilyInstance(location, symbol, wall, level, StructuralType.NonStructural);
        x += 10;
        y += 10;
        z += 1.5;
    }
}

Create pillars

Only the location, type and floor of the column are required.

public FamilyInstance NewFamilyInstance(DB.XYZ location, DB.FamilySymbol symbol, Level level, StructuralType structuralType);

Steps:

  1. Find the FamilySymbol of the column
  2. Create a family instance FamilyInstance at the origin
FamilyInstance CreateColumn(Autodesk.Revit.DB.Document document, Level level)
{
    // Get a Column type from Revit
    FilteredElementCollector collector = new FilteredElementCollector(document);
    collector.OfClass(typeof(FamilySymbol)).OfCategory(BuiltInCategory.OST_StructuralColumns);
    FamilySymbol columnType = collector.FirstElement() as FamilySymbol;

    FamilyInstance instance = null;
    if (null != columnType)
    {
        // Create a column at the origin
        XYZ origin = new XYZ(0, 0, 0);

        instance = document.Create.NewFamilyInstance(origin, columnType, level, StructuralType.Column);
    }

    return instance;
}

Create beam

An interface with location line is required:

public FamilyInstance NewFamilyInstance(Curve curve, DB.FamilySymbol symbol, Level level, StructuralType structuralType);

Steps:

  1. Find the FamilySymbol of the beam
  2. Create family instance FamilyInstance for location line
FamilyInstance CreateBeam(Autodesk.Revit.DB.Document document, View view)
{

   // get the given view's level for beam creation
    Level level = document.GetElement(view.LevelId) as Level;

    // get a family symbol
    FilteredElementCollector collector = new FilteredElementCollector(document);
    collector.OfClass(typeof(FamilySymbol)).OfCategory(BuiltInCategory.OST_StructuralFraming);

    FamilySymbol gotSymbol = collector.FirstElement() as FamilySymbol;

    // create new beam 10' long starting at origin
    XYZ startPoint = new XYZ(0, 0, 0);
    XYZ endPoint = new Autodesk.Revit.DB.XYZ(10, 0, 0);

    Autodesk.Revit.DB.Curve beamLine = Line.CreateBound(startPoint, endPoint);

    // create a new beam
    FamilyInstance instance = document.Create.NewFamilyInstance(beamLine, gotSymbol,
                                                                level, StructuralType.Beam);

    return instance;
}

Create reinforcement on the wall

Place an interface for face based family instances:

public FamilyInstance NewFamilyInstance(Face face, Line position, DB.FamilySymbol symbol);

Steps:

  1. Find the FamilySymbol of the reinforcement
  2. Traverse the geometry of the wall to find a Face
  3. Use this Face and the Line created on it to create a family instance FamilyInstance
public void PlaceStiffenerOnWallFace(Autodesk.Revit.DB.Document doc, Wall wall)
{
    // The structural stiffeners family type is compatible with line-based face placement
    FilteredElementCollector fsCollector = new FilteredElementCollector(doc);
    fsCollector.OfClass(typeof(FamilySymbol)).OfCategory(BuiltInCategory.OST_StructuralStiffener);
    FamilySymbol stiffenerSymbol = fsCollector.FirstElement() as FamilySymbol;

    // The only way to get a Face to use with this NewFamilyInstance overload
    // is from Element.Geometry with ComputeReferences turned on
    Face face = null;
    Options geomOptions = new Options();
    geomOptions.ComputeReferences = true;
    GeometryElement wallGeom = wall.get_Geometry(geomOptions);
    foreach (GeometryObject geomObj in wallGeom)
    {
        Solid geomSolid = geomObj as Solid;
        if (null != geomSolid)
        {
            foreach (Face geomFace in geomSolid.Faces)
            {
                face = geomFace;
                break;
            }
            break;
        }
    }

    // Generate line for path
    BoundingBoxUV bbox = face.GetBoundingBox();
    UV lowerLeft = bbox.Min;
    UV upperRight = bbox.Max;
    double deltaU = upperRight.U - lowerLeft.U;
    double deltaV = upperRight.V - lowerLeft.V;
    double vOffset = deltaV * 0.80; // 80% up the wall face

    UV firstPoint = lowerLeft + new UV(deltaU * 0.30, vOffset);
    UV lastPoint = lowerLeft + new UV(deltaU * 0.70, vOffset);

    Line line = Line.CreateBound(face.Evaluate(firstPoint), face.Evaluate(lastPoint));

    doc.Create.NewFamilyInstance(face, line, stiffenerSymbol);     
}

Published 47 original articles, won praise 12, visited 10000+
Private letter follow

Posted on Wed, 04 Mar 2020 00:39:19 -0800 by peter_anderson