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