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; namespace ShrlAlgoToolkit.RevitAddins.RvIndependent.NetworkCreator; 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; /// /// 获取族并载入,若已存在项目,则获取同名族 /// /// 文件完整路径 /// private Family GetFamily(string familyname) { doc.LoadFamily(familyname, out var family); family ??= new FilteredElementCollector(doc) .OfClass(typeof(Family)) .Cast() .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() .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 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().ToList(); var connectors = new List(); 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(); } /// /// 连接管线 /// private void ConnectPipes() { var pipes = new FilteredElementCollector(doc).OfClass(typeof(Pipe)).Cast().ToList(); var connectors = new List(); 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(); } /// /// 创建水管管网 /// /// /// 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() .FirstOrDefault(x => x.Name is "Other" or "其他"); currentPipeSystemType = pipeSystemtype.Duplicate(excelData.System) as PipingSystemType; } catch (Exception) { currentPipeSystemType = new FilteredElementCollector(doc) .OfClass(typeof(PipingSystemType)) .Cast() .FirstOrDefault(p => p.Name == excelData.System); } PipeType currentPipeType = null; try { var pipeType = new FilteredElementCollector(doc) .OfClass(typeof(PipeType)) .Cast() .FirstOrDefault(); currentPipeType = pipeType.Duplicate(current.Material) as PipeType; } catch (Exception) { currentPipeType = new FilteredElementCollector(doc) .OfClass(typeof(PipeType)) .Cast() .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() .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() .FirstOrDefault(d => d.Name == excelData.System); } DuctType currentDuctType; try { var ductType = new FilteredElementCollector(doc) .OfClass(typeof(DuctType)) .Cast() .FirstOrDefault(); currentDuctType = ductType.Duplicate(current.Material) as DuctType; } catch (Exception) { currentDuctType = new FilteredElementCollector(doc) .OfClass(typeof(DuctType)) .Cast() .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; } } } } /// /// 布置节点 /// /// /// /// 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; } }