1.设计思路
和上章差不多,区别不大,很多函数略加修改就可以直接使用。
通过ui交互设置过滤房间的条件,提取房间标高和房间轮廓,生成墙体,连接墙体以及同步墙体和房间的信息。
2.界面设计
using Autodesk.Revit.DB;
using System;
using System.Collections.Generic;
using System.Windows.Forms;
namespace CreateWallSuface
{
public partial class SetUi : System.Windows.Forms.Form
{
List rooms = null;
public SetUi(List room, List roomParametersNames, List wallTypeNames)
{
InitializeComponent();
roomParametersNames.Add("无");
parametersName.DataSource = roomParametersNames;
wallTypeName.DataSource = wallTypeNames;
rooms = room;
}
//传入属性名称,在属性值的combox中显示对应的值
private void parametersName_SelectedIndexChanged(object sender, EventArgs e)
{
if (parametersName.SelectedItem != null)
{
string parameterName = parametersName.SelectedItem.ToString();
List parameterValuelist = new List();
parameterValuelist.Add("无");
foreach (Element el in rooms)
{
parametersValue.DataSource = null;
IList 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());
}
}
}
}
}
parametersValue.DataSource = parameterValuelist;
}
}
private void commitButton_Click(object sender, EventArgs e)
{
if (parametersName.SelectedItem != null
&& parametersValue.SelectedItem != null
&& wallTypeName.SelectedItem != null
&& double.Parse(wallHeight.Text) > 0)
{
this.DialogResult = DialogResult.OK;
this.Close();
}
}
private void SetUi_Load(object sender, EventArgs e)
{
//设置控件显示的默认值
parametersName.SelectedIndex = 1;
parametersValue.SelectedIndex = 0;
wallTypeName.SelectedIndex = 0;
wallHeight.Text = "3000";
}
//限制只能输入数组
private void wallHeight_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar != 8 && !Char.IsDigit(e.KeyChar))
{
e.Handled = true;
}
}
//限制只能输入数组
private void BottomOffset_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar != 8 && !Char.IsDigit(e.KeyChar))
{
e.Handled = true;
}
}
}
}
3后台处理
部分函数和上章不同,贴重点。
获取房间轮廓中,传入房间集合和在ui界面设置的条件,返回边界集合,过滤后的房间集合和墙的集合(相邻的墙连接)。
//获取房间轮廓
private List RoomBoundaryList(List roomList,List createSetting, out List roomToCreate, out List> wallToJoin)
{
//通过传入的creatSetting获取指定房间
List roomsList = new List();
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 CurveLoopList = new List();
roomToCreate = new List();
wallToJoin = new List>();
foreach (Element element in roomsList)
{
Room room = element as Room;
SpatialElementBoundaryOptions seBoundaryOption = new SpatialElementBoundaryOptions();
IList> roomBoundaryListList = room.GetBoundarySegments(seBoundaryOption);
//获取房间的所有边界
if (roomBoundaryListList != null)
{
CurveLoop ca = new CurveLoop();
foreach (IList roomBoundaryList in roomBoundaryListList)
{
ca = new CurveLoop();
List wall = new List();
foreach (BoundarySegment roomBoundary in roomBoundaryList)
{
ca.Append(roomBoundary.GetCurve());
wall.Add(roomBoundary.ElementId);
}
CurveLoopList.Add(ca);
roomToCreate.Add(element);
wallToJoin.Add(wall);
}
}
}
return CurveLoopList;
}
在创建墙体面层,需要注意连接相邻的墙。
//创建墙体面层
private bool CreateWallSuface(Document doc, List CurveLoopList, WallType walltype, List roomsList,List createSetting,List> wallToJoin)
{
double wallHeight=double.Parse(createSetting[3]) / 304.8;//1英尺=304.8mm
double bottomOffset = double.Parse(createSetting[4]) / 304.8;
bool structural = false;
int boundary = 0;
if (createSetting[5] == bool.TrueString) structural = true;
if (createSetting[6] == bool.TrueString) boundary = 1;
using (Transaction trans = new Transaction(doc, "生成墙体面层"))
{
trans.Start();
for (int i = 0; i < CurveLoopList.Count; i++)
{
//更改偏移量
CurveLoop cLoop = CurveLoop.CreateViaOffset(CurveLoopList[i], walltype.Width / 2, -XYZ.BasisZ);
for(int j=0;j 0)
{
Element secWall = doc.GetElement(wallToJoin[i][j]);
JoinGeometryUtils.JoinGeometry(doc,secWall, aWall);
}
}
}
trans.Commit();
}
return true;
}