ObjectArx创建自定义块
一. 目的
仿照AutoCad的Block命令,实现简版创建块功能!
二. 开发环境
W
in7操作系统,AutoCad2012, VS2008, ObjectArx_SDK_2012
三. 相关函数简介
1
)
int acedSSGet (const ACHAR *str, const void *pt1,const void *pt2, const struct resbuf *filter,ads_name ss);
选择集,个人理解:就是让你一次可以选择多个实体,与之相似的acedEntSel()一次只能选择一个实体
2) int acedSSName (const ads_name ss, AdInt32 i, ads_name entres)
既然选择了多个实体,我怎么得到其中的每一个实体呢?次函数即可让你得到选择实体中的任一个,参数二相当于索引,参数三就是还回的实体名
3)Acad::ErrorStatus acdbGetObjectId(AcDbObjectId& objId,const ads_name objName);
通过实体名获取实体ID,与之相同的另外几个函数(指针,句柄,ads_name之间的转换)
acdbopenAcDbEntity,objectid,getAcDbObject,acdbGetObjectid,acdbGetAdsName等
四.代码实现流程
1) 首先我们得获取实体,保存这些实体的ID,实现代码:
void MyBlock::GetPickEntity(AcDbObjectIdArray &idObjectArray)
{
ads_name adsName;
AdInt32 ssLen;
acedSSGet(NULL, NULL, NULL, NULL, adsName);
acedSSLength(adsName, &ssLen);
idObjectArray.removeAll();
for (INT32 i = 0; i < ssLen; i++)
{
ads_name entityName;
acedSSName(adsName, i, entityName);
AcDbObjectId entityID;
acdbGetObjectId(entityID, entityName);
idObjectArray.append(entityID);
}
acedSSFree(adsName);
2) 从当前块表中查看是否已存在此块名记录,没有则创建新的块表记录,将选择的实体Clone一份,插入到新的
块表记录中
,切记,关闭所有的数据库对象,实现代码(代码有点渣):
Acad::ErrorStatus MyBlock::CreateBlock(const CString &strBlockName, const AcDbObjectIdArray &idObjectArray)
{
AcDbBlockTable *pBlockTable = NULL;
Acad::ErrorStatus es = acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlockTable, AcDb::kForRead);
if (Acad::eOk != es)
{
return es;
}
if (Adesk::kTrue == pBlockTable->has(strBlockName))
{
pBlockTable->close();
return es;
}
AcDbBlockTableRecord *pBlockTableRcd = new AcDbBlockTableRecord();
es = pBlockTableRcd->setName(strBlockName);
es = pBlockTableRcd->setOrigin(AcGePoint3d::kOrigin);
es = pBlockTable->upgradeOpen();
if (Acad::eOk != es)
{
pBlockTableRcd->close();
pBlockTable->close();
return es;
}
es = pBlockTable->add(pBlockTableRcd);
if (Acad::eOk != es)
{
pBlockTable->close();
pBlockTableRcd->close();
return es;
}
pBlockTable->close();
AcGeMatrix3d mat;
mat.setToIdentity();
for (INT32 i = 0; i < idObjectArray.length(); i++)
{
AcDbEntity *pEntity = NULL;
es = acdbOpenAcDbEntity(pEntity, idObjectArray.at(i), AcDb::kForRead);
if (Acad::eOk != es)
{
acDocManager->unlockDocument(curDoc());
pBlockTableRcd->close();
return es;
}
AcDbEntity *pNewEntity = AcDbEntity::cast(pEntity->clone());
es = pBlockTableRcd->appendAcDbEntity(pNewEntity);
if (Acad::eOk != es)
{
acDocManager->unlockDocument(curDoc());
pBlockTableRcd->close();
pEntity->close();
pNewEntity->close();
return es;
}
pEntity->close();
pNewEntity->close();
}
pBlockTableRcd->close();
return es;
三).创建非模式对话框,继承自CAcUiDialog类!
具体添加一些控件与消息响应以及还未完成的非模式对话框销毁(DestoryWindow)就不一一叙述了!
五. 成果截图
1)执行自定义命令,点击拾取,我这里选择3条边与一个圆,总共4个对象,joke为新块名,然后点击创建
2)在命令提示符输入指令insert,即可预览刚才创建的新块
3)点击确定,即可在Cad工作区添加此块,然后可点击颜色,如下:
4)这里我先则蓝色,即可改变刚才插入新块的颜色:
六. 源码
源码地址:http://download.csdn.net/detail/u012158162/9795717
七 后序:
A. 由于个人技术原因以及刚接触Cad与ObjectArx几天,其中难免有些胡说八道,请见谅!
B. 程序中修改块的颜色存在Bug,以及没对MFC的对话框销毁做处理!
C. 祝大家学习是艰辛的,生活是快乐的!