176 lines
7.2 KiB
C#
176 lines
7.2 KiB
C#
using System.Windows;
|
||
using Autodesk.Revit.Attributes;
|
||
using Autodesk.Revit.DB;
|
||
using Nice3point.Revit.Toolkit.External;
|
||
|
||
namespace ShrlAlgoToolkit.RevitAddins.Mep;
|
||
|
||
[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,
|
||
new FuncFilter(e => e.GetConnectors(true)?.Size > 0),
|
||
"请选择基准的管线、管件、设备实例"
|
||
);
|
||
|
||
moveReference = UiDocument.Selection.PickObject(
|
||
Autodesk.Revit.UI.Selection.ObjectType.Element,
|
||
new FuncFilter(
|
||
e =>
|
||
e.Id != baseReference.ElementId
|
||
&& e.GetConnectors(true)?.Size > 0
|
||
),
|
||
"请选择需要移动连接的管线、管件、设备实例"
|
||
);
|
||
}
|
||
catch (Autodesk.Revit.Exceptions.OperationCanceledException)
|
||
{
|
||
return;
|
||
}
|
||
var baseElement = Document.GetElement(baseReference);
|
||
var elementToMove = Document.GetElement(moveReference);
|
||
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;
|
||
// }
|
||
|
||
//}
|
||
//管线所在的垂直于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.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
|
||
);
|
||
|
||
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;
|
||
|
||
ElementTransformUtils.RotateElement(Document, elementToMove!.Id, line, complementaryAngle);
|
||
|
||
conn1.ConnectByFitting(conn2);
|
||
}
|
||
}
|
||
},
|
||
"移动连接"
|
||
);
|
||
}
|
||
}
|