hu_puma 发表于 2005-3-29 10:59:00

遍历AcDbVoidPtrArray的问题?请教,多谢!

请教高手:我在炸开一个实体后,产生一个AcDbVoidPtrArray类的数组,在遍历的时候怎么总是有问题:测试过程中炸开实体产生的object的ID和名称都是一样的,程序如下:请指点迷津:


void MYEX()//执行的命令函数<BR>{<BR>        struct resbuf *pcb;<BR>        pcb=acutNewRb(RTDXF0);//创建一个结果缓冲区,组码为0,表示实体类型<BR>        ads_name ss;<BR>        char sbuf;<BR>        strcpy(sbuf,"3DSOLID");


        pcb-&gt;resval.rstring=sbuf;<BR>        pcb-&gt;rbnext=NULL;


        acedSSGet("X",NULL,NULL,NULL,ss);//生成选择集<BR>        long lenSet;<BR>        acedSSLength(ss,&amp;lenSet);<BR>        for(int i=0;i&lt;lenSet;i++)<BR>        {<BR>                ads_name solidName;<BR>                acedSSName(ss,i,solidName);<BR>                AcDbObjectId objId;<BR>                acdbGetObjectId(objId,solidName);


                acutPrintf("\\n objId=%s",objId);<BR>                AcDbEntity *pEnt;<BR>                acdbOpenObject(pEnt,objId,AcDb::kForRead);<BR>                AcDbVoidPtrArray pArr;//声明一个数组,用于存放返回实体


                if(pEnt-&gt;isKindOf(AcDb3dSolid::desc()))<BR>                {<BR>                                        pEnt-&gt;explode(pArr);//这样指针pArr指向的内存地址的内容就是explode后的各实体。<BR>                        acutPrintf("\\n objID=%s",objId);


                        int lenArr=pArr.length();<BR>                        for(int j=0;j&lt;lenArr;j++)<BR>                        {<BR>                                ads_name objName;<BR>                                acedSSName(ss,j,objName);<BR>                                AcDbObjectId objSubId;<BR>                                acdbGetObjectId(objSubId,objName);<BR>                                AcDbEntity *pEntPlode;<BR>                                acdbOpenObject(pEntPlode,objSubId,AcDb::kForRead);


                                CString str;<BR>                                str.Format("objName=%s",objName);<BR>                                AfxMessageBox(str);<BR>                                <A href="file://acutPrintf/" target="_blank" >acutPrintf</A>("\\n objSubId=%s",objSubId);}<BR>                        pEnt-&gt;close();<BR>                }<BR>        }<BR>        acutRelRb(pcb);        <BR>        acedSSFree(ss);//释放选择集<BR>}

pandoram 发表于 2005-4-1 17:00:00

这个问题是因为..

你的遍历根本不是在对AcDbVoidPtrArray操作..



原因如下:


if(pEnt-&gt;isKindOf(AcDb3dSolid::desc()))<BR>                {<BR>                                        <FONT color=#ff0000>pEnt-&gt;explode(pArr);</FONT>


AcDbEntity的explode函数只制造array, 并不负责把里头的东西加到CAD数据库里面去. 这个跟CAD自己的explode命令系不一样地, CAD自己的explode会自动把explode出来的array里面的所有东西都加入数据库..(不要问偶为什么ARX这么笨, 它不是偶写的..)


偶的意思就是说ARX里面这个函数完了之后产生的array中的实体还都是孤儿, object ID是要等实体被加入CAD数据库时才分配的, 所以没有加数据库的意思就是<B>array里头的实体在你手动把它们加入数据库之前都没有objectID</B>..


但是你的程序并没有报找不到object ID, 那系因为:<BR><BR>                        for(int j=0;j&lt;lenArr;j++)<BR>                        {<BR>                                ads_name objName;<BR>                                <FONT color=#ff0000>acedSSName(ss,j,objName);</FONT>


<FONT color=#000000>这个选择集ss是原来选中所有3D实体形成的, 到这里为止都没有变过, <B>所以你取出来的objName是原来3dSolid的名字</B>, 不是炸开后形成的实体的名字, 下面的所有遍历操作都是对数据库里已经存在的那些3dSolid的记录进行的, 而不是对pArr的数组对象进行, 所以取出来的object ID和名字当然都是一样的, 因为是同一个3dSolid object的ID和名字..</FONT>


你可以只留第一个选择集的遍历部分, 在CAD里画一个3D盒子, 用MYEX命令显示ID一次, 然后在CAD里用CAD自己的炸开命令炸开这个盒子, 再用MYEX命令显示ID一次, 就能看到炸开后的实体的ID了:)<BR>


       
       
......
搞啊, 快要变成专业debug的了..
......................

hu_puma 发表于 2005-4-5 11:23:00

谢谢<A name=19717><FONT color=#000066><B>pandoram</B></FONT></A>,
页: [1]
查看完整版本: 遍历AcDbVoidPtrArray的问题?请教,多谢!