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, |
其中,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; |
上面的代码中虽然使用了结果缓冲区,但是仅是在栈上声明,由编译器自动管理它所使用的内存空间,不需要使用 acutRelRb 函数来手工销毁它。
如果要指定多个过滤条件,可以使用 acutBuildList 函数来构造结果缓冲区。如果要选择当前图形窗口中位于 0 层上的所有直线,就可以使用下面的方法:
struct resbuf *rb; //
结果缓冲区链表 |
在标准的 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); |