天气与日历 切换到窄版

 找回密码
 立即注册
中国膜结构网
十大进口膜材评选 十大国产膜材评选 十大膜结构设计评选 十大膜结构公司评选
查看: 136|回复: 0

在ObjectARX中,获取图块定义并按顺序插入到当前图纸

[复制链接]

该用户从未签到

主题

0

回帖

2912

积分

管理员

积分
2912
发表于 2024-5-24 09:09:01 | 显示全部楼层 |阅读模式
段代码定义了一个外部命令AsdkInsertAllBlocks,它遍历当前图形文档的块表,对于每个非匿名块定义,调用insertBlock函数将其插入到图纸上。插入点默认设置为原点(0, 0, 0),你可以根据需要调整插入点逻辑。请确保在使用前正确配置你的ObjectARX开发环境,并将上述代码编译为ARX插件加载到AutoCAD中。
  1. #include <acad.h>
  2. #include <aced.h>
  3. #include <adslib.h>
  4. #include <dbmain.h>
  5. #include <dbblocktable.h>
  6. #include <dbblocktablerecord.h>
  7. #include <dbents.h>
  8. using namespace std;
  9. // 插入块的函数
  10. void insertBlock(AcDbDatabase* db, const ACHAR* blockName, const AcGePoint3d& insertionPoint)
  11. {
  12.     Acad::ErrorStatus status;
  13.    
  14.     // 创建插入块的参数
  15.     AcDbObjectId blockTableRecordId;
  16.     status = db->getSymbolTable()->lookup(blockName, blockTableRecordId);
  17.     if (status != Acad::eOk) {
  18.         acutPrintf(L"Block %s not found.", blockName);
  19.         return;
  20.     }
  21.    
  22.     AcDbBlockTableRecordPtr pBlockTableRecord;
  23.     status = pBlockTableRecord.openObject(blockTableRecordId, AcDb::OpenMode::kForRead);
  24.     if (status != Acad::eOk) {
  25.         acutPrintf(L"Failed to open block record.");
  26.         return;
  27.     }
  28.    
  29.     // 执行插入操作
  30.     AcDbInsert* pInsert = new AcDbInsert();
  31.     pInsert->setBlockTableRecord(pBlockTableRecord);
  32.     pInsert->setPosition(insertionPoint);
  33.     pInsert->setScaleFactors(1.0, 1.0, 1.0);
  34.     status = pInsert->upgradeOpen();
  35.     if (status == Acad::eOk) {
  36.         status = pInsert->insert(db);
  37.         if (status != Acad::eOk) {
  38.             acutPrintf(L"Failed to insert block.");
  39.         }
  40.         pInsert->close();
  41.     } else {
  42.         acutPrintf(L"Failed to upgrade object.");
  43.         delete pInsert;
  44.     }
  45. }
  46. // 主函数:遍历块表并插入所有块
  47. void insertAllBlocks(AcDbDatabase* db, const AcGePoint3d& baseInsertionPoint)
  48. {
  49.     AcDbBlockTable* pBlockTable;
  50.     Acad::ErrorStatus status = db->getBlockTable(pBlockTable);
  51.     if (status != Acad::eOk) {
  52.         acutPrintf(L"Failed to get Block Table.");
  53.         return;
  54.     }
  55.    
  56.     AcDbBlockTableIterator* pIter;
  57.     pIter = pBlockTable->newIterator();
  58.     for (pIter->start(); !pIter->done(); pIter->step())
  59.     {
  60.         AcDbBlockTableRecord* pRecord;
  61.         status = pIter->getRecord(pRecord, AcDb::OpenMode::kForRead);
  62.         if (status != Acad::eOk) continue;
  63.         
  64.         // 确保是块定义而非其他类型的记录
  65.         if (pRecord->isAnonymousBlock()) {
  66.             pRecord->close();
  67.             continue;
  68.         }
  69.         
  70.         ACHAR* blockName = pRecord->getName();
  71.         // 这里可以根据需要调整插入点,例如加上偏移量或使用某种模式
  72.         insertBlock(db, blockName, baseInsertionPoint);
  73.         pRecord->close();
  74.     }
  75.     delete pIter;
  76. }
  77. // 外部命令定义
  78. void AsdkInsertAllBlocks()
  79. {
  80.     Acad::ErrorStatus status;
  81.     AcDbDatabase* pDb = acdbHostApplicationServices()->workingDatabase();
  82.     AcGePoint3d insertionPoint(0, 0, 0); // 设置初始插入点
  83.    
  84.     insertAllBlocks(pDb, insertionPoint);
  85. }
  86. // ObjectARX模块入口点
  87. ACRX采用DECLARE采用MODULE(NeededFunctions)
  88.     ACRX采用ENTRY采用FUNCTION(AsdkInsertAllBlocks)
  89. END采用ARX采用DEFINE采用MODULE()
复制代码





这段代码在每次插入块之后,都会调用getBlockBoundingBoxMaxPoint函数估算当前块的大致尺寸(这里简化为边界框的最大点),然后通过updateInsertionPoint函数更新下一个块的插入位置。请注意,这个方法非常基础,实际应用中可能需要更复杂的逻辑来精确处理块的布局,比如考虑块的旋转、缩放、以及不规则形状等。此外,为了简化,这里假设所有块都是正向放置的,并且在X-Y平面上进行布局调整。



  1. // 获取块的边界框(简化版,仅考虑矩形边界)
  2. AcGePoint3d getBlockBoundingBoxMaxPoint(AcDbBlockTableRecord* pRecord)
  3. {
  4.     AcGePoint3d minPoint, maxPoint;
  5.     pRecord->getBoundingBox(minPoint, maxPoint);
  6.     return maxPoint; // 返回边界框的最大点,可用于估计块的“右下”位置
  7. }
  8. // 更新插入点的函数,基于前一个块的大小
  9. AcGePoint3d updateInsertionPoint(const AcGePoint3d& currentInsertionPoint, const AcGePoint3d& blockSize)
  10. {
  11.     // 假设块大小由其边界框的最大点表示,这里简单地在X和Y方向上各增加一个单位长度
  12.     // 实际应用中,可能需要考虑块的具体布局要求,如对齐方式、间距等
  13.     return AcGePoint3d(currentInsertionPoint.x + blockSize.x + 1.0,
  14.                       currentInsertionPoint.y + blockSize.y + 1.0,
  15.                       currentInsertionPoint.z);
  16. }
  17. // 更新后的主函数:遍历块表并插入所有块
  18. void insertAllBlocksWithOffset(AcDbDatabase* db, AcGePoint3d& insertionPoint)
  19. {
  20.     AcDbBlockTable* pBlockTable;
  21.     Acad::ErrorStatus status = db->getBlockTable(pBlockTable);
  22.     if (status != Acad::eOk) {
  23.         acutPrintf(L"Failed to get Block Table.");
  24.         return;
  25.     }
  26.    
  27.     AcDbBlockTableIterator* pIter;
  28.     pIter = pBlockTable->newIterator();
  29.     for (pIter->start(); !pIter->done(); pIter->step())
  30.     {
  31.         AcDbBlockTableRecord* pRecord;
  32.         status = pIter->getRecord(pRecord, AcDb::OpenMode::kForRead);
  33.         if (status != Acad::eOk) continue;
  34.         
  35.         if (pRecord->isAnonymousBlock()) {
  36.             pRecord->close();
  37.             continue;
  38.         }
  39.         
  40.         insertBlock(db, pRecord->getName(), insertionPoint);
  41.         
  42.         // 获取并更新插入点
  43.         AcGePoint3d blockSize = getBlockBoundingBoxMaxPoint(pRecord);
  44.         insertionPoint = updateInsertionPoint(insertionPoint, blockSize);
  45.         
  46.         pRecord->close();
  47.     }
  48.     delete pIter;
  49. }
复制代码

 

 

 

 

在ObjectARX中,获取图块定义并按顺序插入到当前图纸
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2024-11-5 12:29 , Processed in 0.149484 second(s), 25 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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