Тема: Jig и AcDbAttribute

Проблема такая:
написал ф-цию вставки блока с атрибутами, аналог Акадовского insert(). Для отображения блока в момент вставки, такое требование, использую AcEdJig. Как сделать так чтобы в этот самый момент вставки атрибуты блока не отображались. И в update() и в apply() для атрибутов устанавливается свойство Invisible, и в последствии они действительно невидимые, но в момент вставки они отрисовываются.В общем и целом мне нужен так сказать исходник акадовского inserta.

Re: Jig и AcDbAttribute

> Alexey
В этот момент уже поздно их делать Invisible - им нужно присвоить свойство Invisible при создании.

Re: Jig и AcDbAttribute

Спасибо. Я еще покурю arxref.chm, но задача в целом следующая:
Есть база блоков, представляющая собой папку в которой около 6000 dwg 1фаил=1блок. И управляющее приложение в акаде. Дополнительная информация о блоках храниться в *.mdb. Пользователь загружает в упр.прилож. базу из *.mdb, потом выбирает одину позицию для вставки. Упр.прилож. из *.mdb получает необходимое имя фаила и из этого фаила копируется в текущий чертеж Block Definition. Потом при помощи Jig вставляется. Тонкость в том, что изменять оригиналы блоков ОЧЕНЬ не желательно и реализовать все это желательно без CustumObjects, чтоб чертежи читались стандартными средствами Акада без доп.надсртроек.

Re: Jig и AcDbAttribute

По-ходу пьесы возникла ещё одна проблема: как добраться из AcDbBlockReference до атрибута с флагом Invisible?.
P.S. Александр подскажите какие известны источники информации, кроме доков которые прилагаются к ObjectArx.

Re: Jig и AcDbAttribute

> Alexey

      //
      //  Получаем информацию о неконстантных атрибутах в блоке
      //
      AcDbObjectIterator *pAttrIter = pBlockRef->attributeIterator();
      if (pAttrIter) {
        for (pAttrIter->start();!pAttrIter->done();pAttrIter->step()) {
          AcDbObjectId objAttrId = pAttrIter->objectId();
          AcDbObjectPointer<AcDbAttribute> pAttr(objAttrId,AcDb::kForRead);
          if ((es = pAttr.openStatus()) == Acad::eOk) {
            //
            // Здесь можно получить информацию об атрибуте
            //
            acutPrintf("\nАтрибут: Tag=%s Value=%s IsConst=%s IsPreset=%s IsInvisible=%s isVerifiable=%s",
                       pAttr->tagConst(), pAttr->textStringConst(),
                      (pAttr->isConstant()?"Yes":"No"),
                      (pAttr->isPreset()?"Yes":"No"),
                      (pAttr->isInvisible()?"Yes":"No"),
                      (pAttr->isVerifiable()?"Yes":"No")
            );
          } else {
            acutPrintf("\nНе удалось открыть атрибут блока! Ошибка: %s", acadErrorStatusText(es));
          }
        }
      }

Re: Jig и AcDbAttribute

Sorry.Я так и делал. Они у меня и невидимые и константые, я решил что итератор игнорирует невидимые атрибуты. Как прочитать константные?
Александр, откуда черпать инфу? Я даже в осле ничего толковей стандартных доков не нахожу, а там далеко не все описано, да и с ошибками :(.

Re: Jig и AcDbAttribute

Alexey пишет:

Александр, откуда черпать инфу?

Если честно, то из опыта и интуиции и аналогичных форумов. Кстати на этом сайте очень(!!!) много полезной информации - пользуйся поиском.

Они у меня и невидимые и константые, я решил что итератор игнорирует невидимые атрибуты. Как прочитать константные?

1) Прочитать все (в том числе и константые) вот так (если бы воспользовался поиском, то нашел бы и сам): https://www.caduser.ru/forum/topic21945.html

2) Константые атрибуты - это общие для всех блоков с одним именем - отключить (т.е. сделать невидимыми) их можно только в определении блока (!).

Re: Jig и AcDbAttribute

> Александр Ривилис
"В этот момент уже поздно их делать Invisible — им нужно присвоить свойство Invisible при создании."Формально я их не создаю.
Я их (AttDef) копирую ф-цией AcDbDatabase::insert(...). В исходном dwg нет возможости их менять. Или имеете ввиду выставить флаг invisible в скопированой BTR? Пробовал - не работает, т.е. флаг выставляется, а в Jig-е все равно прорисовывается тег AttDef-a.
1.Какие есть еще способы скопировать BTR?
2.Как же при моем способе сделать так чтоб в Jig не рисовались AttDef?
Пробовал подсунуть Jig-у свой класс-наследник AcDbBlockReference с переопределенной worldDraw. Отображение AttDef убрал, но блок в Jig-e перестал двигаться.
Сделал так:
class CsBlockReference : public AcDbBlockReference
{
public:
//        ACRX_DECLARE_MEMBERS(CsBlockReference);
    CsBlockReference(const AcGePoint3d&  position,AcDbObjectId  blockTableRec);
    virtual ~CsBlockReference();
virtual    Adesk::Boolean worldDraw(AcGiWorldDraw* p_Wd);
virtual Acad::ErrorStatus setPosition(const AcGePoint3d&);
private:
    AcDbObjectId m_BlockBTRId;
};
CsBlockReference::CsBlockReference(const AcGePoint3d&  position,AcDbObjectId  blockTableRec)
{
    AcDbBlockReference::AcDbBlockReference(position,blockTableRec);
    m_BlockBTRId=blockTableRec;
}
Adesk::Boolean CsBlockReference::worldDraw(AcGiWorldDraw* p_Wd)
{
    Acad::ErrorStatus e;
    AcDbBlockTableRecordIterator *btrIterator;
    AcDbBlockTableRecord *btr;
    AcDbEntity *t_Entity;
    AcDbText *t_AttDef;
    e=acdbOpenObject(btr,m_BlockBTRId,AcDb::kForRead);
    e=btr->newIterator(btrIterator);
    for(btrIterator->start();!btrIterator->done();btrIterator->step())
    {
        e=btrIterator->getEntity(t_Entity,AcDb::kForRead);
        t_AttDef=AcDbText::cast(t_Entity);
        CString debugstr;
        debugstr.Format("%s\n",t_Entity->isA()->name());
        OutputDebugString(debugstr);
        if(t_AttDef==NULL)
        {
            p_Wd->geometry().draw(t_Entity);
        }
        e=t_Entity->close();
    }
    delete btrIterator;
    btr->close();
    return Adesk::kTrue;
}
Acad::ErrorStatus CsBlockReference::setPosition(const AcGePoint3d &pt)
{
    return AcDbBlockReference::setPosition(pt);
}
что-то может еще переопределить надо?
setPosition transformBy и т.д. по-идее должны вызываться родительские.
Пробовал даже варварский способ:
перед вызовом Jig-a удалить AttDef из BTR сохранив его ObjectId, а при выходе из Jig-a восстановить [erase(true/false)]. Это работает, но:
1.не уверен на счет сохранности Id и прочих глюков.
2. AttDef утрачивает свойства текстовые. Это самое неприятное.
3. Ужасно коряво выглядит.
Как всеже работает акадовский _insert?

Re: Jig и AcDbAttribute

Я их (AttDef) копирую ф-цией AcDbDatabase::insert(...). В исходном dwg нет возможости их менять. Или имеете ввиду выставить флаг invisible в скопированой BTR? Пробовал — не работает, т.е. флаг выставляется, а в Jig-е все равно прорисовывается тег AttDef-a.

На уровне идеи - сам не проверял (нет времени) вместо AcDbAttributeDefinition::setInvisible() использовать AcDbEntity::setVisibility().

Re: Jig и AcDbAttribute

> Александр Ривилис
За идею спасибо. Перед вышеописаными манипуляциями - пробовал. Впечатление что AcDbAttributeDefinition::setInvisible() просто вызывает AcDbEntity::setVisibility(), вобщем не работает. Тут вот какая вещь: при таскании блока отрисовывается не содержимое атрибута, а именно тег AttDef.

Re: Jig и AcDbAttribute

Понятно. В приведенном тобой коде наследнике есть ошибка - в worlDraw ты не учитываешь тот факт, что ты показываваешь примитивы из описания блока и поэтому их следует рансформировать используя матрицу blockTransform(). Поэтому они у тебя и не двигаются.
Еще один вариант - создать временную (неименованную) AcDbBlockTableRecord на основе реальной но без постоянных атрибутов и все операции производить с AcDbBlockReference, который ссылается на эту AcDbBlockTableRecord. А после Jig сослатся на оригинальную.

Re: Jig и AcDbAttribute

Александр Ривилис пишет:

создать временную (неименованную)

- мысль! Большое спасибо за участие.
Как думаете, опираясь на опыт и интуицию, штатный _insert как реализован?

Re: Jig и AcDbAttribute

> Alexey
1) Стандартный _INSERT показывает постоянные атрибуты при вставке блока - кстати, не понимаю почему это тебе мешает.
2) Воспользуйся ARXDBG (включи все реакторы) чтобы посмотреть как работает _INSERT
3) Не исключено, что команда _INSERT использует недокументированные (а еще хуже неэкспортируемые) и соответственно недоступные разработчикам на ObjectARX возможности.

Re: Jig и AcDbAttribute

> Александр Ривилис
Спасибо за участие.

не понимаю почему это тебе мешает.

Мешает потому, что при достаточно насыщенном чертеже надпись "BlockText" моргающая на пол экрана, мягко говоря, напрягает.
В итоге: сделал временный класс с переопределенным worldDraw() и подсунул его Jig-у.
Все работает.
Если кому понадобиться, worldDraw()выглядит так:

Adesk::Boolean CsBlockReference::worldDraw(AcGiWorldDraw* p_Wd)
{
    Acad::ErrorStatus e;
    AcDbBlockTableRecordIterator *btrIterator;
    AcDbBlockTableRecord *btr;
    AcDbEntity *t_Entity;
    AcDbEntity *t_CopyOfEntity;
    AcDbText *t_AttDef;
    AcGeMatrix3d TransMatrix;
    e=acdbOpenObject(btr,m_BlockBTRId,AcDb::kForRead);
    e=btr->newIterator(btrIterator);
            TransMatrix = blockTransform();
    for(btrIterator->start();!btrIterator->done();btrIterator->step())
    {
        LockDoc;
        e=btrIterator->getEntity(t_Entity,AcDb::kForWrite);
        t_AttDef=AcDbText::cast(t_Entity);
        CString debugstr;
        debugstr.Format("%s\n",t_Entity->isA()->name());
        OutputDebugString(debugstr);
        if(t_AttDef==NULL)
        {
            t_CopyOfEntity=AcDbEntity::cast(t_Entity->clone());
            t_CopyOfEntity->transformBy(TransMatrix);
            p_Wd->geometry().draw(t_CopyOfEntity);
        }
        e=t_Entity->close();
        UnlockDoc;
    }
    delete btrIterator;
    btr->close();
    return Adesk::kTrue;
}

Re: Jig и AcDbAttribute

> Alexey Suprun
Пару замечаний:
1) LockDoc лучше делать до запуска Jig (чтобы не делать этого в worldDraw - меньше будет тормозить при перерисовке), а UnlockDoc после окончания Jig.
2) Попробуй вместо t_CopyOfEntity->transformBy(TransMatrix); использовать до цикла:

p_Wd->geometry().pushModelTransform(TransMatrix);

после цикла

p_Wd->geometry().popModelTransform(TransMatrix);

А в цикле 1) не нужно делать клоны 2) не нужно открывать примитивы на запись - достаточно на чтение. И вызывать:

p_Wd->geometry().draw(t_Entity);

Re: Jig и AcDbAttribute

> Alexey Suprun
P.S.: Кстати ты создаешь клоны для каждого примитива из блока, но нигде их не удаляешь - это приведет к утечке памяти.

Re: Jig и AcDbAttribute

> Александр Ривилис
Большое спасибо. Теперь понимаю откуда берется инфа :).