基于前面管道的打断功能改进,之前的管道打断后不能保证打断后 管道能够保证打断前的连接关系。
代码实现如下
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 Autodesk.Revit.UI.Selection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Test
{
class MainCommand : IExternalEventHandler
{
//KeyValuePair<int, int> info=new KeyValuePair<int, int>();
public MainWindow MainWindow = new MainWindow();
public void Execute(UIApplication app)
{
UIDocument UIDoc = app.ActiveUIDocument;
Commamd(UIDoc);
}
private void Commamd(UIDocument UIDoc)
{
try
{
while (true)
{
Document Doc = UIDoc.Document;
Selection selection = UIDoc.Selection;
Reference refer = selection.PickObject(ObjectType.PointOnElement, new MEPFilter());
MEPCurve mepCurve = Doc.GetElement(refer) as MEPCurve;
XYZ point = refer.GlobalPoint;
//原来管道定位线
LocationCurve locationCurve = mepCurve.Location as LocationCurve;
//投影点
XYZ PickPointPro = locationCurve.Curve.Project(point).XYZPoint;
//原来管道两个端点
XYZ startPoint = locationCurve.Curve.GetEndPoint(0);
XYZ endPoint = locationCurve.Curve.GetEndPoint(1);
//复制的新管道位置
Line LineOne = Line.CreateBound(startPoint, PickPointPro);
Line LineTwo = Line.CreateBound(endPoint, PickPointPro);
if (MainWindow.gap.IsChecked == true)
{
XYZ one = (startPoint - PickPointPro).Normalize() * ToFEET(double.Parse(MainWindow.gapvalue.Text)) / 2 + PickPointPro;
XYZ two = (endPoint - PickPointPro).Normalize() * ToFEET(double.Parse(MainWindow.gapvalue.Text)) / 2 + PickPointPro;
LineOne = Line.CreateBound(startPoint, one);
LineTwo = Line.CreateBound(endPoint, two);
}
Transaction transaction = new Transaction(Doc, "打断管道");
transaction.Start();
//复制两个管道
ElementId mepcurveid = Doc.GetElement(refer).Id;
MEPCurve mEPCurveone = CopyMEPCurve(Doc, mepcurveid, LineOne);
MEPCurve mEPCurvetwo = CopyMEPCurve(Doc, mepcurveid, LineTwo);
//原管道所有的连接器
ConnectorSet connectorSet = mepCurve.ConnectorManager.Connectors;
//找出连接器中有连接的连接器
foreach (Connector con in connectorSet)
{
if (con.IsConnected == true)
{
//找出与原管道连接的连接器
ConnectorSet ConnectedCons = con.AllRefs;
foreach (Connector connector in ConnectedCons)
{
//排除非自身连接器
bool conself = connector.Owner.UniqueId.Equals(con.Owner.UniqueId);
if (!conself)
{
//找出与原来管道连接的连接器距离最近的连接器
Connector willcon = FindNearCon(connector, mEPCurveone, mEPCurvetwo);
connector.ConnectTo(willcon);
}
}
}
}
//删除原来的管道
Doc.Delete(Doc.GetElement(refer).Id);
transaction.Commit();
}
}
catch (Exception e)
{
MainWindow.Close();
}
}
private double ToFEET(double v)
{
return UnitUtils.Convert(v, DisplayUnitType.DUT_MILLIMETERS, DisplayUnitType.DUT_DECIMAL_FEET);
}
/// <summary>
/// 复制MEPCurve
/// </summary>
/// <param name="doc">document</param>
/// <param name="id">需要复制的构件ElementId</param>
/// <param name="curve">复制到的位置</param>
/// <returns></returns>
private MEPCurve CopyMEPCurve(Document doc, ElementId id, Curve curve)
{
MEPCurve mEPCurve = doc.GetElement(ElementTransformUtils.CopyElement(doc, id, new XYZ()).FirstOrDefault()) as MEPCurve;
LocationCurve locationCurve = mEPCurve.Location as LocationCurve;
locationCurve.Curve = curve;
return mEPCurve;
}
private Connector FindNearCon(Connector connector, MEPCurve mEPCurveone, MEPCurve mEPCurvetwo)
{
Connector willcon = null;
ConnectorSet connectorSet = new ConnectorSet();
foreach (Connector con in mEPCurveone.ConnectorManager.Connectors)
{
connectorSet.Insert(con);
}
foreach (Connector con in mEPCurvetwo.ConnectorManager.Connectors)
{
connectorSet.Insert(con);
}
double Mindistance = double.MaxValue;
foreach (Connector con in connectorSet)
{
double distance = connector.Origin.DistanceTo(con.Origin);
if (distance < Mindistance)
{
Mindistance = distance;
willcon = con;
}
}
return willcon;
}
public string GetName()
{
return "EventFunction";
}
}
public class MEPFilter : 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 class utils
{
public static double ToFEET(this double d)
{
return UnitUtils.Convert(d, DisplayUnitType.DUT_MILLIMETERS, DisplayUnitType.DUT_DECIMAL_FEET);
}
}
}