Revit二次开发之管道避让
时间:2022-12-19 16:00:00
本项目实现了管道碰撞时跳跃或弯曲的避让功能。废话少说,直接上代码
这个Command类别是项目的主要类别。
try { while (true) { Document doc = UIDoc.Document; ///交互选择第一点 Reference reference = UIDoc.Selection.PickObject(ObjectType.PointOnElement, new MEPFilter(), "请选择第一根管"); XYZ point1 = reference.GlobalPoint; //MEPCurve mepCurve = doc.GetElement(reference) as MEPCurve; ///判断接头是否配置 // Pipe pipe = doc.GetElement(reference) as Pipe; // ConnectorSet connects = pipe.ConnectorManager.Connectors; // if (null == connects) // { // TaskDialog.Show("Error", "无管件"); // MainWindow.Close(); // return Result.Failed; // } ///交互选择第二点 Reference reference2 = UIDoc.Selection.PickObject(ObjectType.PointOnElement, new MEPFilter(), "请选择第二根管"); XYZ point2 = reference2.GlobalPoint; //选择第三点 XYZ point3 = point1; if (1== MainWindow.TabC.SelectedIndex) { point3 = UIDoc.Selection.PickPoint(ObjectSnapTypes.Endpoints | ObjectSnapTypes.Intersections, "请选择一个点来确认偏移的方向"); } //获取管道 //Pipe pipe = doc.GetElement(reference) as Pipe; MEPCurve pipe = doc.GetElement(reference) as MEPCurve; //获取管道定位线 LocationCurve locationcurve = pipe.Location as LocationCurve; /// XYZ start = locationcurve.Curve.GetEndPoint(0); XYZ end = locationcurve.Curve.GetEndPoint(1); //上面的点是管道表面的点,需要投影到管道中心定位线 XYZ propoint1 = locationcurve.Curve.Project(point1).XYZPoint; XYZ propoint2 = locationcurve.Curve.Project(point2).XYZPoint; getWindowValue(out double offsetvalue, out double angle,out bool updown); // //Line LineOne = Line.CreateBound(propoint1, near(start, end, propoint1)); Line LineOne = Line.CreateBound(start,propoint1); Line LineTwo = Line.CreateBound(propoint2, end); bool m_flag = false; if (propoint1.DistanceTo(start) > propoint2.DistanceTo(start)) m_flag = true; if (m_flag) { LineOne = Line.CreateBound(propoint1, end ); LineTwo = Line.CreateBound(start, propoint2); } if (0 == MainWindow.TabC.SelectedIndex) { if (MainWindow.onePoint.IsChecked == true) { double acLength; if (angle == 90) acLength = 0; else acLength = offsetvalue / Math.Tan((angle / 180.0) * Math.PI); Line pipeoffset = Line.CreateBound(propoint1, propoint2); XYZ point1offset = pipeoffset.Evaluate(acLength / pipeoffset.ApproximateLength, true); double tempoffset = offsetvalue; if (MainWindow.Down.IsChecked == true) tempoffset = -tempoffset; LineTwo = Line.CreateBound(point1offset new XYZ(0, 0, tempoffset), end new XYZ(0, 0, tempoffset)); if (m_flag) LineTwo = Line.CreateBound(start new XYZ(0, 0, tempoffset), point1offset new XYZ(0, 0, tempoffset)); } } else { if (MainWindow.moveOnePoint.IsChecked == true) { double acLength; if (angle == 90) acLength = 0; else acLength = offsetvalue / Math.Tan((angle / 180.0) * Math.PI); Line pipeoffset = Line.CreateBound(propoint1, propoint2); XYZ point1offset = pipeoffset.Evaluate(acLength / pipeoffset.ApproximateLength, true); double value = (point3.Y - end.Y) * (end.X - start.X) - (end.Y - start.Y) * (point3.X - end.X); XYZ res = new XYZ0, 0, 1);
if (value > 0)
{
res = new XYZ(0, 0, -1);
}
// LineTwo = Line.CreateBound(point1offset, pointnext).CreateOffset(offsetvalue, res) as Line;
LineTwo = Line.CreateBound(point1offset, end).CreateOffset(offsetvalue, res) as Line;
if (m_flag)
LineTwo = Line.CreateBound(start,point1offset).CreateOffset(offsetvalue, res) as Line;
}
}
List lines = creatlines(start, end, propoint1, propoint2, point3, updown, angle, offsetvalue);
//创建一个管道列表来存储生成的所有管道
//List pipes = new List();
List pipes = new List();
using (Transaction transaction = new Transaction(doc))
{
transaction.Start("创建管道");
ElementId mepcurveid = doc.GetElement(reference).Id;
//Pipe mEPCurveone = CopyPipe(doc, mepcurveid, LineOne);
//Pipe mEPCurvetwo = CopyPipe(doc, mepcurveid, LineTwo);
MEPCurve mEPCurveone = CopyPipe(doc, mepcurveid, LineOne);
MEPCurve mEPCurvetwo = CopyPipe(doc, mepcurveid, LineTwo);
//原管道所有的连接器pipe
ConnectorSet connectorSet = pipe.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)
if (con.Origin.IsAlmostEqualTo(connector.Origin) && con.Owner.Id != connector.Owner.Id)
{
//找出与原来管道连接的连接器距离最近的连接器
Connector willcon = FindNearCon(connector, mEPCurveone, mEPCurvetwo);
connector.ConnectTo(willcon);
}
}
}
}
pipes.Add(mEPCurveone);
pipes.Add(mEPCurvetwo);
//通过遍历生成的所有定位线来创建管道
foreach (Line line in lines)
{
MEPCurve newpipe = CopyPipe(doc, pipe.Id, line);
pipes.Add(newpipe);
}
doc.Delete(pipe.Id);
Connectpipes(doc,pipes);//创建连接器
transaction.Commit();
}
}
}
catch (Exception e)
{
//TaskDialog.Show("Error", e.Message);
MainWindow.Close();
return Result.Cancelled;
}
这是主要思想
private List creatlines(XYZ start, XYZ end, XYZ propoint1, XYZ propoint2, XYZ propoint3, bool updown,double angle ,double offsetvalue)
{
List lines = new List();
//Line thispipecurve = Line.CreateBound(propoint1, near(start, end, propoint1));
//lines.Add(thispipecurve);
//Line newpipecurve = Line.CreateBound(propoint2, near(start, end, propoint2));
//lines.Add(newpipecurve);
XYZ propoint1offset, propoint2offset ;
if (0 == MainWindow.TabC.SelectedIndex)
{
if (updown)
{
double acLength;
if (angle == 90)
acLength = 0;
else
acLength = offsetvalue / Math.Tan((angle / 180.0) * Math.PI);
Line pipeoffset = Line.CreateBound(propoint1, propoint2);
//Line pipeoffset1= pipeoffset.CreateOffset(-100, new XYZ(0, 0, 1)) as Line;
XYZ point1offset = pipeoffset.Evaluate(acLength / pipeoffset.ApproximateLength, true);
propoint1offset = point1offset + new XYZ(0, 0, offsetvalue);
pipeoffset = Line.CreateBound(propoint2, propoint1);
point1offset = pipeoffset.Evaluate(acLength / pipeoffset.ApproximateLength, true);
propoint2offset = point1offset + new XYZ(0, 0, offsetvalue);
}
else
{
double acLength;
if (angle == 90)
acLength = 0;
else
acLength = offsetvalue / Math.Tan((angle / 180.0) * Math.PI);
Line pipeoffset = Line.CreateBound(propoint1, propoint2);
XYZ point1offset = pipeoffset.Evaluate(acLength / pipeoffset.ApproximateLength, true);
propoint1offset = point1offset + new XYZ(0, 0, -offsetvalue);
pipeoffset = Line.CreateBound(propoint2, propoint1);
point1offset = pipeoffset.Evaluate(acLength / pipeoffset.ApproximateLength, true);
propoint2offset = point1offset + new XYZ(0, 0, -offsetvalue);
}
Line line1 = Line.CreateBound(propoint1, propoint1offset);
lines.Add(line1);
if (MainWindow.twoPoint.IsChecked == true)
{
Line offsetline = Line.CreateBound(propoint1offset, propoint2offset);
lines.Add(offsetline);
Line line2 = Line.CreateBound(propoint2, propoint2offset);
lines.Add(line2);
}
}
else
{
bool m_flag = false;
if (propoint1.DistanceTo(start) > propoint2.DistanceTo(start))
m_flag = true;
double acLength;
if (angle == 90)
acLength = 0;
else
acLength = offsetvalue / Math.Tan((angle / 180.0) * Math.PI);
Line pipeoffsetOrg = Line.CreateBound(propoint1, propoint2);
XYZ point1offset = pipeoffsetOrg.Evaluate(acLength / pipeoffsetOrg.ApproximateLength, true);
pipeoffsetOrg = Line.CreateBound(propoint2, propoint1);
XYZ point2offset = pipeoffsetOrg.Evaluate(acLength / pipeoffsetOrg.ApproximateLength, true);
//https://blog.csdn.net/mazhiyuan1981/article/details/114369939 解析
double value = (propoint3.Y - end.Y) * (end.X - start.X) - (end.Y - start.Y) * (propoint3.X - end.X);
XYZ res=new XYZ(0, 0, 1);
if (value>0)
{
res = new XYZ(0, 0, -1);
}
Line pipeoffset = Line.CreateBound(point1offset, point2offset).CreateOffset(offsetvalue, res) as Line;
if (m_flag)
{
pipeoffset = Line.CreateBound(point2offset, point1offset).CreateOffset(offsetvalue, res) as Line;
}
//lines.Add(pipeoffset);
XYZ offsetstart = pipeoffset.GetEndPoint(0);
XYZ offsetend = pipeoffset.GetEndPoint(1);
//Line line1 = Line.CreateBound(offsetstart, near(propoint1, propoint2, offsetstart)) :
Line line1 = Line.CreateBound(propoint1,offsetstart);
if (m_flag)
line1 = Line.CreateBound(propoint1, offsetend);
// line1 = Line.CreateBound(offsetstart, propoint1.DistanceTo(offsetstart) > propoint2.DistanceTo(offsetstart) ? propoint2 : propoint1);
lines.Add(line1);
if (MainWindow.moveTwoPoint.IsChecked == true)
{
//Line line2 = Line.CreateBound(offsetend, near(propoint1, propoint2, offsetend));
//Line line2 = Line.CreateBound(offsetend, propoint1.DistanceTo(offsetstart) > propoint2.DistanceTo(offsetstart) ? propoint1 : propoint2);
Line line2 = Line.CreateBound(offsetend, propoint2);
if (m_flag)
line2 = Line.CreateBound(offsetstart, propoint2);
lines.Add(line2);
lines.Add(pipeoffset);
}
}
return lines;
}
这是计算新的管道