老潜水员 2024-01-22 08:43 采纳率: 100%
浏览 35
已结题

ObjectARX判断是否为同一实体

CAD二次开发,ObjectARX如何判断两次取到的实体是否为同一实体

  • 写回答

2条回答 默认 最新

  • CSDN-Ada助手 CSDN-AI 官方账号 2024-01-22 10:02
    关注

    【相关推荐】



    • 这篇博客: 关于objectArx /CAD二次开发中“属性块”操作中的 关于objectArx /CAD二次开发中“属性块”操作 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:

      属性块就是在图块上附加一些文字属性(Attribute),这些文字可以非常方便地修改。属性块被广泛应用在工程设计和机械设计中,在工程设计中会用属性块来设计轴号、门窗、水暖电设备等,在机械设计中会应用于粗糙度符号定制、图框标题栏、明细表等。例如建筑图中的轴号就是同一个图块
      轴号做成属性块
      objectArx /CAD二次开发中常见的“属性块”操作有
      1.创建属性块
      2.插入属性块
      3.向现有的块参照中追加属性
      4.读取块中属性值
      5.修改块中属性值
      6.判断块中是否包含某标识的属性
      1.创建属性块
      创建一个带属性的块定义时,可直观地将“属性”看成一个直线一样的“实体”,将其附加到块表记录中即可。下面函数演示的是创建包含两条直线,一个圆以及属性标志为“直径”,值为“20”的属性块定义。

      bool yBlock::createBlockWithAtt(CString blkName)
      {
      	// 获得当前图形数据库的块表
      	AcDbBlockTable *pBlkTbl = NULL;
      	acdbHostApplicationServices()->workingDatabase()
      		->getBlockTable(pBlkTbl, AcDb::kForWrite);
      
      	// 创建新的块表记录
      	AcDbBlockTableRecord *pBlkTblRcd ;
      	Acad::ErrorStatus es = pBlkTbl->getAt(blkName, pBlkTblRcd, AcDb::kForRead);
      	if (es == Acad::eOk)
      	{
      		pBlkTbl->close();
      		acutPrintf(_T("记录已经存在"));
      		return false;
      	}
      	pBlkTblRcd->setName(blkName);
      
      	// 将块表记录添加到块表中
      	AcDbObjectId blkDefId;
      	pBlkTbl->add(blkDefId, pBlkTblRcd);
      	pBlkTbl->close();
      
      	// 向块表记录中添加实体
      	AcGePoint3d ptStart(-10, 0, 0), ptEnd(10, 0, 0);
      	AcDbLine *pLine1 = new AcDbLine(ptStart, ptEnd);	// 创建一条直线
      	ptStart.set(0, -10, 0);
      	ptEnd.set(0, 10, 0);
      	AcDbLine *pLine2 = new AcDbLine(ptStart, ptEnd);	// 创建一条直线
      	AcGeVector3d vecNormal(0, 0, 1);
      	AcDbCircle *pCircle = new AcDbCircle(AcGePoint3d::kOrigin, vecNormal, 6);
      
      	// 创建一个属性  输入直径
      	AcDbAttributeDefinition *pAttDef = new AcDbAttributeDefinition(
      		ptEnd, TEXT("20"), TEXT("直径"), TEXT("输入直径"));
      
      	AcDbObjectId entId;
      	pBlkTblRcd->appendAcDbEntity(entId, pLine1);
      	pBlkTblRcd->appendAcDbEntity(entId, pLine2);
      	pBlkTblRcd->appendAcDbEntity(entId, pCircle);
      	pBlkTblRcd->appendAcDbEntity(entId, pAttDef);
      
      	// 关闭实体和块表记录
      	pLine1->close();
      	pLine2->close();
      	pCircle->close();
      	pAttDef->close();
      	pBlkTblRcd->close();
      	return true;
      }
      

      2.插入属性块
      当数据库内存在属性块时,插入属性块与插入普通快有较大区别,其过程可描述为:
      1.插入一个普通的块参照
      2.遍历块参照中对应的块表记录,如果找到的记录是属性定义,则创建一个属性,属性参数来自于块记录,最后附加到块参照中。
      下面函数展示的是掺入一个属性块,参数idBlkDef(块定义ID),ptInsert(属性块插入位置),返回属性块参照。

      AcDbBlockReference* CreateAttBlkRef(const AcDbObjectId& idBlkDef, const AcGePoint3d& ptInsert)
      {
      	AcDbBlockReference* pBlkRef = new AcDbBlockReference(ptInsert, idBlkDef);
      	//判断指定的块表是否包含属性定义
      	AcDbBlockTableRecordPointer pBlkTblRcd(idBlkDef, AcDb::kForWrite);
      	if (Acad::eOk != pBlkTblRcd.openStatus())
      		return pBlkRef;
      	if (!pBlkTblRcd->hasAttributeDefinitions())
      		return pBlkRef;
      	//创建块表记录遍历器,用于访问块定义中的所有实体
      	AcDbBlockTableRecordIterator* pIter = NULL;
      	Acad::ErrorStatus es = pBlkTblRcd->newIterator(pIter);
      	if (Acad::eOk != es)
      		return pBlkRef;
      	for (pIter->start(); !pIter->done(); pIter->step())
      	{
      		AcDbEntity* pEnt = NULL;
      		if (Acad::eOk != pIter->getEntity(pEnt, AcDb::kForRead))
      			continue;
      		//如果是属性定义,就向块参照添加属性
      		AcDbAttributeDefinition* pAttDef = AcDbAttributeDefinition::cast(pEnt);
      		if (pAttDef != NULL)
      		{
      			//创建一个新的属性对象
      			AcDbAttribute* pAtt = new AcDbAttribute();
      			//从属性定义获得属性对象的对象特征
      			pAtt->setPropertiesFrom(pBlkRef);
      			pAtt->setLayer(pBlkRef->layerId());
      			//设置属性对象的其它特性
      			pAtt->setInvisible(pAttDef->isInvisible());
      			pAtt->setPosition(pAttDef->position());
      			pAtt->setHeight(pAttDef->height());
      			pAtt->setWidthFactor(pAttDef->widthFactor());
      			pAtt->setRotation(pAttDef->rotation());
      			pAtt->setHorizontalMode(pAttDef->horizontalMode());
      			pAtt->setVerticalMode(pAttDef->verticalMode());
      			pAtt->setAlignmentPoint(pAttDef->alignmentPoint());
      			pAtt->setTextStyle(pAttDef->textStyle());
      			pAtt->setAttributeFromBlock(pBlkRef->blockTransform());
      			//获得属性对象的Tag、Prompt和TextString
      			pAtt->setTag(pAttDef->tagConst());
      			pAtt->setFieldLength(pAttDef->fieldLength());
      			pAtt->setTextString(pAttDef->textStringConst());
      			//设置颜色
      			pAtt->setColorIndex(pAttDef->colorIndex());
      			//向块参照追加属性对象
      			pBlkRef->appendAttribute(pAtt);
      			pAtt->close();
      		}
      		pEnt->close();
      	}
      	DEL(pIter);
      
      	return pBlkRef;
      }
      

      3.向现有的块参照中追加属性
      当数据库中已经创建了块参照,而块参照中并无属性,以下函数展示了像现有的块参照中追加属性,注意,该块参照追加属性后,再插入一个新的同名块时,属性也存在块定义中了。
      参数:blkRefId(块参照ID),ptPos(属性在块参照中的位置),strTag(属性标志)
      prompt(属性提示字符串),strValue(属性值),textHeight(属性文字高度),textStyle(属性文字样式)

      bool AppendBlkAttribute(AcDbObjectId &blkRefId, AcGePoint3d ptPos, CString strTag, CString prompt, CString strValue,double textHeight, AcDbObjectId textStyle)
      {
      	if (!blkRefId.isValid())
      	{
      		return false;
      	}
      	//
      	AcDbObjectPointer<AcDbBlockReference> pBlkRef(blkRefId, AcDb::kForWrite);
      	if (pBlkRef == NULL)
      	{
      		return false;
      	}
      	AcDbObjectId blkTblRcdId = pBlkRef->blockTableRecord();
      	AcDbObjectPointer<AcDbBlockTableRecord> pBlkTblRcd(blkTblRcdId, AcDb::kForWrite);
      
      	AcDbBlockTableRecordIterator* pIter = NULL;
      	if (Acad::eOk != pBlkTblRcd->newIterator(pIter) || NULL == pIter)
      		return false;
      
      
      	int nRs = 0;
      	for (pIter->start(); !pIter->done(); pIter->step())
      	{
      		AcDbObjectId attId;
      		if (Acad::eOk != pIter->getEntityId(attId))
      			continue;
      
      		AcDbObjectPointer<AcDbAttributeDefinition> pDef(attId, AcDb::kForRead);
      		if (Acad::eOk != pDef.openStatus())
      			continue;
      		CString strText;
      		CString strTagT = pDef->tagConst();
      		if (strTagT.Compare(strTag) == 0)
      		{
      			//pDef->setPrompt(strPro);
      			strText = pDef->textStringConst();
      			return true;
      		}
      	}
      	//添加属性
      	AcDbAttributeDefinition *pAttDef = new AcDbAttributeDefinition(ptPos, strValue, strTag,prompt);
      	pAttDef->setHeight(textHeight);
      	pAttDef->setInvisible(false);
      	pAttDef->setTextStyle(textStyle);
      	//pAttDef->setVisibility(AcDb::Visibility::kInvisible);
      	Acad::ErrorStatus es = pBlkTblRcd->appendAcDbEntity(pAttDef);
      	pAttDef->close();
      	if (es == Acad::eOk)
      	{
      		AcDbAttribute *pAtt = new AcDbAttribute(ptPos, strValue, strTag);
      		pAtt->setInvisible(false);
      		pBlkRef->appendAttribute(pAtt);
      
      		pAtt->close();
      	}
      	return false;
      }
      

      4.读取块中属性值
      以下函数展示了获取块参照的属性标志以及对应的属性值
      参数:idRef(块参照ID)

      std::map<CString, CString> GetAttInfoOnBlkRef(const AcDbObjectId& idRef)
      {
      	std::map<CString, CString> maptag;
      	AcDbObjectPointer<AcDbBlockReference> pBlkRef(idRef, AcDb::kForRead);
      	if (pBlkRef.openStatus() != Acad::eOk)
      		return maptag;
      
      	AcDbObjectIterator* pIter = pBlkRef->attributeIterator();
      	if (!pIter)
      		return maptag;
      
      	for (pIter->start(); !pIter->done(); pIter->step())
      	{
      		AcDbObjectId attId = pIter->objectId();
      		AcDbAttribute* pAtt = NULL;
      		if (pBlkRef->openAttribute(pAtt, attId, AcDb::kForRead) != Acad::eOk)
      			continue;
      		maptag.insert(std::pair<CString, CString>(pAtt->tagConst(), pAtt->textStringConst()));
      		pAtt->close();
      	}
      	DEL(pIter);
      	return maptag;
      }
      

      5.修改块中属性值
      以下函数展示了设置属性块某个标志的值
      参数:idRef(块参照ID),szTag(属性标志),szText(属性值)

      bool SetAttTextOnBlkRef(const AcDbObjectId& idRef, LPCTSTR szTag, LPCTSTR szText)
      {
      	AcDbObjectPointer<AcDbBlockReference> pBlkRef(idRef, AcDb::kForWrite);
      	if (pBlkRef.openStatus() != Acad::eOk)
      		return false;
      	AcDbObjectIterator* pIter = pBlkRef->attributeIterator();
      	if (!pIter)
      		return false;
      	bool bFlag = false;
      	for (pIter->start(); !pIter->done(); pIter->step())
      	{
      		AcDbObjectId attId = pIter->objectId();
      		AcDbAttribute* pAtt = NULL;
      		if (pBlkRef->openAttribute(pAtt, attId, AcDb::kForWrite) != Acad::eOk)
      			continue;
      		CString strTempTag = pAtt->tagConst();
      		if (_tcsicmp(szTag, strTempTag) == 0)
      		{
      			pAtt->setTextString(szText);
      			pAtt->close();
      			bFlag = true;
      			break;
      		}
      		pAtt->close();
      	}
      	DEL(pIter);
      	return bFlag;
      }
      

      6.判断块中是否包含某个标识的属性
      以下函数展示了判断一个块中是否包含了标识为szTag的属性
      参数:pBlkRef(块参照),szAttName(属性标志)

      bool IsExistAtt(AcDbBlockReference* pBlkRef, LPCTSTR szAttName)
      {
      	AcDbObjectIterator* pIter = pBlkRef->attributeIterator();
      	if (!pIter)
      		return false;
      	for (pIter->start(); !pIter->done(); pIter->step())
      	{
      		AcDbObjectId attId = pIter->objectId();
      		AcDbAttribute* pAtt = NULL;
      		if (pBlkRef->openAttribute(pAtt, attId, AcDb::kForRead) != Acad::eOk)
      			continue;
      		CString strTempTag = pAtt->tagConst();
      		if (_tcsicmp(szAttName, strTempTag) == 0)
      		{
      			pAtt->close();
      			DEL(pIter);
      			return true;
      		}
      		pAtt->close();
      	}
      	DEL(pIter);
      	return false;
      }
      

    如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 6月1日
  • 已采纳回答 5月24日
  • 创建了问题 1月22日