Revit二次开发之递归实现查找相连接的管道系统

最近有人提出一个问题 ,就是根据选择的一根管道 ,获得与这根管道相连接的管道系统中的其他图元,包括弯头,闸阀等管道附件及管件,那么对于这个问题,我们第一时间想到的就是根据管道和管道附件特有的连接件属性来做判断,从一根管道获得它的一段的连接件,根据连接件获得它的Owner 再根据Owner获得所属的连接件 以此类推的向下查找 直到某个连接件下再也没有其他可连接的图元,这是典型的递推原理,代码和示例图如下:

 

using Autodesk.Revit.UI;

using Autodesk.Revit.DB;

using Autodesk.Revit.Attributes;

using Autodesk.Revit.UI.Selection;

using Autodesk.Revit.DB.Plumbing;

namespace autoMake

{

    [Transaction(TransactionMode.Manual)]

    [Regeneration(RegenerationOption.Manual)]

    class PipeFind : IExternalCommand

    {

        IList(ElementId) listId = new List(ElementId)();

        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)

        {

            UIApplication uiapp = commandData.Application;

            UIDocument uidoc = uiapp.ActiveUIDocument;

            Document doc = uidoc.Document;

 

            Reference refer = uidoc.Selection.PickObject(ObjectType.Element, "");

            Element elem = doc.GetElement(refer);

            listId.Add(elem.Id);

            Pipe pipe = elem as Pipe;

            XYZ xyz = refer.GlobalPoint;

            Curve curve = (pipe.Location as LocationCurve).Curve;

            XYZ project = curve.Project(xyz).XYZPoint;

            Connector connector = BackPipeNearConnectors(elem, xyz);

            BackAlrefsConnectors(connector);

            uidoc.Selection.SetElementIds(listId);

            return Result.Succeeded;

        }

        ///

        /// 返回管道连接件原点与鼠标拾取点在管道上的投影点最近的那个

        ///

        ///

        ///

        ///

        private Connector BackPipeNearConnectors(Element elem, XYZ xyz)

        {

            Connector conn = null;

            MEPCurve mep = elem as MEPCurve;

            SortedDictionary(double, Connector) dictionary = new SortedDictionary(double, Connector)();

            ConnectorSetIterator connectorSetIterator = mep.ConnectorManager.Connectors.ForwardIterator();

            while (connectorSetIterator.MoveNext())

            {

                Connector connector = connectorSetIterator.Current as Connector;

                if (connector.AllRefs.Size > 0)

                {

                    dictionary.Add(connector.Origin.DistanceTo(xyz), connector);

                }

            }

 

            return dictionary.Values.ElementAt(0);

        }

        ///

        /// 获得连接件上的连接的所有连接件 根据连接件获得图元 根据图元获得连接件 实现递归查询

        ///

        ///

        private void BackAlrefsConnectors(Connector connector)

        {

            Element elem = null;

            ConnectorSetIterator connectorSetIterator = connector.AllRefs.ForwardIterator();

            while (connectorSetIterator.MoveNext())

            {

                Connector connref = connectorSetIterator.Current as Connector;

                if (connref.Origin.IsAlmostEqualTo(connector.Origin))

                {

                    elem = connref.Owner;

                    break;

                }

            }

 

            if (elem.GetType().ToString() == "Autodesk.Revit.DB.Plumbing.Pipe")

            {

                listId.Add(elem.Id);

 

                Connector connector1 = BackPipeConnectors(elem, connector);

                if (connector1.IsConnected)

                {

                    BackAlrefsConnectors(connector1);

                }

            }

            else if (elem.GetType().ToString() == "Autodesk.Revit.DB.FamilyInstance")

            {

                listId.Add(elem.Id);

                Connector connector1 = BackInstanceConnectors(elem as FamilyInstance, connector);

                if (connector1.IsConnected)

                {

                    BackAlrefsConnectors(connector1);

                }

            }

 

        }

        ///

        /// 返回管道上指定连接件

        ///

        ///

        ///

        ///

        private Connector BackPipeConnectors(Element elem, Connector conn)

        {

            Connector connector = null;

            MEPCurve mep = elem as MEPCurve;

            ConnectorSetIterator connectorSetIterator = mep.ConnectorManager.Connectors.ForwardIterator();

            while (connectorSetIterator.MoveNext())

            {

                Connector connectorset = connectorSetIterator.Current as Connector;

                if (connectorset.AllRefs.Size > 0)

                {

                    if (!connectorset.Origin.IsAlmostEqualTo(conn.Origin))

                    {

                        connector = connectorset;

                        break;

                    }

                }

            }

 

            return connector;

        }

        ///

        /// 返回弯头 闸阀等实例的指定连接件

        ///

        ///

        ///

        ///

        private Connector BackInstanceConnectors(FamilyInstance instance, Connector conn)

        {

            Connector connector = null;

            MEPModel model = instance.MEPModel as MEPModel;

            ConnectorSetIterator connectorSetIterator = model.ConnectorManager.Connectors.ForwardIterator();

            while (connectorSetIterator.MoveNext())

            {

                Connector connectorset = connectorSetIterator.Current as Connector;

                if (connectorset.AllRefs.Size > 0)

                {

                    if (!connectorset.Origin.IsAlmostEqualTo(conn.Origin))

                    {

                        connector = connectorset;

                        break;

                    }

                }

            }

            return connector;

        }

    }

    public class PipeFilters : ISelectionFilter

    {

        public bool AllowElement(Element elem)

        {

            return elem is Pipe;

        }

 

        public bool AllowReference(Reference reference, XYZ position)

        {

            return false;

        }

    }

}

Revit二次开发之递归实现查找相连接的管道系统

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值