添加项目文件。
This commit is contained in:
195
Sai.RvKits/RvMEP/MoveConnectCmd.cs
Normal file
195
Sai.RvKits/RvMEP/MoveConnectCmd.cs
Normal file
@@ -0,0 +1,195 @@
|
||||
using System.Windows;
|
||||
|
||||
using Autodesk.Revit.Attributes;
|
||||
using Autodesk.Revit.DB;
|
||||
|
||||
using Nice3point.Revit.Toolkit.External;
|
||||
|
||||
namespace Sai.RvKits.RvMEP;
|
||||
|
||||
[Transaction(TransactionMode.Manual)]
|
||||
[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
|
||||
)
|
||||
);
|
||||
|
||||
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,
|
||||
"请选择需要移动连接的管线、管件、设备实例"
|
||||
);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
},
|
||||
"移动连接"
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user