添加项目文件。

This commit is contained in:
GG Z
2024-09-22 11:05:41 +08:00
parent fb5d55723a
commit 49ceaae6a8
764 changed files with 78850 additions and 0 deletions

View File

@@ -0,0 +1,8 @@
namespace Sai.RvKits.RvIndependent
{
public enum AlignType
{
Top = 0,
Bottom = 1
}
}

View File

@@ -0,0 +1,56 @@
using OfficeOpenXml;
namespace Sai.RvKits.RvIndependent
{
public class ExcelData
{
public ExcelData(ExcelWorksheet sheet)
{
DataRows = new List<ExcelDataRow>();
var lastColumn = sheet.Dimension.End.Column;
var lastRow = sheet.Dimension.End.Row;
//不计算所有末行首列为空的行
while (sheet.Cells[lastRow, 3].Value == null)
{
lastRow--;
}
System = sheet.Cells[2, 3].Value?.ToString().Split(':').Last();
for (var i = 5; i <= lastRow; i++)
{
var edr = new ExcelDataRow
{
StartId = sheet.Cells[i, 1].Value?.ToString(), //起点节点号
Number = sheet.Cells[i, 2].Value?.ToString(), //管线点号
EndId = sheet.Cells[i, 3].Value?.ToString(), //连接点号
LayingMode = sheet.Cells[i, 4].Value?.ToString(), //埋设s方式
Material = sheet.Cells[i, 5].Value?.ToString(), //管材
Size = sheet.Cells[i, 6].Value?.ToString(), //截面尺寸
Feature = sheet.Cells[i, 7].Value?.ToString(), //特征
AccessoryType = sheet.Cells[i, 8].Value?.ToString(), //节点类型
X = Convert.ToDouble(sheet.Cells[i, 9].Value),
Y = Convert.ToDouble(sheet.Cells[i, 10].Value),
GroundElev = Convert.ToDouble(sheet.Cells[i, 11].Value), //地面高程
Top = Convert.ToDouble(sheet.Cells[i, 12].Value), //管顶
InnerBottom = Convert.ToDouble(sheet.Cells[i, 13].Value), //管内底
Depth = Convert.ToDouble(sheet.Cells[i, 14].Value), //埋深=地面高程-管顶/管内底groundElev-top/innerBottom
NumberOfCablesOrHoles = sheet.Cells[i, 15].Value?.ToString(), //电缆根数或总孔数/已用孔数
ArrangementOfHoles = sheet.Cells[i, 16].Value?.ToString(), //管孔排列(行X列)
VoltageorPressure = sheet.Cells[i, 17].Value?.ToString(), //电力电压(KV)/压力
Remarks = sheet.Cells[i, 18].Value?.ToString() //备注
};
if (edr.StartId == null)
{
edr.StartId = DataRows.Last().StartId;
edr.HasManHole = false;
}
DataRows.Add(edr);
}
}
public List<ExcelDataRow> DataRows;
public string System { get; set; }
}
}

View File

@@ -0,0 +1,209 @@
using Autodesk.Revit.DB;
using System;
using System.Linq;
namespace Sai.RvKits.RvIndependent
{
public class ExcelDataRow
{
/// <summary>
/// 对齐方式
/// </summary>
public AlignType AlignType
{
get
{
return Top switch
{
0.0 => AlignType.Bottom,
_ => AlignType.Top,
};
}
}
/// <summary>
/// 管中心坐标
/// </summary>
public XYZ CenterPoint => Location - new XYZ(0, 0, Offest) * 1000 / 304.8;
/// <summary>
/// 节点附属定位点
/// </summary>
public XYZ Location => new XYZ(X, Y, GroundElev) * 1000 / 304.8;
/// <summary>
/// 截面高度
/// </summary>
public double SectionHeight
{
get
{
if (SectionType == SectionType.Rectangle)
{
var s = Size.ToUpper().Split('X');
return Convert.ToDouble(s.Last());
}
return 0;
}
}
/// <summary>
/// 截面类型
/// </summary>
public SectionType SectionType
{
get
{
if (Size.Contains("X"))
{
return SectionType.Rectangle;
}
return SectionType.Circle;
}
}
/// <summary>
/// 截面宽度
/// </summary>
public double SectionWidth
{
get
{
if (SectionType == SectionType.Rectangle)
{
var s = Size.ToUpper().Split('X');
return Convert.ToDouble(s.First());
}
return 0;
}
}
//垂直截面半高度
private double Half
{
get
{
double half;
if (SectionType == SectionType.Circle)
{
half = Convert.ToDouble(Size) / 2;
}
else
{
var s = Size.ToUpper().Split('X');
half = Convert.ToDouble(s.Last()) / 2;
}
return half;
}
}
private double Offest
{
get
{
switch (AlignType)
{
case AlignType.Top:
return Depth + Half / 1000; //管中心距离地面高度
case AlignType.Bottom:
return Depth - Half / 1000;
default:
return 0;
}
}
}
/// <summary>
/// 唯一节点
/// </summary>
public bool HasManHole { get; set; } = true;
public double X { get; set; }
public double Y { get; set; }
/// <summary>
/// 地面高程
/// </summary>
public double GroundElev { get; set; }
/// <summary>
/// 管顶
/// </summary>
public double Top { get; set; }
/// <summary>
/// 管内底
/// </summary>
public double InnerBottom { get; set; }
/// <summary>
/// //埋深=地面高程-管顶/管内底:groundElev-top/innerBottom
/// </summary>
public double Depth { get; set; }
/// <summary>
/// 起点节点号
/// </summary>
public string StartId { get; set; }
/// <summary>
/// 管线点号
/// </summary>
public string Number { get; set; }
/// <summary>
/// 连接点号
/// </summary>
public string EndId { get; set; }
/// <summary>
/// 埋设方式
/// </summary>
public string LayingMode { get; set; }
/// <summary>
/// 管材
/// </summary>
public string Material { get; set; }
public string Size { get; set; }
/// <summary>
/// 特征
/// </summary>
public string Feature { get; set; }
/// <summary>
/// 节点类型
/// </summary>
public string AccessoryType { get; set; }
/// <summary>
/// 电缆根数或总孔数/已用孔数
/// </summary>
public string NumberOfCablesOrHoles { get; set; }
/// <summary>
/// 管孔排列(行X列)
/// </summary>
public string ArrangementOfHoles { get; set; }
/// <summary>
/// 电力电压(KV)/压力
/// </summary>
public string VoltageorPressure { get; set; }
/// <summary>
/// 备注
/// </summary>
public string Remarks { get; set; }
}
}

View File

@@ -0,0 +1,15 @@
using Nice3point.Revit.Toolkit.External;
namespace Sai.RvKits.RvIndependent
{
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
[Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
internal class NetworkCreatorCmd : ExternalCommand
{
public override void Execute()
{
var win = new NetworkCreatorView(Document);
win.ShowDialog();
}
}
}

View File

@@ -0,0 +1,76 @@
<ex:FluentWindowEx
x:Class="Sai.RvKits.RvIndependent.NetworkCreatorView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:ex="https://github.com/sherlockforrest/Wpf.Ui.Extend"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
Title="物探管网"
Width="500"
Height="100"
MinHeight="110"
mc:Ignorable="d">
<Window.Resources>
<ResourceDictionary Source="pack://application:,,,/Sai.RvKits;component/WPFUI.xaml" />
</Window.Resources>
<ex:AutoGrid
ChildMargin="5"
Columns="*,Auto,Auto,Auto"
Rows="Auto,Auto">
<ui:TextBox
x:Name="TbXlsxPath"
Grid.Row="0"
Grid.Column="0"
IsReadOnly="True"
PlaceholderText="Excel文件"
TextWrapping="NoWrap"
ToolTip="双击选择文件" />
<Button
x:Name="ExcelSelectBtn"
Grid.Row="0"
Grid.Column="1"
Click="BtnExcelSelect_Click"
Content="选择文件" />
<ui:TextBox
x:Name="TbParaName"
Grid.Row="0"
Grid.Column="2"
Grid.ColumnSpan="2"
PlaceholderText="参数名"
TextWrapping="Wrap" />
<ui:TextBox
x:Name="TbFamilyPath"
Grid.Row="1"
Grid.Column="0"
VerticalAlignment="Center"
Cursor="Arrow"
IsReadOnly="True"
MouseDoubleClick="TbFamilyPath_MouseDoubleClick"
PlaceholderText="族文件"
TextWrapping="NoWrap"
ToolTip="双击选择文件" />
<Button
x:Name="BtnFamilyInit"
Grid.Row="1"
Grid.Column="1"
Content="选择族"
Cursor="Hand" />
<ComboBox
x:Name="CbSheetName"
Grid.Row="1"
Grid.Column="2"
Width="120"
DisplayMemberPath="Name"
SelectedValuePath="Index"
SelectionChanged="CBSheetName_SelectionChanged"
Text="表名" />
<Button
x:Name="BtnApple"
Grid.Row="1"
Grid.Column="3"
Click="BtnApply_Click"
Content="创建"
ToolTip="创建模型" />
</ex:AutoGrid>
</ex:FluentWindowEx>

View File

@@ -0,0 +1,490 @@
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 Sai.RvKits.RvIndependent;
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;
}
}

View File

@@ -0,0 +1,14 @@
namespace Sai.RvKits.RvIndependent
{
internal enum NetworkType
{
WaterSupplySystem = 0,
SewerageSystem = 1,
StormWaterDrainageSystem = 2,
StreetLightSystem = 3,
ElectricPowerSystem = 4,
GasSystem = 5,
TelecommunicationSystem = 6,
Invalid = -1
}
}

View File

@@ -0,0 +1,8 @@
namespace Sai.RvKits.RvIndependent
{
public enum SectionType
{
Circle = 0,
Rectangle = 1
}
}