找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 1232|回复: 9

[求助]:一个关于ads_ssget的老问题。。哎~

[复制链接]
发表于 2003-8-7 09:50:31 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×

  1.   [FONT=courier new]
  2. 以下代码想实现的功能是:通过鼠标选取的2点形成直线,取得与直线相交的符合过滤条件的实体,符合条件的实体亮显。

  3. void gradDim()
  4. {
  5.         ads_point stpt,pt1,pt2,enpt,prept,dimpt;
  6.         ads_name ssname,entres,EntityName;
  7.         struct resbuf pRb1,pRb,*pointlist;
  8.         AcDbObjectId objId;
  9.         AcDbEntity *pEnt;

  10.         ads_getpoint(NULL,"\n点取<逐点标注>起始点<退出>:",stpt);
  11.         ads_getpoint(stpt,"\n点取结束点<退出>:",enpt);

  12.         pt1[X] = enpt[X];
  13.         pt1[Y] = stpt[Y];
  14.        
  15.         pt2[X] = enpt[X];
  16.         pt2[Y] = stpt[Y];
  17.        
  18.         //获取选择集过滤List(由实体名称过滤)
  19.         pointlist = ads_buildlist(RTPOINT,stpt, RTPOINT,pt1,RTPOINT,enpt,RTPOINT,pt2,0);

  20.         char sbuf[50],sbuf1[50]; // Buffers to hold strings

  21.         pRb1.restype = 8;        //层名
  22.         strcpy(sbuf1, "0");
  23.         strupr(sbuf1);
  24.         pRb1.resval.rstring = sbuf1;
  25.         pRb1.rbnext = NULL;
  26.        
  27.         pRb.restype = 0;        //实体名称
  28.         strcpy(sbuf, "Line");
  29.         strupr(sbuf);
  30.         pRb.resval.rstring = sbuf;
  31.         pRb.rbnext = &pRb1;

  32.         int ss = ads_ssget("CP",pointlist,NULL,&pRb,ssname);
  33.        
  34.         long NumOfEntity;
  35.         ss = ads_sslength(ssname,&NumOfEntity);
  36.        
  37.         for(long i = 0 ; i < NumOfEntity; i++)
  38.                 {
  39.                         ads_ssname(ssname,i,EntityName);
  40.                
  41.                         acdbGetObjectId(objId,EntityName);
  42.                        
  43.                         if(acdbOpenObject(pEnt,objId,AcDb::kForRead)!=Acad::eOk)
  44.                         {
  45.                                 ads_printf("\n打开实体时出错!");
  46.                                 return;
  47.                         }
  48.                         //pEnt->highlight();  //这种方法不好
  49.                        
  50.                         MessageBox(NULL,pEnt->isA()->name(),NULL,MB_OK);//测试用
  51.                         //pEnt->close();
  52.                 }

  53.         ads_relrb(pointlist);
  54.         ads_ssfree(ssname);


  55.        
  56. }


  57. 但现在存在2个问题:
  58. 1。符合条件的实体可以取得,但没有亮显。。。
  59. 2。我想取得CAD中rectang画的矩形或者polyline画的线,用"polyline"怎么过滤不到?

  60. 请高手指点~~
  61.   [/FONT]
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
发表于 2003-8-8 08:09:06 | 显示全部楼层
highlight()  Why?不好
选不到pline就用 list命令看看,说明那是LWPOLYLINE不是POLYLINE,从R14就有的东东了
另外,你的程序从不判断函数返回值,很有特点
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2003-8-8 17:43:29 | 显示全部楼层
首先谢谢老何~~呵呵
我一向懒的很的,所以一般只在关键地方判断返回值  :P

2个问题自己回答下:
1。目前没有找到让ads_ssget()自动亮显上面代码中选择集里面实体的办法,所以只好在选择集中遍历实体用highlight()了。期待着好的解决办法~~~~
2。pline过滤的名称是“LWPOLYLINE”不是"POLYLINE",偶太菜了,只知道去看属性里面的名称 。   :(

但, 又出现了个问题:在上面代码操作完成并实现功能后,用AutoCAD里面的旋转操作被操作过的实体时,出现如下错误,见
图1,我程序中每个打开实体和指针都关闭了的。。。

请高手指点指点~~~~
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2003-8-11 13:57:44 | 显示全部楼层
至于亮显,ACAD官方文裆里就有相关例子。查查看,我忘了。
至于第2个,我个人认为是你没有关闭实体。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2003-8-11 14:21:21 | 显示全部楼层
好久不见,谢谢先
嗯,现在改的差不多了~   
下面是完整的代码:

  1.   [FONT=courier new]
  2. //逐点标注
  3. void gradDim()
  4. {
  5.         ads_point stpt,pt1,pt2,enpt,prept,dimpt;
  6.         ads_name ssname,entres,EntityName;
  7.         struct resbuf pRb,*pointlist;
  8.         AcDbObjectId objId,objId1,LayerId,dimStyleId;
  9.         AcDbEntity *pEnt,*pEnt1;
  10.         Adesk::Boolean KeepPick = Adesk::kTrue;
  11.         AcDbPolyline *polyline;
  12.         Acad::ErrorStatus es;

  13.         int retCode = ads_getpoint(NULL,"\n点取<逐点标注>起始点<退出>:",stpt);
  14.         if(retCode != RTNORM)  return;
  15.         retCode = ads_getpoint(stpt,"\n点取结束点<退出>:",enpt);
  16.         if(retCode != RTNORM)  return;

  17.         pt1[X] = enpt[X];
  18.         pt1[Y] = stpt[Y];
  19.        
  20.         pt2[X] = enpt[X];
  21.         pt2[Y] = stpt[Y];
  22.        
  23.         //获取选择集过滤List(由实体名称过滤)
  24.         pointlist = ads_buildlist(RTPOINT,stpt, RTPOINT,pt1,RTPOINT,enpt,RTPOINT,pt2,0);

  25.         char sbuf[50];                                        // Buffers to hold strings
  26.         pRb.restype = 0;                                //实体名称
  27.         strcpy(sbuf, "LWPOLYLINE");        
  28.         strupr(sbuf);
  29.         pRb.resval.rstring = sbuf;
  30.         pRb.rbnext = NULL;

  31.         //初步拾取选择集
  32.         retCode = ads_ssget("CP",pointlist,NULL,&pRb,ssname);
  33.         if(retCode != RTNORM)
  34.                 return;
  35.        
  36.         //取得选择实体个数
  37.         long NumOfEntity;
  38.         retCode = ads_sslength(ssname,&NumOfEntity);
  39.        
  40.         //再次过滤,取得符合条件的实体
  41.         for(long i = 0 ; i < NumOfEntity; i++)
  42.         {
  43.                 ads_ssname(ssname,i,EntityName);
  44.        
  45.                 acdbGetObjectId(objId,EntityName);
  46.                
  47.                 if(acdbOpenObject(pEnt,objId,AcDb::kForRead)!=Acad::eOk)
  48.                 {
  49.                         ads_printf("\n打开实体时出错!");
  50.                         return;
  51.                 }

  52.                 polyline = AcDbPolyline::cast(pEnt);

  53.                 int iNum = polyline->numVerts();
  54.                 AcGePoint2d p0,p1,p2,p3;
  55.                 AcGeVector2d v1,v2,v3;
  56.                 AcGeTol aTol;
  57.                
  58.                 aTol.setEqualVector(0.001);
  59.                
  60.                 //取得polyline上各点
  61.                 polyline->getPointAt(0,p0);
  62.                 polyline->getPointAt(1,p1);
  63.                 polyline->getPointAt(2,p2);
  64.                 polyline->getPointAt(3,p3);
  65.                
  66.                 polyline->close();

  67.                 //取得各分段向量
  68.                 v1 = p1 - p0;
  69.                 v2 = p2 - p1;
  70.                 v3 = p3 - p2;
  71.                
  72.                 //设置过滤条件,"rectang"
  73.                 if(iNum == 4)
  74.                 {

  75.                         if((p0.x == p1.x || p0.y == p1.y)&&(abs(v1.dotProduct(v2)/(v1.length()*v2.length()))<=0.001)&&
  76.                                 (abs(v2.dotProduct(v3)/(v2.length()*v3.length()))<=0.001))
  77.                         {
  78.                                 pEnt->highlight();
  79.                                 pEnt->close();
  80.                         }
  81.                         else
  82.                         {
  83.                                 pEnt->close();
  84.                                 ads_ssdel(EntityName,ssname);
  85.                         }
  86.                        
  87.                 }
  88.                 else
  89.                 {
  90.                         pEnt->close();
  91.                         ads_ssdel(EntityName,ssname);
  92.                 }
  93.                
  94.         }

  95.         //选择不需要标注的线
  96.         while(KeepPick)
  97.         {
  98.                 retCode = ads_entsel("\n选择不需要标注的线<无>:",entres,prept);
  99.                 if(retCode == RTNORM)
  100.                 {
  101.                         acdbGetObjectId(objId1,entres);
  102.                         acdbOpenAcDbEntity(pEnt1,objId1,AcDb::kForRead);

  103.                         pEnt1->unhighlight();
  104.                         pEnt1->close();
  105.                         ads_ssdel(entres,ssname);
  106.        
  107.                 }
  108.                 else
  109.                 {
  110.                         //关闭亮显
  111.                         for(i = 0 ; i < NumOfEntity; i++)
  112.                         {
  113.                                 ads_ssname(ssname,i,EntityName);
  114.                        
  115.                                 acdbGetObjectId(objId,EntityName);
  116.                                
  117.                                 if(acdbOpenObject(pEnt,objId,AcDb::kForRead)!=Acad::eOk)
  118.                                 {
  119.                                         ads_printf("\n打开实体时出错!");
  120.                                         return;
  121.                                 }
  122.                                 pEnt->unhighlight();
  123.                                 pEnt->close();
  124.                        
  125.                         }

  126.                         KeepPick = Adesk::kFalse;
  127.                         break;
  128.                 }
  129.         }

  130.         //构造直线
  131.         AcGePoint3dArray ptArr;
  132.         AcGeVector3d vec, vec1(1,0,0);
  133.         AcGePoint3d Cenpt,stPt,enPt,Cenpt1;
  134.         stPt = asPnt3d(stpt);
  135.         enPt = asPnt3d(enpt);
  136.         vec = enPt - stPt;

  137.         //取得直线倾角
  138.         double dAngle = vec1.angleTo(vec);

  139.         //取得两选点的中点
  140.         getCenpt(stPt,enPt,Cenpt);
  141.         AcGeVector3d Lvec(1,0,0);
  142.         Cenpt1[X] =  Cenpt[X]*2;
  143.         Cenpt1[Y] =  Cenpt[Y];
  144.        
  145.         if((dAngle >= PI/4 && dAngle <= 3*PI/4)||(dAngle >= 5*PI/4 && dAngle <= 7*PI/4))
  146.         {
  147.                 Lvec.rotateBy(PI/2,AcGeVector3d(0,0,1));
  148.                 Cenpt1[X] =  Cenpt[X];
  149.                 Cenpt1[Y] =  Cenpt[Y]*2;
  150.         }

  151.         AcDbLine *pLine = new AcDbLine(Cenpt,Cenpt1);

  152.         AcGeLine3d ple(Cenpt,Lvec);
  153.         double DimLen;
  154.        
  155.         //取得尺寸线位置
  156.         retCode = ads_getpoint(asDblArray(Cenpt),"\n点取尺寸线的位置<原位标注>:",dimpt);
  157.         if(retCode != RTNORM)  return;

  158.         DimLen = ple.distanceTo(asPnt3d(dimpt));
  159.        
  160.         //取得直线pLine和选择集里面实体的交点集
  161.         retCode = ads_sslength(ssname,&NumOfEntity);
  162.         for(i = 0 ; i < NumOfEntity; i++)
  163.         {
  164.                 AcGePoint3dArray ptArrAdd;
  165.                 ads_ssname(ssname,i,EntityName);
  166.        
  167.                 acdbGetObjectId(objId,EntityName);
  168.                
  169.                 if(acdbOpenObject(pEnt,objId,AcDb::kForRead)!=Acad::eOk)
  170.                 {
  171.                         ads_printf("\n打开实体时出错!");
  172.                         return;
  173.                 }

  174.                 es = pLine->intersectWith(pEnt,AcDb::kExtendBoth,ptArrAdd);
  175.                
  176.                 for(int k = 0; k < ptArrAdd.length(); k++)
  177.                 {
  178.                         ptArr.append(ptArrAdd.at(k));
  179.                 }

  180.                 pEnt->close();
  181.                 ads_ssfree(EntityName);

  182.         }

  183.         //把取得的点集排序
  184.         if((dAngle >= PI/4 && dAngle <= 3*PI/4)||(dAngle >= 5*PI/4 && dAngle <= 7*PI/4))
  185.         {
  186.                 //按各点的Y值排序
  187.                 sort(ptArr,2);
  188.         }
  189.         else
  190.                 //按各点的X值排序
  191.                 sort(ptArr,1);

  192.         //创建Dim层
  193.         gCyz_ArxBegin();
  194.         //取得层的ID,如果层不存在则创建然后取得层的ID
  195.         LayerId = gConfig.GetLayerId(LBIAOZHU);
  196.         //取得DimensionStyle的ID,如果DimensionStyle不存在则创建然后取得DimensionStyle的ID
  197.         dimStyleId=gConfig.GetDimStyleId();
  198.         gCyz_ArxEnd();

  199.         AcGePoint3d sPt,ePt,DimPt;
  200.         double DimDist;
  201.         int iDist;
  202.         CString str;
  203.         AcDbObjectId retId;

  204.         //创建标注
  205.         for(i = 0 ; i < ptArr.length() - 1; i++)
  206.         {
  207.                 AcDbAlignedDimension *pNewDim = new AcDbAlignedDimension;
  208.                 sPt = ptArr.at(i);
  209.                 ePt = ptArr.at(i+1);
  210.                 //取得长度值
  211.                 DimDist = sPt.distanceTo(ePt);
  212.                 iDist = (int)DimDist;
  213.                 if((DimDist - iDist) > 0.5)  iDist += 1;
  214.                 str.Format("%d",iDist);

  215.                 DimPt.set((sPt.x + ePt.x)/2,(sPt.y + ePt.y)/2,0);

  216.                 Lvec.normalize();
  217.                
  218.                 if(asPnt3d(dimpt).x <= Cenpt.x || asPnt3d(dimpt).y > Cenpt.y )
  219.                         DimPt += (Lvec.perpVector())*DimLen;
  220.                 else
  221.                         DimPt -= (Lvec.perpVector())*DimLen;

  222.                 pNewDim->setXLine1Point(ptArr.at(i));
  223.                 pNewDim->setXLine2Point(ptArr.at(i+1));
  224.                 pNewDim->setDimensionStyle(dimStyleId);
  225.                 pNewDim->setDimLinePoint(DimPt);
  226.                 pNewDim->setLayer(LayerId);
  227.                 pNewDim->setDimensionText(str);
  228.                
  229.                 //把实体加入到数据库中
  230.                 addToModelSpace(retId,pNewDim);
  231.                 pNewDim->close();
  232.         }

  233.         pLine->close();
  234.         ads_relrb(pointlist);
  235.         ads_ssfree(ssname);
  236. }
  237.   [/FONT]
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2003-8-15 16:29:51 | 显示全部楼层

回上一篇

在对resbuf结构的rstring进行赋值前应该对它应用的内存进行重新分配,这样直接用=号直接对指针赋值的话,你就无法主动的用free去释放它,除非你在释放它之前对它进行内存重新分配。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2003-8-20 10:13:25 | 显示全部楼层
多谢指点
小生半道出家,基础不好,而且人好像也不是很勤奋。。。但对于高手的指点一定虚心受教,努力吸收~  
请大家不吝指教~
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2003-10-26 11:51:13 | 显示全部楼层
你上面的代码中getCenpt、gConfig,gCyz_ArxEnd、addToModelSpace、sort函数是怎样定义的呢
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2003-10-27 11:17:31 | 显示全部楼层
这样的代码看起来很舒服啊,整齐有序,真希望大家能将代码都写成这样
给我们学习参考!

谢谢了
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2003-12-23 11:48:58 | 显示全部楼层
最初由 xux4618 发布
[B]你上面的代码中getCenpt、gConfig,gCyz_ArxEnd、addToModelSpace、sort函数是怎样定义的呢 [/B]


呵呵,那些函数都是自己为了偷懒写的一个Dll,用的时候很方便,不过都是R14下面的,现在在陆续更改到2002或2004,人比较懒,而且有好长一段时间没有接触ARX了,改好了放上来希望大家多提意见
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

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

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2024-9-21 10:39 , Processed in 0.217396 second(s), 51 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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