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