Тема: Интересная особенность получения Reference блока

Заметил такую особенность:
Получаю всё внутренности блока, через Entity, проверяю является ли он AcDbBlockReference, и если да делаю от него cast, то оказывается, что сам Entity принадлежит блоку *Model_Space, а его cast уже принадлежит другому блоку, чьё имя мне и нужно. Если же сразу получать BlockReference, то всё нормально.
Кто-нить уже с таким сталкивался?

Re: Интересная особенность получения Reference блока

Непонятно. Четко напишите, что хотите получить. А потом уже, что делали :)

Re: Интересная особенность получения Reference блока

По имени блока, хочу определить все его Entity, в том числе и его Reference. Для этого испльзую вот такой кусок кода.

void CDWGFunctions::AddBlockEntity(char* BlockName, unsigned short BlockID)
{
    //Подключение к таблице блоков
    AcDbBlockTable *pBlockTable;
    if (
            (acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlockTable,AcDb::kForRead)!=Acad::eOk)
        ||    (!pBlockTable)    
    ){
        acutPrintf("Не могу получить доступ к таблице блоков\n");
        return;
    }
    AcDbBlockTableRecord* pBlockTableRecord=NULL;
    if (
        (pBlockTable->getAt(BlockName, pBlockTableRecord, AcDb::kForRead)!=Acad::eOk)
        ||    (!pBlockTableRecord)    
    ){
        acutPrintf("Блока с именем %s не найдено\n", BlockName);
        return;
    }
    
    //acutPrintf("Получаем Entity блока\n");
    //Создание итератора
    AcDbBlockTableRecordIterator *pBlockTableRecordIterator=NULL;
    if (
            (pBlockTableRecord->newIterator(pBlockTableRecordIterator, true)!=Acad::eOk)
        ||    (!pBlockTableRecordIterator)
    ){
        acutPrintf("Ошибка создания итератора блоков: не хватает памяти\n");
        return;
    }

Потом с помощью итератора  бегаю по всем Entity:

AcDbEntity *pEntity=NULL;
            for(pBlockTableRecordIterator->start();!pBlockTableRecordIterator->done();pBlockTableRecordIterator->step())
    {
        if (
                (pBlockTableRecordIterator->getEntity(pEntity,AcDb::kForRead)==Acad::eOk)
            || !(!pEntity)
        ){
                 //Что-то делается
                }
         }

Далее ищу объекты типа AcDBReference

if (!strcmp(pEntity->isA()->name(),"AcDbBlockReference"))
            {
                AcDbBlockReference *pBlockReference=NULL;
                AcGePoint3d EntityPosition;
                if ((pBlockReference = AcDbBlockReference::cast(pEntity))!= NULL) {
                // Можно считывать текстовую информацию из pBlockReference:
                    //acutPrintf("Reference %s\n", BlockName);
                    EntityPosition=pBlockReference->position();
                    ACHAR *layer=pBlockReference->layer();
                    DocVars.docData().TempObjects.AddBlockRef(EntityPosition[0], EntityPosition[1], EntityPosition[2], pBlockReference->rotation(), BlockID, layer);
                    acutDelString(layer);
                }
                pBlockReference=NULL;
            }

И оказывается, что у объекта *Model_Space множество Reference-ов. А у многих объектом их вообще нет.
Если же мы получим окузатель на запись в таблице блоков pBlockReference>blockTableRecord() и посмотрим имя этой записи, то оказывается, что Reference принадлежит уже не *Model_Space, а правильному блоку.
Если же мы используем pEntity->blockid(), и запросим имя записи, то опять получаем *Model_Space
Вот такая вот особенность.

Re: Интересная особенность получения Reference блока

Есть простой метод

AcDbBlockTableRecord::getBlockReferenceIds

This function returns a list of AcDbBlockReferences that either directly or indirectly, through block nesting, reference this block. It only returns those block references that are currently active. Use getErasedBlockReferenceIds() to get a list of erased references

Кроме того, проверка
"if (!strcmp(pEntity->isA()->name(),"AcDbBlockReference"))"
явно лишняя поскольку второй "if ((pBlockReference = AcDbBlockReference::cast(pEntity))!= NULL)" вполне достаточно поскольку

Re: Интересная особенность получения Reference блока

This static member function provides a safe casting mechanism. If
inPtr->isKindOf(<ThisClass>::desc()) == Adesk::kTrue
then <ThisClass>::cast(inPtr) returns the input pointer else <ThisClass>::cast(inPtr) returns NULL.

Re: Интересная особенность получения Reference блока

> Roman
Я на самом деле так и сделал, как ты советуешь, просто меня очень удивила именно такая ситуация. Хорошо вовремя заметил иначе бы боюсь наполучал данные