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();
                    }                   
                }
            }
        }
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM