Revit二次开发 管道生成三通——两管生成和三管生成

本文主要参考以下博客

“revit二次开发 关于管道弯头、三通、四通的生成”

using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using Autodesk.Revit.Attributes;
using System.Linq;
using System.Collections.Generic;
using Autodesk.Revit.DB.Mechanical;
using System;
using System.Windows;
using Autodesk.Revit.DB.Plumbing;

namespace WPF_srqc
{
    [Transaction(TransactionMode.Manual)]
    class NewTeeFitting : IExternalCommand
    {
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            UIApplication uiApp = commandData.Application;
            Document doc = uiApp.ActiveUIDocument.Document;
            Selection sel = uiApp.ActiveUIDocument.Selection;

            //选取管道,管道必须相交,否则intersectPoint为空
            var reference1 = sel.PickObject(ObjectType.Element, "请选择第1个管");
            MEPCurve duct1 = doc.GetElement(reference1) as MEPCurve;

            var reference2 = sel.PickObject(ObjectType.Element, "请选择第2个管");
            MEPCurve duct2 = doc.GetElement(reference2) as MEPCurve;

            var reference3 = sel.PickObject(ObjectType.Element, "请选择第3个管");
            MEPCurve duct3 = doc.GetElement(reference3) as MEPCurve;

            Curve curve1 = (doc.GetElement(reference1).Location as LocationCurve).Curve;
            Curve curve2 = (doc.GetElement(reference2).Location as LocationCurve).Curve;
            Curve curve3 = (doc.GetElement(reference3).Location as LocationCurve).Curve;

            var ductList = GetMainDuct(duct1, duct2);

            MEPCurve MainDuct = ductList[0];//the main Pipe

            MEPCurve LessDuct = ductList[1];// the minor Pipe
            
            MEPCurve duct4 = null;//the main pipe

            IntersectionResultArray intersectPoint12 = new IntersectionResultArray();//交点数组,管道必须相交
            IntersectionResultArray intersectPoint13 = new IntersectionResultArray();
            IntersectionResultArray intersectPoint23 = new IntersectionResultArray();
            curve2.MakeUnbound(); //判断曲线是否相交时,线段变为直线判断。
            curve3.MakeUnbound();

            var x = curve1.Intersect(curve2, out intersectPoint12);//输出曲线1和曲线2的交点
            var x1 = curve1.Intersect(curve3, out intersectPoint13);
            var x2 = curve2.Intersect(curve3, out intersectPoint23);
            
            #region Intersect返回值解释

            string info = "曲线1和曲线2:" + x
                + "\n" + "曲线1和曲线3:" + x1
                + "\n" + "曲线2和曲线3:" + x2;
            TaskDialog.Show("1", info);
            //1.SetComparisonResult.Overlap,共面且相交。
            //2.SetComparisonResult.Subset,共线,且只有一个交点,即两条有边界直线共线且首尾相连。
            //3.SetComparisonResult.Superset,共线;注:使用前需将其中一条曲线MakeUnbound();
            //4.SetComparisonResult.Disjoint,无交点,可能是共面且平行,也可能是空间内不共面;
            //5.SetComparisonResult.Equal,两条直线有重合部分(只有一个交点的情况除外)。
            #endregion

            //如果管道1和管道2有交点,则用两管创建三通;无交点则用三个管创建。
            if (x == SetComparisonResult.Overlap)
            {//这一部分代码是两管生成三通
                using (Transaction tran = new Transaction(doc))
                {
                    tran.Start("创建三通");

                    var OrginPoint = intersectPoint12.get_Item(0).XYZPoint;

                    ElementId elementId = null;
                    try
                    {
                        elementId = PlumbingUtils.BreakCurve(doc, MainDuct.Id, OrginPoint);//打断主管道,仅限水管
                    }
                    catch
                    {
                        elementId = MechanicalUtils.BreakCurve(doc, MainDuct.Id, OrginPoint);//打断主管道,仅限风管
                    }
                    
                    duct4 = doc.GetElement(elementId) as MEPCurve;

                    ConnectTwoDuctsWithElbow(doc, MainDuct, duct4, LessDuct);
                    
                    tran.Commit();
                }
            }
            else
            {//这一部分代码是用三管生成三通
                
                Transaction tran2 = new Transaction(doc);
                tran2.Start("创建三通2");


                ConnectTwoDuctsWithElbow(doc, duct1, duct2, duct3);
                tran2.Commit();
            }

            

            return Result.Succeeded;
        }

        /// <summary>
        /// 区分主要管道与次要管道
        /// </summary>
        /// <param name="duct1"></param>
        /// <param name="duct2"></param>
        /// <returns></returns>
        public static List<MEPCurve> GetMainDuct(MEPCurve duct1, MEPCurve duct2)
        {
            List<MEPCurve> mEPCurves = new List<MEPCurve>();

            Curve curve1 = (duct1.Location as LocationCurve).Curve;
            Curve curve2 = (duct2.Location as LocationCurve).Curve;

            List<double> disList = new List<double>();
            double dis = double.MaxValue;
            XYZ pointA1 = curve1.GetEndPoint(0);
            XYZ pointA2 = curve1.GetEndPoint(1);
            XYZ pointB1 = curve2.GetEndPoint(0);
            XYZ pointB2 = curve2.GetEndPoint(1);

            //计算曲线1两个点到曲线2的距离
            var distance1 = curve2.Distance(pointA1);
            var distance2 = curve2.Distance(pointA2);

            //计算曲线2两个点到曲线1的距离
            var distance3 = curve1.Distance(pointB1);
            var distance4 = curve1.Distance(pointB2);

            disList.Add(distance1);
            disList.Add(distance2);
            disList.Add(distance3);
            disList.Add(distance4);

            dis = disList.Min();//得到最小值
            var x = disList.IndexOf(dis);//获取最小值在数组中的位置

            if (x < 2)//曲线2是主管
            {
                mEPCurves.Add(duct2);
                mEPCurves.Add(duct1);
                return mEPCurves;
            }
            else//曲线1是主管
            {
                mEPCurves.Add(duct1);
                mEPCurves.Add(duct2);
                return mEPCurves;
            }


        }

        /// <summary>
        /// 创建连接
        /// </summary>
        /// <param name="doc"></param>
        /// <param name="duct1">主要管道1</param>
        /// <param name="duct2">主要管道2</param>
        /// <param name="duct3">次要管道</param>
        public static void ConnectTwoDuctsWithElbow(Document doc, MEPCurve duct1, MEPCurve duct2, MEPCurve duct3)
        {
            double minDistance = double.MaxValue;
            Connector connector1, connector2, connector3;
            connector1 = connector2 = connector3 = null;

            foreach (Connector con1 in duct1.ConnectorManager.Connectors)
            {
                foreach (Connector con2 in duct2.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 duct3.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);

            }
        }
    }
}

两管生成三通:(如果没有——curve2.MakeUnbound();  管道12的关系将是Disjoint)

三管生成三通:

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Revit二次开发中,可以使用Revit API来实现管道的碰撞检测和自动翻弯功能。具体实现方法包括以下几个步骤: 1. 获取所有的管道对象,并对它们进行分类和分组。 2. 遍历所有的管道,检测管道是否与其他管道或墙体碰撞。 3. 如果管道碰撞,则根据碰撞的位置和方向计算出管道需要翻弯的位置和方向。 4. 创建翻弯的管道对象,并将其放置在计算出的位置和方向上。 下面是一个简单的示例代码,用于实现简单的管道碰撞自动翻弯功能: ```csharp // 获取当前文档 Document doc = uidoc.Document; // 定义一个过滤器,过滤出所有的管道和墙体 ElementCategoryFilter pipeFilter = new ElementCategoryFilter(BuiltInCategory.OST_Pipe); ElementCategoryFilter wallFilter = new ElementCategoryFilter(BuiltInCategory.OST_Walls); LogicalOrFilter filter = new LogicalOrFilter(pipeFilter, wallFilter); // 获取所有符合条件的管道和墙体 List<Element> elements = new FilteredElementCollector(doc) .WherePasses(filter) .ToList(); // 将管道分组 List<Element> pipes = elements.Where(e => e.Category.Id.IntegerValue == (int)BuiltInCategory.OST_Pipe).ToList(); // 遍历所有的管道 foreach (Element pipe in pipes) { // 检测管道是否与其他管道或墙体碰撞 bool isCollided = false; foreach (Element e in elements) { if (e.Id == pipe.Id) continue; if (pipe.get_Geometry(new Options()).Intersect(e.get_Geometry(new Options())) != null) { isCollided = true; break; } } if (!isCollided) continue; // 计算管道需要翻弯的位置和方向 // TODO: 计算管道需要翻弯的位置和方向 // 创建翻弯的管道对象 // TODO: 创建翻弯的管道对象并放置在计算出的位置和方向上 } ``` 上述代码中,我们首先使用过滤器获取所有的管道和墙体对象,并将管道分组。然后,我们遍历所有的管道,检测管道是否与其他管道或墙体碰撞。如果管道碰撞,则需要根据碰撞的位置和方向计算出管道需要翻弯的位置和方向。最后,我们创建翻弯的管道对象,并将其放置在计算出的位置和方向上。需要注意的是,上述代码仅为示例代码,实际应用中可能需要根据具体需求进行修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值