增加保温层和整理管线的功能,修复自动保存功能等修复多个bug
This commit is contained in:
18
Sai.RvKits/RvMEP/AddInsulationCmd.cs
Normal file
18
Sai.RvKits/RvMEP/AddInsulationCmd.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
|
||||
using Autodesk.Revit.Attributes;
|
||||
using Autodesk.Revit.DB;
|
||||
using Autodesk.Revit.UI;
|
||||
using Autodesk.Revit.UI.Selection;
|
||||
|
||||
using Nice3point.Revit.Toolkit.External;
|
||||
|
||||
namespace Sai.RvKits.RvMEP;
|
||||
[Transaction(TransactionMode.Manual)]
|
||||
public class AddInsulationCmd : ExternalCommand
|
||||
{
|
||||
public override void Execute()
|
||||
{
|
||||
WinDialogHelper.ShowModeless<AddInsulationView>(new AddInsulationViewModel(Document));
|
||||
}
|
||||
}
|
||||
108
Sai.RvKits/RvMEP/AddInsulationView.xaml
Normal file
108
Sai.RvKits/RvMEP/AddInsulationView.xaml
Normal file
@@ -0,0 +1,108 @@
|
||||
<ex:FluentWindowEx
|
||||
x:Class="Sai.RvKits.RvMEP.AddInsulationView"
|
||||
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:local="clr-namespace:Sai.RvKits.RvMEP"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
Title="保温层"
|
||||
Width="620"
|
||||
MinHeight="300"
|
||||
d:DataContext="{d:DesignInstance Type=local:AddInsulationViewModel}"
|
||||
SizeToContent="Height"
|
||||
mc:Ignorable="d">
|
||||
<Window.Resources>
|
||||
<ResourceDictionary Source="pack://application:,,,/Sai.RvKits;component/WPFUI.xaml" />
|
||||
</Window.Resources>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<ex:StackPanelEx
|
||||
Grid.RowSpan="2"
|
||||
Grid.Column="0"
|
||||
Margin="5"
|
||||
IsEnabled="{Binding AddToPipe, Mode=TwoWay}"
|
||||
Spacing="5">
|
||||
<ex:ComboBoxEx
|
||||
DisplayMemberPath="Name"
|
||||
Header="管道系统类型"
|
||||
ItemsSource="{Binding PipingSystemTypes}"
|
||||
SelectedItem="{Binding SelectedPipingSystemType}" />
|
||||
<DataGrid
|
||||
ex:StackPanelEx.Fill="Fill"
|
||||
AutoGenerateColumns="False"
|
||||
ItemsSource="{Binding PipeInsulationItems}"
|
||||
SelectionUnit="FullRow">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Binding="{Binding MinDiameter}" Header="最小管径" />
|
||||
<DataGridTextColumn Binding="{Binding MaxDiameter}" Header="最大管径" />
|
||||
<DataGridTextColumn Binding="{Binding Thickness}" Header="保温层厚度" />
|
||||
<!--<DataGridTextColumn Binding="{Binding PipeInsulationType.Name}" Header="保温层材料" />-->
|
||||
<!--<DataGridComboBoxColumn
|
||||
DisplayMemberPath=""
|
||||
Header="保温层材料"
|
||||
ItemsSource="{Binding PipeInsulationTypes}"
|
||||
SelectedItemBinding="{Binding PipeInsulationType, UpdateSourceTrigger=PropertyChanged}"
|
||||
TextBinding="{Binding PipeInsulationType.Name}" />-->
|
||||
<DataGridTemplateColumn Width="*" Header="保温层材料">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel>
|
||||
<ComboBox
|
||||
DisplayMemberPath="Name"
|
||||
ItemsSource="{Binding DataContext.PipeInsulationTypes, RelativeSource={RelativeSource AncestorType={x:Type Window}, Mode=FindAncestor}}"
|
||||
SelectedItem="{Binding PipeInsulationType, UpdateSourceTrigger=PropertyChanged}" />
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
</ex:StackPanelEx>
|
||||
<ex:StackPanelEx
|
||||
Grid.Column="1"
|
||||
Margin="5"
|
||||
IsEnabled="{Binding AddToDuct, Mode=TwoWay}"
|
||||
Spacing="5">
|
||||
<ex:ComboBoxEx
|
||||
DisplayMemberPath="Name"
|
||||
Header="风管系统类型:"
|
||||
ItemsSource="{Binding DuctSystemTypes}"
|
||||
SelectedItem="{Binding SelectedDuctSystem}" />
|
||||
<ex:ComboBoxEx
|
||||
DisplayMemberPath="Name"
|
||||
Header="保温层类型:"
|
||||
ItemsSource="{Binding DuctInsulationTypes}"
|
||||
SelectedItem="{Binding DuctInsulationItem.DuctInsulationType}" />
|
||||
<ex:TextBoxEx Header="保温层厚度:" Text="{Binding DuctInsulationItem.Thickness, UpdateSourceTrigger=PropertyChanged}" />
|
||||
</ex:StackPanelEx>
|
||||
<StackPanel
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
HorizontalAlignment="Right"
|
||||
Orientation="Horizontal">
|
||||
<CheckBox
|
||||
MinWidth="50"
|
||||
Margin="5"
|
||||
Content="管道"
|
||||
IsChecked="{Binding AddToPipe}" />
|
||||
<CheckBox
|
||||
MinWidth="50"
|
||||
Margin="5"
|
||||
Content="风管"
|
||||
IsChecked="{Binding AddToDuct}" />
|
||||
<Button
|
||||
Grid.Row="1"
|
||||
HorizontalAlignment="Right"
|
||||
Command="{Binding AddInsulationCommand}"
|
||||
Content="添加保温层" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</ex:FluentWindowEx>
|
||||
25
Sai.RvKits/RvMEP/AddInsulationView.xaml.cs
Normal file
25
Sai.RvKits/RvMEP/AddInsulationView.xaml.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace Sai.RvKits.RvMEP;
|
||||
/// <summary>
|
||||
/// AddInsulationView.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class AddInsulationView
|
||||
{
|
||||
public AddInsulationView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
190
Sai.RvKits/RvMEP/AddInsulationViewModel.cs
Normal file
190
Sai.RvKits/RvMEP/AddInsulationViewModel.cs
Normal file
@@ -0,0 +1,190 @@
|
||||
using Autodesk.Revit.DB;
|
||||
using Autodesk.Revit.DB.Mechanical;
|
||||
using Autodesk.Revit.DB.Plumbing;
|
||||
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
|
||||
using Nice3point.Revit.Toolkit.External.Handlers;
|
||||
|
||||
namespace Sai.RvKits.RvMEP
|
||||
{
|
||||
public partial class AddInsulationViewModel : ObservableObject
|
||||
{
|
||||
private readonly ActionEventHandler addInsulationHandler = new();
|
||||
|
||||
[ObservableProperty]
|
||||
[NotifyCanExecuteChangedFor(nameof(AddInsulationCommand))]
|
||||
private bool addToDuct;
|
||||
[ObservableProperty]
|
||||
[NotifyCanExecuteChangedFor(nameof(AddInsulationCommand))]
|
||||
private bool addToPipe;
|
||||
/// <summary>
|
||||
/// 定义的风管保温层
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
private InsulationItem ductInsulationItem;
|
||||
/// <summary>
|
||||
/// 定义的管道保温层
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
private List<InsulationItem> pipeInsulationItems;
|
||||
/// <summary>
|
||||
/// 选中的风管系统类型
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
[NotifyCanExecuteChangedFor(nameof(AddInsulationCommand))]
|
||||
|
||||
private MechanicalSystemType selectedDuctSystem;
|
||||
/// <summary>
|
||||
/// 选中的管道系统类型
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
[NotifyCanExecuteChangedFor(nameof(AddInsulationCommand))]
|
||||
private PipingSystemType selectedPipingSystemType;
|
||||
|
||||
public AddInsulationViewModel(Document doc)
|
||||
{
|
||||
PipingSystemTypes = doc.OfClass<PipingSystemType>().Cast<PipingSystemType>().ToList();
|
||||
DuctSystemTypes = doc.OfClass<MechanicalSystemType>().Cast<MechanicalSystemType>().ToList();
|
||||
DuctInsulationTypes = doc.OfClass<DuctInsulationType>().Cast<DuctInsulationType>().ToList();
|
||||
PipeInsulationTypes = doc.OfClass<PipeInsulationType>().Cast<PipeInsulationType>().ToList();
|
||||
PipeInsulationItems = [
|
||||
new InsulationItem(){MinDiameter=15,MaxDiameter=25, Thickness=25,PipeInsulationType=PipeInsulationTypes.FirstOrDefault()},
|
||||
new InsulationItem(){MinDiameter=32,MaxDiameter=80, Thickness=30,PipeInsulationType=PipeInsulationTypes.FirstOrDefault()},
|
||||
new InsulationItem(){MinDiameter=100,MaxDiameter=1000, Thickness=35,PipeInsulationType=PipeInsulationTypes.FirstOrDefault()},
|
||||
];
|
||||
DuctInsulationItem = new() { Thickness = 50, DuctInsulationType = DuctInsulationTypes.FirstOrDefault() };
|
||||
}
|
||||
|
||||
[RelayCommand(CanExecute = nameof(CanAdd))]
|
||||
private void AddInsulation()
|
||||
{
|
||||
addInsulationHandler.Raise(
|
||||
uiapp =>
|
||||
{
|
||||
var uidoc = uiapp.ActiveUIDocument;
|
||||
var doc = uidoc.Document;
|
||||
doc.Invoke(
|
||||
ts =>
|
||||
{
|
||||
if (AddToDuct)
|
||||
{
|
||||
var systems = doc.OfClass<MechanicalSystem>().Cast<MechanicalSystem>();
|
||||
|
||||
foreach (var system in systems)
|
||||
{
|
||||
var elems = system.DuctNetwork;
|
||||
foreach (Element elem in elems)
|
||||
{
|
||||
var id = InsulationLiningBase.GetInsulationIds(doc, elem.Id).FirstOrDefault();
|
||||
if (id == null)
|
||||
{
|
||||
//风管或风管管件
|
||||
if (elem is Duct duct ||
|
||||
(elem is FamilyInstance instance &&
|
||||
instance.Category.Id.IntegerValue == -2008010))
|
||||
{
|
||||
Autodesk.Revit.DB.Mechanical.DuctInsulation
|
||||
.Create(
|
||||
doc,
|
||||
elem.Id,
|
||||
DuctInsulationItem.DuctInsulationType.Id,
|
||||
DuctInsulationItem.Thickness / 304.8);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var insulation = doc.GetElement(id) as DuctInsulation;
|
||||
insulation.ChangeTypeId(DuctInsulationItem.DuctInsulationType.Id);
|
||||
insulation.Thickness = DuctInsulationItem.Thickness / 304.8;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (AddToPipe)
|
||||
{
|
||||
var systems = doc.OfClass<PipingSystem>().Cast<PipingSystem>();
|
||||
|
||||
foreach (var system in systems)
|
||||
{
|
||||
var elems = system.PipingNetwork;
|
||||
foreach (Element elem in elems)
|
||||
{
|
||||
//水管或水管管件
|
||||
if (elem is Pipe pipe ||
|
||||
(elem is FamilyInstance instance &&
|
||||
instance.Category.Id.IntegerValue == -2008049))
|
||||
{
|
||||
InsulationItem pipeInsulation = default;
|
||||
foreach (var item in PipeInsulationItems)
|
||||
{
|
||||
//直径
|
||||
var str = elem.get_Parameter(BuiltInParameter.RBS_CALCULATED_SIZE)
|
||||
.AsString()
|
||||
.Split(' ')
|
||||
.FirstOrDefault();
|
||||
if (double.TryParse(str, out var d))
|
||||
{
|
||||
if (d >= item.MinDiameter && d <= item.MaxDiameter)
|
||||
{
|
||||
pipeInsulation = item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var id = InsulationLiningBase.GetInsulationIds(doc, elem.Id).FirstOrDefault();
|
||||
if (id == null)
|
||||
{
|
||||
if (pipeInsulation != null)
|
||||
{
|
||||
Autodesk.Revit.DB.Plumbing.PipeInsulation
|
||||
.Create(
|
||||
doc,
|
||||
elem.Id,
|
||||
pipeInsulation.PipeInsulationType.Id,
|
||||
pipeInsulation.Thickness / 304.8);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var insulation = doc.GetElement(id) as PipeInsulation;
|
||||
insulation.ChangeTypeId(pipeInsulation.PipeInsulationType.Id);
|
||||
insulation.Thickness = pipeInsulation.Thickness / 304.8;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, "添加保温层");
|
||||
});
|
||||
}
|
||||
|
||||
//private bool CanAdd()
|
||||
//{
|
||||
// return (AddToDuct && SelectedDuctSystem != null) || (AddToPipe && SelectedPipingSystemType != null);
|
||||
//}
|
||||
private bool CanAdd => (AddToDuct && SelectedDuctSystem != null) ||
|
||||
(AddToPipe && SelectedPipingSystemType != null);
|
||||
|
||||
/// <summary>
|
||||
/// 所有风管保温层类型
|
||||
/// </summary>
|
||||
public List<DuctInsulationType> DuctInsulationTypes { get; set; }
|
||||
/// <summary>
|
||||
/// 所有风管系统类型
|
||||
/// </summary>
|
||||
public List<MechanicalSystemType> DuctSystemTypes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 所有管道保温层类型
|
||||
/// </summary>
|
||||
public List<PipeInsulationType> PipeInsulationTypes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 所有管道系统类型
|
||||
/// </summary>
|
||||
public List<PipingSystemType> PipingSystemTypes { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,13 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
using Autodesk.Revit.Attributes;
|
||||
using Autodesk.Revit.DB.Plumbing;
|
||||
|
||||
using Nice3point.Revit.Toolkit.External;
|
||||
|
||||
namespace Sai.RvKits.RvMEP;
|
||||
|
||||
[Transaction(TransactionMode.Manual)]
|
||||
[Regeneration(RegenerationOption.Manual)]
|
||||
public class AnyConnectCmd : ExternalCommand
|
||||
{
|
||||
public override void Execute()
|
||||
|
||||
@@ -310,7 +310,7 @@ public partial class AnyConnectViewModel : ObservableValidator
|
||||
//var copyMepCurveId = ElementTransformUtils
|
||||
// .CopyElement(doc, elementToCopy.Id, XYZ.Zero)
|
||||
// .FirstOrDefault();
|
||||
//var copyMepCurve = doc.GetElement(copyMepCurveId) as MEPCurve;
|
||||
//var copyMepCurve = doc.GetElement(copyMepCurveId) as ElementToMove;
|
||||
//取短的线作为旋转轴的基准点,保证能创建
|
||||
var isFirstMEPCurveLengther = line1.Length < line2.Length;
|
||||
var l = isFirstMEPCurveLengther ? Line.CreateBound(
|
||||
|
||||
@@ -4,7 +4,17 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Autodesk.Revit.Attributes;
|
||||
|
||||
using Nice3point.Revit.Toolkit.External;
|
||||
|
||||
namespace Sai.RvKits.RvMEP;
|
||||
internal class ArrangeMEPCurveCmd
|
||||
|
||||
[Transaction(TransactionMode.Manual)]
|
||||
internal class ArrangeMEPCurveCmd : ExternalCommand
|
||||
{
|
||||
public override void Execute()
|
||||
{
|
||||
WinDialogHelper.ShowModeless<ArrangeMEPCurveView>(new ArrangeMEPCurveViewModel());
|
||||
}
|
||||
}
|
||||
|
||||
44
Sai.RvKits/RvMEP/ArrangeMEPCurveView.xaml
Normal file
44
Sai.RvKits/RvMEP/ArrangeMEPCurveView.xaml
Normal file
@@ -0,0 +1,44 @@
|
||||
<ex:FluentWindowEx
|
||||
x:Class="Sai.RvKits.RvMEP.ArrangeMEPCurveView"
|
||||
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:local="clr-namespace:Sai.RvKits.RvMEP"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
Title="整理管线"
|
||||
Width="270"
|
||||
MinHeight="180"
|
||||
d:DataContext="{d:DesignInstance Type=local:ArrangeMEPCurveViewModel}"
|
||||
SizeToContent="Height"
|
||||
mc:Ignorable="d">
|
||||
<Window.Resources>
|
||||
<ResourceDictionary Source="pack://application:,,,/Sai.RvKits;component/WPFUI.xaml" />
|
||||
</Window.Resources>
|
||||
<ex:StackPanelEx Margin="5" Spacing="5">
|
||||
<GroupBox Header="参考方向">
|
||||
<UniformGrid Rows="1">
|
||||
<RadioButton Content="水平方向" IsChecked="{Binding IsHorizon}" />
|
||||
<RadioButton Content="垂直方向" IsChecked="{Binding IsHorizon, Converter={StaticResource InvertBooleanConverter}}" />
|
||||
</UniformGrid>
|
||||
</GroupBox>
|
||||
<ex:TextBoxEx
|
||||
Prefix="间距:"
|
||||
Suffix="mm"
|
||||
Text="{Binding Gap, UpdateSourceTrigger=PropertyChanged}" />
|
||||
<UniformGrid Rows="1">
|
||||
<RadioButton
|
||||
MinWidth="50"
|
||||
Content="管中心"
|
||||
IsChecked="{Binding MEPCurveCenter}" />
|
||||
<RadioButton
|
||||
Content="管外壁/考虑保温层"
|
||||
IsChecked="{Binding MEPCurveCenter, Converter={StaticResource InvertBooleanConverter}}"
|
||||
ToolTip="若无保温,则仅考虑管外壁" />
|
||||
</UniformGrid>
|
||||
<Button
|
||||
HorizontalAlignment="Stretch"
|
||||
Command="{Binding ArrangeCommand}"
|
||||
Content="整理" />
|
||||
</ex:StackPanelEx>
|
||||
</ex:FluentWindowEx>
|
||||
25
Sai.RvKits/RvMEP/ArrangeMEPCurveView.xaml.cs
Normal file
25
Sai.RvKits/RvMEP/ArrangeMEPCurveView.xaml.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace Sai.RvKits.RvMEP;
|
||||
/// <summary>
|
||||
/// ArrangeMEPCurveView.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class ArrangeMEPCurveView
|
||||
{
|
||||
public ArrangeMEPCurveView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
364
Sai.RvKits/RvMEP/ArrangeMEPCurveViewModel.cs
Normal file
364
Sai.RvKits/RvMEP/ArrangeMEPCurveViewModel.cs
Normal file
@@ -0,0 +1,364 @@
|
||||
using System.Windows;
|
||||
|
||||
using Autodesk.Revit.DB;
|
||||
using Autodesk.Revit.DB.Electrical;
|
||||
using Autodesk.Revit.DB.Mechanical;
|
||||
using Autodesk.Revit.DB.Plumbing;
|
||||
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
|
||||
using Nice3point.Revit.Toolkit.External.Handlers;
|
||||
|
||||
namespace Sai.RvKits.RvMEP
|
||||
{
|
||||
public partial class ArrangeMEPCurveViewModel : ObservableObject
|
||||
{
|
||||
private readonly ActionEventHandler arrangeHandler = new();
|
||||
|
||||
[ObservableProperty]
|
||||
private double gap = 250;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool mEPCurveCenter = true;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool isHorizon = true;
|
||||
[RelayCommand]
|
||||
private void Arrange()
|
||||
{
|
||||
arrangeHandler.Raise(
|
||||
uiapp =>
|
||||
{
|
||||
var uidoc = uiapp.ActiveUIDocument;
|
||||
var doc = uidoc.Document;
|
||||
doc.Invoke(
|
||||
ts =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var ids = uidoc.Selection
|
||||
.PickElementsByRectangle(
|
||||
new FuncFilter(
|
||||
e => e is MEPCurve &&
|
||||
e is not InsulationLiningBase &&
|
||||
e is not FlexDuct &&
|
||||
e is not FlexPipe &&
|
||||
!(e.GetLocCurve() as Line).Direction.IsParallelTo(XYZ.BasisZ)),
|
||||
"请选择要整理的管线")
|
||||
.Select(e => e.Id)
|
||||
.ToList();
|
||||
var baseId = uidoc.Selection
|
||||
.PickObject(
|
||||
Autodesk.Revit.UI.Selection.ObjectType.Element,
|
||||
new FuncFilter(e => ids.Contains(e.Id)),
|
||||
"请选择基准管线")
|
||||
.ElementId;
|
||||
|
||||
if (ids.Count <= 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var baseElement = doc.GetElement(baseId);
|
||||
var baseLine = baseElement.GetLocCurve() as Line;
|
||||
baseLine.MakeUnbound();
|
||||
if (IsHorizon)
|
||||
{
|
||||
//移除基准
|
||||
ids.Remove(baseId);
|
||||
|
||||
List<ArrangeElement> arranges = [];
|
||||
foreach (var id in ids)
|
||||
{
|
||||
var elem = doc.GetElement(id);
|
||||
var l = elem.GetLocCurve() as Line;
|
||||
if (!l.Direction.IsParallelTo(baseLine.Direction))
|
||||
{
|
||||
MessageBox.Show("错误", "所选管线不平行");
|
||||
return;
|
||||
}
|
||||
var d = baseLine.Distance(l.Origin);
|
||||
var project = baseLine.Project(l.Origin).XYZPoint;
|
||||
|
||||
var vector = l.Origin.Flatten() - project.Flatten();
|
||||
var ae = new ArrangeElement
|
||||
{
|
||||
ElementToMove = elem,
|
||||
//用来确定与基准管线的位置和方向
|
||||
HorizonDistanceVector = vector
|
||||
};
|
||||
arranges.Add(ae);
|
||||
}
|
||||
var groups = arranges.OrderBy(ar => ar.HorizonDistanceVector.GetLength())
|
||||
.GroupBy(
|
||||
ar => XYZ.BasisZ
|
||||
.CrossProduct(baseLine.Direction)
|
||||
.IsAlmostEqualTo(ar.HorizonDistanceVector.Normalize()));
|
||||
if (groups.Count() > 2)
|
||||
{
|
||||
MessageBox.Show("管线定位线存在误差");
|
||||
return;
|
||||
}
|
||||
//管中心距离
|
||||
if (MEPCurveCenter)
|
||||
{
|
||||
foreach (var group in groups)
|
||||
{
|
||||
for (var i = 0; i < group.Count(); i++)
|
||||
{
|
||||
var arrange = group.ElementAt(i);
|
||||
//当前的距离
|
||||
var dis = arrange.HorizonDistanceVector.GetLength();
|
||||
var moveUnitDir = arrange.HorizonDistanceVector.Normalize();
|
||||
//最终的距离
|
||||
var actualDis = (i + 1) * Gap / 304.8;
|
||||
var translate = moveUnitDir * (actualDis - dis);
|
||||
ElementTransformUtils.MoveElement(
|
||||
doc,
|
||||
arrange.ElementToMove.Id,
|
||||
translate);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//遍历两个方向的分组
|
||||
foreach (var group in groups)
|
||||
{
|
||||
double actualDis = 0;
|
||||
double previousHalfSize = 0;
|
||||
//基准半宽
|
||||
if (baseElement is Pipe pipe)
|
||||
{
|
||||
previousHalfSize = pipe.get_Parameter(BuiltInParameter.RBS_PIPE_OUTER_DIAMETER).AsDouble() / 2;
|
||||
}
|
||||
else if (baseElement is Conduit conduit)
|
||||
{
|
||||
previousHalfSize = conduit.get_Parameter(BuiltInParameter.RBS_CONDUIT_OUTER_DIAM_PARAM).AsDouble() / 2;
|
||||
}
|
||||
else if (baseElement is CableTray tray || baseElement is Duct duct)
|
||||
{
|
||||
var baseConnector = baseElement.GetConnectors()
|
||||
.OfType<Connector>()
|
||||
.FirstOrDefault();
|
||||
if (baseConnector.Shape == ConnectorProfileType.Oval || baseConnector.Shape == ConnectorProfileType.Rectangular)
|
||||
{
|
||||
previousHalfSize = baseConnector.Width / 2;
|
||||
}
|
||||
else if (baseConnector.Shape == ConnectorProfileType.Round)
|
||||
{
|
||||
previousHalfSize = baseConnector.Radius;
|
||||
}
|
||||
}
|
||||
if (baseElement is Pipe or Duct)
|
||||
{
|
||||
//基准保温层厚度
|
||||
var insulationId = InsulationLiningBase.GetInsulationIds(
|
||||
doc,
|
||||
baseElement.Id).FirstOrDefault();
|
||||
if (insulationId != null)
|
||||
{
|
||||
var insulation = doc.GetElement(insulationId) as InsulationLiningBase;
|
||||
previousHalfSize += insulation.Thickness;
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < group.Count(); i++)
|
||||
{
|
||||
var arrange = group.ElementAt(i);
|
||||
//当前的距离
|
||||
var dis = arrange.HorizonDistanceVector.GetLength();
|
||||
var moveUnitDir = arrange.HorizonDistanceVector.Normalize();
|
||||
|
||||
double currentHalfSize = 0;
|
||||
if (arrange.ElementToMove is Pipe p)
|
||||
{
|
||||
currentHalfSize = p.get_Parameter(BuiltInParameter.RBS_PIPE_OUTER_DIAMETER).AsDouble() / 2;
|
||||
}
|
||||
else if (arrange.ElementToMove is Conduit conduit)
|
||||
{
|
||||
currentHalfSize = conduit.get_Parameter(BuiltInParameter.RBS_CONDUIT_OUTER_DIAM_PARAM).AsDouble() / 2;
|
||||
}
|
||||
else if (arrange.ElementToMove is CableTray tray || arrange.ElementToMove is Duct duct)
|
||||
{
|
||||
var conn = arrange.ElementToMove.GetConnectors()
|
||||
.OfType<Connector>()
|
||||
.FirstOrDefault();
|
||||
if (conn.Shape == ConnectorProfileType.Oval || conn.Shape == ConnectorProfileType.Rectangular)
|
||||
{
|
||||
currentHalfSize = conn.Width / 2;
|
||||
}
|
||||
else if (conn.Shape == ConnectorProfileType.Round)
|
||||
{
|
||||
currentHalfSize = conn.Radius;
|
||||
}
|
||||
}
|
||||
//只有管道和风管有保温
|
||||
if (arrange.ElementToMove is Pipe or Duct)
|
||||
{
|
||||
//考虑保温层
|
||||
var currentInsulationId = InsulationLiningBase.GetInsulationIds(
|
||||
doc,
|
||||
arrange.ElementToMove.Id).FirstOrDefault();
|
||||
if (currentInsulationId != null)
|
||||
{
|
||||
var currentInsulation = doc.GetElement(currentInsulationId) as InsulationLiningBase;
|
||||
currentHalfSize += currentInsulation.Thickness;
|
||||
}
|
||||
}
|
||||
//最终的距离叠加,附加上次的距离,使得每次只要增加一个上一个半宽+当前的半宽+间隙
|
||||
actualDis += previousHalfSize + currentHalfSize + Gap / 304.8;
|
||||
var translate = moveUnitDir * (actualDis - dis);
|
||||
ElementTransformUtils.MoveElement(
|
||||
doc,
|
||||
arrange.ElementToMove.Id,
|
||||
translate);
|
||||
//修改上个半宽,用于当前分组里下一个元素循环
|
||||
previousHalfSize = currentHalfSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//垂向
|
||||
else
|
||||
{
|
||||
//通过LocationCurve确定相对位置关系
|
||||
var orderIds = ids.Select(id => doc.GetElement(id) as MEPCurve)
|
||||
.OrderBy(c => (c.GetLocCurve() as Line).Origin.Z).Select(e => e.Id).ToList();
|
||||
//中心距
|
||||
if (MEPCurveCenter)
|
||||
{
|
||||
var baseIndex = orderIds.IndexOf(baseId);
|
||||
for (var i = 0; i < orderIds.Count; i++)
|
||||
{
|
||||
var currentZ = (doc.GetElement(orderIds[i]).GetLocCurve() as Line).Origin.Z;
|
||||
var dis = Math.Abs(baseLine.Origin.Z - currentZ);
|
||||
var actualDis = Math.Abs((baseIndex - i)) * Gap / 304.8;
|
||||
//判断方向
|
||||
var vector = i > baseIndex ? XYZ.BasisZ : -XYZ.BasisZ;
|
||||
|
||||
var translate = (actualDis - dis) * vector;
|
||||
|
||||
ElementTransformUtils.MoveElement(doc, orderIds[i], translate);
|
||||
//if (i > baseIndex)
|
||||
//{
|
||||
// var dis = currentZ - baseLine.Origin.Z;//正的
|
||||
// var actualDis = (i - baseIndex) * Gap / 304.8;//正的
|
||||
// var translate = (actualDis - dis) * XYZ.BasisZ;
|
||||
// ElementTransformUtils.MoveElement(doc, orderIds[i], translate);
|
||||
//}
|
||||
}
|
||||
}
|
||||
//外距
|
||||
else
|
||||
{
|
||||
ids.Remove(baseId);
|
||||
var groups = ids.Select(id => doc.GetElement(id) as MEPCurve)
|
||||
.OrderBy(c => (c.GetLocCurve() as Line).Origin.Z).GroupBy(e => (e.GetLocCurve() as Line).Origin.Z > baseLine.Origin.Z);
|
||||
var baseTop = baseElement.get_BoundingBox(null).Max.Z;
|
||||
var baseBottom = baseElement.get_BoundingBox(null).Min.Z;
|
||||
if (baseElement is Pipe or Duct)
|
||||
{
|
||||
//基准保温层厚度
|
||||
var insulationId = InsulationLiningBase.GetInsulationIds(
|
||||
doc,
|
||||
baseElement.Id).FirstOrDefault();
|
||||
if (insulationId != null)
|
||||
{
|
||||
var insulation = doc.GetElement(insulationId) as InsulationLiningBase;
|
||||
baseTop = insulation.get_BoundingBox(null).Max.Z;
|
||||
baseBottom = insulation.get_BoundingBox(null).Min.Z;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var group in groups)
|
||||
{
|
||||
if (group.Key)
|
||||
{
|
||||
var sumHeight = 0.0;
|
||||
var vector = XYZ.BasisZ;
|
||||
for (var i = 0; i < group.Count(); i++)
|
||||
{
|
||||
var mep = group.ElementAt(i);
|
||||
var currentTop = mep.get_BoundingBox(null).Max.Z;
|
||||
var currentBottom = mep.get_BoundingBox(null).Min.Z;
|
||||
if (mep is Pipe or Duct)
|
||||
{
|
||||
//基准保温层厚度
|
||||
var insulationId = InsulationLiningBase.GetInsulationIds(
|
||||
doc,
|
||||
mep.Id).FirstOrDefault();
|
||||
if (insulationId != null)
|
||||
{
|
||||
var insulation = doc.GetElement(insulationId) as InsulationLiningBase;
|
||||
currentTop = insulation.get_BoundingBox(null).Max.Z;
|
||||
currentBottom = insulation.get_BoundingBox(null).Min.Z;
|
||||
}
|
||||
}
|
||||
//当前间距
|
||||
var dis = currentBottom - baseTop;
|
||||
var actualDis = (i + 1) * Gap / 304.8 + sumHeight;
|
||||
var translate = (actualDis - dis) * vector;
|
||||
ElementTransformUtils.MoveElement(doc, mep.Id, translate);
|
||||
//整体高度
|
||||
sumHeight += currentTop - currentBottom;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var sumHeight = 0.0;
|
||||
var vector = -XYZ.BasisZ;
|
||||
for (var i = group.Count() - 1; i >= 0; i--)
|
||||
{
|
||||
var mep = group.ElementAt(i);
|
||||
var currentTop = mep.get_BoundingBox(null).Max.Z;
|
||||
var currentBottom = mep.get_BoundingBox(null).Min.Z;
|
||||
if (mep is Pipe or Duct)
|
||||
{
|
||||
//基准保温层厚度
|
||||
var insulationId = InsulationLiningBase.GetInsulationIds(
|
||||
doc,
|
||||
mep.Id).FirstOrDefault();
|
||||
if (insulationId != null)
|
||||
{
|
||||
var insulation = doc.GetElement(insulationId) as InsulationLiningBase;
|
||||
currentTop = insulation.get_BoundingBox(null).Max.Z;
|
||||
currentBottom = insulation.get_BoundingBox(null).Min.Z;
|
||||
}
|
||||
}
|
||||
//当前间距
|
||||
var dis = baseBottom - currentTop;
|
||||
var actualDis = (group.Count() - i) * Gap / 304.8 + sumHeight;
|
||||
var translate = (actualDis - dis) * vector;
|
||||
ElementTransformUtils.MoveElement(doc, mep.Id, translate);
|
||||
//整体高度
|
||||
sumHeight += currentTop - currentBottom;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Autodesk.Revit.Exceptions.OperationCanceledException)
|
||||
{
|
||||
}
|
||||
},
|
||||
"整理管线");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public class ArrangeElement
|
||||
{
|
||||
public double ElementHeight => ElementToMove.get_BoundingBox(null).Max.Z - ElementToMove.get_BoundingBox(null).Min.Z;
|
||||
public Element ElementToMove { get; set; }
|
||||
|
||||
public BoundingBoxXYZ Box { get; set; }
|
||||
/// <summary>
|
||||
/// 与基准元素的间距及方向向量
|
||||
/// </summary>
|
||||
public XYZ HorizonDistanceVector { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,7 @@ internal class BloomConnectorCmd : ExternalCommand //根据连接件创建一根
|
||||
var elemIds = UiDocument.Selection.GetElementIds();
|
||||
if (elemIds.Count == 0)
|
||||
{
|
||||
var reference = UiDocument.Selection.PickObject(ObjectType.Element, new GenericFilter<FamilyInstance>(), "请选择族实例");
|
||||
var reference = UiDocument.Selection.PickObject(ObjectType.Element, new FuncFilter(e => e is FamilyInstance ins && ins.MEPModel.ConnectorManager != null), "请选择族实例");
|
||||
elemIds.Add(Document.GetElement(reference).Id);
|
||||
}
|
||||
|
||||
@@ -35,9 +35,9 @@ internal class BloomConnectorCmd : ExternalCommand //根据连接件创建一根
|
||||
var conduitTypeId = Document.OfClass<ConduitType>().FirstElementId();
|
||||
|
||||
var filteredElementCollector = Document.OfClass<DuctType>();
|
||||
var roundTypeId = ElementId.InvalidElementId;
|
||||
var rectangleTypeId = ElementId.InvalidElementId;
|
||||
var ovalTypeId = ElementId.InvalidElementId;
|
||||
var roundDuctTypeId = ElementId.InvalidElementId;
|
||||
var rectangleDuctTypeId = ElementId.InvalidElementId;
|
||||
var ovalDuctTypeId = ElementId.InvalidElementId;
|
||||
|
||||
foreach (var element2 in filteredElementCollector)
|
||||
{
|
||||
@@ -45,15 +45,15 @@ internal class BloomConnectorCmd : ExternalCommand //根据连接件创建一根
|
||||
|
||||
if (ductType.FamilyName == "圆形风管" || ductType.FamilyName.Contains("Round Duct"))
|
||||
{
|
||||
roundTypeId = ductType.Id;
|
||||
roundDuctTypeId = ductType.Id;
|
||||
}
|
||||
else if (ductType.FamilyName == "矩形风管" || ductType.FamilyName.Contains("Rectangular Duct"))
|
||||
{
|
||||
rectangleTypeId = ductType.Id;
|
||||
rectangleDuctTypeId = ductType.Id;
|
||||
}
|
||||
else if (ductType.FamilyName == "椭圆形风管" || ductType.FamilyName.Contains("Oval Duct"))
|
||||
{
|
||||
ovalTypeId = ductType.Id;
|
||||
ovalDuctTypeId = ductType.Id;
|
||||
}
|
||||
}
|
||||
var fabricationConfiguration = FabricationConfiguration.GetFabricationConfiguration(Document);
|
||||
@@ -63,6 +63,8 @@ internal class BloomConnectorCmd : ExternalCommand //根据连接件创建一根
|
||||
{
|
||||
continue;
|
||||
}
|
||||
CableTray referCabTray = null;
|
||||
Conduit referConduit = null;
|
||||
//拿到连接的管线的类型
|
||||
foreach (Connector conn in elem.GetConnectors())
|
||||
{
|
||||
@@ -84,13 +86,13 @@ internal class BloomConnectorCmd : ExternalCommand //根据连接件创建一根
|
||||
case ConnectorProfileType.Invalid:
|
||||
break;
|
||||
case ConnectorProfileType.Round:
|
||||
roundTypeId = connector.Owner.GetTypeId();
|
||||
roundDuctTypeId = connector.Owner.GetTypeId();
|
||||
break;
|
||||
case ConnectorProfileType.Rectangular:
|
||||
rectangleTypeId = connector.Owner.GetTypeId();
|
||||
rectangleDuctTypeId = connector.Owner.GetTypeId();
|
||||
break;
|
||||
case ConnectorProfileType.Oval:
|
||||
ovalTypeId = connector.Owner.GetTypeId();
|
||||
ovalDuctTypeId = connector.Owner.GetTypeId();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -100,10 +102,12 @@ internal class BloomConnectorCmd : ExternalCommand //根据连接件创建一根
|
||||
{
|
||||
if (connector.Owner is CableTray cableTray)
|
||||
{
|
||||
referCabTray = cableTray;
|
||||
cableTrayTypeId = cableTray.GetTypeId();
|
||||
}
|
||||
else if (connector.Owner is Conduit conduit)
|
||||
{
|
||||
referConduit = conduit;
|
||||
conduitTypeId = conduit.GetTypeId();
|
||||
}
|
||||
}
|
||||
@@ -239,7 +243,7 @@ internal class BloomConnectorCmd : ExternalCommand //根据连接件创建一根
|
||||
element = Duct.Create(
|
||||
Document,
|
||||
mechanicalSystem.Id,
|
||||
roundTypeId,
|
||||
roundDuctTypeId,
|
||||
levelId,
|
||||
origin,
|
||||
xyz2
|
||||
@@ -253,7 +257,7 @@ internal class BloomConnectorCmd : ExternalCommand //根据连接件创建一根
|
||||
element = Duct.Create(
|
||||
Document,
|
||||
mechanicalSystem.Id,
|
||||
rectangleTypeId,
|
||||
rectangleDuctTypeId,
|
||||
levelId,
|
||||
origin,
|
||||
xyz2
|
||||
@@ -264,7 +268,7 @@ internal class BloomConnectorCmd : ExternalCommand //根据连接件创建一根
|
||||
break;
|
||||
|
||||
case ConnectorProfileType.Oval:
|
||||
element = Duct.Create(Document, mechanicalSystem.Id, ovalTypeId, levelId, origin, xyz2);
|
||||
element = Duct.Create(Document, mechanicalSystem.Id, ovalDuctTypeId, levelId, origin, xyz2);
|
||||
Document.Regenerate();
|
||||
element.get_Parameter(BuiltInParameter.RBS_CURVE_WIDTH_PARAM).Set(connector.Width);
|
||||
element.get_Parameter(BuiltInParameter.RBS_CURVE_HEIGHT_PARAM).Set(connector.Height);
|
||||
@@ -274,7 +278,7 @@ internal class BloomConnectorCmd : ExternalCommand //根据连接件创建一根
|
||||
element = Duct.Create(
|
||||
Document,
|
||||
mechanicalSystem.Id,
|
||||
roundTypeId,
|
||||
roundDuctTypeId,
|
||||
levelId,
|
||||
origin,
|
||||
xyz2
|
||||
@@ -391,18 +395,18 @@ internal class BloomConnectorCmd : ExternalCommand //根据连接件创建一根
|
||||
break;
|
||||
//电力
|
||||
case Domain.DomainCableTrayConduit:
|
||||
if (cableTrayTypeId == ElementId.InvalidElementId)
|
||||
{
|
||||
cableTrayTypeId = new FilteredElementCollector(Document)
|
||||
.OfClass(typeof(CableTrayType))
|
||||
.FirstElementId();
|
||||
}
|
||||
if (conduitTypeId == ElementId.InvalidElementId)
|
||||
{
|
||||
conduitTypeId = new FilteredElementCollector(Document)
|
||||
.OfClass(typeof(ConduitType))
|
||||
.FirstElementId();
|
||||
}
|
||||
//if (cableTrayTypeId == ElementId.InvalidElementId)
|
||||
//{
|
||||
// cableTrayTypeId = new FilteredElementCollector(Document)
|
||||
// .OfClass(typeof(CableTrayType))
|
||||
// .FirstElementId();
|
||||
//}
|
||||
//if (conduitTypeId == ElementId.InvalidElementId)
|
||||
//{
|
||||
// conduitTypeId = new FilteredElementCollector(Document)
|
||||
// .OfClass(typeof(ConduitType))
|
||||
// .FirstElementId();
|
||||
//}
|
||||
|
||||
|
||||
//switch (connector.ElectricalSystemType)
|
||||
@@ -420,11 +424,27 @@ internal class BloomConnectorCmd : ExternalCommand //根据连接件创建一根
|
||||
|
||||
case ConnectorProfileType.Round:
|
||||
element = Conduit.Create(Document, conduitTypeId, origin, xyz2, levelId);
|
||||
element.get_Parameter(BuiltInParameter.RBS_CONDUIT_DIAMETER_PARAM).Set(connector.Radius * 2);
|
||||
if (referConduit != null)
|
||||
{
|
||||
var value = referConduit.get_Parameter(
|
||||
BuiltInParameter.RBS_CTC_SERVICE_TYPE)
|
||||
.AsString();
|
||||
element.get_Parameter(BuiltInParameter.RBS_CTC_SERVICE_TYPE).Set(value);
|
||||
}
|
||||
break;
|
||||
|
||||
case ConnectorProfileType.Rectangular:
|
||||
element = CableTray.Create(Document, cableTrayTypeId, origin, xyz2, levelId);
|
||||
|
||||
element.get_Parameter(BuiltInParameter.RBS_CABLETRAY_WIDTH_PARAM).Set(connector.Width);
|
||||
element.get_Parameter(BuiltInParameter.RBS_CABLETRAY_HEIGHT_PARAM).Set(connector.Height);
|
||||
if (referCabTray != null)
|
||||
{
|
||||
var value = referCabTray.get_Parameter(
|
||||
BuiltInParameter.RBS_CTC_SERVICE_TYPE)
|
||||
.AsString();
|
||||
element.get_Parameter(BuiltInParameter.RBS_CTC_SERVICE_TYPE).Set(value);
|
||||
}
|
||||
break;
|
||||
|
||||
case ConnectorProfileType.Oval:
|
||||
|
||||
@@ -63,7 +63,7 @@ public class BreakMEPCurveCmd : ExternalCommand
|
||||
//else
|
||||
//{
|
||||
// var second = mepCurve.BreakByPoint(breakPoint2);
|
||||
// //var mepCurve2 = Document.GetElement(second) as MEPCurve;
|
||||
// //var mepCurve2 = Document.GetElement(second) as ElementToMove;
|
||||
// var third = mepCurve.BreakByPoint(breakPoint1);
|
||||
// Document.Delete(third);
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ public class CableLayoutCmd : ExternalCommand
|
||||
Document.Invoke(
|
||||
_ =>
|
||||
{
|
||||
//Reference refer = UiDocument.Selection.PickObject(ObjectType.Element, new TypeSelectionFilter<CableTray>(), "请选择桥架");
|
||||
//Reference refer = UiDocument.Selection.PickObject(ObjectType.ElementToMove, new TypeSelectionFilter<CableTray>(), "请选择桥架");
|
||||
//var ct = UiDocument.Document.GetElement(refer) as CableTray;
|
||||
var refer = UiDocument.Selection.PickObject(ObjectType.Element, new GenericFilter<CableTray>(), "请选择需要敷设桥架");
|
||||
var ct = UiDocument.Document.GetElement(refer) as MEPCurve;
|
||||
|
||||
@@ -62,108 +62,121 @@ public partial class ClashResolveViewModel : ObservableObject
|
||||
doc.Invoke(
|
||||
ts =>
|
||||
{
|
||||
switch (LocationType)
|
||||
try
|
||||
{
|
||||
case LocationType.Manual:
|
||||
switch (LocationType)
|
||||
{
|
||||
case LocationType.Manual:
|
||||
|
||||
{
|
||||
var reference1 = uidoc.Selection.PickObject(
|
||||
ObjectType.PointOnElement,
|
||||
new FuncFilter(
|
||||
e =>
|
||||
e is MEPCurve mepCurve and not InsulationLiningBase
|
||||
&& mepCurve.GetLocCurve() is Line line
|
||||
&& !line.Direction.CrossProduct(XYZ.BasisZ).IsAlmostEqualTo(XYZ.Zero)
|
||||
),
|
||||
"请选择翻弯的管线上的点"
|
||||
);
|
||||
mepCurveToBend = doc.GetElement(reference1) as MEPCurve;
|
||||
|
||||
var reference2 = uidoc.Selection.PickObject(
|
||||
ObjectType.PointOnElement,
|
||||
new FuncFilter(e => e.Id == mepCurveToBend!.Id),
|
||||
"请选择另一个翻弯管线上的点或确定单侧翻弯的需要偏移一侧"
|
||||
);
|
||||
//两个断点,breakPoint1距离原直线起点近,反向时,交换值
|
||||
breakPoint1 = mepCurveToBend.GetLocCurve().Project(reference1.GlobalPoint).XYZPoint;
|
||||
breakPoint2 = mepCurveToBend.GetLocCurve().Project(reference2.GlobalPoint).XYZPoint;
|
||||
}
|
||||
break;
|
||||
case LocationType.Reference:
|
||||
|
||||
{
|
||||
var reference = uidoc.Selection.PickObject(
|
||||
ObjectType.Element,
|
||||
new FuncFilter(
|
||||
e =>
|
||||
e is MEPCurve mepCurve and not InsulationLiningBase
|
||||
&& mepCurve.GetLocCurve() is Line line
|
||||
&& !line.Direction.CrossProduct(XYZ.BasisZ).IsAlmostEqualTo(XYZ.Zero)
|
||||
),
|
||||
"请选择参照的管线"
|
||||
);
|
||||
//参考的管线定位
|
||||
var referenceMEPCurve = doc.GetElement(reference);
|
||||
var referenceLine = referenceMEPCurve.GetLocCurve() as Line;
|
||||
|
||||
var reference1 = uidoc.Selection.PickObject(
|
||||
ObjectType.PointOnElement,
|
||||
new FuncFilter(
|
||||
e =>
|
||||
e is MEPCurve mepCurve and not InsulationLiningBase
|
||||
&& mepCurve.GetLocCurve() is Line line
|
||||
&& !line.Direction.CrossProduct(XYZ.BasisZ).IsAlmostEqualTo(XYZ.Zero)
|
||||
&& e.Id != referenceMEPCurve!.Id
|
||||
),
|
||||
"请选择翻弯的管线或确定单侧翻弯的需要偏移一侧"
|
||||
);
|
||||
//翻弯的管线定位
|
||||
mepCurveToBend = doc.GetElement(reference1) as MEPCurve;
|
||||
var bendLine = mepCurveToBend.GetLocCurve() as Line;
|
||||
|
||||
var result = bendLine!.Intersect(referenceLine, out var array);
|
||||
|
||||
XYZ intersectPoint = default;
|
||||
switch (result)
|
||||
{
|
||||
case SetComparisonResult.Overlap:
|
||||
intersectPoint = array.get_Item(0).XYZPoint;
|
||||
break;
|
||||
case SetComparisonResult.Disjoint:
|
||||
{
|
||||
IList<ClosestPointsPairBetweenTwoCurves> points =
|
||||
[];
|
||||
bendLine.ComputeClosestPoints(referenceLine, true, true, false, out points);
|
||||
var point = points.FirstOrDefault()?.XYZPointOnFirstCurve;
|
||||
if (bendLine.IsInsideEx(point, 0.2))
|
||||
{
|
||||
intersectPoint = point;
|
||||
}
|
||||
var reference1 = uidoc.Selection.PickObject(
|
||||
ObjectType.PointOnElement,
|
||||
new FuncFilter(
|
||||
e =>
|
||||
e is MEPCurve mepCurve and not InsulationLiningBase
|
||||
&& mepCurve.GetLocCurve() is Line line
|
||||
&& !line.Direction.CrossProduct(XYZ.BasisZ).IsAlmostEqualTo(XYZ.Zero)
|
||||
),
|
||||
"请选择翻弯的管线上的点"
|
||||
);
|
||||
mepCurveToBend = doc.GetElement(reference1) as MEPCurve;
|
||||
if (mepCurveToBend.Pinned)
|
||||
{
|
||||
MessageBox.Show("错误", "请解锁图元");
|
||||
CanRunning = true;
|
||||
return;
|
||||
}
|
||||
var reference2 = uidoc.Selection.PickObject(
|
||||
ObjectType.PointOnElement,
|
||||
new FuncFilter(e => e.Id == mepCurveToBend!.Id),
|
||||
"请选择另一个翻弯管线上的点或确定单侧翻弯的需要偏移一侧"
|
||||
);
|
||||
//两个断点,breakPoint1距离原直线起点近,反向时,交换值
|
||||
breakPoint1 = mepCurveToBend.GetLocCurve().Project(reference1.GlobalPoint).XYZPoint;
|
||||
breakPoint2 = mepCurveToBend.GetLocCurve().Project(reference2.GlobalPoint).XYZPoint;
|
||||
}
|
||||
break;
|
||||
case LocationType.Reference:
|
||||
|
||||
{
|
||||
var reference = uidoc.Selection.PickObject(
|
||||
ObjectType.Element,
|
||||
new FuncFilter(
|
||||
e =>
|
||||
e is MEPCurve mepCurve and not InsulationLiningBase
|
||||
&& mepCurve.GetLocCurve() is Line line
|
||||
&& !line.Direction.CrossProduct(XYZ.BasisZ).IsAlmostEqualTo(XYZ.Zero)
|
||||
),
|
||||
"请选择参照的管线"
|
||||
);
|
||||
//参考的管线定位
|
||||
var referenceMEPCurve = doc.GetElement(reference);
|
||||
var referenceLine = referenceMEPCurve.GetLocCurve() as Line;
|
||||
|
||||
var reference1 = uidoc.Selection.PickObject(
|
||||
ObjectType.PointOnElement,
|
||||
new FuncFilter(
|
||||
e =>
|
||||
e is MEPCurve mepCurve and not InsulationLiningBase
|
||||
&& mepCurve.GetLocCurve() is Line line
|
||||
&& !line.Direction.CrossProduct(XYZ.BasisZ).IsAlmostEqualTo(XYZ.Zero)
|
||||
&& e.Id != referenceMEPCurve!.Id
|
||||
),
|
||||
"请选择翻弯的管线或确定单侧翻弯的需要偏移一侧"
|
||||
);
|
||||
//翻弯的管线定位
|
||||
mepCurveToBend = doc.GetElement(reference1) as MEPCurve;
|
||||
var bendLine = mepCurveToBend.GetLocCurve() as Line;
|
||||
|
||||
var result = bendLine!.Intersect(referenceLine, out var array);
|
||||
|
||||
XYZ intersectPoint = default;
|
||||
switch (result)
|
||||
{
|
||||
case SetComparisonResult.Overlap:
|
||||
intersectPoint = array.get_Item(0).XYZPoint;
|
||||
break;
|
||||
}
|
||||
}
|
||||
case SetComparisonResult.Disjoint:
|
||||
{
|
||||
IList<ClosestPointsPairBetweenTwoCurves> points =
|
||||
[];
|
||||
bendLine.ComputeClosestPoints(referenceLine, true, true, false, out points);
|
||||
var point = points.FirstOrDefault()?.XYZPointOnFirstCurve;
|
||||
if (bendLine.IsInsideEx(point, 0.2))
|
||||
{
|
||||
intersectPoint = point;
|
||||
}
|
||||
|
||||
breakPoint1 = intersectPoint - (bendLine.Direction * Offset / 304.8);
|
||||
breakPoint2 = intersectPoint + (bendLine.Direction * Offset / 304.8);
|
||||
if (
|
||||
reference1.GlobalPoint.DistanceTo(breakPoint1)
|
||||
< reference1.GlobalPoint.DistanceTo(breakPoint2)
|
||||
) //距离近的是breakpoint2
|
||||
{
|
||||
(breakPoint1, breakPoint2) = (breakPoint2, breakPoint1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
intersectPoint == default
|
||||
|| !bendLine.IsInsideEx(breakPoint1, 0.2)
|
||||
|| !bendLine.IsInsideEx(breakPoint2, 0.2)
|
||||
)
|
||||
{
|
||||
return;
|
||||
breakPoint1 = intersectPoint - (bendLine.Direction * Offset / 304.8);
|
||||
breakPoint2 = intersectPoint + (bendLine.Direction * Offset / 304.8);
|
||||
if (
|
||||
reference1.GlobalPoint.DistanceTo(breakPoint1)
|
||||
< reference1.GlobalPoint.DistanceTo(breakPoint2)
|
||||
) //距离近的是breakpoint2
|
||||
{
|
||||
(breakPoint1, breakPoint2) = (breakPoint2, breakPoint1);
|
||||
}
|
||||
|
||||
if (
|
||||
intersectPoint == default
|
||||
|| !bendLine.IsInsideEx(breakPoint1, 0.2)
|
||||
|| !bendLine.IsInsideEx(breakPoint2, 0.2)
|
||||
)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (Autodesk.Revit.Exceptions.OperationCanceledException)
|
||||
{
|
||||
CanRunning = true;
|
||||
return;
|
||||
}
|
||||
|
||||
var originBaseLine = mepCurveToBend.GetLocCurve() as Line;
|
||||
|
||||
@@ -5,6 +5,7 @@ using Autodesk.Revit.DB;
|
||||
using Autodesk.Revit.DB.Electrical;
|
||||
using Autodesk.Revit.DB.Mechanical;
|
||||
using Autodesk.Revit.DB.Plumbing;
|
||||
|
||||
using Nice3point.Revit.Toolkit.External;
|
||||
|
||||
|
||||
@@ -118,6 +119,8 @@ public class CorrectMEPCurveSlopeCmd : ExternalCommand
|
||||
case Duct:
|
||||
{
|
||||
var param = mepCurve.get_Parameter(BuiltInParameter.RBS_DUCT_SLOPE);
|
||||
var loc = mepCurve.GetLocCurve() as Line;
|
||||
|
||||
isError = param.HasValue && ((param.AsDouble() < 0.025 && param.AsDouble() > 0) || param.AsDouble() > 0.055); //坡度过大或过小时
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -126,8 +126,8 @@ public class HeadroomCheckCmd : ExternalCommand
|
||||
// if (inputMessage.DialogResult == true)
|
||||
// {
|
||||
// var elems = UiDocument.Selection
|
||||
// .PickElementsByRectangle(new FuncFilter(e => e is MEPCurve, (_, _) => true))
|
||||
// .OfType<MEPCurve>();
|
||||
// .PickElementsByRectangle(new FuncFilter(e => e is ElementToMove, (_, _) => true))
|
||||
// .OfType<ElementToMove>();
|
||||
// if (double.TryParse(inputMessage.InputContent, out var headroomValue))
|
||||
// {
|
||||
// CheckHeadroom(elems, headroomValue, 1000, 300);
|
||||
@@ -137,7 +137,7 @@ public class HeadroomCheckCmd : ExternalCommand
|
||||
// {
|
||||
// var elem = UiDocument.SelectObject<DirectShape>();
|
||||
// var clashFilter = new ElementIntersectsElementFilter(elem, false);
|
||||
// var elems = Document.OfCollector().WherePasses(clashFilter).OfType<MEPCurve>();
|
||||
// var elems = Document.OfCollector().WherePasses(clashFilter).OfType<ElementToMove>();
|
||||
// if (double.TryParse(inputMessage.InputContent, out var headroomValue))
|
||||
// {
|
||||
// CheckHeadroom(elems, headroomValue, 1000, 300);
|
||||
|
||||
58
Sai.RvKits/RvMEP/InsulationItem.cs
Normal file
58
Sai.RvKits/RvMEP/InsulationItem.cs
Normal file
@@ -0,0 +1,58 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml.Linq;
|
||||
|
||||
using Autodesk.Revit.DB.Mechanical;
|
||||
using Autodesk.Revit.DB.Plumbing;
|
||||
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
|
||||
using Sai.Toolkit.Mvvm.Attributes;
|
||||
|
||||
namespace Sai.RvKits.RvMEP;
|
||||
public partial class InsulationItem : ObservableValidator
|
||||
{
|
||||
[GreaterThan(nameof(MinDiameter))]
|
||||
[Range(15, 1000)]
|
||||
public double MaxDiameter
|
||||
{
|
||||
get => maxDiameter;
|
||||
set
|
||||
{
|
||||
SetProperty(ref maxDiameter, value, true);
|
||||
}
|
||||
}
|
||||
|
||||
private double maxDiameter;
|
||||
|
||||
[Range(0, 1000)]
|
||||
|
||||
public double MinDiameter
|
||||
{
|
||||
get => minDiameter;
|
||||
set
|
||||
{
|
||||
SetProperty(ref minDiameter, value, true);
|
||||
ValidateProperty(MaxDiameter, nameof(MaxDiameter));
|
||||
}
|
||||
}
|
||||
private double minDiameter;
|
||||
|
||||
[Required]
|
||||
[Range(10, 1000)]
|
||||
public double Thickness
|
||||
{
|
||||
get => thickness;
|
||||
set => SetProperty(ref thickness, value, true);
|
||||
}
|
||||
private double thickness;
|
||||
|
||||
[ObservableProperty]
|
||||
private PipeInsulationType pipeInsulationType;
|
||||
[ObservableProperty]
|
||||
private DuctInsulationType ductInsulationType;
|
||||
}
|
||||
@@ -11,185 +11,186 @@ namespace Sai.RvKits.RvMEP;
|
||||
[Regeneration(RegenerationOption.Manual)]
|
||||
public class MoveConnectCmd : ExternalCommand
|
||||
{
|
||||
public override void Execute()
|
||||
{
|
||||
Reference baseReference;
|
||||
Reference moveReference;
|
||||
try
|
||||
{
|
||||
FuncFilter filter =
|
||||
new(
|
||||
e =>
|
||||
((e is MEPCurve mep and not InsulationLiningBase) && mep.GetConnectors(true).Size > 0)
|
||||
|| (
|
||||
e is FamilyInstance instance
|
||||
&& instance.MEPModel.ConnectorManager != null
|
||||
&& instance.MEPModel.ConnectorManager.UnusedConnectors.Size > 0
|
||||
)
|
||||
);
|
||||
public override void Execute()
|
||||
{
|
||||
Reference baseReference;
|
||||
Reference moveReference;
|
||||
try
|
||||
{
|
||||
FuncFilter filter =
|
||||
new(
|
||||
e =>
|
||||
((e is MEPCurve mep and not InsulationLiningBase) && mep.GetConnectors(true).Size > 0)
|
||||
|| (
|
||||
e is FamilyInstance instance
|
||||
&& instance.MEPModel.ConnectorManager != null
|
||||
&& instance.MEPModel.ConnectorManager.UnusedConnectors.Size > 0
|
||||
)
|
||||
);
|
||||
|
||||
baseReference = UiDocument.Selection.PickObject(
|
||||
Autodesk.Revit.UI.Selection.ObjectType.Element,
|
||||
filter,
|
||||
"请选择基准的管线、管件、设备实例"
|
||||
);
|
||||
FuncFilter filter1 =
|
||||
new(
|
||||
e =>
|
||||
e.Id != baseReference.ElementId
|
||||
&& ((e is MEPCurve mep and not InsulationLiningBase) && mep.GetConnectors(true).Size > 0)
|
||||
|| (
|
||||
e is FamilyInstance instance
|
||||
&& instance.MEPModel.ConnectorManager != null
|
||||
&& instance.MEPModel.ConnectorManager.UnusedConnectors.Size > 0
|
||||
)
|
||||
);
|
||||
moveReference = UiDocument.Selection.PickObject(
|
||||
Autodesk.Revit.UI.Selection.ObjectType.Element,
|
||||
filter,
|
||||
baseReference = UiDocument.Selection.PickObject(
|
||||
Autodesk.Revit.UI.Selection.ObjectType.Element,
|
||||
filter,
|
||||
"请选择基准的管线、管件、设备实例"
|
||||
);
|
||||
FuncFilter filter1 =
|
||||
new(
|
||||
e =>
|
||||
e.Id != baseReference.ElementId
|
||||
&& ((e is MEPCurve mep and not InsulationLiningBase) && mep.GetConnectors(true).Size > 0)
|
||||
|| (
|
||||
e is FamilyInstance instance
|
||||
&& instance.MEPModel.ConnectorManager != null
|
||||
&& instance.MEPModel.ConnectorManager.UnusedConnectors.Size > 0
|
||||
&& instance.Id != baseReference.ElementId
|
||||
)
|
||||
);
|
||||
moveReference = UiDocument.Selection.PickObject(
|
||||
Autodesk.Revit.UI.Selection.ObjectType.Element,
|
||||
filter,
|
||||
"请选择需要移动连接的管线、管件、设备实例"
|
||||
);
|
||||
}
|
||||
catch (Autodesk.Revit.Exceptions.OperationCanceledException)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var baseElement = Document.GetElement(baseReference);
|
||||
var elementToMove = Document.GetElement(moveReference);
|
||||
var list = ConnectorAssist.GetNearestDomainConnectors(baseElement, elementToMove);
|
||||
if (list.Count != 2)
|
||||
{
|
||||
MessageBox.Show("缺少可连接的连接件", "提示");
|
||||
return;
|
||||
}
|
||||
Document.Invoke(
|
||||
_ =>
|
||||
{
|
||||
var conn1 = list[0];
|
||||
var conn2 = list.Last();
|
||||
//if (conn1.Domain != conn2.Domain)//类型不一样不能连接
|
||||
//{
|
||||
// return;
|
||||
//}
|
||||
var origin1 = conn1.Origin;
|
||||
var origin2 = conn2.Origin;
|
||||
var direction1 = conn1.CoordinateSystem.BasisZ;
|
||||
var direction2 = conn2.CoordinateSystem.BasisZ;
|
||||
//夹角
|
||||
var radian = Math.Acos(direction1.DotProduct(direction2));
|
||||
//都是管线,角度小于135,主次分支对齐连接,仅支持中心对齐
|
||||
if (
|
||||
baseElement is MEPCurve mainMEPCurve
|
||||
&& elementToMove is MEPCurve branchMEPCurve
|
||||
&& radian < 135.0.ToRadian()
|
||||
)
|
||||
{
|
||||
//if ((conn2.Shape == ConnectorProfileType.Oval || conn2.Shape == ConnectorProfileType.Rectangular))
|
||||
//{
|
||||
// var verticalJustification = mainMEPCurve.get_Parameter(BuiltInParameter.RBS_CURVE_VERT_OFFSET_PARAM);
|
||||
// var delta = XYZ.BasisZ * (branchMEPCurve.Height / 2 - mainMEPCurve.Height / 2);
|
||||
// //底部
|
||||
// if (verticalJustification.AsInteger() == 1)
|
||||
// {
|
||||
// origin2 -= delta;
|
||||
// }
|
||||
// //顶部
|
||||
// if (verticalJustification.AsInteger() == 2)
|
||||
// {
|
||||
// origin2 += delta;
|
||||
// }
|
||||
}
|
||||
catch (Autodesk.Revit.Exceptions.OperationCanceledException)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var baseElement = Document.GetElement(baseReference);
|
||||
var elementToMove = Document.GetElement(moveReference);
|
||||
var list = ConnectorAssist.GetNearestDomainConnectors(baseElement, elementToMove);
|
||||
if (list.Count != 2)
|
||||
{
|
||||
MessageBox.Show("缺少可连接的连接件", "提示");
|
||||
return;
|
||||
}
|
||||
Document.Invoke(
|
||||
_ =>
|
||||
{
|
||||
var conn1 = list[0];
|
||||
var conn2 = list.Last();
|
||||
//if (conn1.Domain != conn2.Domain)//类型不一样不能连接
|
||||
//{
|
||||
// return;
|
||||
//}
|
||||
var origin1 = conn1.Origin;
|
||||
var origin2 = conn2.Origin;
|
||||
var direction1 = conn1.CoordinateSystem.BasisZ;
|
||||
var direction2 = conn2.CoordinateSystem.BasisZ;
|
||||
//夹角
|
||||
var radian = Math.Acos(direction1.DotProduct(direction2));
|
||||
//都是管线,角度小于135,主次分支对齐连接,仅支持中心对齐
|
||||
if (
|
||||
baseElement is MEPCurve mainMEPCurve
|
||||
&& elementToMove is MEPCurve branchMEPCurve
|
||||
&& radian < 135.0.ToRadian()
|
||||
)
|
||||
{
|
||||
//if ((conn2.Shape == ConnectorProfileType.Oval || conn2.Shape == ConnectorProfileType.Rectangular))
|
||||
//{
|
||||
// var verticalJustification = mainMEPCurve.get_Parameter(BuiltInParameter.RBS_CURVE_VERT_OFFSET_PARAM);
|
||||
// var delta = XYZ.BasisZ * (branchMEPCurve.Height / 2 - mainMEPCurve.Height / 2);
|
||||
// //底部
|
||||
// if (verticalJustification.AsInteger() == 1)
|
||||
// {
|
||||
// origin2 -= delta;
|
||||
// }
|
||||
// //顶部
|
||||
// if (verticalJustification.AsInteger() == 2)
|
||||
// {
|
||||
// origin2 += delta;
|
||||
// }
|
||||
|
||||
//}
|
||||
//管线所在的垂直于xoy平面的面法向
|
||||
var normal = XYZ.BasisZ.CrossProduct(direction2);
|
||||
//如果是立管,则取不移动的管线的方向,过移动管线做平面
|
||||
if (normal.IsZeroLength())
|
||||
{
|
||||
normal = direction1;
|
||||
}
|
||||
//}
|
||||
//管线所在的垂直于xoy平面的面法向
|
||||
var normal = XYZ.BasisZ.CrossProduct(direction2);
|
||||
//如果是立管,则取不移动的管线的方向,过移动管线做平面
|
||||
if (normal.IsZeroLength())
|
||||
{
|
||||
normal = direction1;
|
||||
}
|
||||
|
||||
var plane = Plane.CreateByNormalAndOrigin(normal, origin2);
|
||||
//找到交点
|
||||
var intersectPoint = plane.IntersectPoint(Line.CreateUnbound(origin1, direction1));
|
||||
//不相交则直接移动
|
||||
if (intersectPoint == null)
|
||||
{
|
||||
ElementTransformUtils.MoveElement(Document, elementToMove!.Id, origin1 - origin2);
|
||||
}
|
||||
else
|
||||
{
|
||||
//避免交点在原管线外,导致反向连接
|
||||
if ((mainMEPCurve.GetLocCurve() as Line).IsInsideEx(intersectPoint, 0.5))
|
||||
{
|
||||
ElementTransformUtils.MoveElement(Document, elementToMove!.Id, intersectPoint - origin2);
|
||||
}
|
||||
else
|
||||
{
|
||||
ElementTransformUtils.MoveElement(Document, elementToMove!.Id, origin1 - origin2);
|
||||
}
|
||||
}
|
||||
mainMEPCurve.ConnectTo(branchMEPCurve);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (baseElement is MEPCurve baseMEPCurve && elementToMove is MEPCurve moveMEPCurve)
|
||||
{
|
||||
if (
|
||||
(
|
||||
conn2.Shape == ConnectorProfileType.Oval
|
||||
|| conn2.Shape == ConnectorProfileType.Rectangular
|
||||
)
|
||||
)
|
||||
{
|
||||
var verticalJustification = baseMEPCurve.get_Parameter(
|
||||
BuiltInParameter.RBS_CURVE_VERT_OFFSET_PARAM
|
||||
);
|
||||
var plane = Plane.CreateByNormalAndOrigin(normal, origin2);
|
||||
//找到交点
|
||||
var intersectPoint = plane.IntersectPoint(Line.CreateUnbound(origin1, direction1));
|
||||
//不相交则直接移动
|
||||
if (intersectPoint == null)
|
||||
{
|
||||
ElementTransformUtils.MoveElement(Document, elementToMove!.Id, origin1 - origin2);
|
||||
}
|
||||
else
|
||||
{
|
||||
//避免交点在原管线外,导致反向连接
|
||||
if ((mainMEPCurve.GetLocCurve() as Line).IsInsideEx(intersectPoint, 0.5))
|
||||
{
|
||||
ElementTransformUtils.MoveElement(Document, elementToMove!.Id, intersectPoint - origin2);
|
||||
}
|
||||
else
|
||||
{
|
||||
ElementTransformUtils.MoveElement(Document, elementToMove!.Id, origin1 - origin2);
|
||||
}
|
||||
}
|
||||
mainMEPCurve.ConnectTo(branchMEPCurve);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (baseElement is MEPCurve baseMEPCurve && elementToMove is MEPCurve moveMEPCurve)
|
||||
{
|
||||
if (
|
||||
(
|
||||
conn2.Shape == ConnectorProfileType.Oval
|
||||
|| conn2.Shape == ConnectorProfileType.Rectangular
|
||||
)
|
||||
)
|
||||
{
|
||||
var verticalJustification = baseMEPCurve.get_Parameter(
|
||||
BuiltInParameter.RBS_CURVE_VERT_OFFSET_PARAM
|
||||
);
|
||||
|
||||
var delta = XYZ.BasisZ * (baseMEPCurve.Height / 2 - moveMEPCurve.Height / 2);
|
||||
//底部
|
||||
if (verticalJustification.AsInteger() == 1)
|
||||
{
|
||||
origin2 += delta;
|
||||
}
|
||||
//顶部
|
||||
if (verticalJustification.AsInteger() == 2)
|
||||
{
|
||||
origin2 -= delta;
|
||||
}
|
||||
}
|
||||
}
|
||||
var xyz = origin1 - origin2;
|
||||
var delta = XYZ.BasisZ * (baseMEPCurve.Height / 2 - moveMEPCurve.Height / 2);
|
||||
//底部
|
||||
if (verticalJustification.AsInteger() == 1)
|
||||
{
|
||||
origin2 += delta;
|
||||
}
|
||||
//顶部
|
||||
if (verticalJustification.AsInteger() == 2)
|
||||
{
|
||||
origin2 -= delta;
|
||||
}
|
||||
}
|
||||
}
|
||||
var xyz = origin1 - origin2;
|
||||
|
||||
Document.InvokeSub(_ =>
|
||||
{
|
||||
if (!xyz.IsZeroLength())
|
||||
{
|
||||
ElementTransformUtils.MoveElement(Document, elementToMove!.Id, xyz);
|
||||
}
|
||||
});
|
||||
if (direction1.IsAlmostEqualTo(direction2.Negate())) //对齐
|
||||
{
|
||||
conn1.ConnectByFitting(conn2);
|
||||
}
|
||||
else
|
||||
{
|
||||
var xyz2 = direction1.CrossProduct(direction2); //旋转轴方向
|
||||
if (direction1.IsAlmostEqualTo(direction2))
|
||||
{
|
||||
xyz2 = conn1.CoordinateSystem.BasisY;
|
||||
}
|
||||
var line = Line.CreateUnbound(origin1, xyz2);
|
||||
var angle = direction1.AngleTo(direction2);
|
||||
//互补角
|
||||
var complementaryAngle = Math.PI - angle;
|
||||
Document.InvokeSub(_ =>
|
||||
{
|
||||
if (!xyz.IsZeroLength())
|
||||
{
|
||||
ElementTransformUtils.MoveElement(Document, elementToMove!.Id, xyz);
|
||||
}
|
||||
});
|
||||
if (direction1.IsAlmostEqualTo(direction2.Negate())) //对齐
|
||||
{
|
||||
conn1.ConnectByFitting(conn2);
|
||||
}
|
||||
else
|
||||
{
|
||||
var xyz2 = direction1.CrossProduct(direction2); //旋转轴方向
|
||||
if (direction1.IsAlmostEqualTo(direction2))
|
||||
{
|
||||
xyz2 = conn1.CoordinateSystem.BasisY;
|
||||
}
|
||||
var line = Line.CreateUnbound(origin1, xyz2);
|
||||
var angle = direction1.AngleTo(direction2);
|
||||
//互补角
|
||||
var complementaryAngle = Math.PI - angle;
|
||||
|
||||
ElementTransformUtils.RotateElement(Document, elementToMove!.Id, line, complementaryAngle);
|
||||
ElementTransformUtils.RotateElement(Document, elementToMove!.Id, line, complementaryAngle);
|
||||
|
||||
conn1.ConnectByFitting(conn2);
|
||||
}
|
||||
}
|
||||
},
|
||||
"移动连接"
|
||||
);
|
||||
}
|
||||
conn1.ConnectByFitting(conn2);
|
||||
}
|
||||
}
|
||||
},
|
||||
"移动连接"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user