锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

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;

        }

这是计算新的管道 

锐单商城拥有海量元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章