天气与日历 切换到窄版

 找回密码
 立即注册
中国膜结构网
十大进口膜材评选 十大国产膜材评选 十大膜结构设计评选 十大膜结构公司评选
楼主: admin1

ObjectArx块操作封装

[复制链接]

该用户从未签到

主题

0

回帖

2912

积分

管理员

积分
2912
 楼主| 发表于 2024-5-4 10:50:08 | 显示全部楼层
块定义
  1. #include "StdAfx.h"
  2. #include "Commands.h"
  3. #include "Editor.h"
  4. void AddCommands()
  5. {       
  6.         Editor::AddCommand(采用T("AddBlock"), ACRX采用CMD采用MODAL, CreateBlock);
  7. }
  8. void CreateBlock()
  9. {   // 创建一个空的块表对象指针pBlkTbl
  10.         AcDbBlockTable *pBlkTbl = NULL;
  11.         // 以写得方式打开数据库文件dwg,获得块表指针,并赋值给pBlkTbl
  12.         acdbHostApplicationServices()->workingDatabase()->
  13.                                 getBlockTable(pBlkTbl, AcDb::kForWrite);
  14.         // 创建一个块表记录对象(构造函数创建的)指针pBlkRcd
  15.         AcDbBlockTableRecord *pBlkRcd = new AcDbBlockTableRecord();
  16.        
  17.         // ACHAR:CAD中用于定义宽字符型变量
  18.         ACHAR  blkName[40];
  19.         // 与用户交互:输入是否包含空格、提示文字(无则NULL)、
  20.         //                          接收输入变量;RTNORM为return normal
  21.         if (acedGetString(Adesk::kFalse,
  22.                                           采用T("\n 请输入块名(空格结束):"),
  23.                                           blkName) !=  RTNORM)
  24.         {        // 未输入退出:关闭块表(针对dwg文件)
  25.                 pBlkTbl->close();
  26.                 // 删除块表指针指向的内存(释放内存)
  27.                 delete pBlkRcd;
  28.                 // 结束退出
  29.                 return;
  30.         }
  31.         // 设置块表记录名:跟Model采用Space同级,见下图
  32.         pBlkRcd->setName(blkName);
  33.         // 将块表记录添加进块表中
  34.         AcDbObjectId blkDefId;
  35.         pBlkTbl->add(blkDefId, pBlkRcd);
  36.         // 重要:添加后,调用类方法close关闭块表,可通过pBlkRcd继续操作块表记录
  37.         pBlkTbl->close();
  38.         // 创建两个数据库线对象指针
  39.         AcGePoint3d pt1(0, 0, 0), pt2(100, 0, 0), pt3(0, 100, 0);
  40.         AcDbLine *pL采用1 = new AcDbLine(pt1, pt2);
  41.         AcDbLine *pL采用2 = new AcDbLine(pt1, pt3);
  42.         // 将对象指针添加进块表记录中,entId返回的是每次添加的对象返回的对象id
  43.         AcDbObjectId entId;
  44.         pBlkRcd->appendAcDbEntity(entId, pL采用1);
  45.         pBlkRcd->appendAcDbEntity(entId, pL采用2);
  46.         // 重要:添加后,调用close函数关闭直线对象
  47.         pL采用1->close();
  48.         pL采用2->close();
  49.         // 重要:调用类方法close关闭块表记录
  50.         pBlkRcd->close();
  51. }
复制代码

 

 

 

 

ObjectArx块操作封装

该用户从未签到

主题

0

回帖

2912

积分

管理员

积分
2912
 楼主| 发表于 2024-5-4 10:51:09 | 显示全部楼层
块参照类
  1. Block.h
  2. #pragma once
  3. class Block
  4. {
  5. public:
  6.         Block();
  7.         ~Block();
  8.         // 插入块参照:块定义对象ID、插入点、比例、旋转弧度
  9.         static AcDbObjectId InsertBlkRef(AcDbObjectId blkDefId,
  10.                                                                           const AcGePoint3d &ptInsert,
  11.                                                                          double scale = 1.0,
  12.                                                                          double rotation = 0.0);
  13.         // 设置块参照比例:块参照指针、比例
  14.         static void   SetBlkScale(AcDbBlockReference *pBlkRef, double scale = 1.0);
  15.         // 获取块参照ID:传入块参照名称、数据库指针
  16.         static AcDbObjectId GetBlkDefId(const ACHAR *blkDefName,
  17.                                                                         AcDbDatabase *pDb =
  18.                                                                         acdbHostApplicationServices()->
  19.                                                                         workingDatabase());
  20. };
  21. Block.cpp
  22. #include "stdafx.h"
  23. #include "Block.h"
  24. #include "Database.h"
  25. Block::Block(){}
  26. Block::~Block(){}
  27. // 插入块参照:块定义对象ID、插入点、比例、旋转弧度
  28. AcDbObjectId Block::InsertBlkRef(AcDbObjectId blkDefId,
  29.                                                                  const AcGePoint3d &ptInsert,
  30.                                                                  double scale ,
  31.                                                                  double rotation)
  32. {        // 块参照对象指针:插入点,块定义对象ID
  33.         AcDbBlockReference *pBlkRef = new AcDbBlockReference(ptInsert, blkDefId);
  34.         // 设置块参照旋转弧度
  35.         pBlkRef->setRotation(rotation);
  36.         // 设置块参照比例
  37.         SetBlkScale(pBlkRef, scale);
  38.         // 添加进数据库文件dwg
  39.         return Database::PostToModelSpace(pBlkRef);
  40. }
  41. // 设置块参照比例:块参照指针、比例
  42. void Block::SetBlkScale(AcDbBlockReference *pBlkRef, double scale)
  43. {        // 断言块参照指针:若为空则报错,判断括号里表达式真假
  44.         assert(pBlkRef);
  45.         // 设置3d比例
  46.         AcGeScale3d geScale(scale, scale, scale);
  47.         // 设置块参照比例:传入的需要是AcGeScale3d
  48.         pBlkRef->setScaleFactors(geScale);
  49. }
  50. // 获取块定义ID:传入块定义名称、数据库指针
  51. AcDbObjectId Block::GetBlkDefId(const ACHAR *blkDefName, AcDbDatabase *pDb)
  52. {        // 块表指针
  53.         AcDbBlockTable *pBlkTbl = NULL;
  54.         // 获得块表指针并给pBlkTbl赋值
  55.         Acad::ErrorStatus es = pDb->getBlockTable(pBlkTbl, AcDb::kForRead);
  56.         // 块定义对象ID
  57.         AcDbObjectId blkDefId;
  58.         // 通过块定义名称获得块定义对象id
  59.         es = pBlkTbl->getAt(blkDefName, blkDefId);
  60.         // 关闭块表
  61.         pBlkTbl->close();
  62.         // 如果查找到,返回对象ID,没查找到返回空
  63.         if (es == Acad::eOk)
  64.         {
  65.                 return blkDefId;
  66.         }
  67.         else
  68.         {
  69.                 return AcDbObjectId::kNull;
  70.         }
  71. }
  72. #include "StdAfx.h"
  73. void AddCommands();
  74. void CreateBlock();
  75. void InsertBlk();
  76. #include "StdAfx.h"
  77. #include "Commands.h"
  78. #include "Editor.h"
  79. #include "MathUtil.h"
  80. #include "Block.h"
  81. void AddCommands()
  82. {        // 块定义
  83.         Editor::AddCommand(采用T("AddBlock"), ACRX采用CMD采用MODAL, CreateBlock);
  84.         // 插入块参照
  85.         Editor::AddCommand(采用T("InsertBlock"), ACRX采用CMD采用MODAL, InsertBlk);
  86. }
  87. void CreateBlock()
  88. {   
  89.         ...见块定义
  90. }
  91. // 插入块参照
  92. void InsertBlk()
  93. {        // 块定义名称:这里需输入AddBlock命令增加的块定义的块名
  94.         ACHAR blkName[40];
  95.         if (acedGetString(Adesk::kFalse,
  96.                                           采用T("\n 请输入待插入的块名:"),
  97.                                           blkName) != RTNORM)
  98.                 return;
  99.         // 获得块定义ID:传入块定义名称
  100.         AcDbObjectId blkDefId = Block::GetBlkDefId(blkName);
  101.         if (blkDefId.isNull())
  102.         {
  103.                 acutPrintf(采用T("\n查无此块!"));
  104.                 return;
  105.         }
  106.         // 用户交互:选项、提示信息、插入点(后续解释)
  107.         ads采用point pt;
  108.         if (acedGetPoint(NULL, 采用T("\n 选择插入点:"), pt) != RTNORM)
  109.                 return;
  110.         // 将ads采用point转换为AcGePoint3d
  111.         AcGePoint3d pInsert = asPnt3d(pt);
  112.         // 插入块参照:块定义ID、插入点、缩放比例、旋转弧度
  113.         Block::InsertBlkRef(blkDefId, pInsert, 2.0, MathUtil::PI() / 2);
  114. }
复制代码

 

 

 

 

ObjectArx块操作封装

该用户从未签到

主题

0

回帖

2912

积分

管理员

积分
2912
 楼主| 发表于 2024-5-4 10:52:36 | 显示全部楼层
// 插入带属性的块参照:块定义id、插入点、缩放比例、旋转弧度
static AcDbObjectId InsertBlkRefWithAtt(const AcDbObjectId &blkDefId,
                                                                                const AcGePoint3d &insertPoint,
                                                                                double scale = 1.0,
                                                                                double rotation = 0.0);
  1. // 插入带属性的块参照:块定义id、插入点、缩放比例、旋转弧度
  2. AcDbObjectId Block::InsertBlkRefWithAtt(const AcDbObjectId &blkDefId,
  3.                                                                                 const AcGePoint3d &insertPoint,
  4.                                                                                 double scale,
  5.                                                                                 double rotation)
  6. {        // 创建块参照对象指针:插入点、块定义id,
  7.         //                 带属性的块参照只是在块参照上增加了个文字属性,还是块参照
  8.         AcDbBlockReference *pBlkRef = new AcDbBlockReference(insertPoint, blkDefId);
  9.         // 设置块参照比例:参见本文件
  10.         SetBlkScale(pBlkRef, scale);
  11.         // 给块参照设置旋转弧度
  12.         pBlkRef->setRotation(rotation);
  13.         // 查找块定义所在的块表记录
  14.         AcDbBlockTableRecord *pBlkTblRcd = NULL;
  15.         if (acdbOpenObject(pBlkTblRcd, blkDefId, AcDb::kForRead) == Acad::eOk)
  16.         {        // 如果块表记录含有属性定义对象
  17.                 if (pBlkTblRcd->hasAttributeDefinitions())
  18.                 {        // 创建块表记录迭代器pItr
  19.                         AcDbBlockTableRecordIterator *pItr = NULL;
  20.                         // 初始化pItr
  21.                         pBlkTblRcd->newIterator(pItr);
  22.                         // 遍历块表记录中的每个实体对象,为了找属性定义对象
  23.                         for (pItr->start();!pItr->done(); pItr->step())
  24.                         {        // AcDbEntity是所有实体的基类
  25.                                 AcDbEntity *pEnt = NULL;
  26.                                 // 查找属性定义:打开每个实体
  27.                                 if (pItr->getEntity(pEnt, AcDb::kForRead) == Acad::eOk)
  28.                                 {        // 如果实体是属性定义的派生类
  29.                                         if (pEnt->isKindOf(AcDbAttributeDefinition::desc()))
  30.                                         {        // 强制类型转换,转成属性定义的指针pAttdef
  31.                                                 AcDbAttributeDefinition *pAttdef =
  32.                                                                         AcDbAttributeDefinition::cast(pEnt);
  33.                                                 // 调用本文件的函数,将属性定义加工后添加进块参照中
  34.                                                 appendAttributeToBlkRef(pBlkRef, pAttdef);
  35.                                         }
  36.                                 }// 循环内,每次打开的实体对象都要关闭
  37.                                 pEnt->close();
  38.                         }// 循环结束,删除迭代器
  39.                         delete pItr;
  40.                 }       
  41.                 // 关闭块表记录
  42.                 pBlkTblRcd->close();
  43.         }// 将块参照(属性块参照)添加进数据库文件dwg中
  44.         return Database::PostToModelSpace(pBlkRef);
  45. }
复制代码

 

 

 

 

ObjectArx块操作封装

该用户从未签到

主题

0

回帖

2912

积分

管理员

积分
2912
 楼主| 发表于 2024-5-4 10:53:16 | 显示全部楼层
// 添加属性定义到块参照:块参照指针、属性定义指针
static  void  appendAttributeToBlkRef(AcDbBlockReference *pBlkRef,
                                                                          AcDbAttributeDefinition *pAttDef);
  1. // 添加属性到块参照:块参照指针、属性定义指针
  2. void Block::appendAttributeToBlkRef(AcDbBlockReference *pBlkRef,
  3.                                                                         AcDbAttributeDefinition *pAttDef)
  4. {        // 创建属性对象指针pAtt
  5.         AcDbAttribute *pAtt = new AcDbAttribute();
  6.         // 从块参照获得属性对象的对象特性、图层
  7.         pAtt->setPropertiesFrom(pBlkRef);
  8.         pAtt->setLayer(pBlkRef->layerId());
  9.         // 从属性定义获得可见性、定位、高度、宽度因子、旋转角度
  10.         pAtt->setInvisible(pAttDef->isInvisible());
  11.         pAtt->setPosition(pAttDef->position());
  12.         pAtt->setHeight(pAttDef->height());
  13.         pAtt->setWidthFactor(pAttDef->widthFactor());
  14.         pAtt->setRotation(pAttDef->rotation());
  15.         // 从属性定义获得水平模式、垂直模式、对齐点、文字样式、属性
  16.         pAtt->setHorizontalMode(pAttDef->horizontalMode());
  17.         pAtt->setVerticalMode(pAttDef->verticalMode());
  18.         pAtt->setAlignmentPoint(pAttDef->alignmentPoint());
  19.         pAtt->setTextStyle(pAttDef->textStyle());
  20.         pAtt->setAttributeFromBlock(pBlkRef->blockTransform());
  21.         // 从属性定义中 获得 并设置 标签tag名,就是样例为“直径”
  22.         ACHAR *pStr = pAttDef->tag();
  23.         pAtt->setTag(pStr);
  24.         // 删除字符串指针
  25.         acutDelString(pStr);
  26.         // 从属性定义中获得命名空间长度、设置text的value
  27.         pAtt->setFieldLength(pAttDef->fieldLength());
  28.         pAtt->setTextString(pAttDef->textString());
  29.         // 将属性对象添加进块参照中,构成属性块参照
  30.         pBlkRef->appendAttribute(pAtt);
  31.         // 关闭属性对象
  32.         pAtt->close();
  33. }
复制代码

 

 

 

 

ObjectArx块操作封装

该用户从未签到

主题

0

回帖

2912

积分

管理员

积分
2912
 楼主| 发表于 2024-5-4 10:53:54 | 显示全部楼层
// 修改带属性的块参照中的属性:块参照指针、属性标签、Text对应的value新值
static bool SetBlockRefAttribute(AcDbBlockReference *pBlkRef,
                                                                 const ACHAR *tag,
                                                                 const ACHAR *val);
  1. // 修改带属性的块参照的属性:块参照指针、tag标签名、text的value新值
  2. bool Block::SetBlockRefAttribute(AcDbBlockReference *pBlkRef,
  3.                                                                  const ACHAR *tag,
  4.                                                                  const ACHAR *val)
  5. {
  6.         AcDbBlockTableRecord *pBlkTblRcd = NULL;
  7.         bool bRet = true;
  8.         // 提取 块参照 的 块表记录指针pBlkTblRcd:
  9.         //                块参照指针->blockTableRecord()
  10.         //                返回 块参照 的 块表记录 的 对象id
  11.         if (acdbOpenObject(pBlkTblRcd,
  12.                                            pBlkRef->blockTableRecord(),
  13.                                            AcDb::kForRead) == Acad::eOk)
  14.         {        // 判断模型空间中的块表记录(块参照所在的)是否含有属性
  15.                 if (pBlkTblRcd->hasAttributeDefinitions())
  16.                 {        // 创建 块表记录迭代器 指针 及 初始化
  17.                         AcDbBlockTableRecordIterator *pItr = NULL;
  18.                         pBlkTblRcd->newIterator(pItr);
  19.                         AcDbEntity *pEnt = NULL;
  20.                         // 通过 块表记录迭代器 遍历 块表记录中 各个实体 找 属性对象
  21.                         for (pItr->start();!pItr->done(); pItr->step())
  22.                         {
  23.                                 pItr->getEntity(pEnt, AcDb::kForRead);
  24.                                 // 如果找到属性对象:见代码下的解释
  25.                                 if (pEnt->isKindOf(AcDbAttributeDefinition::desc()))
  26.                                 {        // 强制类型转换为 属性定义指针(从基类到派生类)
  27.                                         AcDbAttributeDefinition *pAttDef =
  28.                                                                         AcDbAttributeDefinition::cast(pEnt);
  29.                                         // 获得属性定义的tag标签名:此例为“直径”
  30.                                         ACHAR *pszTag = pAttDef->tag();
  31.                                         // 浅拷贝个副本
  32.                                         CString strTag = pszTag;
  33.                                         // 释放pszTag指针内存,未删除指针
  34.                                         acutDelString(pszTag);
  35.                                         // 找到目标标签tag:不区分大小写的比较strTag和tag(相同为0)
  36.                                         if (strTag.CompareNoCase(tag) == 0)
  37.                                         {        // 是否发现目标tag标签
  38.                                                 bool bFound = false;
  39.                                                 // 创建块参照 的 属性迭代器(一个属性块可以有多个属性)
  40.                                                 // 方法的返回值为AcDbObjectIterator *
  41.                                                 AcDbObjectIterator *attIt = pBlkRef->attributeIterator();
  42.                                                 // 循环迭代读取每个属性
  43.                                                 for (attIt->start();!attIt->done();attIt->step())
  44.                                                 {       
  45.                                                         AcDbAttribute *pAtt = NULL;
  46.                                                         // attIt->objectId():属性遍历器获得对象ID的方法,
  47.                                                         //                                          属性对象指针pAtt接收返回值
  48.                                                         Acad::ErrorStatus es = acdbOpenObject(pAtt,
  49.                                                                                                                                   attIt->objectId(),
  50.                                                                                                                                   AcDb::kForWrite);
  51.                                                         if (es == Acad::eOk)
  52.                                                         {        // 提取属性对象的标签,此例“直径”
  53.                                                                 pszTag = pAtt->tag();
  54.                                                                 strTag = pszTag;
  55.                                                                 acutDelString(pszTag);
  56.                                                                 // 当当前遍历的标签名strTag和传入的目标标签名tag匹配
  57.                                                                 if (strTag.CompareNoCase(tag) == 0)
  58.                                                                 {        // 修改属性的text的value值
  59.                                                                         pAtt->setTextString(val);
  60.                                                                         bFound = true;
  61.                                                                 }// 关闭属性对象
  62.                                                                 pAtt->close();
  63.                                                         }
  64.                                                 }// 删除属性迭代器
  65.                                                 delete attIt;
  66.                                                 // 如果没发现匹配的属性标签tag,将属性定义添加进块参照中
  67.                                                 if (!bFound)
  68.                                                 {        // 将属性添加进块参照中
  69.                                                         appendAttributeToBlkRef(pBlkRef, pAttDef);
  70.                                                 }
  71.                                         }
  72.                                 }// 关闭实体
  73.                                 pEnt->close();
  74.                         }// 删除实体迭代器
  75.                         delete pItr;
  76.                 }// 提取失败:返回false
  77.                 else
  78.                 {        // 修改失败
  79.                         bRet = false;
  80.                 }// 关闭块表记录
  81.                 pBlkTblRcd->close();
  82.         }// 返回是否修改是否成功
  83.         return bRet;
  84. }
复制代码

 

 

 

 

ObjectArx块操作封装

该用户从未签到

主题

0

回帖

2912

积分

管理员

积分
2912
 楼主| 发表于 2024-5-4 10:54:12 | 显示全部楼层
  1. #include "StdAfx.h"
  2. #include "Commands.h"
  3. #include "Editor.h"
  4. #include "MathUtil.h"
  5. #include "Block.h"
  6. #include "atlstr.h"        // 需要这个,否则CString无法识别
  7. void AddCommands()
  8. {        // 属性块定义
  9.         Editor::AddCommand(采用T("AddAttBlk"), ACRX采用CMD采用MODAL, CreateAttBlk);
  10.         // 插入属性块参照
  11.         Editor::AddCommand(采用T("InsertAtt"), ACRX采用CMD采用MODAL, InsertAtt);
  12. }
  13. // 创建属性块定义
  14. void CreateAttBlk()
  15. {        // 以下为创建块定义代码,同上一节
  16.         AcDbBlockTable *pBlkTbl = NULL;
  17.         acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlkTbl,
  18.                                                                                                                                         AcDb::kForWrite);
  19.         AcDbBlockTableRecord *pBlkRcd = new AcDbBlockTableRecord();
  20.         ACHAR  blkName[40];
  21.         if(acedGetString(Adesk::kFalse,采用T("\n 请输入块名(空格结束):"),blkName) != RTNORM)
  22.         {       
  23.                 pBlkTbl->close();
  24.                 delete pBlkRcd;
  25.                 return;
  26.         }
  27.         pBlkRcd->setName(blkName);
  28.         AcDbObjectId blkDefId;
  29.         pBlkTbl->add(blkDefId, pBlkRcd);
  30.         pBlkTbl->close();
  31.         AcGePoint3d pt1(0, 0, 0), pt2(100, 0, 0), pt3(0, 100, 0);
  32.         AcDbLine *pL采用1 = new AcDbLine(pt1, pt2);
  33.         AcDbLine *pL采用2 = new AcDbLine(pt1, pt3);
  34.         // 创建属性定义对象指针:插入点、tag标签、text的value值、提示信息
  35.         AcDbAttributeDefinition *pAttDef = new AcDbAttributeDefinition(pt3,
  36.                                                                                                                                    采用T("20"),
  37.                                                                                                                                    采用T("直径"),
  38.                                                                                                                                    采用T("请输入直径"));
  39.         // 将对象指针添加进块表记录中,entId返回的是每次添加的对象返回的对象id
  40.         AcDbObjectId entId;
  41.         pBlkRcd->appendAcDbEntity(entId, pL采用1);
  42.         pBlkRcd->appendAcDbEntity(entId, pL采用2);
  43.         // 将属性定义添加进块定义中
  44.         pBlkRcd->appendAcDbEntity(entId, pAttDef);
  45.         pL采用1->close();
  46.         pL采用2->close();
  47.         pAttDef->close();
  48.         pBlkRcd->close();
  49. }
  50. // 插入带属性的块参照
  51. void InsertAtt()
  52. {
  53.         ACHAR blkName[40];
  54.         if (acedGetString(Adesk::kFalse, 采用T("\n请输入带属性的块参照名:"), blkName) != RTNORM)
  55.         {
  56.                 return;
  57.         }
  58.         // 调用函数获得 块定义的对象id
  59.         AcDbObjectId blkDefId = Block::GetBlkDefId(blkName);
  60.         if (blkDefId.isNull())
  61.         {
  62.                 acutPrintf(采用T("查无此属性块定义"));
  63.                 return;
  64.         }
  65.         ads采用point pt;
  66.         if (acedGetPoint(NULL, 采用T("\n请选择插入点:"), pt) != RTNORM)
  67.         {
  68.                 return;
  69.         }
  70.         AcGePoint3d pInsert = asPnt3d(pt);
  71.         // 插入带属性的块参照:块定义对象id、插入点、比例、旋转角度
  72.         AcDbObjectId blkRefId = Block::InsertBlkRefWithAtt(blkDefId,
  73.                                                                                                        pInsert,
  74.                                                                                                            2,
  75.                                                                                                            MathUtil::PI()/2);
  76.        
  77.         AcDbBlockReference *pBlkRef = NULL;
  78.         if (acdbOpenObject(pBlkRef, blkRefId, AcDb::kForWrite) == Acad::eOk)
  79.         {        // 调用函数 修改块参照 的 属性值:块参照、标签名、text的value新值
  80.                 Block::SetBlockRefAttribute(pBlkRef, 采用T("直径"), 采用T("600"));
  81.                 pBlkRef->close();
  82.         }
  83. }
复制代码

 

 

 

 

ObjectArx块操作封装

该用户从未签到

主题

0

回帖

2912

积分

管理员

积分
2912
 楼主| 发表于 2024-5-4 10:55:28 | 显示全部楼层
  1. ObjectArx创建自定义块
  2. 一.  目的
  3.        仿照AutoCad的Block命令,实现简版创建块功能!
  4. 二.   开发环境
  5. W in7操作系统,AutoCad2012, VS2008, ObjectArx采用SDK采用2012
  6. 三.  相关函数简介
  7. 1 )  int acedSSGet (const ACHAR *str, const void *pt1,const void *pt2, const struct resbuf *filter,ads采用name ss);  
  8. 选择集,个人理解:就是让你一次可以选择多个实体,与之相似的acedEntSel()一次只能选择一个实体
  9. 2) int acedSSName (const ads采用name ss, AdInt32 i, ads采用name entres)
  10. 既然选择了多个实体,我怎么得到其中的每一个实体呢?次函数即可让你得到选择实体中的任一个,参数二相当于索引,参数三就是还回的实体名
  11. 3)Acad::ErrorStatus acdbGetObjectId(AcDbObjectId& objId,const ads采用name objName);
  12. 通过实体名获取实体ID,与之相同的另外几个函数(指针,句柄,ads采用name之间的转换)
  13. acdbopenAcDbEntity,objectid,getAcDbObject,acdbGetObjectid,acdbGetAdsName等
  14. 四.代码实现流程
  15. 1) 首先我们得获取实体,保存这些实体的ID,实现代码:
  16. void MyBlock::GetPickEntity(AcDbObjectIdArray &idObjectArray)
  17. {
  18. ads采用name adsName;
  19. AdInt32 ssLen;
  20. acedSSGet(NULL, NULL, NULL, NULL, adsName);
  21. acedSSLength(adsName, &ssLen);
  22. idObjectArray.removeAll();
  23. for (INT32 i = 0; i < ssLen; i++)
  24. {
  25.   ads采用name entityName;
  26.   acedSSName(adsName, i, entityName);
  27.   AcDbObjectId entityID;
  28.   acdbGetObjectId(entityID, entityName);
  29.   idObjectArray.append(entityID);
  30. }
  31. acedSSFree(adsName);
  32. }
  33. 2) 从当前块表中查看是否已存在此块名记录,没有则创建新的块表记录,将选择的实体Clone一份,插入到新的
  34. 块表记录中 ,切记,关闭所有的数据库对象,实现代码(代码有点渣):
  35. Acad::ErrorStatus MyBlock::CreateBlock(const CString &strBlockName, const AcDbObjectIdArray &idObjectArray)
  36. {
  37. AcDbBlockTable *pBlockTable = NULL;
  38. Acad::ErrorStatus es = acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlockTable, AcDb::kForRead);
  39. if (Acad::eOk != es)
  40. {
  41.   return es;
  42. }
  43. if (Adesk::kTrue == pBlockTable->has(strBlockName))
  44. {
  45.   pBlockTable->close();
  46.   return es;
  47. }
  48. AcDbBlockTableRecord *pBlockTableRcd = new AcDbBlockTableRecord();
  49. es = pBlockTableRcd->setName(strBlockName);
  50. es = pBlockTableRcd->setOrigin(AcGePoint3d::kOrigin);
  51. es = pBlockTable->upgradeOpen();
  52. if (Acad::eOk != es)
  53. {
  54.   pBlockTableRcd->close();
  55.   pBlockTable->close();
  56.   return es;
  57. }
  58. es = pBlockTable->add(pBlockTableRcd);
  59. if (Acad::eOk != es)
  60. {
  61.   pBlockTable->close();
  62.   pBlockTableRcd->close();
  63.   return es;
  64. }
  65. pBlockTable->close();
  66. AcGeMatrix3d mat;
  67. mat.setToIdentity();
  68. for (INT32 i = 0; i < idObjectArray.length(); i++)
  69. {
  70.   AcDbEntity *pEntity = NULL;
  71.   es = acdbOpenAcDbEntity(pEntity, idObjectArray.at(i), AcDb::kForRead);
  72.   if (Acad::eOk != es)
  73.   {
  74.    acDocManager->unlockDocument(curDoc());
  75.    pBlockTableRcd->close();
  76.    return es;
  77.   }
  78.   AcDbEntity *pNewEntity = AcDbEntity::cast(pEntity->clone());
  79.   es = pBlockTableRcd->appendAcDbEntity(pNewEntity);
  80.   if (Acad::eOk != es)
  81.   {
  82.    acDocManager->unlockDocument(curDoc());
  83.    pBlockTableRcd->close();
  84.    pEntity->close();
  85.    pNewEntity->close();
  86.    return es;
  87.   }
  88.   pEntity->close();
  89.   pNewEntity->close();
  90. }
  91. pBlockTableRcd->close();
  92. return es;
  93. }
复制代码

 

 

 

 

ObjectArx块操作封装

该用户从未签到

主题

0

回帖

2912

积分

管理员

积分
2912
 楼主| 发表于 2024-5-4 10:56:16 | 显示全部楼层
1、AcDbSortentsTable
1.1、类简介
AcDbSortentsTable是绘制订单信息的持久容器。它位于关键的ACAD采用SORTENTS下的关联AcDbBlockTableRecord的扩展字典中。

AcDbSortentsTable包含一组对象ID /句柄对。对象ID是要绘制的实体的对象ID, 并且句柄是块表记录中的实体的句柄(通常但不总是与关联的对象ID不同), 其表示绘制顺序中的位置。实体按递增句柄值的顺序附加到块表记录中; 换句话说, 句柄值越高, 它就越晚出现在块表记录中。当在块表记录中绘制实体时, 迭代器以附加顺序遍历块表记录。在每个实体处, 获取句柄值并用于查询sortents表。如果匹配, 则绘制与sortents表中的句柄值关联的对象ID。如果sortents表中没有匹配项,  

当修改实体的绘制顺序时, 可以修改sortents表中的许多条目。例如, 块表记录具有五个具有以下句柄的实体(通常表示为表示十六进制数字的字符串):4A, 4B, 4C, 4D, 4E。这些句柄按升序显示。当应用程序在默认方向上迭代块表记录中的实体时, 句柄值总是从一个实体增加到next实体。

要先在空间中绘制最后一个实体(或“后面”其他实体), 必须在sortents表中创建五个条目, 如下所示:

实体ID

绘制订单处理

4E

4A

4A

4B

4B

4C

4C

4D

4D

4E

条目的顺序(表示为上表中的一行)无关紧要; 绘制订单处理在执行绘制时最终通过绘制顺序句柄对条目进行排序。换句话说, 在DXF文件中, 表条目可能按以下顺序出现, 但结果绘制顺序是相同的:

实体ID

绘制订单处理

4C

4D

4B

4C

4E

4A

4D

4E

4A

4B

作为另一示例, 空间中的最后一个实体在空间中的倒数第二个实体“下”移动, 但其余实体以“自然”顺序绘制。在这种情况下, sortents表只需要两个条目, 如下所示:

实体ID

绘制订单处理

4E

4D

4D

4E

使用隐式绘制顺序“last”将新实体添加到块表记录中不需要sortents表中的新条目。

1.2、成员方法
Acad::ErrorStatus moveToBottom( const AcDbObjectIdArray& ar);

将输入对象ID数组中指定的所有实体放置在绘制顺序的开头。被移动的实体保留其相对绘制顺序。

返回eInvalidInput如果任何输入对象ID不在相关的块, 或eDuplicateKey如果任何对象ID输入数组中出现两次。

2、代码实现
如果你要调整块内的显示顺序,就是获得AcDbBlockTableRecord的扩展辞典里面的ACAD采用SORTENTS,执行完参数后记得CLOSE返回的对象。

打开块时要先以块参照AcDbBlockReference对象打开,然后用AcDbBlockReference::blockTableRecord()获取块表记录blockTableRecordId,用这个blockTableRecordId打开才是块表记录,直接用块blkid打开块,将返回eNullObjectId错误。








  1. 获取块排序表对象
  2. AcDbSortentsTable * getSortentsTable(AcDbBlockTableRecord * pRec)
  3. {
  4.     if (!pRec)
  5.         return NULL;
  6.     Acad::ErrorStatus es;
  7.     AcDbObjectId ext采用id = pRec->extensionDictionary();
  8.     if (AcDbObjectId::kNull == ext采用id)
  9.     {
  10.         pRec->upgradeOpen();
  11.         es = pRec->createExtensionDictionary();
  12.         if (es != eOk)
  13.             return NULL;
  14.         pRec->downgradeOpen();
  15.         ext采用id = pRec->extensionDictionary();
  16.         if (AcDbObjectId::kNull == ext采用id)
  17.         {
  18.             return NULL;
  19.         }
  20.         pRec->downgradeOpen();
  21.     }
  22.     AcDbDictionary *pExt;
  23.     es = acdbOpenObject(pExt, ext采用id, AcDb::kForRead);
  24.     if (Acad::eOk != es)
  25.         return NULL;
  26.     AcDbObject *pObj;
  27.     if (Acad::eOk != pExt->getAt(采用T("ACAD采用SORTENTS"), pObj, AcDb::kForWrite))
  28.     {
  29.         if (Acad::eOk != pExt->upgradeOpen())
  30.         {
  31.             pExt->close();
  32.             return NULL;
  33.         }
  34.         AcDbSortentsTable *pSt = new AcDbSortentsTable;
  35.         if (NULL == pSt)
  36.         {
  37.             pExt->close();
  38.             return NULL;
  39.         }
  40.         AcDbObjectId new采用id;
  41.         if (Acad::eOk != pExt->setAt(采用T("ACAD采用SORTENTS"), pSt, new采用id))
  42.         {
  43.             delete pSt;
  44.             pExt->close();
  45.             return NULL;
  46.         }
  47.         pSt->setBlockId(pRec->objectId());
  48.         pObj = pSt;
  49.     }
  50.     pExt->close();
  51.     if (!pObj->isKindOf(AcDbSortentsTable::desc()))
  52.     {
  53.         pObj->close();
  54.         return NULL;
  55.     }
  56.     return (AcDbSortentsTable*)pObj;
  57. }
复制代码

 

 

 

 

ObjectArx块操作封装

该用户从未签到

主题

0

回帖

2912

积分

管理员

积分
2912
 楼主| 发表于 2024-5-4 10:56:38 | 显示全部楼层
  1. 遍历块实体,后置实体集合
  2. void softBlockEntity(const AcDbObjectId& blkid)
  3. {
  4.     // 后置实体集合
  5.     AcDbObjectIdArray behindids;
  6.     AcDbBlockTableRecordIterator *iter;
  7.     AcDbBlockReference *pBlkRef;
  8.     AcDbBlockTableRecord *pRecord;
  9.     Acad::ErrorStatus es = acdbOpenObject(pBlkRef, blkid, AcDb::kForRead);
  10.     if (es != Acad::eOk)
  11.         return;
  12.     AcDbObjectId blockTableRecordId = pBlkRef->blockTableRecord();
  13.     pBlkRef->close();
  14.     es = acdbOpenObject(pRecord, blockTableRecordId, AcDb::kForWrite);
  15.     if (es != Acad::eOk || pRecord == NULL)
  16.         return;
  17.     // 遍历块内实体
  18.     pRecord->newIterator(iter);
  19.     for (iter->start(); !iter->done(); iter->step())
  20.     {
  21.         AcDbObjectId id;
  22.         es = iter->getEntityId(id);
  23.         if (es != Acad::eOk || !id.isValid())
  24.             continue;
  25.         // 过滤出需要后置的实体集合           
  26.         if (筛选条件)
  27.             behindids.append(id);
  28.     }
  29.     AcDbSortentsTable *pSortentsTable = getSortentsTable(pRecord);
  30.     // 排序表对象在使用完后记得close
  31.     if (pSortentsTable != NULL)
  32.     {
  33.         es = pSortentsTable->moveToBottom(behindids);
  34.         pSortentsTable->close();
  35.     }
  36.     delete iter;
  37.     pRecord->close();
  38. }
复制代码

 

 

 

 

ObjectArx块操作封装

该用户从未签到

主题

0

回帖

2912

积分

管理员

积分
2912
 楼主| 发表于 2024-5-4 10:59:22 | 显示全部楼层
获取指定块表,没有则创建
  1. AcDbObjectId GetBlkId(const CString& sBlkName, bool bCreate)
  2. {
  3.         AcDbObjectId idBlk = AcDbObjectId::kNull;
  4.         // 获取指定块表ID 没有则添加
  5.         AcDbBlockTablePointer pTable(acdbCurDwg(), AcDb::kForRead);
  6.         if (pTable.openStatus() != Acad::eOk)
  7.                 return idBlk;
  8.        
  9.         if (pTable->has(sBlkName))// 有指定块表直接获取ID
  10.         {
  11.                 pTable->getAt(sBlkName, idBlk);
  12.         }
  13.         else if(bCreate)// 没有指定块表 且允许创建 则创建指定块表
  14.         {
  15.                 AcDbBlockTableRecord* pRecord = new AcDbBlockTableRecord();
  16.                 pRecord->setName(sBlkName);
  17.                 if (pTable->add(idBlk, pRecord) == Acad::eOk)
  18.                         pRecord->close();
  19.                 else
  20.                         delete pRecord;
  21.         }
  22.         return idBlk;
  23. }
  24. void testCreateBlock()
  25. {
  26.         // 选择实体创建块参照
  27.         AcDbObjectId entId = SelectEnt();
  28.         if (entId.isNull())
  29.         {
  30.                 acutPrintf(采用T("选择实体失败"));
  31.                 return;
  32.         }
  33.         //获取指定块表Id
  34.         AcDbObjectId idRec = GetBlkId(采用BLOCK采用Test采用, true);
  35.         if (idRec.isNull())
  36.         {
  37.                 acutPrintf(采用T("获取%s块表Id失败"), 采用BLOCK采用Test采用);
  38.                 return;
  39.         }
  40.         AcDbEntityPointer pEnt(entId, AcDb::kForRead);
  41.         if (pEnt.openStatus() != Acad::eOk)
  42.         {
  43.                 acutPrintf(采用T("打开实体失败"));
  44.                 return;
  45.         }
  46.         //打开新的块表记录 添加实体至新块表中
  47.         AcDbBlockTableRecordPointer pBlkNew(idRec, AcDb::kForWrite);
  48.         if (pBlkNew.openStatus() != Acad::eOk)
  49.                 return;
  50.         pBlkNew->appendAcDbEntity(pEnt);
  51.         // 打开当前块表
  52.         AcDbBlockTablePointer pBlkTable(acdbCurDwg(), AcDb::kForRead);
  53.         if (pBlkTable.openStatus() != Acad::eOk)
  54.                 return;
  55.         AcGePoint3d ptInsert = AcGePoint3d::kOrigin;
  56.         // 创建块参照
  57.         AcDbObjectPointer<AcDbBlockReference> pBlkRef;
  58.         if (pBlkRef.create() != Acad::eOk)
  59.                 return;
  60.         pBlkRef->setDatabaseDefaults();
  61.         pBlkRef->setPosition(ptInsert);
  62.         pBlkRef->setBlockTableRecord(idRec);
  63.        
  64.         // 缩放块 两种方法:
  65.         // 1、通过缩放比例缩放
  66.         pBlkRef->setScaleFactors(1);//缩放比例
  67.         // 2、通过缩放矩阵缩放
  68.         AcGeMatrix3d scaleMat;
  69.         scaleMat.setToScaling(3, ptInsert);
  70.         pBlkRef->transformBy(scaleMat);
  71.        
  72.         // 旋转块 两种方法
  73.         // 1、通过旋转角度旋转
  74.         pBlkRef->setRotation(0);//旋转角度
  75.         // 2、通过旋转矩阵旋转
  76.         AcGeMatrix3d rotateMat;
  77.         rotateMat.setToRotation(3.1415926 * 0.5, AcGeVector3d::kZAxis, ptInsert);
  78.         pBlkRef->transformBy(rotateMat);
  79.         // 打开当前空间的块表记录
  80.         AcDbBlockTableRecordPointer pBlkRcd(curDoc()->database()->currentSpaceId(), AcDb::kForWrite);
  81.         if (pBlkRcd.openStatus() != Acad::eOk)
  82.                 return;
  83.         // 添加块参照到数据库
  84.         pBlkRcd->appendAcDbEntity(pBlkRef);
  85.        
  86.         return;
  87. }
  88. AcDbObjectId SelectEnt()
  89. {
  90.         ads采用name ent;
  91.         ads采用point pt;
  92.         AcDbObjectId entId = AcDbObjectId::kNull;
  93.         int ret = RTNORM;
  94.         ret = acedEntSel(采用T("\nSelect Entity: "), ent, pt);
  95.         if (RTNORM != ret)
  96.                 return entId;
  97.         acdbGetObjectId(entId, ent);
  98.         return entId;
  99. }
复制代码

 

 

 

 

ObjectArx块操作封装
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|中国膜结构网|中国膜结构协会|进口膜材|国产膜材|ETFE|PVDF|PTFE|设计|施工|安装|车棚|看台|污水池|中国膜结构网_中国空间膜结构协会

GMT+8, 2024-11-1 08:37 , Processed in 0.153922 second(s), 21 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表