管道两点翻弯并于原管件保持连接
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Electrical;
using Autodesk.Revit.DB.Mechanical;
using Autodesk.Revit.DB.Plumbing;
using Autodesk.Revit.UI;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ClassLibrary11
{
/// <summary>
/// 管道翻绕简单案例
/// 1-选取两个翻弯的点
/// 2-管道与弯头等断开连接
/// 3-创建5跟新的管道
/// 4-删除原管道
/// 5-新管道连接弯头
/// </summary>
[Transaction(TransactionMode.Manual)]
[Regeneration(RegenerationOption.Manual)]
[Journaling(JournalingMode.NoCommandData)]
internal class Class11 : IExternalCommand
{
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
UIDocument uIDocument = commandData.Application.ActiveUIDocument;
Document revitDoc = uIDocument.Document;
Reference reference1 = uIDocument.Selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.PointOnElement, "选择第一个翻弯点");
XYZ refPoint1 = reference1.GlobalPoint;
Pipe pipe = revitDoc.GetElement(reference1) as Pipe;
Line line = (pipe.Location as LocationCurve).Curve as Line;
line.MakeUnbound();
XYZ Point1 = line.Project(refPoint1).XYZPoint;//上面的点是管道表面的点,需要投影到管道中心定位线上
Reference reference2 = uIDocument.Selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.PointOnElement, "选择第二个翻弯点");
XYZ refPoint2 = reference2.GlobalPoint;
XYZ Point2 = line.Project(refPoint2).XYZPoint;
XYZ startPoint = (pipe.Location as LocationCurve).Curve.GetEndPoint(0);
XYZ endPoint = (pipe.Location as LocationCurve).Curve.GetEndPoint(1);
XYZ line1point = NearPoint(Point1, startPoint, endPoint);
XYZ line2point = NearPoint(Point2, endPoint, startPoint);
Connector pipeConStart = GetConnectorAtPoint(pipe, line1point);
Connector pipeConEnd = GetConnectorAtPoint(pipe, line2point);
Connector fittingConStart = GetConToConctor(pipeConStart);
Connector fittingConEnd = GetConToConctor(pipeConEnd);
double h = 500;//翻弯高度,管中心距高度
//ConnectorSet connectors = pipe.ConnectorManager.Connectors;
using (Transaction tr = new Transaction(revitDoc, "fq"))
{
tr.Start();
//原管线断开连接,如果管线两端有接头或者连接其他族,则断开连接
//foreach (Connector item in connectors)
//{
// if (item.IsConnected==true)
// {
// ConnectorSet connectorSet = item.AllRefs;
// ConnectorSetIterator csChild = connectorSet.ForwardIterator();
// while (csChild.MoveNext())
// {
// Connector csChildCon = csChild.Current as Connector;
// csChildCon.DisconnectFrom(item);
// }
// }
//}
//断开连接
if (fittingConStart != null) pipeConStart.DisconnectFrom(fittingConStart);
if (fittingConEnd != null) pipeConEnd.DisconnectFrom(fittingConEnd);
Line line1 = Line.CreateBound(Point1, line1point);
Line line2 = Line.CreateBound(Point1, new XYZ(Point1.X, Point1.Y, Point1.Z + h / 304.8));
Line line3 = Line.CreateBound(new XYZ(Point1.X, Point1.Y, Point1.Z + h / 304.8), new XYZ(Point2.X, Point2.Y, Point2.Z + h / 304.8));
Line line4 = Line.CreateBound(Point2, new XYZ(Point2.X, Point2.Y, Point2.Z + h / 304.8));
Line line5 = Line.CreateBound(Point2, line2point);
Pipe newpipe1 = revitDoc.GetElement(ElementTransformUtils.CopyElement(revitDoc, pipe.Id, new XYZ(0, 0, 0)).FirstOrDefault()) as Pipe;
Pipe newpipe2 = revitDoc.GetElement(ElementTransformUtils.CopyElement(revitDoc, pipe.Id, new XYZ(0, 0, 0)).FirstOrDefault()) as Pipe;
Pipe newpipe3 = revitDoc.GetElement(ElementTransformUtils.CopyElement(revitDoc, pipe.Id, new XYZ(0, 0, 0)).FirstOrDefault()) as Pipe;
Pipe newpipe4 = revitDoc.GetElement(ElementTransformUtils.CopyElement(revitDoc, pipe.Id, new XYZ(0, 0, 0)).FirstOrDefault()) as Pipe;
Pipe newpipe5 = revitDoc.GetElement(ElementTransformUtils.CopyElement(revitDoc, pipe.Id, new XYZ(0, 0, 0)).FirstOrDefault()) as Pipe;
(newpipe1.Location as LocationCurve).Curve = line1;
(newpipe2.Location as LocationCurve).Curve = line2;
(newpipe3.Location as LocationCurve).Curve = line3;
(newpipe4.Location as LocationCurve).Curve = line4;
(newpipe5.Location as LocationCurve).Curve = line5;
TwoMEPCurveCeateElbow(revitDoc, newpipe1, newpipe2);
TwoMEPCurveCeateElbow(revitDoc, newpipe2, newpipe3);
TwoMEPCurveCeateElbow(revitDoc, newpipe3, newpipe4);
TwoMEPCurveCeateElbow(revitDoc, newpipe4, newpipe5);
revitDoc.Delete(pipe.Id);//删除原管线
//新管线连接弯头
Connector newPipeStartCon = GetConnectorAtPoint(newpipe1, line1point);
Connector newPipeEndCon = GetConnectorAtPoint(newpipe5, line2point);
if (fittingConStart != null) newPipeStartCon.ConnectTo(fittingConStart);
if (fittingConEnd != null) newPipeEndCon.ConnectTo(fittingConEnd);
tr.Commit();
}
return Result.Succeeded;
}
private Connector GetConnectorAtPoint(Element ele, XYZ point)
{
ConnectorSet connectorSet = null;
if (ele is Duct)
connectorSet = (ele as Duct).ConnectorManager.Connectors;
//管线连接件集合
if (ele is Pipe)
connectorSet = (ele as Pipe).ConnectorManager.Connectors;
//桥架的连接件集合
if (ele is CableTray)
connectorSet = (ele as CableTray).ConnectorManager.Connectors;
//管件等可载入族的连接件集合
if (ele is FamilyInstance)
{
FamilyInstance fi = ele as FamilyInstance;
connectorSet = fi.MEPModel.ConnectorManager.Connectors;
}
//遍历连接件集合
foreach (Connector connector in connectorSet)
{
//如果连接件的中心和目标点相距很小时视为目标连接件
if (connector.Origin.DistanceTo(point) < 1 / 304.8)
//返回该连接件
return connector;
}
//如果没有匹配到,则返回null
return null;
}
public Connector GetConToConctor(Connector connector)
{
foreach (Connector con in connector.AllRefs)
{
//仅选择管件
if (con.Owner is FamilyInstance)
{
return con;
}
}
return null;
}
public XYZ NearPoint(XYZ pickPoint, XYZ firstPoint, XYZ secondPoint)
{
if (firstPoint.DistanceTo(pickPoint) > secondPoint.DistanceTo(pickPoint))
{
return secondPoint;
}
else
{
return firstPoint;
}
}
public void TwoMEPCurveCeateElbow(Document doc, MEPCurve curve1, MEPCurve curve2)
{
double distance = double.MaxValue;
Connector connector1 = null, connector2 = null;
foreach (Connector item1 in curve1.ConnectorManager.Connectors)
{
foreach (Connector item2 in curve2.ConnectorManager.Connectors)
{
double d = item1.Origin.DistanceTo(item2.Origin);
if (d < distance)
{
distance = d;
connector1 = item1;
connector2 = item2;
}
}
}
if (connector1 != null && connector2 != null)
{
doc.Create.NewElbowFitting(connector1, connector2);
}
}
}
}