Revit 二次开发之弯管剪辑翻弯练习

C#代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.UI.Selection;
using Autodesk.Revit.DB.Plumbing;

namespace StudentRevit
{
    [TransactionAttribute(TransactionMode.Manual)]
    [RegenerationAttribute(RegenerationOption.Manual)]
    public class Class1 : IExternalCommand
    {
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            UIDocument uidoc = commandData.Application.ActiveUIDocument;
            Document doc = uidoc.Document;
            Selection sel = uidoc.Selection;
            //让用户选择一个点或一个元素
            //第二个参数,ISelectionFilter,这个点必须符合这个过滤器的
            Reference r = sel.PickObject(ObjectType.PointOnElement, new PipeFilter());
            //获取到这一点
            XYZ firstPos = r.GlobalPoint;
            //获取第二点
            r = sel.PickObject(ObjectType.PointOnElement, new PipeFilter());
            XYZ secondPos = r.GlobalPoint;
            //获取管道Pipe
            Pipe pipe = doc.GetElement(r) as Pipe;
            //获取位置曲线
            LocationCurve locationCurve =pipe.Location as LocationCurve;
            //获取这个线的第一个点
            XYZ startPoint=locationCurve.Curve.GetEndPoint(0);
            //获取这个线的第二个点
            XYZ endPoint =locationCurve.Curve.GetEndPoint(1);
            //GetNearXYZ:获取最近的哪一点;Project:在这条曲线上投射指定的点
            XYZ pos1 =locationCurve.Curve.Project(GetNearXYZ(startPoint, firstPos, secondPos)).XYZPoint;
            XYZ pos2=locationCurve.Curve.Project(GetNearXYZ(endPoint, firstPos, secondPos)).XYZPoint;
            //using (Transaction trans=new Transaction(doc,"相邻点坐标")) 
            //{
            //    trans.Start();
            //    locationCurve.Curve = Line.CreateBound(startPoint,pos1);
            //    //将管子拷贝一份
            //    ElementId newElemId = ElementTransformUtils.CopyElement(doc, pipe.Id, new XYZ(0, 0, 0)).FirstOrDefault();
            //    Element newPipe = doc.GetElement(newElemId);
            //    (newPipe.Location as LocationCurve).Curve = Line.CreateBound(endPoint, pos2);
            //    trans.Commit();
            //}
            List<Line> line_list = GenerateLines(startPoint,endPoint,firstPos,secondPos,100);
            using (Transaction trans=new Transaction(doc,"相邻点坐标"))
            {
                trans.Start();
                foreach (Line line in line_list)
                {
                    ElementId newElemId = ElementTransformUtils.CopyElement(doc, pipe.Id, XYZ.Zero).FirstOrDefault();
                    Pipe newPipe = doc.GetElement(newElemId) as Pipe;
                    (newPipe.Location as LocationCurve).Curve = line;
                }
                doc.Delete(pipe.Id);
                trans.Commit();
            }
            return Result.Succeeded;
        }

        private List<Line> GenerateLines(XYZ startPoint, XYZ endPoint, XYZ firstPos, XYZ secondPos, int offset)
        {
            List<Line> line_list = new List<Line>();
            Line projLine=Line.CreateBound(startPoint, endPoint);
            XYZ near = GetNearXYZ(startPoint, firstPos, secondPos);
            XYZ pos1 = projLine.Project(near).XYZPoint;
            line_list.Add(Line.CreateBound(pos1, startPoint));

            near = GetNearXYZ(endPoint, firstPos, secondPos);
            XYZ pos2 = projLine.Project(near).XYZPoint;
            line_list.Add(Line.CreateBound(pos2, endPoint));

            XYZ offsetPos1=pos1+new XYZ(0,0, offset);
            line_list.Add(Line.CreateBound(pos1, offsetPos1));
            XYZ offsetPos2=pos2+new XYZ(0,0, offset);
            line_list.Add(Line.CreateBound(pos2, offsetPos2));
            line_list.Add(Line.CreateBound(offsetPos1,offsetPos2));
            return line_list;
        }

        /// <summary>
        /// 选择元素过滤器,过滤出管道(Pipe),===》用户只能选择管道的元素
        /// </summary>
        public class PipeFilter : ISelectionFilter
        {
            public bool AllowElement(Element elem)
            {
                //如果是管道(Pipe)返回true,否则false
                return elem is Pipe;
            }

            public bool AllowReference(Reference reference, XYZ position)
            {
                return true;
            }
        }
        /// <summary>
        /// 获取最近的相邻点坐标
        /// </summary>
        /// <param name="current">当前点</param>
        /// <param name="first">选择的第一个点坐标</param>
        /// <param name="second">选择的第二个点坐标</param>
        /// <returns></returns>
        public XYZ GetNearXYZ(XYZ current,XYZ first,XYZ second)
        {
            //DistanceTo:返回从该点到指定点的距离。
            return first.DistanceTo(current) > second.DistanceTo(current) ? second : first;
        }
    }
}

演示

完整代码,解决弯管问题

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.UI.Selection;
using Autodesk.Revit.DB.Plumbing;

namespace StudentRevit
{
    [TransactionAttribute(TransactionMode.Manual)]
    [RegenerationAttribute(RegenerationOption.Manual)]
    public class Class1 : IExternalCommand
    {
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            UIDocument uidoc = commandData.Application.ActiveUIDocument;
            Document doc = uidoc.Document;
            Selection sel = uidoc.Selection;
            //让用户选择一个点或一个元素
            //第二个参数,ISelectionFilter,这个点必须符合这个过滤器的
            Reference r = sel.PickObject(ObjectType.PointOnElement, new PipeFilter());
            //获取到这一点
            XYZ firstPos = r.GlobalPoint;
            //获取第二点
            r = sel.PickObject(ObjectType.PointOnElement, new PipeFilter());
            XYZ secondPos = r.GlobalPoint;
            //获取管道Pipe
            Pipe pipe = doc.GetElement(r) as Pipe;
            //获取位置曲线
            LocationCurve locationCurve =pipe.Location as LocationCurve;
            //获取这个线的第一个点
            XYZ startPoint=locationCurve.Curve.GetEndPoint(0);
            //获取这个线的第二个点
            XYZ endPoint =locationCurve.Curve.GetEndPoint(1);
            //GetNearXYZ:获取最近的哪一点;Project:在这条曲线上投射指定的点
            XYZ pos1 =locationCurve.Curve.Project(GetNearXYZ(startPoint, firstPos, secondPos)).XYZPoint;
            XYZ pos2=locationCurve.Curve.Project(GetNearXYZ(endPoint, firstPos, secondPos)).XYZPoint;
            //using (Transaction trans=new Transaction(doc,"相邻点坐标")) 
            //{
            //    trans.Start();
            //    locationCurve.Curve = Line.CreateBound(startPoint,pos1);
            //    //将管子拷贝一份
            //    ElementId newElemId = ElementTransformUtils.CopyElement(doc, pipe.Id, new XYZ(0, 0, 0)).FirstOrDefault();
            //    Element newPipe = doc.GetElement(newElemId);
            //    (newPipe.Location as LocationCurve).Curve = Line.CreateBound(endPoint, pos2);
            //    trans.Commit();
            //}
            List<Line> line_list = GenerateLines(startPoint,endPoint,firstPos,secondPos,100);
            List<Pipe> pipe_list = new List<Pipe>();
            using (Transaction trans=new Transaction(doc,"相邻点坐标"))
            {
                trans.Start();
                foreach (Line line in line_list)
                {
                    ElementId newElemId = ElementTransformUtils.CopyElement(doc, pipe.Id, XYZ.Zero).FirstOrDefault();
                    Pipe newPipe = doc.GetElement(newElemId) as Pipe;
                    (newPipe.Location as LocationCurve).Curve = line;
                    pipe_list.Add(newPipe);
                }
                doc.Delete(pipe.Id);
                trans.Commit();
            }
            //获取所有连接器
            List<Connector> cons = new List<Connector>();
            foreach (Pipe newPipe in pipe_list)
            {
                ConnectorSet connectorSet=newPipe.ConnectorManager.Connectors;
                foreach (var conn in connectorSet)
                {
                    cons.Add(conn as Connector);
                }
            }
            for (int i = cons.Count-1; i >0; i--)
            {
                Connector conn = cons[i];
                Connector connectTo = GetConnector(conn, cons);
                if (connectTo != null)
                {
                    using (Transaction trans = new Transaction(doc, "create elbow"))
                    {
                        trans.Start();
                        doc.Create.NewElbowFitting(conn, connectTo);
                        trans.Commit();
                    }
                }
            }
            return Result.Succeeded;
        }
        public Connector GetConnector(Connector currentCon,List<Connector> connectors)
        {
            foreach (Connector con in connectors)
            {
                if (con.Origin.IsAlmostEqualTo(currentCon.Origin)&&con.Owner.Id!=currentCon.Owner.Id)
                {
                    return con;
                }
            }
            return null;
        }
        private List<Line> GenerateLines(XYZ startPoint, XYZ endPoint, XYZ firstPos, XYZ secondPos, int offset)
        {
            List<Line> line_list = new List<Line>();
            Line projLine=Line.CreateBound(startPoint, endPoint);
            XYZ near = GetNearXYZ(startPoint, firstPos, secondPos);
            XYZ pos1 = projLine.Project(near).XYZPoint;
            line_list.Add(Line.CreateBound(pos1, startPoint));

            near = GetNearXYZ(endPoint, firstPos, secondPos);
            XYZ pos2 = projLine.Project(near).XYZPoint;
            line_list.Add(Line.CreateBound(pos2, endPoint));

            XYZ offsetPos1=pos1+new XYZ(0,0, offset);
            line_list.Add(Line.CreateBound(pos1, offsetPos1));
            XYZ offsetPos2=pos2+new XYZ(0,0, offset);
            line_list.Add(Line.CreateBound(pos2, offsetPos2));
            line_list.Add(Line.CreateBound(offsetPos1,offsetPos2));
            return line_list;
        }

        /// <summary>
        /// 选择元素过滤器,过滤出管道(Pipe),===》用户只能选择管道的元素
        /// </summary>
        public class PipeFilter : ISelectionFilter
        {
            public bool AllowElement(Element elem)
            {
                //如果是管道(Pipe)返回true,否则false
                return elem is Pipe;
            }

            public bool AllowReference(Reference reference, XYZ position)
            {
                return true;
            }
        }
        /// <summary>
        /// 获取最近的相邻点坐标
        /// </summary>
        /// <param name="current">当前点</param>
        /// <param name="first">选择的第一个点坐标</param>
        /// <param name="second">选择的第二个点坐标</param>
        /// <returns></returns>
        public XYZ GetNearXYZ(XYZ current,XYZ first,XYZ second)
        {
            //DistanceTo:返回从该点到指定点的距离。
            return first.DistanceTo(current) > second.DistanceTo(current) ? second : first;
        }
    }
}
原文地址:https://www.cnblogs.com/chenyanbin/p/13300893.html