Тема: вставка блока

Доброго времени суток!
В дополнение к избитой теме о вставке блоков, хочу задать знатокам еще вопрос о расчленении блоков.
Блок Bl_Name со всеми атрибутами находится в отдельном файле, и вставляется в текущую базу как подобает. Если он в таблице блоков уже имеется, то берется оттуда, и вставляется как бы пройдя через процедуру "explode". Как избежать расчленения? Помогите! Заранее спасибо.

AcDbDatabase *InsertDatabase = new AcDbDat abase(false,true); 

if (!pBlockTbl->has(Bl_Name)){      
        InsertDatabase->readDwgFile( BlFileName, _SH_DENYWR, false, NULL );
        pCurDatabase->insert( xform, InsertDatabase, true));   
}else{
        this->pBlockTbl->getAt( Bl_Name, blockId));
        pCurDatabase->wblock(InsertDatabase, blockId));
        pCurDatabase->insert(xform, InsertDatabase, false ));             
}

(изменено: Александр Ривилис, 9 ноября 2010г. 12:09:51)

Re: вставка блока

Максим Маланичев пишет:

Как избежать расчленения?

Не понял вопрос. Сделать блок "нерасчленимым"?
Вообще-то, вот эта часть у тебя совсем непонятная:

this->pBlockTbl->getAt( Bl_Name, blockId));
pCurDatabase->wblock(InsertDatabase, blockId));
pCurDatabase->insert(xform, InsertDatabase, false )); 

Здесь напрашивается просто создание AcDbBlockReference в текущей базе.

Re: вставка блока

Если он в таблице блоков уже имеется, то берется оттуда, и вставляется как бы пройдя через процедуру "explode"

ИМХО, че-то ты намудрил :), так не бывает.
в любом случае в ЧЕРТЕЖ вставляется блок из БД текущего чертежа. при вставке в текущую базу по-любому приходится делать wblock и insert. вот пример вставки в текущую БД. значит логика такая. есть dwg с некоторым количеством блоков. мы знаем имя блока и полное имя файла (включая путь). вставка происходит через пустую базу. сразу блок копируется в пустую БД (pTempDB), а потом вся эта пустая база вставляется в текущую БД.

AcDbObjectId importBlockToCurDWGDat abase(const ACHAR *pBlockName, const ACHAR *pFileName)
{
    Acad::ErrorStatus es=Acad::eOk;
    AcDbObjectId idImported; // ID нашего нового блока
    AcDbDatabase* pWorkDatabase = acdbHostApplicationServices()->workingDat abase();
    AcAxDocLock docLock(pWorkDatabase);
    AcDbDatabase* pBlockDatabase = new AcDbDat abase(false,true);
    es = pBlockDatabase->readDwgFile(pFileName);
    if(es!=Acad::eOk){delete pBlockDatabase;return NULL;}
            
    try
    {
        AcDbBlockTable* pBlockTable;
        es=pBlockDatabase->getSymbolTable(pBlockTable,AcDb::kForRead);
        if(es!=Acad::eOk){delete pBlockDatabase;return NULL;} // нет символьной таблицы (блоков вооообще)
              
        AcDbObjectId idInsRecord;      
        es=pBlockTable->getAt(pBlockName,idInsRecord);
        pBlockTable->close();
        if(es!=Acad::eOk){delete pBlockDatabase;return NULL;} // нет такого блока
          
        AcDbDatabase* pTempDB;
        es=pBlockDatabase->wblock(pTempDB,idInsRecord);
        if(es!=Acad::eOk){delete pBlockDatabase;return NULL;} // не скопировался блок в пустую базу
              
        es=pWorkDatabase->insert(idImported,pBlockName,pTempDB);
        delete pTempDB;
        if(es!=Acad::eOk){delete pBlockDatabase;return NULL;} // не вставилась пустая база с блоком в нашу текущую базу
    }catch(...){delete pBlockDatabase;return NULL;}

    delete pBlockDatabase;
    return idImported;
}

вариант вставки в таком случае будет выглядеть где-то так

ACHAR blockName[255], blockPath[255]; // заполнить данными
double scale = 0.5; // масштабный коэфициент
AcDbObjectId newBlockTableId = importBlockToCurDWGDat abase(blockName,blockPath);
if (newBlockTableId.isNull()) 
{
    acedAlert(_T("Данный блок не найден"));
    return;
}
AcGePoint3d insPnt;            
acedCommand (RTSTR, _T("_ucs"),RTSTR,_T("_v"),0);
if(acedGetPoint(NULL,_T("\nТочка вставки: "),asDblArray (insPnt))!=RTNORM)
{
    acedCommand(RTSTR,_T("_ucs"),RTSTR,_T("_p"),0);
    return;
}

AcDbBlockReference *blockReference = new AcDbBlockReference(insPnt,newBlockTableId);
blockReference->setRotation(0.0);
blockReference->setNormal (AcGeVector3d (0.0, 0.0, 1.0)) ;
blockReference->setScaleFactors(AcGeScale3d(scale));
AcGeMatrix3d matUcs;
acedGetCurrentUCS(matUcs);
blockReference->transformBy(matUcs);
postToDb(blockReference); // запись в БД

PS: код рабочий (отрываю от сердца :)). если оставить все как есть, то при каждой втавке блока запись в БД по поводу блока с указанным именем будет обновляться.
если перед функцией importBlockToCurDWGDat abase(blockName,blockPath); сразу проверить наличие блока в БД и взять его ObjectId, то обновление внутренностей блока происходить не будет.
ну вариант такой

AcDbObjectId newBlockTableId;newBlockTableId.setNull();
// тут поиск в БД по имени блока и получение его id в переменную newBlockTableId
if (newBlockTableId.isNull())
    newBlockTableId = importBlockToCurDWGDat abase(blockName,blockPath);
//ну и дальше по тексту

Re: вставка блока

Спасибо, уважаемые! Оперативно и в точку!
С AcDbBlockReference обязательно сейчас попробую!