- UID
- 1
- 积分
- 16111
- 精华
- 贡献
-
- 威望
-
- 活跃度
-
- D豆
-
- 在线时间
- 小时
- 注册时间
- 2002-1-3
- 最后登录
- 1970-1-1
|
发表于 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实体。
你可以参考下:

- [FONT=courier new]
- **********************************************************************\
- *
- // arx_ssget.cpp : Initialization functions
- #include "StdAfx.h"
- AcDbObjectIdArray gIdArray;
- void testArxSSGet();
- // Few simple ones to start with
- // you can expand on this if necessary.
- //
- // If you don't like it this way, you can
- // use pEnt->isKindOf(AcDbXXX::desc())
- // in the arx_ssget() function body to
- // verify the entity type.
- //
- enum entityType {
- LWPOLYLINE,
- CIRCLE,
- SPLINE
- };
- /////////////////////////////////////////////////////////////////////////////
- // ObjectARX EntryPoint
- extern "C" AcRx::AppRetCode
- acrxEntryPoint(AcRx::AppMsgCode msg, void* pkt)
- {
- switch (msg) {
- case AcRx::kInitAppMsg:
- acrxDynamicLinker->unlockApplication(pkt);
- acrxDynamicLinker->registerAppMDIAware(pkt);
- acedRegCmds->addCommand("ASDK", "TEST", "TEST", ACRX_CMD_MODAL, testArxSSGet);
- break;
- case AcRx::kUnloadAppMsg:
- acedRegCmds->removeGroup("ASDK");
- break;
- }
- return AcRx::kRetOK;
- }
- //
- // Iterate the BT, BTR to acquire entities by the
- // critiria provided by the parameters.
- // Builds a global objectId array. If desired,
- // you can change it to be function parameter.
- //
- bool arx_ssget(const char* pAppName, const int entType)
- {
- // notice pBT is a smart pointer
- AcDbBlockTablePointer pBT(curDoc()->database(), AcDb::kForRead);
- if(pBT.openStatus() != Acad::eOk)
- return false;
- AcDbBlockTableIterator* pBTIter = NULL;
- pBT->newIterator(pBTIter);
- if(!pBTIter)
- return false;
- for(pBTIter->start(); !pBTIter->done(); pBTIter->step())
- {
- AcDbBlockTableRecord* pRec = NULL;
- Acad::ErrorStatus es = pBTIter->getRecord(pRec, AcDb::kForRead);
- if(es != Acad::eOk)
- {
- delete pBTIter;
- return false;
- }
- AcDbBlockTableRecordIterator* pIter = NULL;
- pRec->newIterator(pIter);
- if(!pIter)
- {
- pRec->close();
- delete pIter;
- return false;
- }
- for(pIter->start(); !pIter->done(); pIter->step())
- {
- AcDbEntity* pEnt = NULL;
- es = pIter->getEntity(pEnt, AcDb::kForRead);
- if(es != Acad::eOk)
- {
- delete pIter;
- delete pBTIter;
- pRec->close();
- return false;
- }
- if(!gIdArray.contains(pEnt->objectId(), 0))
- {
- bool bAppend = false;
- switch(entType)
- {
- case LWPOLYLINE:
- pEnt->isKindOf(AcDbPolyline::desc());
- bAppend = true;
- break;
- case CIRCLE:
- // do nothing at this time
- break;
- }
- resbuf* rb = pEnt->xData(pAppName);
- if(bAppend == true && rb != NULL)
- {
- gIdArray.append(pEnt->objectId());
- acutRelRb(rb);
- }
- }
- pEnt->close();
- }
- pRec->close();
- delete pIter;
- }
- delete pBTIter;
- return true;
- }
- //
- // This a simple test with the problem dwg.
- // I've made copies of the contents multiple times
- // in different spaces as well. I did the following,
- // (repeat 1000 (command "test")) and
- // the memory consumptiom remains stable,
- // even there is a acutRelRb() call thousands of times
- // in arx_ssget().
- //
- void testArxSSGet()
- {
- // clean up the global array first
- while(!gIdArray.isEmpty())
- gIdArray.removeFirst();
- const char testAppName[] = "AUTO_SCHEMATIC_258NBP9DQ9FX8G0";
-
- if(arx_ssget(testAppName, LWPOLYLINE))
- acutPrintf("\n%i entities found with the %s application name and type LWPOLYLINE.",
- gIdArray.length(), testAppName);
- else
- acutPrintf("\nNothing found.");
- }
- [/FONT]
|
|