找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 994|回复: 10

[ARX函数]:ads_ssfree函数能够完全清空已分配的内存吗?

[复制链接]
发表于 2002-10-18 00:19:39 | 显示全部楼层 |阅读模式

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

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

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

已领礼包: 145个

财富等级: 日进斗金

发表于 2002-10-18 00:34:16 | 显示全部楼层

Re: [ARX函数]:ads_ssfree函数能够完全清空已分配的内存吗?

最初由 xb4270293 发布
[B]ads_ssfree函数能够完全清空已分配的内存吗?
如何解决? [/B]


如果你程序里面大量的使用选择集,即使及时释放,系统内存也要耗费尽。这是由于ACAD释放选择集内存后,并没有把它们归还给操作系统。

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

使用道具 举报

 楼主| 发表于 2002-10-18 00:42:55 | 显示全部楼层
由于看中了ads_ssget("CP", ...)可以根据一个多边形区域选择实体,不必自己去判断每一个实体是否在区域内或相交,所以使用了ads构造选择集的方法,不得以而为之。由于选择的图形实体数量较多,在循环体中,三、五下就占满了内存。我晕!
不知ObjectARX中有没有相应的对象或函数?
请指教.
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 145个

财富等级: 日进斗金

发表于 2002-10-18 00:50:35 | 显示全部楼层
最初由 xb4270293 发布
[B]由于看中了ads_ssget("CP", ...)可以根据一个多边形区域选择实体,不必自己去判断每一个实体是否在区域内或相交,所以使用了ads构造选择集的方法,不得以而为之。由于选择的图形实体数量较多,在循环体中,三、五下?.. [/B]


ads_ssget是ARX的全局函数部分中的,在ARX开发中也是必不可少的,比如和ACAD交互的时候,ads_getxxxx类还有ads_entsel等等。

ads_ssget就是ARX的一部分,因此就没有ARX是否有类似ssget这样的对象。构造选择集只能用ads_ssget.

你可以根据实际需要,不使用选择集存放大量的实体,使用一个全局的ID数组,里面存放你要处理的实体ID。

获得满足需要的ID,自己完全可以根据实际需要写代码,而且测试过,即使整个数据库遍历查找对象,用ARX的遍历也要比ads_ssget 的"X“参数的方法速度要快一个数量集。ads_ssget只有在选择屏幕内的实体的时候,比如W,C等参数时候,速度稍微快些,因为ACAD使用了显示表的方法获得屏幕内的实体(基于象素)的。

下面的代码是一个arx的ssget(自己定义),选取符号条件的POLYLINE实体。

你可以参考下:

  1. [FONT=courier new]
  2. **********************************************************************\
  3. *
  4. // arx_ssget.cpp : Initialization functions
  5. #include "StdAfx.h"

  6. AcDbObjectIdArray gIdArray;

  7. void testArxSSGet();

  8. // Few simple ones to start with
  9. // you can expand on this if necessary.
  10. //
  11. // If you don't like it this way, you can
  12. // use pEnt->isKindOf(AcDbXXX::desc())
  13. // in the arx_ssget() function body to
  14. // verify the entity type.
  15. //
  16. enum entityType {
  17.         LWPOLYLINE,
  18.         CIRCLE,
  19.         SPLINE
  20. };

  21. /////////////////////////////////////////////////////////////////////////////
  22. // ObjectARX EntryPoint
  23. extern "C" AcRx::AppRetCode
  24. acrxEntryPoint(AcRx::AppMsgCode msg, void* pkt)
  25. {
  26.         switch (msg) {
  27.         case AcRx::kInitAppMsg:
  28.                 acrxDynamicLinker->unlockApplication(pkt);
  29.                 acrxDynamicLinker->registerAppMDIAware(pkt);
  30.                 acedRegCmds->addCommand("ASDK", "TEST", "TEST", ACRX_CMD_MODAL, testArxSSGet);
  31.                 break;
  32.         case AcRx::kUnloadAppMsg:
  33.                 acedRegCmds->removeGroup("ASDK");
  34.                 break;
  35.         }
  36.         return AcRx::kRetOK;
  37. }
  38. //
  39. // Iterate the BT, BTR to acquire entities by the
  40. // critiria provided by the parameters.
  41. // Builds a global objectId array. If desired,
  42. // you can change it to be function parameter.
  43. //
  44. bool arx_ssget(const char* pAppName, const int entType)
  45. {
  46.         // notice pBT is a smart pointer
  47.         AcDbBlockTablePointer pBT(curDoc()->database(), AcDb::kForRead);
  48.         if(pBT.openStatus() != Acad::eOk)
  49.                 return false;

  50.         AcDbBlockTableIterator* pBTIter = NULL;
  51.         pBT->newIterator(pBTIter);
  52.         if(!pBTIter)
  53.                 return false;

  54.         for(pBTIter->start(); !pBTIter->done(); pBTIter->step())
  55.         {
  56.                 AcDbBlockTableRecord* pRec = NULL;
  57.                 Acad::ErrorStatus es = pBTIter->getRecord(pRec, AcDb::kForRead);
  58.                 if(es != Acad::eOk)
  59.                 {
  60.                         delete pBTIter;
  61.                         return false;
  62.                 }
  63.                 AcDbBlockTableRecordIterator* pIter = NULL;
  64.                 pRec->newIterator(pIter);
  65.                 if(!pIter)
  66.                 {
  67.                         pRec->close();
  68.                         delete pIter;
  69.                         return false;
  70.                 }
  71.                 for(pIter->start(); !pIter->done(); pIter->step())
  72.                 {
  73.                         AcDbEntity* pEnt = NULL;
  74.                         es = pIter->getEntity(pEnt, AcDb::kForRead);
  75.                         if(es != Acad::eOk)
  76.                         {
  77.                                 delete pIter;
  78.                                 delete pBTIter;
  79.                                 pRec->close();
  80.                                 return false;
  81.                         }
  82.                         if(!gIdArray.contains(pEnt->objectId(), 0))
  83.                         {
  84.                                 bool bAppend = false;
  85.                                 switch(entType)
  86.                                 {
  87.                                 case LWPOLYLINE:
  88.                                         pEnt->isKindOf(AcDbPolyline::desc());
  89.                                         bAppend = true;
  90.                                         break;
  91.                                 case CIRCLE:
  92.                                         // do nothing at this time
  93.                                         break;
  94.                                 }
  95.                                 resbuf* rb = pEnt->xData(pAppName);
  96.                                 if(bAppend == true && rb != NULL)
  97.                                 {
  98.                                         gIdArray.append(pEnt->objectId());
  99.                                         acutRelRb(rb);
  100.                                 }
  101.                         }

  102.                         pEnt->close();
  103.                 }
  104.                 pRec->close();
  105.                 delete pIter;
  106.         }
  107.         delete pBTIter;
  108.         return true;
  109. }
  110. //
  111. // This a simple test with the problem dwg.
  112. // I've made copies of the contents multiple times
  113. // in different spaces as well. I did the following,
  114. // (repeat 1000 (command "test")) and
  115. // the memory consumptiom remains stable,
  116. // even there is a acutRelRb() call thousands of times
  117. // in arx_ssget().
  118. //
  119. void testArxSSGet()
  120. {
  121.         // clean up the global array first
  122.         while(!gIdArray.isEmpty())
  123.                 gIdArray.removeFirst();

  124.         const char testAppName[] = "AUTO_SCHEMATIC_258NBP9DQ9FX8G0";
  125.        
  126.         if(arx_ssget(testAppName, LWPOLYLINE))
  127.                 acutPrintf("\n%i entities found with the %s application name and type LWPOLYLINE.",
  128.                         gIdArray.length(), testAppName);
  129.         else
  130.                 acutPrintf("\nNothing found.");
  131. }

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

使用道具 举报

已领礼包: 145个

财富等级: 日进斗金

发表于 2002-10-18 01:00:13 | 显示全部楼层

acedSSGet和ObjectArx哪个快?

给你贴篇背景资料,对ads_ssget和用ARX实现的遍历进行测试


  1. [FONT=courier new]
  2. Which is faster, acedSSGet or ObjectARX ?  
  3. ID    14192  
  4. Applies to:    AutoCAD 2002
  5. AutoCAD 2000
  6. AutoCAD 2000I


  7. This document is part of    ADS   ObjectARX   AcDb (AutoCAD Database)   Selection Sets     


  8. Question
  9. When I am iterating through the entire database, is it faster to use acedSSGet()
  10. or to use ObjectARX techniques? With ObjectARX I have to open every entity,
  11. whereas with acedSSGet() I do not.
  12. Answer
  13. It is generally faster to use ObjectARX when querying the entire database.  
  14. However, when you specify an area (giving 2 points to acedSSGet() for example),
  15. or when using the special ssget modes '"W, C, P, F, CP, WP', then acedSSGet()
  16. is faster because it uses the display list to retrieve the entities. But those
  17. modes work only for the entity in the display list, not for the others.

  18. The attached code was run on the attached DWG. There were three tests: one to
  19. create an AcDbObjectIdArray of all entitites in model space; another to create
  20. an AcDbObjectIdArray of all circles in model space; thirdly, to create an
  21. AcDbObjectIdArray of entities on a given layer.

  22. The results were:
  23.                           acedSSGet()          ObjectARX
  24. All Entities              0.080                      0.01
  25. All Circles              0.090                      0.01
  26. All on Layer 1        0.110                      0.02

  27. There are a few techniques here to note.

  28. 1. The layerId is identified outside the loop. This means that you can compare
  29. the ObjectIds, which is faster than opening the layer every time to compare the strings.

  30. 2. The selection set in the acedSSGet() tests knows how many entities are present.
  31. The AcDbObjectIdArray can therefore be initiated correctly rather than having to grow.

  32. 3. The use of the function approxNumObjects() makes the ObjectARX test much
  33. faster, for the same reason as in # 2.
  34. [/FONT]
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2002-10-18 01:01:35 | 显示全部楼层
感谢BOSS!
我的工程,需要面对一张电子地图(DWG),里面可能有几万个块、几十万条3dPolyline,每条折线顶点数可能有几万个点,还包含有文字、填充、等等。如果一一遍历和判断,速度快不到哪去,因此考虑利用CAD的显示表来解决。
我再晕!!
HELP!
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2002-10-18 01:12:04 | 显示全部楼层
用户在地图中绘制无数个(如:100)多边形,判断多边形是否于折线相交的效率太低,尤其是折线的顶点无数(如:5000~50000个点)。
需要将与多边形相交的实体复制到另一张图中,而后XClip它们,而且限定在AutoCAD R14上,由于Acad2000 / 2002太贵。已在R14中折腾了三年。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 145个

财富等级: 日进斗金

发表于 2002-10-18 01:24:55 | 显示全部楼层
最初由 xb4270293 发布
[B]用户在地图中绘制无数个(如:100)多边形,判断多边形是否于折线相交的效率太低,尤其是折线的顶点无数(如:5000~50000个点)。
需要将与多边形相交的实体复制到另一张图中,而后XClip它们,而且限定在AutoCAD R14?.. [/B]


你试试吧,ACAD数据库遍历一次速度很快的。不是想象的那样:)

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

使用道具 举报

已领礼包: 145个

财富等级: 日进斗金

发表于 2002-10-18 01:26:40 | 显示全部楼层
最初由 xb4270293 发布
[B]用户在地图中绘制无数个(如:100)多边形,判断多边形是否于折线相交的效率太低,尤其是折线的顶点无数(如:5000~50000个点)。
需要将与多边形相交的实体复制到另一张图中,而后XClip它们,而且限定在AutoCAD R14?.. [/B]


你可以用包围盒求交,这个速度快,别用实体的interSectWith

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

使用道具 举报

 楼主| 发表于 2002-10-18 01:45:57 | 显示全部楼层
thanks !  :>
我再去试!
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 145个

财富等级: 日进斗金

发表于 2002-10-18 01:50:48 | 显示全部楼层
最初由 xb4270293 发布
[B]thanks !  :>
我再去试! [/B]


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

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-11-15 17:33 , Processed in 0.229234 second(s), 51 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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