首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >将AutoCAD中的折线与C#连接起来

将AutoCAD中的折线与C#连接起来
EN

Stack Overflow用户
提问于 2016-10-19 15:09:32
回答 3查看 3K关注 0票数 1

我试图选择一个特定层的所有多边形,然后加入他们与正常的autocad _JOIN命令。因为某种原因,我无法让它开始工作。

选择集被正确地找到,因为我可以循环它并改变polyline的颜色(只是为了测试目的)。

我在这里错过了什么/做错了什么?

代码语言:javascript
运行
复制
        [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));
            }
        }
    }
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-11-21 12:14:44

如果有人仍然关心这是我最后想出的最终结果,我会将所有实体保存到一个类的列表中,该类具有保存的多行的实体、起始点和端点。

然后比较列表中元素的起始点和端点是否匹配,并将它们与entity.join()连接起来。

代码语言:javascript
运行
复制
        /// <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);
    }
票数 2
EN

Stack Overflow用户

发布于 2016-10-20 10:26:46

编辑器命令似乎与客户端联接不同。

作为解决办法,我现在使用以下方法:

代码语言:javascript
运行
复制
doc.SendStringToExecute("._JOIN\n_p\n\n", true, false, false);

我对此并不百分之百满意,但这是我现在必须要做的。

票数 0
EN

Stack Overflow用户

发布于 2016-10-20 15:31:08

正确的方法(如果您使用的是AutoCAD >= 2013的版本)是使用Polyline.JoinEntities方法。

别忘了读医生:

Polyline.JoinEntities要求给定的实体是共享公共起点或终结点的其他、未关闭的折线或Polyline2d、Line和/或Arc实体。

要处理3D多边形,您必须将它们转换为线条/2D多边形(当然,所有实体都必须在同一平面上)。

这里有一个示例:http://adndevblog.typepad.com/autocad/2012/05/joining-2d-3d-polylines.html

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40135332

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档