Cad 首尾相连的线段连接成多段线

 
        /// <summary>
        ///首尾相连的线段连接成多段线
        /// V1.0 by WeltionChen @2011.02.17
        /// 实现原理:
        /// 1.选择图面上所有直线段
        /// 2.选取选集第一条直线作为起始线段,向线段的两个方向搜索与之相连的直线段
        /// 3.搜索方式采用Editor的SelectCrossingWindow方法通过线段的端点创建选集
        /// 正常情况下会选到1到2个线段(本程序暂不处理3个线段相交的情况),剔除本身,得到与之相连的直线段
        /// 4.处理过的直线段将不再作为起始线段,由集合中剔除
        /// 4.通过递归循环依次搜索,直到末端。
        /// 5.删除原线段,根据创建多段线
        /// 6.循环处理所有的线段
        /// </summary>
        [CommandMethod ("tt5")]
        public void JionLinesToPline()
        {
            //选择图面上所有直线段
            Editor ed = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;
            SelectionFilter sf = new SelectionFilter(new TypedValue[] { new TypedValue(0, "Line") });
            PromptSelectionResult selectLinesResult = ed.SelectAll(sf);
            if (selectLinesResult.Status != PromptStatus.OK)
                return;
            //需要处理的直线段集合
            List<ObjectId> lineObjectIds = new List<ObjectId>(selectLinesResult.Value.GetObjectIds());
            using (Transaction tr = HostApplicationServices.WorkingDatabase.TransactionManager.StartTransaction())
            {
                Database db = HostApplicationServices.WorkingDatabase;
                BlockTableRecord currentSpace = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;
                while (true)
                {
                    //选取选集第一条直线作为起始线段
                    ObjectId currentLineId = lineObjectIds[0];
                    //处理过的直线段将不再作为起始线段,由集合中剔除
                    lineObjectIds.RemoveAt(0);
                    Line currentLine = tr.GetObject(currentLineId, OpenMode.ForWrite) as Line;
                    //多段线的顶点集合,由各段相连的直线段的端点组成,初始值为起始线段的端点
                    List<Point3d> plinePoints = new List<Point3d> { currentLine.StartPoint, currentLine.EndPoint };
                    //每个直线段有两个方向,由起点向终点方向搜索
                    JionLinesToPline(ref lineObjectIds, tr, ref plinePoints, currentLineId, currentLineId);
                    //翻转点集
                    plinePoints.Reverse();
                    //由终点向起点方向搜索
                    JionLinesToPline(ref lineObjectIds, tr, ref plinePoints, currentLineId, currentLineId);
                    //本程序为将相连的直线段转成多段线,所以对孤立的直线段不做处理
                    if (plinePoints.Count > 2)
                    {
                        //创建多段线
                        Autodesk.AutoCAD.DatabaseServices.Polyline resultPline = new Autodesk.AutoCAD.DatabaseServices.Polyline();                       
                        for (int i = 0; i < plinePoints.Count-1; i++)
                        {
                            resultPline.AddVertexAt(i, new Point2d(plinePoints.X, plinePoints.Y), 0, 0, 0);
                        }
                        if (plinePoints[0] == plinePoints[plinePoints.Count - 1])
                        {
                            resultPline.Closed = true;
                        }
                        else
                        {
                            resultPline.AddVertexAt(plinePoints.Count - 1, new Point2d(plinePoints[plinePoints.Count - 1].X, plinePoints[plinePoints.Count - 1].Y), 0, 0, 0);
                        }
                        resultPline.Layer = currentLine.Layer;
                        resultPline.Linetype = currentLine.Linetype;
                        resultPline.LinetypeScale = currentLine.LinetypeScale;
                        currentSpace.AppendEntity(resultPline);
                        tr.AddNewlyCreatedDBObject(resultPline, true);
                        //删除起始直线段
                        currentLine.Erase();
                    }
                    //处理完毕,跳出循环
                    if (lineObjectIds.Count == 0)
                        break;
                }
                tr.Commit();
            }
        }
        /// <summary>
        /// 线段连接成多段线递归循环部分
        /// V1.0 by WeltionChen @2011.02.17
        /// </summary>
        /// <param name="lineObjectIds">线段的objectid集合</param>
        /// <param name="tr">transaction</param>
        /// <param name="plinePoints">多段线顶点坐标,也是各线段的端点坐标集合</param>
        /// <param name="currentLineId">当前线段的objectid</param>
        void JionLinesToPline(ref List<ObjectId> lineObjectIds, Transaction tr, ref List<Point3d> plinePoints, ObjectId currentLineId, ObjectId startLineId)
        {
            //提取端点
            Point3d lastPoint = plinePoints[plinePoints.Count - 1];
            Editor ed = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;
            SelectionFilter sf = new SelectionFilter(new TypedValue[] { new TypedValue(0, "Line") });
            //通过点创建选集
            PromptSelectionResult selectLinesResult = ed.SelectCrossingWindow(lastPoint, lastPoint, sf);
            if (selectLinesResult.Status == PromptStatus.OK)
            {
                List<ObjectId> selectedLinesId = new List<ObjectId>(selectLinesResult.Value.GetObjectIds());
                //剔除本身
                selectedLinesId.Remove(currentLineId);
                //处理相连的直线段
                if (selectedLinesId.Count == 1)
                {
                    ObjectId selectedLineId = selectedLinesId[0];
                    //处理过的直线段将不再作为起始线段,由集合中剔除
                    if (selectedLineId != startLineId)
                    {
                        lineObjectIds.Remove(selectedLineId);
                        Line selectedLine = tr.GetObject(selectedLineId, OpenMode.ForWrite) as Line;
                        //添加顶点
                        if (selectedLine.StartPoint == lastPoint)
                        {
                            plinePoints.Add(selectedLine.EndPoint);
                        }
                        else
                        {
                            plinePoints.Add(selectedLine.StartPoint);
                        }
                        //递归继续搜索
                        JionLinesToPline(ref lineObjectIds, tr, ref plinePoints, selectedLineId, startLineId);
                        //删除中间线段
                        selectedLine.Erase();
                    }                   
                }
            }
        }