Files
ShrlAlgoToolkit/ShrlAlgoToolkit.RevitAddins/Mep/MoveConnectCmd.cs

176 lines
7.2 KiB
C#
Raw Normal View History

2024-09-22 11:05:41 +08:00
using System.Windows;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Nice3point.Revit.Toolkit.External;
2026-02-22 20:03:42 +08:00
namespace ShrlAlgoToolkit.RevitAddins.Mep;
2024-09-22 11:05:41 +08:00
[Transaction(TransactionMode.Manual)]
public class MoveConnectCmd : ExternalCommand
{
public override void Execute()
{
Reference baseReference;
Reference moveReference;
try
{
baseReference = UiDocument.Selection.PickObject(
Autodesk.Revit.UI.Selection.ObjectType.Element,
2024-12-22 10:26:12 +08:00
new FuncFilter(e => e.GetConnectors(true)?.Size > 0),
"请选择基准的管线、管件、设备实例"
);
2024-12-22 10:26:12 +08:00
moveReference = UiDocument.Selection.PickObject(
Autodesk.Revit.UI.Selection.ObjectType.Element,
2024-12-22 10:26:12 +08:00
new FuncFilter(
e =>
e.Id != baseReference.ElementId
&& e.GetConnectors(true)?.Size > 0
),
2024-09-22 11:05:41 +08:00
"请选择需要移动连接的管线、管件、设备实例"
);
}
catch (Autodesk.Revit.Exceptions.OperationCanceledException)
{
return;
}
var baseElement = Document.GetElement(baseReference);
var elementToMove = Document.GetElement(moveReference);
2025-07-11 09:20:23 +08:00
var list = baseElement.GetNearestDomainConnectors(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;
// }
2024-09-22 11:05:41 +08:00
//}
//管线所在的垂直于xoy平面的面法向
var normal = XYZ.BasisZ.CrossProduct(direction2);
//如果是立管,则取不移动的管线的方向,过移动管线做平面
if (normal.IsZeroLength())
{
normal = direction1;
}
2024-09-22 11:05:41 +08:00
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
{
//避免交点在原管线外,导致反向连接
2024-12-22 10:26:12 +08:00
if ((mainMEPCurve.GetCurve() 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
);
2024-09-22 11:05:41 +08:00
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;
2024-09-22 11:05:41 +08:00
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;
2024-09-22 11:05:41 +08:00
ElementTransformUtils.RotateElement(Document, elementToMove!.Id, line, complementaryAngle);
2024-09-22 11:05:41 +08:00
conn1.ConnectByFitting(conn2);
}
}
},
"移动连接"
);
}
2024-09-22 11:05:41 +08:00
}