ObjectArx创建指定块

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. 祝大家学习是艰辛的,生活是快乐的!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值