ObjectARX_AcDbAttributeDefinition屬性定義對象

(1)先介紹倆個cad的命令:數據庫

命令BATTMAN : 塊屬性管理器(批量修改圖塊屬性)app

命令BEDIT:編輯塊定義3d

(2)建立帶屬性的塊code

// 根據用戶的輸入設置塊表記錄的名稱
	TCHAR blkName[40];
	if (acedGetString(Adesk::kFalse, _T("\n輸入圖塊的名稱:"), blkName) !=RTNORM)
		return;

	// 得到當前圖形數據庫的塊表
	AcDbBlockTable *pBlkTbl = NULL;
	acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlkTbl, AcDb::kForWrite);
	if (NULL == pBlkTbl)
		return;

	// 建立新的塊表記錄
	AcDbBlockTableRecord *pBlkTblRcd = new AcDbBlockTableRecord();
	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, _T("默認值"),_T( "標記"), _T("提示")); 
	
	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();

(3)插入帶屬性圖塊:能夠直接使用cad提供的INSERT命令orm

// 得到用戶輸入的塊定義名稱 
	TCHAR blkName[40];
	if (acedGetString(Adesk::kFalse, _T("\n輸入圖塊的名稱:"), blkName) !=RTNORM)
		return;
	
	// 得到當前數據庫的塊表
	AcDbBlockTable *pBlkTbl = NULL;
	acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlkTbl, AcDb::kForWrite);
	if (NULL == pBlkTbl)
		return;

	// 查找用戶指定的塊定義是否存在
	CString strBlkDef;
	strBlkDef.Format(_T("%s"), blkName);
	if (!pBlkTbl->has(strBlkDef))
	{
		acutPrintf(_T("\n當前圖形中未包含指定名稱的塊定義!"));
		pBlkTbl->close();
		return;
	}

	// 得到用戶輸入的塊參照的插入點
	ads_point pt;
	if (acedGetPoint(NULL, _T("\n輸入塊參照的插入點:"), pt) != RTNORM)
	{ 
		pBlkTbl->close();
		return;
	}

	AcGePoint3d ptInsert = asPnt3d(pt);
	// 得到用戶指定的塊表記錄
	AcDbObjectId blkDefId;
	pBlkTbl->getAt(strBlkDef, blkDefId);

	// 將塊參照添加到模型空間
	AcDbBlockTableRecord *pBlkTblRcd = NULL;
	pBlkTbl->getAt(ACDB_MODEL_SPACE, pBlkTblRcd,AcDb::kForWrite);
	pBlkTbl->close();
	if (NULL == pBlkTblRcd)
		return;
	
	// 建立塊參照對象
	AcDbBlockReference *pBlkRef = new AcDbBlockReference(ptInsert,	blkDefId);
	AcDbObjectId entId;
	pBlkTblRcd->appendAcDbEntity(entId, pBlkRef); 

	// 判斷指定的塊表記錄是否包含屬性定義
	AcDbBlockTableRecord *pBlkDefRcd = NULL;
	acdbOpenObject(pBlkDefRcd, blkDefId, AcDb::kForRead);
	if (NULL == pBlkDefRcd)
	{
		pBlkRef->close();
		pBlkTblRcd->close();
		return;
	}

	if (pBlkDefRcd->hasAttributeDefinitions())
	{
		AcDbBlockTableRecordIterator *pItr = NULL;
		pBlkDefRcd->newIterator(pItr);
		AcDbEntity *pEnt = NULL;
		AcDbAttributeDefinition *pAttDef = NULL;
		for (pItr->start(); !pItr->done(); pItr->step())
		{
			pItr->getEntity(pEnt, AcDb::kForRead);

			// 檢查實體是不是屬性定義
			pAttDef = AcDbAttributeDefinition::cast(pEnt);
			if (pAttDef != NULL)
			{
				// 建立一個新的屬性對象
				AcDbAttribute *pAtt = new AcDbAttribute();

				// 從屬性定義得到屬性對象的對象特性
				pAtt->setPropertiesFrom(pAttDef);

				// 設置屬性對象的其餘特性
				pAtt->setInvisible(pAttDef->isInvisible());

				AcGePoint3d ptBase = pAttDef->position();
				ptBase += pBlkRef->position().asVector();

				pAtt->setPosition(ptBase);
				pAtt->setHeight(pAttDef->height());
				pAtt->setRotation(pAttDef->rotation());
					
				// 得到屬性對象的Tag、Prompt和TextString
				ACHAR *pStr;
				pStr = pAttDef->tag();
				pAtt->setTag(pStr);
				free(pStr);
				pStr = pAttDef->prompt();
				acutPrintf(_T("\n%s%s"), pStr);
				free(pStr);
				pAtt->setFieldLength(30);
				pAtt->setTextString(_T("當前值"));

				// 向塊參照追加屬性對象
				pBlkRef->appendAttribute(pAtt);
				pAtt->close();
				
			}
			pEnt->close();
		}
		pAttDef->close();
		delete pItr;
	}
	// 關閉數據庫的對象
	pBlkRef->close();
	pBlkTblRcd->close();
	pBlkDefRcd->close();

(4)獲取參照塊的屬性對象

ads_name ssResult;
	ads_point ssptres;
	acedEntSel(_T("選擇一個塊:\n"), ssResult, ssptres);

	AcDbObjectId blkRefId;
	acdbGetObjectId(blkRefId, ssResult);

	AcDbBlockReference *pRef = NULL;
	Acad::ErrorStatus es = acdbOpenObject(pRef, blkRefId, AcDb::kForWrite);  
	if (NULL == pRef || es != eOk)
		return ;
	
	AcDbObjectId  blkrecId = pRef->blockTableRecord();
	pRef->close();

	AcDbBlockTableRecord *pBlkDefRcd = NULL;
	es=acdbOpenObject(pBlkDefRcd, blkrecId , AcDb::kForRead); 
	if (NULL == pBlkDefRcd || es != eOk)
		return ;

	if (pBlkDefRcd->hasAttributeDefinitions())  //是否有屬性
	{
		//當前值
		AcDbObjectIterator* pItr = pRef->attributeIterator();
		for(pItr->start(); !pItr->done(); pItr->step())
		{
			AcDbObjectId attid = pItr->objectId();
			AcDbAttribute* pAttr = NULL;
			pRef->openAttribute(pAttr, attid, AcDb::kForRead);

			ACHAR* text = pAttr->textString();
			acutPrintf(_T("當前值:%s\n"), text);
			pAttr->close();
			free(text);
		}
		delete pItr;

		//屬性
		AcDbBlockTableRecordIterator *pTItr = NULL;
		pBlkDefRcd->newIterator(pTItr);
		AcDbEntity* pEnt = NULL;
		for(pTItr->start(); !pTItr->done(); pTItr->step())
		{
			pTItr->getEntity(pEnt, AcDb::kForRead);
			AcDbAttributeDefinition* pAttDef = AcDbAttributeDefinition::cast(pEnt);
			if(pAttDef != NULL)
			{
				ACHAR * strTemp;
				strTemp = pAttDef->tag();
				acutPrintf(_T("標記:%s\n"), strTemp);
				free(strTemp);
				strTemp = pAttDef->prompt();
				acutPrintf(_T("提示:%s\n"), strTemp);
				free(strTemp);
				strTemp=pAttDef->textString();			
				acutPrintf(_T("值:%s\n"), strTemp);
				free(strTemp);

				pAttDef->close();
			}
			pEnt->close();
		}
		delete pTItr;
	}
	pBlkDefRcd->close();