Files
Shrlalgo.RvKits/ShrlAlgoToolkit.RevitAddins/RvMEP/AnyConnectViewModel.cs
ShrlAlgo 4d35cadb56 更新
2025-07-11 09:20:23 +08:00

1022 lines
62 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.ComponentModel.DataAnnotations;
using System.Diagnostics;
using System.Windows;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Mechanical;
using Autodesk.Revit.DB.Plumbing;
using Autodesk.Revit.UI.Selection;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Nice3point.Revit.Toolkit.External.Handlers;
namespace ShrlAlgoToolkit.RevitAddins.RvMEP;
public partial class AnyConnectViewModel : ObservableValidator
{
//#if REVIT2020
// public AnyConnectViewModel()
// {
// OptionsBarAssist.ShowOptionsBar();
// }
//#endif
private readonly ActionEventHandler anyConnectHandler = new();
[ObservableProperty]
private bool activeSnackbar;
[ObservableProperty]
private bool isMultiSelect = true;
[ObservableProperty]
[NotifyCanExecuteChangedFor(nameof(RevitAddins.RvMEP.AnyConnectViewModel.ConnectCommand))]
private bool canRunning = true;
[ObservableProperty]
[Range(0, 90)]
[NotifyDataErrorInfo]
private double angle = 90;
[ObservableProperty]
private WPFluent.Controls.InfoBar messageQueue = new();
[ObservableProperty]
private string message;
[RelayCommand]
private static void Closing()
{
KeyIntPtrHelper.RaiseEscTwice();
}
partial void OnIsMultiSelectChanged(bool value)
{
KeyIntPtrHelper.RaiseEscTwice();
}
[RelayCommand(CanExecute = nameof(RevitAddins.RvMEP.AnyConnectViewModel.CanRunning))]
private void Connect()
{
CanRunning = false;
anyConnectHandler.Raise(uiapp =>
{
var uidoc = uiapp.ActiveUIDocument;
var doc = uidoc.Document;
FuncFilter filter = new(e => e is MEPCurve and not InsulationLiningBase and not FlexDuct and not FlexPipe);
List<MEPCurve> list;
try
{
#if REVIT2018
list = IsMultiSelect
? uidoc.Selection
.PickObjects(ObjectType.Element, filter, "请选择管线并完成")
.Select(r => doc.GetElement(r))
.OfType<MEPCurve>()
.ToList()
: uidoc.Selection.PickElementsByRectangle(filter, "请框选管线").Cast<MEPCurve>().ToList();
#elif REVIT2020 || REVIT2025
list = uidoc.Selection
.PickObjects(ObjectType.Element, filter, "请选择管线并完成")
.Select(r => doc.GetElement(r))
.OfType<MEPCurve>()
.ToList();
#endif
var defaultType = list.FirstOrDefault()?.GetType();
if (list.Count < 2 || list.Any(t => defaultType != t.GetType()))
{
Message = "所选管线数量小于2或类别不同不允许连接";
CanRunning = true;
#if REVIT2020
OptionsBarAssist.HideOptionsBar();
#endif
return;
}
doc.Invoke(
ts =>
{
switch (list.Count)
{
case 2:
{
var originMEPCurve1 = list[0];
var originMEPCurve2 = list[1];
var line1 = originMEPCurve1.GetCurve() as Line;
var line2 = originMEPCurve2.GetCurve() as Line;
var unboundLine1 = originMEPCurve1.GetCurve() as Line;
var unboundLine2 = originMEPCurve2.GetCurve() as Line;
unboundLine1!.MakeUnbound();
unboundLine2!.MakeUnbound();
var isPerpendicular = line1.IsPerpendicularTo(line2);
var result = line1!.Intersect(line2, out var array);
MEPCurve mainMEPCurve;
MEPCurve branchMEPCurve;
var intersectionUnbound = unboundLine1.IntersectionPoint(unboundLine2);
switch (result)
{
case SetComparisonResult.Disjoint:
{
Debug.WriteLine("管线没有交点");
var intersection1 = line1.IntersectionPoint(unboundLine2);
var intersection2 = line2.IntersectionPoint(unboundLine1);
if (intersection1 == null && intersection2 != null)
{
branchMEPCurve = originMEPCurve1;
mainMEPCurve = originMEPCurve2;
Debug.WriteLine($"共面无交点:交点在第二条线上{mainMEPCurve.Id},为主管");
if (isPerpendicular && Angle is not 0 and not 90)
{
Debug.WriteLine("使用角度");
ConnectByAngle(mainMEPCurve, branchMEPCurve, intersection2, Angle);
}
else
{
mainMEPCurve.ConnectTo(branchMEPCurve);
}
break;
}
if (intersection1 != null && intersection2 == null)
{
mainMEPCurve = originMEPCurve1;
branchMEPCurve = originMEPCurve2;
Debug.WriteLine($"共面无交点:交点在第一条线上{mainMEPCurve.Id},为主管");
if (isPerpendicular && Angle is not 0 and not 90)
{
Debug.WriteLine("使用角度");
ConnectByAngle(mainMEPCurve, branchMEPCurve, intersection1, Angle);
}
else
{
mainMEPCurve.ConnectTo(branchMEPCurve);
}
break;
}
// ReSharper disable once ConditionIsAlwaysTrueOrFalse
if (
intersection1 == null
&& intersection2 == null
&& intersectionUnbound != null
)
{
Debug.WriteLine("共面无交点:两根线都延长才有交点,交叉成角");
var conn5 = originMEPCurve1
.GetConnectors()
.GetNearestConnector(intersectionUnbound);
var conn6 = originMEPCurve2
.GetConnectors()
.GetNearestConnector(intersectionUnbound);
var cos = conn5.CoordinateSystem.BasisZ.DotProduct(
conn6.CoordinateSystem.BasisZ
);
if (cos < -10E-8 || Math.Abs(cos) < 10E-8)
{
Debug.WriteLine("夹角大于等于90度,直接连接");
if (line1.Direction.IsAlmostEqualTo(XYZ.BasisZ))
{
mainMEPCurve = originMEPCurve1;
branchMEPCurve = originMEPCurve2;
}
else if (line2!.Direction.IsAlmostEqualTo(XYZ.BasisZ))
{
mainMEPCurve = originMEPCurve2;
branchMEPCurve = originMEPCurve1;
}
else if (line1.Length > line2!.Length)
{
mainMEPCurve = originMEPCurve1;
branchMEPCurve = originMEPCurve2;
}
else
{
mainMEPCurve = originMEPCurve2;
branchMEPCurve = originMEPCurve1;
}
if (isPerpendicular && Angle is not 0 and not 90)
{
Debug.WriteLine("使用角度");
ConnectByAngle(
mainMEPCurve,
branchMEPCurve,
intersectionUnbound,
Angle
);
}
else
{
var extendLine = line1.ExtendLine(intersectionUnbound);
originMEPCurve1.SetLocationCurve(extendLine);
var extendLine2 = line2.ExtendLine(intersectionUnbound);
originMEPCurve2.SetLocationCurve(extendLine2);
conn5.ConnectByFitting(conn6);
}
}
else
{
Debug.WriteLine($"夹角是锐角{Math.Acos(cos).ToDegree()}°,创建一条管线再连接");
var newMepCurveId = ElementTransformUtils
.CopyElement(doc, originMEPCurve1.Id, XYZ.Zero)
.FirstOrDefault();
var connectMEPCurve = doc.GetElement(newMepCurveId) as MEPCurve;
connectMEPCurve.SetLocationCurve(
Line.CreateBound(conn5.Origin, conn6.Origin)
);
var connectors = connectMEPCurve.GetConnectors().Cast<Connector>();
conn5.ConnectByFitting(connectors.ElementAt(0));
conn6.ConnectByFitting(connectors.ElementAt(1));
}
break;
}
if (line1.IsParallelTo(line2))
{
var c = line1.Intersect(unboundLine2); //第一个是第二个的SubSet子集
//var c1 = unboundLine1.Intersect(line2);//第一个是第二个的SuperSet超集
//距离最近的两个连接件
var originConnectors = originMEPCurve1.GetNearestConnectors(originMEPCurve2
);
if (c == SetComparisonResult.Subset)
{
Debug.WriteLine("共线平行");
originConnectors[0].ConnectByFitting(originConnectors[1]);
}
else
{
Debug.WriteLine("非共线平行");
//最近连接件距离太短时
var dis = originConnectors[0].Origin.DistanceTo(
originConnectors[1].Origin
);
if (dis < uiapp.Application.ShortCurveTolerance)
{
MessageBox.Show("连接处相距太近");
break;
}
var isOriginMEPCurve1Bigger = false;
//取小的管径,用于复制作为转弯管
switch (originConnectors[0].Shape)
{
case ConnectorProfileType.Round:
isOriginMEPCurve1Bigger = originMEPCurve1.Diameter > originMEPCurve2.Diameter;
break;
case ConnectorProfileType.Rectangular:
case ConnectorProfileType.Oval:
isOriginMEPCurve1Bigger =
originMEPCurve1.Width > originMEPCurve2.Width
|| originMEPCurve1.Height > originMEPCurve2.Height;
break;
}
var elementToCopy = isOriginMEPCurve1Bigger ? originMEPCurve2 : originMEPCurve1;
////原位复制
//var copyMepCurveId = ElementTransformUtils
// .CopyElement(doc, elementToCopy.Id, XYZ.Zero)
// .FirstOrDefault();
//var copyMepCurve = doc.GetElement(copyMepCurveId) as ElementToMove;
//取短的线作为旋转轴的基准点,保证能创建
var isFirstMEPCurveLengther = line1.Length < line2.Length;
var l = isFirstMEPCurveLengther ? Line.CreateBound(
originConnectors[0].Origin,
originConnectors[1].Origin
) : Line.CreateBound(
originConnectors[1].Origin,
originConnectors[0].Origin);
////取短的线作为旋转轴的基准点,保证能创建
//var origin = line1.Length < line2.Length
// ? originConnectors[0].Origin
// : originConnectors[1].Origin;
var copyMepCurve = elementToCopy.CopyAndSetLocationCurve(l);
doc.Regenerate();
var conns1 = originMEPCurve1.GetNearestConnectors(
copyMepCurve
);
var conns2 = originMEPCurve2.GetNearestConnectors(
copyMepCurve
);
//同向原管线和复制转弯管线的夹角一定是大于等于90度单位向量等价于余弦值
var cos = conns1[0].CoordinateSystem.BasisZ.DotProduct(
conns1[1].CoordinateSystem.BasisZ
);
//平行管可以垂直连接
if (Angle != 0)
{
Debug.WriteLine("修改角度");
var radian = Angle.ToRadian() - (Math.PI - Math.Acos(cos));
//侧向的轴,反向斜管的接口向量,使其为锐角
var direction = conns1[0].CoordinateSystem.BasisZ.CrossProduct(
-conns1[1].CoordinateSystem.BasisZ
);
var axis = Line.CreateUnbound(l.Origin, direction);
ElementTransformUtils.RotateElement(
doc,
copyMepCurve!.Id,
axis,
radian
);
}
if (cos < -10E-8 || Math.Abs(cos) < 10E-8)
{
Debug.WriteLine("夹角大于等于时90度");
//var angleUnboundLine = copyMepCurve.GetCurve().Clone();
//angleUnboundLine.MakeUnbound();
//if (!conns1[0].Origin.IsAlmostEqualTo(conns1[1].Origin))
//{
// var point = unboundLine1.IntersectionPoint(angleUnboundLine);
// var newOriginMEPCurve1 = line1.ExtendLine(point);
// originMEPCurve1.SetLocationCurve(newOriginMEPCurve1);
// //copyMepCurve.SetLocationCurve()
//}
//if (!conns2[0].Origin.IsAlmostEqualTo(conns2[1].Origin))
//{
// var point = unboundLine2.IntersectionPoint(angleUnboundLine);
// var newOriginMEPCurve2 = line2.ExtendLine(point);
// originMEPCurve2.SetLocationCurve(newOriginMEPCurve2);
//}
//doc.Regenerate();
conns1[0].ConnectByFitting(conns1[1]);
conns2[0].ConnectByFitting(conns2[1]);
}
else
{
ts.RollBack();
}
}
}
else
{
Debug.WriteLine("异面无交点");
var conn = originMEPCurve1
.GetConnectors()
.OfType<Connector>()
.FirstOrDefault();
if (line1.Distance(line2) > conn.GetExtensionLength())
{
//找到两条线都垂直的向量
var normal = line1.Direction.CrossProduct(line2!.Direction);
var p1 = originMEPCurve1.GetCurve().GetEndPoint(0);
//根据垂直向量,找到能投影到的同一平面
var plane = Plane.CreateByNormalAndOrigin(normal, p1);
//投影线
var newProjectLine = plane.ProjectOnto(
originMEPCurve2.GetCurve() as Line
);
//不动的线
var stableCurve = originMEPCurve1.GetCurve();
stableCurve.MakeUnbound();
newProjectLine.MakeUnbound();
//共面线关系
var comparisonResult = stableCurve.Intersect(
newProjectLine,
out var array2
);
if (comparisonResult == SetComparisonResult.Overlap)
{
Debug.WriteLine("非共面相交");
var intersectPoint1 = array2.get_Item(0).XYZPoint;
var intersectPoint2 = unboundLine2
.Project(intersectPoint1)
.XYZPoint;
if (
intersectPoint1.DistanceTo(intersectPoint2)
< uiapp.Application.ShortCurveTolerance
)
{
Debug.WriteLine("交点距离太近");
break;
}
var verticalLine = Line.CreateBound(
intersectPoint1,
intersectPoint2
);
var verticalMEPCurveId = ElementTransformUtils
.CopyElement(doc, originMEPCurve1.Id, XYZ.Zero)
.FirstOrDefault();
var verticalMEPCurve = doc.GetElement(verticalMEPCurveId);
verticalMEPCurve.SetLocationCurve(verticalLine);
if (
!line1.IsInsideEx(intersectPoint1)
&& !line2.IsInsideEx(intersectPoint2)
)
{
Debug.WriteLine("都不在直线内,直角连接");
var extendLine1 = (
originMEPCurve1.GetCurve() as Line
).ExtendLine(intersectPoint1);
originMEPCurve1.SetLocationCurve(extendLine1);
var extendLine2 = (
originMEPCurve2.GetCurve() as Line
).ExtendLine(intersectPoint2);
originMEPCurve2.SetLocationCurve(extendLine2);
var conn1 = originMEPCurve1
.GetConnectors()
.GetNearestConnector(intersectPoint1);
var conn2 = verticalMEPCurve
.GetConnectors()
.GetNearestConnector(intersectPoint1);
var conn3 = originMEPCurve2
.GetConnectors()
.GetNearestConnector(intersectPoint1);
var conn4 = verticalMEPCurve
.GetConnectors()
.GetNearestConnector(intersectPoint2);
conn1.ConnectByFitting(conn2);
conn3.ConnectByFitting(conn4);
break;
}
if (
line1.IsInsideEx(intersectPoint1, 0.5)
&& !line2.IsInsideEx(intersectPoint2, 0.1)
) //在直线一内,在直线二端点,生成一个三通,一个弯头
{
mainMEPCurve = originMEPCurve1;
branchMEPCurve = originMEPCurve2;
Debug.WriteLine($"在直线一{mainMEPCurve.Id}内,在直线一端点,生成一个三通,一个弯头");
var line = (branchMEPCurve.GetCurve() as Line).ExtendLine(
intersectPoint2
);
branchMEPCurve.SetLocationCurve(line);
ConnectBranchMEP(
intersectPoint2,
intersectPoint1,
verticalMEPCurve,
mainMEPCurve,
branchMEPCurve
);
break;
}
if (
!line1.IsInsideEx(intersectPoint1, 0.1)
&& line2.IsInsideEx(intersectPoint2, 0.5)
)
{
mainMEPCurve = originMEPCurve2;
branchMEPCurve = originMEPCurve1;
Debug.WriteLine($"在直线二内{mainMEPCurve.Id},在直线一端点,生成一个三通,一个弯头");
var line = (branchMEPCurve.GetCurve() as Line).ExtendLine(
intersectPoint1
);
branchMEPCurve.SetLocationCurve(line);
ConnectBranchMEP(
intersectPoint1,
intersectPoint2,
verticalMEPCurve,
mainMEPCurve,
branchMEPCurve
);
break;
}
if (
line1.IsInsideEx(intersectPoint1, 0.5)
&& line2.IsInsideEx(intersectPoint2, 0.5)
) //
{
Debug.WriteLine("都在直线范围内,生成两个三通");
var newMEP = doc.GetElement(
originMEPCurve1.BreakByPoint(intersectPoint1)
);
var newMEP2 = doc.GetElement(
originMEPCurve2.BreakByPoint(intersectPoint2)
);
//找到交点最近的连接件
var connector1 = originMEPCurve1
.GetConnectors()
.GetNearestConnector(intersectPoint1);
var connector2 = newMEP
.GetConnectors()
.GetNearestConnector(intersectPoint1);
var connector3 = verticalMEPCurve
.GetConnectors()
.GetNearestConnector(intersectPoint1);
var connector4 = originMEPCurve2
.GetConnectors()
.GetNearestConnector(intersectPoint2);
var connector5 = newMEP2
.GetConnectors()
.GetNearestConnector(intersectPoint2);
var connector6 = verticalMEPCurve
.GetConnectors()
.GetNearestConnector(intersectPoint2);
doc.Create.NewTeeFitting(connector1, connector2, connector3);
doc.Create.NewTeeFitting(connector4, connector5, connector6);
}
}
}
}
}
break;
case SetComparisonResult.Overlap:
{
Debug.WriteLine("共面相交");
var intersectPoint = array.get_Item(0).XYZPoint;
if (
line1.IsInsideEx(intersectPoint, 0.3)
&& line2.IsInsideEx(intersectPoint, 0.3)
) //
{
Debug.WriteLine("管线交叉");
doc.Regenerate();
var mepCurve1 =
doc.GetElement(originMEPCurve1.BreakByPoint(intersectPoint))
as MEPCurve;
var mepCurve2 =
doc.GetElement(originMEPCurve2.BreakByPoint(intersectPoint))
as MEPCurve;
var conn1 = mepCurve1!.ConnectorManager.Connectors.GetNearestConnector(
intersectPoint
);
var conn2 = mepCurve2!.ConnectorManager.Connectors.GetNearestConnector(
intersectPoint
);
var conn3 = originMEPCurve1.ConnectorManager.Connectors.GetNearestConnector(
intersectPoint
);
var conn4 = originMEPCurve2.ConnectorManager.Connectors.GetNearestConnector(
intersectPoint
);
try
{
doc.Create.NewCrossFitting(conn1, conn3, conn2, conn4);
}
catch (Autodesk.Revit.Exceptions.InvalidOperationException) { }
}
else if (
!line1.IsInsideEx(intersectPoint, 0.1)
&& line2.IsInsideEx(intersectPoint, 0.3)
)
{
Debug.WriteLine($"主({originMEPCurve2.Id})次分支");
if (isPerpendicular && Angle is not 0 and not 90)
{
Debug.WriteLine("使用角度");
ConnectByAngle(
originMEPCurve2,
originMEPCurve1,
intersectionUnbound,
Angle
);
}
else
{
originMEPCurve2.ConnectTo(originMEPCurve1);
}
}
else if (
line1.IsInsideEx(intersectPoint, 0.1)
&& !line2.IsInsideEx(intersectPoint, 0.3)
)
{
Debug.WriteLine($"主({originMEPCurve1.Id})次分支");
if (isPerpendicular && Angle is not 0 and not 90)
{
Debug.WriteLine("使用角度");
ConnectByAngle(
originMEPCurve1,
originMEPCurve2,
intersectionUnbound,
Angle
);
}
else
{
originMEPCurve1.ConnectTo(originMEPCurve2);
}
}
else
{
Debug.WriteLine("端点相交");
if (line1.Direction.IsAlmostEqualTo(XYZ.BasisZ))
{
mainMEPCurve = originMEPCurve1;
branchMEPCurve = originMEPCurve2;
}
else if (line2!.Direction.IsAlmostEqualTo(XYZ.BasisZ))
{
mainMEPCurve = originMEPCurve2;
branchMEPCurve = originMEPCurve1;
}
else if (line1.Length > line2!.Length)
{
mainMEPCurve = originMEPCurve1;
branchMEPCurve = originMEPCurve2;
}
else
{
mainMEPCurve = originMEPCurve2;
branchMEPCurve = originMEPCurve1;
}
if (isPerpendicular && Angle is not 0 and not 90)
{
Debug.WriteLine("使用角度");
ConnectByAngle(
mainMEPCurve,
branchMEPCurve,
intersectionUnbound,
Angle
);
}
else
{
originMEPCurve1.ConnectTo(originMEPCurve2);
}
}
}
break;
case SetComparisonResult.Subset:
case SetComparisonResult.Superset:
case SetComparisonResult.Equal:
Debug.WriteLine("共线,且只有一个交点,即两条有边界直线共线且首尾相连或者两条直线有重合部分");
MergeParallelMEPCurve(originMEPCurve1, originMEPCurve2);
break;
}
//List<Connector> conns4 = ConnectorAssist.GetNearestConnectors(originMEPCurve1, originMEPCurve2, true);
//conns4[0].ConnectByFitting(conns4[1], true);
break;
}
case 3:
{
var unboundLine1 = list[0].GetCurve();
var unboundLine2 = list[1].GetCurve();
var unboundLine3 = list[2].GetCurve();
//无边界保证相交
unboundLine1.MakeUnbound();
unboundLine2.MakeUnbound();
unboundLine3.MakeUnbound();
var result1 = unboundLine1.Intersect(unboundLine2, out var array1);
var result2 = unboundLine1.Intersect(unboundLine3, out var array2);
var result3 = unboundLine2.Intersect(unboundLine3, out var array3);
if (result1 == SetComparisonResult.Equal && result2 == SetComparisonResult.Overlap)
{
ConnectBy3MEPCurve(list[0], list[1], list[2], array2);
}
if (result2 == SetComparisonResult.Equal && result3 == SetComparisonResult.Overlap)
{
ConnectBy3MEPCurve(list[0], list[2], list[1], array3);
}
if (result3 == SetComparisonResult.Equal && result1 == SetComparisonResult.Overlap)
{
ConnectBy3MEPCurve(list[1], list[2], list[0], array1);
}
break;
}
case 4:
{
var unboundLine1 = list[0].GetCurve() as Line;
var unboundLine2 = list[1].GetCurve() as Line;
var unboundLine3 = list[2].GetCurve() as Line;
var unboundLine4 = list[3].GetCurve() as Line;
unboundLine1!.MakeUnbound();
unboundLine2!.MakeUnbound();
unboundLine3!.MakeUnbound();
unboundLine4!.MakeUnbound();
var result1 = unboundLine1.Intersect(unboundLine2, out var array1);
var result2 = unboundLine3.Intersect(unboundLine4);
var result3 = unboundLine1.Intersect(unboundLine3, out var array3);
var result4 = unboundLine2.Intersect(unboundLine4);
var result5 = unboundLine1.Intersect(unboundLine4);
var result6 = unboundLine2.Intersect(unboundLine3);
//保证垂直关系
if (
result1 == SetComparisonResult.Equal
&& result2 == SetComparisonResult.Equal
&& result3 == SetComparisonResult.Overlap
)
{
if (unboundLine1.IsPerpendicularTo(unboundLine3))
{
ConnectBy4MEPCurve(list[0], list[1], list[2], list[3], array3);
}
}
if (
result3 == SetComparisonResult.Equal
&& result4 == SetComparisonResult.Equal
&& result1 == SetComparisonResult.Overlap
)
{
if (unboundLine1.IsPerpendicularTo(unboundLine2))
{
ConnectBy4MEPCurve(list[0], list[2], list[1], list[3], array1);
}
}
if (
result5 == SetComparisonResult.Equal
&& result6 == SetComparisonResult.Equal
&& result1 == SetComparisonResult.Overlap
)
{
if (unboundLine1.IsPerpendicularTo(unboundLine2))
{
ConnectBy4MEPCurve(list[0], list[3], list[1], list[2], array1);
}
}
break;
}
}
#if REVIT2020
OptionsBarAssist.HideOptionsBar();
#endif
},
"任意连接"
);
}
catch (Autodesk.Revit.Exceptions.OperationCanceledException)
{
CanRunning = true;
#if REVIT2020
OptionsBarAssist.HideOptionsBar();
#endif
return;
}
catch (Exception)
{
CanRunning = true;
}
CanRunning = true;
});
}
/// <summary>
/// 连接异面两根管管
/// </summary>
/// <param name="intersectPoint1"></param>
/// <param name="intersectPoint2"></param>
/// <param name="verticalMEPCurve"></param>
/// <param name="mainMEPCurve"></param>
/// <param name="branchMEPCurve"></param>
private static void ConnectBranchMEP(
XYZ intersectPoint1,
XYZ intersectPoint2,
Element verticalMEPCurve,
MEPCurve mainMEPCurve,
MEPCurve branchMEPCurve
)
{
var doc = verticalMEPCurve.Document;
var mepId = mainMEPCurve.BreakByPoint(intersectPoint2);
var newMEP = doc.GetElement(mepId);
var conn = mainMEPCurve.GetConnectors().GetNearestConnector(intersectPoint2);
var conn2 = newMEP.GetConnectors().GetNearestConnector(intersectPoint2);
var conn3 = verticalMEPCurve.GetConnectors().GetNearestConnector(intersectPoint2);
var conn4 = verticalMEPCurve.GetConnectors().GetNearestConnector(intersectPoint1);
var conn5 = branchMEPCurve.GetConnectors().GetNearestConnector(intersectPoint1);
doc.Create.NewTeeFitting(conn, conn2, conn3);
conn4.ConnectByFitting(conn5);
}
/// <summary>
/// 三管连接
/// </summary>
/// <param name="originMEPCurve1">主管</param>
/// <param name="originMEPCurve2">主管</param>
/// <param name="originMEPCurve3">支管</param>
/// <param name="array"></param>
private static void ConnectBy3MEPCurve(
MEPCurve originMEPCurve1,
MEPCurve originMEPCurve2,
MEPCurve originMEPCurve3,
IntersectionResultArray array
)
{
var doc = originMEPCurve1.Document;
var intersection = array.get_Item(0).XYZPoint;
var line1 = originMEPCurve1.GetCurve() as Line;
var line2 = originMEPCurve2.GetCurve() as Line;
var line3 = originMEPCurve3.GetCurve() as Line;
var extendLine = line1.ExtendLine(intersection);
originMEPCurve1.SetLocationCurve(extendLine);
var extendLine2 = line2.ExtendLine(intersection);
originMEPCurve2.SetLocationCurve(extendLine2);
var conns = originMEPCurve1.GetNearestConnectors( originMEPCurve2);
if (line3.IsInsideEx(intersection, 0.5))
{
var newBranchId = originMEPCurve3.BreakByPoint(intersection);
var newBranchMEPCurve = doc.GetElement(newBranchId);
var conns2 = originMEPCurve3.GetNearestConnectors(newBranchMEPCurve);
doc.Create.NewCrossFitting(conns[0], conns[1], conns2[0], conns2[1]);
}
else
{
var extendLine3 = line3.ExtendLine(intersection);
originMEPCurve3.SetLocationCurve(extendLine3);
var conn = originMEPCurve3.GetConnectors(true).GetNearestConnector(intersection);
conn.ConnectByTee(conns[0], conns[1]);
}
}
/// <summary>
/// 四根管线连接
/// </summary>
/// <param name="originMEPCurve1"></param>
/// <param name="originMEPCurve2"></param>
/// <param name="originMEPCurve3"></param>
/// <param name="originMEPCurve4"></param>
/// <param name="array"></param>
private static void ConnectBy4MEPCurve(
MEPCurve originMEPCurve1,
MEPCurve originMEPCurve2,
MEPCurve originMEPCurve3,
MEPCurve originMEPCurve4,
IntersectionResultArray array
)
{
var doc = originMEPCurve1.Document;
var intersection = array.get_Item(0).XYZPoint;
var line = originMEPCurve1.GetCurve() as Line;
var line2 = originMEPCurve2.GetCurve() as Line;
var line3 = originMEPCurve3.GetCurve() as Line;
var line4 = originMEPCurve4.GetCurve() as Line;
var extendLine = line.ExtendLine(intersection);
originMEPCurve1.SetLocationCurve(extendLine);
var extendLine2 = line2.ExtendLine(intersection);
originMEPCurve2.SetLocationCurve(extendLine2);
var extendLine3 = line3.ExtendLine(intersection);
originMEPCurve3.SetLocationCurve(extendLine3);
var extendLine4 = line4.ExtendLine(intersection);
originMEPCurve4.SetLocationCurve(extendLine4);
var conns = originMEPCurve1.GetNearestConnectors(originMEPCurve2);
var conns2 = originMEPCurve3.GetNearestConnectors(originMEPCurve4);
//Debug.WriteLine(string.Format("{0}-{1}", originConnectors[0].Origin, originConnectors[0].CoordinateSystem.BasisZ));
//Debug.WriteLine(string.Format("{0}-{1}", originConnectors[1].Origin, originConnectors[1].CoordinateSystem.BasisZ));
//Debug.WriteLine(string.Format("{0}-{1}", conns2[0].Origin, conns2[0].CoordinateSystem.BasisZ));
//Debug.WriteLine(string.Format("{0}-{1}", conns2[1].Origin, conns2[1].CoordinateSystem.BasisZ));
doc.Create.NewCrossFitting(conns[0], conns[1], conns2[0], conns2[1]);
}
/// <summary>
/// 主分支角度连接
/// </summary>
/// <param name="mainMepCurve"></param>
/// <param name="branchMepCurve"></param>
/// <param name="intersection2">交点</param>
/// <param name="angle">角度</param>
private static void ConnectByAngle(MEPCurve mainMepCurve, MEPCurve branchMepCurve, XYZ intersection2, double angle)
{
var doc = mainMepCurve.Document;
var mainFarthestConnector = mainMepCurve.ConnectorManager.Connectors.GetFarthestConnector(intersection2); //获取距离交点远处的连接件
var branchNearestConnector = branchMepCurve.ConnectorManager.Connectors.GetNearestConnector(intersection2); //分支管距离主管最近的连接件
var extendLength = branchNearestConnector.GetExtensionLength();
if (branchNearestConnector.Origin.DistanceTo(intersection2) < 3 * extendLength)
{
var branchEndpoint =
branchNearestConnector.Origin - (branchNearestConnector.CoordinateSystem.BasisZ * extendLength);
var branchLine = (branchMepCurve.GetCurve() as Line).ExtendLine(branchEndpoint);
branchMepCurve.SetLocationCurve(branchLine);
}
doc.Regenerate();
var normal = branchNearestConnector.CoordinateSystem.BasisZ.CrossProduct(
mainFarthestConnector.CoordinateSystem.BasisZ
);
var axis = Line.CreateUnbound(branchNearestConnector.Origin, normal);
var angleLine = Line.CreateBound(intersection2, branchNearestConnector.Origin);
if (!angleLine.Direction.IsAlmostEqualTo((branchMepCurve.GetCurve() as Line)?.Direction))
{
angleLine = angleLine.CreateReversed() as Line;
}
var id = ElementTransformUtils.CopyElement(doc, branchMepCurve.Id, XYZ.Zero).FirstOrDefault();
var angleMepCurve = doc.GetElement(id) as MEPCurve;
angleMepCurve.SetLocationCurve(angleLine);
ElementTransformUtils.RotateElement(doc, angleMepCurve!.Id, axis, angle.ToRadian());
doc.Regenerate();
var unboundMainLine = mainMepCurve.GetCurve() as Line;
unboundMainLine!.MakeUnbound();
var unboundAngleLine = angleMepCurve.GetCurve() as Line;
unboundAngleLine!.MakeUnbound();
var mainEndpoint = unboundAngleLine.IntersectionPoint(unboundMainLine);
var mainLine = (mainMepCurve.GetCurve() as Line).ExtendLine(mainEndpoint);
mainMepCurve.SetLocationCurve(mainLine);
doc.Regenerate();
mainMepCurve.ConnectTo(angleMepCurve);
angleMepCurve.ConnectTo(branchMepCurve);
}
/// <summary>
/// 合并平行管线
/// </summary>
/// <param name="originMEPCurve1"></param>
/// <param name="originMEPCurve2"></param>
private static void MergeParallelMEPCurve(MEPCurve originMEPCurve1, MEPCurve originMEPCurve2)
{
var doc = originMEPCurve1.Document;
var conns = originMEPCurve1.GetFarthestConnectors(originMEPCurve2, false);
var flag = false;
//判断大小管
switch (conns[0].Shape)
{
case ConnectorProfileType.Round:
flag =
originMEPCurve1.Diameter > originMEPCurve2.Diameter
|| originMEPCurve1.GetCurve().Length > originMEPCurve2.GetCurve().Length;
break;
case ConnectorProfileType.Rectangular:
case ConnectorProfileType.Oval:
flag =
originMEPCurve1.Width > originMEPCurve2.Width
|| originMEPCurve1.Height > originMEPCurve2.Height
|| originMEPCurve1.GetCurve().Length > originMEPCurve2.GetCurve().Length;
break;
}
//保留
MEPCurve reserveMEPCurve;
MEPCurve removeMEPCurve;
if (flag)
{
reserveMEPCurve = originMEPCurve1;
removeMEPCurve = originMEPCurve2;
}
else
{
reserveMEPCurve = originMEPCurve2;
removeMEPCurve = originMEPCurve1;
}
List<Connector> connsConnected = [];
//Dictionary<Connector, Connector> dict = new ();
foreach (var item in conns)
{
if (item.GetConnectedConnector() != null)
{
connsConnected.Add(item.GetConnectedConnector());
}
}
var loc = reserveMEPCurve.Location as LocationCurve;
var locLine = loc!.Curve as Line;
var newLocLine = Line.CreateBound(conns[0].Origin, conns[1].Origin);
//判断方向
loc.Curve = locLine!.Direction.IsAlmostEqualTo(newLocLine.Direction) ? newLocLine : newLocLine.CreateReversed();
//删除短管,先删除才好后续连接
doc.Delete(removeMEPCurve.Id);
doc.Regenerate();
foreach (var connConnected in connsConnected)
{
//keyValuePair.Key.ConnectByFitting(keyValuePair.Value, false);
foreach (Connector conn in reserveMEPCurve.GetConnectors(true))
{
if (
conn.Origin.IsAlmostEqualTo(connConnected.Origin)
&& conn.CoordinateSystem.BasisZ.IsAlmostEqualTo(connConnected.CoordinateSystem.BasisZ.Negate())
)
{
conn.ConnectByFitting(connConnected);
}
}
}
}
partial void OnMessageChanged(string value)
{
ActiveSnackbar = true;
Thread.Sleep(2_000);
ActiveSnackbar = false;
//MessageQueue.Enqueue(value, null, null, null, false, true, TimeSpan.FromSeconds(2));
}
}