admin 发表于 2024-9-20 09:13:24

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

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;
}
页: [1]
查看完整版本: 查看外部引用并找到具有给定名称的所有模块的选取点