最近更新于 2025-04-29 08:55
环境
AutoCAD 机械版 2025
ObjectARX 2025
VS 2022(ISO C++14)
环境配置参考:https://blog.iyatt.com/?p=16480
块属性使用参考:https://blog.iyatt.com/?p=19800
自定义类使用参考:https://blog.iyatt.com/?p=16635
实现
InsertBlockWithAttribute.hpp
#pragma once
class InsertBlockWithAttribute
{
public:
static void init();
static void unload();
private:
/**
* @brief 工作命令
*/
static void work();
/**
* @brief 获取块定义ID
* @param blockName 块名称
* @return 块定义 ID
*/
static AcDbObjectId getBlockDefineId(AcString blockName);
/**
* @brief 插入带属性的块
* @param blockDefineId 块定义ID
* @param insertPtObj 插入点
* @return 块参照 ID
*/
static AcDbObjectId insertBlock(const AcDbObjectId& blockDefineId, const AcGePoint3d& insertPtObj);
/**
* @brief 将实体插入到模型空间中
* @param pEnt 实体
* @param pDb 当前工作数据库
* @return 插入实体的 ID
*/
static AcDbObjectId postToModalSpace(AcDbEntity* pEnt);
/**
* @brief 将属性定义添加到块参照中
* @param pBlockReference 块参照
* @param pAttributeDefinition 属性定义
*/
static void appendAttributeToBlockReference(AcDbBlockReference* pBlockReference, AcDbAttributeDefinition* pAttributeDefinition);
/**
* @brief 设置块参照的属性值
* @param pBlockReference 块参照
* @param tag 属性标记
* @param textVal 属性值
*/
static void setBlockReferenceAttribute(AcDbBlockReference* pBlockReference, AcString& tag, AcString& textVal);
};
insertBlockWithAttributeProject.cpp
#include "stdafx.h"
#include "InsertBlockWithAttribute.hpp"
void InsertBlockWithAttribute::init()
{
acedRegCmds->addCommand(L"IYATTyxTestInsertBlockWithAttribute", L"TestInsertBlockWithAttribute", L"TestInsertBlockWithAttribute", ACRX_CMD_MODAL, InsertBlockWithAttribute::work);
}
void InsertBlockWithAttribute::unload()
{
acedRegCmds->removeGroup(L"IYATTyxTestInsertBlockWithAttribute");
}
void InsertBlockWithAttribute::work()
{
AcString blockName = L"序号块";
//if (acedGetString(Adesk::kFalse, L"输入要插入的块名称:", blockName) != RTNORM)
//{
// return;
//}
AcDbObjectId blockDefineId = InsertBlockWithAttribute::getBlockDefineId(blockName);
if (blockDefineId.isNull())
{
acutPrintf(L"块定义不存在!\n");
return;
}
ads_point insertPt;
if (acedGetPoint(nullptr, L"输入插入点:", insertPt) != RTNORM)
{
return;
}
AcGePoint3d insertPtObj = asPnt3d(insertPt);
// 插入块参照
AcDbObjectId blockReferenceId = InsertBlockWithAttribute::insertBlock(blockDefineId, insertPtObj);
// 设置参数值
static int num = 1;
AcDbBlockReference* pBlockReference = nullptr;
if (acdbOpenObject(pBlockReference, blockReferenceId, AcDb::kForWrite) == Acad::eOk)
{
AcString tag = L"序号";
AcString textVal;
textVal.format(L"%d", num);
InsertBlockWithAttribute::setBlockReferenceAttribute(pBlockReference, tag, textVal);
pBlockReference->close();
++num;
}
}
AcDbObjectId InsertBlockWithAttribute::getBlockDefineId(AcString blockName)
{
AcDbBlockTable* pBlockTable = nullptr;
if (acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlockTable, AcDb::kForRead) != Acad::eOk)
{
return AcDbObjectId::kNull;
}
AcDbObjectId blockDefineId;
Acad::ErrorStatus es = pBlockTable->getAt(blockName.kACharPtr(), blockDefineId);
pBlockTable->close();
if (es == Acad::eOk)
{
return blockDefineId;
}
else
{
return AcDbObjectId::kNull;
}
}
AcDbObjectId InsertBlockWithAttribute::insertBlock(const AcDbObjectId& blockDefineId, const AcGePoint3d& insertPtObj)
{
// 块参照实例
AcDbBlockReference* pBlockReference = new AcDbBlockReference(insertPtObj, blockDefineId);
// 比例
double scale = 1;
AcGeScale3d scaleObj(scale, scale, scale);
pBlockReference->setScaleFactors(scaleObj);
// 旋转角度
double rotation = 0;
pBlockReference->setRotation(rotation);
AcDbBlockTableRecord* pBlockTableRecord = nullptr;
if (acdbOpenObject(pBlockTableRecord, pBlockReference->blockTableRecord(), AcDb::kForRead) == Acad::eOk)
{
// 判断块参照的块表记录中是否有属性定义
if (pBlockTableRecord->hasAttributeDefinitions())
{
AcDbBlockTableRecordIterator* pBlockTableRecordIterator = nullptr;
pBlockTableRecord->newIterator(pBlockTableRecordIterator);
for (pBlockTableRecordIterator->start(); !pBlockTableRecordIterator->done(); pBlockTableRecordIterator->step())
{
AcDbEntity* pEnt = nullptr;
if (pBlockTableRecordIterator->getEntity(pEnt, AcDb::kForRead) == Acad::eOk)
{
AcDbAttributeDefinition* pAttributeDefinition = AcDbAttributeDefinition::cast(pEnt);
if (pAttributeDefinition)
{
InsertBlockWithAttribute::appendAttributeToBlockReference(pBlockReference, pAttributeDefinition);
}
pEnt->close();
}
}
delete pBlockTableRecordIterator;
}
}
pBlockTableRecord->close();
return InsertBlockWithAttribute::postToModalSpace(pBlockReference);
}
AcDbObjectId InsertBlockWithAttribute::postToModalSpace(AcDbEntity* pEnt)
{
assert(pEnt);
AcDbBlockTable* pBlockTable = nullptr;
acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlockTable, AcDb::kForWrite);
AcDbBlockTableRecord* pBlockTableRecord = nullptr;
pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord, AcDb::kForWrite);
pBlockTable->close();
AcDbObjectId entId;
if (pBlockTableRecord->appendAcDbEntity(entId, pEnt) != Acad::eOk)
{
pBlockTableRecord->close();
delete pEnt;
pEnt = nullptr;
return AcDbObjectId::kNull;
}
pBlockTableRecord->close();
pEnt->close();
return entId;
}
void InsertBlockWithAttribute::appendAttributeToBlockReference(AcDbBlockReference* pBlockReference, AcDbAttributeDefinition* pAttributeDefinition)
{
// 创建一个属性对象
AcDbAttribute* pAttribute = new AcDbAttribute();
// 从块参照获取属性对象的特性
pAttribute->setPropertiesFrom(pBlockReference);
pAttribute->setLayer(pBlockReference->layerId());
// 设置属性对象的其它特性
pAttribute->setInvisible(pAttribute->isInvisible());
pAttribute->setPosition(pAttributeDefinition->position());
pAttribute->setHeight(pAttributeDefinition->height());
pAttribute->setWidthFactor(pAttributeDefinition->widthFactor());
pAttribute->setRotation(pAttributeDefinition->rotation());
pAttribute->setHorizontalMode(pAttributeDefinition->horizontalMode());
pAttribute->setVerticalMode(pAttributeDefinition->verticalMode());
pAttribute->setAlignmentPoint(pAttributeDefinition->alignmentPoint());
pAttribute->setTextStyle(pAttributeDefinition->textStyle());
pAttribute->setAttributeFromBlock(pBlockReference->blockTransform());
// 获取属性对象的标记、值
pAttribute->setTag(pAttributeDefinition->tag());
pAttribute->setFieldLength(pAttributeDefinition->fieldLength());
pAttribute->setTextString(pAttributeDefinition->textString());
pBlockReference->appendAttribute(pAttribute);
pAttribute->close();
}
void InsertBlockWithAttribute::setBlockReferenceAttribute(AcDbBlockReference* pBlockReference, AcString& tag, AcString& textVal)
{
AcDbObjectIterator* pAttributeIterator = pBlockReference->attributeIterator();
for (pAttributeIterator->start(); !pAttributeIterator->done(); pAttributeIterator->step())
{
AcDbAttribute* pAttribute = nullptr;
if (acdbOpenObject(pAttribute, pAttributeIterator->objectId(), AcDb::kForWrite) != Acad::eOk)
{
continue;
}
if (tag == pAttribute->tag())
{
pAttribute->setTextString(textVal.kACharPtr());
}
pAttribute->close();
}
delete pAttributeIterator;
}
创建一个块,名称为:序号块
附带一个属性定义,标记:序号
调试运行,执行命令 TestInsertBlockWithAttribute
ObjectARX 2025(C++)插入带属性的块参照 AcDbAttribute