Revit创建楼层面板

1.设计思路

创建楼板面层.png

其中,在运行前设置的时候需要创建ui界面,其他处理包含将楼板标记信息同步为楼板所在房间编号和将楼板面层信息同步为楼板面层名称。

2.后台处理

通过过滤器获得所有的房间

public List<Element> getRoomList(Document doc)        //获取所有房间
        {
            FilteredElementCollector RoomCollector = new FilteredElementCollector(doc);
            RoomCollector.OfCategory(BuiltInCategory.OST_Rooms).OfClass(typeof(SpatialElement));//SpatialElement空间元素
            List<Element> RoomList = RoomCollector.ToList();
            return RoomList;
        }

通过过滤器获得所有楼板的集合

 private List<Element> getFloorList(Document doc)    //获取楼板集合
        {
            FilteredElementCollector FloorCollector = new FilteredElementCollector(doc);
            FloorCollector.OfCategory(BuiltInCategory.OST_Floors).OfClass(typeof(FloorType));//SpatialElement空间元素
            List<Element> FloorList = FloorCollector.ToList();
            return FloorList;
        }

通过比较房间中所有轮廓的拉伸体的体积,获取房间的最大轮廓

private List<CurveArray> RoomBoundaryList(List<Element> roomList)   //获取房间轮廓
        {
            List<CurveArray> CurveArrayList = new List<CurveArray>();
            foreach(Element element in roomList)
            {
                Room room = element as Room;
                SpatialElementBoundaryOptions seBoundaryOption = new SpatialElementBoundaryOptions();
                CurveArray ca = new CurveArray();
                IList<IList<BoundarySegment>> roomBoundaryListList = room.GetBoundarySegments(seBoundaryOption);
                List<CurveLoop> curveLoopList = new List<CurveLoop>();
                //获取房间的所有边界
                if(roomBoundaryListList!=null)
                {
                    foreach(IList<BoundarySegment> roomBoundaryList in roomBoundaryListList)
                    {
                        CurveLoop curveLoop = new CurveLoop();
                        foreach(BoundarySegment roomBoundary in roomBoundaryList)
                        {
                            curveLoop.Append(roomBoundary.GetCurve());
                        }
                        curveLoopList.Add(curveLoop);
                    }
                }

                //获取房间边界拉伸体的体积
                List<double> volumn = new List<double>();
                try
                {
                    foreach(CurveLoop curveLoop in curveLoopList)
                    {
                        IList<CurveLoop> cList = new List<CurveLoop>();
                        cList.Add(curveLoop);
                        Solid solid = GeometryCreationUtilities.CreateExtrusionGeometry(cList, XYZ.BasisZ, 1);
                        volumn.Add(solid.Volume);
                    }
                }
                catch
                {
                    continue;
                }

                //通过房间边界拉伸体的体积找出最大轮廓
                CurveLoop LargeLoop = curveLoopList.ElementAt(volumn.IndexOf(volumn.Max()));
                foreach(Curve curve in LargeLoop)
                {
                    ca.Append(curve);
                }
                CurveArrayList.Add(ca);
            }
            return CurveArrayList;
        }

绘制楼层面板

private bool CreateSurface(Document doc,FloorType floorType,List<CurveArray> roomBoundaryList)
        {
            using (Transaction Trans = new Transaction(doc, "生成楼层面板"))
            {
                Trans.Start();
                foreach(CurveArray ca in roomBoundaryList)
                {
                    Floor floor = doc.Create.NewFloor(ca, false);
                }
                Trans.Commit();
            }
            return true;
        }

其中,过滤房间和过滤楼板的函数可以合并为一个,根据传入函数的不同来过滤。

3.界面设计

ui

采用winform设计,工具箱直接拖控件,很神奇的是在vs里面看不到标题,于是手动在代码里面添加了this.Text = "创建楼板面层",然后发现vs还是看不到,但是revit里面却显示有,而且生平第一次用中文来当变量名,震惊了。

界面代码:
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using Autodesk.Revit.DB;

namespace 创建楼板面层
{
    public partial class setUi : System.Windows.Forms.Form
    {
        //声明一个List对象rooms,通过rooms来找出属性值
        List<Element> rooms = null;

        //构造函数,传入房间集合,房间集合拥有的所有属性名称以及楼板类型
        public setUi(List<Element> room, List<string> roomParametersNames, List<string> floorTypeNames)
        {
            InitializeComponent();
            roomParametersNames.Add("无");
            属性名称.DataSource = roomParametersNames;
            类型名称.DataSource = floorTypeNames;
            rooms = room;
        }

        private void setUi_Load(object sender, EventArgs e)
        {
            this.Text = "创建楼板面层";   //设置窗口标题
            //禁用放大和缩小按钮
            this.MaximizeBox = false;
            this.MinimizeBox = false;   
            //设置combox的默认值
            属性名称.SelectedIndex = 1;
            属性值.SelectedIndex = 0;
            类型名称.SelectedIndex = 0;
        }

        //找出属性值的集合,传入combox
        private void 属性名称_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (属性名称.SelectedItem != null)
            {
                string parameterName = 属性名称.SelectedItem.ToString();
                List<string> parameterValuelist = new List<string>();
                parameterValuelist.Add("无");
                foreach (Element el in rooms)
                {
                    属性值.DataSource = null;
                    IList<Parameter> roomsPa = el.GetParameters(parameterName);
                    foreach (Parameter pa in roomsPa)
                    {
                        if (pa.HasValue)
                        {
                            if (pa.StorageType != StorageType.String)
                            {
                                if (!parameterValuelist.Contains(pa.AsValueString()))
                                {
                                    parameterValuelist.Add(pa.AsValueString());
                                }
                            }
                            else
                            {
                                if (!parameterValuelist.Contains(pa.AsString()))
                                {
                                    parameterValuelist.Add(pa.AsString());
                                }
                            }
                        }
                    }
                }
                属性值.DataSource = parameterValuelist;
            }
        }

        private void commitButton_Click(object sender, EventArgs e)
        {
            if (属性名称.SelectedItem != null &&属性值.SelectedItem != null && 类型名称.SelectedItem != null)
            {
                this.DialogResult = DialogResult.OK;
                this.Close();
            }
        }
    }
}
;

4.后台代码的再处理

对后台代码再处理,将ui返回的值传到后台,并根据条件创建楼板。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB.Architecture;
using System.Windows.Forms;

namespace 创建楼板面层
{
    [Transaction(TransactionMode.Manual)]
    public class CreateFloorSurface : IExternalCommand
    {
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            UIDocument uidoc = commandData.Application.ActiveUIDocument;
            Document doc = uidoc.Document;

            //过滤房间
            List<Element> roomList = getRoomList(doc); 
            if(!(roomList.Count>0))
            {
                message = "模型中没有绘制房间!";
                return Result.Failed;
            }

            //过滤所有楼板
            List<Element> floorList = getFloorList(doc);
            if (!(floorList.Count > 0))
            {
                message = "模型中没有绘制楼板!";
                return Result.Failed;
            }

            //弹出对话框,选择过滤条件和楼板类型
            List<string> createSetting = ShowDialog(roomList, floorList);
            if(!(createSetting.Count>0))
            {
                return Result.Cancelled;
            }

            //获取房间轮廓
            List<Element> roomsList = new List<Element>();
            List<CurveArray> CuveArrayList = RoomBoundaryList(roomList,createSetting,out roomsList);
            if (!(CuveArrayList.Count > 0))
            {
                message = "模型中的房间没有轮廓!";
                return Result.Failed;
            }

            //绘制楼层面板
            FloorType ft = floorList.Where(x => x.Name == createSetting[2]).First() as FloorType;
            bool result = CreateSurface(doc, ft, CuveArrayList,roomsList);
            if (!result)
            {
                message = "楼层绘制失败!";
                return Result.Failed;
            }

            return Result.Succeeded;
        }

        public List<Element> getRoomList(Document doc)        //获取所有房间
        {
            FilteredElementCollector RoomCollector = new FilteredElementCollector(doc);
            RoomCollector.OfCategory(BuiltInCategory.OST_Rooms).OfClass(typeof(SpatialElement));//SpatialElement空间元素
            List<Element> RoomList = RoomCollector.ToList();
            return RoomList;
        }

        private List<Element> getFloorList(Document doc)    //获取楼板集合
        {
            FilteredElementCollector FloorCollector = new FilteredElementCollector(doc);
            FloorCollector.OfCategory(BuiltInCategory.OST_Floors).OfClass(typeof(FloorType));
            List<Element> FloorList = FloorCollector.ToList();
            return FloorList;
        }

        private List<CurveArray> RoomBoundaryList(List<Element> roomList,List<string> createSetting,out List<Element> roomToCreate)   //获取房间轮廓
        {
            //通过传入的creatSetting获取指定房间
            List<Element> roomsList = new List<Element>();
            string paraName = createSetting[0];
            string paraValue = createSetting[1];
            foreach(Element ele in roomList)
            {
                ParameterMap paraMap = ele.ParametersMap;
                foreach(Parameter para in paraMap)
                {
                    if(para.Definition.Name==paraName)
                    {
                        if(para.HasValue)
                        {
                            string value;
                            if (para.StorageType == StorageType.String)
                                value = para.AsString();
                            else
                                value = para.AsString();
                            if (value == paraValue)
                                roomsList.Add(ele);
                        }
                    }
                }
            }
            List<CurveArray> CurveArrayList = new List<CurveArray>();
            roomToCreate = new List<Element>();
            foreach(Element element in roomsList)
            {
                Room room = element as Room;
                SpatialElementBoundaryOptions seBoundaryOption = new SpatialElementBoundaryOptions();
                CurveArray ca = new CurveArray();
                IList<IList<BoundarySegment>> roomBoundaryListList = room.GetBoundarySegments(seBoundaryOption);
                List<CurveLoop> curveLoopList = new List<CurveLoop>();
                //获取房间的所有边界
                if(roomBoundaryListList!=null)
                {
                    foreach(IList<BoundarySegment> roomBoundaryList in roomBoundaryListList)
                    {
                        CurveLoop curveLoop = new CurveLoop();
                        foreach(BoundarySegment roomBoundary in roomBoundaryList)
                        {
                            curveLoop.Append(roomBoundary.GetCurve());
                        }
                        curveLoopList.Add(curveLoop);
                    }
                }
                if (curveLoopList.Count == 0)
                    continue;

                //获取房间边界拉伸体的体积
                List<double> volumn = new List<double>();
                try
                {
                    foreach(CurveLoop curveLoop in curveLoopList)
                    {
                        IList<CurveLoop> cList = new List<CurveLoop>();
                        cList.Add(curveLoop);
                        Solid solid = GeometryCreationUtilities.CreateExtrusionGeometry(cList, XYZ.BasisZ, 1);
                        volumn.Add(solid.Volume);
                    }
                }
                catch
                {
                    continue;
                }

                //通过房间边界拉伸体的体积找出最大轮廓
                CurveLoop LargeLoop = curveLoopList.ElementAt(volumn.IndexOf(volumn.Max()));
                foreach(Curve curve in LargeLoop)
                {
                    ca.Append(curve);
                }
                CurveArrayList.Add(ca);
                roomToCreate.Add(element);
            }
            return CurveArrayList;
        }

        //创建楼板并同步房间和楼板类型
        private bool CreateSurface(Document doc,FloorType floorType,List<CurveArray> roomBoundaryList,List<Element> roomsList)
        {
            double thick = floorType.get_Parameter(BuiltInParameter.FLOOR_ATTR_DEFAULT_THICKNESS_PARAM).AsDouble();
            using (Transaction Trans = new Transaction(doc, "生成楼层面板"))
            {
                Trans.Start();
                for(int i=0;i<roomBoundaryList.Count;i++)
                {
                    Floor floor = doc.Create.NewFloor(roomBoundaryList[i],floorType,doc.GetElement(roomsList[i].LevelId)as Level , false);
                    floor.get_Parameter(BuiltInParameter.FLOOR_HEIGHTABOVELEVEL_PARAM).Set(thick);  //更改偏移量
                    floor.get_Parameter(BuiltInParameter.ALL_MODEL_MARK).Set(roomsList[i].get_Parameter(BuiltInParameter.ROOM_NUMBER).AsString());  //同步房间信息
                    roomsList[i].get_Parameter(BuiltInParameter.ROOM_FINISH_FLOOR).Set(floorType.Name);
                }
                Trans.Commit();
            }
            return true;
        }

        //创建界面对象,并返回value,其中value包含combox选中的三个值
        private List<string> ShowDialog(List<Element> roomList,List<Element> floorList)
        {
            //获取房间编号,房间属性名称以及楼板类型
            List<string> value = new List<string>();   //保存ui返还的值
            List<Element> room = new List<Element>();
            List<string> roomParametersNames = new List<string>();
            List<string> floorTypeNames = new List<string>();
            //找出属性名称,属性值,以及楼板类型,并传入给setUi的构造函数
            foreach (Element rm in roomList)
            {
                room.Add(rm);
            }
            ParameterMap pm = room[0].ParametersMap;
            foreach (Parameter pa in pm)
            {
                if (!roomParametersNames.Contains(pa.Definition.Name))
                {
                    roomParametersNames.Add(pa.Definition.Name);
                }
            }
            foreach (Element el in floorList)
            {
                floorTypeNames.Add(el.Name);
            }
            setUi ui = new setUi(room, roomParametersNames, floorTypeNames);
            if(ui.ShowDialog() == DialogResult.OK)
            {
                value.Add(ui.属性名称.SelectedItem.ToString());
                value.Add(ui.属性值.SelectedItem.ToString());
                value.Add(ui.类型名称.SelectedItem.ToString());
                return value;
            }
            return null;

        }
    }
}

5.前方高能

神奇的是,ui设计器会出问题???不是很懂问题出在哪里,但是点击“忽略并继续”后,可以成功生成,而且运行也没问题,哪位大佬路过看到了望告知。

这是高能
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,594评论 18 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,428评论 25 707
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,016评论 4 62
  • 文/松烟袅袅 近日逛b站无意中看了一个回忆童年系列视频,里面有《福星高照猪八戒》里牛魔王和铁扇公主的cut,然后就...
    松烟袅袅阅读 1,436评论 36 29
  • 在需要实现功能的地方绑定实现 onmouseover="ShowPrompt(this)" onmouseout=...
    f675b1a02698阅读 543评论 0 0