找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 活动 交友 discuz
查看: 38|回复: 0

查看外部引用并找到具有给定名称的所有模块的选取点

[复制链接]

0

主题

0

回帖

26

积分

管理员

积分
26
发表于 2024-9-20 09:13:24 | 显示全部楼层 |阅读模式
  1. bool getPoints( const ACHAR *xRefName, const ACHAR *moduleName, std::vector<std::pair<AcGePoint2d,double>> *points )
  2. {
  3.         Acad::ErrorStatus errorStatus;
  4.         AcDbDatabase *database = acdbHostApplicationServices()->workingDatabase();
  5.         AcDbBlockTable *blockTable = NULL;
  6.         AcDbBlockTableRecord *blockTableRecord = NULL;
  7.         AcDbDatabase *xRefDatabase = NULL;
  8.         const ACHAR *xRefPath = NULL;
  9.         AcDbDatabase *xRefDWGDatabase = NULL;
  10.         AcDbBlockTable *xRefBlockTable = NULL;
  11.         AcDbBlockTableRecord *xRefBlockTableRecord = NULL;
  12.         AcDbDynBlockTableRecord *xRefDynBlockTableRecord = NULL;
  13.         AcDbDynBlockReference *xRefDynBlockTableReference = NULL;
  14.         AcDbEntity *ent = NULL;
  15.         AcDbBlockReference *ref = NULL;
  16.         AcDbObjectIdArray blockIds;
  17.         AcDbObjectIdArray refIds;
  18.         AcDbObjectIdArray anonyIds;
  19.         AcDbObjectId tmp;
  20.         AcDbBlockTableRecord *tmpRec;
  21.         //xRef transformations
  22.         double xOffset = 0;
  23.         double yOffset = 0;
  24.         double rotation = 0;
  25.         //Get the block table for our database
  26.         errorStatus = database->getBlockTable(blockTable, AcDb::kForRead);
  27.         if( errorStatus != Acad::eOk )
  28.         {
  29.                 acutPrintf(L"\nError getting block table %s", acadErrorStatusText( errorStatus ) );     
  30.                 return false;
  31.         }
  32.         //Get the block table record for the external reference
  33.         errorStatus = blockTable->getAt( xRefName, blockTableRecord, AcDb::kForRead );
  34.         if( errorStatus != Acad::eOk )
  35.         {
  36.                 acutPrintf(L"\nError could not get xref %s %s", xRefName, acadErrorStatusText( errorStatus ) );
  37.                 blockTable->close();
  38.                 return false;
  39.         }
  40.         blockTable->close();
  41.         //Get the transformation of the xRef
  42.         errorStatus = blockTableRecord->getBlockReferenceIds( refIds );
  43.         if( errorStatus != Acad::eOk || refIds.length() < 1 )
  44.         {
  45.                 acutPrintf(L"\nError could not get xref reference ids %s", acadErrorStatusText( errorStatus ));     
  46.                 return false;
  47.         }
  48.         //Open the reference
  49.         acdbOpenObject( ent, refIds.at(0), AcDb::kForRead );
  50.         if( ent == NULL )
  51.         {
  52.                 acutPrintf(L"\nError could not get xref reference entity %s", acadErrorStatusText( errorStatus ));     
  53.                 return false;
  54.         }
  55.         //Cast the reference
  56.         ref = AcDbBlockReference::cast( ent );
  57.         if( ref == NULL )
  58.         {
  59.                 acutPrintf(L"\nError could not get xref reference %s", acadErrorStatusText( errorStatus ));     
  60.                 ent->close();
  61.                 return false;
  62.         }
  63.        
  64.         //Get transformations
  65.         xOffset = ref->position().x;
  66.         yOffset = ref->position().y;
  67.         rotation = ref->rotation();
  68.         ref->close();
  69.         ent->close();
  70.         xRefDatabase = blockTableRecord->xrefDatabase(true);
  71.         blockTableRecord->close();
  72.         if( xRefDatabase == NULL )
  73.         {
  74.                 acutPrintf(L"\nCould not get external reference database" );
  75.                 return false;
  76.         }
  77.         //Get path for external reference dwg file
  78.         xRefPath = acdbOriginalXrefFullPathFor( xRefDatabase );
  79.         if( xRefPath == NULL )
  80.         {
  81.                 acutPrintf(L"\nCould not get external reference path" );
  82.                 return false;
  83.         }
  84.        
  85.         //Get database for the external reference drawing
  86.         xRefDWGDatabase = new AcDbDatabase(Adesk::kFalse);
  87.         errorStatus = xRefDWGDatabase->readDwgFile(xRefPath);
  88.         if( errorStatus != Acad::eOk )
  89.         {
  90.                 acutPrintf(L"\nError could not read xref file %s", acadErrorStatusText( errorStatus ));   
  91.                 delete xRefDWGDatabase;
  92.                 return false;
  93.         }
  94.         //Get the block table for the open model reference file
  95.         errorStatus = xRefDWGDatabase->getBlockTable( xRefBlockTable, AcDb::kForRead );
  96.         if( errorStatus != Acad::eOk )
  97.         {
  98.                 acutPrintf(L"\nError could not load xref block table %s", acadErrorStatusText( errorStatus ));
  99.                 delete xRefDWGDatabase;
  100.                 return false;
  101.         }
  102.         //delete xRefDWGDatabase;
  103.         //Get the definition for the block in the the external reference
  104.         errorStatus = xRefBlockTable->getAt( moduleName, xRefBlockTableRecord, AcDb::kForRead );
  105.         if( errorStatus != Acad::eOk )
  106.         {
  107.                 acutPrintf(L"\nError could not get xref block table record %s", acadErrorStatusText( errorStatus ));  
  108.                 delete xRefDWGDatabase;
  109.                 xRefBlockTable->close();
  110.                 return false;
  111.         }
  112.        
  113.         /**
  114.         * Note on dynamic blocks
  115.         * Dynamic blocks have parameters. Whenever the parameters are changed an "anonymous" block is added to
  116.         * the DWG. These anonymous blocks will come up in the xRefBlockTableRecord as *U12 where 12 can be any
  117.         * integer. To get these blocks correctly you have to get the block ids associated with the dynamic block
  118.         * and then add the points from those blocks.
  119.         */
  120.        
  121.         //Check if the block is dynamic
  122.         if( AcDbDynBlockReference::isDynamicBlock( xRefBlockTableRecord->id() ) )
  123.         {
  124.                 //Get ids of anonymous blocks associated with this dynamic block
  125.                 xRefDynBlockTableRecord = new AcDbDynBlockTableRecord( xRefBlockTableRecord->id() );
  126.                 errorStatus = xRefDynBlockTableRecord->getAnonymousBlockIds( anonyIds );
  127.                 if( errorStatus != Acad::eOk )
  128.                 {
  129.                         acutPrintf(L"\nError could not get xref anonymous block ids %s", acadErrorStatusText( errorStatus ));
  130.                         delete xRefDWGDatabase;                       
  131.                         xRefBlockTable->close();
  132.                         return false;
  133.                 }
  134.                 //Loop through all anonymous blocks and find the correct records in the block table
  135.                 for( int i = 0; i < anonyIds.length(); i++ )
  136.                 {
  137.                         //Compare with block table record
  138.                         AcDbBlockTableIterator *it;
  139.                         errorStatus = xRefBlockTable->newIterator(it);
  140.                         if( errorStatus != Acad::eOk || it == NULL )
  141.                         {
  142.                                 acutPrintf(L"\nError could not get block table record iterator %s", acadErrorStatusText( errorStatus ));
  143.                                 continue;
  144.                         }
  145.                         while( !it->done() )
  146.                         {
  147.                                 it->getRecordId(tmp);
  148.                                 if( anonyIds.at(i) == tmp )
  149.                                 {
  150.                                         //If we found the correct record then add its reference ids to our array
  151.                                         errorStatus = it->getRecord( tmpRec, AcDb::kForRead );
  152.                                         if( errorStatus != Acad::eOk )
  153.                                         {
  154.                                                 acutPrintf(L"\nError could not get xref block table record %s", acadErrorStatusText( errorStatus ));     
  155.                                                 it->step();
  156.                                                 continue;
  157.                                         }
  158.                                         tmpRec->getBlockReferenceIds( blockIds );
  159.                                         if( errorStatus != Acad::eOk )
  160.                                         {
  161.                                                 acutPrintf(L"\nError could not get xref block ids %s", acadErrorStatusText( errorStatus ));
  162.                                         }
  163.                                         tmpRec->close();
  164.                                 }
  165.                                 it->step();
  166.                         }
  167.                         delete it;
  168.                 }
  169.                 delete xRefDynBlockTableRecord;
  170.         }
  171.         //We also need to add the references to the block itself
  172.         errorStatus = xRefBlockTableRecord->getBlockReferenceIds( blockIds );
  173.         if( errorStatus != Acad::eOk )
  174.         {
  175.                 acutPrintf(L"\nError could not get xref block ids %s", acadErrorStatusText( errorStatus ));
  176.                 xRefBlockTable->close();
  177.                 return false;
  178.         }
  179.         xRefBlockTableRecord->close();
  180.         //Push all points into the vector
  181.         for( int i = 0; i < blockIds.length(); i++ )
  182.         {
  183.                 ent = NULL;
  184.                 acdbOpenObject( ent, blockIds.at(i), AcDb::kForRead );
  185.                 if( ent != NULL )
  186.                 {
  187.                         ref = NULL;
  188.                         ref = AcDbBlockReference::cast( ent );
  189.                         if( ref != NULL )
  190.                         {
  191.                                 AcGePoint2d pnt;
  192.                                 pnt.x = ref->position().x;
  193.                                 pnt.y = ref->position().y;
  194.                                 //Transfrom point
  195.                                 pnt.x += xOffset;
  196.                                 pnt.y += yOffset;
  197.                                 points->push_back( std::pair<AcGePoint2d,double>(pnt,ref->rotation()) );
  198.                         }
  199.                         ent->close();
  200.                 }               
  201.         }
  202.         xRefBlockTable->close();
  203.         delete xRefDWGDatabase;
  204.         return true;
  205. }
复制代码
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|膜结构网

GMT+8, 2024-12-27 22:01 , Processed in 0.129767 second(s), 19 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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