【问题标题】:How do I get all the entities on a specific layer in a .DWG file without opening the file (C#.NET/AutoCAD)?如何在不打开文件(C#.NET/AutoCAD)的情况下获取 .DWG 文件中特定图层上的所有实体?
【发布时间】:2017-04-25 01:45:34
【问题描述】:

我正在编写一个通过 AutoCAD .NET API 与 AutoCAD 交互的 C#.NET 程序。程序循环遍历目录中的 DWG 文件并检查“testLayer”层上的每个文本实体,看它是否与“testText”匹配。我通过打开每个文件并制作一个选择过滤器来获取“testLayer”层上的所有实体来实现这一点。

        Application.DocumentManager.Open(curfile.FullName, false);
        ....
        Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
        Document doc = Application.DocumentManager.MdiActiveDocument;
        Database db = doc.Database;

        using (Transaction acTrans = doc.TransactionManager.StartTransaction())
        {
            ObjectIdCollection ents = new ObjectIdCollection();

            // Set up filter and filter on layer name
            TypedValue[] tvs = new TypedValue[1] { new TypedValue((int)DxfCode.LayerName, "testLayer")};
            SelectionFilter sf = new SelectionFilter(tvs);
            PromptSelectionResult psr = ed.SelectAll(sf);

            if (psr.Status == PromptStatus.OK)
            {
                // Get the object ids for all of the entities for the filtered layer
                ents = new ObjectIdCollection(psr.Value.GetObjectIds());

                foreach (ObjectId objid in ents)
                {
                    DBText dbText = acTrans.GetObject(objid, OpenMode.ForRead) as DBText;
                    if (dbText.TextString.Contains("testText")
                    {
                         return dbText.TextString;
                    }
                }
                return "";
            }
            else
            {
                return "";
            }
        }           
    }

但现在我将我的程序转换为侧加载底层数据库,因为程序打开和关闭每个 .DWG 文件需要很长时间。问题是我现在正在使用

db.ReadDwgFile(currentDWG, FileOpenMode.OpenForReadAndAllShare, true, string.Empty);

读取文件而不实际打开它们,所以我不能使用

Editor ed = Application.DocumentManager.MdiActiveDocument.Editor

ed.SelectAll(sf) 用于我之前使用的选择过滤器策略,因为该文档实际上并未打开。那么如何在不实际打开 DWG 文件的情况下获取每个名为“testLayer”的图层上的所有文本实体呢?

【问题讨论】:

    标签: c# .net autocad


    【解决方案1】:

    在“侧数据库”中,要模仿 SelectAll,您必须遍历所有布局中的所有实体并检查实体层。

    编辑:在“侧面数据库”中,要模仿 SelectAll,您必须遍历所有布局中的所有实体并检查实体 type 和层。

        private IEnumerable<ObjectId> GetTextEntitiesOnLayer(Database db, string layerName)
        {
            using (var tr = db.TransactionManager.StartOpenCloseTransaction())
            {
                var blockTable = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
                foreach (ObjectId btrId in blockTable)
                {
                    var btr = (BlockTableRecord)tr.GetObject(btrId, OpenMode.ForRead);
                    var textClass = RXObject.GetClass(typeof(DBText));
                    if (btr.IsLayout)
                    {
                        foreach (ObjectId id in btr)
                        {
                            if (id.ObjectClass == textClass)
                            {
                                var text = (DBText)tr.GetObject(id, OpenMode.ForRead);
                                if (text.Layer.Equals(layerName, System.StringComparison.CurrentCultureIgnoreCase))
                                {
                                    yield return id;
                                }
                            }
                        }
                    }
                }
            }
        }
    

    【讨论】:

    • var textClass = RXObject.GetClass(typeof(DBText)); 不需要在循环内。把它放在循环之前,这样它只会发生一次,它会快一点。
    猜你喜欢
    • 2011-09-26
    • 1970-01-01
    • 2020-01-18
    • 2010-11-04
    • 2020-04-26
    • 2012-06-02
    • 2015-11-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多