ObjectARX帮助 > ObjectARX开发实例教程 > 第5章 使用 ADSRX > 5.3 选择集 >
5.3.2 思路
后退前进

      1.选择集的创建和删除

      选择集是 AutoCAD 当前图形中的一组实体,通过图元名进行引用,也就是一个 ads_name变量。创建选择集可以使用 acedSSAdd 和 acedSSGet 函数,其中 acedSSGet 函数提供了绝大多数创建选择集的方法:

      ■ 提示用户选择实体。

      ■ 使用 PICKFIRST 选择集(在未执行命令时用户已经选择的图形集合,也就是AutoCAD 中的先选择、再输入命令)或者交叉(Crossing)、多变性交叉(CrossingPolygon)、栅栏(Fence)、最后一个(Last)、前一个(Previous)、窗口(Window)、多边形窗口(Window Polygon)等方式,也可以指定一个点或者一系列点来明确地限定所要选择的实体。

      ■ 指定选择实体所要满足的一系列属性和条件来过滤当前数据库,可以和前面的选择方式配合使用。

      无论使用 acedSSAdd 还是 acedSSGet 函数,都需要在程序结束之前使用 acedSSFree 函数释放选择集的内存空间。

      2.选择集中元素的增加和删除

      这里所说的元素增加和删除,仅指在已经获得对象引用的情况下,使用 acedSSAdd 和acedSSDel 函数对选择集进行元素的增加和删除。

      acedSSAdd 函数定义为:

        int acedSSAdd(const ads_name ename, const ads_name sname, ads_name result);    

      其中,ename  指定要添加到选择集的实体的图元名;
               sname  指定选择集的图元名;
               result   返回被创建或者更新的选择集。
      根据 ename 和 sname 的不同取值,acedSSAdd 有以下几种可能的执行结果:

       ■ 如果 ename 和 sname 都是空指针,则创建一个未包含任何成员的选择集。

       ■ 如果 ename 指向一个有效的实体,但 sname 是空指针,则创建一个选择集,该选择集仅包含一个成员 ename。

       ■ 如果 ename 指向有效的实体,且 sname 指向有效的选择集,则将 ename 所指向的实体添加到 sname 所指向的选择集中。

      acedSSDel 函数定义为:

        int acedSSDel(const ads_name ename, const ads_name ss);    

      其中,ename 指定了要从选择集中删除的实体;
               ss       指定了所要操作的选择集。

      3.对象选择的方法

      所谓对象选择的方法,就是以某种方式从图形窗口中获得满足某些条件的图形对象。这里要介绍的是使用 acedSSGet 函数所实现的选择对象的方法,该函数被定义为:

        int acedSSGet (const char *str,
                      const void *pt1,
                      const void *pt2,
                      const struct resbuf *entmask,
                      ads_name ss);
    

      其中,str            参数描述了创建选择集的方法,可以使用的参数值参见表 5-1;
               pt1 和 pt2 为相关的创建方式提供了点参数,如果不需要指定可以输入 NULL 作为参数值;
               entmask    用于指定选择实体的过滤条件;
               ss             则指定了要操作的选择集的图元名。

表 5-1 acedSSGet 函数的选择模式选项

 值(选择模式)

 说 明

 NULL

 单点选择(如果指定了 pt1)或者提示用户选择(如果 pt1的值为 NULL)

 #

 非几何选择模式(包括 All、Last 和 Previous 选择模式)

 :$

 仅提供提示(Prompts supplied)

 .

 用户选择模式

 :?

 其他回调选择模式(Other callbacks)

 A

 全部选择

 B

 框选模式

 C

 窗交选择模式

 CP

 圈交选择模式(选择多边形(通过在待选对象周围指定点来定义)内部或与之相交的所有对象)

 :D

 允许复制选择模式(Duplicates OK)

 :E

 小孔中的所有实体(Everything in aperture)

 F

 栏选模式

 G

 选择编组

 I

 获得当前图形窗口中已经选择的实体(PickFirst 选择集)

 :K

 键盘回调选择模式(Keyword callbacks)

 L

 选择最近一次创建的可见实体

 M

 指定多次选择而不高亮显示对象,从而加快对复杂对象的选择过程

 P

 选择最近创建的选择集

 :S

 单一对象选择模式

 W

 窗口选择模式

 WP

 圈围选择模式

 X

 过滤选择模式

       4.使用选择集过滤器

      在使用各种选择对象的方法时,可以使用过滤器来限定选择的对象。例如,可以指定仅选择图层 0 上的直线对象,也可以指定仅选择蓝色的半径大于 30 的圆,等等。

      如果仅使用一个过滤条件,可以使用下面的代码:

        struct resbuf rb;
        char sbuf[10];
                                   // 存储字符串的缓冲区
        ads_name ssname;
        rb.restype = 0;            // 实体名
        strcpy(sbuf, "CIRCLE");
        rb.resval.rstring = sbuf;
        rb.rbnext = NULL;          // 不需要设置其他的属性
                                   // 选择图形中所有的圆
        acedSSGet("X", NULL, NULL, &rb, ssname);
        acedSSFree(ssname);
    

      上面的代码中虽然使用了结果缓冲区,但是仅是在栈上声明,由编译器自动管理它所使用的内存空间,不需要使用 acutRelRb 函数来手工销毁它。

      如果要指定多个过滤条件,可以使用 acutBuildList 函数来构造结果缓冲区。如果要选择当前图形窗口中位于 0 层上的所有直线,就可以使用下面的方法:

        struct resbuf *rb; // 结果缓冲区链表
        ads_name ssname;
        rb = acutBuildList(RTDXF0, "LINE",   // 实体类型
                           8, "0",           // 图层
                           RTNONE);
        // 选择图形中位于0层上的所有直线
        acedSSGet("X", NULL, NULL, rb, ssname);
        acutRelRb(rb);
        acedSSFree(ssname);
    

      在标准的 DXF 组码中,0 用于表示实体类型,但是在 acutBuildList 函数中 0 也可以用于表示结束链表,因此用 RTDXF0 来代替 0。

      过滤器列表由成对的参数组成。第一个参数标识过滤器的类型(例如对象),第二个参数指定要过滤的值(例如圆)。过滤器类型是指定使用哪种过滤器的 DXF 组码,下面列出了一些最常用的过滤器类型:

      ■ 0:对象类型(字符串),例如“Line”、“Arc”等。

      ■ 1:图元的主文字值(字符串),例如文字、属性的字符串内容。

      ■ 2:对象名(字符串),例如属性标记、块名等。

      ■ 8:图层名(字符串)。

      ■ 10:主要点(直线或文字图元的起点、圆的圆心等),用三个实数的数组来表示三维点。

      ■ 60:对象可见性(整数),0 表示可见,1 表示不可见。

      ■ 62:颜色编号(整数),可取 0~256 的整数值,其中 0 表示 ByBlock,256 表示 ByLayer。

      ■ 67:模型/图纸空间标识符(整数),0(默认)表示在模型空间,1 表示在图纸空间。

      ■ 1000:扩展数据中的 ASCII 字符串,最多可以包含 255 个字节。

      ■ 1001:扩展数据的注册应用程序名,最多可以包含 31 个字节的 ASCII 字符串。

      ■ 1003:扩展数据图层名。

      关于DXF组码的完整列表,可以参考“DXF参考”中的内容(AutoCAD 2002 中文版帮助系统中的DXF参考是英文的,因此这里使用的是AutoCAD 2005 中文版的帮助系统),如图5.7所示。

图5.7 完整的 DXF 组码参考

      值得一提的是,在大部分选择模式中均可以使用选择集过滤器,下面的代码提示用户选择实体的同时使用了选择集过滤器:

     acedSSGet(NULL, NULL, NULL, rb, ssname);    


ObjectARX开发实例教程(张帆)