Files
ShrlAlgoToolkit/ShrlAlgoToolkit.RevitAddins/RvIndependent/NetworkCreator/NetworkCreatorView.xaml.cs

488 lines
18 KiB
C#
Raw Normal View History

2024-09-22 11:05:41 +08:00
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Mechanical;
using Autodesk.Revit.DB.Plumbing;
using Microsoft.Win32;
using OfficeOpenXml;
2025-04-24 20:56:44 +08:00
namespace ShrlAlgoToolkit.RevitAddins.RvIndependent.NetworkCreator;
2024-09-22 11:05:41 +08:00
public partial class NetworkCreatorView
{
public NetworkCreatorView(Document doc)
{
InitializeComponent();
this.doc = doc;
}
private static readonly string AddinPath = typeof(NetworkCreatorView).Assembly.Location;
internal Document doc;
internal ExcelWorkbook workbook;
private ExcelWorksheet sheet;
/// <summary>
/// 获取族并载入,若已存在项目,则获取同名族
/// </summary>
/// <param name="familyname">文件完整路径</param>
/// <returns></returns>
private Family GetFamily(string familyname)
{
doc.LoadFamily(familyname, out var family);
family ??= new FilteredElementCollector(doc)
.OfClass(typeof(Family))
.Cast<Family>()
.FirstOrDefault(f => f.Name == Path.GetFileNameWithoutExtension(familyname));
return family;
}
private void BtnApply_Click(object sender, RoutedEventArgs e)
{
if (TbFamilyPath.Text == null || TbXlsxPath.Text == null || CbSheetName.SelectedItem == null)
{
return;
}
sheet = (ExcelWorksheet)CbSheetName.SelectedItem;
ExcelData excelData = new(sheet); //Excel表格
Family family = null;
var level = new FilteredElementCollector(doc)
.OfClass(typeof(Level))
.Cast<Level>()
.FirstOrDefault(l => l.Elevation == 0);
using TransactionGroup tg = new(doc, "创建管网");
tg.Start();
using (Transaction trans = new(doc, "载入族"))
{
trans.Start();
switch (sheet.Name)
{
case "J":
family = GetFamily(Path.GetDirectoryName(AddinPath) + "\\Families\\J-检查井.rfa");
break;
case "W":
family = GetFamily(Path.GetDirectoryName(AddinPath) + "\\Families\\W-污水检查井.rfa");
break;
case "Y":
family = GetFamily(Path.GetDirectoryName(AddinPath) + "\\Families\\Y-检查井.rfa");
break;
case "LD":
family = GetFamily(Path.GetDirectoryName(AddinPath) + "\\Families\\LD-电气检查井.rfa");
break;
case "L":
family = GetFamily(Path.GetDirectoryName(AddinPath) + "\\Families\\L-直通型电力井.rfa");
break;
case "R":
family = GetFamily(Path.GetDirectoryName(AddinPath) + "\\Families\\R-检修井.rfa");
break;
case "D":
family = GetFamily(Path.GetDirectoryName(AddinPath) + "\\Families\\D-弱电井.rfa");
break;
}
trans.Commit();
}
CreateMunicipalNetWork(excelData, family, level);
try
{
ConnectDucts();
ConnectPipes();
}
catch (Exception ex)
{
System.Windows.MessageBox.Show(ex.StackTrace);
}
tg.Assimilate();
//StringBuilder sb = new StringBuilder();
//var filen = System.IO.Directory.GetCurrentDirectory();//revit安装目录
//var filem = System.AppDomain.CurrentDomain.BaseDirectory;//revit安装目录
}
private void BtnExcelSelect_Click(object sender, RoutedEventArgs e)
{
//string filter = "导入文件(*.xlsx,*.xls)|*.xlsx;*.xls";
const string filter = "Excel表格(*.xlsx,)|*.xlsx;";
OpenFileDialog openDialog = new() { Filter = filter, Title = "选择表格文件" };
openDialog.ShowDialog();
var path = openDialog.FileName;
if (path?.Length == 0)
{
return;
}
FileInfo fi = new(path);
TbXlsxPath.Text = path;
List<ExcelWorksheet> sheetli = [];
ExcelPackage p = new(fi);
workbook = p.Workbook;
for (var i = 0; i < workbook.Worksheets.Count; i++)
{
sheetli.Add(workbook.Worksheets[i]);
}
CbSheetName.ItemsSource = sheetli;
}
private void CBSheetName_SelectionChanged(object sender, SelectionChangedEventArgs e) { }
private void ConnectDucts()
{
var ducts = new FilteredElementCollector(doc).OfClass(typeof(Duct)).Cast<Duct>().ToList();
var connectors = new List<Connector>();
using Transaction trans = new(doc, "连接风管");
trans.Start();
foreach (var duct in ducts)
{
var connilter = duct.ConnectorManager.Connectors.ForwardIterator();
while (connilter.MoveNext())
{
connectors.Add(connilter.Current as Connector);
}
}
foreach (var ele in connectors)
{
if (ele.Origin == null)
{
continue;
}
var conns =
from conn in connectors
where
conn.Origin.IsAlmostEqualTo(ele.Origin)
&& !conn.IsConnected
&& !ele.IsConnected
&& conn.Id != ele.Id
&& conn.Shape == ConnectorProfileType.Rectangular
select conn;
if (conns.Any())
{
try
{
var elbow = doc.Create.NewElbowFitting(ele, conns.FirstOrDefault());
}
catch (Autodesk.Revit.Exceptions.InvalidOperationException) { }
}
}
trans.Commit();
}
/// <summary>
/// 连接管线
/// </summary>
private void ConnectPipes()
{
var pipes = new FilteredElementCollector(doc).OfClass(typeof(Pipe)).Cast<Pipe>().ToList();
var connectors = new List<Connector>();
using Transaction trans = new(doc, "连接水管");
trans.Start();
foreach (var pi in pipes)
{
var connilter = pi.ConnectorManager.Connectors.ForwardIterator();
while (connilter.MoveNext())
{
connectors.Add(connilter.Current as Connector);
}
}
foreach (var ele in connectors)
{
var conns =
from conn in connectors
where
conn.Origin.IsAlmostEqualTo(ele.Origin)
&& !conn.IsConnected
&& !ele.IsConnected
&& conn.Id != ele.Id
select conn;
if (conns.Any())
{
try
{
var elbow = doc.Create.NewElbowFitting(ele, conns.FirstOrDefault());
}
catch (Autodesk.Revit.Exceptions.InvalidOperationException) { }
}
}
trans.Commit();
}
/// <summary>
/// 创建水管管网
/// </summary>
/// <param name="excelData"></param>
/// <param name="family"></param>
private void CreateMunicipalNetWork(ExcelData excelData, Family family, Level level)
{
var rows = excelData.DataRows; //行的集合
for (var i = 0; i < rows.Count; i++)
{
var current = rows[i];
PlaceManhole(current, level, family);
//向后查找终点节点
for (var j = i + 1; j < rows.Count; j++)
{
var next = rows[j];
if (next.StartId == current.EndId && current.StartId == next.EndId)
{
switch (current.SectionType)
{
case SectionType.Circle:
Pipe pipe;
using (Transaction trans = new(doc, "创建水管"))
{
trans.Start();
PipingSystemType currentPipeSystemType = null;
try
{
var pipeSystemtype = new FilteredElementCollector(doc)
.OfClass(typeof(PipingSystemType))
.Cast<PipingSystemType>()
.FirstOrDefault(x => x.Name is "Other" or "其他");
currentPipeSystemType =
pipeSystemtype.Duplicate(excelData.System) as PipingSystemType;
}
catch (Exception)
{
currentPipeSystemType = new FilteredElementCollector(doc)
.OfClass(typeof(PipingSystemType))
.Cast<PipingSystemType>()
.FirstOrDefault(p => p.Name == excelData.System);
}
PipeType currentPipeType = null;
try
{
var pipeType = new FilteredElementCollector(doc)
.OfClass(typeof(PipeType))
.Cast<PipeType>()
.FirstOrDefault();
currentPipeType = pipeType.Duplicate(current.Material) as PipeType;
}
catch (Exception)
{
currentPipeType = new FilteredElementCollector(doc)
.OfClass(typeof(PipeType))
.Cast<PipeType>()
.FirstOrDefault(p => p.Name == current.Material);
}
pipe = Pipe.Create(
doc,
currentPipeSystemType.Id,
currentPipeType.Id,
level.Id,
current.CenterPoint,
next.CenterPoint
);
trans.Commit();
}
using (Transaction trans = new(doc, "设置水管"))
{
trans.Start();
SetPipeParam(current, pipe);
trans.Commit();
}
break;
case SectionType.Rectangle:
Duct duct;
using (Transaction trans = new(doc, "创建风管"))
{
trans.Start();
MechanicalSystemType currentDuctSystemType;
try
{
var ductSystemtype = new FilteredElementCollector(doc)
.OfClass(typeof(MechanicalSystemType))
.Cast<MechanicalSystemType>()
.FirstOrDefault(x => x.Name is "Supply Air" or "送风");
currentDuctSystemType =
ductSystemtype.Duplicate(excelData.System) as MechanicalSystemType;
}
catch (Exception)
{
currentDuctSystemType = new FilteredElementCollector(doc)
.OfClass(typeof(MechanicalSystemType))
.Cast<MechanicalSystemType>()
.FirstOrDefault(d => d.Name == excelData.System);
}
DuctType currentDuctType;
try
{
var ductType = new FilteredElementCollector(doc)
.OfClass(typeof(DuctType))
.Cast<DuctType>()
.FirstOrDefault();
currentDuctType = ductType.Duplicate(current.Material) as DuctType;
}
catch (Exception)
{
currentDuctType = new FilteredElementCollector(doc)
.OfClass(typeof(DuctType))
.Cast<DuctType>()
.FirstOrDefault(d => d.Name == current.Material);
}
duct = Duct.Create(
doc,
currentDuctSystemType.Id,
currentDuctType.Id,
level.Id,
current.CenterPoint,
next.CenterPoint
);
trans.Commit();
}
using (Transaction trans = new(doc, "设置风管"))
{
trans.Start();
SetDuctParam(current, duct);
trans.Commit();
}
break;
}
break;
}
}
}
}
/// <summary>
/// 布置节点
/// </summary>
/// <param name="dr"></param>
/// <param name="level"></param>
/// <param name="family"></param>
private void PlaceManhole(ExcelDataRow dr, Level level, Family family)
{
using Transaction trans = new(doc, "布置节点");
trans.Start();
if (dr.AccessoryType != null && dr.HasManHole)
{
var symbols =
from ElementId eleid in family.GetFamilySymbolIds()
where doc.GetElement(eleid).Name == dr.AccessoryType
select doc.GetElement(eleid) as FamilySymbol;
var symbol = symbols.FirstOrDefault();
if (symbol == null)
{
var defsymbol = doc.GetElement(family.GetFamilySymbolIds().FirstOrDefault()) as FamilySymbol;
symbol = defsymbol.Duplicate(dr.AccessoryType) as FamilySymbol;
}
symbol.Activate();
var instance = doc.Create.NewFamilyInstance(
dr.Location,
symbol,
level,
Autodesk.Revit.DB.Structure.StructuralType.NonStructural
);
instance.get_Parameter(BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS).Set(dr.StartId);
}
trans.Commit();
}
private void SetDuctParam(ExcelDataRow dr, Duct duct)
{
//switch (dr.AlignType)
//{
// case AlignType.Top:
// duct.get_Parameter(BuiltInParameter.RBS_CURVE_VERT_OFFSET_PARAM).Set(2);//顶部
// break;
// case AlignType.Bottom:
// duct.get_Parameter(BuiltInParameter.RBS_CURVE_VERT_OFFSET_PARAM).Set(1);//底部 break;
// default:
// duct.get_Parameter(BuiltInParameter.RBS_CURVE_VERT_OFFSET_PARAM).Set(0);
// break;
//}
duct.get_Parameter(BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS).Set(dr.StartId + "_" + dr.EndId);
duct.get_Parameter(BuiltInParameter.RBS_CURVE_WIDTH_PARAM).Set(dr.SectionWidth / 304.8);
duct.get_Parameter(BuiltInParameter.RBS_CURVE_HEIGHT_PARAM).Set(dr.SectionHeight / 304.8);
}
private void SetPipeParam(ExcelDataRow dr, Pipe pipe)
{
var pipesize = Convert.ToDouble(dr.Size) / 304.8;
var ps = pipe.PipeSegment;
var pt = pipe.PipeType;
//RoutingPreferenceManager rpm = pt.RoutingPreferenceManager;
//RoutingPreferenceRule rpr = rpm.GetRule(RoutingPreferenceRuleGroupType.Segments, 0);
////var eid = rpr.MEPPartId;
////int num = rpm.GetNumberOfRules(RoutingPreferenceRuleGroupType.Segments);//获取管段设置数量
//PrimarySizeCriterion psc = rpr.GetCriterion(0) as PrimarySizeCriterion;//获取管段的设置值
//PipeSegment ps = doc.GetElement(eid) as PipeSegment;
var existsize = from s in ps.GetSizes() where s.NominalDiameter.Equals(pipesize) select s;
if (!existsize.Any())
{
MEPSize mepsize = new(pipesize, pipesize, pipesize, true, true);
ps.AddSize(mepsize);
}
//rpr.AddCriterion(new PrimarySizeCriterion(psc.MinimumSize, pipesize));
//psc.MaximumSize = pipesize;
//rpm.AddRule(RoutingPreferenceRuleGroupType.Segments, rpr);
pipe.get_Parameter(BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS).Set(dr.StartId + "_" + dr.EndId);
pipe.get_Parameter(BuiltInParameter.RBS_PIPE_DIAMETER_PARAM).Set(pipesize);
//switch (dr.AlignType)
//{
// case AlignType.Top:
// pipe.get_Parameter(BuiltInParameter.RBS_CURVE_VERT_OFFSET_PARAM).Set(2);//顶部
// break;
// case AlignType.Bottom:
// pipe.get_Parameter(BuiltInParameter.RBS_CURVE_VERT_OFFSET_PARAM).Set(1);//底部 break;
// default:
// pipe.get_Parameter(BuiltInParameter.RBS_CURVE_VERT_OFFSET_PARAM).Set(0);
// break;
//}
}
private void TbFamilyPath_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
const string filter = "选择族文件(*.rfa)|*.rfa";
OpenFileDialog openDialog = new() { Filter = filter, Title = "选择族文件" };
openDialog.ShowDialog();
var path = openDialog.FileName;
TbFamilyPath.Text = path;
}
}