十一、元素的创建

十一、元素的创建

  • 元素创建的四种方法

    类名(className)

    元素创建工厂类(ItemFactory)

    复制Depulicate

    操作工具类Utilities

  • 在实践的过程中要创建一个元素,到底用哪一种方法呢?实际上最简单的思路就是到REVITAPI中从第一种方法开始找起,看看有无可用的方法,没有就依次往下去找其他的方法,直到实现你的目标。

using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ElementCUD
{
    /// <summary>
    /// 创建一面墙并且在墙的中部创建一个门
    /// </summary>
    [Transaction(TransactionMode.Manual)]
    public class ElementCreation : IExternalCommand
    {
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            //获取当前文档
            var doc = commandData.Application.ActiveUIDocument.Document;
            
            //要创建一面墙,需要必备几个条件:一条线段、一个标高
            
            //通过一种元素创建方法(类名Line创建),来创建一条直线
            var line = Line.CreateBound(new XYZ(0, 0, 0),new XYZ(10, 0, 0));
            //创建一个过滤器,过滤并获取出名字为标高1的元素(这里采用linq写法)
            var levellist = from element in new FilteredElementCollector(doc).OfClass(typeof(Level)) where element.Name == "标高 1" select element;
            //获得结果对象(对找到的集合,取第一个元素,转换成我们需要的Level)
            var level = levellist.FirstOrDefault() as Level;

            //要创建一个门,其实就是创建一个FamilyInstance,这个的创建方法可以查阅API文档。Document-Create-查阅menbers
            //找到public FamilyInstance NewFamilyInstance(XYZ location,FamilySymbol symbol,Element host,StructuralType structuralType)
            //即使用位置、类型/符号和主体元素将族的新实例插入到文档中。



            //创建好在墙中待放置的门的位置坐标(用线的line.Evaluat()方法,设置中点)
            var doorLocation = line.Evaluate(0.5, true);
            //找到门的族模型FamilySymbol(假设找到的是ID为94654这个门,在实际项目中一定要用过滤的方法获取)
            var doorId = new ElementId(94654);
            //获取它的族模型
            var doorSymbol = doc.GetElement(doorId) as FamilySymbol;


            try
            {
                //创建一个事务
                var transaction = new Transaction(doc,"创建墙体");
                //启动事务
                transaction.Start();
                //创建墙(在revitlookup中查找Wall的Create方法,选择其中的Create Method (Document, Curve, ElementId, Boolean)方法)
                //使用默认墙样式在项目内创建新的矩形轮廓墙
                var wall = Wall.Create(doc, line, level.Id, false);
                //在这面墙的中心创建一个门
                doc.Create.NewFamilyInstance(doorLocation, doorSymbol, wall,Autodesk.Revit.DB.Structure.StructuralType.NonStructural);

                //提交事务
                transaction.Commit();
            }
            catch(Exception e)  //异常处理
            {
                TaskDialog.Show("zzw", e.Message);  //弹出一个对话框,显示报错信息
                return Result.Failed;
            }

            return Result.Succeeded;
        }
    }
}
  • 按照上述代码在revit中去执行,会报一个错误:FamilySymbol is not active(族模型未激活),在revit中点击了门-这个门模型后,再重新载入外部工具,这时候就会正常创建了。可以采用以下办法解决这个问题,加一个if判断(如果族模型未激活,激活它)。

    using Autodesk.Revit.Attributes;
    using Autodesk.Revit.DB;
    using Autodesk.Revit.UI;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace ElementCUD
    {
        /// <summary>
        /// 创建一面墙并且在墙的中部创建一个门
        /// </summary>
        [Transaction(TransactionMode.Manual)]
        public class ElementCreation : IExternalCommand
        {
            public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
            {
                //获取当前文档
                var doc = commandData.Application.ActiveUIDocument.Document;
                
                //要创建一面墙,需要必备几个条件:一条线段、一个标高
                
                //通过一种元素创建方法(类名Line创建),来创建一条直线
                var line = Line.CreateBound(new XYZ(0, 0, 0),new XYZ(10, 0, 0));
                //创建一个过滤器,过滤并获取出名字为标高1的元素(这里采用linq写法)
                var levellist = from element in new FilteredElementCollector(doc).OfClass(typeof(Level)) where element.Name == "标高 1" select element;
                //获得结果对象(对找到的集合,取第一个元素,转换成我们需要的Level)
                var level = levellist.FirstOrDefault() as Level;
    
                //要创建一个门,其实就是创建一个FamilyInstance,这个的创建方法可以查阅API文档。Document-Create-查阅menbers
                //找到public FamilyInstance NewFamilyInstance(XYZ location,FamilySymbol symbol,Element host,StructuralType structuralType)
                //即使用位置、类型/符号和主体元素将族的新实例插入到文档中。
    
    
    
                //创建好在墙中待放置的门的位置坐标(用线的line.Evaluat()方法,设置中点)
                var doorLocation = line.Evaluate(0.5, true);
                //找到门的族模型FamilySymbol(假设找到的是ID为94654这个门,在实际项目中一定要用过滤的方法获取)
                var doorId = new ElementId(94654);
                //获取它的族模型
                var doorSymbol = doc.GetElement(doorId) as FamilySymbol;
                //激活族模型(加一个判断,如果族模型未激活,激活它)
                if (!doorSymbol.IsActive) doorSymbol.Activate();
    
    
                try
                {
                    //创建一个事务
                    var transaction = new Transaction(doc,"创建墙体");
                    //启动事务
                    transaction.Start();
                    //创建墙(在revitlookup中查找Wall的Create方法,选择其中的Create Method (Document, Curve, ElementId, Boolean)方法)
                    //使用默认墙样式在项目内创建新的矩形轮廓墙
                    var wall = Wall.Create(doc, line, level.Id, false);
                    //在这面墙的中心创建一个门
                    doc.Create.NewFamilyInstance(doorLocation, doorSymbol, wall,Autodesk.Revit.DB.Structure.StructuralType.NonStructural);
    
                    //提交事务
                    transaction.Commit();
                }
                catch(Exception e)  //异常处理
                {
                    TaskDialog.Show("zzw", e.Message);  //弹出一个对话框,显示报错信息
                    return Result.Failed;
                }
    
                return Result.Succeeded;
            }
        }
    }
    
  • 案例创建多面相同的墙(墙中心创建一个门),围着一个点形成一个圆

    using Autodesk.Revit.Attributes;
    using Autodesk.Revit.DB;
    using Autodesk.Revit.UI;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace ElementCUD
    {
        /// <summary>
        /// 创建多面相同的墙(墙中心创建一个门),围着一个点形成一个圆
        /// </summary>
        [Transaction(TransactionMode.Manual)]
        public class ElementCreationWall : IExternalCommand
        {
            public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
            {
                //获取当前文档
                var doc = commandData.Application.ActiveUIDocument.Document;
                //创建这个围成一个圆形的墙,主要是要解决多面墙的不同位置的问题。本质上就是墙围绕一个圆心以固定角度不断复制的过程。
                //先解决标高问题。用过滤器,用linq语法
                var levellist = from element in new FilteredElementCollector(doc).OfClass(typeof(Level)) where element.Name == "标高 1" select element;
                var level = levellist.FirstOrDefault() as Level;
                //创建一个门,本质上就是创建一个族实例,而且应用的方法是在一个墙上创建门的族实例,查询API文档可以采用这个方法
                //public FamilyInstance NewFamilyInstance(XYZ location,FamilySymbol symbol,Element host,StructuralType structuralType)            
                //获取门的族模型
                var doorId = new ElementId(94654);
                var doorSymbol = doc.GetElement(doorId) as FamilySymbol;
                //加一个判断族模型是否激活,未激活则激活它
                if (!doorSymbol.IsActive) doorSymbol.Activate();
    
                try
                {
                    //创建事务
                    var transaction = new Transaction(doc,"创建多面墙并围成一个圆");
                    //启动事务
                    transaction.Start();
                    //定义墙的数量
                    var count = 30;
                    //定义一个半径r1
                    var r1 = 10;
                    //定义一个半径r2
                    var r2 = 25;
                    //定义一个角度(用弧度制表示)
                    var alpha = 2 * Math.PI / count;
                    //用循环来绘制所有的墙
                    for (int i = 0; i < count; i++)
                    {
                        //定义墙的线
                        var line = Line.CreateBound(new XYZ(r1 * Math.Cos(alpha * i), r1 * Math.Sin(alpha * i), 0),
                            new XYZ(r2 * Math.Cos(alpha * i), r2 * Math.Sin(alpha * i), 0));
                        //获取到门的位置信息(用Line里面的.Evaluate方法,求中点)
                        var doorLocation = line.Evaluate(0.5, true);
    
                        //绘制墙
                        var wall = Wall.Create(doc, line, level.Id, false);
                                           
                        //绘制门
                        doc.Create.NewFamilyInstance(doorLocation, doorSymbol, wall, 
                            Autodesk.Revit.DB.Structure.StructuralType.NonStructural);
    
                    }
    
                    //提交事务
                    transaction.Commit();
                 
                }
                catch(Exception e)
                {
                    TaskDialog.Show("zzw", e.Message);
                    return Result.Failed;
                }
                return Result.Succeeded;
            }
        }
    }
    
  • 创建一根梁,让其位置坐标稍稍变化,产生一条警告信息,然后处理失败的警告

using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ElementCUD
{
    /// <summary>
    /// 创建一根梁,让其弹出警告信息(不精确警告),然后消除这个警告
    /// </summary>
    [Transaction(TransactionMode.Manual)]
    public class ElementCreationBeamCaveat : IExternalCommand
    {
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            //获取当前文档
            var doc = commandData.Application.ActiveUIDocument.Document;
            //创建一根梁就相当于创建一个族实例,查阅API文档选用这个方法实现
            //public FamilyInstance NewFamilyInstance(Curve curve,FamilySymbol symbol,Level level,StructuralType structuralType)
            //使用曲线、类型 / 符号和标高将族的新实例插入到文档中。


            //获取梁的位置
            var location = Line.CreateBound(new XYZ(0, 0, 0), new XYZ(10, 0, 0.02));
            //获取梁的标高枚举值(用过滤器+linq语句实现)
            var levellist = from element in new FilteredElementCollector(doc).OfClass(typeof(Level)) where element.Name == "标高 1" select element;
            //获取梁的标高
            var level = levellist.FirstOrDefault() as Level;
            //获取梁的族实例
            var beamSymbol = doc.GetElement(new ElementId(265299)) as FamilySymbol;
            //激活族实例
            if (!beamSymbol.IsActive) beamSymbol.Activate();
            
            try
            {
                //创建事务
                var transaction = new Transaction(doc,"创建一根梁");
                //消除警告
                var options = transaction.GetFailureHandlingOptions();
                var processor = new InaccurateFailureProcessor();
                options.SetFailuresPreprocessor(processor);
                transaction.SetFailureHandlingOptions(options);
                //启动事务
                transaction.Start();
                //绘制梁
                doc.Create.NewFamilyInstance(location, beamSymbol,level, Autodesk.Revit.DB.Structure.StructuralType.Beam);

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

            }
            catch(Exception e)
            {
                TaskDialog.Show("zzw", e.Message);
                return Result.Failed;
            }
            return Result.Succeeded;
        }
    }
    public class InaccurateFailureProcessor : IFailuresPreprocessor
    {
        public FailureProcessingResult PreprocessFailures(FailuresAccessor failuresAccessor)
        {
            //找到所有失败的消息
            var failurelist = failuresAccessor.GetFailureMessages();
            //遍历failurelist
            foreach (var item in failurelist)
            {
                //获取每一个failureId
                var failureId = item.GetFailureDefinitionId();
                //判断,如果failureId等于revit自定义的梁或者支撑的不精确警告
                if (failureId == BuiltInFailures.InaccurateFailures.InaccurateBeamOrBrace)
                    failuresAccessor.DeleteWarning(item);

            }
            return FailureProcessingResult.Continue;
        }
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值