【AutoCad 2025】【C#】零基础教程(二)——遍历 Entity 插件 =》 AutoCAD 核心对象层级结构

文章目录

  • 相关教程
  • 相关文献
  • [遍历 Entity](#遍历 Entity)
    • [获取 ModelSpace 中所有实体数量](#获取 ModelSpace 中所有实体数量)
    • [📌 补充说明](#📌 补充说明)
    • [🔁 如果你想统计整个数据库中的所有 Entity(包括块定义中的)](#🔁 如果你想统计整个数据库中的所有 Entity(包括块定义中的))
  • [🧱 AutoCAD 核心对象层级结构(简化版)](#🧱 AutoCAD 核心对象层级结构(简化版))
    • [🔍 关键概念解释](#🔍 关键概念解释)
      • [1. **Application**](#1. Application)
      • [2. **Document**](#2. Document)
      • [3. **Database(最重要!)**](#3. Database(最重要!))
      • [4. **Entity**](#4. Entity)
      • [5. **BlockTable & BlockTableRecord**](#5. BlockTable & BlockTableRecord)
    • [📦 对应的 C# 类型(来自 `acdbmgd.dll`)](# 类型(来自 acdbmgd.dll))
    • [🎯 总结一句话:](#🎯 总结一句话:)

作者:小猪快跑

基础数学&计算数学,从事优化领域8年+,主要研究方向:MIP求解器、整数规划、随机规划、智能优化算法

笔者也是从零开始学习并使用 c# & Python 二次开发 AutoCad 2025。本系列教程会从最基础的项目构建开始,到最终完成复杂插件开发。

如有错误,欢迎指正。如有更好的算法,也欢迎交流!!!------@小猪快跑

相关教程

C#

Python

相关文献

遍历 Entity

获取 ModelSpace 中所有实体数量

csharp 复制代码
using System.Diagnostics;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Runtime;
using Application = Autodesk.AutoCAD.ApplicationServices.Core.Application;

// 注册命令类
[assembly: CommandClass(typeof(AutoCad_CSharp.CountEntities))]

namespace AutoCad_CSharp
{
    public class CountEntities
    {
        [CommandMethod("CountAllEntities")]
        public void CountAllEntitiesInModelSpace()
        {
            // 获取当前文档和数据库
            var doc = Application.DocumentManager.MdiActiveDocument;
            var db = doc.Database;
            var ed = doc.Editor;

            var entityCount = 0;

            // 启动事务
            using (var tr = db.TransactionManager.StartTransaction())
            {
                // 打开 BlockTable
                var bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
                // 打开 ModelSpace(通常用于绘图)
                var modelSpace = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead) as BlockTableRecord;

                // 遍历 ModelSpace 中的所有对象
                foreach (var id in modelSpace)
                {
                    // 检查是否为 Entity(图形实体,如 Line、Circle 等)
                    if (id.ObjectClass.IsDerivedFrom(RXObject.GetClass(typeof(Entity))))
                    {
                        entityCount++;
                    }
                }

                tr.Commit();
            }

            // 输出结果到命令行
            ed.WriteMessage($"\n模型空间中共有 {entityCount} 个实体。\n");
        }
    }
}

于是我们载入插件,在 AutoCad 中运行


📌 补充说明

  • 如果你也想统计 PaperSpace(布局空间) 中的实体,可以类似地遍历 BlockTableRecord.PaperSpace 或其他布局对应的 BlockTableRecord
  • 上述代码仅统计 直接位于 ModelSpace 中的实体,不包括嵌套在块引用(BlockReference)内部的实体。如果你需要递归统计所有嵌套实体,逻辑会更复杂。
  • Entity 是所有图形对象(Line、Circle、Polyline 等)的基类,但不包括非图形对象(如 Layer、TextStyle 等)。

🔁 如果你想统计整个数据库中的所有 Entity(包括块定义中的)

你可以遍历所有 BlockTableRecord

csharp 复制代码
foreach (ObjectId btrId in bt)
{
    BlockTableRecord btr = tr.GetObject(btrId, OpenMode.ForRead) as BlockTableRecord;
    foreach (ObjectId id in btr)
    {
        if (id.ObjectClass.IsDerivedFrom(RXObject.GetClass(typeof(Entity))))
        {
            totalCount++;
        }
    }
}

但注意:这会包含所有块定义中的实体,可能远多于用户看到的图形数量。

🧱 AutoCAD 核心对象层级结构(简化版)

cmd 复制代码
Application
│
└── Document (当前打开的 DWG 文件)
    │
    ├── Database ← 所有图形数据的容器(核心!)
    │   │
    │   ├── BlockTable ← 块表(存储所有 BlockTableRecord)
    │   │   │
    │   │   ├── BlockTableRecord (ModelSpace) ← 模型空间 → 包含 Entity 对象
    │   │   │   │
    │   │   │   ├── Line        ← Entity
    │   │   │   ├── Circle      ← Entity
    │   │   │   ├── Polyline    ← Entity
    │   │   │   └── ...         ← 所有图形实体都继承自 Entity
    │   │   │
    │   │   ├── BlockTableRecord (PaperSpace) ← 图纸空间
    │   │   │
    │   │   └── BlockTableRecord ("MyBlock") ← 自定义块定义(也包含 Entity)
    │   │
    │   ├── LayerTable       ← 图层表(LayerTableRecord)
    │   ├── LinetypeTable    ← 线型表
    │   ├── TextStyleTable   ← 文字样式表
    │   └── ...              ← 其他命名对象表
    │
    └── Editor               ← 用于用户交互(如提示输入、写消息)

🔍 关键概念解释

1. Application

  • 表示整个 AutoCAD 应用程序。
  • 通过 Autodesk.AutoCAD.ApplicationServices.Application 访问。
  • 可获取所有打开的文档:Application.DocumentManager.

2. Document

  • 表示一个打开的 .dwg 文件(即一个绘图窗口)。

  • 每个 Document 有一个唯一的 Database

  • 获取方式:

    csharp 复制代码
    Document doc = Application.DocumentManager.MdiActiveDocument;

3. Database(最重要!)

  • 所有图形数据的根容器
  • 不管是实体(Line)、图层(Layer)、块(Block),都存在 Database 中。
  • 实体并不直接属于 Document,而是属于 Database 中的 BlockTableRecord(如 ModelSpace)。

纠正误区

❌ "Document 下面有 Entity" → 不准确

✅ "Document → Database → BlockTable → BlockTableRecord (ModelSpace) → Entity"

4. Entity

  • 所有图形对象的基类(抽象类)。
  • 派生类包括:Line, Circle, Polyline, Text, MText, Dimension 等。
  • 只有 Entity 或其子类才会在图形中显示
  • 所有 Entity 都必须位于某个 BlockTableRecord 中(通常是 ModelSpace 或 PaperSpace)。

5. BlockTable & BlockTableRecord

  • BlockTable:数据库中的"块表",类似目录。
  • BlockTableRecord:代表一个具体的"空间"或"块定义"。
    • BlockTableRecord.ModelSpace:模型空间(主绘图区)
    • BlockTableRecord.PaperSpace:图纸空间(布局)
    • 其他:用户自定义的块(如 "Chair" 块)

每个 BlockTableRecord 内部是一个 ObjectId 集合 ,每个 ObjectId 指向一个数据库对象(可能是 Entity,也可能是其他对象如 DimensionStyle,但通常我们只关心 Entity)。


📦 对应的 C# 类型(来自 acdbmgd.dll

AutoCAD 概念 .NET 类名
Application Autodesk.AutoCAD.ApplicationServices.Application
Document Autodesk.AutoCAD.ApplicationServices.Document
Database Autodesk.AutoCAD.DatabaseServices.Database
BlockTable Autodesk.AutoCAD.DatabaseServices.BlockTable
BlockTableRecord Autodesk.AutoCAD.DatabaseServices.BlockTableRecord
Entity(基类) Autodesk.AutoCAD.DatabaseServices.Entity
Line / Circle 等 Line, Circle 等(均继承自 Entity

🎯 总结一句话:

AutoCAD 中的所有图形实体(Entity)都存储在 Database 的 BlockTableRecord(如 ModelSpace)中,而 Document 是用户界面与 Database 之间的桥梁。

相关推荐
Dxy12393102162 小时前
Python字符串处理全攻略
开发语言·python
毕设源码-朱学姐2 小时前
【开题答辩全过程】以 基于Java的失物招领系统设计与实现为例,包含答辩的问题和答案
java·开发语言
Gomiko2 小时前
JavaScript进阶(四):DOM监听
开发语言·javascript·ecmascript
清晓粼溪2 小时前
统一异常处理
java·开发语言
syt_10133 小时前
grid布局之-子项放置4
开发语言·javascript·ecmascript
喵了meme3 小时前
C语言实战2
c语言·开发语言·网络
烛阴3 小时前
C# Dictionary 入门:用键值对告别低效遍历
前端·c#
charlie1145141913 小时前
现代C++工程实践:简单的IniParser3——改进我们的split
开发语言·c++·笔记·学习
fish_xk3 小时前
c++的引用和类的初见
开发语言·c++