天气与日历 切换到窄版

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

ObjectArx块操作封装

[复制链接]
  • TA的每日心情
    开心
    2024-5-11 06:18
  • 签到天数: 49 天

    [LV.5]常住居民I

    185

    主题

    150

    回帖

    1695

    积分

    管理员

    积分
    1695
     楼主| 发表于 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块操作封装
    哎...膜结构车棚,签到来了1...
  • TA的每日心情
    开心
    2024-5-11 06:18
  • 签到天数: 49 天

    [LV.5]常住居民I

    185

    主题

    150

    回帖

    1695

    积分

    管理员

    积分
    1695
     楼主| 发表于 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块操作封装
    哎...膜结构车棚,签到来了1...
  • TA的每日心情
    开心
    2024-5-11 06:18
  • 签到天数: 49 天

    [LV.5]常住居民I

    185

    主题

    150

    回帖

    1695

    积分

    管理员

    积分
    1695
     楼主| 发表于 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块操作封装
    哎...膜结构车棚,签到来了1...
  • TA的每日心情
    开心
    2024-5-11 06:18
  • 签到天数: 49 天

    [LV.5]常住居民I

    185

    主题

    150

    回帖

    1695

    积分

    管理员

    积分
    1695
     楼主| 发表于 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块操作封装
    哎...膜结构车棚,签到来了1...
  • TA的每日心情
    开心
    2024-5-11 06:18
  • 签到天数: 49 天

    [LV.5]常住居民I

    185

    主题

    150

    回帖

    1695

    积分

    管理员

    积分
    1695
     楼主| 发表于 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块操作封装
    哎...膜结构车棚,签到来了1...
  • TA的每日心情
    开心
    2024-5-11 06:18
  • 签到天数: 49 天

    [LV.5]常住居民I

    185

    主题

    150

    回帖

    1695

    积分

    管理员

    积分
    1695
     楼主| 发表于 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块操作封装
    哎...膜结构车棚,签到来了1...
  • TA的每日心情
    开心
    2024-5-11 06:18
  • 签到天数: 49 天

    [LV.5]常住居民I

    185

    主题

    150

    回帖

    1695

    积分

    管理员

    积分
    1695
     楼主| 发表于 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块操作封装
    哎...膜结构车棚,签到来了1...
  • TA的每日心情
    开心
    2024-5-11 06:18
  • 签到天数: 49 天

    [LV.5]常住居民I

    185

    主题

    150

    回帖

    1695

    积分

    管理员

    积分
    1695
     楼主| 发表于 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块操作封装
    哎...膜结构车棚,签到来了1...
  • TA的每日心情
    开心
    2024-5-11 06:18
  • 签到天数: 49 天

    [LV.5]常住居民I

    185

    主题

    150

    回帖

    1695

    积分

    管理员

    积分
    1695
     楼主| 发表于 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块操作封装
    哎...膜结构车棚,签到来了1...
  • TA的每日心情
    开心
    2024-5-11 06:18
  • 签到天数: 49 天

    [LV.5]常住居民I

    185

    主题

    150

    回帖

    1695

    积分

    管理员

    积分
    1695
     楼主| 发表于 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块操作封装
    哎...膜结构车棚,签到来了1...
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|Archiver|手机版|中国膜结构网_中国空间膜结构协会

    GMT+8, 2024-5-19 04:07 , Processed in 0.063493 second(s), 21 queries .

    Powered by Discuz! X3.5

    © 2001-2024 Discuz! Team.

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