Revit机电二次开发之如何打断机电管线

来源:互联网 发布:知乎 长期熬夜保健品 编辑:程序博客网 时间:2024/06/08 04:15

本文开发环境为C#,Revit2014
Revit机电二次开发API并没有提供打断管件的方法,只能采用间接的办法实现,思路就是将需要打断的管件就地复制一根,然后将两根管件缩短并放置在合适的位置,同时应当考虑管件与原管路系统的连接问题,以风管Duct为例,C#实现的代码如下:

[TransactionAttribute(TransactionMode.Manual)]public class Test : IExternalCommand{    Autodesk.Revit.ApplicationServices.Application application;    Autodesk.Revit.DB.Document document;    public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)    {        UIApplication revit = commandData.Application;        application = revit.Application;        UIDocument uiDocument = revit.ActiveUIDocument;        document = uiDocument.Document;        using (Transaction transaction = new Transaction(document, "风管打断"))        {            transaction.Start();            DuctSelectionFilter ductSelectionFilter=new DuctSelectionFilter();            IList<Duct> ductList=new List<Duct>();            //选取一个风管            Duct duct = PickMEPCurve(uiDocument, ductSelectionFilter, "请选择一个风管") as Duct;            XYZ pointOnDuct = PickPointOnMEPCurve(uiDocument, duct as MEPCurve, "请选择一个打断点");            IList<MEPCurve> mepList = SliceMEPCurveIntoTwo(duct as MEPCurve, pointOnDuct, document);            transaction.Commit();        }    }}//风管选择过滤器class DuctSelectionFilter : ISelectionFilter{    public bool AllowElement(Element element)    {        if (element is Duct)        {            return true;        }        return false;    }    public bool AllowReference(Reference refer, XYZ point)    {        return false;    }}//选择一个机电管件MEPCurve PickMEPCurve(UIDocument uiDocument,ISelectionFilter selectionFilter,string promptTextWhilePickingElement){    Selection selection = uiDocument.Selection;    Reference mepReference = selection.PickObject(ObjectType.Element, selectionFilter, promptTextWhilePickingElement);    return uiDocument.Document.GetElement(mepReference) as MEPCurve;}//在管件上选择一个打断点XYZ PickPointOnMEPCurve(UIDocument uiDocument,MEPCurve mep,string promptTextWhilePickingPoint){    Selection selection = uiDocument.Selection;    XYZ selectedPoint = selection.PickPoint(ObjectSnapTypes.Nearest, promptTextWhilePickingPoint);    LocationCurve locationCurve = mep.Location as LocationCurve;    IntersectionResult intersectionResult = locationCurve.Curve.Project(selectedPoint);    return intersectionResult.XYZPoint;}//打断管件IList<MEPCurve> SliceMEPCurveIntoTwo(MEPCurve mepCurve, XYZ point, Document document){    IList<MEPCurve> mepCurveList = new List<MEPCurve>();    LocationCurve locationCurve = mepCurve.Location as LocationCurve;    XYZ start_point = locationCurve.Curve.GetEndPoint(0);    XYZ end_point = locationCurve.Curve.GetEndPoint(1);    Curve line1 = Line.CreateBound(start_point, point);    Curve line2 = Line.CreateBound(point, end_point);    //原地复制原机电管线    MEPCurve newMEPCurve = document.GetElement(ElementTransformUtils.CopyElement(document, mepCurve.Id, new XYZ(0, 0, 0)).ElementAt(0)) as MEPCurve;    LocationCurve newLocationCurve = newMEPCurve.Location as LocationCurve;    //为复制的机电管线指定基线    newLocationCurve.Curve = line1;    //断开原机电管线的连接,建立新机电管线的连接    ConnectorSetIterator connectorSetIterator = mepCurve.ConnectorManager.Connectors.ForwardIterator();    while (connectorSetIterator.MoveNext())    {        Connector connector = connectorSetIterator.Current as Connector;        if (connector.Origin.IsAlmostEqualTo(start_point))        {            ConnectorSet tempConnectorSet = connector.AllRefs;            ConnectorSetIterator tempConnectorSetIterator = tempConnectorSet.ForwardIterator();            while (tempConnectorSetIterator.MoveNext())            {                Connector tempConnector = tempConnectorSetIterator.Current as Connector;                if (tempConnector != null)                {                    if (tempConnector.ConnectorType == ConnectorType.End ||                    tempConnector.ConnectorType == ConnectorType.Curve ||                    tempConnector.ConnectorType == ConnectorType.Physical)                    {                        if (tempConnector.Owner.UniqueId != mepCurve.UniqueId)                        {                            connector.DisconnectFrom(tempConnector);                            ConnectorSetIterator newConnectorSetIterator = newMEPCurve.ConnectorManager.Connectors.ForwardIterator();                            while (newConnectorSetIterator.MoveNext())                            {                                Connector newConnector = newConnectorSetIterator.Current as Connector;                                if (newConnector.Origin.IsAlmostEqualTo(start_point))                                {                                    newConnector.ConnectTo(tempConnector);                                }                            }                        }                    }                }            }        }    }    //缩短原机电管线    locationCurve.Curve = line2;    mepCurveList.Add(newMEPCurve);    mepCurveList.Add(mepCurve);    return mepCurveList;}

由于Revit中Duct、Pipe、CableTray三个机电系统族的基类都是MEPCurve,所以上面的三个方法用在Duct、Pipe和CableTray都是可以,强制转换即可

1 0