Revit二开学习-多排管道标注

Revit二开学习-多排管道标注

Revit二开学习-多排管道标注
管道标注摘自:

https://blog.csdn.net/qq_43026206/article/details/84256346?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522159152319919725219929766%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=159152319919725219929766&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_ecpm_v3~pc_rank_v3-2-84256346.first_rank_ecpm_v3_pc_rank_v3&utm_term=revit%E4%BA%8C%E6%AC%A1%E5%BC%80%E5%8F%91%E7%AE%A1%E9%81%93%E6%A0%87%E6%B3%A8

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;
using Test.Filter;
using Teigha.Runtime;

namespace Test
{
    /// <summary>
    /// 多排管道标注
    /// 只能在平面视图标注
    /// 只标注在管道法线右侧
    /// </summary>
    [Transaction(TransactionMode.Manual)]
    class Cmd_MEPMarking : IExternalCommand
    {
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            UIDocument uidoc = commandData.Application.ActiveUIDocument;
            Document doc = uidoc.Document;

            // 判断当前视图是否是平面视图
            if (!(doc.ActiveView is ViewPlan))
            {
                TaskDialog.Show("Error", "当前视图不是平面视图");
                return Result.Cancelled;
            }

            Selection sel = uidoc.Selection;

            // 获取需要标注的管道
            IList<Element> elems = sel.PickElementsByRectangle(new MEPCurveFilter(), "请选择管道");

            IList<MEPCurve> curves = new List<MEPCurve>();

            // 判断是否选择了机电管线
            if(elems.Count == 0)
            {
                TaskDialog.Show("Error","未选择机电管线");
                return Result.Cancelled;
            }

            foreach (Element e in elems)
            {
                curves.Add(e as MEPCurve);
            }


            // 判断管道是否平行
            if (!isMEPCurvesParallel(curves))
            {
                TaskDialog.Show("Test", "所选择的机电管线不平行");
                return Result.Cancelled;
            }


            // 获取单根管道的向量并确保方向准确
            Line MEPLine1 = (curves[0].Location as LocationCurve).Curve as Line;

            XYZ pipeVector = MEPLine1.Direction;

            double X = pipeVector.X;
            double Y = pipeVector.Y;

            if (Y == -1)
            {
                pipeVector = new XYZ(pipeVector.X, 1, pipeVector.Z);
            }

            else if (X < 0)
            {
                pipeVector = pipeVector.Multiply(-1);
            }


            // 选择标记点
            XYZ tagStart = sel.PickPoint();


            List<double> list = new List<double>();// 距离数组

            Dictionary<XYZ,MEPCurve> map = new Dictionary<XYZ, MEPCurve>();// 管线与垂直交点
            Dictionary<double,XYZ> tagToMep = new Dictionary<double,XYZ>();// 距离与垂直交点


            foreach (MEPCurve mep in curves)
            {
                LocationCurve location = mep.Location as LocationCurve;
                Curve curve = location.Curve;
                IntersectionResult intersection = curve.Project(tagStart);
                XYZ intersectionP = intersection.XYZPoint;
                XYZ interPoint = new XYZ(intersectionP.X, intersectionP.Y, 0.00);

                map.Add(interPoint,mep);

                list.Add(interPoint.DistanceTo(tagStart));

                tagToMep.Add(interPoint.DistanceTo(tagStart),interPoint);
            }
            list.Sort();

            list.Reverse();
            //StringBuilder s = new StringBuilder();
            //foreach(double d in list)
            //{
            //    s.Append(d.ToString()+'\n');
            //}
            //TaskDialog.Show("Test",s.ToString());

            double distance = 0.00;// 标注距离

            IList<Line> lines = new List<Line>();// 所需要绘制的线段
            IList<XYZ> tagPoints = new List<XYZ>();// 标记点位置


            Dictionary<MEPCurve, XYZ> tagMEP = new Dictionary<MEPCurve, XYZ>();// 机电管线与标记点

            foreach (double d in list)
            {
                XYZ verticalPoint = tagToMep[d];
                XYZ verticalVector = getPointVector(verticalPoint,tagStart);
                XYZ tempPoint = verticalPoint + verticalVector.Normalize() * (d+distance);
                distance += 450 / 304.8;
                Line line = Line.CreateBound(verticalPoint,tempPoint);
                lines.Add(line);

                XYZ tagPoint = tempPoint + pipeVector.Normalize() * 400 / 304.8;
                tagPoints.Add(tagPoint);
                line = Line.CreateBound(tempPoint,tagPoint);
                lines.Add(line);

                tagMEP.Add(map[verticalPoint],tagPoint);
            }

            ICollection<ElementId> group = new List<ElementId>();
            using (Transaction t = new Transaction(doc, "XX"))
            {
                t.Start();
                foreach(Line line in lines)
                {
                    DetailCurve detailCurve = doc.Create.NewDetailCurve(doc.ActiveView,line);
                    group.Add(detailCurve.Id);
                }
                doc.Create.NewGroup(group);
                t.Commit();
            }

            TagMode tagMode = TagMode.TM_ADDBY_CATEGORY;
            TagOrientation tagOrientation = TagOrientation.Horizontal;//标记的朝向


            using (Transaction trans = new Transaction(doc))
            {
                trans.Start("Creat  IndependentTag");

                foreach (MEPCurve curve in curves)
                {
                    XYZ tagPoint = tagMEP[curve];

                    IndependentTag tag = IndependentTag.Create(doc, doc.ActiveView.Id, new Reference(curve), true, tagMode, tagOrientation, tagPoint);
                    if (null == tag)
                    {
                        throw new System.Exception("Create IndependentTag Failed.");
                    }

                    tag.LeaderEndCondition = LeaderEndCondition.Free;
                    tag.HasLeader = false;//不要箭头
                                          //XYZ elbowPnt = mid + new XYZ(2.0, 2.0, 0.0);
                                          //tag.LeaderElbow = elbowPnt;//有箭头的话,箭头拐点
                    XYZ headerPnt = tagPoint;
                    tag.TagHeadPosition = headerPnt;//标记的位置

                }

              
                trans.Commit();
            }


            return Result.Succeeded;
        }

        // 获取两个点的向量
        public XYZ getPointVector(XYZ p1,XYZ p2)
        {
            Line line = Line.CreateBound(p1,p2);
            return line.Direction;
        }

        // 判断多条管道平行
        public bool isMEPCurvesParallel(IList<MEPCurve> mepCurves)
        {
            Stack<MEPCurve> stack = new Stack<MEPCurve>();
            foreach (MEPCurve curve in mepCurves)
            {
                stack.Push(curve);
            }

            while (stack.Count > 1)
            {
                MEPCurve m1 = stack.Pop();
                MEPCurve m2 = stack.Peek();

                if (!isParallel(m1, m2))
                    return false;
            }

            return true;
        }

        // 判断两条直线是否平行
        public bool isParallel(MEPCurve c1,MEPCurve c2)
        {
            Line l1 = CurveZZ(c1) as Line;
            Line l2 = CurveZZ(c2) as Line;

            XYZ vector1 = l1.Direction;
            XYZ vector2 = l2.Direction;
            if (vector1.IsAlmostEqualTo(vector2) || vector1.IsAlmostEqualTo(vector2*-1))
                return true;

            return false;
        }

        // 将Curve的Z值归零
        public Curve CurveZZ(MEPCurve c)
        {
            Curve curve = (c.Location as LocationCurve).Curve;
            XYZ p1 = curve.GetEndPoint(0);
            XYZ p2 = curve.GetEndPoint(1);
            p1 = new XYZ(p1.X, p1.Y, 0);
            p2 = new XYZ(p2.X, p2.Y, 0);
            return Line.CreateBound(p1,p2);
        }
    }
}


上一篇:Linux 驱动开发 二十七:自旋锁


下一篇:PCL:Spin Image旋转图像