与用户交互或直接构建选择集,函数调用了空间搜索算法,执行效率高,多用于图面搜索程序
ARXDLL int mcedSSGet(LPCTSTR pszStr, const void * pt1, const void * pt2, const struct resbuf * filter, mds_name& ss, MxSSGetSubEntity* pSubEntitys = NULL, bool isRetGroup = true, bool isGetHideObject = false);
Mcedads.h
参数 |
说明 |
LPCTSTR pszStr |
选择控制字符串,可以是如下值 _X 选择图中的所有实体 _I 返回当前图上已经选择的实体 _ 与用户交互选择实体 _W 由p1,p2框选实体,选择的实体必须全部在pt和p2组成的矩形框内 _C 由p1,p2交叉框选实体,实体在pt和p2组成的矩形框内或与矩形框边线相交都放入选择集 _POINT 由pt1点和当前光标拾取大小生成一个矩形框,再由_C方式构造选择集。 _CP pt1指向一个点链表,点集合组成一个多边形区域,在这个区域内的和多边形的边相交的实体都放入到选择集中 _CW pt1指向一个点链表,点集合组成一个多边形区域,在这个区域内的实体都放入到选择集中 |
const void * pt1 |
输入矩形框的对角点坐标1 输入矩形框的对角点坐标2 |
const struct resbuf * filter |
构造选择集的过滤链表,用实体DXF组码过滤, 过滤实体类型使用组码RTDXF0,比如只想选择文字实体,代码如下: struct resbuf* filter = acutBuildList(RTDXF0, _T("TEXT") ,0); 过滤实体图层组码是8,比如只想选择MYLayer图层上的实体,代码如下: struct resbuf* filter = acutBuildList(8, _T("MYLayer") ,0); 图块名的组码是2,比如只想选择图块名为CL的图块,代码如下: struct resbuf* filter = acutBuildList(2, _T("CL") ,0); 过滤条件还支持通配符比较和OR(逻辑或),AND(逻辑与)运算,支持把扩展数据应用程序名当着过滤条件 |
Ss |
返回构造的选择集对象,该有对象不使用时,需要调用mcedSSFree函数释放选择集 |
成功返回RTNORM,用户取消返回RTCAN
例如:X方式选择图上所有实体
void CTestCommands::SelectAll() { /* CString layer = _T("*建筑面积线"); struct resbuf* filter = acutBuildList(8,layer,RTDXF0, _T("LWPOLYLINE"),-4,_T("<OR"),2,_T("_CL"), 2,_T("_GL"),2,_T("_AL"),-4,_T("OR>"),0); */ /* struct resbuf* filter = acutBuildList(8,layer,RTDXF0, _T("LWPOLYLINE"),-4,_T("<OR"),62,0, 62,1,62,256,-4,_T("OR>"),0); */ /* struct resbuf* filter = acutBuildList(RTDXF0, _T("LWPOLYLINE"),-4,_T("<OR"),62,0, 62,1,62,256,-4,_T("OR>"),0); */ /* struct resbuf* filter = acutBuildList(RTDXF0, _T("LINE,LWPOLYLINE,POLYLINE,ARC"), -3,1001,_T("SWGX"),RTNONE ); */ /* struct resbuf* filter = acutBuildList(RTDXF0, _T("LINE,LWPOLYLINE,POLYLINE,ARC"),RTNONE ); struct resbuf* filter = acutBuildList(RTDXF0, _T("ARC"),RTNONE ); */ struct resbuf* filter = NULL; acutPrintf(_T("n 选择实体:")); ads_name ss; int rc = acedSSGet(_T("X"), NULL, NULL,filter,ss); acutRelRb(filter); if(rc != RTNORM) { AfxMessageBox(_T("没有发现满足要求的实体")); return; } long len = 0; acedSSLength(ss,&len); CString sT; sT.Format(_T("发现%d个实体"),len); AfxMessageBox(sT); for(int i = 0; i < len;i++) { ads_name entName; acedSSName(ss,i,entName); AcDbObjectId id; acdbGetObjectId(id,entName); AcDbObjectPointer<AcDbEntity> spEnt(id,AcDb::kForRead); if(spEnt.openStatus() == Acad::eOk) { acutPrintf(_T("n class name:%s"),spEnt->isA()->name()); } } acedSSFree(ss); acutPrintf(_T("n")); }
例如:与用户交互构造选择集
void CTestCommands::TestUserSSGet() { struct resbuf* filter = NULL; ads_name ss; int rc = acedSSGet(_T("_"), NULL, NULL,filter,ss); acutRelRb(filter); if(rc != RTNORM) { return; } long len = 0; acedSSLength(ss,&len); CString sT; sT.Format(_T("发现%d个实体"),len); AfxMessageBox(sT); acedSSFree(ss); acutPrintf(_T("n")); }
例如:带过滤功能,与用户交互单选择实体函数
int MxTools::SelectEnt(IN const CString& strPrompt, IN const struct resbuf* pRbFilter, OUT AcDbObjectId& objId, OUT AcGePoint3d& ptPick) { double dPickLen = 10.0; struct resbuf pickbox; acedGetVar(_T("PICKBOX"), &pickbox); dPickLen = pickbox.resval.rreal; ads_point pt00 ; ads_name ent ; int ret = ads_entsel(strPrompt, ent, pt00) ; ptPick = asPnt3d(pt00) ; switch(ret) { case RTNORM: { ads_point pt01, pt02 ; ads_real dist = dPickLen * 0.5 ; ads_polar(pt00, 0.78, dist, pt01) ; ads_polar(pt00, 3.81, dist, pt02) ; ads_name ss ; if(Mx::mcedSSGet(_T("C"), pt01, pt02,pRbFilter, ss) == RTNORM) { std::map<double,AcDbObjectId> mapFind; long iLen = 0; ads_sslength(ss,&iLen); for(int j = 0;j < iLen;j++) { ads_ssname(ss, j, ent) ; AcDbObjectId tmpId; acdbGetObjectId(tmpId, ent) ; double dDis = dPickLen; AcDbObjectPointer<AcDbCurve> spCurve(tmpId,AcDb::kForRead); if(spCurve.openStatus() == Acad::eOk) { McGePoint3d ptOn; if(spCurve->getClosestPointTo(ptPick,ptOn) == Acad::eOk) { dDis = ptOn.distanceTo(ptPick); } } mapFind.insert(std::make_pair(dDis,tmpId)); } ads_ssfree(ss); if(mapFind.empty() ) { ret = RTERROR; } else { objId = mapFind.begin()->second; ret = RTNORM; } } else { ret = RTERROR ; } } break ; case RTERROR: ret = RTNONE; break; default: break ; } return ret ; }
例如:搜索一点下面的实体
BOOL MxTools::FindEntAtPoint(IN AcGePoint3d pt,IN struct resbuf* pFilter, IN double dTol,OUT AcDbObjectIdArray& aryId) { aryId.setLogicalLength(0); AcGePoint3d pt1 = pt + dTol * (AcGeVector3d::kXAxis + AcGeVector3d::kYAxis); AcGePoint3d pt2 = pt - dTol * (AcGeVector3d::kXAxis + AcGeVector3d::kYAxis); ads_name ss; int result = acedSSGet(_T("_C"), asDblArray(pt1), asDblArray(pt2), pFilter, ss); if(result != RTNORM) { return FALSE; } long sslen; if (acedSSLength(ss, &sslen) != RTNORM) { acedSSFree(ss); return FALSE; } for(int i = 0; i < sslen;i++) { ads_name ent; acedSSName(ss, i, ent); AcDbObjectId id; acdbGetObjectId(id,ent); aryId.append(id); } acedSSFree(ss); return !aryId.isEmpty(); }