首页 ObjectARX-组字典(Group)

ObjectARX-组字典(Group)

小白鼠 2019-04-03 12:38:43 0 3577

(1)使用ObjectARX创建一个新工程Group.

注册命令AddGroup,提示用户选择实体,将其创建成一个编组,

实现函数为:

static void AAAMyGroupAddGroup() {
		//提示用户选择多个实体
		AcDbObjectIdArray entIds;
		if (CSelectUtil::PromptSelectEnts(TEXT("\n选择要成组的实体:"),
			AcDbEntity::desc(), entIds))
		{
			//创建组
			AcDbGroup *pGroup = new AcDbGroup();
			for (int i = 0; i < entIds.length(); i++)
			{
				pGroup->append(entIds[i]);
			}
 
			//将组添加到有名对象字典的组字典中
			AcDbDictionary *pGroupDict = NULL;
			acdbHostApplicationServices()->workingDatabase()
				->getGroupDictionary(pGroupDict, AcDb::kForWrite);
 
			//如果组名为*,则会创建匿名组
			CString groupName = TEXT("*");
			AcDbObjectId groupId;
			pGroupDict->setAt(groupName, pGroup, groupId);
			pGroupDict->close();
			pGroup->close();
		}
 
	}

其中,函数PromptSelectEnts 的实现:

首先在项目中添加一个普通类 CSelectUtil,

函数 PromptSelectEnts 的声明:

	// 提示用户选择多个实体
	static bool PromptSelectEnts(const TCHAR* prompt, AcRxClass* classDesc, AcDbObjectIdArray &entIds);
	static bool PromptSelectEnts(const TCHAR* prompt, const std::vector<AcRxClass*> &classDescs, AcDbObjectIdArray &entIds);

函数 PromptSelectEnts 的实现:

bool CSelectUtil::PromptSelectEnts(const TCHAR* prompt, AcRxClass* classDesc, AcDbObjectIdArray &entIds)
{
	std::vector<AcRxClass*> vecClassDesc;
	vecClassDesc.push_back(classDesc);
 
	return PromptSelectEnts(prompt, vecClassDesc, entIds);
}
 
bool CSelectUtil::PromptSelectEnts(const TCHAR* prompt, const std::vector<AcRxClass*> &classDescs, AcDbObjectIdArray &entIds)
{
	// 初始化
	entIds.setLogicalLength(0);
 
	// 提示用户选择实体
	ads_name sset;
	int result = 0;
	acutPrintf(prompt);
	result = acedSSGet(NULL, NULL, NULL, NULL, sset);
 
	if (result != RTNORM)
	{
		return false;
	}
 
	// 取得选择集的长度
	long length = 0;
	acedSSLength(sset, reinterpret_cast<Adesk::Int32*>(&length));
 
	// 遍历选择集
	Acad::ErrorStatus es; 
	AcDbEntity* pEnt = NULL;
	for (long i = 0; i < length; i++)
	{
		ads_name ename;
		acedSSName(sset, i, ename);
 
		AcDbObjectId curEntId;
		es = acdbGetObjectId(curEntId, ename);
		if (es != Acad::eOk)
		{
			continue;
		}
 
		// 打开实体
		es = acdbOpenObject(pEnt, curEntId, AcDb::kForRead);
		if (es != Acad::eOk)
		{
			continue;
		}
 
		// 判断当前实体是否是指定的实体类型
		for (int j = 0; j < (int)classDescs.size(); j++)
		{
			if (pEnt->isKindOf(classDescs[j]))
			{
				entIds.append(pEnt->objectId());
				break;
			}
		}
 
		pEnt->close();	// 关闭实体
	}
	acedSSFree(sset);	// 释放选择集
 
	return (entIds.length() > 0);
}

(2)注册一个命令DeleteGroup,

提示用户选择图形中位于编组内的实体,然后删除这个编组。

实现函数为:

	static void AAAMyGroupDeleteGroup() {
		AcDbObjectIdArray entIds;
		if (CSelectUtil::PromptSelectEnts(TEXT("\n选择要分解的组中的实体:"), AcDbEntity::desc(), entIds))
		{
			//遍历组字典,判断是否包含了给定的实体
			AcDbDictionary *pGroupDict = NULL;
			acdbHostApplicationServices()->workingDatabase()->getGroupDictionary(pGroupDict, AcDb::kForWrite);
			AcDbDictionaryIterator *it = pGroupDict->newIterator();
			for (; !it->done(); it->next())
			{
				AcDbGroup *pGroup = NULL;
				if (it->getObject((AcDbObject*&)pGroup, AcDb::kForWrite) == Acad::eOk)
				{
					AcDbObjectIdArray groupEntIds;
					pGroup->allEntityIds(groupEntIds);
					bool bFound = false;
					for (int i = 0; i < entIds.length(); i++)
					{
						if (groupEntIds.contains(entIds[i]))
						{
							bFound = true;
							break;
						}
					}
					//删除包含选择集中实体的组
					if (bFound)
					{
						pGroup->erase();
					}
 
					pGroup->close();
				}
				
			}
			pGroupDict->close();
		}
 
	}

效果:

①运行AutoCAD,加载生成的ARX文件,执行AddGroup命令,

选择若干实体,然后按enter键;

②使用ArxDbg工具来观察:

20180928072500730.png

20180928072557741.png

如果你没有ArxDbg工具,可从这里下载:

   https://blog.csdn.net/qq_40416052/article/details/82832475 

③执行DelGroup命令,删除编组。

ObjectARX · · 字典 ·

发表评论