我正在尝试选择特定图层的所有折线,然后使用普通的autocad _JOIN命令将它们连接起来。出于某种原因,我无法让它发挥作用。
正确找到了选择集,因为我可以遍历它并改变折线的颜色(只是为测试目的而做)
我在这里错过/做错了什么?
[CommandMethod("JOINPOLY",
CommandFlags.UsePickSet |
CommandFlags.Redraw |
CommandFlags.Modal)]
public void SelectAllPolylineByLayer()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
try
{
// create the typevalue (criteria what should be selected)
TypedValue[] tvs = new TypedValue[] {
new TypedValue(Convert.ToInt32(DxfCode.Operator), "<and"),
new TypedValue(Convert.ToInt32(DxfCode.LayerName), "Test unlocked"),
new TypedValue(Convert.ToInt32(DxfCode.Operator), "<or"),
new TypedValue(Convert.ToInt32(DxfCode.Start), "POLYLINE"),
new TypedValue(Convert.ToInt32(DxfCode.Start), "LWPOLYLINE"),
new TypedValue(Convert.ToInt32(DxfCode.Start), "POLYLINE2D"),
new TypedValue(Convert.ToInt32(DxfCode.Start), "POLYLINE3d"),
new TypedValue(Convert.ToInt32(DxfCode.Operator), "or>"),
new TypedValue(Convert.ToInt32(DxfCode.Operator), "and>")
};
// create a selectionfilter out of our created typevalue
SelectionFilter oSf = new SelectionFilter(tvs);
PromptSelectionResult selRes = ed.SelectAll(oSf);
// if there is a problemw ith the promtselection stop here
if (selRes.Status != PromptStatus.OK)
{
ed.WriteMessage("\nError in getting the selectAll");
return;
}
SelectionSet ss = selRes.Value;
ed.Command("_JOIN", ss, "");
tr.Commit();
}
//Catch the error and write the errormessage
catch (System.Exception ex)
{
ed.WriteMessage(Convert.ToString(ex));
}
}
}
答案 0 :(得分:1)
如果有人仍在关心这是我最终想出的最终结果 我将所有实体保存到一个类的列表中,该类包含保存折线的实体,起点和终点
然后我比较列表中元素的起点和终点是否匹配并将它们与entity.join()
连接起来 /// <summary>
/// Gets a layerName and tries to join all polylines on the given layer
/// sends back a little log message to display
/// </summary>
/// <param name="layerName"></param>
/// <returns></returns>
public static string JoinPolylineOnLayer(Database db, string layerName)
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
TypedValue[] tvs = null;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
LayerTable layerTable = (LayerTable)tr.GetObject(db.LayerTableId, OpenMode.ForRead);
try
{
// get layerid of the selected layer
var layerId = layerTable[layerName];
// open layer table record with write privileges
// if the layer is locked return with an error message that the layer cant be deleted
LayerTableRecord layer = (LayerTableRecord)tr.GetObject(layerId, OpenMode.ForWrite);
if (layer.IsLocked)
return "' cannot be merged(locked).";
// create the typevalue (criteria what should be selected)
tvs = new TypedValue[] {
new TypedValue(Convert.ToInt32(DxfCode.Operator), "<and"),
new TypedValue(Convert.ToInt32(DxfCode.LayerName), layerName),
new TypedValue(Convert.ToInt32(DxfCode.Operator), "<or"),
new TypedValue(Convert.ToInt32(DxfCode.Start), "POLYLINE"),
new TypedValue(Convert.ToInt32(DxfCode.Start), "LWPOLYLINE"),
new TypedValue(Convert.ToInt32(DxfCode.Start), "POLYLINE2D"),
new TypedValue(Convert.ToInt32(DxfCode.Start), "POLYLINE3D"),
new TypedValue(Convert.ToInt32(DxfCode.Operator), "or>"),
new TypedValue(Convert.ToInt32(DxfCode.Operator), "and>")
};
// create a list of the entities
List<PolylineClass> entities = FillListOfEntities(tvs, tr, ed);
for (int i = entities.Count - 1; i >= 0; i--)
{
for (int j = i - 1; j >= 0; j--)
{
try
{
// check if start/endpoints are the same
// if they are join them and reset the loops and start again
if ((entities[i].StartPoint == entities[j].StartPoint) ||
(entities[i].StartPoint == entities[j].EndPoint) ||
(entities[i].EndPoint == entities[j].StartPoint) ||
(entities[i].EndPoint == entities[j].EndPoint))
{
Entity srcPLine = entities[i].Ent;
Entity addPLine = entities[j].Ent;
// join both entities
srcPLine.UpgradeOpen();
srcPLine.JoinEntity(addPLine);
// delete the joined entity
addPLine.UpgradeOpen();
entities.RemoveAt(j);
addPLine.Erase();
// set new start and end point of the joined polyline
entities[i - 1] = new PolylineClass(srcPLine, GetStartPointData(srcPLine), GetEndPointData(srcPLine));
// reset i to the start (as it has changed)
i = entities.Count;
j = 0;
}
}
catch (System.Exception ex)
{
ed.WriteMessage("\nError: n{0}", ex.Message);
}
}
}
tr.Commit();
return "' have been joined";
}
//Catch the error and write the errormessage
catch (System.Exception ex)
{
return Convert.ToString(ex);
}
}
}
/// <summary>
/// Function to fill the entities list with a give TypedValue
/// </summary>
/// <param name="tvs"></param>
/// <param name="tr"></param>
/// <param name="ed"></param>
/// <returns></returns>
private static List<PolylineClass> FillListOfEntities(TypedValue[] tvs, Transaction tr, Editor ed)
{
SelectionFilter oSf = new SelectionFilter(tvs);
PromptSelectionResult selRes = ed.SelectAll(oSf);
// if there is a problemw ith the promtselection stop here
if (selRes.Status != PromptStatus.OK)
{
return null;
}
// declare a list and fill it with all elements from our selectionfilter
List<PolylineClass> entities = new List<PolylineClass>();
foreach (ObjectId obj in selRes.Value.GetObjectIds())
{
Entity ent = tr.GetObject(obj, OpenMode.ForRead) as Entity;
entities.Add(new PolylineClass(ent, GetStartPointData(ent), GetEndPointData(ent)));
}
return entities;
}
/// <summary>
/// Function to get the startpoint coordinates of a polyline
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
private static Point3d GetStartPointData(Entity obj)
{
// If a "lightweight" (or optimized) polyline
Polyline lwp = obj as Polyline;
if (lwp != null)
{
return new Point3d(lwp.GetPoint2dAt(0).X, lwp.GetPoint2dAt(0).Y, lwp.Elevation);
}
else
{
// If an old-style, 2D polyline
Polyline2d p2d = obj as Polyline2d;
if (p2d != null)
{
return new Point3d (p2d.StartPoint.X, p2d.StartPoint.Y, p2d.Elevation);
}
else
{
// If an old-style, 3D polyline
Polyline3d p3d = obj as Polyline3d;
if (p3d != null)
{
return p3d.StartPoint;
}
}
}
return new Point3d(0, 0, 0);
}
/// <summary>
/// Function to get the endpoint coordinates of a polyline
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
private static Point3d GetEndPointData(Entity obj)
{
// If a "lightweight" (or optimized) polyline
Polyline lwp = obj as Polyline;
if (lwp != null)
{
return new Point3d(lwp.GetPoint2dAt(lwp.NumberOfVertices - 1).X, lwp.GetPoint2dAt(lwp.NumberOfVertices - 1).Y, lwp.Elevation);
}
else
{
// If an old-style, 2D polyline
Polyline2d p2d = obj as Polyline2d;
if (p2d != null)
{
return new Point3d(p2d.EndPoint.X, p2d.EndPoint.Y, p2d.Elevation);
}
else
{
// If an old-style, 3D polyline
Polyline3d p3d = obj as Polyline3d;
if (p3d != null)
{
return p3d.EndPoint;
}
}
}
return new Point3d(0, 0, 0);
}
答案 1 :(得分:0)
编辑器命令似乎与客户端连接不同
作为解决方法我现在使用以下内容:
doc.SendStringToExecute("._JOIN\n_p\n\n", true, false, false);
我并不是百分之百满意,但那是我现在必须要做的事情。
答案 2 :(得分:0)
正确的方法(如果您使用的是AutoCAD&gt; = 2013版)是使用Polyline.JoinEntities
方法。
别忘了阅读文档:
Polyline.JoinEntities要求给定实体为其他未闭合的折线或Polyline2d,线和/或弧实体,它们共享共同的起点或终点。
要处理三维多段线,您必须将它们转换为线/二维多段线(当然所有实体必须位于同一平面内)。
此处有一个示例:http://adndevblog.typepad.com/autocad/2012/05/joining-2d-3d-polylines.html