1.設(shè)計(jì)思路
創(chuàng)建樓板面層.png
其中顿乒,在運(yùn)行前設(shè)置的時(shí)候需要?jiǎng)?chuàng)建ui界面滥搭,其他處理包含將樓板標(biāo)記信息同步為樓板所在房間編號(hào)和將樓板面層信息同步為樓板面層名稱(chēng)何什。
2.后臺(tái)處理
通過(guò)過(guò)濾器獲得所有的房間
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;
}
通過(guò)過(guò)濾器獲得所有樓板的集合
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;
}
通過(guò)比較房間中所有輪廓的拉伸體的體積譬巫,獲取房間的最大輪廓
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;
}
//通過(guò)房間邊界拉伸體的體積找出最大輪廓
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;
}
其中咖楣,過(guò)濾房間和過(guò)濾樓板的函數(shù)可以合并為一個(gè),根據(jù)傳入函數(shù)的不同來(lái)過(guò)濾芦昔。
3.界面設(shè)計(jì)
ui
采用winform設(shè)計(jì)诱贿,工具箱直接拖控件,很神奇的是在vs里面看不到標(biāo)題咕缎,于是手動(dòng)在代碼里面添加了this.Text = "創(chuàng)建樓板面層"珠十,然后發(fā)現(xiàn)vs還是看不到,但是revit里面卻顯示有凭豪,而且生平第一次用中文來(lái)當(dāng)變量名焙蹭,震驚了。
界面代碼:
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using Autodesk.Revit.DB;
namespace 創(chuàng)建樓板面層
{
public partial class setUi : System.Windows.Forms.Form
{
//聲明一個(gè)List對(duì)象rooms墅诡,通過(guò)rooms來(lái)找出屬性值
List<Element> rooms = null;
//構(gòu)造函數(shù)壳嚎,傳入房間集合桐智,房間集合擁有的所有屬性名稱(chēng)以及樓板類(lèi)型
public setUi(List<Element> room, List<string> roomParametersNames, List<string> floorTypeNames)
{
InitializeComponent();
roomParametersNames.Add("無(wú)");
屬性名稱(chēng).DataSource = roomParametersNames;
類(lèi)型名稱(chēng).DataSource = floorTypeNames;
rooms = room;
}
private void setUi_Load(object sender, EventArgs e)
{
this.Text = "創(chuàng)建樓板面層"; //設(shè)置窗口標(biāo)題
//禁用放大和縮小按鈕
this.MaximizeBox = false;
this.MinimizeBox = false;
//設(shè)置combox的默認(rèn)值
屬性名稱(chēng).SelectedIndex = 1;
屬性值.SelectedIndex = 0;
類(lèi)型名稱(chēng).SelectedIndex = 0;
}
//找出屬性值的集合末早,傳入combox
private void 屬性名稱(chēng)_SelectedIndexChanged(object sender, EventArgs e)
{
if (屬性名稱(chēng).SelectedItem != null)
{
string parameterName = 屬性名稱(chēng).SelectedItem.ToString();
List<string> parameterValuelist = new List<string>();
parameterValuelist.Add("無(wú)");
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 (屬性名稱(chēng).SelectedItem != null &&屬性值.SelectedItem != null && 類(lèi)型名稱(chēng).SelectedItem != null)
{
this.DialogResult = DialogResult.OK;
this.Close();
}
}
}
}
;
4.后臺(tái)代碼的再處理
對(duì)后臺(tái)代碼再處理,將ui返回的值傳到后臺(tái)说庭,并根據(jù)條件創(chuàng)建樓板然磷。
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 創(chuàng)建樓板面層
{
[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;
//過(guò)濾房間
List<Element> roomList = getRoomList(doc);
if(!(roomList.Count>0))
{
message = "模型中沒(méi)有繪制房間!";
return Result.Failed;
}
//過(guò)濾所有樓板
List<Element> floorList = getFloorList(doc);
if (!(floorList.Count > 0))
{
message = "模型中沒(méi)有繪制樓板刊驴!";
return Result.Failed;
}
//彈出對(duì)話(huà)框姿搜,選擇過(guò)濾條件和樓板類(lèi)型
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 = "模型中的房間沒(méi)有輪廓!";
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) //獲取房間輪廓
{
//通過(guò)傳入的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;
}
//通過(guò)房間邊界拉伸體的體積找出最大輪廓
CurveLoop LargeLoop = curveLoopList.ElementAt(volumn.IndexOf(volumn.Max()));
foreach(Curve curve in LargeLoop)
{
ca.Append(curve);
}
CurveArrayList.Add(ca);
roomToCreate.Add(element);
}
return CurveArrayList;
}
//創(chuàng)建樓板并同步房間和樓板類(lèi)型
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;
}
//創(chuàng)建界面對(duì)象,并返回value躲惰,其中value包含combox選中的三個(gè)值
private List<string> ShowDialog(List<Element> roomList,List<Element> floorList)
{
//獲取房間編號(hào)致份,房間屬性名稱(chēng)以及樓板類(lèi)型
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>();
//找出屬性名稱(chēng),屬性值础拨,以及樓板類(lèi)型氮块,并傳入給setUi的構(gòu)造函數(shù)
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.屬性名稱(chēng).SelectedItem.ToString());
value.Add(ui.屬性值.SelectedItem.ToString());
value.Add(ui.類(lèi)型名稱(chēng).SelectedItem.ToString());
return value;
}
return null;
}
}
}
5.前方高能
神奇的是,ui設(shè)計(jì)器會(huì)出問(wèn)題诡宗?滔蝉??不是很懂問(wèn)題出在哪里塔沃,但是點(diǎn)擊“忽略并繼續(xù)”后蝠引,可以成功生成,而且運(yùn)行也沒(méi)問(wèn)題,哪位大佬路過(guò)看到了望告知螃概。
這是高能