|
楼主 |
发表于 2024-5-4 11:05:22
|
显示全部楼层
关于objectArx /CAD二次开发中“属性块”操作
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;
- }
复制代码 |
|