1.交互选择两根管道(先选主管,后选择支管)
2.获取主管在支管上的投影点
3.获取支管在主管上的投影点
4.两个投影点相连,获取新的管道(即竖向管道)
5.生成弯头,生成三通
其中需要获取最近的两个或者三个连接器,再生成管件。
最终效果
实现代码如下(有待优化生成带有坡度的新支管)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB.Architecture;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using Autodesk.Revit.DB.Plumbing;
namespace Test
{
[Transaction(TransactionMode.Manual)]
public class TestCommand : IExternalCommand
{
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
UIDocument Uidoc = commandData.Application.ActiveUIDocument;
Document Doc = Uidoc.Document;
Reference pipe1refer = Uidoc.Selection.PickObject(ObjectType.Element, new PipeFilter());
Reference pipe2refer = Uidoc.Selection.PickObject(ObjectType.Element, new PipeFilter());
Pipe pipe1 = Doc.GetElement(pipe1refer) as Pipe;
Pipe pipe2 = Doc.GetElement(pipe2refer) as Pipe;
//获取管道定位直线
Line Pipe1Line = (pipe1.Location as LocationCurve).Curve as Line;
Line Pipe2Line = (pipe2.Location as LocationCurve).Curve as Line;
//支管在主管上的投影点
XYZ line2endpointproject = Pipe1Line.Project(Pipe2Line.GetEndPoint(0)).XYZPoint;
XYZ point1 = Pipe2Line.GetEndPoint(1);
//让支管变成无限延伸的直线
Pipe2Line.MakeUnbound();
//主管在支管投影点
XYZ projectpoint = Pipe2Line.Project(line2endpointproject).XYZPoint;
Transaction transaction = new Transaction(Doc, "shiwu");
transaction.Start("shiwu");
//创建竖向新管道
Pipe NewPipe = Doc.GetElement(ElementTransformUtils.CopyElement(Doc, pipe1.Id, new XYZ(0, 0, 0)).FirstOrDefault()) as Pipe;
(NewPipe.Location as LocationCurve).Curve = Line.CreateBound(line2endpointproject, projectpoint);
//支管与新管生成弯头
ConnectTwopipesWithElbow(Doc, NewPipe as MEPCurve,pipe2 as MEPCurve);
//主管与新管生成三通
MEPCurve mEPCurve3 =Doc.GetElement(PlumbingUtils.BreakCurve(Doc, pipe1.Id, line2endpointproject)) as MEPCurve;
ConnectTwopipesWithElbow(Doc,mEPCurve3,pipe1 as MEPCurve, NewPipe as MEPCurve);
transaction.Commit();
return Result.Succeeded;
}
//限制选择
public class PipeFilter : ISelectionFilter
{
public bool AllowElement(Element elem)
{
if (elem is Pipe)
{
return true;
}
return false;
}
public bool AllowReference(Reference reference, XYZ position)
{
return true;
}
}
//生成弯头
public static void ConnectTwopipesWithElbow(Document doc, MEPCurve pipe1, MEPCurve pipe2)
{
double minDistance = double.MaxValue;
Connector connector1, connector2;
connector1 = connector2 = null;
foreach (Connector con1 in pipe1.ConnectorManager.Connectors)
{
foreach (Connector con2 in pipe2.ConnectorManager.Connectors)
{
var dis = con1.Origin.DistanceTo(con2.Origin);
if (dis < minDistance)
{
minDistance = dis;
connector1 = con1;
connector2 = con2;
}
}
}
if (connector1 != null && connector2 != null)
{
var elbow = doc.Create.NewElbowFitting(connector1, connector2);
}
}
//生成三通
public static void ConnectTwopipesWithElbow(Document doc, MEPCurve pipe1, MEPCurve pipe2, MEPCurve pipe3)
{
double minDistance = double.MaxValue;
Connector connector1, connector2, connector3;
connector1 = connector2 = connector3 = null;
foreach (Connector con1 in pipe1.ConnectorManager.Connectors)
{
foreach (Connector con2 in pipe2.ConnectorManager.Connectors)
{
var dis = con1.Origin.DistanceTo(con2.Origin);
if (dis < minDistance)
{
minDistance = dis;
connector1 = con1;
connector2 = con2;
}
}
}
minDistance = double.MaxValue;
foreach (Connector con3 in pipe3.ConnectorManager.Connectors)
{
var dis = con3.Origin.DistanceTo(connector1.Origin);
if (dis < minDistance)
{
minDistance = dis;
connector3 = con3;
}
}
if (connector1 != null && connector2 != null && connector3 != null)
{
var elbow = doc.Create.NewTeeFitting(connector1, connector2, connector3);
}
}
}
}