revit 二次开发管道翻弯

管道两点翻弯并于原管件保持连接

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);
            }
        }
    }
}

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
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: 创建翻弯管道对象并放置在计算出的位置和方向上 } ``` 上述代码中,我们首先使用过滤器获取所有的管道和墙体对象,并将管道分组。然后,我们遍历所有的管道,检测管道是否与其他管道或墙体碰撞。如果管道碰撞,则需要根据碰撞的位置和方向计算出管道需要翻弯的位置和方向。最后,我们创建翻弯管道对象,并将其放置在计算出的位置和方向上。需要注意的是,上述代码仅为示例代码,实际应用中可能需要根据具体需求进行修改。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值