天气与日历 切换到窄版

 找回密码
 立即注册
中国膜结构网
十大进口膜材评选 十大国产膜材评选 十大膜结构设计评选 十大膜结构公司评选
查看: 50|回复: 0

objectArx --- ADS篇

[复制链接]

该用户从未签到

主题

0

回帖

2912

积分

管理员

积分
2912
发表于 2024-6-22 09:46:18 | 显示全部楼层 |阅读模式
[code]目录
一、基本概念
1.1 基本定义
1.2 关键类型
二、数据类型
2.1 ads数据类型
2.2 类型转换
2.2.1 浮点数 与 字符串
2.2.2 角值 转换
2.2 结果缓冲区
2.2.1 定义
2.2.2 结果类型码
2.2.3 简单使用
2.2.4 链表命令
三、用户交互
3.1 函数返回码
3.2 常用
3.3 acedGetXXX函数
3.3.1 常规
3.3.2 acedInitGet
3.3.3 选择实体
3.4 选择集
3.4.1 常用函数
3.4.2 acedSSGet函数详解
四、系统变量
一、基本概念
1.1 基本定义
ADS:autocad design system 简称,早期CAD面向过程编程系统,现在整合入objectarx中
功能:对CAD全局参数编辑,提供与用户交互函数,头文件:adslib.h、adsdlg.h,默认已加入
1.2 关键类型
类型定义

类型名        特性
对象id
AcDbObjectId        在一个CAD进程中管理多个CAD文件,所有打开的数据库对象在内存中都有唯一的id,每个对象在每次加载后id值都不同,此对象是以下各类型的中介
实体名
ads_name        为ADS存储实体对象的临时变量,关闭文件即丢失,此对象通常用来接收用户选择实体或选择集
句柄
AcDbHandle        数据库文件dwg真实标记实体的数据类型,每次打开文件,同一实体,句柄不变
转换关系


二、数据类型
2.1 ads数据类型
包含:浮点型、整型、字符串、点、实体名
代码
// 整形
int num = 5;
// 打印写法:跟C语言printf一样
acutPrintf(_T("%d\n"), num);

// 浮点型:typedef double   ads_real;
ads_real r1=3.14;
acutPrintf(_T("%0.3f\n"), r1);

// 字符串型:以下二者可相互转换
ACHAR * str = _T("兼容性最好\n");
CString cstr = _T("此类为mfc项目默认字符串,函数更友好\n");
acutPrintf(str);
acutPrintf(cstr);

// 点:typedef ads_real ads_point[3];
ads_point pt1, pt2;
// 三个坐标不可留空
pt1[X] = pt1[Y] = pt1[Z] = 1.0;
// 点覆盖式赋值:用pt1赋值pt2
ads_point_set(pt1, pt2);
acutPrintf(_T("%0.3f\n"),pt2[X]);

// 实体名(由鼠标选择赋值),通常由其获得对象id
// typedef int64_t ads_name[2];
ads_name en, en1;
// 将en0深拷贝给en1
ads_name_set(en0, en1);

2.2 类型转换
2.2.1 浮点数 与 字符串
代码示例
ads_real rel = 1.23456789;
ACHAR str[12];
// 浮点数转字符串:浮点数、转换模式、小数位数、待接收字符串
// 转换正常ret为RTNORM,否则见第3.1节
int ret = acdbRToS(rel, 1, 3, str);
acutPrintf(str);

// 字符串转浮点数:字符串、转换模式、浮点数(注意取地址符)
ACHAR str_a[12]= _T("9.87654");
// ret用于存储结果类型码(本篇3.1) 判断是否正常转换:RTNORM为正常
// 转换正常ret为RTNORM,否则见第3.1节
ret = acdbDisToF(str_a,1,&rel);
acutPrintf(_T("\n%f"),rel);

转换模式:

1科学记数法:结果为1.235E+00
2十进制:结果为1.235
3工程、4建筑:略
5分数:结果为1 1/4
2.2.2 角值 转换
弧度 转 字符串(由控制符 控制 转换格式)
// 函数acdbAngToS参数:弧度值、控制符、精度、字符串指针
// 转换正常ret为RTNORM,否则见第3.1节

ACHAR str[12];
// 0弧度转角度
int ret = acdbAngToS(MathUtil::PI() / 4, 0, 4, str);
// 返回:45.0000,0都省略了
acutPrintf(_T("\n%s"),str);

// 1弧度转角度
ret = acdbAngToS(MathUtil::PI()/4, 1, 4, str);
// 返回:45d0'0"
acutPrintf(_T("\n%s"), str);

// 2弧度转工程
ret =acdbAngToS(MathUtil::PI() / 4, 2, 4, str);
// 返回:50g
acutPrintf(_T("\n%s"), str);

// 3弧度(ads_real)转弧度(字符串)(带r标识)
ret =acdbAngToS(MathUtil::PI() / 4, 3, 4, str);
// 返回:0.7854r
acutPrintf(_T("\n%s"), str);

角 转 浮点数
// 函数acdbAngToF参数:字符串(弧度/角度值)、控制符、浮点数
// 转换正常ret为RTNORM,否则见第3.1节

ads_real rel;
// 0:百分角度 转弧度
int ret = acdbAngToF(_T("45"), 0, &rel);
acutPrintf(_T("\n%.4f"),rel);

// 1:度分秒角度 转弧度
ret = acdbAngToF(_T("45d0'0\""), 0, &rel);
acutPrintf(_T("\n%.4f"), rel);

// 2:工程 转弧度
ret = acdbAngToF(_T("50g"), 0, &rel);
acutPrintf(_T("\n%.4f"), rel);

// 3:弧度(带r标识) 转弧度(不含r标识)
ret = acdbAngToF(_T("0.7854r"), 0, &rel);
acutPrintf(_T("\n%.4f"), rel);

关系:acdbAngTo与acdbAngToS为互补函数

2.2 结果缓冲区
功能:CAD中数据种类多样,需要有一个进行数据临时交换与存储的媒介
2.2.1 定义
源文件声明
// 结果缓冲区节点为结构体
struct resbuf {            
                // 用于构造单链表,未设置则为NULL                                 
        struct resbuf *rbnext;
        // 用于定义ads_u_val 的类型
        short restype;
        // 联合体:用于存储具体值
        union ads_u_val resval;
};

// 联合体ads_u_val的定义
union ads_u_val {
        // 浮点型:常用
    ads_real rreal;
    // 点:常用
    ads_real rpoint[3];
    // 短整型:常用
    short rint;
    // 字符串:常用
    ACHAR *rstring;
        // 剩下不常用略,可以转到结果缓冲区查看
};

2.2.2 结果类型码
类型码列表
#define RTNONE    5000 /* 无结果 */
#define RTREAL    5001 /* 浮点型 */
#define RTPOINT   5002 /* 2D点 */
#define RTSHORT   5003 /* 短整型 */
#define RTANG     5004 /* 角度 */
#define RTSTR     5005 /* 字符串 */
#define RTENAME   5006 /* 实体名 */
#define RTPICKS   5007 /* 选择集 */
#define RTORINT   5008 /* 方向*/
#define RT3DPOINT 5009 /* 3D点 */
#define RTLONG    5010 /* 长整型 */
#define RTVOID    5014 /* 空白符号 */
#define RTLB      5016 /* 列表开始 */
#define RTLE      5017 /* 列表结束 */
#define RTDOTE    5018 /* 点对 */
#define RTNIL     5019 /* 零*/
#define RTDXF0    5020 /* DXF码,仅供ads_buildlist使用 */
#define RTRESBUF  5023 /* 结果缓冲区 */

用于指定结果缓冲区节点的值类型

组码:特殊的类型码,≤1071的类型码有特殊含义,传送门
2.2.3 简单使用
结果缓冲区链表
void  test()
{        // 自制结果缓冲区的迭代器,提取链表每个节点
        resbuf* rb_iter;
        resbuf* cmdlist;
        ads_point pt1 = { 1,1,1 };
        int num = 3;
        // 函数:构建结果缓冲区链表
        cmdlist = acutBuildList(RTSTR,        _T("test"),
                                                        RTPOINT,pt1,
                                                        RTSHORT,num,
                                                        RTNONE);
        // 拷贝 链表 首节点 的 指针 给 迭代器
        rb_iter = cmdlist;
        // rb_iter的指针不为空
        while (rb_iter != NULL)
        {
                acutPrintf(_T("结果类型码:%d\n"), rb_iter->restype);
                switch (rb_iter->restype)
                {
                case RTSTR:
                        acutPrintf(_T("值为:%s\n"), rb_iter->resval.rstring);
                        break;
                case RTPOINT:
                        acutPrintf(_T("值为:%f\n"), rb_iter->resval.rpoint[X]);
                        break;
                case RTSHORT:
                        acutPrintf(_T("值为:%d\n"), rb_iter->resval.rint);
                        break;
                }
                rb_iter = rb_iter->rbnext;
        }
        acutPrintf(_T("执行完毕\n"));
        // 手动释放结果缓冲区
        acutRelRb(rb_iter);
        acutRelRb(cmdlist);
}

效果

2.2.4 链表命令
函数用法
// 必须包含头文件
#include "acedCmdNF.h"

// 模拟人工输入命令:隐式构建结果缓冲区链表
acedCommandS(RTSTR, _T("circle"),
                         RTSTR, _T("0,0"),
                         RTSTR, _T("300"),
                         RTNONE);

三、用户交互
3.1 函数返回码
功能:用于标识函数执行情况
常用返回码列表(重要)
#define RTNORM    5100 /* 正常 */

#define RTERROR          (-5001) // 其他错误
#define RTCAN            (-5002) // 用户按Ctl-C或ECS
#define RTREJ            (-5003) // AutoCAD拒绝的请求--无效
#define RTFAIL           (-5004) // 连接失败 -- Lisp脚本可能崩溃了
#define RTKWORD          (-5005) // 来自 getxxx() 的关键字
#define RTINPUTTRUNCATED (-5008) // 输入不完全适合缓冲区

3.2 常用
弹出警告框:acedAlert(_T("弹出警告框"));

命令行打印:acutPrintf(_T("跟C语言printf函数一样\n"));
捕捉离光标最近的中点、端点、中心点(最好关掉对象捕捉)
acedOsnap(pt, _T("midp,endp,center"), pt1);,pt是传入的点,pt1是返回的点
遍历全图实体(包括隐藏实体)
ads_name en0, en1;

// 遍历全图:首参数为null,则获取第一个元素的ads_name
if (acdbEntNext(NULL, en0) != RTNORM)
        return;
// acdbEntNext遍历链表,以首参数为参照,获取第二个参数ads_name
do
{        // 从ads_name获取对象id
        AcDbObjectId id;
        acdbGetObjectId(id, en0);
        // ld 长整型
        acutPrintf(_T("\n对象id为:%ld"), id);
        // acedUsrBrk()用于判断用户是否按下esc键
        if (acedUsrBrk())
                return;
        // 将en0深拷贝给en1
        ads_name_set(en0, en1);
// en1变为参考点,en0值被覆盖,从而获取下一个链表节点的ads_name
} while (acdbEntNext(en1, en0) == RTNORM);

3.3 acedGetXXX函数
3.3.1 常规
获取整型:acedGetInt

// 获取整型:提示字符串、变量地址(看函数头文件)
int num;
if (acedGetInt(_T("\n请输入整数:"), &num) == RTNORM)
        acutPrintf(_T("\n整数为:%d"),num);

获取浮点数:acedGetReal

// 获取浮点数:提示字符串、变量地址
ads_real num_real;
if (acedGetReal(_T("\n请输入浮点数:"), &num_real) == RTNORM)
        acutPrintf(_T("\n浮点数为:%0.3f"), num_real);

获取字符串:acedGetString

// 获得字符串:是否允许空格(1允许)、提示字符串、字符串指针、字符串变量长度(包括结尾\0)
// 如果超出长度ret返回RTINPUTTRUNCATED,超出的字符串丢弃,正常返回RTNORM
ACHAR str[6];
int ret = acedGetString(0, _T("\n请输入字符串:"), str, 6);
if ( ret == RTNORM)
        acutPrintf(_T("\n字符串为:%s"), str);
else
{
        acutPrintf(_T("\n结果返回码为:%d"), ret);
}

// 字符串正则匹配函数:待校验字符串指针、匹配规则
if (acutWcMatch(str, _T("ro*b"))==RTNORM) {
        acedAlert(_T("此字符串匹配了定义的正则表达式"));
}

获取点坐标:acedGetPoint

// 获取点坐标:是否允许空格(1允许)、提示字符串、点变量
ads_point pt;
if (acedGetPoint(0, _T("\n请选取点:"), pt) == RTNORM)
        acutPrintf(_T("\n点为:%f,%f"), pt[X],pt[Y]);
       
// 极坐标法获得点坐标:基点ads_point、弧度ads_real,极半径ads_real,返回点ads_point
acutPolar(pt,ang, 100.0, pt3);

获取夹角弧度:acedGetAngle

// 获取与三点钟方向夹角弧度:基准点(若为NULL则在屏幕上点)、提示字符串、接收弧度值
ads_point pt_ang = { 0,0,0 };
ads_real ang;
if (acedGetAngle(pt_ang, _T("\n请角度点:"), &ang) == RTNORM)
        acutPrintf(_T("\n角弧度为:%f"), ang);
       
// 方法2:直接计算pt与pt1线段与x轴正向夹角弧度
ads_real ang = acutAngle(pt, pt1);



方框内角度:非弧度,会跟着十字光标动态变化

获取两点间距离:acedGetDist

// 返回屏幕上两点间距离:基准点(若为NULL则在屏幕上点)、提示字符串,
ads_real distance;
if (acedGetDist(NULL, _T("\n请选择点:"), &distance) == RTNORM)
        acutPrintf(_T("\n距离为:%f"), distance);

3.3.2 acedInitGet
功能一:循环检测用户非法输入

关键字代码:

// 过滤用户非法输入,输入符合要求才能通过,可esc退出
acedInitGet(RSG_NONEG + RSG_NOZERO + RSG_NONULL, NULL);
int num;
if (acedGetInt(_T("\n请输入整数:"), &num) == RTNORM)
        acutPrintf(_T("\n整数为:%d"),num);

控制位开关:

非负:RSG_NONEG ,非零 RSG_NOZERO,非空RSG_NONULL
开启橡皮筋或虚矩形追踪RSG_DASH
去掉Z坐标:RSG_2D,仅用于acedGetDist
特点:仅对紧跟着的那个acedGetXXX函数起效


功能二:关键字选项控制

// 禁止输入空,并明确关键字为以下四个(空格分隔)
acedInitGet(RSG_NONULL, _T("1 2 3 4"));
ACHAR kw[5];
// 这是控制关键字显示:见下面效果图
acedGetKword(_T("\n选择一个关键字[ONE(1)/TWO(2)/THREE(3)]:"), kw);
switch (tc)
{
case RTCAN:
        acutPrintf(_T("\n你取消了输入"));
        break;
case RTNORM:
        if (_tcscmp(kw, _T("1")) == 0)
        {        // 可以通过关键字跳转其他程序处理后续
                acutPrintf(_T("\n你选择了1"));
                break;
        }
        else if (_tcscmp(kw, _T("2")) == 0)
        {
                acutPrintf(_T("\n你选择了2"));
                break;
        }
        else if (_tcscmp(kw, _T("3")) == 0)
        {
                acutPrintf(_T("\n你选择了3"));
                break;
        }
default:
        break;
}
acutPrintf(_T("\n程序结束"));

效果


3.3.3 选择实体
功能:获取实体ads_name和选择点
代码示例
// 获取与三点钟方向夹角弧度:基准点(若为NULL则在屏幕上点)、提示字符串、接收弧度值
ads_point pt;
ads_name en;
if (acedEntSel(NULL, en, pt) == RTNORM)
        acutPrintf(_T("点选处为:%f,%f"), pt[X], pt[Y]);

常用函数
ads_name en1, en2;
ads_point pt1, pt2;

acedEntSel(NULL, en1, pt1);
acedEntSel(NULL, en2, pt2);

// 判断ads_name是否相等
if (acdbNameEqual(en1, en2))
        acutPrintf(_T("\n选择了同一个实体"));
else
        acutPrintf(_T("\n选择了两个实体"));
       
// 清空ads_name值
acdbNameClear(en2);
// 判断ads_name是否为空,为空则为true
if (acdbNameNil(en2))
        acutPrintf(_T("\n清除成功"));
       
// 用en2给en1赋值
acdbNameSet(en1,en2);
if (acdbNameEqual(en1, en2))
        acutPrintf(_T("\n赋值成功"));


效果

3.4 选择集
定义:实体的有名集合
特性:
非互斥性:一个实体可以包含在不同选择集中
唯一性:多次选择一个实体,选择集中只包含一次
易用性:可空,可手动框选添加实体进选择集
3.4.1 常用函数
代码示例
// 图上框选创建选择集
ads_name  en1, en2, ss1;
acedSSGet(NULL, NULL, NULL, NULL, ss1);

// 获得选择集长度
int len;
acedSSLength(ss1, &len);
acutPrintf(_T("\n初始选择集实体个数为%d"), len);

// 获取 选择集 首元素 的ads_name赋值en:一般用在for循环里
acedSSName(ss1,0,en1);
// 判断实体是否在选择集里
if(acedSSMemb(en1, ss1))
        acutPrintf(_T("\n实体在选择集中"));

// 获取实体en2
acedEntSel(NULL, en2, NULL);
// 将实体添加进现有选择集:第2、3参数均为选择集
acedSSAdd(en2,ss1,ss1);
acedSSLength(ss1, &len);
acutPrintf(_T("\n新增后选择集实体个数为%d"), len);

// 从选择集中删除实体,实体还在图中
acedSSDel(en1, ss1);
acedSSLength(ss1, &len);
acutPrintf(_T("\n删除后选择集实体个数为%d"), len);

// 释放选择集:选择集数量有上限,及时释放
acedSSFree(ss1);
acutPrintf(_T("\n程序结束"));

效果

3.4.2 acedSSGet函数详解
常用
写法        注释
acedSSGet(_T("A"), NULL, NULL, NULL, ss1);        选择全部实体
acedSSGet(_T("W"), pt1, pt2, NULL, ss1);        矩形框选window:包住的、跟边线重合的实体
acedSSGet(_T("C"), pt1, pt2, NULL, ss1);        矩形叉选crossing:包住的、跟边线重合、相交的实体
围区点列表
点列表框选:acedSSGet(_T("WP"), pointlist, NULL, NULL, ss1);
点列表叉选:acedSSGet(_T("CP"), pointlist, NULL, NULL, ss1);
1
2
// 图上框选创建选择集
ads_name  ss1;
ads_point pt1 = { 0,0,0 },
                  pt2 = { 100,100,0 },
                  pt3 = { 100,0,0 },
                  pt4 = { 0,100,0 };
// 点列表构建
resbuf * pointlist;
pointlist = acutBuildList(RT3DPOINT, pt1,
                                                  RT3DPOINT, pt3,
                                                  RT3DPOINT, pt2,
                                                  RT3DPOINT, pt4,
                                                  RTNONE);        // 必须有这个,否则cad崩溃
// CP可以换成WP或F(栏选:仅选择跟边线交叉的实体),
// 点列首尾自动闭合,P为Polygon
acedSSGet(_T("CP"), pointlist, NULL, NULL, ss1);
// 显示选择集内实体个数
int len;
acedSSLength(ss1, &len);
acutPrintf(_T("\n选择集内实体个数为%d"), len);
// 释放选择集、释放结果缓冲区
acedSSFree(ss1);
acutRelRb(pointlist);
acutPrintf(_T("程序结束"));

过滤选择集
常规过滤
ads_name  ss1;
resbuf * filter;
// 构建筛选器:RTDXF0为实体类型组码、8为图层组码、结尾要有RTNONE
filter = acutBuildList(RTDXF0, _T("CIRCLE"), 8, _T("0"), RTNONE);
// X 开启筛选器,filter为筛选器缓冲区指针
acedSSGet(_T("X"), NULL, NULL, filter, ss1);
// 打印选择集内实体数
int len;
acedSSLength(ss1, &len);
acutPrintf(_T("\n选择集内实体个数为%d"), len);

acedSSFree(ss1);
acutRelRb(filter);
acutPrintf(_T("程序结束"));

关系过滤 filter写法
// -4:条件运算符,40:圆半径组码(必须是100.0有小数)
filter = acutBuildList(RTDXF0, _T("CIRCLE"),
                                       -4,     _T(">="),
                                           40,     100.0,
                                           RTNONE);

条件过滤 filter写法
// 为了好读,加了缩进:选取所有0层上的直线和所有半径为100的圆
filter = acutBuildList(
        // or内为或关系:内部有一个就选择
        -4, _T("<OR"),
                // and内为与关系,一个整体
                -4, _T("<AND"),
                        RTDXF0, _T("LINE"), 8, _T("0"),
                -4, _T("AND>"),
                // and内为与关系,一个整体
                -4, _T("<AND"),
                        RTDXF0, _T("CIRCLE"), 40, 100.0,
                -4, _T("AND>"),

        -4, _T("OR>"),

        RTNONE);

四、系统变量
浮点型

// 对结果缓冲区 浮点型 操作
resbuf rb, rb1;
// 获取系统变量:圆角半径
acedGetVar(_T("FILLETRAD"), &rb);
acutPrintf(_T("系统变量值为:%.3f"), rb.resval.rreal);

// 给自定义结果缓冲区变量赋值,rb1.next默认为null
rb1.restype = RTREAL;
rb1.resval.rreal = 1.0;

// 提取并操作系统变量值
if (rb.resval.rreal < 1.0)
        // 设置系统变量值:传入自定义结果缓冲区变量
        if (acedSetVar(_T("FILLETRAD"), &rb1) != RTNORM)
                return;

整型

// 对结果缓冲区 整型 操作
resbuf rb2, rb3;
acedGetVar(_T("CMDECHO"), &rb2);
acutPrintf(_T("\n当前的CMECHO变量的值为%d."), rb2.resval.rint);
// 给自定义结果缓冲区变量赋值,rb1.next默认为null
rb3.restype = RTSHORT;
rb3.resval.rint = 0;
if (acedSetVar(_T("CMDECHO"), &rb3) == RTNORM)
{
        acutPrintf(_T("\n系统变量值CMDECHO,已修改,现在的值为%d"), rb3.resval.rint);
}
else
        acutPrintf(_T("\n设置系统变量值失败!"));

字符串型

// 对结果缓冲区 字符串 操作
resbuf rb4, rb5;
// 获取系统变量:字体样式
acedGetVar(_T("TEXTSTYLE"), &rb4);
if (rb4.resval.rstring != NULL)
{        // 打印当前字体样式、随后释放结果缓冲区
        acutPrintf(_T("\n当前的文字样式是%s"), rb4.resval.rstring);
        acdbFree(rb4.resval.rstring);
        // 自定义结果缓冲区rb5,类型
        rb5.restype = RTSTR;
        // C语言的分配内存空间,判断分配成功
        // 指针自身 = (指针类型*)malloc(sizeof(指针类型)*数据数量)
        // mallo函数返回的实际是一个无类型指针,必须在其前面加上指针类型强制转换才可以使用
        if ((rb5.resval.rstring = (ACHAR *)malloc(20)) != NULL)
        {        // 给结果缓冲区赋值
                _tcscpy(rb5.resval.rstring, _T("STANDARD"));
                // 用自定义的设置结果缓冲区
                acedSetVar(_T("TEXTSTYLE"), &rb5);
                acutPrintf(_T("\n新修改的文字样式是:%s"), rb5.resval.rstring);
                acdbFree(rb5.resval.rstring);
        }
        else
                acedAlert(_T("内存不足!"));
}

点坐标

// 对结果缓冲区点 坐标 操作
resbuf rb6, rb7;
ads_real lx, ly;
// 获取系统变量:当前图形最大点、最小点
acedGetVar(_T("EXTMAX"), &rb6);
acedGetVar(_T("EXTMIN"), &rb7);
// 结果缓冲区点提取
lx = rb6.resval.rpoint[X] - rb7.resval.rpoint[X];
ly = rb6.resval.rpoint[Y] - rb7.resval.rpoint[Y];
acutPrintf(_T("\n当前图形的水平长度和垂直长度分别为<%.3f , %.3f>"), lx, ly);
[/code]

 

 

 

 

objectArx --- ADS篇
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|中国膜结构网|中国膜结构协会|进口膜材|国产膜材|ETFE|PVDF|PTFE|设计|施工|安装|车棚|看台|污水池|中国膜结构网_中国空间膜结构协会

GMT+8, 2024-11-1 10:30 , Processed in 0.226516 second(s), 34 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表