块表记录是包裹实体对象的最后一层包装了,接下来让我们继续利用MgdDbg工具查看上一小节创建的块定义内的对象有哪些。

操作步骤如下:选择块表记录TestBlock,在右侧列表中找到“Entities within block”,选中该行并单击鼠标左键,弹出Snoop Objects对话框,列表中显示出了创建块定义时选择的两个对象:圆和直线。(下图中BED、BEE分别为实体对象的句柄(Handle))。

图 4‑10 TestBlock块表记录中的实体对象

如果刚才创建块时,您选择了删除所选对象,此时模型空间应该是不存在实体对象的,如果您选择*Model_Space块表记录,可以发现Entities within block为常规字体,没有加粗,点击时不会弹出对话框。

如果你选择的是保留所选对象,此时模型空间是存在一个圆和一条直线的,*Model_Space块表记录中的实体对象与TestBlock块表记录中的实体对象一致。(注意截图中选中的块表记录与上图不同)

图 4‑11 *Model_Space块表记录中的实体对象

如果你选择的是转换为块,此时模型空间中有一个块参照,*Model_Space块表记录中的实体对象为块参照。

图 4‑12 *Model_Space块表记录中的实体对象

再次回想之前我们利用命令Block创建块的过程:

操作

块表变化

块表记录变化

模型空间创建实体

无变化

*Model_Space内增加实体

创建块定义

增加块表记录TestBlock

TestBlock内增加实体

创建块时的不同选项

保留

无变化

不变

转换为块

无变化

*Model_Space中实体被删除,增加块参照

删除

无变化

*Model_Space中实体被删除

注:1.表中的实体指的是用于创建块的实体,例如之前示例中的圆和直线。

2.如果用命令Bedit来创建块,上述块表及块表记录的变化会有多不同。

接下来就让我看一下如何采用代码块表、块表记录及块表记录内部实体的查询。继续4.1.2 节的项目,在MyCommands类中添加以下代码:

 [CommandMethod("MyGroup", "ListEnts", CommandFlags.Modal)]

 public void ListEnts()

 {

     Document doc = Application.DocumentManager.MdiActiveDocument;   //活动文档

     Editor ed = doc.Editor;                                    //获取编辑器

     Database db = doc.Database;                           //获取数据库

     //Database db = HostApplicationServices.WorkingDatabase;               //另一种方法

     ObjectId blockTblId = db.BlockTableId;                          //块表Id

     using (Transaction tr = db.TransactionManager.StartTransaction())

     {

         BlockTable bt = blockTblId.GetObject(                               //块表

             OpenMode.ForRead) as BlockTable;

         foreach (ObjectId btrId in bt)                              //遍历块表记录

         {

             BlockTableRecord btr = btrId.GetObject(

                 OpenMode.ForRead) as BlockTableRecord;

             ed.WriteMessage("\n块表记录:{0}", btr.Name);    //输出块表记录名称

             foreach (ObjectId entId in btr)                                //遍历实体

             {

                 DBObject obj = entId.GetObject(OpenMode.ForRead);

                 ed.WriteMessage("\n实体类型为:{0}\t句柄:{1}",

                     obj.GetType().Name, obj.Handle);          //类型名称及句柄

             }

         }

         tr.Commit();

     }

 }

这段代码输出了每条块表记录的名称,并遍历块表记录的实体,输出实体类型与句柄。代码第6行通过活动文档获取数据库,第7行(注释掉的一行)采用另一种方法获取了当前正在操作的数据库(注意:这种方法获取的数据库并不一定是活动文档的数据库,您需要查阅更多资料);代码第8行通过数据库获得块表的Id;代码第11、12行打开块表;代码第13行针对块表中的每一个ObjectId进行循环操作,这个Id是块表记录的Id;代码第15、16行代开块表记录;代码第13行针对块表记录中的每一个ObjectId进行循环操作,这个Id是数据库对象(实体)的Id。阅读这段代码,您应该把重点放在理解对象之间层级关系上,至于如何打开对象、获取对象属性等操作并不是重点。

代码第9行中涉及到的事务(Transaction)、第11、12行涉及到的由ObjectId获取Object后续章节中详细讲述。

再次回想一下刚才的操作过程:获取文档、获取数据库、从数据库中找到块表、块表内部是块表记录、块表记录内是实体。一层又一层的包装箱,如果您能清楚的知道刚才拆了几层包装箱,说明您对数据库之间的层级关系也就明白了。

编译、加载项目,打开之前的dwg文件,输入命令ListEnts,看到的结果与下图类似;如果您是在其他图形文件,例如用_AutoCAD Civil 3D (Metric) NCS.dwt样板文件创建的图形,这里列出的块表记录会很多。

图 4‑13 代码运行结果

(注:前后几个截图中实体句柄不同是因为我并不是利用一个图形文件完成的测试)

您可能早就想到这样一个问题:如何直接获取模型空间或某个图纸空间的呢?

在MyCommands类中添加以下代码:

 [CommandMethod("MyGroup", "ListBlkRcd", CommandFlags.Modal)]

 public void ListBlkRcd()

 {

     string[] btrNames = new string[]{

             "*Model_Space","*model_space","*Paper_Space",

             "*Paper_Space0", "*Paper_Space1", "*Paper_Space2",

             "Line","TestBlock","Something",

             BlockTableRecord.ModelSpace,BlockTableRecord.PaperSpace};

     Document doc = Application.DocumentManager.MdiActiveDocument;   //活动文档

     Editor ed = doc.Editor;                                          //获取编辑器

     Database db = doc.Database;                                    //获取数据库

     //Database db = HostApplicationServices.WorkingDatabase;

     ObjectId blockTblId = db.BlockTableId;                                //块表Id

     using (Transaction tr = db.TransactionManager.StartTransaction())

     {

         BlockTable bt = blockTblId.GetObject(                             //块表

             OpenMode.ForRead) as BlockTable;

         foreach (string btrName in btrNames)                   //遍历每一名称

         {

             if (bt.Has(btrName))                                    //判断是否存在

             {

                 BlockTableRecord btr = bt[btrName].GetObject(

                     OpenMode.ForRead) as BlockTableRecord;

                 ed.WriteMessage("\n块表记录{0}找到了!\t句柄:{1}",

                     btr.Name, btr.Handle);                         //输出名称及句柄

             }

             else

             {

                 ed.WriteMessage("\n块表记录{0}不存在!", btrName);

             }

         }

         tr.Commit();

     }

 }

因为目前没有涉及到输入操作,因此代码第4-8行用字符串数组存储了若干块表记录名称,注意其大小写,代码第8行中的两个“字符串”是类BlockTableRecord中的两个静态属性,用于返回模型空间及图纸空间的名称。代码第18行对每一块表记录名称进行循环操作;代码第20-30行根据是否存在相应的块表记录输出不同的信息。

代码第22行bt[btrName]用于获取与名称btrName对应的块表记录的ObjectId,是此段代码的核心。也就是说,我们可以通过名称来获取块表记录的Id,之后就可以进行其他操作。

经过测试,名称字符串的大小写并不敏感,"*Model_Space"、"*model_space"都能顺利获取到模型空间。

图 4‑14 块表记录查询结果

图 4‑15

了解AutoCAD对象层次结构 —— 6 ——块表记录的更多相关文章

  1. 了解AutoCAD对象层次结构 —— 5 —— 块表

    为了清楚的了解块表的组成内容,让我们利用MgdDbg工具查看一下块表中的块表记录.在开始页面,以无样板模式新建一个.dwg文件(图 4‑7(1)),这样的话,默认的块表记录只有3条(图 4‑7(2)) ...

  2. 了解AutoCAD对象层次结构 —— 4 —— 符号表

    上一小节我们看到了符号表包含了一系列的表(共9个),这些表数量是固定的,用户不能增加新的表,也不能删除现有的表. 符号表名称 符号表功能 Block Table 块表 存储图形数据库中定义的块.此表中 ...

  3. 了解AutoCAD对象层次结构 —— 2 ——文档

    再次想象另外一个场景:启动AutoCAD程序后,您新建了两个.dwg文件,也就是说创建了两个文档(Document)对象.将窗口进行层叠,您看到的窗口应该与下图类似: 图 4‑3 如何访问这些文档呢? ...

  4. 了解AutoCAD对象层次结构 —— 1 ——应用程序

    想象这样一个场景:当您开始一天的工作,坐到电脑前面,用鼠标双击桌面上的AutoCAD Civil 3D图标,这时一个AutoCAD Civil 3D应用程序将运行起来.打开Windows任务管理器,我 ...

  5. 了解AutoCAD对象层次结构 —— 3 ——数据库

    数据库的结构是什么样的?对象是如何存储在数据库中的?这些问题我们需要搞明白.在此我们可以借助工具ArxDbg或MgdDbg来查看数据库结构及其内容.下图就是利用MgdDbg工具查看到的内容,我们可以看 ...

  6. Civil 3D 二次开发 创建AutoCAD对象—— 01 —— 创建直线

    在方法CreateLine内完成以下代码: 01 public void CreateLine() 02 { 03 PromptPointOptions ppo = new PromptPointOp ...

  7. 获得指定数据库中指定块表中所有实体的id

    该函数也使用外部指定图纸中的数据库中的块 Int getIdsByDwgBlkName(AcDbDatabase *pDwg, CString strBlkName, AcDbObjectIdArra ...

  8. {django模型层(二)多表操作}一 创建模型 二 添加表记录 三 基于对象的跨表查询 四 基于双下划线的跨表查询 五 聚合查询、分组查询、F查询和Q查询

    Django基础五之django模型层(二)多表操作 本节目录 一 创建模型 二 添加表记录 三 基于对象的跨表查询 四 基于双下划线的跨表查询 五 聚合查询.分组查询.F查询和Q查询 六 xxx 七 ...

  9. MyBatis 用户表记录数查询

    搭建MyBatis开发环境,实现用户表记录数查询 1.在MyEclipse中创建工程,导入MyBatis的jar包

随机推荐

  1. Python实现分发数据块到多台服务器上

    代码如下: # coding: utf-8 import paramiko import re import os from time import sleep # 定义一个类,表示一台远端linux ...

  2. 深入浅出Tomcat/3 - Tomcat生命周期

    在上面的部分,其实我们已经接触到Tomcat的生命周期了,接下来我们将仔细讨论和学习Tomcat的生命周期的具体实现. LifeCycle接口 这个LifeCycle接口上面在讲解Server和Ser ...

  3. Faster R-CNN:详解目标检测的实现过程

    本文详细解释了 Faster R-CNN 的网络架构和工作流,一步步带领读者理解目标检测的工作原理,作者本人也提供了 Luminoth 实现,供大家参考.   Luminoth 实现:https:// ...

  4. linux if -d -e -f表达的意思

    文件表达式-e filename 如果 filename存在,则为真-d filename 如果 filename为目录,则为真 -f filename 如果 filename为常规文件,则为真-L ...

  5. C++类的描述

    类的描述分为两个部分,public和private public可以用来定义函数,对类的对象进行操作,对于用户是可见的,是用户对对象操作的唯一手段. private部分用于定义函数和数据成员,这些函数 ...

  6. 培训班课程课时及费用管理系统V3.0,适合钢琴培训班、艺术培训班等

    联系QQ 564955427. ACM3.02 文件下载                    还有: 预收课时版 特点: 1. 适合主要业务是一对一课程和部分集体课培训的中小培训班(非连锁管理).考 ...

  7. 在Git中添加一个项目

    首先保证Git服务器正确配置,管理员机器可正常连接并使用Git. 第一步:在服务器上新建一个项目仓库 切换到git用户: a@ubuntu:/home/git$ su - git $ cd /home ...

  8. WCF使用相关

    1.不显示WCF服务主机 在WCF项目属性中的WCF选项卡总关闭下图的选项 2.在其他项目中承载WCF服务 其他加载的操作一致,需要把WCF的endpoint和behavior节点复制到 启动服务的那 ...

  9. Linux系统中常用的命令汇总

    日常开发,上线的服务器系统一般都是Linux系统,所以,熟练的掌握常用的命令操作就尤其的重要了 1) 查看某个服务的运行情况 (例如Redis) ps -ef | grep redis //e-显示程 ...

  10. 【Python3练习题 016】 猴子吃桃问题:猴子第一天摘下若干个桃子,当即吃了一半,还不瘾,又多吃了一个。第二天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下的一半零一个。到第10天早上想再吃时,见只剩下一个桃子了。求第一天共摘了多少。

    这题得倒着推.第10天还没吃,就剩1个,说明第9天吃完一半再吃1个还剩1个,假设第9天还没吃之前有桃子p个,可得:p * 1/2 - 1 = 1,可得 p = 4.以此类推,即可手算出. 代码思路为: ...