几何尺寸与公差论坛------致力于产品几何量公差标准GD&T (GDT:ASME)|New GPS(ISO)研究/CAD设计/CAM加工/CMM测量

几何尺寸与公差论坛------致力于产品几何量公差标准GD&T (GDT:ASME)|New GPS(ISO)研究/CAD设计/CAM加工/CMM测量 (http://www.dimcax.com/hust/index.php)
-   ObjectARX(C++) (http://www.dimcax.com/hust/forumdisplay.php?f=34)
-   -   遍历acdbvoidptrarray的问题?请教,多谢! (http://www.dimcax.com/hust/showthread.php?t=8319)

yang686526 2009-04-18 10:58 PM

遍历acdbvoidptrarray的问题?请教,多谢!
 
遍历acdbvoidptrarray的问题?请教,多谢!
遍历acdbvoidptrarray的问题?请教,多谢!
请教高手:我在炸开一个实体后,产生一个acdbvoidptrarray类的数组,在遍历的时候怎么总是有问题:测试过程中炸开实体产生的object的id和名称都是一样的,程序如下:请指点迷津:
void myex()//执行的命令函数
{
struct resbuf *pcb;
pcb=acutnewrb(rtdxf0);//创建一个结果缓冲区,组码为0,表示实体类型
ads_name ss;
char sbuf[100];
strcpy(sbuf,"3dsolid");
pcb->resval.rstring=sbuf;
pcb->rbnext=null;
acedssget("x",null,null,null,ss);//生成选择集
long lenset;
acedsslength(ss,&lenset);
for(int i=0;i<lenset;i++)
{
ads_name solidname;
acedssname(ss,i,solidname);
acdbobjectid objid;
acdbgetobjectid(objid,solidname);
acutprintf("\\n objid=%s",objid);
acdbentity *pent;
acdbopenobject(pent,objid,acdb::kforread);
acdbvoidptrarray parr;//声明一个数组,用于存放返回实体
if(pent->iskindof(acdb3dsolid::desc()))
{
pent->explode(parr);//这样指针parr指向的内存地址的内容就是explode后的各实体。
acutprintf("\\n objid=%s",objid);
int lenarr=parr.length();
for(int j=0;j<lenarr;j++)
{
ads_name objname;
acedssname(ss,j,objname);
acdbobjectid objsubid;
acdbgetobjectid(objsubid,objname);
acdbentity *pentplode;
acdbopenobject(pentplode,objsubid,acdb::kforread);
cstring str;
str.format("objname=%s",objname);
afxmessagebox(str);
pent->close();
}
}
acutrelrb(pcb);
acedssfree(ss);//释放选择集
}
这个问题是因为..
你的遍历根本不是在对acdbvoidptrarray操作..
原因如下:
if(pent->iskindof(acdb3dsolid::desc()))
{
pent->explode(parr);
acdbentity的explode函数只制造array, 并不负责把里头的东西加到cad数据库里面去. 这个跟cad自己的explode命令系不一样地, cad自己的explode会自动把explode出来的array里面的所有东西都加入数据库..(不要问偶为什么arx这么笨, 它不是偶写的..)
偶的意思就是说arx里面这个函数完了之后产生的array中的实体还都是孤儿, object id是要等实体被加入cad数据库时才分配的, 所以没有加数据库的意思就是array里头的实体在你手动把它们加入数据库之前都没有objectid..
但是你的程序并没有报找不到object id, 那系因为:
for(int j=0;j<lenarr;j++)
{
ads_name objname;
acedssname(ss,j,objname);
这个选择集ss是原来选中所有3d实体形成的, 到这里为止都没有变过, 所以你取出来的objname是原来3dsolid的名字, 不是炸开后形成的实体的名字, 下面的所有遍历操作都是对数据库里已经存在的那些3dsolid的记录进行的, 而不是对parr的数组对象进行, 所以取出来的object id和名字当然都是一样的, 因为是同一个3dsolid object的id和名字..
你可以只留第一个选择集的遍历部分, 在cad里画一个3d盒子, 用myex命令显示id一次, 然后在cad里用cad自己的炸开命令炸开这个盒子, 再用myex命令显示id一次, 就能看到炸开后的实体的id了:)


......
搞啊, 快要变成专业debug的了..
......................
virtue is like a rich stone, best plain set.
-- francis bacon, <of beauty>
谢谢pandoram,


所有的时间均为北京时间。 现在的时间是 10:48 PM.