|
- bool getPoints( const ACHAR *xRefName, const ACHAR *moduleName, std::vector<std::pair<AcGePoint2d,double>> *points )
- {
- Acad::ErrorStatus errorStatus;
- AcDbDatabase *database = acdbHostApplicationServices()->workingDatabase();
- AcDbBlockTable *blockTable = NULL;
- AcDbBlockTableRecord *blockTableRecord = NULL;
- AcDbDatabase *xRefDatabase = NULL;
- const ACHAR *xRefPath = NULL;
- AcDbDatabase *xRefDWGDatabase = NULL;
- AcDbBlockTable *xRefBlockTable = NULL;
- AcDbBlockTableRecord *xRefBlockTableRecord = NULL;
- AcDbDynBlockTableRecord *xRefDynBlockTableRecord = NULL;
- AcDbDynBlockReference *xRefDynBlockTableReference = NULL;
- AcDbEntity *ent = NULL;
- AcDbBlockReference *ref = NULL;
- AcDbObjectIdArray blockIds;
- AcDbObjectIdArray refIds;
- AcDbObjectIdArray anonyIds;
- AcDbObjectId tmp;
- AcDbBlockTableRecord *tmpRec;
- //xRef transformations
- double xOffset = 0;
- double yOffset = 0;
- double rotation = 0;
- //Get the block table for our database
- errorStatus = database->getBlockTable(blockTable, AcDb::kForRead);
- if( errorStatus != Acad::eOk )
- {
- acutPrintf(L"\nError getting block table %s", acadErrorStatusText( errorStatus ) );
- return false;
- }
- //Get the block table record for the external reference
- errorStatus = blockTable->getAt( xRefName, blockTableRecord, AcDb::kForRead );
- if( errorStatus != Acad::eOk )
- {
- acutPrintf(L"\nError could not get xref %s %s", xRefName, acadErrorStatusText( errorStatus ) );
- blockTable->close();
- return false;
- }
- blockTable->close();
- //Get the transformation of the xRef
- errorStatus = blockTableRecord->getBlockReferenceIds( refIds );
- if( errorStatus != Acad::eOk || refIds.length() < 1 )
- {
- acutPrintf(L"\nError could not get xref reference ids %s", acadErrorStatusText( errorStatus ));
- return false;
- }
- //Open the reference
- acdbOpenObject( ent, refIds.at(0), AcDb::kForRead );
- if( ent == NULL )
- {
- acutPrintf(L"\nError could not get xref reference entity %s", acadErrorStatusText( errorStatus ));
- return false;
- }
- //Cast the reference
- ref = AcDbBlockReference::cast( ent );
- if( ref == NULL )
- {
- acutPrintf(L"\nError could not get xref reference %s", acadErrorStatusText( errorStatus ));
- ent->close();
- return false;
- }
-
- //Get transformations
- xOffset = ref->position().x;
- yOffset = ref->position().y;
- rotation = ref->rotation();
- ref->close();
- ent->close();
- xRefDatabase = blockTableRecord->xrefDatabase(true);
- blockTableRecord->close();
- if( xRefDatabase == NULL )
- {
- acutPrintf(L"\nCould not get external reference database" );
- return false;
- }
- //Get path for external reference dwg file
- xRefPath = acdbOriginalXrefFullPathFor( xRefDatabase );
- if( xRefPath == NULL )
- {
- acutPrintf(L"\nCould not get external reference path" );
- return false;
- }
-
- //Get database for the external reference drawing
- xRefDWGDatabase = new AcDbDatabase(Adesk::kFalse);
- errorStatus = xRefDWGDatabase->readDwgFile(xRefPath);
- if( errorStatus != Acad::eOk )
- {
- acutPrintf(L"\nError could not read xref file %s", acadErrorStatusText( errorStatus ));
- delete xRefDWGDatabase;
- return false;
- }
- //Get the block table for the open model reference file
- errorStatus = xRefDWGDatabase->getBlockTable( xRefBlockTable, AcDb::kForRead );
- if( errorStatus != Acad::eOk )
- {
- acutPrintf(L"\nError could not load xref block table %s", acadErrorStatusText( errorStatus ));
- delete xRefDWGDatabase;
- return false;
- }
- //delete xRefDWGDatabase;
- //Get the definition for the block in the the external reference
- errorStatus = xRefBlockTable->getAt( moduleName, xRefBlockTableRecord, AcDb::kForRead );
- if( errorStatus != Acad::eOk )
- {
- acutPrintf(L"\nError could not get xref block table record %s", acadErrorStatusText( errorStatus ));
- delete xRefDWGDatabase;
- xRefBlockTable->close();
- return false;
- }
-
- /**
- * Note on dynamic blocks
- * Dynamic blocks have parameters. Whenever the parameters are changed an "anonymous" block is added to
- * the DWG. These anonymous blocks will come up in the xRefBlockTableRecord as *U12 where 12 can be any
- * integer. To get these blocks correctly you have to get the block ids associated with the dynamic block
- * and then add the points from those blocks.
- */
-
- //Check if the block is dynamic
- if( AcDbDynBlockReference::isDynamicBlock( xRefBlockTableRecord->id() ) )
- {
- //Get ids of anonymous blocks associated with this dynamic block
- xRefDynBlockTableRecord = new AcDbDynBlockTableRecord( xRefBlockTableRecord->id() );
- errorStatus = xRefDynBlockTableRecord->getAnonymousBlockIds( anonyIds );
- if( errorStatus != Acad::eOk )
- {
- acutPrintf(L"\nError could not get xref anonymous block ids %s", acadErrorStatusText( errorStatus ));
- delete xRefDWGDatabase;
- xRefBlockTable->close();
- return false;
- }
- //Loop through all anonymous blocks and find the correct records in the block table
- for( int i = 0; i < anonyIds.length(); i++ )
- {
- //Compare with block table record
- AcDbBlockTableIterator *it;
- errorStatus = xRefBlockTable->newIterator(it);
- if( errorStatus != Acad::eOk || it == NULL )
- {
- acutPrintf(L"\nError could not get block table record iterator %s", acadErrorStatusText( errorStatus ));
- continue;
- }
- while( !it->done() )
- {
- it->getRecordId(tmp);
- if( anonyIds.at(i) == tmp )
- {
- //If we found the correct record then add its reference ids to our array
- errorStatus = it->getRecord( tmpRec, AcDb::kForRead );
- if( errorStatus != Acad::eOk )
- {
- acutPrintf(L"\nError could not get xref block table record %s", acadErrorStatusText( errorStatus ));
- it->step();
- continue;
- }
- tmpRec->getBlockReferenceIds( blockIds );
- if( errorStatus != Acad::eOk )
- {
- acutPrintf(L"\nError could not get xref block ids %s", acadErrorStatusText( errorStatus ));
- }
- tmpRec->close();
- }
- it->step();
- }
- delete it;
- }
- delete xRefDynBlockTableRecord;
- }
- //We also need to add the references to the block itself
- errorStatus = xRefBlockTableRecord->getBlockReferenceIds( blockIds );
- if( errorStatus != Acad::eOk )
- {
- acutPrintf(L"\nError could not get xref block ids %s", acadErrorStatusText( errorStatus ));
- xRefBlockTable->close();
- return false;
- }
- xRefBlockTableRecord->close();
- //Push all points into the vector
- for( int i = 0; i < blockIds.length(); i++ )
- {
- ent = NULL;
- acdbOpenObject( ent, blockIds.at(i), AcDb::kForRead );
- if( ent != NULL )
- {
- ref = NULL;
- ref = AcDbBlockReference::cast( ent );
- if( ref != NULL )
- {
- AcGePoint2d pnt;
- pnt.x = ref->position().x;
- pnt.y = ref->position().y;
- //Transfrom point
- pnt.x += xOffset;
- pnt.y += yOffset;
- points->push_back( std::pair<AcGePoint2d,double>(pnt,ref->rotation()) );
- }
- ent->close();
- }
- }
- xRefBlockTable->close();
- delete xRefDWGDatabase;
- return true;
- }
复制代码 |
|