CAD二次开发,ObjectARX如何判断两次取到的实体是否为同一实体
2条回答 默认 最新
关注【相关推荐】
- 这篇博客: 关于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; }
如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^本回答被题主选为最佳回答 , 对您是否有帮助呢?解决 无用评论 打赏 举报- 这篇博客: 关于objectArx /CAD二次开发中“属性块”操作中的 关于objectArx /CAD二次开发中“属性块”操作 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读: