RevitAPI实现简易房间的创建

zhy

发布于 2020.02.12 22:52 阅读 2758 评论 0

     学习完Revit元素的筛选和修改后,接下来要学习元素的创建,以创建房间为例练习,这个demo应该如何实现呢?

 

    RevitAPI提供了 Autodesk.Revit.Creation.Document类提供了众多的 NewFamilyInstance方法来创建族实例,我们可以通过使用NewFamilyInstance方法来创建房间的组件,以此来达到目的。

 

  

  了解了API后,接下来我们就要使用API创建房间:

 

创建房间可分为以下步骤:

 

1. 创建墙面

2. 创建门

3. 创建屋顶

 

创建墙面步骤:

 

1. 获取当前文档

2. 获取CW 102-50-100p类型的墙

3. 获取标高

4. 创建线

4. 设置墙高

6. 创建并开始事务

7. 创建墙(使用的Wall.Create方法)

8. 提交事务

 

具体代码如下:

public void createDefaultWalls(Document document, XYZ start, XYZ end)
        {
            //获取当前文档
            FilteredElementCollector collector = new FilteredElementCollector(document);
            //获取CW 102-50-100p类型的墙
            Element element = collector.OfCategory(BuiltInCategory.OST_Walls).OfClass(typeof(WallType)).FirstOrDefault(x => x.Name == "CW 102-50-100p");
            WallType wallType = element as WallType;
            
            //获取标高
            Level level = new FilteredElementCollector(document).OfClass(typeof(Level)).FirstOrDefault(x => x.Name == "标高 1") as Level;

            //创建线
            Line geomLine = Line.CreateBound(start, end);

            //设置墙高
            double height = 5 / 0.3048;//转化为英尺
            double offset = 0;

            //创建事务
            Transaction transaction = new Transaction(document, "创建墙");
            transaction.Start();

            //创建墙
            Wall wall = Wall.Create(document, geomLine, wallType.Id, level.Id, height, offset, true, true);

            IList<Curve> profile = new List<Curve>();

            profile.Append(Line.CreateBound(new XYZ(), new XYZ()));

            Wall.Create(document,profile,false);
            transaction.Commit();

        }

 

创建门:

 

1. 获取当前文档

2. 在文档中找到“700 x 2100mm”的门类型

3.将找到的FamilySymbol赋值给doorType

4.找到线形的墙

5.获取墙的线

6.获取墙的中间位置

7.获取墙的标线

8.激活FamilySymbol

9.创建门:传入标高参数,作为门的默认标高(使用的NewFamilyInstance方法

 

具体代码如下:

 

public void createDefaultDoor(Document RevitDoc)
        {
            //获取当前文档
            FilteredElementCollector doorSymbols = new FilteredElementCollector(RevitDoc);

            //创建FamilySymbol
            FamilySymbol doorType = null;

            // 在文档中找到名字为"700 x 2100mm"的门类型
            String doorTypeName = "700 x 2100mm";

            ElementFilter doorCategoryFilter = new ElementCategoryFilter(BuiltInCategory.OST_Doors);

            ElementFilter familySymbolFilter = new ElementClassFilter(typeof(FamilySymbol));

            LogicalAndFilter andFilter = new LogicalAndFilter(doorCategoryFilter, familySymbolFilter);

            doorSymbols = doorSymbols.WherePasses(andFilter);
            //将找到的FamilySymbol赋值给doorType
            foreach (FamilySymbol element in doorSymbols)

            {

                if (element.Name == doorTypeName)
                {
                    doorType = element;
                    break;
                }

            }
            // 使用族类型创建门
            if (doorType != null)
            {
                // 首先找到线形的墙
                FilteredElementCollector filteredElements = new FilteredElementCollector(RevitDoc).OfClass(typeof(Wall));

                Wall wall = null;
                Line line = null;
                foreach (Wall element in filteredElements)
                {
                    LocationCurve locationCurve = element.Location as LocationCurve;

                    if (locationCurve != null)
                    {
                        //获取墙的线
                        line = locationCurve.Curve as Line;
                        if (line != null)
                        {
                            //墙的线不为空,将墙赋值给wall
                            wall = element;
                            break;
                        }
                    }
                }

                // 在墙的中心位置创建一个门
                if (wall != null)

                { 
                    //获取墙的中间位置
                    XYZ midPoint = (line.GetEndPoint(0) + line.GetEndPoint(1)) / 2;

                    //获取墙的标线
                    Level wallLevel = RevitDoc.GetElement(wall.LevelId) as Level;

                    //开始事务
                    Transaction transaction = new Transaction(RevitDoc, "创建门");
                    transaction.Start();

                    //激活doorType,必须在事务中激活
                    doorType.Activate();

                    //创建门:传入标高参数,作为门的默认标高
                    FamilyInstance door = RevitDoc.Create.NewFamilyInstance(midPoint, doorType, wall, wallLevel, StructuralType.NonStructural);

                    //提交事务
                    transaction.Commit();

                    Autodesk.Revit.UI.TaskDialog.Show("Succeed", door.Id.ToString());

                    Trace.WriteLine("Door created: " + door.Id.ToString());

                }
            }

        }

 

创建屋顶:

 

1.先创建参照平面的位置参数

2.创建参照平面

3.创建屋顶前准备参数

4.创建拉伸屋顶(使用的NewExtrusionRoof方法

 

具体代码如下:

 public void createDefaultRoof(Document RevitDoc)
        {
            Transaction transaction = new Transaction(RevitDoc);

            View view = RevitDoc.ActiveView;
            //先创建参照平面的位置
            XYZ bubbleEnd = new XYZ(0, 0, 0);
            XYZ freeEnd = new XYZ(0, 30, 0);
            XYZ thirdPnt = new XYZ(0, 0, 30);

            //开始事务
            transaction.Start("Create reference plane");

            //创建参照平面
            ReferencePlane plane = RevitDoc.Create.NewReferencePlane2(bubbleEnd, freeEnd, thirdPnt, view);
            //提交事务
            transaction.Commit();
            //创建屋顶前准备参数 
            Level level = RevitDoc.GetElement(new ElementId(311)) as Level;
            RoofType roofType = RevitDoc.GetElement(new ElementId(335)) as RoofType;
            CurveArray curveArray = new CurveArray();
            curveArray.Append(Line.CreateBound(new XYZ(0, 0, 5/0.3048), new XYZ(0, 30, 5/0.3048)));
            
            //创建屋顶
            transaction.Start("Create roof");
            RevitDoc.Create.NewExtrusionRoof(curveArray, plane, level, roofType, 0, 30);
            transaction.Commit();

        }

 

最终效果:

个人总结:

   1.族实例的创建都是以族类型为参数的,所以要先创建族类型,族类型可以从活动文档中筛选提取,也可以从利用 LoadFamilySymbol方法从外部载入。族类型在使用时必须要在事务中激活。

   2.在创建拉伸物体时,要以工作平面( SketchPlane ), 工作平面上的(闭合)二维轮廓( CurveArrArray ),拉伸实体或剪切体(True,False),以及拉伸长度作为参数。

   3.在创建拉伸屋顶时,工作平面上的二维轮廓是不能闭合的,否则会出现 Autodesk.Revit.Exceptions.InvalidOperationException 。