Revit二次开发之 族的创建

一、revit族按照约束条件可以分为:

1、位置约束:确定族放置的位置

2、线约束:必须基于一条线进行布置和生成

3、方向约束:族具有呈现方向,通过指定referenceDirection来确定族显示的方向

4、视图约束:这个族只能在二维视图上添加

5、面(面的引用)约束:当前族只能位于指定的面之上

6、宿主约束:当前族只能基于宿主存在,且宿主可能是确定的类型

7、结构类型约束:指定当前组件必须是确定的结构类型

二、函数说明

1、使用将族的新实例插入到现有图元的面上。

public FamilyInstance NewFamilyInstance( 
  Face face,          //一个图形的面。 
  Line position,     //面上定义符号放置位置的线。 
  FamilySymbol symbol //对应的族对象。 
)

使用此方法可以在另一个图元的面上插入一个族实例,使用面上的线定义新符号的位置和方向,

案例如下:创建一个墙体的结构加强件,这个加强件位于墙体表面,且以线线方式呈现。

public void PlaceStiffenerOnWallFace(Autodesk.Revit.DB.Document doc, Wall wall)
{
    // 结构加劲杆族类型与基于线的面放置兼容
    FilteredElementCollector fsCollector = new FilteredElementCollector(doc);
    fsCollector.OfClass(typeof(FamilySymbol)).OfCategory(BuiltInCategory.OST_StructuralStiffener);
    FamilySymbol stiffenerSymbol = fsCollector.FirstElement() as FamilySymbol;
    // 唯一能让脸与这个新的FamilyInstance重载一起使用的方法
    // 是来自元素。启用计算机参考的几何图形
    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;
        }
    }
    // 创建一个线的路径
    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);     
}

2、基于线创建族元素,当前创建必须在一个二维视图中

将基于线的详图族实例添加到Autodesk Revit文档中,使用应放置该实例的线和视图。

public FamilyInstance NewFamilyInstance(
    Line line,            //族的线线结构
    FamilySymbol symbol,   族类型
    View specView          对应的视图
)

此重载仅适用于基于二维族线的详图符号。调用此方法之前,必须将使用的类型/符号加载到文档中。可以使用文档加载族及其符号。

案例如下:

void CreateDetailComponent(Autodesk.Revit.DB.Document document, View view)
{
    // 如果是详图视图或绘图视图,则在给定视图中创建详图构件
    if (view.ViewType == ViewType.Detail ||
        view.ViewType == ViewType.DraftingView)
    {
        FamilySymbol symbol = null;
        FilteredElementCollector fsCollector = new FilteredElementCollector(document);
        fsCollector.OfClass(typeof(FamilySymbol)).OfCategory(BuiltInCategory.OST_DetailComponents);
        ICollection<Element> collection = fsCollector.ToElements();
        foreach (Element element in collection)
        {
            FamilySymbol current = element as FamilySymbol;
            // 此NewFamilyInstance重载需要基于曲线的族
            if (current.Family.FamilyPlacementType == FamilyPlacementType.CurveBasedDetail)
            {
                symbol = current;
                break;
            }
        }
        if (symbol != null)
        {
            // 在视图原点创建2'详图构件
            XYZ start = view.Origin;
            XYZ end = start + new XYZ(2, 0, 0);
            Line line = Line.CreateBound(start, end);
            FamilyInstance instance = document.Create.NewFamilyInstance(line, symbol, view);
        }
    }
}

3、通过一个参考平面和线线创建一个族

将族的新实例插入到输入参照实例所参照的面上,使用该面上的线作为其位置,并使用类型/符号。其和1的功能基本一样,只是一个基于面,一个基于面的参照

public FamilyInstance NewFamilyInstance(
    Reference reference,
    Line position,
    FamilySymbol symbol
)

4、使用位置和类型/符号将族的新实例插入到文档中。

使用此方法可以插入不需要主体图元或标高的族实例。要创建基于标高的族的实例,调用此方法之前,必须将使用的类型/符号加载到文档中。可以使用文档加载族及其符号。某些族(如梁)具有多个端点,并以与单点实例相同的方式插入。插入后,这些线性族实例可以使用实例的图元更改其端点。属性的位置。

public FamilyInstance NewFamilyInstance(
    XYZ location,
    FamilySymbol symbol,
    StructuralType structuralType
)

这个函数适合那种自由且可以任意插入到文档中的族元素

5、在指定的视图和位置插入族

此重载仅适用于二维族符号(详图构件、注释符号、标题栏等)

public FamilyInstance NewFamilyInstance(
    XYZ origin,
    FamilySymbol symbol,
    View specView
)

6、通过线线和标高创建族

该方法用于沿曲线的几何图形将一个族实例插入另一个图元中。如果未能创建实例,则可能会引发异常。宿主对象必须支持实例插入,否则此方法将失败。通过遍历整个文档并搜索Autodesk.Revit.Elements.Level类型的对象,可以找到文档中的所有级别。

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

案例如下:比如创建一个桁架结构、梁等元素

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

7、在一个面上创建一个族,并且指定族的位置和方向

使用此方法可以在另一个图元的面上插入一个族实例,使用面上的点和矢量定义新符号的位置和方向。

public FamilyInstance NewFamilyInstance(
    Face face,
    XYZ location,
    XYZ referenceDirection,
    FamilySymbol symbol
)

案例如下,通过指定位置和方向创建一个照明设备

void CreateLightFixtureOnWall(Autodesk.Revit.DB.Document document, Wall wall)
{
    FilteredElementCollector collector = new FilteredElementCollector(document);
    collector.OfClass(typeof(FamilySymbol)).OfCategory(BuiltInCategory.OST_LightingFixtures);
    FamilySymbol symbol = collector.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;
        }
    }

    // Get the center of the wall 
    BoundingBoxUV bboxUV = face.GetBoundingBox();
    UV center = (bboxUV.Max + bboxUV.Min) / 2.0;
    XYZ location = face.Evaluate(center);
    XYZ normal = face.ComputeNormal(center);
    XYZ refDir = normal.CrossProduct(XYZ.BasisZ);

    FamilyInstance instance = document.Create.NewFamilyInstance(face, location, refDir, symbol);         
}

8、通过一个面的引用,并指定族的位置和方向

使用此方法可以在另一个图元的面上插入一个族实例,使用面上的点和矢量定义新符号的位置和方向。

public FamilyInstance NewFamilyInstance(
    Reference reference,
    XYZ location,
    XYZ referenceDirection,
    FamilySymbol symbol
)

其功能和7相似。案例如下:

void CreateNurseCallDomeOnWall(Autodesk.Revit.DB.Document document, Wall wall)
{
    FilteredElementCollector collector = new FilteredElementCollector(document);
    collector.OfClass(typeof(FamilySymbol)).OfCategory(BuiltInCategory.OST_NurseCallDevices);

    FamilySymbol symbol = collector.FirstElement() as FamilySymbol;

    // Get interior face of wall
    IList<Reference> sideFaces = HostObjectUtils.GetSideFaces(wall, ShellLayerType.Interior);
    Reference interiorFaceRef = sideFaces[0];

    XYZ location = new XYZ(4, 2, 8);
    XYZ refDir = new XYZ(0, 0, 1);

    FamilyInstance instance = document.Create.NewFamilyInstance(interiorFaceRef, location, refDir, symbol);
}

9、通过位置和标高确定族的信息

此方法用于添加不需要主体图元但可以与标高关联的族实例。如果未能创建实例,则可能会引发异常。

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

案例如下:创建一个柱子

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

10、给宿主对象创建一个族对象,这个对象是一个结构类型

此方法用于将一个族实例插入另一个图元,例如将窗插入墙。如果未能创建实例,则可能会引发异常。宿主对象必须支持实例插入,否则此方法将失败。某些族(如梁)具有多个端点,并以与单点实例相同的方式插入。插入后,这些线性族实例可以使用实例的图元更改其端点。属性的位置。

public FamilyInstance NewFamilyInstance(
    XYZ location,
    FamilySymbol symbol,
    Element host,
    StructuralType structuralType
)

案例如下:给墙添加一个窗户

Wall CreateWallWithWindows(Autodesk.Revit.DB.Document document, Level level)
{
    // Create a new wall
    // Build a location line for the wall creation
    XYZ start = new XYZ(0, 0, 0);
    XYZ end = new XYZ(10, 10, 0);
    Line wallLine = Line.CreateBound(start, end);

    // Create a wall using the location line
    Wall newWall = Wall.Create(document, wallLine, level.Id, true);

    // Find a Window type for the new windows
    FilteredElementCollector winCollector = new FilteredElementCollector(document);
    IList<Element> windowTypes = winCollector.OfCategory(BuiltInCategory.OST_Windows).WhereElementIsElementType().ToElements();
    FamilySymbol winType = windowTypes.First() as FamilySymbol;
    // put 3 windows in the wall
    double x = 2, y = 2, z = 2;
    for (int i = 0; i < 3; i++)
    {
        XYZ location = new XYZ(x, y, z);
        FamilyInstance instance = document.Create.NewFamilyInstance(location, winType, newWall, StructuralType.NonStructural);
        x += 3;
        y += 3;
    }

    return newWall;
}

11、具有标高和宿主同时约束的族对象

使用位置、类型/符号、主体图元和基准标高将族的新实例插入到文档中。

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

案例说明,给指定的墙添加一个门

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

12、具有位置、宿主和方向的族对象

使用位置、类型/符号、主体图元和参照方向将族的新实例插入到文档中。

public FamilyInstance NewFamilyInstance(
    XYZ location,
    FamilySymbol symbol,
    XYZ referenceDirection,
    Element host,
    StructuralType structuralType
)

案例说明,添加族元素

FilteredElementCollector collector = new FilteredElementCollector(document);
 Floor floor = collector.OfClass(typeof(Floor)).FirstElement() as Floor;
 if (floor != null)
 {
     // Find a Bed-Box family
     Family family = null;
     FilteredElementCollector famCollector = new FilteredElementCollector(document);
     famCollector.OfClass(typeof(Family));
     ICollection<Element> collection = famCollector.ToElements();
     foreach (Element element in collection)
     {

         if (element.Name.CompareTo("Bed-Box") == 0)
         {
             family = element as Family;
             break;
         }
     }

     if (family != null)
     {
         // Enumerate the beds in the Bed-Box family
         FilteredElementCollector fsCollector = new FilteredElementCollector(document);
         ICollection<Element> fsCollection = fsCollector.WherePasses(new FamilySymbolFilter(family.Id)).ToElements();
         IEnumerator<Element> symbolItor = fsCollection.GetEnumerator();

         int x = 0, y = 0;
         int i = 0;
         while (symbolItor.MoveNext())
         {
             FamilySymbol symbol = symbolItor.Current as FamilySymbol;
             XYZ location = new XYZ(x, y, 0);
             XYZ direction = new XYZ();
             switch (i % 3)
             {
                 case 0:
                     direction = new XYZ(1, 1, 0);
                     break;
                 case 1:
                     direction = new XYZ(0, 1, 1);
                     break;
                 case 2:
                     direction = new XYZ(1, 0, 1);
                     break;
             }
             FamilyInstance instance = document.Create.NewFamilyInstance(location, symbol, direction, floor, StructuralType.NonStructural);
             x += 10;
             i++;
         }
     }
 }

 

posted @ 2022-09-06 10:54  Min.Xiaoshuang  阅读(823)  评论(1编辑  收藏  举报